Browse Source

incorporate proper 302 redirect handling

3.12
karl anderson 13 years ago
parent
commit
1165465302
1 changed files with 82 additions and 150 deletions
  1. +82
    -150
      kamailio/kamailio.cfg

+ 82
- 150
kamailio/kamailio.cfg View File

@ -17,9 +17,9 @@
####### Global Parameters ######### ####### Global Parameters #########
fork = yes fork = yes
children = 16
#group =
#user =
children = 25
group = kamailio
user = kamailio
server_signature = no server_signature = no
server_header = "Server: Kazoo" server_header = "Server: Kazoo"
user_agent_header = "User-Agent: Kazoo" user_agent_header = "User-Agent: Kazoo"
@ -158,8 +158,8 @@ modparam("path", "use_received", 0)
######## Generic Hash Table container in shared memory ######## ######## Generic Hash Table container in shared memory ########
loadmodule "htable.so" loadmodule "htable.so"
modparam("htable", "htable", "associations=>size=14;")
modparam("htable", "htable", "a=>size=10;")
modparam("htable", "htable", "associations=>size=10;")
modparam("htable", "htable", "auth_cache=>size=10;")
######## Pseudo-Variables module ######## ######## Pseudo-Variables module ########
loadmodule "pv.so" loadmodule "pv.so"
@ -199,7 +199,7 @@ loadmodule "db_kazoo.so"
# FIXME: uncomment the next line and set the correct hostname that should be advertised to Kazoo # FIXME: uncomment the next line and set the correct hostname that should be advertised to Kazoo
#modparam("db_kazoo", "node_hostname", "kamailio.kazoo.com") #modparam("db_kazoo", "node_hostname", "kamailio.kazoo.com")
# If you want a certain fs_path to be sent Kazoo, uncomment the next line and set the right value # If you want a certain fs_path to be sent Kazoo, uncomment the next line and set the right value
#modparam("db_kazoo", "register_fs_path", "IP:PORT")
#modparam("db_kazoo", "register_fs_path", "127.0.0.1:5060")
####### Authentication Interface module ########## ####### Authentication Interface module ##########
loadmodule "auth.so" loadmodule "auth.so"
@ -235,7 +235,8 @@ modparam("auth_db|usrloc", "db_url", "kazoo://guest:guest@127.0.0.1:5672/callmgr
####### Routing Logic ######## ####### Routing Logic ########
route {
route
{
# log the basic info regarding this call # log the basic info regarding this call
xlog("L_INFO", "$ci|start|recieved $oP request $rm $ou"); xlog("L_INFO", "$ci|start|recieved $oP request $rm $ou");
xlog("L_INFO", "$ci|log|source $si:$sp"); xlog("L_INFO", "$ci|log|source $si:$sp");
@ -244,8 +245,6 @@ route {
route(SANITY_CHECK); route(SANITY_CHECK);
route(SET_LOGGING_FLAGS);
route(CLASSIFY_SOURCE); route(CLASSIFY_SOURCE);
route(HANDLE_OPTIONS); route(HANDLE_OPTIONS);
@ -267,7 +266,8 @@ route {
route(EXTERNAL_TO_INTERNAL_RELAY); route(EXTERNAL_TO_INTERNAL_RELAY);
} }
route[SANITY_CHECK] {
route[SANITY_CHECK]
{
if (!mf_process_maxfwd_header("10")) { if (!mf_process_maxfwd_header("10")) {
xlog("L_WARN", "$ci|end|max-forward limit reached"); xlog("L_WARN", "$ci|end|max-forward limit reached");
sl_send_reply("483", "Too Many Hops"); sl_send_reply("483", "Too Many Hops");
@ -280,25 +280,19 @@ route[SANITY_CHECK] {
} }
} }
route[SET_LOGGING_FLAGS] {
return();
}
route[CLASSIFY_SOURCE] route[CLASSIFY_SOURCE]
{ {
if (ds_is_from_list("1") || ds_is_from_list("3"))
{
if (ds_is_from_list("1") || ds_is_from_list("3")) {
xlog("L_INFO", "$ci|log|originated from internal sources"); xlog("L_INFO", "$ci|log|originated from internal sources");
setflag(FLAG_INTERNALLY_SOURCED); setflag(FLAG_INTERNALLY_SOURCED);
}
else
{
} else {
xlog("L_INFO", "$ci|log|originated from external sources"); xlog("L_INFO", "$ci|log|originated from external sources");
} }
} }
route[HANDLE_OPTIONS] {
route[HANDLE_OPTIONS]
{
if (is_method("OPTIONS")) { if (is_method("OPTIONS")) {
if (isflagset(FLAG_INTERNALLY_SOURCED)) { if (isflagset(FLAG_INTERNALLY_SOURCED)) {
route(INTERNAL_TO_EXTERNAL_RELAY); route(INTERNAL_TO_EXTERNAL_RELAY);
@ -309,30 +303,21 @@ route[HANDLE_OPTIONS] {
} }
} }
# Called on in-dialog requests
# If the request in an Invite for on hold from external to internal,
# associate the contact with the media server
route[MAYBE_ASSOCIATE_USER] {
# if Invite for on hold, we need to associate the contact URI with the next hop
if (is_method("INVITE") && !isflagset(FLAG_INTERNALLY_SOURCED) && is_audio_on_hold()) {
setflag(FLAG_ASSOCIATE_USER);
}
}
route[HANDLE_IN_DIALOG_REQUESTS] {
route[HANDLE_IN_DIALOG_REQUESTS]
{
if (has_totag()) { if (has_totag()) {
if (loose_route()) { if (loose_route()) {
xlog("L_INFO", "$ci|log|loose_route in-dialog message"); xlog("L_INFO", "$ci|log|loose_route in-dialog message");
route(MAYBE_ASSOCIATE_USER);
# Called on in-dialog requests
# If the request in an Invite for on hold from external to internal,
# associate the contact with the media server
# if Invite for on hold, we need to associate the contact URI with the next hop
if (is_method("INVITE") && !isflagset(FLAG_INTERNALLY_SOURCED) && is_audio_on_hold()) {
setflag(FLAG_ASSOCIATE_USER);
}
route(RELAY); route(RELAY);
} else if (isflagset(FLAG_INTERNALLY_SOURCED)) { } else if (isflagset(FLAG_INTERNALLY_SOURCED)) {
xlog("L_INFO", "$ci|log|relay internally sourced in-dialog message without loose_route"); xlog("L_INFO", "$ci|log|relay internally sourced in-dialog message without loose_route");
if(is_method("INVITE")) {
xlog("L_INFO", "$ci|log|re-associate $ci with media server $si:$sp");
}
route(RELAY); route(RELAY);
} else if (t_check_trans()) { } else if (t_check_trans()) {
xlog("L_INFO", "$ci|log|allow message for a known transaction"); xlog("L_INFO", "$ci|log|allow message for a known transaction");
@ -345,7 +330,8 @@ route[HANDLE_IN_DIALOG_REQUESTS] {
} }
} }
route[PREPARE_INITIAL_REQUESTS] {
route[PREPARE_INITIAL_REQUESTS]
{
if (is_method("CANCEL")) { if (is_method("CANCEL")) {
if (t_check_trans()) { if (t_check_trans()) {
route(RELAY); route(RELAY);
@ -368,60 +354,43 @@ route[HANDLE_IN_DIALOG_REQUESTS] {
} }
if (is_method("REGISTER")) { if (is_method("REGISTER")) {
if (nat_uac_test("3")) {
xlog("L_INFO", "Nated contact\n");
#setflag(FLB_NATSIPPING);
force_rport();
setbflag(FLB_NATB);
setbflag(FLB_NATSIPPING);
fix_nated_register();
}
# authenticate requests
# check iif we have the password in cache
if ( is_present_hf("Authorization") ) {
if ( $sht(a=>$Au) != $null ) {
xlog("L_INFO", "Found stored password for $Au, $sht(a=>$Au)\n");
if (!pv_auth_check("$fd", "$sht(a=>$Au)", "0", "0")) {
xlog("L_INFO", "Authentication did not work with stored password\n");
## RABBITMQ - Credentials fetch
if (!auth_check("$fd", "subscriber", "1")) {
auth_challenge("$fd", "0");
exit;
} else {
xlog("Credential fetch $avp(password)\n");
# xlog("au=$au, ad = $ad, aU=$aU, Au= $Au\n");
$sht(a=>$Au) = $avp(password);
}
}
if (is_present_hf("Authorization")) {
if ($sht(auth_cache=>$Au) != $null && pv_auth_check("$fd", "$sht(auth_cache=>$Au)", "0", "0")) {
xlog("L_INFO", "$ci|log|Authenticated $Au via cached SIP creds\n");
} else { } else {
## RABBITMQ - Credentials fetch ## RABBITMQ - Credentials fetch
if (!auth_check("$fd", "subscriber", "1")) { if (!auth_check("$fd", "subscriber", "1")) {
auth_challenge("$fd", "0"); auth_challenge("$fd", "0");
xlog("L_INFO", "$ci|log|Issued new auth challenge to failed registration attempt\n");
exit; exit;
} else { } else {
xlog("L_INFO", "Credential fetch $avp(password)\n");
# xlog("au=$Au, ad = $ad, aU=$aU, Au= $Au\n");
$sht(a=>$Au) = $avp(password);
xlog("$ci|log|Caching SIP credentials for $Au\n");
$sht(auth_cache=>$Au) = $avp(password);
} }
} }
} else { } else {
auth_challenge("$fd", "0"); auth_challenge("$fd", "0");
xlog("L_INFO", "$ci|log|Issued new auth challenge to new registration attempt\n");
exit; exit;
} }
# user authenticated - remove auth header # user authenticated - remove auth header
consume_credentials(); consume_credentials();
if (nat_uac_test("3")) {
xlog("L_INFO", "$ci|log|Correcting NATed contact in registration\n");
force_rport();
setbflag(FLB_NATB);
setbflag(FLB_NATSIPPING);
fix_nated_register();
}
save("location"); save("location");
exit; exit;
} else {
if (!is_method("MESSAGE")) {
} else if (!is_method("MESSAGE")) {
record_route(); record_route();
}
} }
} }
@ -430,8 +399,7 @@ route[HANDLE_IN_DIALOG_REQUESTS] {
route[FIND_ROUTES] route[FIND_ROUTES]
{ {
# alg 0 = hash(Callid) # alg 0 = hash(Callid)
if (!ds_select_dst("1", "0"))
{
if (!ds_select_dst("1", "0")) {
xlog("L_ERR", "$ci|end|no servers avaliable"); xlog("L_ERR", "$ci|end|no servers avaliable");
sl_send_reply("480", "All servers busy"); sl_send_reply("480", "All servers busy");
@ -441,9 +409,7 @@ route[FIND_ROUTES]
# Handle the case when a prefered route is set # Handle the case when a prefered route is set
$var(contact_uri) = @from.uri.user + "@" + @from.uri.host; $var(contact_uri) = @from.uri.user + "@" + @from.uri.host;
if ($sht(associations=>$var(contact_uri)) != $null)
{
if ($sht(associations=>$var(contact_uri)) != $null) {
$var(prefered_route) = $sht(associations=>$var(contact_uri)); $var(prefered_route) = $sht(associations=>$var(contact_uri));
xlog("L_INFO", "$ci|log|should route to $var(prefered_route)"); xlog("L_INFO", "$ci|log|should route to $var(prefered_route)");
@ -452,13 +418,11 @@ route[FIND_ROUTES]
} }
} }
route[REORDER_ROUTES] {
route[REORDER_ROUTES]
{
$var(i) = 0; $var(i) = 0;
$var(found) = 0; $var(found) = 0;
while($(avp(ds_dst)[$var(i)]) != $null)
{
xlog("L_INFO", "$ci|log|IN $var(i): $(avp(ds_dst)[$var(i)])");
while($(avp(ds_dst)[$var(i)]) != $null) {
if($(avp(ds_dst)[$var(i)]) != $var(prefered_route)) { if($(avp(ds_dst)[$var(i)]) != $var(prefered_route)) {
$avp(tmp_ds_dst) = $(avp(ds_dst)[$var(i)]); $avp(tmp_ds_dst) = $(avp(ds_dst)[$var(i)]);
} else { } else {
@ -474,8 +438,7 @@ route[REORDER_ROUTES] {
$(avp(ds_dst)[*]) = $null; $(avp(ds_dst)[*]) = $null;
$var(i) = 0; $var(i) = 0;
while($(avp(tmp_ds_dst)[$var(i)]) != $null)
{
while($(avp(tmp_ds_dst)[$var(i)]) != $null) {
$avp(ds_dst) = $(avp(tmp_ds_dst)[$var(i)]); $avp(ds_dst) = $(avp(tmp_ds_dst)[$var(i)]);
$var(i) = $var(i) + 1; $var(i) = $var(i) + 1;
@ -489,31 +452,20 @@ route[REORDER_ROUTES] {
$sht(associations=>$var(contact_uri)) = $null; $sht(associations=>$var(contact_uri)) = $null;
} }
$var(i) = 0;
while($(avp(ds_dst)[$var(i)]) != $null)
{
xlog("L_INFO", "$ci|log|OUT $var(i): $(avp(ds_dst)[$var(i)])");
$var(i) = $var(i) + 1;
}
} }
route[HANDLE_MOVE_REQUEST] route[HANDLE_MOVE_REQUEST]
{ {
if (is_method("INVITE") && $rU == "*6683*")
{
if (is_method("INVITE") && $rU == "*6683*") {
$var(contact_uri) = @from.uri.user + "@" + @from.uri.host; $var(contact_uri) = @from.uri.user + "@" + @from.uri.host;
if ($sht(associations=>$var(contact_uri)) != $null)
{
if ($sht(associations=>$var(contact_uri)) != $null) {
xlog("L_INFO", "$ci|log|remove association for user $var(contact_uri) xlog("L_INFO", "$ci|log|remove association for user $var(contact_uri)
with media server $sht(associations=>$var(contact_uri))\n"); with media server $sht(associations=>$var(contact_uri))\n");
$sht(associations=>$var(contact_uri)) = $null; $sht(associations=>$var(contact_uri)) = $null;
} }
# TODO - does the test expect smth like $rd:$rp as reason?
send_reply("503", "Removed association"); send_reply("503", "Removed association");
xlog("L_INFO", "$ci|log|removed association for user $var(contact_uri) xlog("L_INFO", "$ci|log|removed association for user $var(contact_uri)
@ -523,7 +475,8 @@ route[HANDLE_MOVE_REQUEST]
} }
} }
route[RELAY] {
route[RELAY]
{
if (isflagset(FLAG_INTERNALLY_SOURCED)) { if (isflagset(FLAG_INTERNALLY_SOURCED)) {
route(INTERNAL_TO_EXTERNAL_RELAY); route(INTERNAL_TO_EXTERNAL_RELAY);
} else { } else {
@ -533,7 +486,8 @@ route[RELAY] {
exit(); exit();
} }
route[INTERNAL_TO_EXTERNAL_RELAY] {
route[INTERNAL_TO_EXTERNAL_RELAY]
{
remove_hf("X-AUTH-IP"); remove_hf("X-AUTH-IP");
t_on_reply("EXTERNAL_REPLY"); t_on_reply("EXTERNAL_REPLY");
@ -543,7 +497,8 @@ route[INTERNAL_TO_EXTERNAL_RELAY] {
t_relay(); t_relay();
} }
route[EXTERNAL_TO_INTERNAL_RELAY] {
route[EXTERNAL_TO_INTERNAL_RELAY]
{
if (!isflagset(FLAG_INTERNALLY_SOURCED)) { if (!isflagset(FLAG_INTERNALLY_SOURCED)) {
route(NAT_TEST_AND_CORRECT); route(NAT_TEST_AND_CORRECT);
} }
@ -559,7 +514,8 @@ route[EXTERNAL_TO_INTERNAL_RELAY] {
t_relay(); t_relay();
} }
route[LOG_DESTINATION] {
route[LOG_DESTINATION]
{
if (isdsturiset()) { if (isdsturiset()) {
$var(port) = $dp; $var(port) = $dp;
$var(domain) = $dd; $var(domain) = $dd;
@ -575,7 +531,8 @@ route[LOG_DESTINATION] {
xlog("L_INFO", "$ci|pass|$var(domain):$var(port)"); xlog("L_INFO", "$ci|pass|$var(domain):$var(port)");
} }
route[NAT_TEST_AND_CORRECT] {
route[NAT_TEST_AND_CORRECT]
{
if (is_present_hf("Record-Route")) { if (is_present_hf("Record-Route")) {
$var(i) = $rr_count; $var(i) = $rr_count;
while($var(i) > 0) { while($var(i) > 0) {
@ -603,7 +560,8 @@ route[NAT_TEST_AND_CORRECT] {
} }
} }
onreply_route[EXTERNAL_REPLY] {
onreply_route[EXTERNAL_REPLY]
{
xlog("L_INFO", "$ci|log|external reply $T_reply_code"); xlog("L_INFO", "$ci|log|external reply $T_reply_code");
route(NAT_TEST_AND_CORRECT); route(NAT_TEST_AND_CORRECT);
@ -615,29 +573,26 @@ onreply_route[INTERNAL_REPLY]
xlog("L_INFO", "$ci|start|recieved internal reply $T_reply_code $rr"); xlog("L_INFO", "$ci|start|recieved internal reply $T_reply_code $rr");
xlog("L_INFO", "$ci|log|source $si:$sp"); xlog("L_INFO", "$ci|log|source $si:$sp");
if ($rs < 300)
{
if ($rs < 300) {
xlog("L_INFO", "$ci|pass|$T_req($si):$T_req($sp)"); xlog("L_INFO", "$ci|pass|$T_req($si):$T_req($sp)");
} }
# change 6xx to 4xx # change 6xx to 4xx
if (t_check_status("6[0-9][0-9]"))
{
if (t_check_status("6[0-9][0-9]")) {
$var(new_code) = "4" + $(T_reply_code{s.substr,1,0}); $var(new_code) = "4" + $(T_reply_code{s.substr,1,0});
change_reply_status("$var(new_code)", "$rr"); change_reply_status("$var(new_code)", "$rr");
} }
} }
failure_route[INTERNAL_FAULT]
failure_route[INTERNAL_FAULT]
{ {
# this branch handles failures (>=300) to our media servers, # this branch handles failures (>=300) to our media servers,
# which we can sometimes overcome by routing to another server # which we can sometimes overcome by routing to another server
# if the failure cause was due to the transaction being # if the failure cause was due to the transaction being
# cancelled then we are complete # cancelled then we are complete
if (t_is_canceled())
{
if (t_is_canceled()) {
xlog("L_INFO", "$ci|log|transaction was cancelled"); xlog("L_INFO", "$ci|log|transaction was cancelled");
exit; exit;
@ -645,14 +600,11 @@ failure_route[INTERNAL_FAULT]
# if the failure case was something that we should recover # if the failure case was something that we should recover
# from then try to find a new media server # from then try to find a new media server
if (t_check_status("(401)|(407)"))
{
if (t_check_status("(401)|(407)")) {
xlog("L_INFO", "$ci|log|failure route ignoring auth reply $T_reply_code $rr"); xlog("L_INFO", "$ci|log|failure route ignoring auth reply $T_reply_code $rr");
exit; exit;
}
else if (t_check_status("403"))
{
} else if (t_check_status("403")) {
xlog("L_INFO", "$ci|log|failure route overriding reply code 403 with 503"); xlog("L_INFO", "$ci|log|failure route overriding reply code 403 with 503");
xlog("L_INFO", "$ci|pass|$si:$sp"); xlog("L_INFO", "$ci|pass|$si:$sp");
@ -660,9 +612,7 @@ failure_route[INTERNAL_FAULT]
send_reply("503", "Error: Services Unavailable. Try Later"); send_reply("503", "Error: Services Unavailable. Try Later");
exit; exit;
}
else if (t_check_status("402"))
{
} else if (t_check_status("402")) {
xlog("L_INFO", "$ci|log|failure route overriding reply code 402 with 486"); xlog("L_INFO", "$ci|log|failure route overriding reply code 402 with 486");
xlog("L_INFO", "$ci|pass|$si:$sp"); xlog("L_INFO", "$ci|pass|$si:$sp");
@ -670,14 +620,11 @@ failure_route[INTERNAL_FAULT]
send_reply("486", "Insufficient Funds"); send_reply("486", "Insufficient Funds");
exit; exit;
}
else if (t_check_status("(4[0-9][0-9])|(5[0-9][0-9])"))
{
} else if (t_check_status("(4[0-9][0-9])|(5[0-9][0-9])")) {
xlog("L_INFO", "$ci|start|received failure reply $T_reply_code $rr"); xlog("L_INFO", "$ci|start|received failure reply $T_reply_code $rr");
# try to find a new media server to send the call to # try to find a new media server to send the call to
if ($avp(route_attempts) < 3 && ds_next_domain())
{
if ($avp(route_attempts) < 3 && ds_next_domain()) {
xlog("L_INFO", "$ci|log|attempting retry $avp(route_attempts) of failed request"); xlog("L_INFO", "$ci|log|attempting retry $avp(route_attempts) of failed request");
xlog("L_INFO", "$ci|log|routing call to next media server $rd:$rp"); xlog("L_INFO", "$ci|log|routing call to next media server $rd:$rp");
@ -692,48 +639,33 @@ failure_route[INTERNAL_FAULT]
route(EXTERNAL_TO_INTERNAL_RELAY); route(EXTERNAL_TO_INTERNAL_RELAY);
$avp(route_attempts) = $avp(route_attempts) + 1; $avp(route_attempts) = $avp(route_attempts) + 1;
}
else if (t_check_status("404"))
{
} else if (t_check_status("404")) {
xlog("L_ERR", "$ci|log|no other media servers avaliable, sending 486"); xlog("L_ERR", "$ci|log|no other media servers avaliable, sending 486");
send_reply("486", "Not found"); send_reply("486", "Not found");
exit; exit;
}
else
{
} else {
xlog("L_ERR", "$ci|log|no other media servers avaliable"); xlog("L_ERR", "$ci|log|no other media servers avaliable");
exit; exit;
} }
}
else if (t_check_status("302"))
{
} else if (t_check_status("302")) {
## TODO - test this ## TODO - test this
## get_redirects("*"); ## get_redirects("*");
/*
if(@msg.header["X-Redirect-Server"] != $null)
{
$var(test) = @msg.header["X-Redirect-Server"].value;
xlog("L_INFO", "$ci|log|X-Redirect-Server $var(test)");
$var(contact_uri) = $(ct{tobody.user}) + "@" + $(ct{tobody.host});
$var(redirect_host) = $(hdr(X-Redirect-Server){uri.host});
$var(redirect_port) = $(hdr(X-Redirect-Server){uri.port});
if($T_rpl($hdr(X-Redirect-Server)) != $null) {
$var(contact_uri) = @from.uri.user + "@" + @from.uri.host;
$sht(associations=>$var(contact_uri))= "sip:$var(redirect_host):$var(redirect_port)";
$sht(associations=>$var(contact_uri)) = $T_rpl($hdr(X-Redirect-Server));
xlog("L_INFO", "$ci|log|stored redirect mapping for $var(contact_uri) to sip:$var(redirect_host):$var(redirect_port)");
xlog("L_INFO", "$ci|log|stored redirect mapping for $var(contact_uri) to $T_rpl($hdr(X-Redirect-Server))");
remove_hf("X-Redirect-Server"); remove_hf("X-Redirect-Server");
} }
*/
}
else
{
route(EXTERNAL_TO_INTERNAL_RELAY);
} else {
xlog("L_INFO", "$ci|log|failure route ignoring reply $T_reply_code $rr"); xlog("L_INFO", "$ci|log|failure route ignoring reply $T_reply_code $rr");
exit; exit;


Loading…
Cancel
Save