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/4...@github.com>
_______________________________________________
Kamailio - Development Mailing List -- sr-dev@lists.kamailio.org
To unsubscribe send an email to sr-dev-le...@lists.kamailio.org
Important: keep the mailing list in the recipients, do not reply only to the
sender!