Added options to limit the number of resources and for handling of resource conflicts
authorWaqas Hussain <waqas20@gmail.com>
Wed, 26 Nov 2008 21:48:08 +0000 (02:48 +0500)
committerWaqas Hussain <waqas20@gmail.com>
Wed, 26 Nov 2008 21:48:08 +0000 (02:48 +0500)
 - core.max_resources: defaults to 10
 - core.conflict_resolve: can be "random", "increment", "kick_new" and "kick_old" (default)

core/sessionmanager.lua

index e83b7c2334217e8ef28df6562aae9059f3f4abbc..24be2e69205a8d57952ae6d01330ad44b02b0856 100644 (file)
@@ -13,6 +13,7 @@ local log = require "util.logger".init("sessionmanager");
 local error = error;
 local uuid_generate = require "util.uuid".generate;
 local rm_load_roster = require "core.rostermanager".load_roster;
+local config_get = require "core.configmanager".get;
 
 local st = require "util.stanza";
 
@@ -88,9 +89,35 @@ function bind_resource(session, resource)
        if not hosts[session.host].sessions[session.username] then
                hosts[session.host].sessions[session.username] = { sessions = {} };
        else
-               if hosts[session.host].sessions[session.username].sessions[resource] then
+               local sessions = hosts[session.host].sessions[session.username].sessions;
+               local limit = config_get(session.host, "core", "max_resources") or 10;
+               if #sessions >= limit then
+                       return nil, "cancel", "conflict", "Resource limit reached; only "..limit.." resources allowed";
+               end
+               if sessions[resource] then
                        -- Resource conflict
-                       return nil, "cancel", "conflict", "Resource already exists"; -- TODO kick old resource
+                       local policy = config_get(session.host, "core", "conflict_resolve");
+                       local increment;
+                       if policy == "random" then
+                               resource = uuid_generate();
+                               increment = true;
+                       elseif policy == "increment" then
+                               increment = true; -- TODO ping old resource
+                       elseif policy == "kick_new" then
+                               return nil, "cancel", "conflict", "Resource already exists";
+                       else -- if policy == "kick_old" then
+                               hosts[session.host].sessions[session.username].sessions[resource]:close {
+                                       condition = "conflict";
+                                       text = "Replaced by new connection";
+                               };
+                       end
+                       if increment and sessions[resource] then
+                               local count = 1;
+                               while sessions[resource.."#"..count] do
+                                       count = count + 1;
+                               end
+                               resource = resource.."#"..count;
+                       end
                end
        end