Hi All.
I've been toying with ideas on how to determine if a re-INVITE message
should be mediaproxy enabled or not.
I only want mediaproxy to be used if either callee __OR__ caller are
behind a NAT device. Therefore I cannot just blindly call
use_media_session() in my loose_route() logic.
There have been a few posts in the archives about possibly embedding a
NAT tag in the original INVITE message and searching for it when
processing re-INVITE messages.
Although I did get this to work I have concerns this will break some
SIP processing eventually.
So I came up with the following idea which uses AVPOPS in my
loose_route() branch. The problem is I do not know if this is legal
and/or will work in all cases.
The whole basis of this code is that a re-INVITE reverses some of the
headers in the INVITE message and the "domain" from the orignal INVITE
(ie, the caller) is still present in, but is located in the <FROM>
header. So I just copy the domain part to the RURI and
lookup(location) is called to set nat_flag 6, and finally I revert the
RURI.
So if my original INVITE message is this:
INVITE sip:4075552279@sip.mycompany.com;user=phone SIP/2.0.
Via: SIP/2.0/UDP 192.168.0.83:39627;branch=z9hG4bKef3a7e6727dfd10d.
From: "Paul Hazlett"
<sip:3215591111@sip.mycompany.com;user=phone>;tag=3b39918cbd7276b5.
To: <sip:4075552279@sip.mycompany.com;user=phone>.
Contact: <sip:3215591111@192.168.0.83:39627;user=phone>.
Supported: replaces.
Call-ID: 46c60a9c891bc4e8(a)192.168.0.83.
CSeq: 7526 INVITE.
User-Agent: Grandstream BT100 1.0.5.22.
Max-Forwards: 70.
Allow: INVITE,ACK,CANCEL,BYE,NOTIFY,REFER,OPTIONS,INFO,SUBSCRIBE.
Content-Type: application/sdp.
Content-Length: 396.
The re-INVITE would look like this:
INVITE sip:3215591111@66.90.46.29:39627;user=phone SIP/2.0.
Via: SIP/2.0/UDP 216.229.127.60:5060;branch=z9hG4bKd77b196c4f6-d84acd16.
Via: SIP/2.0/UDP 216.229.118.76:4060;branch=z9hG4bK01cc36bc450a3a60.
To: "Paul Hazlett"
<sip:3215591111@216.229.127.60;user=phone>;tag=3b39918cbd7276b5.
From: <sip:4075552279@sip.mycompany.com;user=phone>;tag=0682cabe.
Call-ID: 46c60a9c891bc4e8(a)192.168.0.83.
CSeq: 20292 INVITE.
Max-Forwards: 69.
Contact: sip:4075551111@216.229.118.76:4060.
Record-Route: <sip:216.229.127.60:5060;lr>.
Route: <sip:10.3.0.221:5060;ftag=3b39918cbd7276b5;lr>.
Allow: OPTIONS, INVITE, CANCEL, ACK, BYE, PRACK, INFO.
Accept: multipart/mixed, application/sdp, application/isup,
application/dtmf, application/dtmf-relay.
Supported: timer.
Session-Expires: 240;refresher=uac.
Content-Disposition: session;handling=required.
Content-Type: application/sdp.
Content-Length: 247.
Can anyone review the code snippet below and comment?
loadmodule "/usr/local/lib/ser/modules/avpops.so"
modparam("registrar", "nat_flag", 6)
route {
# sanity checks
if (loose_route()) {
if (method=="INVITE") {
# get domain portion of the <From:> header
avp_write("$from/domain", "i:30");
# save the domain portion of the RURI
avp_write("$ruri/domain", "i:31");
# replace the domain portion of the RURI with the
# domain from the <FROM> header
avp_pushto("$ruri/domain", "i:30");
# call lookup(location) to set nat_flag 6
lookup("location");
# restore the RURI
avp_pushto("$ruri/domain", "i:31");
# discard the AVPs
avp_delete("i:30");
avp_delete("i:31");
};
if (isflagset(6)) {
force_rport();
fix_nated_contact();
use_media_proxy();
};
route(1); # t_relay() the message
break;
};
# normal processing
}
route[1] {
t_on_reply("1");
if (!t_relay()) {
if (method=="INVITE" || method=="ACK") {
end_media_session();
};
sl_reply_error();
};
}
onreply_route[1] {
# Not all 2xx messages have a content body so here we
# make sure our Content-Length > 0 to avoid a parse error
if (isflagset(6)
&&
(status=~"(180)|(183)|2[0-9][0-9]")) {
if (!search("^Content-Length:\ 0")) {
use_media_proxy();
};
};
if (client_nat_test("1")) {
fix_nated_contact();
};
}
Regards,
Paul
Show replies by date