From 82a9ca19afe2647be6e0f1e388bbcbe3c30b29c9 Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Fri, 2 Sep 2011 21:11:47 +0000 Subject: [PATCH] Fix obscure 3-way call connect issue Add test script for this error case Add on-hold/mute media IP handling, but disabled for now --- daemon/call.c | 7 ++ debian/changelog | 7 ++ tests/3-way-connect-simulator | 207 ++++++++++++++++++++++++++++++++++ 3 files changed, 221 insertions(+) create mode 100755 tests/3-way-connect-simulator diff --git a/daemon/call.c b/daemon/call.c index 66ebcf92f..b93796735 100644 --- a/daemon/call.c +++ b/daemon/call.c @@ -918,6 +918,13 @@ static char *streams_print(GQueue *s, unsigned int num, unsigned int off, const ip = t->call->callmaster->ip; if (t->call->callmaster->adv_ip) ip = t->call->callmaster->adv_ip; + +#if 0 + t = s->head->data; + if (t->peers[off].rtps[0].peer.ip == 0) + ip = 0; +#endif + if (!swap) g_string_append_printf(o, IPF, IPP(ip)); diff --git a/debian/changelog b/debian/changelog index f62eea7e5..f87888644 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +ngcp-mediaproxy-ng (1.4.2) unstable; urgency=low + + * Slightly increase syslog verbosity + * Fix obscure 3-way call connect issue + + -- Richard Fuchs Fri, 02 Sep 2011 17:09:38 -0400 + ngcp-mediaproxy-ng (1.4.1) unstable; urgency=low * Fix a memory leak diff --git a/tests/3-way-connect-simulator b/tests/3-way-connect-simulator new file mode 100755 index 000000000..782d8c965 --- /dev/null +++ b/tests/3-way-connect-simulator @@ -0,0 +1,207 @@ +#!/usr/bin/perl + +use warnings; +use strict; +use Socket; + +$| = 1; + +my $local_ip = '192.168.1.90'; + +sub brk { + sleep(1); +} + +sub mp_msg { + my ($cmd) = @_; + + my $fd; + socket($fd, AF_INET, SOCK_STREAM, 0) or die; + connect($fd, sockaddr_in(25060, inet_aton('127.0.0.1'))) or die; + my $old = select($fd); + $| = 1; + print("$cmd\n"); + my $ret = <$fd>; + select($old); + close($fd); + chomp($ret); + return $ret; +} + +sub udp_sock { + while (1) { + my $fd; + socket($fd, AF_INET, SOCK_DGRAM, 0) or die; + bind($fd, sockaddr_in(0, inet_aton('0.0.0.0'))) or die; + my $sa = getsockname($fd); + my ($port, $addr) = sockaddr_in($sa); + (($port % 2) == 0) or next; + return ($fd, $port); + } +} + +sub send_rcv { + my ($sendfd, $sendtoip, $sendtoport, $recvfd) = @_; + print("sending to $sendtoip:$sendtoport... "); + my $pkt = join('',map(rand,1..10)); + send($sendfd, $pkt, 0, sockaddr_in($sendtoport, inet_aton($sendtoip))) or die; + my $inc; + alarm(5); + recv($recvfd, $inc, length($pkt), 0); + alarm(0); + $inc eq $pkt or die; + print("received packet ok\n"); +} + +sub send_rcv4 { + send_rcv(@_[0,1,2,3]); + sleep(1); + send_rcv(@_[3,4,5,0]); + sleep(1); + send_rcv(@_[0,1,2,3]); + sleep(1); + send_rcv(@_[3,4,5,0]); +} + +my $callid1 = join('',map(rand,1..2)); +my $fromtag1 = join('',map(rand,1..4)); +my $totag1 = join('',map(rand,1..4)); +my $callid2 = join('',map(rand,1..2)); +my $fromtag2 = join('',map(rand,1..4)); +my $totag2 = join('',map(rand,1..4)); + +my ($client1, $lp1) = udp_sock(); +my ($client2, $lp2) = udp_sock(); +my ($client3, $lp3) = udp_sock(); +my ($client4, $lp4) = udp_sock(); + +print("call-ids: $callid1 & $callid2\n"); +print("opened ports $lp1 [A->B], $lp2 [B->A], $lp3 [B->C], $lp4 [C->B] as RTP clients\n"); +brk(); + +print("CALL 1: A calling B\n"); +print("A tells B: send RTP to $lp1\n"); +brk(); + +my ($mpip1, $mpport1) = split(/ /, mp_msg("request $callid1 $local_ip:$lp1:audio 192.168.101.11 80.110.1.48 remote 212.41.253.181 remote CS2000_NGSS/9.0 info=domain:voip.sipwise.local,from:431960681661\@80.110.1.48:5060,totag:,to:43720890289\@77.244.249.84:5060,fromtag:$fromtag1")); +print("mediaproxy: tell B to send to $mpport1 instead of $lp1\n"); +brk(); + +print("B tells A: send RTP to $lp2\n"); +brk(); + +my ($mpip2, $mpport2) = split(/ /, mp_msg("lookup $callid1 $local_ip:$lp2:audio 192.168.101.11 80.110.1.48 remote 212.41.253.181 remote CS2000_NGSS/9.0 info=domain:voip.sipwise.local,from:431960681661\@80.110.1.48:5060,totag:$totag1,to:43720890289\@77.244.249.84:5060,fromtag:$fromtag1")); +print("mediaproxy: tell A to send to $mpport2 instead of $lp2\n"); +brk(); + +send_rcv4($client2, $mpip1, $mpport1, $client1, $mpip2, $mpport2); + +brk(); + + + + + + + +print("B puts A on hold\n"); +print("B tells A: send RTP to 0.0.0.0\n"); + +brk(); + +my ($mpip3, $mpport3) = split(/ /, mp_msg("request $callid1 0.0.0.0:$lp2:audio 192.168.101.11 80.110.1.48 remote 212.41.253.181 remote CS2000_NGSS/9.0 info=domain:voip.sipwise.local,from:431960681661\@80.110.1.48:5060,totag:$fromtag1,to:43720890289\@77.244.249.84:5060,fromtag:$totag1")); +print("mediaproxy: tell A to send to $mpip3:$mpport3 instead of 0.0.0.0:$lp2\n"); +brk(); + +print("A tells B: send RTP to 0.0.0.0\n"); +brk(); + +my ($mpip4, $mpport4) = split(/ /, mp_msg("lookup $callid1 0.0.0.0:$lp1:audio 192.168.101.11 80.110.1.48 remote 212.41.253.181 remote CS2000_NGSS/9.0 info=domain:voip.sipwise.local,from:431960681661\@80.110.1.48:5060,totag:$fromtag1,to:43720890289\@77.244.249.84:5060,fromtag:$totag1")); +print("mediaproxy: tell B to send to $mpip4:$mpport4 instead of 0.0.0.0:$lp1\n"); +brk(); + + + + + + + +print("CALL 2: B calling C\n"); +print("B tells C: send RTP to $lp3\n"); + +brk(); + +my ($mpip5, $mpport5) = split(/ /, mp_msg("request $callid2 $local_ip:$lp3:audio 192.168.101.11 80.110.1.48 remote 212.41.253.181 remote CS2000_NGSS/9.0 info=domain:voip.sipwise.local,from:431960681661\@80.110.1.48:5060,totag:,to:43720890289\@77.244.249.84:5060,fromtag:$fromtag2")); +print("mediaproxy: tell C to send to $mpport5 instead of $lp3\n"); +brk(); + +print("C tells B: send RTP to $lp4\n"); +brk(); + +my ($mpip6, $mpport6) = split(/ /, mp_msg("lookup $callid2 $local_ip:$lp4:audio 192.168.101.11 80.110.1.48 remote 212.41.253.181 remote CS2000_NGSS/9.0 info=domain:voip.sipwise.local,from:431960681661\@80.110.1.48:5060,totag:$totag2,to:43720890289\@77.244.249.84:5060,fromtag:$fromtag2")); +print("mediaproxy: tell B to send to $mpport6 instead of $lp4\n"); +brk(); + +send_rcv4($client4, $mpip5, $mpport5, $client3, $mpip6, $mpport6); + +brk(); + + + + + + + +print("B un-holds A\n"); +print("B tells A: send RTP to $lp2\n"); + +brk(); + +my ($mpip7, $mpport7) = split(/ /, mp_msg("request $callid1 $local_ip:$lp2:audio 192.168.101.11 80.110.1.48 remote 212.41.253.181 remote CS2000_NGSS/9.0 info=domain:voip.sipwise.local,from:431960681661\@80.110.1.48:5060,totag:$fromtag1,to:43720890289\@77.244.249.84:5060,fromtag:$totag1")); +print("mediaproxy: tell A to send to $mpport7 instead of $lp2\n"); +brk(); + +print("A tells B: send RTP to $lp1\n"); +brk(); + +my ($mpip8, $mpport8) = split(/ /, mp_msg("lookup $callid1 $local_ip:$lp1:audio 192.168.101.11 80.110.1.48 remote 212.41.253.181 remote CS2000_NGSS/9.0 info=domain:voip.sipwise.local,from:431960681661\@80.110.1.48:5060,totag:$fromtag1,to:43720890289\@77.244.249.84:5060,fromtag:$totag1")); +print("mediaproxy: tell B to send to $mpport8 instead of $lp1\n"); +brk(); + +send_rcv4($client2, $mpip1, $mpport1, $client1, $mpip2, $mpport2); + +brk(); + + + + + +print("CONNECT: B connects A to C\n"); +print("B tells C [call 2]: send RTP to $mpip8:$mpport8\n"); + +brk(); + +my ($mpip9, $mpport9) = split(/ /, mp_msg("request $callid2 $mpip8:$mpport8:audio 192.168.101.11 80.110.1.48 remote 212.41.253.181 remote CS2000_NGSS/9.0 info=domain:voip.sipwise.local,from:431960681661\@80.110.1.48:5060,totag:$totag2,to:43720890289\@77.244.249.84:5060,fromtag:$fromtag2")); +print("mediaproxy: tell C to send to $mpport9 instead of $mpip8:$mpport8\n"); +brk(); + +print("C tells B: send RTP to $lp4\n"); +my ($mpip10, $mpport10) = split(/ /, mp_msg("lookup $callid2 $local_ip:$lp4:audio 192.168.101.11 80.110.1.48 remote 212.41.253.181 remote CS2000_NGSS/9.0 info=domain:voip.sipwise.local,from:431960681661\@80.110.1.48:5060,totag:$totag2,to:43720890289\@77.244.249.84:5060,fromtag:$fromtag2")); +print("mediaproxy: tell B to send to $mpport10 instead of $lp4\n"); +brk(); + + +print("B tells A [call 1]: send RTP to $mpip10:$mpport10\n"); + +my ($mpip11, $mpport11) = split(/ /, mp_msg("request $callid1 $mpip10:$mpport10:audio 192.168.101.11 80.110.1.48 remote 212.41.253.181 remote CS2000_NGSS/9.0 info=domain:voip.sipwise.local,from:431960681661\@80.110.1.48:5060,totag:$fromtag1,to:43720890289\@77.244.249.84:5060,fromtag:$totag1")); +print("mediaproxy: tell A to send to $mpport11 instead of $mpip10:$mpport10\n"); +brk(); + +send_rcv($client1, $mpip11, $mpport11, $client4); ###### <<<<<< error trigger + +print("A tells B: send RTP to $lp1\n"); +my ($mpip12, $mpport12) = split(/ /, mp_msg("lookup $callid1 $local_ip:$lp1:audio 192.168.101.11 80.110.1.48 remote 212.41.253.181 remote CS2000_NGSS/9.0 info=domain:voip.sipwise.local,from:431960681661\@80.110.1.48:5060,totag:$fromtag1,to:43720890289\@77.244.249.84:5060,fromtag:$totag1")); +print("mediaproxy: tell B to send to $mpport12 instead of $lp1\n"); +brk(); + +send_rcv4($client4, $mpip9, $mpport9, $client1, $mpip11, $mpport11);