Re: Assistance on WebRTC implementation with Kamilio, RTPengine and FS on a 1:1 NAT Cloud VM

Goons via sr-users <[email protected]>
Newsgroups gmane.comp.voip.ser
Message-ID <[email protected]>
Hello Sergio Charrua

Find below the necessary routing blocks, I have made some adjustments to the previous routing blocks.

#!ifdef WITH_WEBSOCKETS
event_route[xhttp:request] {
	set_reply_close();
	set_reply_no_connect();
	if ($Rp != MY_WS_PORT && $Rp != MY_WSS_PORT
	) {
		xlog("L_WARN", "HTTP request received on $Rp\n");
		xhttp_reply("403", "Forbidden", "", "");
		exit;
	}

	xlog("L_INFO", "HTTP Request Received\n");

	if ($hdr(Upgrade) =~ "websocket"
		&& $hdr(Connection) =~ "Upgrade"
		&& $rm =~ "GET"
	) {
		if ($hdr(Host) == $null) {
			xlog("L_WARN", "Bad host $hdr(Host)\n");
			xhttp_reply("403", "Forbidden", "", "");
			exit;
		}
		if (ws_handle_handshake()) {
			exit;
		}
	}

	xhttp_reply("404", "Not Found", "", "");
}

event_route[websocket:closed] {
	xlog("L_INFO", "WebSocket connection from $si:$sp has closed\n");
}
#!endif

request_route {
        xlog("L_ALERT"," ------- New Call (Routing) ----- $rm \n");
        xlog("L_INFO",
        "[REQ-IN] "
        "src=$si:$sp "
        "dst=$Ri:$Rp "
        "du =$du "
        "proto=$proto "
        "ru=$ru "
        "ruri_user=$rU "
        "from=$fu "
        "to=$tu "
        "callid=$ci "
        "ct=$hdr(Content-Type)\n"
    );
    
#!ifdef WITH_WEBSOCKETS
	if (nat_uac_test(64)) {
    		force_rport();   
    	if (is_method("REGISTER")) {
        	fix_nated_register();
        	xlog("L_INFO", "Fixed NAT registration for $fu\n");
    	} else {
        	if (!add_contact_alias()) {
            	xlog("L_ERR", "Error aliasing contact <$ct> from $si:$sp\n");
            	sl_send_reply("400", "Bad Request");
            	exit;
        	}
        xlog("L_INFO", "Added contact alias from $si:$sp\n");
        	}
    	}
#!endif
        route(REQINIT);
        route(SET_DIRECTION_FLAG);
        # NAT detection
        route(NATDETECT);

        if ( is_method("OPTIONS") ) {
                if($fU=='sipsak'){
                        sl_send_reply("500", "Server Dead");
                        exit;
                }
        }

        if ( is_method("INFO") ) {
                sl_send_reply("200", "OK");
                exit;
        }

        #!ifdef WITH_HOMER
        #start duplicate the SIP message now
                        sip_trace();
                        setflag(22);
        #!endif
        # per request initial checks

        # handle requests within SIP dialogs
        route(WITHINDLG);

        ### only initial requests (no To tag)

        # CANCEL processing
        if (is_method("CANCEL")){
                if (t_check_trans())
                        t_relay();
                exit;
        }
        t_check_trans();
        # authentication
        route(AUTH);
        # record routing for dialog forming requests (in case they are routed)
        # - remove preloaded route headers
        remove_hf("Route");
        remove_hf("X-VoipMonitor-Custom1");

        if (is_method("INVITE|SUBSCRIBE")){
                record_route_preset("x.x.x.x:5060;nat=yes");
        }

        # account only INVITEs
        if (is_method("INVITE"))
        {
                setflag(FLT_ACC); # do accounting
        }
        # handle registrations
        route(REGISTRAR);
        if ($rU==$null)
        {
                # request with no Username in RURI
                sl_send_reply("484","Address Incomplete");
                exit;
        }

        # dispatch destinations to PSTN
        route(PSTN);
        # user location service
        route(LOCATION);
        xlog("L_INFO",
    "REQ OUT $rm | via proto=$proto sndto=$sndto(proto) "
    "dst=$sndto(ip):$sndto(port) du=$du\n"
);

        route(RELAY);
}

onsend_route {
    #if(to_ip==1.2.3.4 && !isflagset(12)){
    xlog("L_WARN", "[onsend_route] Packet going to $du [$mb]\n" );
    #}
}

