Browse Source

Merge pull request #30 from siplabs/KAZOO-3355

KAZOO-3355: Frontier app
3.20
lazedo 11 years ago
parent
commit
2202dddfe1
4 changed files with 549 additions and 6 deletions
  1. +253
    -0
      kamailio/acl-role.cfg
  2. +40
    -5
      kamailio/default.cfg
  3. +3
    -1
      kamailio/local.cfg
  4. +253
    -0
      kamailio/rate-limiter-role.cfg

+ 253
- 0
kamailio/acl-role.cfg View File

@ -0,0 +1,253 @@
######## DoS prevention module ########
# Default "order" is "deny,allow".
# So if there is no data from DB request will be permitted by default.
#
loadmodule "ipops.so"
modparam("htable", "htable", "acl=>initval=-1;autoexpire=7200")
#!trydef ACL_MESSAGE_DENY "Rejected by ACL"
#!trydef ACL_CODE_DENY "603"
#!trydef ACL_ORDER_ALLOW_DENY "allow,deny"
#!trydef ACL_IP_ADDR_ANY "0.0.0.0/0"
#!trydef IP_REGEX "[0-9]{1,3}\.[0-9]{1,3}.[0-9]{1,3}\.[0-9]{1,3}"
## Route for ACL functionality
route[ACL_CHECK] {
# If packet came from platform or from 4 class MERA, do not check it
if (isflagset(FLAG_INTERNALLY_SOURCED) || isflagset(FLAG_TRUSTED_SOURCE) ) {
xlog("L_DEBUG", "$ci|ACL|Trusted source IP($si) ignoring");
return;
}
if (isflagset(FLAG_IS_REPLY)) {
$var(sip-packet) = $rs;
} else {
$var(sip-packet) = $rm;
}
# FIX for BYE method with IP instead of REALM in From, take REALM from To header
if ($fd =~ IP_REGEX) {
xlog("L_WARNING","$ci|ACL-realm|Fix for $var(sip-packet) with IP in from URI: use to-domain");
$var(realm) = $td;
} else {
$var(realm) = $fd;
}
$var(acl-realm-request) = "false";
$var(acl-device-request) = "false";
$var(realm-decision) = $sht(acl=>$var(realm)/$si);
if ($var(realm-decision) == -1) { # we do not have cached decision
$var(acl-realm-request) = "true";
} else if ($var(realm-decision) == 1 ){ # We have cached decision, let's use it
xlog("L_INFO", "$ci|ACL|$var(sip-packet) from $si is permitted by ACL for $var(realm)\n");
} else {
if (!isflagset(FLAG_IS_REPLY)) {
sl_send_reply(ACL_CODE_DENY, ACL_MESSAGE_DENY);
}
xlog("L_INFO", "$ci|ACL|$var(sip-packet) from $si is rejected by ACL for $var(realm)\n");
exit;
}
if (not_empty("$fU")) {
if ($fd =~ IP_REGEX) {
xlog("L_WARNING","$ci|ACL-device|Fix for $var(sip-packet) with IP in from URI: use to-domain");
$var(device) = $fU + "@" + $td;
} else {
$var(device) = $fU + "@" + $fd;
}
$var(device-decision) = $sht(acl=>$var(device)/$si);
if ($var(device-decision) == -1) { # we do not have cached decision
$var(acl-device-request) = "true";
} else if ($var(device-decision) == 1 ){ # We have cached decision, let's use it
xlog("L_INFO", "$ci|ACL|$var(sip-packet) from $si is permitted by ACL for $var(device)\n");
} else {
if (!isflagset(FLAG_IS_REPLY)) {
sl_send_reply(ACL_CODE_DENY, ACL_MESSAGE_DENY);
}
xlog("L_INFO", "$ci|ACL|$var(sip-packet) from $si is rejected by ACL for $var(device)\n");
exit;
}
}
if ($var(acl-realm-request) == "true" || $var(acl-device-request) == "true") {
if (not_empty("$fU"))
$var(query) = "{'Event-Category': 'acl', 'Event-Name': 'query', 'Entity': '" + $var(device) + "', 'With-Realm': " + $var(acl-realm-request) + "}";
else
$var(query) = "{'Event-Category': 'acl', 'Event-Name': 'query', 'Entity': '" + $var(realm) + "'}";
xlog("L_DBG", "$ci|ACL log|Query: $var(query)");
if (kazoo_query("frontier", "sbc_config", $var(query), "$var(acl-response)")) {
xlog("L_DBG", "$ci|ACL log|Response: $var(acl-response)");
kazoo_json($var(acl-response), "Realm.Order", "$var(acl-realm-order)");
kazoo_json($var(acl-response), "Realm.CIDR", "$var(acl-realm-cidr)");
kazoo_json($var(acl-response), "Device.Order", "$var(acl-device-order)");
kazoo_json($var(acl-response), "Device.CIDR", "$var(acl-device-cidr)");
kazoo_json($var(acl-response), "Device.User-Agent", "$var(acl-device-ua)");
} else {
xlog("L_ERROR","$ci|ACL log|DB is unreachable");
$sht(acl=>$var(device)/$si) = 1;
xlog("L_INFO", "$ci|ACL|$var(sip-packet) from $si is permitted by ACL for $var(device)\n");
return;
}
route(ACL_CHECK_REALM);
if (not_empty("$fU")) {
route(ACL_CHECK_DEVICE);
}
}
}
# Check ORDER setting for REALM
route[ACL_CHECK_REALM] {
if (not_empty("$var(acl-realm-order)")) {
if ($var(acl-realm-order) == ACL_ORDER_ALLOW_DENY) {
route(ACL_CHECK_REALM_ALLOW);
} else {
route(ACL_CHECK_REALM_DENY);
}
} else {
xlog("L_INFO","$ci|ACL-realm|undefined Order in response for $var(realm)");
$sht(acl=>$var(realm)/$si) = 1;
xlog("L_INFO", "$ci|ACL|$var(sip-packet) from $si is permitted by ACL for $var(realm)\n");
}
}
route[ACL_CHECK_REALM_ALLOW] {
if (not_empty("$var(acl-realm-cidr)")) {
$var(i) = 0;
kazoo_json($var(acl-response), "Realm.CIDR[$var(i)]", "$var(record)");;
while(not_empty("$var(record)")) {
xlog("L_INFO", "$ci|ACL-realm|checking if $si is in $var(record)");
if (($var(record) == ACL_IP_ADDR_ANY) || is_in_subnet("$si", $var(record))) {
$sht(acl=>$var(realm)/$si) = 1;
xlog("L_INFO", "$ci|ACL|$var(sip-packet) from $si is permitted by ACL for $var(realm)\n");
return;
}
$var(i) = $var(i) + 1;
kazoo_json($var(acl-response), "Realm.CIDR[$var(i)]", "$var(record)");;
}
} else {
xlog("L_INFO", "$ci|ACL-realm|undefined CIDR in response for $var(realm)");
}
# Remember in CACHE and DENY
$sht(acl=>$var(realm)/$si) = 0;
if (!isflagset(FLAG_IS_REPLY)) {
sl_send_reply(ACL_CODE_DENY, ACL_MESSAGE_DENY);
}
xlog("L_INFO", "$ci|ACL|$var(sip-packet) from $si is rejected by ACL for $var(realm)\n");
exit;
}
route[ACL_CHECK_REALM_DENY] {
$var(size) = $(kzR{kz.json,Realm.CIDR.length});
if (not_empty("$var(acl-realm-cidr)")) {
$var(i) = 0;
kazoo_json($var(acl-response), "Realm.CIDR[$var(i)]", "$var(record)");;
while(not_empty("$var(record)")) {
xlog("L_INFO", "$ci|ACL-realm|checking if $si is in $var(record)");
if (($var(record) == ACL_IP_ADDR_ANY) || is_in_subnet("$si", $var(record))) {
$sht(acl=>$var(realm)/$si) = 0;
if (!isflagset(FLAG_IS_REPLY)) {
sl_send_reply(ACL_CODE_DENY, ACL_MESSAGE_DENY);
}
xlog("L_INFO", "$ci|ACL|$var(sip-packet) from $si is rejected by ACL for $var(realm)\n");
exit;
}
$var(i) = $var(i) + 1;
kazoo_json($var(acl-response), "Realm.CIDR[$var(i)]", "$var(record)");;
}
} else {
xlog("L_INFO", "$ci|ACL-realm|undefined CIDR in response for $var(realm)");
}
# Remember in CACHE and ALLOW
$sht(acl=>$var(realm)/$si) = 1;
xlog("L_INFO", "$ci|ACL|$var(sip-packet) from $si is permitted by ACL for $var(realm)\n");
return;
}
# Check ORDER setting for DEVICE
route[ACL_CHECK_DEVICE] {
if (not_empty("$var(acl-device-order)")) {
if ($var(acl-device-order) == ACL_ORDER_ALLOW_DENY) {
route(ACL_CHECK_DEVICE_ALLOW);
} else {
route(ACL_CHECK_DEVICE_DENY);
}
} else {
xlog("L_INFO","$ci|ACL-device|undefined Order in response for $var(device)");
$sht(acl=>$var(device)/$si) = 1;
xlog("L_INFO", "$ci|ACL|$var(sip-packet) from $si is permitted by ACL for $var(device)\n");
}
}
route[ACL_CHECK_DEVICE_ALLOW] {
if (!not_empty("$var(acl-device-ua)") || (not_empty("$var(acl-device-ua)") && $ua =~ $var(acl-device-ua))) {
if (not_empty("$var(acl-device-cidr)")) {
$var(i) = 0;
kazoo_json($var(acl-response), "Device.CIDR[$var(i)]", "$var(record)");;
while(not_empty("$var(record)")) {
xlog("L_INFO", "$ci|ACL-realm|checking if $si is in $var(record)");
if (($var(record) == ACL_IP_ADDR_ANY) || is_in_subnet("$si", $var(record))) {
$sht(acl=>$var(device)/$si) = 1;
xlog("L_INFO", "$ci|ACL|$var(sip-packet) from $si is permitted by ACL for $var(device)\n");
return;
}
$var(i) = $var(i) + 1;
kazoo_json($var(acl-response), "Device.CIDR[$var(i)]", "$var(record)");;
}
} else {
xlog("L_INFO", "$ci|ACL-realm|undefined CIDR in response for $var(device)");
}
}
# Remember in CACHE and DENY
$sht(acl=>$var(device)/$si) = 0;
if (!isflagset(FLAG_IS_REPLY)) {
sl_send_reply(ACL_CODE_DENY, ACL_MESSAGE_DENY);
}
xlog("L_INFO", "$ci|ACL|$var(sip-packet) from $si is rejected by ACL for $var(device)\n");
exit;
}
route[ACL_CHECK_DEVICE_DENY] {
if (not_empty("$var(acl-device-ua)") && !($ua =~ $var(acl-device-ua))) {
$sht(acl=>$var(device)/$si) = 0;
if (!isflagset(FLAG_IS_REPLY)) {
sl_send_reply(ACL_CODE_DENY, ACL_MESSAGE_DENY);
}
xlog("L_INFO", "$ci|ACL|$var(sip-packet) from $si is rejected by ACL for $var(device)\n");
exit;
}
if (not_empty("$var(acl-device-cidr)")) {
$var(i) = 0;
kazoo_json($var(acl-response), "Device.CIDR[$var(i)]", "$var(record)");;
while(not_empty("$var(record)")) {
xlog("L_INFO", "$ci|ACL-device|checking if $si is in $var(record)");
if (($var(record) == ACL_IP_ADDR_ANY) || is_in_subnet("$si", $var(record))) {
$sht(acl=>$var(device)/$si) = 0;
if (!isflagset(FLAG_IS_REPLY)) {
sl_send_reply(ACL_CODE_DENY, ACL_MESSAGE_DENY);
}
xlog("L_INFO", "$ci|ACL|$var(sip-packet) from $si is rejected by ACL for $var(device)\n");
exit;
}
$var(i) = $var(i) + 1;
kazoo_json($var(acl-response), "Device.CIDR[$var(i)]", "$var(record)");;
}
} else {
xlog("L_INFO", "$ci|ACL-device|undefined CIDR in response for $var(device)");
}
# Remember in CACHE and ALLOW
$sht(acl=>$var(device)/$si) = 1;
xlog("L_INFO", "$ci|ACL|$var(sip-packet) from $si is permitted by ACL for $var(device)\n");
return;
}

