| @ -1,306 +0,0 @@ | |||||
| ### DISPATCHER ROLE #### | |||||
| #!trydef KZ_DISPATCHER_PROBE_MODE 1 | |||||
| #!trydef DISPATCHER_ADD_SERVERS 1 | |||||
| #!trydef DISPATCHER_ADD_SECONDARY_IP 1 | |||||
| #!trydef DISPATCHER_SECONDARY_IP_GROUP 3 | |||||
| #!trydef DISPATCHER_ALG 0 | |||||
| #!trydef KZ_DISPATCHER_HASH_SIZE 8 | |||||
| #!trydef KZ_DISPATCHER_ADD_FLAGS 9 | |||||
| #!trydef KZ_DISPATCHER_PRIMARY_GROUP 1 | |||||
| #!trydef KZ_DISPATCHER_SECONDARY_GROUP 2 | |||||
| #!trydef KZ_DISPATCHER_CLASSIFY_GROUP 3 | |||||
| #!trydef KZ_DISPATCHER_ALTNET1_PRIMARY_GROUP 51 | |||||
| #!trydef KZ_DISPATCHER_ALTNET1_SECONDARY_GROUP 52 | |||||
| #!trydef KZ_DISPATCHER_ALTNET2_PRIMARY_GROUP 53 | |||||
| #!trydef KZ_DISPATCHER_ALTNET2_SECONDARY_GROUP 54 | |||||
| #!trydef KZ_DISPATCHER_PRESENCE_PRIMARY_GROUP 10 | |||||
| #!trydef KZ_DISPATCHER_PRESENCE_SECONDARY_GROUP 11 | |||||
| #!trydef KZ_DISPATCHER_REGISTRAR_PRIMARY_GROUP 20 | |||||
| #!trydef KZ_DISPATCHER_REGISTRAR_SECONDARY_GROUP 21 | |||||
| #!trydef KZ_DISPATCHER_MAX_RETRIES 2 | |||||
| #!trydef KZ_DISPATCHER_ROUTE_ASSOCIATED_MEDIA 1 | |||||
| #!trydef KZ_DISPATCHER_CLASSIFY_FLAGS 2 | |||||
| kazoo.dispatcher_auto_add = DISPATCHER_ADD_SERVERS descr "adds media servers reported by ecallmgr" | |||||
| kazoo.dispatcher_add_secondary_ip = DISPATCHER_ADD_SECONDARY_IP descr "adds internal ip from media servers reported by ecallmgr" | |||||
| kazoo.dispatcher_add_secondary_ip_group = DISPATCHER_SECONDARY_IP_GROUP descr "sets the group where to add internal ip from media servers reported by ecallmgr" | |||||
| kazoo.dispatcher_algorithm = DISPATCHER_ALG descr "dispatcher algorithm to use" | |||||
| kazoo.dispatcher_primary_group = KZ_DISPATCHER_PRIMARY_GROUP descr "dispatcher primary group" | |||||
| kazoo.dispatcher_secondary_group = KZ_DISPATCHER_SECONDARY_GROUP descr "dispatcher secondary group" | |||||
| kazoo.dispatcher_max_retries = KZ_DISPATCHER_MAX_RETRIES descr "max number of retries for media servers" | |||||
| kazoo.dispatcher_route_to_associated_media = KZ_DISPATCHER_ROUTE_ASSOCIATED_MEDIA descr "routes to associated media for atxfer" | |||||
| kazoo.dispatcher_classify_flags = KZ_DISPATCHER_CLASSIFY_FLAGS descr "dispatch classifier flags" | |||||
| ####### Dispatcher module ######## | |||||
| loadmodule "dispatcher.so" | |||||
| modparam("dispatcher", "db_url", "KAZOO_DB_URL") | |||||
| modparam("dispatcher", "flags", 2) | |||||
| modparam("dispatcher", "use_default", 0) | |||||
| modparam("dispatcher", "force_dst", 1) | |||||
| modparam("dispatcher", "dst_avp", "$avp(ds_dst)") | |||||
| modparam("dispatcher", "attrs_avp", "$avp(ds_attrs)") | |||||
| modparam("dispatcher", "grp_avp", "$avp(ds_grp)") | |||||
| modparam("dispatcher", "cnt_avp", "$avp(ds_cnt)") | |||||
| modparam("dispatcher", "hash_pvar", "$avp(ds_grp)") | |||||
| modparam("dispatcher", "ds_hash_size", KZ_DISPATCHER_HASH_SIZE) | |||||
| modparam("dispatcher", "setid_pvname", "$var(setid)") | |||||
| modparam("dispatcher", "attrs_pvname", "$var(attrs)") | |||||
| modparam("dispatcher", "ds_ping_method", "OPTIONS") | |||||
| modparam("dispatcher", "ds_ping_interval", 10) | |||||
| modparam("dispatcher", "ds_probing_threshold", 3) | |||||
| modparam("dispatcher", "ds_probing_mode", KZ_DISPATCHER_PROBE_MODE) | |||||
| modparam("dispatcher", "ds_ping_reply_codes", "501,403,404,400,200") | |||||
| modparam("dispatcher", "ds_ping_from", "sip:sipcheck@MY_HOSTNAME") | |||||
| #!import_file "dispatcher-network-params.cfg" | |||||
| ## Dispatcher Groups: | |||||
| ## 1 - Primary media servers | |||||
| ## 2 - Backup media servers | |||||
| ## 3 - Alternate media server IPs (used only for classification) | |||||
| ## 10 - Presence servers (if not locally handled) | |||||
| ## 20 - Registrar servers (if not locally handled) | |||||
| modparam("rtimer", "timer", "name=dispatcher_reload;interval=20;mode=1;") | |||||
| modparam("rtimer", "exec", "timer=dispatcher_reload;route=DISPATCHER_RELOAD") | |||||
| ####### Dispatcher Logic ######## | |||||
| route[DISPATCHER_CLASSIFY_SOURCE] | |||||
| { | |||||
| #!import_file "dispatcher-network-classify.cfg" | |||||
| if (is_myself("$ou")) { | |||||
| xlog("$var(log_request_level)", "$ci|log|original R-URI ($ou) is this proxy, treating as external sources\n"); | |||||
| } else { | |||||
| $var(classify_dispatcher_flag) = $(sel(cfg_get.kazoo.dispatcher_classify_flags){s.int}); | |||||
| if (ds_is_from_list(KZ_DISPATCHER_PRIMARY_GROUP, "$var(classify_dispatcher_flag)") || | |||||
| ds_is_from_list(KZ_DISPATCHER_SECONDARY_GROUP, "$var(classify_dispatcher_flag)") || | |||||
| ds_is_from_list(KZ_DISPATCHER_CLASSIFY_GROUP, "$var(classify_dispatcher_flag)") || | |||||
| ds_is_from_list(KZ_DISPATCHER_ALTNET1_PRIMARY_GROUP, "$var(classify_dispatcher_flag)") || | |||||
| ds_is_from_list(KZ_DISPATCHER_ALTNET1_SECONDARY_GROUP, "$var(classify_dispatcher_flag)") || | |||||
| ds_is_from_list(KZ_DISPATCHER_ALTNET2_PRIMARY_GROUP, "$var(classify_dispatcher_flag)") || | |||||
| ds_is_from_list(KZ_DISPATCHER_ALTNET2_SECONDARY_GROUP, "$var(classify_dispatcher_flag)") || | |||||
| ds_is_from_list(KZ_DISPATCHER_PRESENCE_PRIMARY_GROUP, "$var(classify_dispatcher_flag)") || | |||||
| ds_is_from_list(KZ_DISPATCHER_PRESENCE_SECONDARY_GROUP, "$var(classify_dispatcher_flag)") || | |||||
| ds_is_from_list(KZ_DISPATCHER_REGISTRAR_PRIMARY_GROUP, "$var(classify_dispatcher_flag)") || | |||||
| ds_is_from_list(KZ_DISPATCHER_REGISTRAR_SECONDARY_GROUP, "$var(classify_dispatcher_flag)")) { | |||||
| xlog("$var(log_request_level)", "$ci|log|originated from internal sources\n"); | |||||
| setflag(FLAG_INTERNALLY_SOURCED); | |||||
| } else { | |||||
| xlog("$var(log_request_level)", "$ci|log|originated from external sources\n"); | |||||
| } | |||||
| } | |||||
| } | |||||
| # Take the routes from dispatcher - hash over callid | |||||
| # If prefered route defined, reorder the destionations | |||||
| route[DISPATCHER_FIND_ROUTES] | |||||
| { | |||||
| $var(ds_primary_group) = $sel(cfg_get.kazoo.dispatcher_primary_group); | |||||
| $var(ds_backup_group) = $sel(cfg_get.kazoo.dispatcher_secondary_group); | |||||
| #!ifndef PRESENCE_ROLE | |||||
| if (is_method("SUBSCRIBE")) { | |||||
| $var(ds_primary_group) = KZ_DISPATCHER_PRESENCE_PRIMARY_GROUP; | |||||
| $var(ds_backup_group) = KZ_DISPATCHER_PRESENCE_SECONDARY_GROUP; | |||||
| add_path(); | |||||
| } | |||||
| #!endif | |||||
| #!ifndef REGISTRAR_ROLE | |||||
| if (is_method("REGISTER")) { | |||||
| $var(ds_primary_group) = KZ_DISPATCHER_REGISTRAR_PRIMARY_GROUP; | |||||
| $var(ds_backup_group) = KZ_DISPATCHER_REGISTRAR_SECONDARY_GROUP; | |||||
| add_path(); | |||||
| } | |||||
| #!endif | |||||
| #!ifdef PRESENCE_ROLE | |||||
| route(PRESENCE_FAST_PICKUP_ATTEMPT); | |||||
| #!endif | |||||
| #!import_file "dispatcher-network-find.cfg" | |||||
| $var(ds_group) = $var(ds_primary_group); | |||||
| if (!ds_select_dst("$var(ds_primary_group)", "$sel(cfg_get.kazoo.dispatcher_algorithm)") || $(avp(ds_dst)[0]) == $null) { | |||||
| # we selected from primary group, try again in backup group | |||||
| if (!ds_select_dst("$var(ds_backup_group)", "$sel(cfg_get.kazoo.dispatcher_algorithm)") || $(avp(ds_dst)[0]) == $null) { | |||||
| xlog("L_WARN", "$ci|end|no servers available in primary or backup group\n"); | |||||
| sl_send_reply("480", "All servers busy"); | |||||
| exit; | |||||
| } else { | |||||
| $var(ds_group) = $var(ds_backup_group); | |||||
| } | |||||
| } | |||||
| $var(user_source) = $(ct{tobody.user}) + "@" + $si + ":" + $sp; | |||||
| if ($sht(associations=>$var(user_source)) != $null) { | |||||
| if($sel(cfg_get.kazoo.dispatcher_route_to_associated_media) == 1) { | |||||
| $var(prefered_route) = $sht(associations=>$var(user_source)); | |||||
| xlog("L_INFO", "$ci|route|found association for contact uri $var(user_source)\n"); | |||||
| route(DISPATCHER_PREFERRED_ROUTE); | |||||
| } | |||||
| $sht(associations=>$var(user_source)) = $null; | |||||
| } | |||||
| $avp(ds_retries) = 0; | |||||
| } | |||||
| route[DISPATCHER_PREFERRED_ROUTE] | |||||
| { | |||||
| ###### | |||||
| # check if the preferred route is active | |||||
| ###### | |||||
| if(!ds_is_from_list(-1, 6, "$var(prefered_route)")) { | |||||
| xlog("L_INFO", "$ci|log|associated media server $var(prefered_route) is inactive, moving to $avp(ds_dst)\n"); | |||||
| return -1; | |||||
| } | |||||
| xlog("L_INFO", "$ci|log|re-ordering the dispatcher list to maintain association with $var(prefered_route)\n"); | |||||
| ###### | |||||
| # filters current list from prefered route | |||||
| # * saves the current list to temp avp removing the preferred route if it exists | |||||
| # * resets current list | |||||
| # * copies the temp back to list | |||||
| # sets the prefered at top | |||||
| # sets $du (destination) to prefered | |||||
| ###### | |||||
| $var(i) = 0; | |||||
| while($(avp(ds_dst)[$var(i)]) != $null) { | |||||
| if($(avp(ds_dst)[$var(i)]) != $var(prefered_route)) { | |||||
| $avp(tmp_ds_dst) = $(avp(ds_dst)[$var(i)]); | |||||
| } | |||||
| $var(i) = $var(i) + 1; | |||||
| } | |||||
| $(avp(ds_dst)[*]) = $null; | |||||
| $var(i) = 0; | |||||
| while($(avp(tmp_ds_dst)[$var(i)]) != $null) { | |||||
| $avp(ds_dst) = $(avp(tmp_ds_dst)[$var(i)]); | |||||
| $var(i) = $var(i) + 1; | |||||
| } | |||||
| $avp(ds_dst) = $var(prefered_route); | |||||
| $du = $var(prefered_route); | |||||
| $(avp(tmp_ds_dst)[*]) = $null; | |||||
| return 1; | |||||
| } | |||||
| route[DISPATCHER_NEXT_ROUTE] | |||||
| { | |||||
| if($avp(ds_retries) >= $sel(cfg_get.kazoo.dispatcher_max_retries)) return; | |||||
| $avp(ds_retries) = $avp(ds_retries) + 1; | |||||
| $var(remaining) = $(sel(cfg_get.kazoo.dispatcher_max_retries){s.int}) - $avp(ds_retries); | |||||
| if(ds_next_dst()) { | |||||
| xlog("L_INFO", "$ci|log|remaining failed retry attempts: $var(remaining)\n"); | |||||
| xlog("L_INFO", "$ci|log|routing call to next media server $du\n"); | |||||
| setflag(FLAG_SKIP_NAT_CORRECTION); | |||||
| # reset the final reply timer | |||||
| $avp(final_reply_timer) = 3; | |||||
| # relay the request to the new media server | |||||
| route(RELAY); | |||||
| exit(); | |||||
| } | |||||
| } | |||||
| event_route[dispatcher:dst-down] | |||||
| { | |||||
| xlog("L_WARNING", "Destination down: $ru\n"); | |||||
| } | |||||
| event_route[dispatcher:dst-up] | |||||
| { | |||||
| xlog("L_NOTICE", "Destination up: $ru\n"); | |||||
| } | |||||
| route[DISPATCHER_CHECK_MEDIA_SERVER] | |||||
| { | |||||
| $var(check_media_server_ret) = 0; | |||||
| if($sel(cfg_get.kazoo.dispatcher_auto_add) == 1) { | |||||
| $var(SetId) = 1; | |||||
| if($var(Zone) != "MY_AMQP_ZONE") { | |||||
| $var(SetId) = 2; | |||||
| } | |||||
| $var(flags) = KZ_DISPATCHER_ADD_FLAGS; | |||||
| $var(attrs) = $_s(zone=$var(Zone);profile=$var(MediaProfile);duid=$(var(MediaUrl){s.corehash, MEDIA_SERVERS_HASH_SIZE});node=$var(MediaName)); | |||||
| #!import_file "dispatcher-custom-media-check.cfg" | |||||
| sql_query("exec", "KZQ_CHECK_MEDIA_SERVER_INSERT"); | |||||
| if($sqlrows(exec) > 0) { | |||||
| $shv(dispatcher_reload) = 1; | |||||
| $var(check_media_server_ret) = 1; | |||||
| } | |||||
| if($sel(cfg_get.kazoo.dispatcher_add_secondary_ip) == 1) { | |||||
| if($var(MediaIP) != "" && $var(MediaIP) != $(var(MediaUrl){uri.host})) { | |||||
| $var(MediaUrlBack) = $var(MediaUrl); | |||||
| $var(MediaUrl) = $_s($(var(MediaUrlBack){uri.scheme}):$var(MediaIP):$(var(MediaUrlBack){uri.port})); | |||||
| $var(attrs) = $_s(zone=$var(Zone);profile=$var(MediaProfile);duid=$(var(MediaUrl){s.corehash, MEDIA_SERVERS_HASH_SIZE});node=$var(MediaName)); | |||||
| $var(SetId) = $sel(cfg_get.kazoo.dispatcher_add_secondary_ip_group); | |||||
| sql_query("exec", "KZQ_CHECK_MEDIA_SERVER_INSERT"); | |||||
| if($sqlrows(exec) > 0) { | |||||
| $shv(dispatcher_reload) = 1; | |||||
| $var(check_media_server_ret) = 1; | |||||
| } | |||||
| $var(MediaUrl) = $var(MediaUrlBack); | |||||
| } | |||||
| } | |||||
| } | |||||
| return $var(check_media_server_ret); | |||||
| } | |||||
| route[DISPATCHER_RELOAD] | |||||
| { | |||||
| if($shv(dispatcher_reload) == 1) { | |||||
| xlog("L_NOTICE", "reloading dispatcher table\n"); | |||||
| ds_reload(); | |||||
| }; | |||||
| $shv(dispatcher_reload) = 0; | |||||
| } | |||||
| route[DISPATCHER_STATUS] | |||||
| { | |||||
| jsonrpc_exec('{"jsonrpc": "2.0", "method": "dispatcher.list", "id": 1}'); | |||||
| $var(Sets) = $(jsonrpl(body){kz.json, result.NRSETS}); | |||||
| $var(i) = 0; | |||||
| $var(ds_groups_json)=""; | |||||
| $var(Sep1) = ""; | |||||
| while($var(i) < $var(Sets)) { | |||||
| $var(Set) = $(jsonrpl(body){kz.json, result.RECORDS[$var(i)].SET}); | |||||
| $var(SetCount) = $(var(Set){kz.json.count,TARGETS}); | |||||
| $var(Sep2)=""; | |||||
| $var(ds_group_json)=""; | |||||
| $var(c) = 0; | |||||
| while($var(c) < $var(SetCount)) { | |||||
| $var(Dest) = $(var(Set){kz.json,TARGETS[$var(c)].DEST}); | |||||
| $var(record) = $_s("$(var(Dest){kz.json,URI})" : {"destination" : "$(var(Dest){kz.json,URI})", "flags" : "$(var(Dest){kz.json,FLAGS})", "priority" : $(var(Dest){kz.json,PRIORITY}), "attrs" : "$(var(Dest){kz.json,ATTRS.BODY})"}); | |||||
| $var(ds_group_json) = $var(ds_group_json) + $var(Sep2) + $var(record); | |||||
| $var(Sep2) = ","; | |||||
| $var(c) = $var(c) + 1; | |||||
| } | |||||
| $var(ds_groups_json) = $var(ds_groups_json) + $var(Sep1) + $_s("$(var(Set){kz.json,ID})" : { $var(ds_group_json) }); | |||||
| $var(Sep1)=", "; | |||||
| $var(i) = $var(i) + 1; | |||||
| } | |||||
| } | |||||
| # vim: tabstop=4 softtabstop=4 shiftwidth=4 expandtab | |||||