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@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@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