[SR-Users] Manipulating SDP IP for Inbound Calls

Daniel-Constantin Mierla miconda at gmail.com
Tue Aug 4 11:05:07 CEST 2020


Hello,


hard to track the execution path without a test environment ... I would
suggest to load debugger module and enable cfgtrace for it to see what
actions in configuration file are executed, to be sure it gets to the
fix_nated_sdp().


Cheers,
Daniel


On 04.08.20 10:44, Edward Romanenco wrote:
> I tried using nathelper in the following way - 
> fix_nated_sdp("2","XX.XX.XX.XX"); - it still shows my internal IP.
> Attaching my request routes, can you kindly check and see if I am
> using it correctly?
>
> *SDP*
> .
> v=0.
> o=FreeSWITCH 1596486133 1596486134 IN IP4 172.18.0.40.
> s=FreeSWITCH.
> c=IN IP4 172.18.0.40.
> t=0 0.
> m=audio 43954 RTP/AVP 8 101.
> a=rtpmap:8 PCMA/8000.
> a=rtpmap:101 telephone-event/8000.
> a=fmtp:101 0-16.
> a=ptime:20.
>
>
> *REQUEST ROUTES*
> request_route {
>     setflag(22);
>     route(REQINIT);
>
>     if (is_method("CANCEL")) {
>         if (t_check_trans()) {
>             route(RELAY);
>         }
>         exit;
>     }
>
>     route(WITHINDLG);
>
>     if(t_precheck_trans()) {
>         t_check_trans();
>         exit;
>     }
>     t_check_trans();
>
>     remove_hf("Route");
>     if (is_method("INVITE|SUBSCRIBE")){// &&
> is_present_hf("X-SESSION-ID")){
>       record_route();
>     }
>     if (is_method("INVITE")) {
>         setflag(FLT_ACC);
>     }
>
>     if ($rU==$null) {
>         sl_send_reply("484","Address Incomplete");
>         exit;
>     }
>
>     route(OUTGOING);
>     route(PSTN);
>     route(INCOMING);
>     route(RELAY);
> }
>
> route[REMOVE_X_HEADERS] {
> if(is_present_hf("X-SESSION-ID")) {
>         remove_hf("X-FS-Support");
>    remove_hf("X-Src");
>    remove_hf("X-DESTINATIONS");
>    remove_hf("X-SESSION-ID");
>     }
>         xinfo("Remove X Headers; Contact Header is $ct");
> }
>
> route[INCOMING] {
>     if(is_present_hf("X-SESSION-ID")) {
>       return;
>     }
>
> if(ds_is_from_list("4")) {
> route(TRANSLATE_SRC_IN);
> }
>
> route(REQUEST_PERMISSIONS);
> fix_nated_sdp("2","XX.XX.XX.XX");
>     exit;
> }
>
> route[REQUEST_PERMISSIONS] {
>     $var(body) = 0;
>     $var(from) = $fU;
>
>     if($(var(from){s.substr,1,4})=="0972") {
>         $var(from)=$(var(from){s.substr,2,0});
>         $fU = $var(from);
>     }
>
>     jansson_set("string", "from", "$var(from)", "$var(body)");
>
>     if(is_present_hf("Diversion")) {
>         xlog("L_INFO", "Call has been forwarded.");
>         jansson_set("string","to","$oU","$var(body)");
>     } else {
>    jansson_set("string","to","$tU","$var(body)");
>     }
>
>     jansson_set("string","forcepstn","false","$var(body)");
>     jansson_set("string", "source", "EGRESS", "$var(body)");
>     $http_req(all) = $null;
>     $http_req(method) = "POST";
>     $http_req(hdr) = "Content-Type: application/json";
>     $http_req(hdr) = "Accept: application/json";
>     $http_req(hdr) = "Connection: keep-alive";
>     $http_req(body) = $var(body);
>     $var(re_url)= "https://VNVHOST/voiceandvideo/makeCall";
>     t_newtran();
>
>     if (http_async_query("$var(re_url)", "REQUEST_PERMISSIONS_REPLY")
> < 0) {
>         t_reply("500", "Server Internal Error");
>         exit;
>     }
> }
>
> route[REQUEST_PERMISSIONS_REPLY] {
>     if ($(http_err{s.len})) {
>         xlog("L_ERR","Got error from server 1");
>    t_reply("500", "Server Internal Error");
>         exit;
>     } else if ($http_rs != 200) {
>         xlog("L_ERR","Got error from server 2");
>         t_reply("500", "Server Error");
>         exit;
>     }
>
>     # Populate dialog variables for CDR Creation
>     $var(count) = 0;
>     jansson_get("list",$http_rb,"$dlg_var(destinations_array)");
>     jansson_get("msgID", $http_rb, "$dlg_var(session_id)");
>     jansson_get("resultCode",$http_rb,"$dlg_var(resultCode)");
>
>     if($dlg_var(resultCode)!=0) {
>         t_reply("500","Server Internal Error");
>         exit;
>     }
>
>     ## EGRESS Server Information
>     route(ADD_TELEMESSAGE_HDRS);
>     $var(setid) = "1";
>
>     if(!ds_select_dst("1", "4")) {
>         send_reply("404", "No destination");
>         exit;
>     }
>
>     route(RELAY);
>     exit;
> }
>
> route[RELAY] {
>     if (is_method("INVITE|BYE|SUBSCRIBE|UPDATE")) {
>         if(!t_is_set("branch_route")) {
>             t_on_branch("MANAGE_BRANCH");
>         }
>     }
>
>     if (is_method("INVITE|SUBSCRIBE|UPDATE")) {
>         if(!t_is_set("onreply_route")) {
>             t_on_reply("MANAGE_REPLY");
>         }
>     }
>     if (is_method("INVITE")) {
>         if(!t_is_set("failure_route")) {
>             t_on_failure("MANAGE_FAILURE");
>         }
>     }
>
>     if (!t_relay()) {
>         sl_reply_error();
>     }
>
>     exit;
> }
>
> # Per SIP request initial checks
> route[REQINIT] {
> #!ifdef WITH_ANTIFLOOD
>     # flood detection from same IP and traffic ban for a while
>     # be sure you exclude checking trusted peers, such as pstn gateways
>     # - local host excluded (e.g., loop to self)
>     if(src_ip!=myself) {
>         if($sht(ipban=>$si)!=$null) {
>             # ip is already blocked
>             xdbg("request from blocked IP - $rm from $fu (IP:$si:$sp)\n");
>             exit;
>         }
>         if (!pike_check_req()) {
>             xlog("L_ALERT","ALERT: pike blocking $rm from $fu
> (IP:$si:$sp)\n");
>             $sht(ipban=>$si) = 1;
>             exit;
>         }
>     }
> #!endif
>     if($ua =~ "friendly-scanner|sipcli|VaxSIPUserAgent") {
>         # silent drop for scanners - uncomment next line if want to reply
>         # sl_send_reply("200", "OK");
>         exit;
>     }
>
>     if (!mf_process_maxfwd_header("10")) {
>         sl_send_reply("483","Too Many Hops");
>         exit;
>     }
>
>     if(is_method("OPTIONS") && uri==myself && $rU==$null) {
>         sl_send_reply("200","Keepalive");
>         exit;
>     }
>
>     if(!sanity_check("1511", "7")) {
>         xlog("Malformed SIP message from $si:$sp\n");
>         exit;
>     }
> }
>
> # Handle requests within SIP dialogs
> route[WITHINDLG] {
>     xlog("L_ERR","Entering withindlgs");
>     if (!has_totag()) return;
>
>     # sequential request withing a dialog should
>     # take the path determined by record-routing
>     if (loose_route()) {
>         xlog("L_ERR","loose route");
>         route(DLGURI);
>         if (is_method("BYE")) {
>             xlog("L_ERR","BYE recevied in loose route");
>             setflag(FLT_ACC); # do accounting ...
>             setflag(FLT_ACCFAILED); # ... even if the transaction fails
>         } else if ( is_method("ACK") ) {
>             # ACK is forwarded statelessly
>             route(NATMANAGE);
>         } else if ( is_method("NOTIFY") ) {
>             # Add Record-Route for in-dialog NOTIFY as per RFC 6665.
>             xlog("L_ERR","*****************1 Adding rr");
>           record_route();
>         }
>
>         route(RELAY);
>         exit;
>     }
>
>     if (is_method("SUBSCRIBE") && uri == myself) {
>         # in-dialog subscribe requests
>         route(PRESENCE);
>         exit;
>     }
>     if ( is_method("ACK") ) {
>         if ( t_check_trans() ) {
>             # no loose-route, but stateful ACK;
>             # must be an ACK after a 487
>             # or e.g. 404 from upstream server
>             route(RELAY);
>             exit;
>         } else {
>             # ACK without matching transaction ... ignore and discard
>             exit;
>         }
>     }
>     sl_send_reply("404","Not here");
>     exit;
> }
>
> # Handle SIP registrations
> route[REGISTRAR] {
>     if (!is_method("REGISTER")) return;
>
>     if(isflagset(FLT_NATS)) {
>         setbflag(FLB_NATB);
> #!ifdef WITH_NATSIPPING
>         # do SIP NAT pinging
>         setbflag(FLB_NATSIPPING);
> #!endif
>     }
>     if (!save("location")) {
>         sl_reply_error();
>     }
>     exit;
> }
>
> # User location service
> route[LOCATION] {
>
> #!ifdef WITH_SPEEDDIAL
>     # search for short dialing - 2-digit extension
>     if($rU=~"^[0-9][0-9]$") {
>         if(sd_lookup("speed_dial")) {
>             route(SIPOUT);
>         }
>     }
> #!endif
>
> #!ifdef WITH_ALIASDB
>     # search in DB-based aliases
>     if(alias_db_lookup("dbaliases")) {
>         route(SIPOUT);
>     }
> #!endif
>
>     $avp(oexten) = $rU;
>     if (!lookup("location")) {
>         $var(rc) = $rc;
>         route(TOVOICEMAIL);
>         t_newtran();
>         switch ($var(rc)) {
>             case -1:
>             case -3:
>                 send_reply("404", "Not Found");
>                 exit;
>             case -2:
>                 send_reply("405", "Method Not Allowed");
>                 exit;
>         }
>     }
>
>     if (is_method("INVITE")) {
>         setflag(FLT_ACCMISSED);
>     }
>
>     route(RELAY);
>     exit;
> }
>
> # Presence server processing
> route[PRESENCE] {
>     if(!is_method("PUBLISH|SUBSCRIBE")) return;
>
>     if(is_method("SUBSCRIBE") && $hdr(Event)=="message-summary") {
>         route(TOVOICEMAIL);
>         # returns here if no voicemail server is configured
>         sl_send_reply("404", "No voicemail service");
>         exit;
>     }
>
> #!ifdef WITH_PRESENCE
>     if (!t_newtran()) {
>         sl_reply_error();
>         exit;
>     }
>
>     if(is_method("PUBLISH")) {
>         handle_publish();
>         t_release();
>     } else if(is_method("SUBSCRIBE")) {
>         handle_subscribe();
>         t_release();
>     }
>     exit;
> #!endif
>
>     # if presence enabled, this part will not be executed
>     if (is_method("PUBLISH") || $rU==$null) {
>         sl_send_reply("404", "Not here");
>         exit;
>     }
>     return;
> }
>
> # IP authorization and user authentication
> route[AUTH] {
> #!ifdef WITH_AUTH
>
> #!ifdef WITH_IPAUTH
>     if((!is_method("REGISTER")) && allow_source_address()) {
>         # source IP allowed
>         return;
>     }
> #!endif
>
>     if (is_method("REGISTER") || from_uri==myself) {
>         # authenticate requests
>         if (!auth_check("$fd", "subscriber", "1")) {
>             auth_challenge("$fd", "0");
>             exit;
>         }
>         # user authenticated - remove auth header
>         if(!is_method("REGISTER|PUBLISH"))
>             consume_credentials();
>     }
>     # if caller is not local subscriber, then check if it calls
>     # a local destination, otherwise deny, not an open relay here
>     if (from_uri!=myself && uri!=myself) {
>         sl_send_reply("403","Not relaying");
>         exit;
>     }
>
> #!endif
>     return;
> }
>
> # Caller NAT detection
> route[NATDETECT] {
> #!ifdef WITH_NAT
>     force_rport();
>     if (nat_uac_test("19")) {
>         if (is_method("REGISTER")) {
>             fix_nated_register();
>         } else {
>             if(is_first_hop()) {
>                 set_contact_alias();
>             }
>         }
>         setflag(FLT_NATS);
>     }
> #!endif
>     return;
> }
>
> # RTPProxy control and signaling updates for NAT traversal
> route[NATMANAGE] {
> #!ifdef WITH_NAT
>     if (is_request()) {
>         if(has_totag()) {
>             if(check_route_param("nat=yes")) {
>                 setbflag(FLB_NATB);
>             }
>         }
>     }
>     if (!(isflagset(FLT_NATS) || isbflagset(FLB_NATB))) return;
>
>     if(nat_uac_test("8")) {
> if(ds_is_from_list()){
> xdbg("__META rtpengine priv->pub");
> rtpengine_manage("replace-session-connection replace-origin
> direction=priv direction=pub");
> } else {
> xdbg("__META rtpengine pub->priv");
> rtpengine_manage("replace-session-connection replace-origin
> direction=pub direction=priv");
> }
>     } else {
> if(ds_is_from_list()) {
> xdbg("__META rtpengine priv->pub");
> rtpengine_manage("replace-session-connection replace-origin
> trust-address direction=priv direction=pub");
> } else {
> xdbg("__META rtpengine pub->priv");
> rtpengine_manage("replace-session-connection replace-origin
> trust-address direction=pub direction=priv");
> }
>     }
>
>     if (is_request()) {
>         if (!has_totag()) {
>             if(t_is_branch_route()) {
>                 add_rr_param(";nat=yes");
>             }
>         }
>     }
>
>     if (is_reply()) {
>         if(isbflagset(FLB_NATB)) {
>             if(is_first_hop())
>                 set_contact_alias();
>         }
> xlog("L_ERR","20202020 in is_reply");
>     }
> #!endif
>     return;
> }
>
> # URI update for dialog requests
> route[DLGURI] {
> #!ifdef WITH_NAT
>     if(!isdsturiset()) {
>         handle_ruri_alias();
>     }
> #!endif
>     return;
> }
>
> # Routing to foreign domains
> route[SIPOUT] {
>     if (uri==myself) return;
>     append_hf("P-hint: outbound\r\n");
>     route(RELAY);
>     exit;
> }
>
> # PSTN GW routing
> route[PSTN] {
> #!ifdef WITH_PSTN
>     # check if PSTN GW IP is defined
>     if (strempty($sel(cfg_get.pstn.gw_ip))) {
>         xlog("SCRIPT: PSTN routing enabled but pstn.gw_ip not defined\n");
>         return;
>     }
>
>     # route to PSTN dialed numbers starting with '+' or '00'
>     #     (international format)
>     # - update the condition to match your dialing rules for PSTN routing
>     if(!($rU=~"^(\+|00)[1-9][0-9]{3,20}$")) return;
>
>     # only local users allowed to call
>     if(from_uri!=myself) {
>         sl_send_reply("403", "Not Allowed");
>         exit;
>     }
>
>     if (strempty($sel(cfg_get.pstn.gw_port))) {
>         $ru = "sip:" + $rU + "@" + $sel(cfg_get.pstn.gw_ip);
>     } else {
>         $ru = "sip:" + $rU + "@" + $sel(cfg_get.pstn.gw_ip) + ":"
>                     + $sel(cfg_get.pstn.gw_port);
>     }
>
>     route(RELAY);
>     exit;
> #!endif
>
>     return;
> }
>
> # XMLRPC routing
> #!ifdef WITH_XMLRPC
> route[XMLRPC] {
>     # allow XMLRPC from localhost
>     if ((method=="POST" || method=="GET")
>             && (src_ip==127.0.0.1)) {
>         # close connection only for xmlrpclib user agents (there is a
> bug in
>         # xmlrpclib: it waits for EOF before interpreting the response).
>         if ($hdr(User-Agent) =~ "xmlrpclib")
>             set_reply_close();
>         set_reply_no_connect();
>         dispatch_rpc();
>         exit;
>     }
>     send_reply("403", "Forbidden");
>     exit;
> }
> #!endif
>
> # Routing to voicemail server
> route[TOVOICEMAIL] {
> #!ifdef WITH_VOICEMAIL
>     if(!is_method("INVITE|SUBSCRIBE")) return;
>
>     # check if VoiceMail server IP is defined
>     if (strempty($sel(cfg_get.voicemail.srv_ip))) {
>         xlog("SCRIPT: VoiceMail routing enabled but IP not defined\n");
>         return;
>     }
>     if(is_method("INVITE")) {
>         if($avp(oexten)==$null) return;
>
>         $ru = "sip:" + $avp(oexten) + "@" + $sel(cfg_get.voicemail.srv_ip)
>                 + ":" + $sel(cfg_get.voicemail.srv_port);
>     } else {
>         if($rU==$null) return;
>
>         $ru = "sip:" + $rU + "@" + $sel(cfg_get.voicemail.srv_ip)
>                 + ":" + $sel(cfg_get.voicemail.srv_port);
>     }
>     route(RELAY);
>     exit;
> #!endif
>
>     return;
> }
>
> //convert phone number from international to internal
> //+972112223344 <-> 011222334
> route[TRANSLATE_DST_OUT] {
>         xinfo("__META TRANSLATE_DST_OUT");
>         xdbg("__META To: $hdr(To)");
>         xdbg("__META Regexp: NUM_TRANSLATE_OUT_RE");
>
>         if(subst_uri("/NUM_TRANSLATE_OUT_RE/0\2/"))
>                 xdbg("__META URI translated");
>         else
>                 xdbg("__META Not translating number in URI");
>
>         if(subst_hf("To", "/NUM_TRANSLATE_OUT_RE/0\2/", "a"))
>                 xdbg("__META To header translated");
>         else
>                 xdbg("__META Not translating number in to header");
> }
>
> //convert phone number from internal format to international
> //011222334 <-> +<972>112223344
> route[TRANSLATE_SRC_IN] {
> $var(number)=$rU;
>         if($(var(number){s.substr,1,4})=="+972") {
>  $rU="0"+$(var(number){s.substr,5,0});
> }
> }
> /////////////////////////////////////////////////////////////////////////////
>
> # Manage outgoing branches
> branch_route[MANAGE_BRANCH] {
>     xdbg("new branch [$T_branch_idx] to $ru\n");
>     route(NATMANAGE);
> }
>
> # Manage incoming replies
> onreply_route[MANAGE_REPLY] {
>     xdbg("incoming reply\n");
>
>     // fix_nated_contact();
>     xlog("L_ERR","2020202020202 Got reply $ct");
>
>     if(status=~"[12][0-9][0-9]") {
>         route(NATMANAGE);
>     }
>
> if(is_method("INVITE") && is_present_hf("P-Asserted-Identity")) {
> remove_hf("P-Asserted-Identity");
> }
> }
>
> # Manage failure routing cases
> failure_route[MANAGE_FAILURE] {
>     xlog("Failure! Going to failure route.");
>     route(NATMANAGE);
>     if (t_is_canceled()) exit;
>
> #!ifdef WITH_BLOCK3XX
>     # block call redirect based on 3xx replies.
>     if (t_check_status("3[0-9][0-9]")) {
>         t_reply("404","Not found");
>         exit;
>     }
> #!endif
>
> #!ifdef WITH_BLOCK401407
>     # block call redirect based on 401, 407 replies.
>     if (t_check_status("401|407")) {
>         t_reply("404","Not found");
>         exit;
>     }
> #!endif
>
> #!ifdef WITH_VOICEMAIL
>     # serial forking
>     # - route to voicemail on busy or no answer (timeout)
>     if (t_check_status("486|408")) {
>         $du = $null;
>         route(TOVOICEMAIL);
>         exit;
>     }
> #!endif
> }
>
> event_route[topoh:msg-outgoing] {
>   if($sndto(ip)=="freeswitch") {
>     drop;
>   }
>   if($sndto(ip)=="81.24.193.248") {
>     drop;
>   }
> }
>
> Edward
> ------------------------------------------------------------------------
> *From:* Daniel-Constantin Mierla <miconda at gmail.com>
> *Sent:* Tuesday, August 4, 2020 11:19 AM
> *To:* Kamailio (SER) - Users Mailing List
> <sr-users at lists.kamailio.org>; Edward Romanenco <edward at telemessage.com>
> *Subject:* Re: [SR-Users] Manipulating SDP IP for Inbound Calls
>  
>
> Hello,
>
> the mangler module does not have any idea of inbound/outbound
> directions, so you can use it for any of them.
>
>
> Also, the nathelper module should have a function allowing to change
> the ip in the sdp, iirc.
>
>
> On the other hand, if you use rtppengine for the calls, then the ips
> should be replaced by it.
>
>
> Do not forget to use msg_apply_changes() in case you want those
> changes to be visible immediately in the configuration file.
>
>
> Cheers,
> Daniel
>
>
> On 29.07.20 13:18, Edward Romanenco wrote:
>> Hey guys,
>>
>> I am working on a project involving Kamailio dockerezation, which is
>> meant to run alongside Freeswitch and RTPEngine containers, on the
>> basis of a Docker-Compose file which is launched on top of a CentOS
>> 7.7 host system.
>>
>> Anyway, I would love to know if there is any way to manipulate / mask
>> the IP addresses that are being appended to a status 183 response for
>> an incoming invite.
>>
>> For some reason which I am trying to figure out in parallel,
>> Freeswitch uses the local network bridge subnet instead of the
>> defined external RTP IPs, and I was wondering - Can I manipulate them
>> using Kamailio? I know that Mangler module can do it for outbound
>> calls, but can I do the same for inbound?
>>
>> v=0.
>> o=FreeSWITCH 1595974788 1595974789 IN IP4 172.18.0.40.
>> s=FreeSWITCH.
>> c=IN IP4 172.18.0.40.
>> t=0 0.
>> m=audio 45878 RTP/AVP 8 101.
>> a=rtpmap:8 PCMA/8000.
>> a=rtpmap:101 telephone-event/8000.
>> a=fmtp:101 0-16
>>
>> Edward
>>
>> _______________________________________________
>> Kamailio (SER) - Users Mailing List
>> sr-users at lists.kamailio.org <mailto:sr-users at lists.kamailio.org>
>> https://lists.kamailio.org/cgi-bin/mailman/listinfo/sr-users
> -- 
> Daniel-Constantin Mierla -- www.asipto.com <http://www.asipto.com>
> www.twitter.com/miconda <http://www.twitter.com/miconda> -- www.linkedin.com/in/miconda <http://www.linkedin.com/in/miconda>
> Funding: https://www.paypal.me/dcmierla

-- 
Daniel-Constantin Mierla -- www.asipto.com
www.twitter.com/miconda -- www.linkedin.com/in/miconda
Funding: https://www.paypal.me/dcmierla

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.kamailio.org/pipermail/sr-users/attachments/20200804/6a607f3b/attachment.htm>


More information about the sr-users mailing list