+ 40
- 5
kamailio/default.cfg View File

@ -8,6 +8,7 @@ flags
FLAG_ASSOCIATE_USER: 4,
FLAG_TRUSTED_SOURCE: 5,
FLAG_SESSION_PROGRESS: 6;
FLAG_IS_REPLY: 7;
####### Global Parameters #########
fork = yes
@ -195,9 +196,15 @@ include_file "accounting-role.cfg"
#!ifdef ANTIFLOOD-ROLE
include_file "antiflood-role.cfg"
#!endif
#!ifdef TRAFFIC-FILTER-ROLE
#!ifdef TRAFFIC_FILTER-ROLE
include_file "traffic-filter-role.cfg"
#!endif
#!ifdef ACL-ROLE
include_file "acl-role.cfg"
#!endif
#!ifdef RATE_LIMITER-ROLE
include_file "rate-limiter-role.cfg"
#endif
#!ifdef PUSHER-ROLE
include_file "pusher-role.cfg"
#!endif
@ -231,10 +238,18 @@ route
route(ANITFLOOD_AUTH_LIMIT);
#!endif
#!ifdef TRAFFIC-FILTER-ROLE
#!ifdef TRAFFIC_FILTER-ROLE
route(TRAFFIC_FILTER);
#!endif
#!ifdef ACL-ROLE
route(ACL_CHECK);
#!endif
#!ifdef RATE_LIMITER-ROLE
route(DOS_PREVENTION);
#!endif
#!ifdef WEBSOCKETS-ROLE
route(HANDLE_WEBSOCKETS);
#!endif
@ -312,7 +327,7 @@ route[HANDLE_OPTIONS]
if (isflagset(FLAG_INTERNALLY_SOURCED)) {
route(INTERNAL_TO_EXTERNAL_RELAY);
} else {
#!ifdef TRAFFIC-FILTER-ROLE
#!ifdef TRAFFIC_FILTER-ROLE
route(FILTER_REQUEST_DOMAIN);
#!endif
@ -336,7 +351,7 @@ route[HANDLE_NOTIFY]
}
route(INTERNAL_TO_EXTERNAL_RELAY);
} else {
#!ifdef TRAFFIC-FILTER-ROLE
#!ifdef TRAFFIC_FILTER-ROLE
route(FILTER_REQUEST_DOMAIN);
#!endif
@ -373,7 +388,7 @@ route[HANDLE_MESSAGE]
xlog("L_INFO", "$ci|log|routing to $ruid");
}
route(INTERNAL_TO_EXTERNAL_RELAY);
#!ifdef TRAFFIC-FILTER-ROLE
#!ifdef TRAFFIC_FILTER-ROLE
} else if (!isflagset(FLAG_TRUSTED_SOURCE)
&& $rd =~ "[0-9]{1,3}\.[0-9]{1,3}.[0-9]{1,3}\.[0-9]{1,3}") {
xlog("L_WARN", "$ci|end|dropping MESSAGE request with IP domain");
@ -580,6 +595,16 @@ onreply_route[EXTERNAL_REPLY]
#!ifdef NAT-TRAVERSAL-ROLE
route(NAT_TEST_AND_CORRECT);
#!endif
#!ifdef ACL-ROLE
setflag(FLAG_IS_REPLY);
route(ACL_CHECK);
#!endif
#!ifdef RATE_LIMITER-ROLE
setflag(FLAG_IS_REPLY);
route(DOS_PREVENTION);
#!endif
}
onreply_route[INTERNAL_REPLY]
@ -592,6 +617,16 @@ onreply_route[INTERNAL_REPLY]
route(NAT_WEBSOCKETS_CORRECT);
#!endif
#!ifdef ACL-ROLE
setflag(FLAG_IS_REPLY);
route(ACL_CHECK);
#!endif
#!ifdef RATE_LIMITER-ROLE
setflag(FLAG_IS_REPLY);
route(DOS_PREVENTION);
#!endif
if (is_method("INVITE") &&
!isflagset(FLAG_SESSION_PROGRESS) &&
t_check_status("(180)|(183)|(200)")


+ 3
- 1
kamailio/local.cfg View File

@ -15,10 +15,12 @@ debug = L_INFO
#!trydef NODES-ROLE
## Disabled Roles - remove all but the last '#' to enable
# # #!trydef TRAFFIC-FILTER-ROLE
# # #!trydef TRAFFIC_FILTER-ROLE
# # #!trydef WEBSOCKETS-ROLE
# # #!trydef TLS-ROLE
# # #!trydef ANTIFLOOD-ROLE
# # #!trydef RATE_LIMITER-ROLE
# # #!trydef ACL-ROLE
# # #!trydef MESSAGE-ROLE
# # #!trydef PUSHER-ROLE


+ 253
- 0
kamailio/rate-limiter-role.cfg View File

@ -0,0 +1,253 @@
######## DoS prevention module ########
modparam("htable", "timer_interval", 10)
modparam("htable", "htable", "rps=>size=8;initval=0;autoexpire=60")
modparam("htable", "htable", "rpm=>size=8;initval=0;autoexpire=180")
modparam("htable", "htable", "tps=>size=8;initval=0;autoexpire=60")
modparam("htable", "htable", "tpm=>size=8;initval=0;autoexpire=180")
modparam("htable", "htable", "rate_limits=>initval=-1;autoexpire=60") # initval = -1 means that record is expired and we need an update from DB
#!trydef RATE_LIMIT_MESSAGE "Over rate Limit"
#!trydef RATE_LIMIT_CODE "603"
#!trydef IP_REGEX "[0-9]{1,3}\.[0-9]{1,3}.[0-9]{1,3}\.[0-9]{1,3}"
route[DOS_PREVENTION] {
# If packet came from platform or from 4 class MERA, do not check it
if (isflagset(FLAG_INTERNALLY_SOURCED) || isflagset(FLAG_TRUSTED_SOURCE) ) {
xlog("L_DEBUG", "$ci |RL| Trusted source IP($si) ignoring");
return;
}
# Initially we do not want to get data
$var(with-realm-request) = "false";
$var(with-realm-total) = "false";
$var(with-device-request) = "false";
$var(with-device-total) = "false";
$var(method-key) = "Method";
$var(method-value) = "\"TOTAL\"";
# SIP methods INVITE and REGISTER have personal counters
if ((is_method("INVITE") || is_method("REGISTER")) && (!isflagset(FLAG_IS_REPLY))) {
$var(lrpm_realm) = $fd+"/"+$rm+"/min";
$var(lrps_realm) = $fd+"/"+$rm+"/sec";
$var(lrpm_device) = $fU+"@"+$fd+"/"+$rm+"/min";
$var(lrps_device) = $fU+"@"+$fd+"/"+$rm+"/sec";
$var(method-value) = "\"" + $rm + "\"";
}
# For BYE method we use REALM from To SIP header
if ($fd =~ IP_REGEX) {
xlog("L_WARNING","$ci|RL-realm log| Fixup for $rm method with IP in from URI: use to-domain");
$var(ltpm_realm) = $td+"/TOTAL/min";
$var(ltps_realm) = $td+"/TOTAL/sec";
$var(ltpm_device) = $fU+"@"+$td+"/TOTAL/min";
$var(ltps_device) = $fU+"@"+$td+"/TOTAL/sec";
$var(entity) = $td;
} else {
$var(ltpm_realm) = $fd+"/TOTAL/min";
$var(ltps_realm) = $fd+"/TOTAL/sec";
$var(ltpm_device) = $fU+"@"+$fd+"/TOTAL/min";
$var(ltps_device) = $fU+"@"+$fd+"/TOTAL/sec";
$var(entity) = $fd;
}
# REALM check
if ((is_method("INVITE") || is_method("REGISTER")) && (!isflagset(FLAG_IS_REPLY))) {
if ($sht(rate_limits=>$var(lrpm_realm)) == -1
|| $sht(rate_limits=>$var(lrps_realm)) == -1) {
xlog("L_INFO", "$ci|RL-realm log| Can't find HASHed rate for $var(entity) with $rm method");
$var(with-realm-request) = "true";
}
}
if ($sht(rate_limits=>$var(ltpm_realm)) == -1
|| $sht(rate_limits=>$var(ltps_realm)) == -1) {
xlog("L_INFO", "$ci|RL-realm log| Can't find HASHed rate for $var(entity) with $rm method");
$var(with-realm-total) = "true";
}
if (not_empty("$fU")) {
if ($fd =~ IP_REGEX) {
xlog("L_WARNING","$ci|RL-realm log| Fixup for $rm method with IP in from URI: use to-domain");
$var(entity) = $fU+"@"+$td;
} else {
$var(entity) = $fU+"@"+$fd;
}
#DEVICE check
if ((is_method("INVITE") || is_method("REGISTER")) && (!isflagset(FLAG_IS_REPLY))) {
if ($sht(rate_limits=>$var(lrpm_device)) == -1
|| $sht(rate_limits=>$var(lrps_device)) == -1) {
xlog("L_INFO", "$ci|RL-device log| Can't find HASHed rate for $var(entity) with $rm method");
$var(with-device-request) = "true";
}
}
if ($sht(rate_limits=>$var(ltpm_device)) == -1 || $sht(rate_limits=>$var(ltps_device)) == -1) {
xlog("L_INFO", "$ci|RL-device log| Can't find HASHed rate for $var(entity) with $rm method");
$var(with-device-total) = "true";
}
}
if ((is_method("INVITE") || is_method("REGISTER"))
&& (($var(with-device-request) == "true" && $var(with-device-total) == "true")
|| ($var(with-realm-request) == "true" && $var(with-realm-total) == "true"))) {
$var(method-key) = "Method-List";
$var(method-value) = "[\"" + $rm + "\", \"TOTAL\"]";
}
if ( $var(with-device-request) == "true"
|| $var(with-device-total) == "true"
|| $var(with-realm-request) == "true"
|| $var(with-realm-total) == "true" ) {
avp_printf("$avp(s:query-request)", "{\"Entity\" : \"$var(entity)\", \"$var(method-key)\" : $var(method-value), \"Event-Category\" : \"rate_limit\", \"Event-Name\" : \"query\", \"With-Realm\" : $var(with-realm-request)}");
xlog("L_INFO", "$ci|RL log| Query: $avp(s:query-request)");
if (kazoo_query("frontier", "sbc_config", $avp(s:query-request), "$var(amqp_result)")) {
xlog("L_INFO", "$ci|RL log| Response: $var(amqp_result)");
kazoo_json($var(amqp_result), "Realm.Minute." + $rm, "$var(realm-min)");
kazoo_json($var(amqp_result), "Realm.Second." + $rm, "$var(realm-sec)");
kazoo_json($var(amqp_result), "Realm.Minute.TOTAL", "$var(realm-min-total)");
kazoo_json($var(amqp_result), "Realm.Second.TOTAL", "$var(realm-sec-total)");
kazoo_json($var(amqp_result), "Device.Minute." + $rm, "$var(device-min)");
kazoo_json($var(amqp_result), "Device.Second." + $rm, "$var(device-sec)");
kazoo_json($var(amqp_result), "Device.Minute.TOTAL", "$var(device-min-total)");
kazoo_json($var(amqp_result), "Device.Second.TOTAL", "$var(device-sec-total)");
if ( not_empty("$var(realm-min)") ) {
$sht(rate_limits=>$var(lrpm_realm)) = $(var(realm-min){s.int});
xlog("L_INFO", "$ci|RL-realm log| $rm DB=>HASH for $var(lrpm_realm)=$sht(rate_limits=>$var(lrpm_realm))");
}
if ( not_empty("$var(realm-sec)") ) {
$sht(rate_limits=>$var(lrps_realm)) = $(var(realm-sec){s.int});
xlog("L_INFO", "$ci|RL-realm log| $rm DB=>HASH for $var(lrps_realm)=$sht(rate_limits=>$var(lrps_realm))");
}
if ( not_empty("$var(realm-min-total)") ) {
$sht(rate_limits=>$var(ltpm_realm)) = $(var(realm-min-total){s.int});
xlog("L_INFO", "$ci|RL-realm log| $rm DB=>HASH for $var(ltpm_realm)=$sht(rate_limits=>$var(ltpm_realm))");
}
if ( not_empty("$var(realm-sec-total)") ) {
$sht(rate_limits=>$var(ltps_realm)) = $(var(realm-sec-total){s.int});
xlog("L_INFO", "$ci|RL-realm log| $rm DB=>HASH for $var(ltps_realm)=$sht(rate_limits=>$var(ltps_realm))");
}
if ( not_empty("$var(device-min)") ) {
$sht(rate_limits=>$var(lrpm_device)) = $(var(device-min){s.int});
xlog("L_INFO", "$ci|RL-device log| $rm DB=>HASH for $var(lrpm_device)=$sht(rate_limits=>$var(lrpm_device))");
}
if ( not_empty("$var(device-sec)") ) {
$sht(rate_limits=>$var(lrps_device)) = $(var(device-sec){s.int});
xlog("L_INFO", "$ci|RL-device log| $rm DB=>HASH for $var(lrps_device)=$sht(rate_limits=>$var(lrps_device))");
}
if ( not_empty("$var(device-min-total)") ) {
$sht(rate_limits=>$var(ltpm_device)) = $(var(device-min-total){s.int});
xlog("L_INFO", "$ci|RL-device log| $rm DB=>HASH for $var(ltpm_device)=$sht(rate_limits=>$var(ltpm_device))");
}
if ( not_empty("$var(device-sec-total)") ) {
$sht(rate_limits=>$var(ltps_device)) = $(var(device-sec-total){s.int});
xlog("L_INFO", "$ci|RL-device log| $rm DB=>HASH for $var(ltps_device)=$sht(rate_limits=>$var(ltps_device))");
}
} else {
xlog("L_ERROR", "$ci|RL log| $rm DB unreachable for entity: $var(entity)");
return;
}
}
if ($fd =~ IP_REGEX) {
xlog("L_WARNING","$ci|RL-device log| Fixup for $rm method with IP in from URI: use to-domain");
$var(entity) = $td;
} else {
$var(entity) = $fd;
}
$var(entity-type) = "realm";
if ((is_method("INVITE") || is_method("REGISTER")) && (!isflagset(FLAG_IS_REPLY))) {
$var(lrpm) = $sht(rate_limits=>$var(lrpm_realm));
$var(lrps) = $sht(rate_limits=>$var(lrps_realm));
}
$var(ltpm) = $sht(rate_limits=>$var(ltpm_realm));
$var(ltps) = $sht(rate_limits=>$var(ltps_realm));
route(DO_DOS_PREVENTION);
if ( not_empty("$fU") ) {
if ($fd =~ IP_REGEX) {
$var(entity) = $fU+"@"+$td;
xlog("L_WARNING","$ci|RL-device log| Fixup for $rm method with IP in from URI: use to-domain");
} else {
$var(entity) = $fU+"@"+$fd;
}
$var(entity-type) = "device";
if ((is_method("INVITE") || is_method("REGISTER")) && (!isflagset(FLAG_IS_REPLY))) {
$var(lrpm) = $sht(rate_limits=>$var(lrpm_device));
$var(lrps) = $sht(rate_limits=>$var(lrps_device));
}
$var(ltpm) = $sht(rate_limits=>$var(ltpm_device));
$var(ltps) = $sht(rate_limits=>$var(ltps_device));
route(DO_DOS_PREVENTION);
}
}
# This route do counting and decide either to ACCEPT or DECLINE packet
route[DO_DOS_PREVENTION] {
# Personal counters for INVITE and REGISTER
if ((is_method("INVITE") || is_method("REGISTER"))) {
$var(rpm) = $var(entity)+":"+$rm+":min:"+$timef(%Y/%m/%d_%H_%M_00);
$var(rps) = $var(entity)+":"+$rm+":sec:"+$timef(%Y/%m/%d_%H_%M_%S);
}
# Commmon counters for ALL packet including INVITE and REGISTER
$var(tpm) = $var(entity)+":TOTAL:min:"+$timef(%Y/%m/%d_%H_%M_00);
$var(tps) = $var(entity)+":TOTAL:sec:"+$timef(%Y/%m/%d_%H_%M_%S);
# Personal debug for INVITE and REGISTER
if ((is_method("INVITE") || is_method("REGISTER"))) {
xlog("L_INFO", "$ci|RL-$var(entity-type) log| L/C for $var(rpm) = $var(lrpm)/$sht(rpm=>$var(rpm))");
xlog("L_INFO", "$ci|RL-$var(entity-type) log| L/C for $var(rps) = $var(lrps)/$sht(rps=>$var(rps))");
}
# Commmon debug for ALL packet including INVITE and REGISTER
xlog("L_INFO", "$ci|RL-$var(entity-type) log| L/C for $var(tpm) = $var(ltpm)/$sht(tpm=>$var(tpm))");
xlog("L_INFO", "$ci|RL-$var(entity-type) log| L/C for $var(tps) = $var(ltps)/$sht(tps=>$var(tps))");
# Personal increment just for INVITE and REGISTER
if ((is_method("INVITE") || is_method("REGISTER")) && (!isflagset(FLAG_IS_REPLY))) {
$sht(rpm=>$var(rpm)) = $shtinc(rpm=>$var(rpm));
$sht(rps=>$var(rps)) = $shtinc(rps=>$var(rps));
}
# Commmon increment for ALL packet including INVITE and REGISTER
$sht(tpm=>$var(tpm)) = $shtinc(tpm=>$var(tpm));
$sht(tps=>$var(tps)) = $shtinc(tps=>$var(tps));
# Personal checks for INVITE and REGISTER
if ((is_method("INVITE") || is_method("REGISTER")) && (!isflagset(FLAG_IS_REPLY))) {
if ($sht(rps=>$var(rps)) > $var(lrps)) {
sl_send_reply(RATE_LIMIT_CODE, RATE_LIMIT_MESSAGE);
xlog("L_INFO", "$ci|RL-$var(entity-type) log| Out of $rm $var(rps) rate limits: $sht(rps=>$var(rps)) > $var(lrps))");
exit;
}
if ($sht(rpm=>$var(rpm)) > $var(lrpm)) {
sl_send_reply(RATE_LIMIT_CODE, RATE_LIMIT_MESSAGE);
xlog("L_INFO", "$ci|RL-$var(entity-type) log| Out of $rm $var(rpm) rate limits: $sht(rpm=>$var(rpm)) > $var(lrpm))");
exit;
}
}
# Commmon checks for ALL packet including INVITE and REGISTER
if ($sht(tps=>$var(tps)) > $var(ltps)) {
if (isflagset(FLAG_IS_REPLY)) {
xlog("L_INFO", "$ci|RL-$var(entity-type) log| Out of TOTAL($rm::$rs $rr) $var(tps) rate limits: $sht(tps=>$var(tps)) > $var(ltps))");
} else {
sl_send_reply(RATE_LIMIT_CODE, RATE_LIMIT_MESSAGE);
xlog("L_INFO", "$ci|RL-$var(entity-type) log| Out of TOTAL($rm) $var(tps) rate limits: $sht(tps=>$var(tps)) > $var(ltps))");
}
exit;
}
if ($sht(tpm=>$var(tpm)) > $var(ltpm)) {
if (isflagset(FLAG_IS_REPLY)) {
xlog("L_INFO", "$ci|RL-$var(entity-type) log| Out of TOTAL($rm::$rs $rr) $var(tpm) rate limits: $sht(tpm=>$var(tpm)) > $var(ltpm))");
} else {
sl_send_reply(RATE_LIMIT_CODE, RATE_LIMIT_MESSAGE);
xlog("L_INFO", "$ci|RL-$var(entity-type) log| Out of TOTAL($rm) $var(tpm) rate limits: $sht(tpm=>$var(tpm)) > $var(ltpm))");
}
exit;
}
}

Loading…
Cancel
Save