[prev in list] [next in list] [prev in thread] [next in thread] 

List:       sr-dev
Subject:    [Devel] Extended nathelper
From:       walter.schober () neotel ! at (Walter Schober)
Date:       2006-02-28 8:48:12
Message-ID: 20060228074822.DD0924C084 () neosrv01
[Download RAW message or body]

Skipped content of type multipart/alternative-------------- next part --------------
Nathelper Patch for registering on remote proxies
-------------------------------------------------

V 0.2 
20060212
WSC walter.schober@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@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@some_ip:port;some-uri-param>;additional-params

If contact_expander is set, this string is inserted as
	Contact: <sip:user@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@1.2.3.4:5066;x-orig=33.44.55.66:5066;x-orig-nat=192.168.1.1:5062;some-uri-param>;additional-params
  
A Invite to such a contact results in 
	INVITE sip:user@1.2.3.4:5066;x-orig=33.44.55.66:5066;x-orig-nat=192.168.1.1:5062;some-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@host:port ->
                // sip:user:password@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;
}

-------------- next part --------------
A non-text attachment was scrubbed...
Name: nathelper.patch
Type: application/octet-stream
Size: 2229 bytes
Desc: not available
Url : http://openser.org/pipermail/devel/attachments/20060228/ab2ff2e3/nathelper.obj


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic