[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