[SR-Users] Recent problem with fix_nated_sdp and kamailio 4.4.4

Anthony Messina amessina at messinet.com
Mon Nov 28 15:12:13 CET 2016


Request -> route[RELAY] -> branch_route[MANAGE_BRANCH] ->  
route[RTPENGINE_DETECT] -> route[NATMANAGE]

route[RELAY] {
	# enable additional event routes for forwarded requests
	# - serial forking, RTP relaying handling, a.s.o.
	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|MESSAGE")) {
		if(!t_is_set("failure_route")) t_on_failure("MANAGE_FAILURE");
	}

	if(!t_relay()) sl_reply_error();

	exit;
}


# rtpengine 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(check_route_param("rtp=yes")) {
				setbflag(FLB_RTPENGINE);

				if(check_route_param("dir=priv")) {
					setbflag(FLB_RTPENGINE_PRIV);
				}

				if(check_route_param("af=6")) {
					setbflag(FLB_RTPENGINE_IP6);
				}

	                        if(check_route_param("m=avp")) {
         	                        setbflag(FLB_RTPENGINE_AVP);
                 	        } else if(check_route_param("m=savp")) {
                         	        setbflag(FLB_RTPENGINE_SAVP);
	                        } else if(check_route_param("m=avpf")) {
         	                        setbflag(FLB_RTPENGINE_AVPF);
                 	        } else if(check_route_param("m=savpf")) {
                         	        setbflag(FLB_RTPENGINE_SAVPF);
	                        }
			}
		}
	}

	if(!(isflagset(FLT_NATS) || isbflagset(FLB_NATB) ||  
isbflagset(FLB_RTPENGINE)))
		return;