route[RELAY] {

        if (is_method("INVITE|SUBSCRIBE|UPDATE|INFO")) {
                route(SET_RTP_REQUEST);
                t_on_branch("MANAGE_BRANCH");
                t_on_reply("MANAGE_REPLY");
        }
        if (is_method("INVITE|UPDATE|INFO")) {
                t_on_failure("MANAGE_FAILURE");
        }

        if (!t_relay()) {
                sl_reply_error();
        }
        exit;
}

# Per SIP request initial checks
route[REQINIT] {
#!ifdef WITH_ANTIFLOOD
        #!ifdef WITH_EXEC
                        #Run-time IPTable
                        if ($ua =~ "(VoipSwitch|Asterisk)") {
                                xdbg("Callfrom UA $ua\n");
                        } else if($ua =~ "(zxcvfdf11|friendly-scanner|pplsip|sipvicious|sipcli|VaxSIPUserAgent|voxalot|MizuPhone|Ozeki|tramb2017|voip|hello|Independant|Skipper)") {
                                # silent drop for scanners
                                xlog("L_INFO","Blocking scanners and pushing IPs to iptables");
                                exec_avp("iptables -I INPUT -s $si -j DROP");
                                exec_avp("/sbin/service iptables save");
                                sl_send_reply("403", "Forbidden");
                                exit;
                        }
        #!endif

        if (is_method("REGISTER")){
                if (!mf_process_maxfwd_header("10")) {
                        sl_send_reply("483","Too Many Hops");
                        exit;
                }
                if(!sanity_check("1511", "7")) {
                        xlog("L_ALERT","Malformed SIP message from $si:$sp\n");
                        send_reply("403", "Forbidden");
                        exit;
                }
                return 1;
        }
        if(is_method("INVITE") || is_method("SUBSCRIBE") || is_method("REGISTER")){
        # 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) {
                                # $fu is already blocked
                                xdbg("request from blocked User - $fU,  $rm from $fu (IP:$si:$sp)\n");
                                if(is_method("INVITE")){
                                                xlog("L_ALERT"," ALERT: $fU user source IP Address $si:$sp is already blocked.\n");
                                }
                                send_reply("403", "Forbidden");
                                exit;
                        }
                        if (!pike_check_req()) {
                                xlog("L_ALERT","Blocking traffic from $si\n");
                                xlog("L_ALERT","ALERT: pike blocking $fU, $rm from $fu  (IP:$si:$sp)\n");
                                $sht(ipban=>$si) = 1;
                                xlog("L_ALERT","ALERT: $fU user source IP Address $si:$sp is blocking by system.\n");
                                xlog("L_INFO","ALERT: INSERT INTO `htable` (`key_name`, `key_value`, ip, htime,serverid) VALUES ('$si', '1','$si',now(),'1')\n");
                                sql_xquery("ca","INSERT INTO `htable` (`key_name`, `key_value`, ip, htime,serverid) VALUES ('$si', '1','$si',now(),'1')", "ra");
                                sql_xquery("ca","INSERT INTO `htabledump` (`key_name`, `key_value`, ip, htime,serverid) VALUES ('$si', '1','$si',now(),'1')", "ra");
                                send_reply("403", "Forbidden");
                                exit;
                        }
                }
                if($ua =~ "friendly-scanner") {
                                sl_send_reply("200", "OK");
                                exit;
                }
        }

        if(!is_method("OPTIONS") && !is_method("SUBSCRIBE") && !is_method("NOTIFY") && !is_method("INVITE")){
                if(src_ip!=myself) {
                        if($sht(userban=>$fU)!=$null) {
                                xdbg("request from blocked User - $fU,  $rm from $fu (IP:$si:$sp)\n");
                                if(is_method("INVITE")){
                                        xlog("L_ALERT"," ALERT: $fU user source IP Address $si:$sp is already blocked.\n");
                                }
                                send_reply("403", "Forbidden");
                                exit;
                        }
                        if (!pike_check_req()) {
                                xlog("L_ALERT","ALERT: pike blocking $fU, $rm from $fu  (IP:$si:$sp)\n");
                                xlog("L_ALERT","Blocking traffic from $si\n");
                                $sht(userban=>$fU) = 1;

                                 xlog("L_ALERT","ALERT: $fU user source IP Address $si:$sp is blocking by system.\n");
                                xlog("L_INFO","ALERT: INSERT INTO `htable` (`key_name`, `key_value`, ip, htime,serverid) VALUES ('$fU', '1','$si',now(),'1')\n");
                                sql_xquery("ca","INSERT INTO `htable` (`key_name`, `key_value`, ip, htime,serverid) VALUES ('$fU', '1','$si',now(),'1')", "ra");
                                sql_xquery("ca","INSERT INTO `htabledump` (`key_name`, `key_value`, ip, htime,serverid) VALUES ('$fU', '1','$si',now(),'1')", "ra");
                                send_reply("403", "Forbidden");
                                exit;
                        }
                }
                if($ua =~ "friendly-scanner") {
                                sl_send_reply("200", "OK");
                                exit;
                }
        }
