From fdfa8f715f71af602c0282a6dade55f84c694f91 Mon Sep 17 00:00:00 2001 From: Alexey Melnichuk Date: Fri, 21 Aug 2015 16:18:52 +0400 Subject: [PATCH 1/3] Change. Store data in cache based on UserID. Change. Support register with AuthID==UserID==Extension for extension with number-alias. 1. We need only one record in memcache. When we get SIP request we can find record by userid. When we want check AuthID we do `user_data userid@domain attr id` which also search record by userid. 2. We do not need check AuthID if we get record from DB. There already has check. So we can reduce number of request to * if there no record in memcached - one memcache get (returns not found) - database auth - one memcache set * if record in memcache - one memcache get to retrieve XML - one memcache get to check Extension==AuthID --- .../resources/scripts/directory/directory.lua | 87 ++++++++++++------- 1 file changed, 56 insertions(+), 31 deletions(-) diff --git a/resources/install/scripts/app/xml_handler/resources/scripts/directory/directory.lua b/resources/install/scripts/app/xml_handler/resources/scripts/directory/directory.lua index f4c0414ddb..9329abf0f8 100644 --- a/resources/install/scripts/app/xml_handler/resources/scripts/directory/directory.lua +++ b/resources/install/scripts/app/xml_handler/resources/scripts/directory/directory.lua @@ -68,6 +68,9 @@ end local from_user = params:getHeader("sip_from_user") + if from_user == '' then + from_user = user + end -- verify from_user and number alias for this methods local METHODS = { @@ -80,30 +83,50 @@ user = ""; end - --get the cache - if (trim(api:execute("module_exists", "mod_memcache")) == "true") then - if (domain_name) then - XML_STRING = trim(api:execute("memcache", "get directory:" .. user .. "@" .. domain_name)); - end - if (XML_STRING == "-ERR NOT FOUND") or (XML_STRING == "-ERR CONNECTION FAILURE") then - source = "database"; - continue = true; - else - source = "cache"; - continue = true; - end - else - XML_STRING = ""; - source = "database"; - continue = true; + if (from_user == "") or (from_user == nil) then + from_user = user end --prevent processing for invalid user - if (user == "*97") then + if (user == "*97") or (user == "") then source = ""; continue = false; end + -- cleanup + XML_STRING = nil; + + --get the cache + if (continue) then + if (trim(api:execute("module_exists", "mod_memcache")) == "true") then + if (domain_name) then + local key = "directory:" .. (from_user or user) .. "@" .. domain_name + XML_STRING = trim(api:execute("memcache", "get " .. key)); + + if debug['cache'] then + if XML_STRING:sub(1, 4) == '-ERR' then + freeswitch.consoleLog("notice", "[xml_handler-directory][memcache] get key: " .. key .. " fail: " .. XML_STRING .. "\n") + else + freeswitch.consoleLog("notice", "[xml_handler-directory][memcache] get key: " .. key .. " pass!" .. "\n") + end + end + else + XML_STRING = "-ERR NOT FOUND" + end + if (XML_STRING == "-ERR NOT FOUND") or (XML_STRING == "-ERR CONNECTION FAILURE") then + source = "database"; + continue = true; + else + source = "cache"; + continue = true; + end + else + XML_STRING = ""; + source = "database"; + continue = true; + end + end + --show the params in the console --if (params:serialize() ~= nil) then -- freeswitch.consoleLog("notice", "[xml_handler-directory.lua] Params:\n" .. params:serialize() .. "\n"); @@ -118,8 +141,10 @@ --freeswitch.consoleLog("notice", "[xml_handler-directory.lua] dialed_extension is " .. dialed_extension .. "\n"); end + local loaded_from_db = false --build the XML string from the database if (source == "database") or (load_balancing) then + loaded_from_db = true --database connection if (continue) then --connect to the database @@ -211,8 +236,10 @@ if (debug["sql"]) then freeswitch.consoleLog("notice", "[xml_handler] SQL: " .. sql .. "\n"); end + continue = false dbh:query(sql, function(row) --general + continue = true domain_uuid = row.domain_uuid; extension_uuid = row.extension_uuid; extension = row.extension; @@ -266,7 +293,7 @@ -- check matching UserID and AuthName if sip_auth_method and (METHODS[sip_auth_method] or METHODS._ANY_) then - continue = (sip_from_user == user) and ((sip_from_number == user) or (sip_from_number == from_user)) + continue = (sip_from_user == user) and ((sip_from_number == from_user) or (from_user == user)) if not continue then XML_STRING = nil; return 1; @@ -279,8 +306,7 @@ else --set a default dial string if (dial_string == null) then - local username = (#number_alias > 0) and number_alias or extension - dial_string = "{sip_invite_domain=" .. domain_name .. ",presence_id=" .. user .. "@" .. domain_name .. "}${sofia_contact(" .. username .. "@" .. domain_name .. ")}"; + dial_string = "{sip_invite_domain=" .. domain_name .. ",presence_id=" .. user .. "@" .. domain_name .. "}${sofia_contact(" .. sip_from_number .. "@" .. domain_name .. ")}"; end --set the an alternative dial string if the hostnames don't match if (load_balancing) then @@ -514,9 +540,11 @@ dbh:release(); --set the cache - if (user and domain_name) then - result = trim(api:execute("memcache", "set directory:" .. user .. "@" .. domain_name .. " '"..XML_STRING:gsub("'", "'").."' "..expire["directory"])); + local key = "directory:" .. sip_from_number .. "@" .. domain_name + if debug['cache'] then + freeswitch.consoleLog("notice", "[xml_handler-directory][memcache] set key: " .. key .. "\n") end + result = trim(api:execute("memcache", "set " .. key .. " '"..XML_STRING:gsub("'", "'").."' "..expire["directory"])); --send the xml to the console if (debug["xml_string"]) then @@ -532,17 +560,14 @@ end end - if XML_STRING and sip_auth_method and (METHODS[sip_auth_method] or METHODS._ANY_) then - --disable registration for number-alias - if (api:execute("user_data", user .. "@" .. domain_name .." attr id") ~= user) then + if XML_STRING and (not loaded_from_db) + and sip_auth_method and (METHODS[sip_auth_method] or METHODS._ANY_) + then + local user_id = api:execute("user_data", from_user .. "@" .. domain_name .." attr id") + --disable registration for number-alias and foreign number_alias + if user_id ~= user then XML_STRING = nil; end - --disable registration for foreign number_alias - if from_user ~= user then - if (api:execute("user_data", from_user .. "@" .. domain_name .." attr id") ~= user) then - XML_STRING = nil; - end - end end --get the XML string from the cache From 148d2b42f266d6c1412140035d6c27f5c68d6d11 Mon Sep 17 00:00:00 2001 From: Alexey Melnichuk Date: Fri, 21 Aug 2015 16:43:25 +0400 Subject: [PATCH 2/3] Add. Flag to switch mode for building dial-string. You can configure ether you register with UserID=number-alias or UserID=Extension In both cases to dial user you should use `user/@domain` or `user_data @domain` Need test setting of presence_id for case when UserID=Extension. --- .../resources/scripts/directory/directory.lua | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/resources/install/scripts/app/xml_handler/resources/scripts/directory/directory.lua b/resources/install/scripts/app/xml_handler/resources/scripts/directory/directory.lua index 9329abf0f8..6d210bf723 100644 --- a/resources/install/scripts/app/xml_handler/resources/scripts/directory/directory.lua +++ b/resources/install/scripts/app/xml_handler/resources/scripts/directory/directory.lua @@ -62,15 +62,18 @@ --all other directory actions: sip_auth, user_call --except for the action: group_call + -- Make sance only for extensions with number_alias + -- true - you should register with AuthID=Extension and UserID=Number Alias + -- false - you should register with AuthID=UserID=Extension + also in this case you need 2 records in memcache for one extension + local DIAL_STRING_BASED_ON_USERID = false + local sip_auth_method = params:getHeader("sip_auth_method") if sip_auth_method then sip_auth_method = sip_auth_method:upper(); end local from_user = params:getHeader("sip_from_user") - if from_user == '' then - from_user = user - end -- verify from_user and number alias for this methods local METHODS = { @@ -306,7 +309,7 @@ else --set a default dial string if (dial_string == null) then - dial_string = "{sip_invite_domain=" .. domain_name .. ",presence_id=" .. user .. "@" .. domain_name .. "}${sofia_contact(" .. sip_from_number .. "@" .. domain_name .. ")}"; + dial_string = "{sip_invite_domain=" .. domain_name .. ",presence_id=" .. user .. "@" .. domain_name .. "}${sofia_contact(" .. (DIAL_STRING_BASED_ON_USERID and sip_from_number or sip_from_user) .. "@" .. domain_name .. ")}"; end --set the an alternative dial string if the hostnames don't match if (load_balancing) then @@ -540,7 +543,7 @@ dbh:release(); --set the cache - local key = "directory:" .. sip_from_number .. "@" .. domain_name + local key = "directory:" .. (DIAL_STRING_BASED_ON_USERID and sip_from_number or sip_from_user) .. "@" .. domain_name if debug['cache'] then freeswitch.consoleLog("notice", "[xml_handler-directory][memcache] set key: " .. key .. "\n") end From d7bc826c308884958abf01eca9edc275581c661c Mon Sep 17 00:00:00 2001 From: Alexey Melnichuk Date: Fri, 21 Aug 2015 17:20:55 +0400 Subject: [PATCH 3/3] Fx. Comment --- .../app/xml_handler/resources/scripts/directory/directory.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/install/scripts/app/xml_handler/resources/scripts/directory/directory.lua b/resources/install/scripts/app/xml_handler/resources/scripts/directory/directory.lua index 6d210bf723..5615058097 100644 --- a/resources/install/scripts/app/xml_handler/resources/scripts/directory/directory.lua +++ b/resources/install/scripts/app/xml_handler/resources/scripts/directory/directory.lua @@ -65,7 +65,7 @@ -- Make sance only for extensions with number_alias -- true - you should register with AuthID=Extension and UserID=Number Alias -- false - you should register with AuthID=UserID=Extension - also in this case you need 2 records in memcache for one extension + -- also in this case you need 2 records in memcache for one extension local DIAL_STRING_BASED_ON_USERID = false local sip_auth_method = params:getHeader("sip_auth_method")