#!ifdef WITH_RTPENGINE
	if(isbflagset(FLB_RTPENGINE)) {
		# Set our default flags
		$xavp(r=>$T_branch_idx)="replace-origin replace-session-connection";

		if(is_request()) {
			if(!has_totag()) {
				# Set the via branch (except for the failure route, in which $T_branch_idx
				# doesn't point to the original request
				if(!t_is_failure_route()) {
					$avp(extra_id)=@via[1].branch + $T_branch_idx;
					$xavp(r=>$T_branch_idx)=$xavp(r=>$T_branch_idx) + " via-branch=extra";
				}

				# Reset, if necessary
				if(isflagset(FLT_RTPENGINE_RESET)) {
					$xavp(r=>$T_branch_idx)=$xavp(r=>$T_branch_idx) + " reset";
				}

				# Interface
				if(dst_ip==127.0.0.1 || dst_ip==10.1.1.2) {
					if(isbflagset(FLB_RTPENGINE_PRIV)) {
						$xavp(r=>$T_branch_idx)=$xavp(r=>$T_branch_idx) + "  
direction=priv direction=priv";
					} else {
						$xavp(r=>$T_branch_idx)=$xavp(r=>$T_branch_idx) + "  
direction=priv direction=pub";
					}
				} else if(isbflagset(FLB_RTPENGINE_PRIV)) {
					$xavp(r=>$T_branch_idx)=$xavp(r=>$T_branch_idx) + " direction=pub  
direction=priv";
				} else {
					$xavp(r=>$T_branch_idx)=$xavp(r=>$T_branch_idx) + " direction=pub  
direction=pub";
				}

				# Address family
				if(af==INET && isbflagset(FLB_RTPENGINE_IP6)) {
					$xavp(r=>$T_branch_idx)=$xavp(r=>$T_branch_idx) + " address-family=IP6";
				} else if(af==INET6 && !isbflagset(FLB_RTPENGINE_IP6)) {
					$xavp(r=>$T_branch_idx)=$xavp(r=>$T_branch_idx) + " address-family=IP4";
				}

				# RTP
				if(isbflagset(FLB_RTPENGINE_AVP)) {
					$xavp(r=>$T_branch_idx)=$xavp(r=>$T_branch_idx) + " RTP/AVP";
				} else if(isbflagset(FLB_RTPENGINE_SAVP)) {
					$xavp(r=>$T_branch_idx)=$xavp(r=>$T_branch_idx) + " RTP/SAVP";
				} else if(isbflagset(FLB_RTPENGINE_AVPF)) {
					$xavp(r=>$T_branch_idx)=$xavp(r=>$T_branch_idx) + " RTP/AVPF";
				} else if(isbflagset(FLB_RTPENGINE_SAVPF)) {
					$xavp(r=>$T_branch_idx)=$xavp(r=>$T_branch_idx) + " RTP/SAVPF";
				}

				# Record call
				$xavp(r=>$T_branch_idx)=$xavp(r=>$T_branch_idx) + " record-call=yes";
			}

			# Accept rtcp-mux (then demux) for the other side
			# Though this might kernelize/de-kernelize the media stream all the time...
			if(proto==WSS) {
				$xavp(r=>$T_branch_idx)=$xavp(r=>$T_branch_idx) + " rtcp-mux-demux";
			}

			# Remove ICE for now (on offer to non-WebSocket connections)
			if($(rP{s.toupper})!="WS") {
				$xavp(r=>$T_branch_idx)=$xavp(r=>$T_branch_idx) + " ICE=remove";
			} else {
				# Offer rtcp-mux to WebSocket endpoints
				$xavp(r=>$T_branch_idx)=$xavp(r=>$T_branch_idx) + " rtcp-mux-offer";
			}
		}

		if(is_reply()) {
			# On reply (answer), specify caller's address family and RTP profile
			# (to support multi-branch calls with different offer parameters)
			# This seems primarily necessary to return audio to Websocket and have ICE
			# negotiation work.  (This may have to do with Websocket IPv6  
setting the pub
			# rather than priv interface....

#	This doesn't seem necessary if we don't use STUN internally.  *OUR*  
Comcast Gateway sux!!!!!!!
#			$xavp(r=>$T_branch_idx)=$xavp(r=>$T_branch_idx) + " " + $avp(caller_af);

			# It *MAY* be possible, if we don't fuck up the current via-branch  
settings to *NOT have
			# to set the $avp(caller_rtp) on the reply (even for websocket.  We  
*WILL* have to
			# set the address family, as RTPengine can't always detect it  
properly since
			# Websocket may set the 0.0.0.0 or IPv4 address, even when it  
connects via IPv6
			#$xavp(r=>$T_branch_idx)=$xavp(r=>$T_branch_idx) + " " + $avp(caller_rtp);

			# But I may need to remove ICE when replying from WebSocket to a  
non-websocket peer
			# that originated the call like Zoiper  (and add back the caller_rtp)
			# The following *IS* necessary (setting the removal of ICE and  
setting the caller_rtp)
			# or else the WebSocket answer is still passed with  
UDP/TLS/RTP/SAVPF (even though the
			# via-branch seems to work for everything else.
			if(proto==WSS) {
				$xavp(r=>$T_branch_idx)=$xavp(r=>$T_branch_idx) + " ICE=remove";
				$xavp(r=>$T_branch_idx)=$xavp(r=>$T_branch_idx) + " " + $avp(caller_rtp);
			}

			# Set the via-branch for the reply
			$avp(extra_id)=@via[2].branch + $T_branch_idx;
			$xavp(r=>$T_branch_idx)=$xavp(r=>$T_branch_idx) + " via-branch=extra";
		}

		# RTPEngine defaults to trust-address; if the SDP has RFC1918 or  
RFC6598 addresses
		# use the SIP source address instead
		# (Do we need to use this only for our own LAN???
		# I may want to use nathelper rewriting of SDP here rather than  
RTPengine (fix_nated_sdp("10");)
		# Then set a flag other than FLB_RTPENGINE -- define something  
separate to rewrite on offer/answer?
		if(dst_ip!=127.0.0.1) {
			if(nat_uac_test("8")) {
				$xavp(r=>$T_branch_idx)=$xavp(r=>$T_branch_idx) + " SIP-source-address";
			}
		}

		xlog("L_INFO", "route[NATMANAGE][$T_branch_idx]: RU: $ru, M:$rm,  
S:$rs, EXTRA: $avp(extra_id), $xavp(r=>$T_branch_idx)\n");
		rtpengine_manage($xavp(r=>$T_branch_idx));
	}
#!endif

	# RTPEngine is not enabled but if STUN media addresses are being used on our
	# internal network, rewrite the media address to the internal source address
	if(dst_ip==10.1.1.2 && compare_pure_ips($sel(contact.uri.host),  
"<EXTERNAL_IP>")) {
		fix_nated_sdp("10");
	}

	if(is_request()) {
		if(!has_totag()) {
			if(t_is_branch_route()) {
				if(isflagset(FLT_NATS) || isbflagset(FLB_NATB)) {
					add_rr_param(";nat=yes");
				}

				if(isbflagset(FLB_RTPENGINE)) {
					add_rr_param(";rtp=yes");

					if(isbflagset(FLB_RTPENGINE_PRIV)) {
						add_rr_param(";dir=priv");
					}

					if(isbflagset(FLB_RTPENGINE_IP6)) {
						add_rr_param(";af=6");
					}

					if(isbflagset(FLB_RTPENGINE_AVP)) {
						add_rr_param(";m=avp");
					} else if(isbflagset(FLB_RTPENGINE_SAVP)) {
						add_rr_param(";m=savp");
					} else if(isbflagset(FLB_RTPENGINE_AVPF)) {
						add_rr_param(";m=avpf");
					} else if(isbflagset(FLB_RTPENGINE_SAVPF)) {
						add_rr_param(";m=savpf");
					}
				}
			}
		}
	}
	if(is_reply()) {
		if(isbflagset(FLB_NATB)) {
			if(is_first_hop()) {
				# Try skipping this for GRUU
				if(@contact.uri!="" && !is_gruu(@contact.uri))
					set_contact_alias();
			}
		}
	}
#!endif
	return;
}


