[OpenSIPS-Users] Nathelper keepalive issue with received column in usrloc

Julian Santer julian.santer at rolmail.net
Wed Dec 12 10:45:43 EST 2018


Hi Liviu,

thank you for your help.
Without the received header, I got some problems. The calls are being 
send from the core to the UAC and not to the edge server.

So now I implemented your workaround on my lab servers:

core:
     $var(rcv) = null;
     $var(rcv_host) = null;
     $var(rcv_port) = null;
     $var(ct_uri_params) = null;

     xlog("L_INFO", "PATH $(hdr(Path)) - LF_BASE");
     if ($(hdr(Path){param.exist,received}))
     {
         $var(rcv) = $(hdr(Path){param.value,received});
         $var(rcv_host) = $(var(rcv){re.subst,/sip://});
         $var(rcv_host) = $(var(rcv_host){re.subst,/:.*//});
         $var(rcv_port) = $(var(rcv){re.subst,/sip:.+://});
         $var(rcv_port) = $(var(rcv_port){re.subst,/>//});

         AVP_RECEIVED = "sip:" + $(ct.fields(uri){uri.user}) + "@" + 
$var(rcv_host) + ":" + $var(rcv_port);
         $var(ct_uri_params) = $(ct.fields(uri){uri.params});
         if ($var(ct_uri_params) != null) {
             AVP_RECEIVED = AVP_RECEIVED + ";" + $var(ct_uri_params);
         }
         xlog("L_INFO", "PATH received $var(rcv), host $var(rcv_host), 
port $var(rcv_port), AVP_RECEIVED - LF_BASE");
     }

     if (src_ip == REGISTRAR_FAILOVER_IP)
     {
         if (! save("LOCATION_TABLE", "mp1"))
         {
             xlog("L_ERR", "Saving contact from REGISTRAR_FAILOVER_IP 
(REGISTRAR_FAILOVER) failed - LF_BASE");
             exit;
         }
         xlog("L_INFO", "Saving contact received from 
REGISTRAR_FAILOVER_IP (REGISTRAR_FAILOVER) - LF_BASE");
         t_on_branch("BR_DROP");
     }
     else
     {
         if (proto == UDP)
         {
             setbflag(SIP_PING_FLAG);
             xlog("L_INFO", "Nat keepalive sip_ping_flag - LF_BASE");
         }

         if (! save("LOCATION_TABLE", "p1"))
         {
             xlog("L_ERR", "Saving contact from EDGE failed - LF_BASE");
             t_replicate("sip:REGISTRAR_FAILOVER", "0x04");
             exit;
         }
         xlog("L_INFO", "Saving contact received from EDGE, replicate to 
REGISTRAR_FAILOVER - LF_BASE");
         t_replicate("sip:REGISTRAR_FAILOVER", "0x04");
         t_on_branch("BR_DROP");
     }

As you can see, I also needed to add the contact uri params to the 
received AVP. Without this params I get a 404 from the UAC.

To be sure, if this workaround works, I have to publish it on the 
production server. I will do this tomorrow morning and I hope it works 
also with the other, undefined UAC's.

Kind regards,
Julian Santer


Am 08.12.18 um 17:29 schrieb Liviu Chircu:
> Hi Julian,
> 
> This asymmetry of the OPTIONS R-URI + To header field when pinging 
> either normal contacts (includes "username@" part) or NAT'ed  contacts 
> (skips the "username@" part) actually looks like a bug -- I will look 
> into a fix in the background.
> 
> For the time being, you should be able to circumvent the bug using the 
> following technique:
> 
> _edge script_
> 
> no need to change anything here, using add_path_received() is correct.
> 
> _core script_
> 
> * define the "received_avp" modparam for both registrar and nathelper -- 
> they must be set to the same AVP, say "$avp(rcv)"
> * using the script transformations [1] and/or other magic, extract the 
> value of the ";received=" Path header parameter into two convenient 
> variables: $var(rcv_host) and $var(rcv_port).
> * prepare the exact content of the future R-URI / To header pings for 
> this contact by populating $avp(rcv):
> 
>      $avp(rcv) = "sip:" + $(ct.fields(uri){uri.user}) + "@" + 
> $var(rcv_host) + ":" + $var(rcv_port);
> 
> * save("p1"); # notice we skip the "v" (Path ";received=" param) logic, 
> as the received URI is already set
> 
> Best regards,
> 
> [1]: https://www.opensips.org/Documentation/Script-Tran-2-2
> 
> Liviu Chircu
> OpenSIPS Developer
> http://www.opensips-solutions.com
> 
> On 20.11.2018 17:01, Julian Santer wrote:
>> Hi guys,
>>
>> as I see in the tcpdump:
>>
>> - with the received header the R-RURI in the INVITE looks like:
>>
>> Request-Line: INVITE 
>> sip:dev-lab1 at 192.168.44.101:40885;line=fjafxbr9 
>> SIP/2.0
>>
>>
>> - without the received header the R-URI in the INVITE looks like:
>>
>> Request-Line: INVITE 
>> sip:dev-lab1 at 212.46.162.97:40885;line=7wsv12yg 
>> SIP/2.0
>>
>>
>> Could the INVITE been rejeced/dropped by the UAC, if the R-RURI 
>> contains the public instead the private IP or another port etc.?
>>
>> From UAC perspective, the R-RURI (puclic IP) by incoming packets 
>> doesn't match the R-RURI (private IP) by outgoing packets.
>>
>>
>> Kind regards,
>>
>> Julian Santer
>>
>> Am 20.11.18 um 15:51 schrieb Julian Santer:
>>> Hi guys,
>>>
>>> if I don't use the received column on the edge server, but I call 
>>> fix_nated_contact instead, it seems to work.
>>>
>>> if (nat_uac_test("127"))
>>> {
>>>     fix_nated_contact();
>>> }
>>>
>>> consume_credentials();
>>>
>>> if (! add_path())
>>> {
>>>     send_reply("500", "Internal path error, registration not stored");
>>>     xlog("L_ERR", "Adding PATH (with received) failed - LF_BASE");
>>>     exit;
>>> }
>>>
>>> Is this the right way or could I break something else with this change?
>>>
>>>
>>> Kind regards,
>>>
>>> Julian Santer
>>>
>>> Am 19.11.18 um 18:41 schrieb Julian Santer:
>>>> Hi guys,
>>>>
>>>> we need to switch from nat_traversal to nathelper.
>>>> The reason is the keepalive mechanism.
>>>>
>>>> The nat_traversal module sends OPTIONS with the following to header: 
>>>> sip:UAC_IP:UAC_PORT
>>>> Most of the UAC's answers with a 404 Not found.
>>>> On AVM Fritzbox with firmware >= 6.04, this OPTIONS may activate a 
>>>> security feature.
>>>> So after a certain time, the Fritzbox blocks all packages send from 
>>>> our proxy.
>>>> As we have ca. 80% AVM Fritzbox as UAC, we got a big problem.
>>>> So we deactivated the nat_keepalive vor this UAC's and we have to 
>>>> enable the keepalive Feature on the Fritzbox.
>>>>
>>>> The better solution would be, if we could send OPTIONS with a to 
>>>> header like: sip:username at UAC_IP:UAC_PORT.
>>>> As I understood the nathelper module could send OPTIONS like this. 
>>>> Because it is looking into the userloc table. Right?
>>>>
>>>> The nathelper module is on our edge server, the registrar on our 
>>>> core server.
>>>> For the "normal" UAC's (no received entry in usrloc) the keepalive's 
>>>> are now sent as expected.
>>>> But for the "nated" UAC's (received entry in usrloc) the keepalive's 
>>>> are like before: sip:UAC_IP:UAC_PORT (values in the received column 
>>>> from usrloc).
>>>> The REGISTER send to the core got the path header looking like:
>>>> Path: <sip:IP_EDGE;lr;received=sip:IP_UAC:40885>
>>>>
>>>> Is there a possibility to add the $fU on the received part of the 
>>>> path header (the user in the path module adds a string to the path 
>>>> part, but not to the received part)?
>>>> Or is there a possiblity on the registrar to store the $fU in the 
>>>> received column?
>>>> On the nathelper keepalive mechanism I don't see any possibility to 
>>>> add the $fU.
>>>>
>>>> We are using the version 2.2.6 from the official debian source list.
>>>>
>>>> The config on the edge server's looks like:
>>>> #### nat helper module
>>>> loadmodule "nathelper.so"
>>>> modparam("nathelper", "natping_interval", 0)
>>>> modparam("nathelper", "ping_nated_only", 0)
>>>> modparam("nathelper", "natping_partitions", 1)
>>>> modparam("nathelper", "natping_tcp", 0)
>>>>
>>>> ### REGISTER
>>>>
>>>> $var(nat) = null;
>>>>
>>>> if (nat_uac_test("127"))
>>>> {
>>>>     $var(nat) = TRUE;
>>>> }
>>>> else
>>>> {
>>>>     $var(nat) = FALSE;
>>>> }
>>>>
>>>> consume_credentials();
>>>>
>>>> if ($var(nat) == TRUE)
>>>> {
>>>>     if (! add_path_received())
>>>>     {
>>>>         xlog("L_ERR", "Adding PATH (with received) failed - LF_BASE");
>>>>         send_reply("500", "Internal path error, registration not 
>>>> stored");
>>>>         exit;
>>>>     }
>>>> }
>>>> else
>>>> {
>>>>     if (! add_path())
>>>>     {
>>>>         send_reply("500", "Internal path error, registration not 
>>>> stored");
>>>>         xlog("L_ERR", "Adding PATH (with received) failed - LF_BASE");
>>>>         exit;
>>>>     }
>>>> }
>>>>
>>>> route("R_RELAY_TO_REGISTRAR");
>>>> exit;
>>>>
>>>> ### OPTIONS
>>>>
>>>> if (method=="OPTIONS")
>>>> {
>>>>     if ($si == "CORE")
>>>>     {
>>>>         topology_hiding("U");
>>>>         if (! t_relay("0x05"))
>>>>         {
>>>>             send_reply("500", "Internal server error - failed to 
>>>> relay");
>>>>             xlog("L_ERR", "Unable to relay OPTIONS - LF_BASE");
>>>>         }
>>>>     }
>>>> }
>>>>
>>>>
>>>> The config on the core server looks like:
>>>> loadmodule "usrloc.so"
>>>> modparam("usrloc", "user_column",           "username")
>>>> modparam("usrloc", "domain_column",         "domain")
>>>> modparam("usrloc", "contact_column",        "contact")
>>>> modparam("usrloc", "expires_column",        "expires")
>>>> modparam("usrloc", "q_column",              "q")
>>>> modparam("usrloc", "callid_column",         "callid")
>>>> modparam("usrloc", "cseq_column",           "cseq")
>>>> modparam("usrloc", "methods_column",        "methods")
>>>> modparam("usrloc", "flags_column",          "flags")
>>>> modparam("usrloc", "user_agent_column",     "user_agent")
>>>> modparam("usrloc", "received_column",       "received")
>>>> modparam("usrloc", "path_column",           "path")
>>>> modparam("usrloc", "socket_column",         "socket")
>>>> modparam("usrloc", "use_domain",            0)
>>>> modparam("usrloc", "desc_time_order",       0)
>>>> modparam("usrloc", "timer_interval",        60)
>>>> modparam("usrloc", "db_url",                "DBURL")
>>>> modparam("usrloc", "db_mode",               2)
>>>> modparam("usrloc", "matching_mode",         0)
>>>> modparam("usrloc", "cseq_delay",            20)
>>>> modparam("usrloc", "nat_bflag",             6)
>>>>
>>>> #### nat helper module
>>>> loadmodule "nathelper.so"
>>>> modparam("nathelper", "natping_interval", 56)
>>>> modparam("nathelper", "ping_nated_only", 0)
>>>> modparam("nathelper", "natping_partitions", 1)
>>>> modparam("nathelper", "sipping_bflag", 8)
>>>> modparam("nathelper", "sipping_from", "sip:keepalive at DEFAULT_REALM")
>>>> modparam("nathelper", "sipping_method", "OPTIONS")
>>>>
>>>> # We want to send a keepalive on each registered UAC
>>>> if (proto == UDP)
>>>> {
>>>>     setbflag(8);
>>>>     xlog("L_INFO", "Nat keepalive sip_ping_flag - LF_BASE");
>>>> }
>>>>
>>>> if (! save("location", "vp1"))
>>>> {
>>>>     xlog("L_ERR", "Saving contact from EDGE failed - LF_BASE");
>>>>     exit;
>>>> }
>>>>
>>>> Thank you for any hint.
>>>>
>>>> Kind regards,
>>>> Julian Santer
>>>> Raiffeisen OnLine
>>>>
>>>> ps: @Bogdan: this is why we have ca. 550 entry's in the address 
>>>> table (permission module). If we solve the keepalives, only ca. 50 
>>>> entry's are remaining.
>>
>> _______________________________________________
>> Users mailing list
>> Users at lists.opensips.org
>> http://lists.opensips.org/cgi-bin/mailman/listinfo/users
> 
> _______________________________________________
> Users mailing list
> Users at lists.opensips.org
> http://lists.opensips.org/cgi-bin/mailman/listinfo/users
> 





More information about the Users mailing list