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)=(a)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)=(a)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((a)contact.uri!="" && !is_gruu((a)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((a)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(a)gmail.com>om>:
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(a)gmail.com>om>:
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(a)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(a)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