[Devel] Extended nathelper
Bogdan-Andrei Iancu
bogdan at voice-system.ro
Fri Mar 3 12:50:54 CET 2006
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;some-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;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 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