#!endif

        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;
        }
}

route[WITHINDLG] {
        if (has_totag()) {
                if (loose_route()) {
                        if (is_method("BYE")) {
                                setflag(FLT_ACC); # do accounting ...
                                setflag(FLT_ACCFAILED); # ... even if the transaction fails
                                rtpengine_delete();
                        }
                        if ( is_method("ACK") ) {
                                # ACK is forwarded statelessy
                                route(NATMANAGE);
                        }
                        remove_hf("X-FROMURI");
                        remove_hf("X-CARRIERCPS");
                        remove_hf("X-CARRIERID");
                        remove_hf("X-MEDIP");
                        remove_hf("X-ACCOUNTCODE");
                        remove_hf("X-DEVICEID");
                        remove_hf("X-DEVICECC");
                        remove_hf("X-DEVICECPS");
                        remove_hf("X-ACCOUNTID");
                        remove_hf("X-ACCOUNTCC");
                        remove_hf("X-ACCOUNTCPS");
                        remove_hf("X-WITHMEDIA");
                        remove_hf("X-DEVICETYPE");
                        remove_hf("X-SRC-ACCOUNT");
                        remove_hf("X-SRC-MED-IP");
                        remove_hf("X-FS-Support");
                        remove_hf("X-DSTURI");
                        remove_hf("X-GMEDIA");
                        remove_hf("X-RE");
                        remove_hf("X-Billing-Code");
                        remove_hf("X-AI");
                        remove_hf("X-PU");
                        remove_hf("X-MEDIATRA");
                        remove_hf("X-INCOMINGCARRIER");
                        remove_hf("X-INCOMINGCARRIERDST");
                        remove_hf("X-DEVICEID-1");
                        remove_hf("Allow-Events");
                        msg_apply_changes();
                        route(RELAY);
                } else {
                        if (is_method("SUBSCRIBE") && uri == myself) {
                                # in-dialog subscribe requests
                                sl_send_reply("404","Not here");
                                exit;
                        }
                        if ( is_method("ACK") ) {
                                if ( t_check_trans() ) {
                                        t_relay();
                                        exit;
                                } else {
                                        exit;
                                }
                        }
                        sl_send_reply("404","Not here");
                }
                exit;
        }
}

route[NATDETECT] {
#!ifdef WITH_NAT
        force_rport();
        if (nat_uac_test("19")) {
                if (is_method("REGISTER")) {
                        fix_nated_register();
                } else {
                        fix_nated_contact();
                }
                setflag(FLT_NATS);
                setbflag(FLB_NATB);
        }
    	if ($proto == "WS" || $proto == "WSS") {
		force_rport();
                if (is_method("REGISTER")) {
                fix_nated_register();
                add_path_received();
     		}
	        setflag(FLT_NATS);
        	setbflag(FLB_NATB);
                xlog("L_INFO", "WebRTC client detected: $si:$sp\n");
    	}
#!endif
        return;
}

route[NATMANAGE] {
    if (is_request()) {
        if(has_totag()) {
            if(check_route_param("nat=yes")) {
                setbflag(FLB_NATB);
            }
        }
    }
    if (!(isflagset(FLT_NATS) || isbflagset(FLB_NATB))) return;

    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();
        }
    }
    return;
}

