[Devel] Extended nathelper

Walter Schober walter.schober at neotel.at
Fri Mar 3 16:02:28 CET 2006


Hi!

The difference is, that a received parameter is added behind the Contact URI
not as URI parameter, but a contact parameter:
Contact:
<sip:0123456 at 1.2.3.4:5060;x-orig=11.11.11.11:5064;x-orig-nat=192.168.40.99:5
064>;received="sip:11.11.11.11:5064"

And that one is not stored in the ContactDB of the next proxy. That one
stores the SIP URI in the contact only.
Thus the received parameter is not included in the sucessive Invite.

BTW: I cannot change the behaviour of that proxy.

Br
Walter

-----Original Message-----
From: Bogdan-Andrei Iancu [mailto:bogdan at voice-system.ro] 
Sent: Friday, March 03, 2006 12:51 PM
To: Walter Schober
Cc: devel at openser.org
Subject: Re: [Devel] Extended nathelper

Hi Walter,

thanks for email.

First I want to see if there is some difference between the new function 
you add and the already existing function add_rcv_param().
    http://openser.org/docs/modules/1.0.x/nathelper.html#AEN331

Regards,
Bogdan


Walter Schober wrote:

> Hi!
>  
> Maybe someone find's that useful. It's nearly the same than mangler, 
> but the difference is, that it stores the old values, too.
>  
> Short description: nathelper stores original contact + addr:port from 
> where the request was received and puts itself in the list to register 
> a client on the next proxy. Keepalive has to be done by other methods.
>  
> See details in attached readme.
>  
> /Walter
>  
>
>------------------------------------------------------------------------
>
>Nathelper Patch for registering on remote proxies
>-------------------------------------------------
>
>V 0.2 
>20060212
>WSC walter.schober at neotel.at
>
>-------------------------------------------------
>
>Description: Openser is placed in front of another proxy not supporting RFC
3327 (Patch Header Support).
>Using module nathelper the OpenSER detects nated clients and modifies the
Contact field of the register. 
>The Contact header is expanded by a new "route", which is substituted
instead of the IP:Port the 
>register is received from. 
>The operation is done after fixing the Contact in
>	fix_nated_contact();
>Original fix_nated_contact() just replaces the host:port with host:port
from where the request was 
>received from.
>If the module parameter "contact_expander" is set, this value is inserted
behind the user@ replacing the 
>fixed original host port.
>e.g. original Contact is
>	Contact:
<sip:user at 192.168.1.1:5555;some-uri-param>;additional-params
>
>the fix_nated_contact() replaces that with the IP from where the request
was received from:
>	Contact: <sip:user at some_ip:port;some-uri-param>;additional-params
>
>If contact_expander is set, this string is inserted as
>	Contact:
<sip:user at value-of-contact-expander;x-orig=some_ip:port;x-orig-nat=original-
contact;some-uri-param>;additional-params
>
>e.g. contact_exander = 1.2.3.4:5066, resulting in
>	Contact:
<sip:user at 1.2.3.4:5066;x-orig=33.44.55.66:5066;x-orig-nat=192.168.1.1:5062;s
ome-uri-param>;additional-params
>	
>A Invite to such a contact results in 
>	INVITE
sip:user at 1.2.3.4:5066;x-orig=33.44.55.66:5066;x-orig-nat=192.168.1.1:5062;so
me-uri-param
>
>which could be replaced by e.g. textops and avp_ops
>        avp_write("$ruri","$x-orig");
>        if (subst_uri('/^sip:(.+)@.*;x-orig-nat=(.*)$/sip:\1@\2/i')) {
>
avp_subst("$x-orig","/^(.*)@.*;x-orig=(.*);x-orig-nat=.*$/\1@\2/");
>                avp_pushto("$duri","$x-orig");
>		route(1);
>
>forwarding to the original contact address, but to NATed contact address.
>
>
>New Module Param:
>--------------------------------------------------
>modparam("nathelper", "contact_expander", "1.2.3.4:5066")
>
>
>New Function Call:
>--------------------------------------------------
>None.
>
>
>Example:
>--------------------------------------------------
># add myself as an alias
>alias=1.2.3.4:5066
>
># set contact_expander to myself
>modparam("nathelper", "contact_expander", "1.2.3.4:5066")
>
># avpops
>modparam("avpops", "avp_aliases", "x-orig=i:32")
>
># is request is directed to me
>if (uri==myself) {
>	# check, if we have to restore old destination
>        avp_write("$ruri","$x-orig");
>        if (subst_uri('/^sip:(.+)@.*;x-orig-nat=(.*)$/sip:\1@\2/i')) {
>
avp_subst("$x-orig","/^(.*)@.*;x-orig=(.*);x-orig-nat=.*$/\1@\2/");
>                avp_pushto("$duri","$x-orig");
>		# forwared to destination
>		route(1);
>		return;
>	}
>}
>
># ... do something ...
>
># fix the Register as usual
>if (method=="REGISTER" || method=="INVITE" || method=="REFER") {
>	if (nat_uac_test("18")) {
>		fix_nated_contact();
>		force_rport();
>		append_hf("P-hint: nathelper applied\r\n");
>	} else {
>		append_hf("P-hint: nathelper not applied\r\n");
>	};
>};
>
># ... continue ... do something with the request
>
>
>Installation
>----------------------------------------------------
>Patch the nathelper.c located in modules/nathelper executing
>	cp nathelper.c nathelper.c.orig
>	patch nathelper.c <nathelper.patch
>	
>Rebuild module nathelper
>	make modules=modules/nathelper modules
>	make install
>
>The patch is based on OpenSER 1.0.0.
>
>Changes are in function fix_nated_contact_f() only + parameter definitions.
>	
>Restart OpenSER.
>
>
>-----------------------------------------------------
>
>
>New function fix_nated_contact_f():
>
>static int
>fix_nated_contact_f(struct sip_msg* msg, char* str1, char* str2)
>{
>        int offset, len, len1;
>        char *cp, *buf, temp[2];
>        contact_t *c;
>        struct lump *anchor;
>        struct sip_uri uri;
>        str hostport;
>
>        if (get_contact_uri(msg, &uri, &c) == -1)
>                return -1;
>        if ((c->uri.s < msg->buf) || (c->uri.s > (msg->buf + msg->len))) {
>                LOG(L_ERR, "ERROR: you can't call fix_nated_contact twice,
"
>                    "check your config!\n");
>                return -1;
>        }
>
>        offset = c->uri.s - msg->buf;
>        anchor = del_lump(msg, offset, c->uri.len, HDR_CONTACT_T);
>        if (anchor == 0)
>                return -1;
>
>        hostport = uri.host;
>        if (uri.port.len > 0)
>                hostport.len = uri.port.s + uri.port.len - uri.host.s;
>
>        cp = ip_addr2a(&msg->rcv.src_ip);
>        len = c->uri.len + strlen(cp) + 6 /* :port */ - hostport.len + 1;
>
>        if (contact_expander.len) {
>                LOG(L_DBG, "Expanding Contact: %s\n", contact_expander.s);
>                len += contact_expander.len + hostport.len + 20;
>        }
>        buf = pkg_malloc(len);
>
>        if (buf == NULL) {
>                LOG(L_ERR, "ERROR: fix_nated_contact: out of memory\n");
>                return -1;
>        }
>
>        temp[0] = hostport.s[0];
>        temp[1] = c->uri.s[c->uri.len];
>        c->uri.s[c->uri.len] = hostport.s[0] = '\0';
>
>        if (contact_expander.len) {
>                // sip:user:password at host:port ->
>                //
sip:user:password at HOST:PORT;x-orig=host:port;x-orig-nat=priv-host:priv-port
>                len1 = snprintf(buf, len,
"%s%s;x-orig=%s:%d;x-orig-nat=%c%s", c->uri.s,
>                        contact_expander.s,
>                        cp, msg->rcv.src_port,
>                        temp[0],
>                        hostport.s + 1);
>        } else {
>                len1 = snprintf(buf, len, "%s%s:%d%s", c->uri.s, cp,
msg->rcv.src_port,
>                        hostport.s + hostport.len);
>        }
>
>        if (len1 < len)
>                len = len1;
>        hostport.s[0] = temp[0];
>        c->uri.s[c->uri.len] = temp[1];
>        if (insert_new_lump_after(anchor, buf, len, HDR_CONTACT_T) == 0) {
>                pkg_free(buf);
>                return -1;
>        }
>        c->uri.s = buf;
>        c->uri.len = len;
>
>        return 1;
>}
>
>  
>
>------------------------------------------------------------------------
>
>_______________________________________________
>Devel mailing list
>Devel at openser.org
>http://openser.org/cgi-bin/mailman/listinfo/devel
>  
>






More information about the Devel mailing list