I am using the latest version of Kamailio, but I am unsure what the problem is. My configuration does not handle the CANCEL request correctly, and it returns an error.
`#!KAMAILIO
#!define WITH_MYSQL
#!define SHM_MEMORY 64

debug=2
log_stderror=no
log_facility=LOG_LOCAL0

mpath="/usr/lib/x86_64-linux-gnu/kamailio/modules/"

loadmodule "permissions.so"
loadmodule "tm.so"
loadmodule "sl.so"
loadmodule "rr.so"
loadmodule "pv.so"
loadmodule "dispatcher.so"
loadmodule "db_mysql.so"
loadmodule "siputils.so"
loadmodule "textops.so"
loadmodule "maxfwd.so"
loadmodule "xlog.so"
loadmodule "ctl.so"
loadmodule "cfgutils.so"
loadmodule "htable.so"
loadmodule "timer.so"
loadmodule "sqlops.so"

listen=udp::5060
alias=:5060

Database connection parameters

modparam("sqlops", "sqlcon", "ca=>mysql://kamailio:@/development")
modparam("permissions", "db_url", "mysql://kamailio@/development")
modparam("permissions", "address_table", "address")
modparam("permissions", "peer_tag_avp", "$avp(tag)")

modparam("dispatcher", "db_url", "mysql://kamailio:@/development")
modparam("dispatcher", "ds_hash_size", 2048)
modparam("dispatcher", "table_name", "dispatcher")
modparam("dispatcher", "flags", 0)
modparam("dispatcher", "force_dst", 1)

Configure hash tables

modparam("htable", "htable", "clientLimits=>size=64;autoexpire=300")
modparam("htable", "htable", "clientCalls=>size=64;autoexpire=60")

modparam("ctl", "binrpc", "unix:/var/run/kamailio/kamailio_ctl")

modparam("cfgutils", "lock_set_size", 14)

Transaction Module Parameters

modparam("tm", "fr_inv_timer", 180000)
modparam("tm", "fr_timer", 60000)
modparam("tm", "restart_fr_on_each_reply", 1)
modparam("tm", "auto_inv_100", 1)

Timer for refreshing limits

modparam("timer", "declare_timer", "LIMITS_TIMER=refresh_limits,300,slow,enable")
modparam("timer", "declare_timer", "CLEANUP_TIMER=cleanup_calls,60,slow,enable")

request_route {
if (is_method("CANCEL")) {
xlog("L_INFO", "Received CANCEL request for $ci - Method: $rm - R-URI: $ru\n");

    if (!t_check_trans()) {
        xlog("L_INFO", "No transaction found with t_check_trans(), trying t_lookup_cancel()\n");
        # Try to find the transaction using branch and Call-ID
        $var(branch) = $(hdr(Via){param.value,branch});
        if (!t_lookup_cancel()) {
            xlog("L_WARN", "No transaction found for CANCEL - $ci with branch $var(branch)\n");
            sl_reply("481", "Call Leg/Transaction Does Not Exist");
            exit;
        }
        xlog("L_INFO", "Found transaction using t_lookup_cancel()\n");
    }

    # Extract destination from original request
    if ($ru != "") {
        $du = $ru;
        xlog("L_INFO", "Setting destination from R-URI: $du\n");
    } else {
        xlog("L_WARN", "No R-URI found for CANCEL\n");
    }
    
    # Add debugging
    xlog("L_INFO", "Forwarding CANCEL to $du for call $ci\n");
    
    if (ds_is_from_list()) {
        ds_load_unset();
        xlog("L_INFO", "Unset dispatcher load for destination\n");
    }

    # Handle the client ID and call counting
    if (is_present_hf("X-VICIdial-Client-Id")) {
        $var(client_id) = $(hdr(X-VICIdial-Client-Id));
        if ($var(client_id) =~ "^(CID_[0-9]+)-[a-z]$") {
            $var(parent_id) = $(var(client_id){re.subst,/^(CID_[0-9]+)-[a-z]$/\1/});
        } else {
            $var(parent_id) = $var(client_id);
        }

        if($var(parent_id) != $null) {
            lock("calls_$var(parent_id)");
            if($sht(clientCalls=>$var(parent_id)) > 0) {
                $sht(clientCalls=>$var(parent_id)) = $sht(clientCalls=>$var(parent_id)) - 1;
                xlog("L_INFO", "CANCEL: Decremented call count for $var(parent_id) to $sht(clientCalls=>$var(parent_id))\n");
            }
            unlock("calls_$var(parent_id)");
        }
    }

    # Send 200 OK response for the CANCEL
    t_reply("200", "OK");
    
    # Force the relay of CANCEL to the destination
    t_relay();
    exit;
}

if(is_method("BYE")) {
    if((!allow_source_address("1") && !ds_is_from_list())) {
        xlog("L_WARN", "IP $si:$sp not in address or dispatcher list\n");
        sl_send_reply("403", "IP Not Allowed");
        exit;
    }
    route(RELAY);
    exit;
}
if (!allow_source_address("1") ) {
    xlog("L_WARN", "IP $si:$sp not allowed\n");
    sl_send_reply("403", "IP Not Allowed");
    exit;
}
if (is_method("ACK")) {
    if (t_check_trans()) {
        t_relay();
    } else {
        route(RELAY);
    }
    exit;
}
if (is_method("OPTIONS")) {
    options_reply();
    exit;
}

if (!mf_process_maxfwd_header("10")) {
    sl_send_reply("483", "Too Many Hops");
    exit;
}

if (is_method("INVITE")) {
    if (!is_present_hf("X-VICIdial-Client-Id")) {
        xlog("L_WARN", "INVITE received without X-VICIdial-Client-Id header\n");
        sl_send_reply("400", "Bad Request - Missing Client ID");
        exit;
    }

    t_check_trans();
    $var(client_id) = $(hdr(X-VICIdial-Client-Id));

    if ($var(client_id) =~ "^(CID_[0-9]+)-[a-z]$") {
        $var(parent_id) = $(var(client_id){re.subst,/^(CID_[0-9]+)-[a-z]$/\1/});
    } else {
        $var(parent_id) = $var(client_id);
    }
    $var(limit) = $sht(clientLimits=>$var(parent_id));
    if(!$var(limit)) {
        xlog("L_WARN", "No limit configured for client $var(parent_id)\n");
        sl_send_reply("403", "Client Not Configured");
        exit;
    }
    lock("calls_$var(parent_id)");
    $var(current_calls) = $sht(clientCalls=>$var(parent_id));
    if(!$var(current_calls)) {
        $var(current_calls) = 0;
    }
    if($var(current_calls) >= $var(limit)) {
        unlock("calls_$var(parent_id)");
        xlog("L_WARN", "Call limit exceeded for client $var(parent_id): $var(current_calls)/$var(limit)\n");
        sl_send_reply("429", "Concurrent Call Limit Exceeded");
        exit;
    }
    $sht(clientCalls=>$var(parent_id)) = $var(current_calls) + 1;
    unlock("calls_$var(parent_id)");
    route(GENERATE_SERIAL_NUMBER);
    # xlog("L_INFO", "Processing INVITE - checking load - Serial Number: $avp(serial_number)\n");
    $var(original_contact) = $ct;
    append_hf("X-Original-Contact: $var(original_contact)\r\n");
    append_hf("X-Original-IP: $si\r\n");
    append_hf("X-Original-Port: $sp\r\n");
    append_hf("X-Serial-Number: $avp(serial_number)\r\n");

    if (!ds_select_dst("4", "10")) {
        xlog("L_WARN", "All destinations at max load, forwarding to dump server\n");
        $du = "sip::5060";
        record_route();
        route(RELAY);
        exit;
    }

    xlog("L_INFO", "Selected destination: $du\n");
    record_route();
    ds_load_update();
    t_on_failure("MANAGE_FAILURE");
    route(RELAY);
    exit;
}

if (is_method("BYE")) {
    t_check_trans();
    if($sht(clientCalls=>$var(parent_id)) > 0) {
        $sht(clientCalls=>$var(parent_id)) = $sht(clientCalls=>$var(parent_id)) - 1;
    }
    if (ds_is_from_list()) {
        ds_load_unset();
    }
    route(RELAY);
    exit;
}

route(RELAY);

}

route[GENERATE_SERIAL_NUMBER] {
$var(seconds) = $Ts;
$var(microseconds) = $TV(u);
$var(server_number) = "01";
$var(seconds_str) = "" + $var(seconds);
$var(truncated_seconds) = $(var(seconds_str){s.substr,2,0});
$var(milliseconds_full) = "" + $var(microseconds);
$var(milliseconds) = $(var(milliseconds_full){s.striptail,3});
if ($var(milliseconds) < 100) {
if ($var(milliseconds) < 10) {
$var(milliseconds_str) = "00" + $var(milliseconds);
} else {
$var(milliseconds_str) = "0" + $var(milliseconds);
}
} else {
$var(milliseconds_str) = "" + $var(milliseconds);
}
$var(random) = $RANDOM;
if ($var(random) < 10) {
$var(random_padded) = "0" + $var(random);
} else {
$var(random_str) = "" + $var(random);
$var(random_padded) = $(var(random_str){s.substr,-2,0});
}
$var(serial_number) = $var(truncated_seconds) + $var(milliseconds_str) + $var(server_number) + $var(random_padded);
$avp(serial_number) = $var(serial_number);

}

route[refresh_limits] {
sql_query("ca", "SELECT client_id, cps_limit FROM client_limits", "ra");
$var(rows) = $dbr(ra=>rows);
$var(i) = 0;
# xlog("L_INFO", "Refreshing limits for $var(rows) clients\n");
while($var(i) < $var(rows)) {
$var(cid) = $dbr(ra=>[$var(i),0]);
$var(limit) = $dbr(ra=>[$var(i),1]);
$sht(clientLimits=>$var(cid)) = $var(limit);
# xlog("L_INFO", "Client $var(cid) limit set to $var(limit) calls/second\n");
$var(i) = $var(i) + 1;
}
sql_result_free("ra");
# xlog("L_INFO", "Finished loading client limits\n");
}
route[RELAY] {
if (!t_relay()) {
sl_reply_error();
}
}
route[options_reply] {
sl_send_reply("200", "OK");
}
reply_route {
if (is_method("INVITE")) {
if (ds_is_from_list()) {
if (status="2[0-9][0-9]") {
ds_load_update();
} else if (status=
"[3-7][0-9][0-9]") {
ds_load_unset();
}
}
}

if(status=~"487|486|603") {
    if (is_present_hf("X-VICIdial-Client-Id")) {
        $var(client_id) = $(hdr(X-VICIdial-Client-Id));
        if ($var(client_id) =~ "^(CID_[0-9]+)-[a-z]$") {
            $var(parent_id) = $(var(client_id){re.subst,/^(CID_[0-9]+)-[a-z]$/\1/});
        } else {
            $var(parent_id) = $var(client_id);
        }
        
        if($var(parent_id) != $null) {
            lock("calls_$var(parent_id)");
            if($sht(clientCalls=>$var(parent_id)) > 0) {
                $sht(clientCalls=>$var(parent_id)) = $sht(clientCalls=>$var(parent_id)) - 1;
                xlog("L_INFO", "Response $rs: Decremented call count for $var(parent_id)\n");
            }
            unlock("calls_$var(parent_id)");
        }
    }
}

}

failure_route[MANAGE_FAILURE] {
if (is_method("INVITE")) {
if (t_check_status("403|408|480|482|483|486|487|488|501|502|503|504|603")) {
xlog("L_WARN", "Failed response received from $du\n");
if (!$var(attempt)) {
$var(attempt) = 1;
}
if (ds_is_from_list() && $var(attempt) < 3) {
$var(attempt) = $var(attempt) + 1;
if (ds_next_dst()) {
xlog("L_INFO", "Trying destination $var(attempt): $du\n");
t_relay();
exit;
}
} else if ($var(attempt) == 3) {
xlog("L_INFO", "3 destinations failed, routing to dump server\n");
$du = "sip::5060";
t_relay();
exit;
} else {
xlog("L_ERR", "Dump server failed, rejecting call\n");
t_reply("503", "Service Unavailable");
exit;
}
}
}
}
route[cleanup_calls] {
sht_iterator_start("cleanup", "clientCalls");
while(sht_iterator_next("cleanup")) {
$var(client_id) = $shtitkey(cleanup);
$var(current_calls) = $shtitval(cleanup);
xlog("L_INFO", "Client $var(client_id) - Current Calls: $var(current_calls)\n");
}
sht_iterator_end("cleanup");
}
event_route[dispatcher:dst-down] {
if ($du != $null) {
xlog("L_WARN", "Destination $du went down\n");
}
}

event_route[dispatcher:dst-up] {
if ($du != $null) {
if ($sht(active_calls=>$du) == $null) {
$sht(active_calls=>$du) = 0;
xlog("L_INFO", "Initialized counter for recovered destination $du\n");
}
}
}
`


Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.Message ID: <kamailio/kamailio/issues/4058@github.com>