[sr-dev] git:master: nathelper(k): hanlde sip ping replies

Daniel-Constantin Mierla miconda at gmail.com
Mon Aug 20 10:14:05 CEST 2012


Hello,

On 8/20/12 9:57 AM, Klaus Darilion wrote:
> Ok. Just found the patch to the README :-)
>
> Nevertheless, it would be useful if it works in all DB modes and for 
> all transports (not only UDP).

for db can be made by adding a new column to store the last keepalive 
timestamp. Besides lack of time, for the moment I just feared of too 
much database ops, because each time there is a keepalive reply, there 
will be an update to database. If there are lot of natted contacts, it 
will result in many database ops (replies being received randomly and 
handled by differente processes, it will be hard to stack many updates 
in a single sql command).

UDP is the only transport for which nathelper module sends keepalive. 
Perhaps it should do also for SCTP, this has to be investigated, but I 
am not aware of any sip phone with sctp support.

For tcp/tls, imo, the natted contact should be removed if the connection 
is not available anymore. This is planned to happen, but I cannot say a 
date right now from my point of view.

Cheers,
Daniel

>
> regards
> Klaus
>
> On 20.08.2012 09:40, Klaus Darilion wrote:
>> Is there any action for missing replies?
>>
>> regards
>> Klaus
>>
>> On 19.08.2012 21:30, Daniel-Constantin Mierla wrote:
>>> Module: sip-router
>>> Branch: master
>>> Commit: a308226ced8b9807ee91f8e24c72d778e5a62e86
>>> URL:
>>> http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=a308226ced8b9807ee91f8e24c72d778e5a62e86 
>>>
>>>
>>>
>>> Author: Daniel-Constantin Mierla <miconda at gmail.com>
>>> Committer: Daniel-Constantin Mierla <miconda at gmail.com>
>>> Date:   Sun Aug 19 12:56:24 2012 +0200
>>>
>>> nathelper(k): hanlde sip ping replies
>>>
>>> - new parameter 'keepalive_timeout' to detect if a contact does not
>>>    reply to sip ping requests
>>> - default is 0 (feature disabled) - it should be few times more than
>>>    natping_interval
>>>
>>> ---
>>>
>>>   modules_k/nathelper/nathelper.c  |  123
>>> +++++++++++++++++++++++++++++++++++++-
>>>   modules_k/nathelper/sip_pinger.h |    2 +-
>>>   2 files changed, 123 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/modules_k/nathelper/nathelper.c
>>> b/modules_k/nathelper/nathelper.c
>>> index e5bfc89..c27d073 100644
>>> --- a/modules_k/nathelper/nathelper.c
>>> +++ b/modules_k/nathelper/nathelper.c
>>> @@ -203,6 +203,7 @@
>>>   #include "../../parser/parse_to.h"
>>>   #include "../../parser/parse_uri.h"
>>>   #include "../../parser/parser_f.h"
>>> +#include "../../parser/parse_methods.h"
>>>   #include "../../parser/sdp/sdp.h"
>>>   #include "../../resolve.h"
>>>   #include "../../timer.h"
>>> @@ -295,6 +296,7 @@ static int fix_nated_register_f(struct sip_msg *,
>>> char *, char *);
>>>   static int fixup_fix_nated_register(void** param, int param_no);
>>>   static int fixup_fix_sdp(void** param, int param_no);
>>>   static int add_rcv_param_f(struct sip_msg *, char *, char *);
>>> +static int nh_sip_reply_received(sip_msg_t *msg);
>>>
>>>   static void nh_timer(unsigned int, void *);
>>>   static int mod_init(void);
>>> @@ -345,6 +347,8 @@ static char *natping_socket = 0;
>>>   static int raw_sock = -1;
>>>   static unsigned int raw_ip = 0;
>>>   static unsigned short raw_port = 0;
>>> +static int nh_keepalive_timeout = 0;
>>> +static request_method_t sipping_method_id = 0;
>>>
>>>
>>>   /*0-> disabled, 1 ->enabled*/
>>> @@ -403,6 +407,8 @@ static param_export_t params[] = {
>>>       {"sipping_bflag",         INT_PARAM, &sipping_flag          },
>>>       {"natping_processes",     INT_PARAM, &natping_processes     },
>>>       {"natping_socket",        STR_PARAM, &natping_socket        },
>>> +    {"keepalive_timeout",     INT_PARAM, &nh_keepalive_timeout  },
>>> +
>>>       {0, 0, 0}
>>>   };
>>>
>>> @@ -422,7 +428,7 @@ struct module_exports exports = {
>>>       mod_pvs,     /* exported pseudo-variables */
>>>       0,           /* extra processes */
>>>       mod_init,
>>> -    0,           /* reply processing */
>>> +    nh_sip_reply_received, /* reply processing */
>>>       mod_destroy, /* destroy function */
>>>       child_init
>>>   };
>>> @@ -646,7 +652,16 @@ mod_init(void)
>>>                   LM_ERR("SIP ping enabled, but SIP ping method is
>>> empty!\n");
>>>                   return -1;
>>>               }
>>> +            if(nh_keepalive_timeout>0 &&
>>> ul.set_keepalive_timeout!=NULL) {
>>> + ul.set_keepalive_timeout(nh_keepalive_timeout);
>>> +            }
>>> +
>>>               sipping_method.len = strlen(sipping_method.s);
>>> +            if(parse_method_name(&sipping_method, &sipping_method_id)
>>> < 0) {
>>> +                LM_ERR("invalid SIP ping method [%.*s]!\n",
>>> sipping_method.len,
>>> +                        sipping_method.s);
>>> +                return -1;
>>> +            }
>>>               sipping_from.len = strlen(sipping_from.s);
>>>               exports.response_f = sipping_rpl_filter;
>>>               init_sip_ping();
>>> @@ -2000,3 +2015,109 @@ fix_nated_register_f(struct sip_msg* msg,
>>> char* str1, char* str2)
>>>
>>>       return 1;
>>>   }
>>> +
>>> +/**
>>> + * handle SIP replies
>>> + */
>>> +static int nh_sip_reply_received(sip_msg_t *msg)
>>> +{
>>> +    to_body_t *fb;
>>> +    str ruid;
>>> +    str ah;
>>> +    unsigned int aorhash;
>>> +    char *p;
>>> +
>>> +    if(nh_keepalive_timeout<=0)
>>> +        return 1;
>>> +    if(msg->cseq==NULL && ((parse_headers(msg, HDR_CSEQ_F, 0)==-1)
>>> +            || (msg->cseq==NULL)))
>>> +    {
>>> +        LM_ERR("no CSEQ header\n");
>>> +        goto done;
>>> +    }
>>> +    if(sipping_method_id!=METHOD_UNDEF &&
>>> sipping_method_id!=METHOD_OTHER)
>>> +    {
>>> +        if(get_cseq(msg)->method_id!=sipping_method_id)
>>> +            goto done;
>>> +    } else {
>>> +        if(sipping_method_id==METHOD_OTHER)
>>> +        {
>>> + if(get_cseq(msg)->method.len!=sipping_method.len)
>>> +                goto done;
>>> +            if(strncmp(get_cseq(msg)->method.s, sipping_method.s,
>>> +                        sipping_method.len)!=0)
>>> +                goto done;
>>> +        } else {
>>> +            goto done;
>>> +        }
>>> +    }
>>> +    /* there must be no second via */
>>> +    if ( ! (parse_headers(msg, HDR_VIA2_F, 0)==-1
>>> +            || (msg->via2==0) || (msg->via2->error!=PARSE_OK)) )
>>> +        goto done;
>>> +
>>> +    /* from uri check */
>>> +    if((parse_from_header(msg))<0)
>>> +    {
>>> +        LM_ERR("cannot parse From header\n");
>>> +        goto done;
>>> +    }
>>> +
>>> +    fb = get_from(msg);
>>> +    if(fb->uri.len!=sipping_from.len
>>> +            || strncmp(fb->uri.s, sipping_from.s, 
>>> sipping_from.len)!=0)
>>> +        goto done;
>>> +
>>> +    /* from-tag is: ruid-aorhash-counter */
>>> +    if(fb->tag_value.len<=0)
>>> +        goto done;
>>> +
>>> +    LM_DBG("checking nathelper keepalive reply [%.*s]\n",
>>> fb->tag_value.len,
>>> +                fb->tag_value.s);
>>> +
>>> +    /* skip counter */
>>> +    p = q_memrchr(fb->tag_value.s, '-', fb->tag_value.len);
>>> +    if(p==NULL) {
>>> +        LM_DBG("from tag format mismatch [%.*s]\n", fb->tag_value.len,
>>> +                fb->tag_value.s);
>>> +        goto done;
>>> +    }
>>> +    /* aor hash */
>>> +    ah.len = p - fb->tag_value.s;
>>> +    aorhash = 0;
>>> +    p = q_memrchr(fb->tag_value.s, '-', ah.len);
>>> +    if(p==NULL) {
>>> +        LM_DBG("from tag format mismatch [%.*s]!\n", 
>>> fb->tag_value.len,
>>> +                fb->tag_value.s);
>>> +        goto done;
>>> +    }
>>> +    ah.s = p + 1;
>>> +    ah.len = fb->tag_value.s + ah.len - ah.s;
>>> +
>>> +    LM_DBG("aor hash string is [%.*s] (%d)\n", ah.len, ah.s, ah.len);
>>> +
>>> +    if(ah.len<=0 || reverse_hex2int(ah.s, ah.len, &aorhash)<0)
>>> +    {
>>> +        LM_DBG("cannot get aor hash in [%.*s]\n", fb->tag_value.len,
>>> +                fb->tag_value.s);
>>> +        goto done;
>>> +    }
>>> +    LM_DBG("aor hash is [%u] string [%.*s]\n", aorhash, ah.len, ah.s);
>>> +
>>> +    ruid.s = fb->tag_value.s;
>>> +    ruid.len = ah.s - ruid.s - 1;
>>> +
>>> +    if(ruid.len<=0)
>>> +    {
>>> +        LM_DBG("cannot get ruid in [%.*s]\n", fb->tag_value.len,
>>> +                fb->tag_value.s);
>>> +        goto done;
>>> +    }
>>> +
>>> +    LM_DBG("reply for keepalive of [%.*s:%u]\n", ruid.len, ruid.s,
>>> aorhash);
>>> +
>>> +    ul.refresh_keepalive(aorhash, &ruid);
>>> +done:
>>> +    /* let the core handle further the reply */
>>> +    return 1;
>>> +}
>>> diff --git a/modules_k/nathelper/sip_pinger.h
>>> b/modules_k/nathelper/sip_pinger.h
>>> index c6098b3..dce4bd8 100644
>>> --- a/modules_k/nathelper/sip_pinger.h
>>> +++ b/modules_k/nathelper/sip_pinger.h
>>> @@ -129,7 +129,7 @@ static inline char* build_sipping(str *curi,
>>> struct socket_info* s, str *path,
>>>                   1 + s->port_no_str.len + s_len(";branch=0") +
>>>           (path->len ? (s_len(CRLF"Route: ") + path->len) : 0) +
>>>           s_len(CRLF"From: ") +  sipping_from.len + s_len(";tag=") +
>>> -                sipping_from.len + 1 + 8 + 1 + 8 +
>>> +                ruid->len + 1 + 8 + 1 + 8 +
>>>           s_len(CRLF"To: ") + curi->len +
>>>           s_len(CRLF"Call-ID: ") + sipping_callid.len + 1 + 8 + 1 + 8
>>> + 1 +
>>>                   s->address_str.len +
>>>
>>>
>>> _______________________________________________
>>> sr-dev mailing list
>>> sr-dev at lists.sip-router.org
>>> http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev
>>>
>>
>> _______________________________________________
>> sr-dev mailing list
>> sr-dev at lists.sip-router.org
>> http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev
>
> _______________________________________________
> sr-dev mailing list
> sr-dev at lists.sip-router.org
> http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev

-- 
Daniel-Constantin Mierla - http://www.asipto.com
http://twitter.com/#!/miconda - http://www.linkedin.com/in/miconda
Kamailio Advanced Training, Seattle, USA, Sep 23-26, 2012 - http://asipto.com/u/katu
Kamailio Practical Workshop, Netherlands, Sep 10-12, 2012 - http://asipto.com/u/kpw




More information about the sr-dev mailing list