From 5dbadc4adbec9f714534b7e542bcb3849915d3af Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Fri, 29 Jan 2016 14:49:15 -0500 Subject: [PATCH] implement port latching option closes #119 Change-Id: I9c5f3a560088ffb04c02e1b229a2616132a506e6 --- README.md | 6 ++++++ daemon/call.c | 14 +++++++++----- daemon/call_interfaces.c | 2 ++ daemon/call_interfaces.h | 1 + tests/simulator-ng.pl | 4 +++- utils/ng-client | 3 ++- 6 files changed, 23 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index a68884ff7..c8411132f 100644 --- a/README.md +++ b/README.md @@ -717,6 +717,12 @@ Optionally included keys are: This flag is valid only in an `offer` message and is useful when the call has been transferred to a new endpoint without change of `From` or `To` tags. + - `port latching` + + Forces *rtpengine* to retain its local ports during a signalling exchange even when the + remote endpoint changes its port. + + * `replace` Similar to the `flags` list. Controls which parts of the SDP body should be rewritten. diff --git a/daemon/call.c b/daemon/call.c index f7ce1ead3..d760c676c 100644 --- a/daemon/call.c +++ b/daemon/call.c @@ -682,7 +682,7 @@ static struct call_media *__get_media(struct call_monologue *ml, GList **it, con } static struct endpoint_map *__get_endpoint_map(struct call_media *media, unsigned int num_ports, - const struct endpoint *ep) + const struct endpoint *ep, const struct sdp_ng_flags *flags) { GList *l; struct endpoint_map *em; @@ -705,13 +705,17 @@ static struct endpoint_map *__get_endpoint_map(struct call_media *media, unsigne } if (!ep) /* creating wildcard map */ break; - /* handle zero endpoint address */ - if (is_addr_unspecified(&ep->address) || is_addr_unspecified(&em->endpoint.address)) { + + if (flags && flags->port_latching) + /* do nothing - ignore endpoint addresses */ ; + else if (is_addr_unspecified(&ep->address) || is_addr_unspecified(&em->endpoint.address)) { + /* handle zero endpoint address: only compare ports */ if (ep->port != em->endpoint.port) continue; } else if (memcmp(&em->endpoint, ep, sizeof(*ep))) continue; + if (em->num_ports >= num_ports) { if (is_addr_unspecified(&em->endpoint.address)) em->endpoint.address = ep->address; @@ -809,7 +813,7 @@ static void __assign_stream_fds(struct call_media *media, GQueue *intf_sfds) { static int __wildcard_endpoint_map(struct call_media *media, unsigned int num_ports) { struct endpoint_map *em; - em = __get_endpoint_map(media, num_ports, NULL); + em = __get_endpoint_map(media, num_ports, NULL, NULL); if (!em) return -1; @@ -1632,7 +1636,7 @@ int monologue_offer_answer(struct call_monologue *other_ml, GQueue *streams, /* get that many ports for each side, and one packet stream for each port, then * assign the ports to the streams */ - em = __get_endpoint_map(media, num_ports, &sp->rtp_endpoint); + em = __get_endpoint_map(media, num_ports, &sp->rtp_endpoint, flags); if (!em) { goto error_ports; } else { diff --git a/daemon/call_interfaces.c b/daemon/call_interfaces.c index 6991e5539..939c67742 100644 --- a/daemon/call_interfaces.c +++ b/daemon/call_interfaces.c @@ -557,6 +557,8 @@ static void call_ng_process_flags(struct sdp_ng_flags *out, bencode_item_t *inpu out->reset = 1; else if (it->iov[1].iov_len >= 5 && !memcmp(it->iov[1].iov_base, "SDES-", 5)) ng_sdes_option(out, it, 5); + else if (!bencode_strcmp(it, "port-latching")) + out->port_latching = 1; else ilog(LOG_WARN, "Unknown flag encountered: '"BENCODE_FORMAT"'", BENCODE_FMT(it)); diff --git a/daemon/call_interfaces.h b/daemon/call_interfaces.h index 1f6cb448c..23ee7bea8 100644 --- a/daemon/call_interfaces.h +++ b/daemon/call_interfaces.h @@ -32,6 +32,7 @@ struct sdp_ng_flags { int tos; int asymmetric:1, trust_address:1, + port_latching:1, replace_origin:1, replace_sess_conn:1, ice_remove:1, diff --git a/tests/simulator-ng.pl b/tests/simulator-ng.pl index 8a93fbc4d..e2894519a 100755 --- a/tests/simulator-ng.pl +++ b/tests/simulator-ng.pl @@ -18,7 +18,7 @@ use SRTP; my ($NUM, $RUNTIME, $STREAMS, $PAYLOAD, $INTERVAL, $RTCP_INTERVAL, $STATS_INTERVAL) = (1000, 30, 1, 160, 20, 5, 5); my ($NODEL, $IP, $IPV6, $KEEPGOING, $REINVITES, $PROTOS, $DEST, $SUITES, $NOENC, $RTCPMUX, $BUNDLE, $LAZY, - $CHANGE_SSRC); + $CHANGE_SSRC, $PORT_LATCHING); GetOptions( 'no-delete' => \$NODEL, 'num-calls=i' => \$NUM, @@ -40,6 +40,7 @@ GetOptions( 'bundle' => \$BUNDLE, 'lazy-params' => \$LAZY, 'change-ssrc' => \$CHANGE_SSRC, + 'port-latching' => \$PORT_LATCHING, ) or die; ($IP || $IPV6) or die("at least one of --local-ip or --local-ipv6 must be given"); @@ -635,6 +636,7 @@ a=rtpmap:111 opus/48000/2 'received from' => [ qw(IP4 127.0.0.1) ], 'rtcp-mux' => ['demux'], }; + $PORT_LATCHING and push(@{$dict->{flags}}, 'port latching'); #$viabranch and $dict->{'via-branch'} = $viabranch; if ($op eq 'offer') { $dict->{'from-tag'} = $$A{tag}; diff --git a/utils/ng-client b/utils/ng-client index a46b5fc0e..c69512fab 100755 --- a/utils/ng-client +++ b/utils/ng-client @@ -43,6 +43,7 @@ GetOptions( 'TOS=i' => \$options{'TOS'}, 'delete-delay=i' => \$options{'delete-delay'}, 'reset' => \$options{'reset'}, + 'port-latching' => \$options{'port latching'}, ) or die; my $cmd = shift(@ARGV) or die; @@ -52,7 +53,7 @@ my %packet = (command => $cmd); for my $x (split(',', 'from-tag,to-tag,call-id,transport protocol,media address,ICE,address family,TOS,DTLS,via-branch,delete-delay')) { defined($options{$x}) and $packet{$x} = $options{$x}; } -for my $x (split(',', 'trust address,symmetric,asymmetric,force,strict source,media handover,sip source address,reset')) { +for my $x (split(',', 'trust address,symmetric,asymmetric,force,strict source,media handover,sip source address,reset,port latching')) { defined($options{$x}) and push(@{$packet{flags}}, $x); } for my $x (split(',', 'origin,session connection')) {