<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 TRANSITIONAL//EN">
<HTML>
<HEAD>
  <META HTTP-EQUIV="Content-Type" CONTENT="text/html; CHARSET=UTF-8">
  <META NAME="GENERATOR" CONTENT="GtkHTML/3.32.2">
</HEAD>
<BODY>
Hello,<BR>
<BR>
I am using Kamailio and nathelper to connect UAs behind a NAT.&nbsp; However, I want to use presence and RLS in this system as well.&nbsp; The problem I have is that the presence and RLS modules are not nathelper&nbsp; aware and the NOTIFY requests that they generate are targeted at the private network IP address and port of the UA.<BR>
<BR>
Has anyone any experience of this?&nbsp; Can anyone help?<BR>
<BR>
I had a cunning plan where, in route[NAT], I detected SUBSCRIBE requests that originate from behind a NAT (and do not have myself as the last hop).&nbsp; When I see a request like this I use add_contact_alias(), record_route() and forward it to myself.&nbsp; I then added a handle_ruri_alias() to the WITH_NAT section of route[RELAY].&nbsp; The theory being that an in-dialog NOTIFY from presence or RLS will use the route-set established by the SUBSCRIBE transaction.<BR>
<BR>
This almost works.&nbsp; The presence.winfo NOTIFY from the presence module and the initial presence NOTIFY from the RLS module make it back to the client successfully.&nbsp; However, when this forwarding of the SUBSCRIBE is in place the RLS subscriptions don't happen.&nbsp; I know it is the forward of the SUBSCRIBE that is the trigger behind this problem because simply commenting that out (and allowing the first SUBSCRIBE to get to RLS) makes the RLS subscriptions happen (but in this case the NOTIFYs get back to the client and are 404'd because the request URI is not correct).<BR>
<BR>
The only difference between the first SUBSCRIBE and the forwarded SUBSCRIBE is an additional &quot;Via:&quot; header and a &quot;Record-Route:&quot; header.<BR>
<BR>
I ran Kamailio with the -E -ddd options and observed that:
<UL>
    <LI>modules_k/rls/subscribe.c:rls_get_service_list() is outputting the line &quot;searching document for user sip:@&quot;
    <LI>This function is called by modules_k/rls/subscribe.c:rls_handle_subscribe() and the output suggests that GET_FROM_PURI(msg)-&gt;user and GET_FROM_PURI(msg)-&gt;host are empty strings
    <LI>However, parse_from_header(msg) is called near the top of rls_handle_subscribe() and clearly succeeds to find the &quot;From:&quot; header in the message
    <LI>As I mentioned above the forwarded SUBSCRIBE is almost identical to the first SUBSCRIBE, and so it does contain a valid &quot;From:&quot; header
</UL>
<BR>
All I can think of is that Kamailio is becoming confused by the two near-identical SUBSCRIBE requests and that the &quot;cleaning up&quot; of the first (statelessly forwarded) SUBSCRIBE is also &quot;cleaning up&quot; the forwarded SUBSCRIBE that I am currently working with?<BR>
<BR>
My route[NAT]:<BR>
<BLOCKQUOTE>
    route[NAT] {<BR>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; xlog(&quot;L_INFO&quot;, &quot;$rm: route[NAT]\n&quot;);<BR>
    #!ifdef WITH_NAT<BR>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; force_rport();<BR>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (nat_uac_test(&quot;19&quot;) &amp;&amp; $si!=&quot;MY_REAL_IP&quot; &amp;&amp; $si!=&quot;127.0.0.1&quot;) {<BR>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; xlog(&quot;L_INFO&quot;, &quot;&nbsp; Request from NAT'd UAC\n&quot;);<BR>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (is_method(&quot;REGISTER&quot;)) {<BR>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fix_nated_register();<BR>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else if (is_method(&quot;SUBSCRIBE&quot;)) {<BR>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; add_contact_alias();<BR>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; route(RECORD_ROUTE);<BR>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; forward(127.0.0.1, MY_REAL_PORT);<BR>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; exit;<BR>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else {<BR>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fix_nated_contact();<BR>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; setflag(FLT_NATS);<BR>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
    #!endif<BR>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return;<BR>
    }<BR>
</BLOCKQUOTE>
<BR>
My route[RECORD_ROUTE]:<BR>
<BLOCKQUOTE>
    route[RECORD_ROUTE]<BR>
    {<BR>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # remove preloaded route headers<BR>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; remove_hf(&quot;Route&quot;);<BR>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (is_method(&quot;INVITE|SUBSCRIBE&quot;))<BR>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; record_route();<BR>
    <BR>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return;<BR>
    }<BR>
    <BR>
</BLOCKQUOTE>
The start of my route[RELAY]:<BR>
<BLOCKQUOTE>
    route[RELAY] {<BR>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; xlog(&quot;L_INFO&quot;, &quot;$rm: route[RELAY]\n&quot;);<BR>
    #!ifdef WITH_NAT<BR>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (check_route_param(&quot;nat=yes&quot;)) {<BR>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; setbflag(FLB_NATB);<BR>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (isflagset(FLT_NATS) || isbflagset(FLB_NATB)) {<BR>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; route(RTPPROXY);<BR>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
    <BR>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; handle_ruri_alias();<BR>
    #!endif<BR>
</BLOCKQUOTE>
<BR>
Regards,<BR>
<BR>
Peter<BR>
<BR>
<TABLE CELLSPACING="0" CELLPADDING="0" WIDTH="100%">
<TR>
<TD>
<PRE>
-- 
Peter Dunkley
Technical Director
Crocodile RCS Ltd
</PRE>
</TD>
</TR>
</TABLE>
</BODY>
</HTML>