route[RTPENGINE_DETECT] {
#!ifdef WITH_RTPENGINE
	if(!has_totag() && has_body("application/sdp")) {
		# Set "Branch" flags for capabilities for Asterisk  
(FLB_RTPENGINE_PRIV, FLB_RTPENGINE_SAVP)
		# when routing directly to 127.0.0.1
		# Need to find a way to not overwrite this if set in  
route[VOICEMAIL]  or route[LCR] or route[PSTN], etc...
		if($rd=="127.0.0.1") {
			$bf=144;
		}

		# Need RTP profile bridging?
		if($avp(caller_rtp)=="RTP/AVP" && !isbflagset(FLB_RTPENGINE_AVP)) {
			setbflag(FLB_RTPENGINE);
		} else if($avp(caller_rtp)=="RTP/SAVP" && !isbflagset(FLB_RTPENGINE_SAVP)) {
			setbflag(FLB_RTPENGINE);
		} else if($avp(caller_rtp)=="RTP/AVPF" && !isbflagset(FLB_RTPENGINE_AVPF)) {
			setbflag(FLB_RTPENGINE);
		} else if($avp(caller_rtp)=="RTP/SAVPF" &&  
!isbflagset(FLB_RTPENGINE_SAVPF)) {
			setbflag(FLB_RTPENGINE);
		}

		# We *may* have an opportunity here to avoid RTPEngine if the  
@contact.uri.host of
		# the caller is the same as the callee -- they are probably behind  
the same NAT
		# (like when Marci & I are both at work and on WiFi).  I think we'd  
check the contact
		# host of the caller and the ruri host of the callee)

		# We may need a flag to disable STUN in NATMANAGE (just like we do  
for our internal network)
		#if(!isbflagset(FLB_RTPENGINE)) {
		#	if(is_ip(@contact.uri.host)) {
		#		if(@contact.uri.host==@ruri.host) {
		#			xlog("L_INFO", "route[RTPENGINE_DETECT][$T_branch_idx]: Caller  
($sel(contact.uri.host)) and callee ($sel(ruri.host)) connecting from  
the same IP");
		#			return;
		#		}
		#	}
		#}

		# Need IPv4/IPv6 address family bridging?
		if(af==INET && isbflagset(FLB_RTPENGINE_IP6)) {
			setbflag(FLB_RTPENGINE);
		} else if(af==INET6 && !isbflagset(FLB_RTPENGINE_IP6)) {
			setbflag(FLB_RTPENGINE);
		}

		# Need priv/pub, pub/priv or pub/pub interface bridging?
		if(!((dst_ip==127.0.0.1 || dst_ip==10.1.1.2) &&  
isbflagset(FLB_RTPENGINE_PRIV))) {
			setbflag(FLB_RTPENGINE);
		}

		# Need WebSocket to plain SIP bridging?
		if(proto==WSS && $(rP{s.toupper})!="WS") {
			setbflag(FLB_RTPENGINE);
		}
	}
