[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