Hello,

I am using Kamailio and nathelper to connect UAs behind a NAT.  However, I want to use presence and RLS in this system as well.  The problem I have is that the presence and RLS modules are not nathelper  aware and the NOTIFY requests that they generate are targeted at the private network IP address and port of the UA.

Has anyone any experience of this?  Can anyone help?

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).  When I see a request like this I use add_contact_alias(), record_route() and forward it to myself.  I then added a handle_ruri_alias() to the WITH_NAT section of route[RELAY].  The theory being that an in-dialog NOTIFY from presence or RLS will use the route-set established by the SUBSCRIBE transaction.

This almost works.  The presence.winfo NOTIFY from the presence module and the initial presence NOTIFY from the RLS module make it back to the client successfully.  However, when this forwarding of the SUBSCRIBE is in place the RLS subscriptions don't happen.  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).

The only difference between the first SUBSCRIBE and the forwarded SUBSCRIBE is an additional "Via:" header and a "Record-Route:" header.

I ran Kamailio with the -E -ddd options and observed that:
All I can think of is that Kamailio is becoming confused by the two near-identical SUBSCRIBE requests and that the "cleaning up" of the first (statelessly forwarded) SUBSCRIBE is also "cleaning up" the forwarded SUBSCRIBE that I am currently working with?

My route[NAT]:
route[NAT] {
        xlog("L_INFO", "$rm: route[NAT]\n");
#!ifdef WITH_NAT
        force_rport();
        if (nat_uac_test("19") && $si!="MY_REAL_IP" && $si!="127.0.0.1") {
                xlog("L_INFO", "  Request from NAT'd UAC\n");
                if (is_method("REGISTER")) {
                        fix_nated_register();
                } else if (is_method("SUBSCRIBE")) {
                        add_contact_alias();
                       route(RECORD_ROUTE);
                       forward(127.0.0.1, MY_REAL_PORT);
                       exit;
                } else {
                        fix_nated_contact();
                }
                setflag(FLT_NATS);
        }
#!endif
        return;
}

My route[RECORD_ROUTE]:
route[RECORD_ROUTE]
{
        # remove preloaded route headers
        remove_hf("Route");
        if (is_method("INVITE|SUBSCRIBE"))
                record_route();

        return;
}

The start of my route[RELAY]:
route[RELAY] {
        xlog("L_INFO", "$rm: route[RELAY]\n");
#!ifdef WITH_NAT
        if (check_route_param("nat=yes")) {
                setbflag(FLB_NATB);
        }
        if (isflagset(FLT_NATS) || isbflagset(FLB_NATB)) {
                route(RTPPROXY);
        }

        handle_ruri_alias();
#!endif

Regards,

Peter

-- 
Peter Dunkley
Technical Director
Crocodile RCS Ltd