route[PSTN] {

                if($hdr(X-DSTURI) == $null){
                        return;
                }else {

                #!ifdef WITH_FREESWITCH
                        if(route(FROMFREESWITCH)){
                                #External Call  sip_h_X-CARRIERCPS    sip_h_X-CARRIERID
                                $var(CARRIERCPS) = $hdr(X-CARRIERCPS);
                                $var(CARRIERID) = $hdr(X-CARRIERID);
                                xlog("L_ALERT","Carrier Allowed CPS $var(CARRIERCPS) for carrier $hdr(X-CARRIERID)\n");
                                if(route(CCPSCHECK)){
                                          sl_send_reply("515", "Limit issue");
                                          exit;
                                }
                                $avp(oexten) = $rU;
                                $ru = $hdr(X-DSTURI);
                                #$du = $null;
                                $tu = $ru;
                                $var(MEDIATRA) = $hdr(X-MEDIATRA);
                                if($hdr(X-MEDIATRA) == '1'){
                                        setflag(FLT_NATS);
                                }else{
                                        resetflag(FLT_NATS);
                                }
                                remove_hf("X-FROMURI");
                                remove_hf("X-CARRIERCPS");
                                remove_hf("X-CARRIERID");
                                remove_hf("X-MEDIP");
                                remove_hf("X-ACCOUNTCODE");
                                remove_hf("X-DEVICEID");
                                remove_hf("X-DEVICECC");
                                remove_hf("X-DEVICECPS");
                                remove_hf("X-ACCOUNTID");
                                remove_hf("X-ACCOUNTCC");
                                remove_hf("X-ACCOUNTCPS");
                                remove_hf("X-WITHMEDIA");
                                remove_hf("X-DEVICETYPE");
                                remove_hf("X-SRC-ACCOUNT");
                                remove_hf("X-SRC-MED-IP");
                                remove_hf("X-FS-Support");
                                remove_hf("X-DSTURI");
                                remove_hf("X-GMEDIA");
                                remove_hf("X-RE");
                                remove_hf("X-AI");
                                remove_hf("X-PU");
                                remove_hf("X-MEDIATRA");
                                remove_hf("Allow-Events");
                                remove_hf("User-Agent");
                                remove_hf("X-INCOMINGCARRIER");
                                remove_hf("X-INCOMINGCARRIERDST");
                                remove_hf("X-Billing-Code");
                                remove_hf("X-DEVICEID-1");
                                append_hf("User-Agent: \r\n");
                                msg_apply_changes();
                                # when routing via usrloc, log the missed calls also
                                if (is_method("INVITE")) {
                                        setflag(FLT_ACCMISSED);
                                }
                                if($(var(CARRIERID){s.len}) > 1 ){
                                        route(CCPSSET);
                                }
                                route(RELAY);
                                exit;
                        }
                }
                #!endif
}

branch_route[MANAGE_BRANCH] {
        xdbg("new branch [$T_branch_idx] to $ru\n");
        route(NATMANAGE);
}


onreply_route[MANAGE_REPLY] {
        xlog("L_INFO",
        "[REPLY-IN] "
        "method=$rm "
        "src=$si:$sp "
        "dst=$Ri:$Rp "
        "du=$du "
        "proto=$proto "
        "ru=$ru "
        "to-tag=$tt "
        "to-tag=$(tt{s.len}) "
        "ct=$hdr(Content-Type)\n"
    );
    xdbg("incoming reply\n");
#     if (!has_body("application/sdp")) return;
#     if (!($rs == 183 || $rs == 200)) return;
#     if (!has_totag()) return;
    route(NATMANAGE);
    route(SET_DIRECTION_FLAG);
    route(SET_RTP_REPLY);
}


failure_route[MANAGE_FAILURE] {
        route(NATMANAGE);
        route(SET_RTP_REPLY);
        if (t_is_canceled()) {
                exit;
        }
#!ifdef WITH_BLOCK3XX
        if (t_check_status("3[0-9][0-9]")) {
                t_reply("404","Not found");
                exit;
        }
#!endif

#!ifdef WITH_CODE486408
        # serial forking
        if (t_check_status("408")) {
                t_reply("486","Busy");
                exit;
        }
        if (t_check_status("408")) {
                t_reply("486","Request Timeout");
                exit;

        }
#!endif
}