#!endif
	return;
}


# Manage outgoing branches
branch_route[MANAGE_BRANCH] {
	route(RTPENGINE_DETECT);
	route(NATMANAGE);
}



Quoting Daniel-Constantin Mierla <miconda at gmail.com>:

> On 28/11/2016 14:44, Anthony Messina wrote:
>> I meant that before 4.4.4, I was building from the 4.4 branch will all
>> commits in that branch up until 81df84b . git diff 81df84b 4.4 should
>> show the difference, I just can't figure out what part isn't working.
>>
>>
>> I am not using t_suspend()/t_continue() or other async processing
>> functions
> Then I don't recall a change that could affect this behaviour.
>
>> and I do call route[NATMANAGE] after route[RELAY] from
>> branch_route[MANAGE_BRANCH].
>
> But I don't really get how you do the above stuff. Maybe you can paste
> here the relevant part of config with route RELAY and branch route....
>
> Cheers,
> Daniel
>
>>
>>
>> Quoting Daniel-Constantin Mierla <miconda at gmail.com>:
>>
>>> The commit 81df84b is related to tls, so there should be no relation
>>> with nat functions.
>>>
>>> Are you using t_suspend()/t_continue() or other async processing
>>> functions?
>>>
>>> Anyhow, whatever changes you want to be specific for each outgoing
>>> request must be done in a branch_route. request_route changes are
>>> visible to all changes and if you do something again in branch_route or
>>> failure_route, then you will see duplicated operations.
>>>
>>> Cheers,
>>> Daniel
>>>
>>>
>>> On 28/11/2016 09:02, Anthony Messina wrote:
>>>> Prior to the upgrade to Kamailio 4.4.4, I was using 4.4.3 with updates
>>>> through 81df84b from the 4.4 branch and the following fix_nated_sdp
>>>> call worked through the initial INVITE and when a voicemail branch was
>>>> appended from the failure_route.
>>>>
>>>> route[NATMANAGE] {
>>>> ...
>>>>
>>>> # RTPEngine is not needed but if STUN addresses are being used on our
>>>> # internal network, rewrite the addresses to the internal source
>>>> address
>>>> if(!isbflagset(FLB_RTPENGINE) && has_body("application/sdp")) {
>>>>         if(dst_ip==10.1.1.2 &&
>>>> compare_pure_ips($sel(contact.uri.host), "<EXTERNAL_IP>")) {
>>>>                 fix_nated_sdp("10");
>>>>         }
>>>> }
>>>>
>>>> ...
>>>> }
>>>>
>>>> Since the upgrade to 4.4.4, when the original INVITE fails over to
>>>> voicemail (branch appended), fix_nated_sdp creates the SDP below,
>>>> doubling the replaced IP addresses.  Asterisk replies with 488, as the
>>>> media address is completely invalid.  I need something like the above
>>>> (which worked for the request and the reply) but can't figure out what
>>>> the problem is.
>>>>
>>>> v=0
>>>> o=Zoiper 0 0 IN IP4 10.1.1.18210.1.1.182
>>>> s=Zoiper
>>>> c=IN IP4 10.1.1.18210.1.1.182
>>>> t=0 0
>>>> m=audio 63732 RTP/SAVP 9 3 0 97 101
>>>> a=rtpmap:9 G722/8000
>>>> a=rtpmap:3 GSM/8000
>>>> a=rtpmap:0 PCMU/8000
>>>> a=rtpmap:97 iLBC/8000
>>>> a=fmtp:97 mode=30
>>>> a=rtpmap:101 telephone-event/8000
>>>> a=fmtp:101 0-16
>>>> a=sendrecv
>>>> a=crypto:5 AES_256_CM_HMAC_SHA1_80
>>>> inline:n2C0BcdXOr32BPTEE8pfHII9mamAK566xMNvQIDIGKI2LPOLdNDOcpFdtqu5DQ==
>>>> a=crypto:6 AES_256_CM_HMAC_SHA1_32
>>>> inline:n2C0BcdXOr32BPTEE8pfHII9mamAK566xMNvQIDIGKI2LPOLdNDOcpFdtqu5DQ==
>>>> a=crypto:3 AES_192_CM_HMAC_SHA1_80
>>>> inline:n2C0BcdXOr32BPTEE8pfHII9mamAK566xMNvQIDIGKI2LPOLdNA=
>>>> a=crypto:4 AES_192_CM_HMAC_SHA1_32
>>>> inline:n2C0BcdXOr32BPTEE8pfHII9mamAK566xMNvQIDIGKI2LPOLdNA=
>>>> a=crypto:1 AES_CM_128_HMAC_SHA1_80
>>>> inline:n2C0BcdXOr32BPTEE8pfHII9mamAK566xMNvQIDI
>>>> a=crypto:2 AES_CM_128_HMAC_SHA1_32
>>>> inline:n2C0BcdXOr32BPTEE8pfHII9mamAK566xMNvQIDI
>>>> a=oldmediaip:<EXTERNAL_IP>
>>>> a=oldmediaip:<EXTERNAL_IP>
>>>> a=oldmediaip:<EXTERNAL_IP>
>>>> a=oldmediaip:<EXTERNAL_IP>
>>>>
>>>>
>>>>
>>>>
>>>> _______________________________________________
>>>> SIP Express Router (SER) and Kamailio (OpenSER) - sr-users mailing list
>>>> sr-users at lists.sip-router.org
>>>> http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-users
>>>
>>> --
>>> Daniel-Constantin Mierla
>>> http://twitter.com/#!/miconda - http://www.linkedin.com/in/miconda
>>> Kamailio Advanced Training, Berlin, Nov 28-30, 2016 -
>>> http://www.asipto.com
>>
>>
>>
>>
>> _______________________________________________
>> SIP Express Router (SER) and Kamailio (OpenSER) - sr-users mailing list
>> sr-users at lists.sip-router.org
>> http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-users
>
> --
> Daniel-Constantin Mierla
> http://twitter.com/#!/miconda - http://www.linkedin.com/in/miconda
> Kamailio Advanced Training, Berlin, Nov 28-30, 2016 - http://www.asipto.com


-- 
Anthony - https://messinet.com/ - https://messinet.com/~amessina/gallery
F9B6 560E 68EA 037D 8C3D  D1C9 FF31 3BDB D9D8 99B6
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 801 bytes
Desc: PGP Digital Signature
URL: <http://lists.sip-router.org/pipermail/sr-users/attachments/20161128/0d1da207/attachment.sig>


More information about the sr-users mailing list