route[HANDLE_INVITE] {
if (!has_totag()) {
if (!t_newtran()) {
xlog("L_ERROR", "Failed to create new transaction\n");
sl_reply_error();
exit;
}
if (!is_present_hf("X-VICIdial-Client-Id")) {
xlog("L_WARN", "INVITE received without X-VICIdial-Client-Id
header\n");
t_reply("400", "Bad Request - Missing Client ID");
exit;
}
if ($rU == $null) {
xlog("L_WARN", "INVITE received with empty Request-URI
username\n");
t_reply("400", "Bad Request - Missing User");
exit;
}
$var(full_client_id) = $hdr(X-VICIdial-Client-Id);
# Extract parent ID
if ($var(full_client_id) =~ "^(CID_[0-9]+)-[a-z]$") {
$var(parent_client_id) =
$(var(full_client_id){re.subst,/^(CID_[0-9]+)-[a-z]$/\1/});
} else {
$var(parent_client_id) = $var(full_client_id);
}
# CPS Check and Rate Limiting
lock("cps_counter");
# Get current CPS count and max limit
$var(current_cps) = $sht(client_limits=>$var(parent_client_id));
$var(max_cps) = $sht(client_max_cps=>$var(parent_client_id));
xlog("L_INFO", "CPS Check - Client: $var(parent_client_id),
Current: $var(current_cps), Max: $var(max_cps)\n");
# Check for configured limit
if($var(max_cps) == $null) {
unlock("cps_counter");
xlog("L_WARN", "No CPS limit configured for client
$var(parent_client_id)\n");
t_reply("403", "Client Not Authorized");
exit;
}
# Get concurrent calls
$var(concurrent_calls) = $sht(client_calls=>$var(parent_client_id));
if($var(concurrent_calls) == $null) {
$var(concurrent_calls) = 0;
}
# Strict limit check
if($var(concurrent_calls) >= $var(max_cps)) {
unlock("cps_counter");
xlog("L_WARN", "Concurrent call limit reached for
$var(parent_client_id): $var(concurrent_calls)/$var(max_cps)\n");
t_reply("503", "Concurrent Call Limit Exceeded");
exit;
}
# Allow call and increment counter
if($var(current_cps) == $null) {
$sht(client_limits=>$var(parent_client_id)) = 1;
} else {
$sht(client_limits=>$var(parent_client_id)) = $var(current_cps) + 1;
}
xlog("L_INFO", "Call allowed for $var(parent_client_id):
Concurrent=$var(concurrent_calls+1)/$var(max_cps)\n");
unlock("cps_counter");
$var(user) = $rU;
# Extract parent client ID if this is a child ID
if ($var(full_client_id) =~ "^(CID_[0-9]+)-[a-z]$") {
$var(parent_client_id) =
$(var(full_client_id){re.subst,/^(CID_[0-9]+)-[a-z]$/\1/});
$var(is_child) = 1;
} else {
$var(parent_client_id) = $var(full_client_id);
$var(is_child) = 0;
}
$avp(full_client_id) = $var(full_client_id);
$avp(parent_client_id) = $var(parent_client_id);
$avp(user) = $var(user);
$var(call_id) = $ci;
route(GENERATE_SERIAL_NUMBER);
# Track client calls
lock("client_counter");
# Update parent counter
$var(parent_calls) = $sht(client_calls=>$var(parent_client_id));
if($var(parent_calls) == $null) {
$var(parent_calls) = 0;
}
$sht(client_calls=>$var(parent_client_id)) = $var(parent_calls) + 1;
# If it's a child ID, update its individual counter too
if ($var(is_child) == 1) {
$var(child_calls) = $sht(client_calls=>$var(full_client_id));
if($var(child_calls) == $null) {
$var(child_calls) = 0;
}
$sht(client_calls=>$var(full_client_id)) = $var(child_calls) + 1;
}
# Store mappings
$sht(client_calls=>$var(call_id)) = $var(parent_client_id);
$sht(client_original=>$var(call_id)) = $var(full_client_id);
unlock("client_counter");
# Find destination with lowest active calls
$var(min_calls) = 999;
$var(selected_dst) = "";
lock("calls_counter");
if (ds_select_dst("4", "4")) {
$var(count) = 0; # Add counter
$var(current_calls) = $sht(active_calls=>$du);
if ($var(current_calls) == $null) {
$var(current_calls) = 0;
}
if ($var(current_calls) < $var(min_calls)) {
$var(min_calls) = $var(current_calls);
$var(selected_dst) = $du;
}
while(ds_next_dst() && $var(count) < 350) { # Set higher than 280
$var(count) = $var(count) + 1;
$var(current_calls) = $sht(active_calls=>$du);
if ($var(current_calls) == $null) {
$var(current_calls) = 0;
}
if ($var(current_calls) < $var(min_calls)) {
$var(min_calls) = $var(current_calls);
$var(selected_dst) = $du;
}
}
}
if ($var(selected_dst) != "" && $var(min_calls) < 25) {
$du = $var(selected_dst);
# Add this block - Double check the count hasn't changed
$var(current_count) = $sht(active_calls=>$du);
if ($var(current_count) >= 25) {
unlock("calls_counter");
xlog("L_ERROR", "Count increased during selection for $du
to $var(current_count)\n");
t_reply("503", "Service Unavailable");
exit;
}
# Store Call-ID to destination mapping
$sht(active_calls=>$var(call_id)) = $du;
# Increment call counter
$sht(active_calls=>$du) = $var(min_calls) + 1;
unlock("calls_counter");
route(RELAY_INVITE);
} else {
unlock("calls_counter");
xlog("L_NOTICE", "Unlocked $ci");
$du = "sip:34.125.5.64:5060";
t_on_failure("FINAL_FAILURE");
if (!t_relay()) {
t_reply("500", "Internal Server Error");
}
}
} else {
route(RELAY);
}
} here is my invite rout configuration if you look at to the cps limit this is occultly
the call per second limit on the client id when i set it 200 and the start calling up to
3000 per seconds so some time or for a bit of time it exceed the limit 201 or 202 then it
start enforce 200 so if anyone have the best idea or suggestion regarding to this with the
good ms time
--
Reply to this email directly or view it on GitHub:
https://github.com/kamailio/kamailio/issues/4040
You are receiving this because you are subscribed to this thread.
Message ID: <kamailio/kamailio/issues/4040(a)github.com>