route[SET_DIRECTION_FLAG] {

    # === FROM CORE ===
    if ( is_ip_rfc1918("$si") ) {

        # Core → WebRTC
        if ($proto == "ws" || $proto == "wss" || $ru =~ "transport=(ws|wss)") {
            xlog("L_INFO", "[DIR] CORE → WEBRTC | src=$si proto=$proto ru=$ru du=$du\n");
            setflag(FLB_FROM_CORE_TO_WEBRTC);
            return;
        }

        # Core → SIP
        xlog("L_INFO", "[DIR] CORE → SIP | src=$si proto=$proto ru=$ru du=$du\n");
        setflag(FLB_FROM_CORE_TO_SIP);
        return;
    }

    # === FROM PUBLIC ===
    else {

        # Public → WebRTC
        if ($proto == "ws" || $proto == "wss") {
            xlog("L_INFO", "[DIR] PUBLIC → WEBRTC | src=$si proto=$proto ru=$ru du=$du\n");
            setflag(FLB_FROM_PUBLIC_FROM_WEBRTC);
            return;
        }

        # Public → SIP
        xlog("L_INFO", "[DIR] PUBLIC → SIP | src=$si proto=$proto ru=$ru du=$du\n");
        setflag(FLB_FROM_PUBLIC_FROM_SIP);
        return;
    }
}

route[SET_RTP_REQUEST] {
        if (!is_method("UPDATE|INVITE"))   {
                return 0;
        }   

        if (sdp_content()) {
                $avp(originalSDP) = $rb;
                if(isflagset(FLB_FROM_PUBLIC_FROM_WEBRTC)) {
                        xlog("L_INFO", "SET_RTP_REQUEST | FROM PUBLIC FROM WEBRTC");
                        rtpengine_manage("replace-origin replace-session-connection RTP/AVP ICE=remove direction=external direction=internal");
                } 
                if(isflagset(FLB_FROM_PUBLIC_FROM_SIP)) {
                        xlog("L_INFO", "SET_RTP_REQUEST | FROM PUBLIC FROM SIP");
                        rtpengine_manage("replace-origin replace-session-connection RTP/AVP ICE=remove direction=external direction=internal");
                }  
                if(isflagset(FLB_FROM_CORE_TO_WEBRTC)) {
                        xlog("L_INFO", "SET_RTP_REQUEST | FROM CORE TO WEBRTC");
                        rtpengine_manage("replace-origin replace-session-connection RTP/SAVPF ICE=force direction=internal direction=external");
                }
                if(isflagset(FLB_FROM_CORE_TO_SIP)) {
                        xlog("L_INFO", "SET_RTP_REQUEST | FROM CORE TO SIP");
                        rtpengine_manage("replace-origin replace-session-connection RTP/AVP direction=internal direction=external");
                }     
        }
}

route[SET_RTP_REPLY] {
        xlog("L_INFO", "SET_RTP_REPLY | ENTERING THE ROUTE BLOCK");

        if (sdp_content()) {
                $avp(originalSDP) = $rb;
                if(isflagset(FLB_FROM_PUBLIC_FROM_WEBRTC)) {
                        xlog("L_INFO", "SET_RTP_REPLY | FROM PUBLIC FROM WEBRTC");
                        rtpengine_manage("replace-origin replace-session-connection RTP/AVP ICE=remove direction=external direction=internal");
                } 
                if(isflagset(FLB_FROM_PUBLIC_FROM_SIP)) {
                        xlog("L_INFO", "SET_RTP_REPLY | FROM PUBLIC FROM SIP");
                        rtpengine_manage("replace-origin replace-session-connection RTP/AVP ICE=remove direction=external direction=internal");
                }  
                if(isflagset(FLB_FROM_CORE_TO_WEBRTC)) {
                        xlog("L_INFO", "SET_RTP_REPLY | FROM CORE TO WEBRTC");
                        rtpengine_manage("replace-origin replace-session-connection RTP/SAVPF ICE=force direction=internal direction=external");
                }
                if(isflagset(FLB_FROM_CORE_TO_SIP)) {
                        xlog("L_INFO", "SET_RTP_REPLY | FROM CORE TO SIP");
                        rtpengine_manage("replace-origin replace-session-connection RTP/AVP direction=external direction=external");
                }          
        }

        if ($rs=~"[3-6][0-9][0-9]") {
                rtpengine_manage();
        }
}




#!ifdef WITH_FREESWITCH
route[FROMFREESWITCH] {
        if(ds_is_from_list("2")){
                return 1;
        }
        return -1;
}
#!endif
__________________________________________________________
Kamailio - Users Mailing List - Non Commercial Discussions -- [email protected]
To unsubscribe send an email to [email protected]
Important: keep the mailing list in the recipients, do not reply only to the sender!
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.