From d5f7624a98baf6b0147b95703759e7f6e14f2dd9 Mon Sep 17 00:00:00 2001 From: Guillem Jover Date: Wed, 8 Nov 2017 17:07:39 +0100 Subject: [PATCH 01/65] TT#24097 Fix perl filehandle usage - Use autoflush method per filehandle instead of setting $| and using the one argument select(). - Use lexical variables instead of barewords for filehandles. Change-Id: Icd71248a28bea0974a79e489add5deee0b65748d --- tests/3-way-connect-simulator | 8 ++--- tests/blist.pl | 5 +-- tests/kernel-module-test.pl | 62 ++++++++++++++++------------------- tests/reinvite-simulator | 8 ++--- utils/rtpengine-ctl | 5 ++- utils/rtpengine-ng-client | 6 ++-- 6 files changed, 43 insertions(+), 51 deletions(-) diff --git a/tests/3-way-connect-simulator b/tests/3-way-connect-simulator index 24e75d241..ae4e8f663 100755 --- a/tests/3-way-connect-simulator +++ b/tests/3-way-connect-simulator @@ -4,7 +4,7 @@ use warnings; use strict; use Socket; -$| = 1; +STDOUT->autoflush(1); @@ -28,11 +28,9 @@ sub mp_msg { 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"); + $fd->autoflush(1); + print { $fd } ("$cmd\n"); my $ret = <$fd>; - select($old); close($fd); chomp($ret); return $ret; diff --git a/tests/blist.pl b/tests/blist.pl index 34368f6bd..807fdbbd7 100755 --- a/tests/blist.pl +++ b/tests/blist.pl @@ -10,9 +10,9 @@ my $t = $ARGV[0] || "0"; my $format = 'SS ia16SS ia16SS ia16SS CCCC LLLLLL'; my $len = length(pack($format, (0) x 100)); -open(X, "<", "/proc/rtpengine/$t/blist") or die; +open(my $fh, "<", "/proc/rtpengine/$t/blist") or die; my $buf; -while (sysread(X, $buf, $len)) { +while (sysread($fh, $buf, $len)) { my @b = unpack($format, $buf); for (2,6,10) { if ($b[$_] == AF_INET) { @@ -30,3 +30,4 @@ while (sysread(X, $buf, $len)) { } printf("%5u %15s:%-5u -> %15s:%-5u (-> %15s:%-5u) [%u] [%llu %llu %llu]\n", @b[0,3,4,7,8,11,12,14,18,20,22]); } +close($fh); diff --git a/tests/kernel-module-test.pl b/tests/kernel-module-test.pl index d53cf8501..ab0ab4ac3 100755 --- a/tests/kernel-module-test.pl +++ b/tests/kernel-module-test.pl @@ -8,14 +8,10 @@ use Socket6; my %cmds = (noop => 1, add => 2, delete => 3, update => 4, add_call => 5, del_call => 6, add_stream => 7, del_stream => 8, packet => 9); my %ciphers = ('null' => 1, 'aes-cm' => 2, 'aes-f8' => 3); my %hmacs = ('null' => 1, 'hmac-sha1' => 2); -$| = 1; +STDOUT->autoflush(1); -open(F, "+> /proc/rtpengine/0/control") or die; -{ - my $x = select(F); - $| = 1; - select($x); -} +open(my $fh, '+>', '/proc/rtpengine/0/control') or die; +$fh->autoflush(1); sub re_address { my ($fam, $addr, $port) = @_; @@ -140,47 +136,47 @@ my $ret; my $msg; # print("add 9876 -> 1234/6543\n"); -# $ret = syswrite(F, rtpengine_message('add', local_addr => \@local, local_port => 9876, src_addr => \@src, src_port => 1234, dst_addr => \@dst, dst_port => 6543, tos => 184, decrypt => $dec, encrypt => $enc)) // '-'; +# $ret = syswrite($fh, rtpengine_message('add', local_addr => \@local, local_port => 9876, src_addr => \@src, src_port => 1234, dst_addr => \@dst, dst_port => 6543, tos => 184, decrypt => $dec, encrypt => $enc)) // '-'; # print("ret = $ret, code = $!\n"); # sleep($sleep); # print("add fail\n"); -# $ret = syswrite(F, rtpengine_message('add', local_addr => \@local, local_port => 9876, src_addr => \@src, src_port => 1234, dst_addr => \@dst, dst_port => 6543, mirror_addr => \@dst, mirror_port => 6789, tos => 184, decrypt => $dec, encrypt => $enc)) // '-'; +# $ret = syswrite($fh, rtpengine_message('add', local_addr => \@local, local_port => 9876, src_addr => \@src, src_port => 1234, dst_addr => \@dst, dst_port => 6543, mirror_addr => \@dst, mirror_port => 6789, tos => 184, decrypt => $dec, encrypt => $enc)) // '-'; # print("ret = $ret, code = $!\n"); # sleep($sleep); # print("update 9876 -> 1234/6543 & 6789\n"); -# $ret = syswrite(F, rtpengine_message('update', local_addr => \@local, local_port => 9876, src_addr => \@src, src_port => 1234, dst_addr => \@dst, dst_port => 6543, mirror_addr => \@dst, mirror_port => 6789, tos => 184, decrypt => $dec, encrypt => $enc)) // '-'; +# $ret = syswrite($fh, rtpengine_message('update', local_addr => \@local, local_port => 9876, src_addr => \@src, src_port => 1234, dst_addr => \@dst, dst_port => 6543, mirror_addr => \@dst, mirror_port => 6789, tos => 184, decrypt => $dec, encrypt => $enc)) // '-'; # print("ret = $ret, code = $!\n"); # sleep($sleep); # print("update 9876 -> 2345/7890 & 4321\n"); -# $ret = syswrite(F, rtpengine_message('update', local_addr => \@local, local_port => 9876, src_addr => \@src, src_port => 2345, dst_addr => \@dst, dst_port => 7890, mirror_addr => \@dst, mirror_port => 4321, tos => 184, decrypt => $dec, encrypt => $enc)) // '-'; +# $ret = syswrite($fh, rtpengine_message('update', local_addr => \@local, local_port => 9876, src_addr => \@src, src_port => 2345, dst_addr => \@dst, dst_port => 7890, mirror_addr => \@dst, mirror_port => 4321, tos => 184, decrypt => $dec, encrypt => $enc)) // '-'; # print("ret = $ret, code = $!\n"); # sleep($sleep); # print("add fail\n"); -# $ret = syswrite(F, rtpengine_message('add', local_addr => \@local, local_port => 9876, src_addr => \@src, src_port => 1234, dst_addr => \@dst, dst_port => 6543, mirror_addr => \@dst, mirror_port => 6789, tos => 184, decrypt => $dec, encrypt => $enc)) // '-'; +# $ret = syswrite($fh, rtpengine_message('add', local_addr => \@local, local_port => 9876, src_addr => \@src, src_port => 1234, dst_addr => \@dst, dst_port => 6543, mirror_addr => \@dst, mirror_port => 6789, tos => 184, decrypt => $dec, encrypt => $enc)) // '-'; # print("ret = $ret, code = $!\n"); # sleep($sleep); # print("update 9876 -> 1234/6543\n"); -# $ret = syswrite(F, rtpengine_message('update', local_addr => \@local, local_port => 9876, src_addr => \@src, src_port => 1234, dst_addr => \@dst, dst_port => 6543, tos => 184, decrypt => $dec, encrypt => $enc)) // '-'; +# $ret = syswrite($fh, rtpengine_message('update', local_addr => \@local, local_port => 9876, src_addr => \@src, src_port => 1234, dst_addr => \@dst, dst_port => 6543, tos => 184, decrypt => $dec, encrypt => $enc)) // '-'; # print("ret = $ret, code = $!\n"); # sleep($sleep); # print("delete\n"); -# $ret = syswrite(F, rtpengine_message('delete', local_addr => \@local, local_port => 9876, decrypt => $dec, encrypt => $enc)) // '-'; +# $ret = syswrite($fh, rtpengine_message('delete', local_addr => \@local, local_port => 9876, decrypt => $dec, encrypt => $enc)) // '-'; # print("ret = $ret, code = $!\n"); # sleep($sleep); # print("delete fail\n"); -# $ret = syswrite(F, rtpengine_message('delete', local_addr => \@local, local_port => 9876, decrypt => $dec, encrypt => $enc)) // '-'; +# $ret = syswrite($fh, rtpengine_message('delete', local_addr => \@local, local_port => 9876, decrypt => $dec, encrypt => $enc)) // '-'; # print("ret = $ret, code = $!\n"); # sleep($sleep); # print("update fail\n"); -# $ret = syswrite(F, rtpengine_message('update', local_addr => \@local, local_port => 9876, src_addr => \@src, src_port => 1234, dst_addr => \@dst, dst_port => 6543, tos => 184, decrypt => $dec, encrypt => $enc)) // '-'; +# $ret = syswrite($fh, rtpengine_message('update', local_addr => \@local, local_port => 9876, src_addr => \@src, src_port => 1234, dst_addr => \@dst, dst_port => 6543, tos => 184, decrypt => $dec, encrypt => $enc)) // '-'; # print("ret = $ret, code = $!\n"); # sleep($sleep); @@ -215,7 +211,7 @@ if (0) { print("creating call $name\n"); $msg = rtpengine_message_call('add_call', 0, $name); - $ret = sysread(F, $msg, length($msg)) // '-'; + $ret = sysread($fh, $msg, length($msg)) // '-'; #print("reply: " . unpack("H*", $msg) . "\n"); print("ret = $ret, code = $!\n"); @@ -232,7 +228,7 @@ if (0) { print("creating stream $name under call idx $call\n"); $msg = rtpengine_message_stream('add_stream', $call, 0, $name); - $ret = sysread(F, $msg, length($msg)) // '-'; + $ret = sysread($fh, $msg, length($msg)) // '-'; #print("reply: " . unpack("H*", $msg) . "\n"); print("ret = $ret, code = $!\n"); @@ -249,7 +245,7 @@ if (0) { print("deleting call idx $call\n"); $msg = rtpengine_message_call('del_call', $call); - $ret = syswrite(F, $msg) // '-'; + $ret = syswrite($fh, $msg) // '-'; #print("ret = $ret, code = $!, reply: " . unpack("H*", $msg) . "\n"); print("ret = $ret, code = $!\n"); @@ -278,7 +274,7 @@ if (0) { print("deleting stream idx $stream->[1] (call $stream->[0])\n"); $msg = rtpengine_message_stream('del_stream', $stream->[0], $stream->[1]); - $ret = syswrite(F, $msg) // '-'; + $ret = syswrite($fh, $msg) // '-'; #print("ret = $ret, code = $!, reply: " . unpack("H*", $msg) . "\n"); print("ret = $ret, code = $!\n"); @@ -295,7 +291,7 @@ if (0) { print("delivering a packet to $idx\n"); $msg = rtpengine_message_packet('packet', 0, $idx, 'packet data bla bla ' . rand() . "\n"); - $ret = syswrite(F, $msg) // '-'; + $ret = syswrite($fh, $msg) // '-'; print("ret = $ret, code = $!\n"); sleep($sleep); @@ -316,7 +312,7 @@ if (0) { print("creating call\n"); $msg = rtpengine_message_call('add_call', 0, 'test call'); -$ret = sysread(F, $msg, length($msg)) // '-'; +$ret = sysread($fh, $msg, length($msg)) // '-'; #print("reply: " . unpack("H*", $msg) . "\n"); print("ret = $ret, code = $!\n"); @@ -330,7 +326,7 @@ sleep($sleep); # print("creating identical call\n"); # # $msg = rtpengine_message_call('add_call', 0, 'test call'); -# $ret = sysread(F, $msg, length($msg)) // '-'; +# $ret = sysread($fh, $msg, length($msg)) // '-'; # #print("reply: " . unpack("H*", $msg) . "\n"); # print("ret = $ret, code = $!\n"); # @@ -344,7 +340,7 @@ sleep($sleep); # print("creating other call\n"); # # $msg = rtpengine_message_call('add_call', 0, 'another test call'); -# $ret = sysread(F, $msg, length($msg)) // '-'; +# $ret = sysread($fh, $msg, length($msg)) // '-'; # #print("reply: " . unpack("H*", $msg) . "\n"); # print("ret = $ret, code = $!\n"); # @@ -359,7 +355,7 @@ for my $exp (0 .. 1000) { print("creating a stream\n"); $msg = rtpengine_message_stream('add_stream', $idx1, 0, 'test stream ' . rand()); - $ret = sysread(F, $msg, length($msg)) // '-'; + $ret = sysread($fh, $msg, length($msg)) // '-'; #print("reply: " . unpack("H*", $msg) . "\n"); print("ret = $ret, code = $!\n"); @@ -373,7 +369,7 @@ for my $exp (0 .. 1000) { # print("creating a stream\n"); # # $msg = rtpengine_message_stream('add_stream', $idx1, 0, 'test stream'); -# $ret = sysread(F, $msg, length($msg)) // '-'; +# $ret = sysread($fh, $msg, length($msg)) // '-'; # #print("reply: " . unpack("H*", $msg) . "\n"); # print("ret = $ret, code = $!\n"); # @@ -387,7 +383,7 @@ for my $exp (0 .. 1000) { # print("creating identical stream\n"); # # $msg = rtpengine_message_stream('add_stream', $idx1, 0, 'test stream'); -# $ret = sysread(F, $msg, length($msg)) // '-'; +# $ret = sysread($fh, $msg, length($msg)) // '-'; # #print("reply: " . unpack("H*", $msg) . "\n"); # print("ret = $ret, code = $!\n"); # @@ -401,7 +397,7 @@ for my $exp (0 .. 1000) { # print("creating different stream\n"); # # $msg = rtpengine_message_stream('add_stream', $idx3, 0, 'test stream'); -# $ret = sysread(F, $msg, length($msg)) // '-'; +# $ret = sysread($fh, $msg, length($msg)) // '-'; # #print("reply: " . unpack("H*", $msg) . "\n"); # print("ret = $ret, code = $!\n"); # @@ -413,7 +409,7 @@ for my $exp (0 .. 1000) { # print("add 9876 -> 1234/6543\n"); -# $ret = syswrite(F, rtpengine_message('add', local_addr => \@local, local_port => 9876, src_addr => \@src, src_port => 1234, dst_addr => \@dst, dst_port => 6543, tos => 184, decrypt => $dec, encrypt => $enc, stream_idx => $sidx1, flags => 0x20)) // '-'; +# $ret = syswrite($fh, rtpengine_message('add', local_addr => \@local, local_port => 9876, src_addr => \@src, src_port => 1234, dst_addr => \@dst, dst_port => 6543, tos => 184, decrypt => $dec, encrypt => $enc, stream_idx => $sidx1, flags => 0x20)) // '-'; # print("ret = $ret, code = $!\n"); # sleep($sleep); @@ -423,7 +419,7 @@ for my $exp (0 .. 1000) { # print("delivering a packet\n"); # # $msg = rtpengine_message_packet('packet', $idx1, $sidx1, 'packet data bla bla ' . rand() . "\n"); -# $ret = syswrite(F, $msg) // '-'; +# $ret = syswrite($fh, $msg) // '-'; # #print("reply: " . unpack("H*", $msg) . "\n"); # print("ret = $ret, code = $!\n"); # @@ -436,7 +432,7 @@ for my $exp (0 .. 1000) { # print("deleting stream\n"); # # $msg = rtpengine_message_stream('del_stream', $idx1, $sidx1, ''); -# $ret = syswrite(F, $msg) // '-'; +# $ret = syswrite($fh, $msg) // '-'; # #print("ret = $ret, code = $!, reply: " . unpack("H*", $msg) . "\n"); # print("ret = $ret, code = $!\n"); # @@ -447,7 +443,7 @@ for my $exp (0 .. 1000) { # print("deleting call\n"); # # $msg = rtpengine_message_call('del_call', $idx1, ''); -# $ret = syswrite(F, $msg) // '-'; +# $ret = syswrite($fh, $msg) // '-'; # #print("ret = $ret, code = $!, reply: " . unpack("H*", $msg) . "\n"); # print("ret = $ret, code = $!\n"); # @@ -456,4 +452,4 @@ for my $exp (0 .. 1000) { -close(F); +close($fh); diff --git a/tests/reinvite-simulator b/tests/reinvite-simulator index aff0c0143..708baa5aa 100755 --- a/tests/reinvite-simulator +++ b/tests/reinvite-simulator @@ -4,7 +4,7 @@ use warnings; use strict; use Socket; -$| = 1; +STDOUT->autoflush(1); @@ -28,11 +28,9 @@ sub mp_msg { 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"); + $fd->autoflush(1); + print { $fd } ("$cmd\n"); my $ret = <$fd>; - select($old); close($fd); chomp($ret); return $ret; diff --git a/utils/rtpengine-ctl b/utils/rtpengine-ctl index ff1b21362..93256e1fc 100755 --- a/utils/rtpengine-ctl +++ b/utils/rtpengine-ctl @@ -10,9 +10,6 @@ if ( ($num_args == 0) or exit; } -# auto-flush on socket -$| = 1; - my $argumentstring = ""; my $ip = "127.0.0.1"; my $port = "9900"; @@ -39,6 +36,8 @@ my $socket = new IO::Socket::INET ( ); die "Cannot connect to the rtpengine $!\n" unless $socket; +$socket->autoflush(1); + #set send/recv timeout so script doesn't hang when rtpengine doesn't interact setsockopt($socket, SOL_SOCKET, SO_SNDTIMEO, pack('L!L!', 3, 0) ) or die $!; setsockopt($socket, SOL_SOCKET, SO_RCVTIMEO, pack('L!L!', 3, 0) ) or die $!; diff --git a/utils/rtpengine-ng-client b/utils/rtpengine-ng-client index c431841d9..c6dc58a81 100755 --- a/utils/rtpengine-ng-client +++ b/utils/rtpengine-ng-client @@ -74,9 +74,9 @@ if (defined($options{sdp})) { $packet{sdp} = $options{sdp}; } elsif (defined($options{'sdp-file'})) { - open(F, '<', $options{'sdp-file'}) or die $!; - my @sdp = or die $!; - close(F); + open(my $fh, '<', $options{'sdp-file'}) or die $!; + my @sdp = <$fh> or die $!; + close($fh); $packet{sdp} = join('', @sdp); } #elsif (@ARGV && $ARGV[0] eq 'sdp') { From 4f006a5cadcb0b4e8f26fedf868f634da8a5cbec Mon Sep 17 00:00:00 2001 From: Guillem Jover Date: Wed, 8 Nov 2017 17:11:57 +0100 Subject: [PATCH 02/65] TT#24097 Use block form for map and grep Change-Id: I6e2c68762c13bb89dcaf916f8e5ce476c34179dd --- tests/3-way-connect-simulator | 14 +++++++------- tests/reinvite-simulator | 8 ++++---- tests/simulator-ng.pl | 2 +- tests/simulator-udp.pl | 2 +- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/tests/3-way-connect-simulator b/tests/3-way-connect-simulator index ae4e8f663..f48796372 100755 --- a/tests/3-way-connect-simulator +++ b/tests/3-way-connect-simulator @@ -51,7 +51,7 @@ sub udp_sock { sub send_rcv { my ($sendfd, $sendtoip, $sendtoport, $recvfd) = @_; print("sending to $sendtoip:$sendtoport... "); - my $pkt = join('',map(rand,1..10)); + my $pkt = join('', map { rand } 1..10); send($sendfd, $pkt, 0, sockaddr_in($sendtoport, inet_aton($sendtoip))) or die; my $inc; { @@ -97,12 +97,12 @@ sub sim_lk { -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 $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(); diff --git a/tests/reinvite-simulator b/tests/reinvite-simulator index 708baa5aa..ac31a0578 100755 --- a/tests/reinvite-simulator +++ b/tests/reinvite-simulator @@ -53,7 +53,7 @@ sub send_rcv { my $laddr = getsockname($sendfd); my ($lport, $lip) = sockaddr_in($laddr); print("local port $lport sending to $sendtoip:$sendtoport... "); - my $pkt = join('',map(rand,1..10)); + my $pkt = join('', map { rand } 1..10); send($sendfd, $pkt, 0, sockaddr_in($sendtoport, inet_aton($sendtoip))) or die; my ($inc, $addr); { @@ -108,9 +108,9 @@ sub sim_lk { -my $callid = join('',map(rand,1..2)); -my $fromtag = join('',map(rand,1..4)); -my $totag = join('',map(rand,1..4)); +my $callid = join('', map { rand } 1..2); +my $fromtag = join('', map { rand } 1..4); +my $totag = join('', map { rand } 1..4); my ($client1, $lp1) = udp_sock(); my ($client2, $lp2) = udp_sock(); diff --git a/tests/simulator-ng.pl b/tests/simulator-ng.pl index 339bce7fd..244193173 100755 --- a/tests/simulator-ng.pl +++ b/tests/simulator-ng.pl @@ -792,7 +792,7 @@ while (time() < $end) { do_rtp($rtcp); - @calls = sort {rand() < .5} grep(defined, @calls); + @calls = sort { rand() < .5 } grep { defined } @calls; if ($REINVITES && $now >= $last_reinv + 15) { $last_reinv = $now; diff --git a/tests/simulator-udp.pl b/tests/simulator-udp.pl index 9556832b1..035cbd1f6 100755 --- a/tests/simulator-udp.pl +++ b/tests/simulator-udp.pl @@ -175,7 +175,7 @@ while (time() < $end) { sleep(1); do_rtp(); - @calls = sort {rand() < .5} grep(defined, @calls); + @calls = sort { rand() < .5 } grep { defined } @calls; if ($REINVITES) { my $c = $calls[rand(@calls)]; From aa2eaee95e867d3ca33d1ff8c9617fa7e35a4bac Mon Sep 17 00:00:00 2001 From: Guillem Jover Date: Wed, 8 Nov 2017 17:12:59 +0100 Subject: [PATCH 03/65] TT#24097 Use a regex for split Change-Id: Id8543d7d792e35a736c770fc87a20fa399d68bad --- utils/rtpengine-ng-client | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/utils/rtpengine-ng-client b/utils/rtpengine-ng-client index c6dc58a81..70a8335e2 100755 --- a/utils/rtpengine-ng-client +++ b/utils/rtpengine-ng-client @@ -49,19 +49,19 @@ my $cmd = shift(@ARGV) or die; my %packet = (command => $cmd); -for my $x (split(',', 'from-tag,to-tag,call-id,transport protocol,media address,ICE,address family,DTLS,via-branch,media address')) { +for my $x (split(/,/, 'from-tag,to-tag,call-id,transport protocol,media address,ICE,address family,DTLS,via-branch,media address')) { defined($options{$x}) and $packet{$x} = \$options{$x}; } -for my $x (split(',', 'TOS,delete-delay')) { +for my $x (split(/,/, 'TOS,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,port latching')) { +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')) { +for my $x (split(/,/, 'origin,session connection')) { defined($options{'replace-' . $x}) and push(@{$packet{replace}}, $x); } -for my $x (split(',', 'rtcp-mux,SDES')) { +for my $x (split(/,/, 'rtcp-mux,SDES')) { defined($options{$x}) && ref($options{$x}) eq 'ARRAY' and $packet{$x} = $options{$x}; } From bf514fb2a0e0dd68c3b41e5f20e2408b55823ddc Mon Sep 17 00:00:00 2001 From: Guillem Jover Date: Wed, 8 Nov 2017 17:15:09 +0100 Subject: [PATCH 04/65] TT#24097 Do not directly return result from sort Using sort on a scalar context has undefined behavior. Assign the result of the sort into an array and return that. Change-Id: I180ba1dfcafe6e49132a38bd01be715718a4dff1 --- perl/NGCP/Rtpclient/ICE.pm | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/perl/NGCP/Rtpclient/ICE.pm b/perl/NGCP/Rtpclient/ICE.pm index c3c062c3e..775873324 100644 --- a/perl/NGCP/Rtpclient/ICE.pm +++ b/perl/NGCP/Rtpclient/ICE.pm @@ -795,7 +795,10 @@ sub keepalives { sub sort_pairs { my ($pair_list) = @_; - return sort {$a->priority() <=> $b->priority()} @$pair_list; + my @sorted_list = sort { + $a->priority() <=> $b->priority() + } @{$pair_list}; + return @sorted_list; } sub get_send_component { From d5ad4a9f88bb4c7b5006f6cb94aed8aba1f1785b Mon Sep 17 00:00:00 2001 From: Guillem Jover Date: Wed, 8 Nov 2017 17:17:37 +0100 Subject: [PATCH 05/65] TT#24097 Do not use magic variable names These variables have magic meanings, we should avoid their usage to not confuse readers nor trigger side-effects. Change-Id: Ieb759f74ccde6ba6466f5c02743e3f881b5d53b7 --- tests/blist.pl | 18 +++++++++--------- tests/simulator-ng.pl | 24 ++++++++++++------------ 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/tests/blist.pl b/tests/blist.pl index 807fdbbd7..a5f1ad1ab 100755 --- a/tests/blist.pl +++ b/tests/blist.pl @@ -13,21 +13,21 @@ my $len = length(pack($format, (0) x 100)); open(my $fh, "<", "/proc/rtpengine/$t/blist") or die; my $buf; while (sysread($fh, $buf, $len)) { - my @b = unpack($format, $buf); + my @buf = unpack($format, $buf); for (2,6,10) { - if ($b[$_] == AF_INET) { - $b[$_ + 1] = inet_ntoa($b[$_ + 1]); + if ($buf[$_] == AF_INET) { + $buf[$_ + 1] = inet_ntoa($buf[$_ + 1]); } - elsif ($b[$_] == AF_INET6) { - $b[$_ + 1] = inet_ntop(AF_INET6, $b[$_ + 1]); + elsif ($buf[$_] == AF_INET6) { + $buf[$_ + 1] = inet_ntop(AF_INET6, $buf[$_ + 1]); } - elsif ($b[$_] == 0) { - $b[$_ + 1] = '---'; + elsif ($buf[$_] == 0) { + $buf[$_ + 1] = '---'; } } for (18, 20, 22) { - $b[$_] += $b[$_ + 1] * 2**32; + $buf[$_] += $buf[$_ + 1] * 2**32; } - printf("%5u %15s:%-5u -> %15s:%-5u (-> %15s:%-5u) [%u] [%llu %llu %llu]\n", @b[0,3,4,7,8,11,12,14,18,20,22]); + printf("%5u %15s:%-5u -> %15s:%-5u (-> %15s:%-5u) [%u] [%llu %llu %llu]\n", @buf[0,3,4,7,8,11,12,14,18,20,22]); } close($fh); diff --git a/tests/simulator-ng.pl b/tests/simulator-ng.pl index 244193173..2eab8515e 100755 --- a/tests/simulator-ng.pl +++ b/tests/simulator-ng.pl @@ -334,24 +334,24 @@ sub rtp_savp { sub savp_crypto { my ($sdp, $ctx, $ctx_o) = @_; - my @a = $sdp =~ /[\r\n]a=crypto:(\d+) (\w+) inline:([\w\/+=]{40,})(?:\|(?:2\^(\d+)|(\d+)))?(?:\|(\d+):(\d+))?(?: (.*?))?[\r\n]/sig; - @a or die; + my @aa = $sdp =~ /[\r\n]a=crypto:(\d+) (\w+) inline:([\w\/+=]{40,})(?:\|(?:2\^(\d+)|(\d+)))?(?:\|(\d+):(\d+))?(?: (.*?))?[\r\n]/sig; + @aa or die; my $i = 0; - while (@a >= 8) { - $$ctx[$i]{in}{crypto_suite} = $NGCP::Rtpclient::SRTP::crypto_suites{$a[1]} or die; - $$ctx[$i]{in}{crypto_tag} = $a[0]; + while (@aa >= 8) { + $$ctx[$i]{in}{crypto_suite} = $NGCP::Rtpclient::SRTP::crypto_suites{$aa[1]} or die; + $$ctx[$i]{in}{crypto_tag} = $aa[0]; ($$ctx[$i]{in}{rtp_master_key}, $$ctx[$i]{in}{rtp_master_salt}) - = NGCP::Rtpclient::SRTP::decode_inline_base64($a[2], $$ctx[$i]{in}{crypto_suite}); - $$ctx[$i]{in}{rtp_mki} = $a[5]; - $$ctx[$i]{in}{rtp_mki_len} = $a[6]; + = NGCP::Rtpclient::SRTP::decode_inline_base64($aa[2], $$ctx[$i]{in}{crypto_suite}); + $$ctx[$i]{in}{rtp_mki} = $aa[5]; + $$ctx[$i]{in}{rtp_mki_len} = $aa[6]; undef($$ctx[$i]{in}{rtp_session_key}); undef($$ctx[$i]{in}{rtcp_session_key}); - ($a[7] || '') =~ /UNENCRYPTED_SRTP/ and $$ctx[$i]{in}{unenc_srtp} = 1; - ($a[7] || '') =~ /UNENCRYPTED_SRTCP/ and $$ctx[$i]{in}{unenc_srtcp} = 1; - ($a[7] || '') =~ /UNAUTHENTICATED_SRTP/ and $$ctx[$i]{in}{unauth_srtp} = 1; + ($aa[7] || '') =~ /UNENCRYPTED_SRTP/ and $$ctx[$i]{in}{unenc_srtp} = 1; + ($aa[7] || '') =~ /UNENCRYPTED_SRTCP/ and $$ctx[$i]{in}{unenc_srtcp} = 1; + ($aa[7] || '') =~ /UNAUTHENTICATED_SRTP/ and $$ctx[$i]{in}{unauth_srtp} = 1; $i++; - @a = @a[8 .. $#a]; + @aa = @aa[8 .. $#aa]; } } From 301af4a2e96204b9038d37810ee18ed176b6053d Mon Sep 17 00:00:00 2001 From: Guillem Jover Date: Wed, 8 Nov 2017 17:18:56 +0100 Subject: [PATCH 06/65] TT#24097 Declare variable as my Change-Id: Id5aa7f7f3c0839564804102fb401e5422e676433 --- utils/rtpengine-ctl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/rtpengine-ctl b/utils/rtpengine-ctl index 93256e1fc..496d50673 100755 --- a/utils/rtpengine-ctl +++ b/utils/rtpengine-ctl @@ -2,7 +2,7 @@ use IO::Socket::INET; -$num_args = $#ARGV + 1; +my $num_args = $#ARGV + 1; if ( ($num_args == 0) or (($num_args == 1) && (($ARGV[0] eq "--help") or ($ARGV[0] eq "-h"))) ) { From 0c728b204118ba8d830852b8c0d31fd93f0e89ca Mon Sep 17 00:00:00 2001 From: Guillem Jover Date: Wed, 8 Nov 2017 17:20:21 +0100 Subject: [PATCH 07/65] TT#24097 Localize %ENV variable assignments While these instances are a bit pointless as they are assigned on the file scope, and this is something that should be allowed by perlcritic. Let's just do this, which does no harm, so that we can catch other problematic cases. Change-Id: I674b1374a62fa976e20a3fedf356ae6d4848a796 --- tests/simulator-ng.pl | 2 +- tests/simulator-udp.pl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/simulator-ng.pl b/tests/simulator-ng.pl index 2eab8515e..0c17aa910 100755 --- a/tests/simulator-ng.pl +++ b/tests/simulator-ng.pl @@ -46,7 +46,7 @@ GetOptions( ($IP || $IPV6) or die("at least one of --local-ip or --local-ipv6 must be given"); -$SIG{ALRM} = sub { print "alarm!\n"; }; +local $SIG{ALRM} = sub { print "alarm!\n"; }; setrlimit(RLIMIT_NOFILE, 8000, 8000); $PROTOS and $PROTOS = [split(/\s*[,;:]+\s*/, $PROTOS)]; diff --git a/tests/simulator-udp.pl b/tests/simulator-udp.pl index 035cbd1f6..5ae170a8a 100755 --- a/tests/simulator-udp.pl +++ b/tests/simulator-udp.pl @@ -23,7 +23,7 @@ GetOptions( ($IP || $IPV6) or die("at least one of --local-ip or --local-ipv6 must be given"); -$SIG{ALRM} = sub { print "alarm!\n"; }; +local $SIG{ALRM} = sub { print "alarm!\n"; }; setrlimit(RLIMIT_NOFILE, 8000, 8000); my @chrs = ('a' .. 'z', 'A' .. 'Z', '0' .. '9'); From b4d0ff7f394f94981477191f944fab3671d76e9a Mon Sep 17 00:00:00 2001 From: Guillem Jover Date: Wed, 8 Nov 2017 17:22:57 +0100 Subject: [PATCH 08/65] TT#24097 Use upper-case HERE-doc markers Change-Id: Ic161ae00c573c6febb4c8366ed1ee3773c2cfc0e --- tests/simulator-ng.pl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/simulator-ng.pl b/tests/simulator-ng.pl index 0c17aa910..7288a66f6 100755 --- a/tests/simulator-ng.pl +++ b/tests/simulator-ng.pl @@ -606,13 +606,13 @@ sub offer_answer { my $tcx = $$A{trans_contexts}; my $tcx_o = $$B{trans_contexts}; - my $sdp = <<"!"; + my $sdp = <<"SDP"; v=0 o=blah 123 123 IN $$pr{family_str} $$ips_t[0] s=session c=IN $$pr{family_str} $$ips_t[0] t=0 0 -! +SDP my $ul = $$A{num_streams}; $op eq 'answer' && $$A{streams_seen} < $$A{num_streams} and $ul = $$A{streams_seen}; @@ -631,11 +631,11 @@ t=0 0 $$A{bundle} && $$A{want_rtcpmux} && $op eq 'offer' and $cp = $p; - $sdp .= <<"!"; + $sdp .= <<"SDP"; m=audio $p $$tr{name} 0 8 111 a=rtpmap:8 PCMA/8000 a=rtpmap:111 opus/48000/2 -! +SDP if ($$A{want_rtcpmux} && $op eq 'offer') { $sdp .= "a=rtcp-mux\n"; $sdp .= "a=rtcp:$cp\n"; From 0012037a32db3cc11826a920de5accd460ebd956 Mon Sep 17 00:00:00 2001 From: Guillem Jover Date: Wed, 8 Nov 2017 17:24:37 +0100 Subject: [PATCH 09/65] TT#24097 Allow perl builtin homonyms for method names These are methods and do not really conflict with the perl builtins with the same name outside of this package. Change-Id: If7405ebc6a9e862433e576743ae6c32d7d6ec51e --- perl/NGCP/Rtpclient/DTLS.pm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/perl/NGCP/Rtpclient/DTLS.pm b/perl/NGCP/Rtpclient/DTLS.pm index a438e7ff8..9dcb8d222 100644 --- a/perl/NGCP/Rtpclient/DTLS.pm +++ b/perl/NGCP/Rtpclient/DTLS.pm @@ -67,7 +67,7 @@ sub set_cert { } # XXX unify these two -sub connect { +sub connect { ## no critic: Subroutines::ProhibitBuiltinHomonyms my ($self) = @_; $self->{_connected} and return; @@ -95,7 +95,7 @@ sub connect { $self->{_mux}->add($near); $self->{_mux}->add($openssl_out); } -sub accept { +sub accept { ## no critic: Subroutines::ProhibitBuiltinHomonyms my ($self) = @_; $self->{_connected} and return; @@ -303,13 +303,13 @@ sub encode { my ($self, @rest) = @_; return $self->[0]->encode(@rest); } -sub connect { +sub connect { ## no critic: Subroutines::ProhibitBuiltinHomonyms my ($self, @rest) = @_; for my $cl (@$self) { $cl->accept(@rest); } } -sub accept { +sub accept { ## no critic: Subroutines::ProhibitBuiltinHomonyms my ($self, @rest) = @_; for my $cl (@$self) { $cl->accept(@rest); From acf84a7eb4c3aeff106db2ba9c1478dce3f0ac53 Mon Sep 17 00:00:00 2001 From: Guillem Jover Date: Wed, 8 Nov 2017 17:28:01 +0100 Subject: [PATCH 10/65] TT#24097 Use semicolon instead of colons for end of statement Change-Id: Iebad9ae973f5e6ddd9712635c21d6137536c0d92 --- tests/simulator-ng.pl | 2 +- utils/kernel-intercept-dump.pl | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/simulator-ng.pl b/tests/simulator-ng.pl index 7288a66f6..11adef966 100755 --- a/tests/simulator-ng.pl +++ b/tests/simulator-ng.pl @@ -676,7 +676,7 @@ SDP rand() > .5 and $$dict{'to-tag'} = $$B{tag}; } elsif ($op eq 'answer') { - $dict->{'from-tag'} = $$B{tag}, + $dict->{'from-tag'} = $$B{tag}; $dict->{'to-tag'} = $$A{tag}; } if (!$LAZY diff --git a/utils/kernel-intercept-dump.pl b/utils/kernel-intercept-dump.pl index 5a951a93d..c5142fd06 100755 --- a/utils/kernel-intercept-dump.pl +++ b/utils/kernel-intercept-dump.pl @@ -187,12 +187,12 @@ sub setup { if ($COMBINE == 0) { $callbacks{stream_setup} = \&stream_pcap; $callbacks{stream_close} = \&stream_pcap_close; - $callbacks{packet} = \&stream_packet, + $callbacks{packet} = \&stream_packet; } elsif ($COMBINE == 1) { $callbacks{call_setup} = \&call_pcap; $callbacks{call_close} = \&call_pcap_close; - $callbacks{packet} = \&call_packet, + $callbacks{packet} = \&call_packet; } } sub cb { From cff9d296fd1e8bb7674f74bb5a1cdbfde39428f7 Mon Sep 17 00:00:00 2001 From: Guillem Jover Date: Wed, 8 Nov 2017 17:28:49 +0100 Subject: [PATCH 11/65] TT#24097 Reorder hash assignment to make perlcritic life easier The code is correct, but perlcritic seems to have problems parsing it and confuses it with a statement separated with a comma. Change-Id: I76cd82699cffa2b1a9d938c53172f02d09f47583 --- perl/NGCP/Rtpengine.pm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/perl/NGCP/Rtpengine.pm b/perl/NGCP/Rtpengine.pm index 3c7f816c4..804c4607e 100644 --- a/perl/NGCP/Rtpengine.pm +++ b/perl/NGCP/Rtpengine.pm @@ -48,11 +48,11 @@ sub req { sub offer { my ($self, $packet) = @_; - return $self->req( { %$packet, command => 'offer' } ); + return $self->req( { command => 'offer', %$packet } ); } sub answer { my ($self, $packet) = @_; - return $self->req( { %$packet, command => 'answer' } ); + return $self->req( { command => 'answer', %$packet } ); } 1; From 0bdc1163878a5671cf6ad94933bace7d90172bf6 Mon Sep 17 00:00:00 2001 From: Guillem Jover Date: Wed, 8 Nov 2017 17:31:11 +0100 Subject: [PATCH 12/65] TT#24097 Rework perl code flow - Avoid comma-separated statements. - Avoid mixed boolean operators, and use proper code flow keywords. Change-Id: Iec4c85a3d39fe94ba7b9f293dc158892ae7d9577 --- perl/NGCP/Rtpclient/ICE.pm | 13 +++++++------ tests/3-way-connect-simulator | 5 ++++- tests/reinvite-simulator | 5 ++++- tests/simulator-ng.pl | 34 +++++++++++++++++++++------------- tests/simulator-udp.pl | 9 ++++++--- tests/stun-client | 10 ++++++++-- tests/stun-server | 25 ++++++++++++++++++++----- utils/rtpengine-ng-client | 4 ++-- 8 files changed, 72 insertions(+), 33 deletions(-) diff --git a/perl/NGCP/Rtpclient/ICE.pm b/perl/NGCP/Rtpclient/ICE.pm index 775873324..b8e85ba0d 100644 --- a/perl/NGCP/Rtpclient/ICE.pm +++ b/perl/NGCP/Rtpclient/ICE.pm @@ -596,17 +596,17 @@ sub stun_handler_binding_success { sub check_to_nominate { my ($self) = @_; - $self->{controlling} or return; - $self->{start_nominating} && time() < $self->{start_nominating} and return; - $self->{nominate} and return; - @{$self->{triggered_checks}} and return; + return unless $self->{controlling}; + return if $self->{start_nominating} && time() < $self->{start_nominating}; + return if $self->{nominate}; + return if @{$self->{triggered_checks}}; my @succeeded; for my $pair (values(%{$self->{candidate_pairs}})) { my @comps = @{$pair->{components}}; my @succeeded_comps = grep {$_->{state} eq 'succeeded'} @comps; - @succeeded_comps < $self->{components} and next; + next if @succeeded_comps < $self->{components}; $self->debug("got fully succeeded pair $pair->{foundation}\n"); push(@succeeded, $pair); } @@ -753,7 +753,8 @@ sub timer { # run checks - defined($self->{other_ufrag}) && defined($self->{other_pwd}) or return; # not enough info + # not enough info + return if !defined($self->{other_ufrag}) || !defined($self->{other_pwd}); if (my $pair = shift(@{$self->{triggered_checks}})) { $pair->debug("running triggered check\n"); diff --git a/tests/3-way-connect-simulator b/tests/3-way-connect-simulator index f48796372..948825223 100755 --- a/tests/3-way-connect-simulator +++ b/tests/3-way-connect-simulator @@ -62,7 +62,10 @@ sub send_rcv { recv($recvfd, $inc, length($pkt), 0); alarm(0); } - $inc eq $pkt or print("NOT received packed ok\n"), return; + if ($inc ne $pkt) { + print("NOT received packed ok\n"); + return; + } print("received packet ok\n"); } diff --git a/tests/reinvite-simulator b/tests/reinvite-simulator index ac31a0578..f10dbfabe 100755 --- a/tests/reinvite-simulator +++ b/tests/reinvite-simulator @@ -65,7 +65,10 @@ sub send_rcv { $addr = recv($recvfd, $inc, length($pkt), 0); alarm(0); } - $inc eq $pkt or print("did NOT receive packet\n"), return; + if ($inc ne $pkt) { + print("did NOT receive packet\n"); + return; + } my ($port, $ip) = sockaddr_in($addr); $laddr = getsockname($recvfd); ($lport, $lip) = sockaddr_in($laddr); diff --git a/tests/simulator-ng.pl b/tests/simulator-ng.pl index 11adef966..9c2aa4188 100755 --- a/tests/simulator-ng.pl +++ b/tests/simulator-ng.pl @@ -50,7 +50,7 @@ local $SIG{ALRM} = sub { print "alarm!\n"; }; setrlimit(RLIMIT_NOFILE, 8000, 8000); $PROTOS and $PROTOS = [split(/\s*[,;:]+\s*/, $PROTOS)]; -$PROTOS && @$PROTOS == 1 and $$PROTOS[1] = $$PROTOS[0]; +$$PROTOS[1] = $$PROTOS[0] if $PROTOS && @$PROTOS == 1; $DEST and $DEST = [$DEST =~ /^(?:([a-z.-]+)(?::(\d+))?|([\d.]+)(?::(\d+))?|([\da-f:]+)|\[([\da-f:]+)\]:(\d+))$/si]; my $dest_host = $$DEST[0] || $$DEST[2] || $$DEST[4] || $$DEST[5] || 'localhost'; my $dest_port = $$DEST[1] || $$DEST[3] || $$DEST[6] || 2223; @@ -86,8 +86,14 @@ sub msg { my @dests = getaddrinfo($dest_host, $dest_port, AF_UNSPEC, SOCK_DGRAM); while (@dests >= 5) { my ($fam, $type, $prot, $addr, $canon, @dests) = @dests; - socket($fd, $fam, $type, $prot) or undef($fd), next; - connect($fd, $addr) or undef($fd), next; + if (!socket($fd, $fam, $type, $prot)) { + undef($fd); + next; + } + if (!connect($fd, $addr)) { + undef($fd); + next; + } last; } $fd or die($!); @@ -106,7 +112,7 @@ sub send_receive { alarm(1); recv($receive_fd, $x, 0xffff, 0) or $err = "$!"; alarm(0); - $err && $err !~ /interrupt/i and die $err; + die $err if $err && $err !~ /interrupt/i; return $x; } @@ -403,7 +409,7 @@ sub do_rtp { $KEEPGOING or undef($c); } $NOENC and $repl = $expect; - !$repl && $KEEPGOING and next; + next if !$repl && $KEEPGOING; $repl eq $expect or die hexdump($repl, $expect) . " $$trans{name} > $$trans_o{name}, $$c{callid}, RTP port $$outputs[$j][0]"; $rtcp or next; @@ -421,7 +427,7 @@ sub do_rtp { $dst = $$pr{sockaddr}($dstport, $addr); $repl = send_receive($sendfd, $expfd, $payload, $dst); $NOENC and $repl = $expect; - !$repl && $KEEPGOING and next; + next if !$repl && $KEEPGOING; $repl eq $expect or die hexdump($repl, $expect) . " $$trans{name} > $$trans_o{name}, $$c{callid}, RTCP"; } } @@ -614,12 +620,12 @@ c=IN $$pr{family_str} $$ips_t[0] t=0 0 SDP my $ul = $$A{num_streams}; - $op eq 'answer' && $$A{streams_seen} < $$A{num_streams} - and $ul = $$A{streams_seen}; + $ul = $$A{streams_seen} if $op eq 'answer' && $$A{streams_seen} < $$A{num_streams}; - $$A{want_bundle} && $op eq 'offer' and - $$A{bundle} = 1, + if ($$A{want_bundle} && $op eq 'offer') { + $$A{bundle} = 1; $sdp .= "a=group:BUNDLE " . join(' ', (0 .. $ul)) . "\n"; + } for my $i (0 .. $ul) { my $bi = $i; @@ -628,8 +634,7 @@ SDP my $p = $$ports_t[$bi]; my $cp = $p + 1; - $$A{bundle} && $$A{want_rtcpmux} && $op eq 'offer' - and $cp = $p; + $cp = $p if $$A{bundle} && $$A{want_rtcpmux} && $op eq 'offer'; $sdp .= <<"SDP"; m=audio $p $$tr{name} 0 8 111 @@ -749,7 +754,10 @@ sub answer { } for my $iter (1 .. $NUM) { - ($iter % 10 == 0) and print("$iter calls established\n"), do_rtp(); + if ($iter % 10 == 0) { + print("$iter calls established\n"); + do_rtp(); + } my $c = {}; offer($c, 0, 1); diff --git a/tests/simulator-udp.pl b/tests/simulator-udp.pl index 5ae170a8a..bc201c4a7 100755 --- a/tests/simulator-udp.pl +++ b/tests/simulator-udp.pl @@ -75,7 +75,7 @@ sub do_rtp { alarm(1); recv($$fds[$b], $x, 0xffff, 0) or $err = "$!"; alarm(0); - $err && $err !~ /interrupt/i and die $err; + die $err if $err && $err !~ /interrupt/i; if (($x || '') ne $payload) { warn("no rtp reply received, ports $$outputs[$b][0] and $$outputs[$a][0]"); $KEEPGOING or undef($c); @@ -162,7 +162,10 @@ sub update_lookup { } for my $iter (1 .. $NUM) { - ($iter % 10 == 0) and print("$iter\n"), do_rtp(); + if ($iter % 10 == 0) { + print("$iter\n"); + do_rtp(); + } my $c = []; update_lookup($c, 0); @@ -200,7 +203,7 @@ if (!$NODEL) { for my $c (@calls) { $c or next; my ($tags, $callid) = @$c[3,5]; - $BRANCHES && rand() < .3 and $callid =~ s/;.*//; + $callid =~ s/;.*// if $BRANCHES && rand() < .3; msg("D $callid $$tags[0] $$tags[1]"); } } diff --git a/tests/stun-client b/tests/stun-client index 72c2dd881..dfce3db6d 100755 --- a/tests/stun-client +++ b/tests/stun-client @@ -13,8 +13,14 @@ my $fd; my @dests = getaddrinfo($ip, $port, AF_UNSPEC, SOCK_DGRAM); while (@dests >= 5) { my ($fam, $type, $prot, $addr, $canon, @dests) = @dests; - socket($fd, $fam, $type, $prot) or undef($fd), next; - connect($fd, $addr) or undef($fd), next; + if (!socket($fd, $fam, $type, $prot)) { + undef($fd); + next; + } + if (!connect($fd, $addr)) { + undef($fd); + next; + } last; } $fd or die($!); diff --git a/tests/stun-server b/tests/stun-server index b4446774b..15440008f 100755 --- a/tests/stun-server +++ b/tests/stun-server @@ -54,14 +54,29 @@ while (1) { } next; } - $cmd == 1 or print("not stun request\n"), next; - length($attrs) == $len or print("length mismatch\n"), next; + if ($cmd != 1) { + print("not stun request\n") + next; + } + if (length($attrs) != $len) { + print("length mismatch\n") + next; + } my ($list, $hash) = unpack_attrs($attrs); - $$list[$#$list]{name} eq 'fingerprint' or print("last attr not fingerprint\n"), next; - $$list[$#$list-1]{name} eq 'message-integrity' or print("last but one attr not MI\n"), next; - $$hash{username} or print("no username\n"), next; + if ($$list[$#$list]{name} ne 'fingerprint') { + print("last attr not fingerprint\n"); + next; + } + if ($$list[$#$list-1]{name} ne 'message-integrity') { + print("last but one attr not MI\n") + next; + } + unless ($$hash{username}) { + print("no username\n") + next; + } $$hash{controlling} and print("is controlling\n"); $$hash{controlled} and print("is controlled\n"); diff --git a/utils/rtpengine-ng-client b/utils/rtpengine-ng-client index 70a8335e2..8d80a91c4 100755 --- a/utils/rtpengine-ng-client +++ b/utils/rtpengine-ng-client @@ -62,8 +62,8 @@ for my $x (split(/,/, 'origin,session connection')) { defined($options{'replace-' . $x}) and push(@{$packet{replace}}, $x); } for my $x (split(/,/, 'rtcp-mux,SDES')) { - defined($options{$x}) && ref($options{$x}) eq 'ARRAY' - and $packet{$x} = $options{$x}; + $packet{$x} = $options{$x} + if defined($options{$x}) && ref($options{$x}) eq 'ARRAY'; } if (defined($options{direction})) { $options{direction} =~ /(.*),(.*)/ or die; From b2636dcb2911dfc192748e4a20122886b14e4207 Mon Sep 17 00:00:00 2001 From: Guillem Jover Date: Wed, 8 Nov 2017 17:33:13 +0100 Subject: [PATCH 13/65] TT#24097 Enable strict and warnings everywhere Change-Id: I7362eaf95a41c67f65d79ea9e4bc1fb94eb32e69 --- tests/kernel-module-test.pl | 12 ++++++++---- utils/rtpengine-ctl | 3 +++ 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/tests/kernel-module-test.pl b/tests/kernel-module-test.pl index ab0ab4ac3..8c38842c7 100755 --- a/tests/kernel-module-test.pl +++ b/tests/kernel-module-test.pl @@ -34,10 +34,14 @@ sub re_address { } sub re_srtp { my ($h) = @_; - no warnings; - return pack('VV a16 a16 a256 Q VV', $ciphers{$$h{cipher}}, $hmacs{$$h{hmac}}, - @$h{qw(master_key master_salt mki last_index auth_tag_len mki_len)}); - use warnings; + my %opts = %{$h}; + + # Explicitly initialize the hash entries. + $opts{$_} //= q{} foreach (qw(master_key master_salt mki)); + $opts{$_} //= 0 foreach (qw(last_index auth_tag_len mki_len)); + + return pack('VV a16 a16 a256 Q VV', $ciphers{$opts{cipher}}, $hmacs{$opts{hmac}}, + @opts{qw(master_key master_salt mki last_index auth_tag_len mki_len)}); } sub rtpengine_message { my ($cmd, %args) = @_; diff --git a/utils/rtpengine-ctl b/utils/rtpengine-ctl index 496d50673..4eccff63f 100755 --- a/utils/rtpengine-ctl +++ b/utils/rtpengine-ctl @@ -1,5 +1,8 @@ #!/usr/bin/perl +use strict; +use warnings; + use IO::Socket::INET; my $num_args = $#ARGV + 1; From 19b4df7fb6d096685b0f674f38afea5fe35950cc Mon Sep 17 00:00:00 2001 From: Guillem Jover Date: Wed, 8 Nov 2017 17:34:58 +0100 Subject: [PATCH 14/65] TT#24097 Do not use unportable test operators Change-Id: Ifea38fdfadf5b1e80bb6a9d9158cec4eeb533531 --- debian/ngcp-rtpengine-daemon.init | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/debian/ngcp-rtpengine-daemon.init b/debian/ngcp-rtpengine-daemon.init index 72e23715e..dc7613e22 100755 --- a/debian/ngcp-rtpengine-daemon.init +++ b/debian/ngcp-rtpengine-daemon.init @@ -71,16 +71,16 @@ fi [ -z "$TOS" ] || OPTIONS="$OPTIONS --tos=$TOS" [ -z "$PORT_MIN" ] || OPTIONS="$OPTIONS --port-min=$PORT_MIN" [ -z "$PORT_MAX" ] || OPTIONS="$OPTIONS --port-max=$PORT_MAX" -[ -z "$REDIS" -o -z "$REDIS_DB" ] || OPTIONS="$OPTIONS --redis=$REDIS/$REDIS_DB" +[ -z "$REDIS" ] || [ -z "$REDIS_DB" ] || OPTIONS="$OPTIONS --redis=$REDIS/$REDIS_DB" [ -z "$REDIS_AUTH_PW" ] || export RTPENGINE_REDIS_AUTH_PW="$REDIS_AUTH_PW" -[ -z "$REDIS_WRITE" -o -z "$REDIS_WRITE_DB" ] || OPTIONS="$OPTIONS --redis-write=$REDIS_WRITE/$REDIS_WRITE_DB" +[ -z "$REDIS_WRITE" ] || [ -z "$REDIS_WRITE_DB" ] || OPTIONS="$OPTIONS --redis-write=$REDIS_WRITE/$REDIS_WRITE_DB" [ -z "$REDIS_WRITE_AUTH_PW" ] || export RTPENGINE_REDIS_WRITE_AUTH_PW="$REDIS_WRITE_AUTH_PW" [ -z "$REDIS_NUM_THREADS" ] || OPTIONS="$OPTIONS --redis-num-threads=$REDIS_NUM_THREADS" [ -z "$REDIS_EXPIRES" ] || OPTIONS="$OPTIONS --redis-expires=$REDIS_EXPIRES" [ -z "$REDIS_MULTIKEY" ] || OPTIONS="$OPTIONS --redis-multikey=$REDIS_MULTIKEY" -[ -z "$NO_REDIS_REQUIRED" -o \( "$NO_REDIS_REQUIRED" != "1" -a "$NO_REDIS_REQUIRED" != "yes" \) ] || OPTIONS="$OPTIONS --no-redis-required" +[ -z "$NO_REDIS_REQUIRED" ] || ( [ "$NO_REDIS_REQUIRED" != "1" ] && [ "$NO_REDIS_REQUIRED" != "yes" ] ) || OPTIONS="$OPTIONS --no-redis-required" [ -z "$B2B_URL" ] || OPTIONS="$OPTIONS --b2b-url=$B2B_URL" -[ -z "$NO_FALLBACK" -o \( "$NO_FALLBACK" != "1" -a "$NO_FALLBACK" != "yes" \) ] || OPTIONS="$OPTIONS --no-fallback" +[ -z "$NO_FALLBACK" ] || ( [ "$NO_FALLBACK" != "1" ] && [ "$NO_FALLBACK" != "yes" ] ) || OPTIONS="$OPTIONS --no-fallback" OPTIONS="$OPTIONS --table=$TABLE" [ -z "$LOG_LEVEL" ] || OPTIONS="$OPTIONS --log-level=$LOG_LEVEL" [ -z "$LOG_FACILITY" ] || OPTIONS="$OPTIONS --log-facility=$LOG_FACILITY" @@ -104,7 +104,7 @@ if [ ! -z "$RECORDING_DIR" ]; then fi [ -z "$RECORDING_METHOD" ] || OPTIONS="$OPTIONS --recording-method=$RECORDING_METHOD" [ -z "$RECORDING_FORMAT" ] || OPTIONS="$OPTIONS --recording-format=$RECORDING_FORMAT" -[ -z "$DTLS_PASSIVE" -o \( "$DTLS_PASSIVE" != "yes" -a "$DTLS_PASSIVE" != "1" \) ] || OPTIONS="$OPTIONS --dtls-passive" +[ -z "$DTLS_PASSIVE" ] || ( [ "$DTLS_PASSIVE" != "yes" ] && [ "$DTLS_PASSIVE" != "1" ] ) || OPTIONS="$OPTIONS --dtls-passive" if test "$FORK" = "no" ; then OPTIONS="$OPTIONS --foreground" From 33518213c0fa92d257443cfd6eeef71b5730e2b6 Mon Sep 17 00:00:00 2001 From: Guillem Jover Date: Wed, 8 Nov 2017 17:36:34 +0100 Subject: [PATCH 15/65] TT#24097 Remove unused shell variables Change-Id: I529a493b2c8d3573d1b848c3fffa951bb8fc60c9 --- debian/ngcp-rtpengine-recording-daemon.init | 7 ------- el/rtpengine.init | 4 ++-- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/debian/ngcp-rtpengine-recording-daemon.init b/debian/ngcp-rtpengine-recording-daemon.init index 32457eb1c..c27177c6d 100755 --- a/debian/ngcp-rtpengine-recording-daemon.init +++ b/debian/ngcp-rtpengine-recording-daemon.init @@ -14,7 +14,6 @@ PATH=/sbin:/bin:/usr/sbin:/usr/bin NAME=ngcp-rtpengine-recording-daemon DESC="RTP/media recording daemon" -TABLE=0 DAEMON=$(which rtpengine-recording) DEFAULTS=/etc/default/${NAME} @@ -76,12 +75,6 @@ fi ### -if [ -x /usr/sbin/ngcp-virt-identify ]; then - if /usr/sbin/ngcp-virt-identify --type container; then - VIRT="yes" - fi -fi - case "$1" in start) set +e diff --git a/el/rtpengine.init b/el/rtpengine.init index 5804b79f8..4e9dc25ef 100644 --- a/el/rtpengine.init +++ b/el/rtpengine.init @@ -187,7 +187,7 @@ start() { else modprobe xt_RTPENGINE fi - temp=`firewall-cmd --state 2>/dev/null` + firewall-cmd --state 2>/dev/null if [[ $? == 0 ]] then # Using firewalld @@ -240,7 +240,7 @@ stop() { . "$cachefile" echo "Unloading module for in-kernel packet forwarding" echo "del $TABLE" > /proc/rtpengine/control - temp=`firewall-cmd --state 2>/dev/null` + firewall-cmd --state 2>/dev/null if [[ $? == 0 ]] then firewall-cmd --direct --remove-rules ipv4 filter rtpengine From 747661ff0df92a07855baa88f46549f339adf9da Mon Sep 17 00:00:00 2001 From: Guillem Jover Date: Wed, 8 Nov 2017 17:38:20 +0100 Subject: [PATCH 16/65] TT#24097 Do not use bash builtin names in sh scripts Even though this is a false-positive, it confuses checkbashisms. So let's rename the variables to something else, even more descriptive, to avoid the check error. Change-Id: Ife79bf76121bb4e3c120525ffe5a0eca871936f6 --- debian/ngcp-rtpengine-daemon.init | 12 ++++++------ debian/ngcp-rtpengine-recording-daemon.init | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/debian/ngcp-rtpengine-daemon.init b/debian/ngcp-rtpengine-daemon.init index dc7613e22..330de4a9c 100755 --- a/debian/ngcp-rtpengine-daemon.init +++ b/debian/ngcp-rtpengine-daemon.init @@ -127,19 +127,19 @@ fi if ! test -z "$SET_USER"; then START_OPTIONS="$START_OPTIONS --chuid $SET_USER" - UID=$(id -u "$SET_USER" 2> /dev/null) - test -z "$UID" || MODPROBE_OPTIONS="$MODPROBE_OPTIONS proc_uid=$UID" + PUID=$(id -u "$SET_USER" 2> /dev/null) + test -z "$PUID" || MODPROBE_OPTIONS="$MODPROBE_OPTIONS proc_uid=$PUID" if test -z "$SET_GROUP"; then - GID=$(id -g "$SET_USER" 2> /dev/null) - test -z "$GID" || MODPROBE_OPTIONS="$MODPROBE_OPTIONS proc_gid=$GID" + PGID=$(id -g "$SET_USER" 2> /dev/null) + test -z "$PGID" || MODPROBE_OPTIONS="$MODPROBE_OPTIONS proc_gid=$PGID" fi test "$DO_DIR_CHOWN" = 1 && chown "$SET_USER": "$PIDDIR" fi if ! test -z "$SET_GROUP"; then START_OPTIONS="$START_OPTIONS --group $SET_GROUP" - GID=$(grep "^$SET_GROUP:" /etc/group | cut -d: -f3 2> /dev/null) - test -z "$GID" || MODPROBE_OPTIONS="$MODPROBE_OPTIONS proc_gid=$GID" + PGID=$(grep "^$SET_GROUP:" /etc/group | cut -d: -f3 2> /dev/null) + test -z "$PGID" || MODPROBE_OPTIONS="$MODPROBE_OPTIONS proc_gid=$PGID" test "$DO_DIR_CHOWN" = 1 && chgrp "$SET_GROUP" "$PIDDIR" fi diff --git a/debian/ngcp-rtpengine-recording-daemon.init b/debian/ngcp-rtpengine-recording-daemon.init index c27177c6d..b584cdde3 100755 --- a/debian/ngcp-rtpengine-recording-daemon.init +++ b/debian/ngcp-rtpengine-recording-daemon.init @@ -57,19 +57,19 @@ fi if ! test -z "$SET_USER"; then START_OPTIONS="$START_OPTIONS --chuid $SET_USER" - UID=$(id -u "$SET_USER" 2> /dev/null) - test -z "$UID" || MODPROBE_OPTIONS="$MODPROBE_OPTIONS proc_uid=$UID" + PUID=$(id -u "$SET_USER" 2> /dev/null) + test -z "$PUID" || MODPROBE_OPTIONS="$MODPROBE_OPTIONS proc_uid=$PUID" if test -z "$SET_GROUP"; then - GID=$(id -g "$SET_USER" 2> /dev/null) - test -z "$GID" || MODPROBE_OPTIONS="$MODPROBE_OPTIONS proc_gid=$GID" + PGID=$(id -g "$SET_USER" 2> /dev/null) + test -z "$PGID" || MODPROBE_OPTIONS="$MODPROBE_OPTIONS proc_gid=$PGID" fi test "$DO_DIR_CHOWN" = 1 && chown "$SET_USER": "$PIDDIR" fi if ! test -z "$SET_GROUP"; then START_OPTIONS="$START_OPTIONS --group $SET_GROUP" - GID=$(grep "^$SET_GROUP:" /etc/group | cut -d: -f3 2> /dev/null) - test -z "$GID" || MODPROBE_OPTIONS="$MODPROBE_OPTIONS proc_gid=$GID" + PGID=$(grep "^$SET_GROUP:" /etc/group | cut -d: -f3 2> /dev/null) + test -z "$PGID" || MODPROBE_OPTIONS="$MODPROBE_OPTIONS proc_gid=$PGID" test "$DO_DIR_CHOWN" = 1 && chgrp "$SET_GROUP" "$PIDDIR" fi From 04f57900fc7698713f10b8d499f60be61474ab13 Mon Sep 17 00:00:00 2001 From: Guillem Jover Date: Wed, 8 Nov 2017 17:42:04 +0100 Subject: [PATCH 17/65] TT#24097 Switch for loop to use the i variable This makes it a more natural code pattern. Change-Id: I200df650625de63ec1a7cacb05c73ee8f0c40080 --- tests/simulator-tcp.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/simulator-tcp.sh b/tests/simulator-tcp.sh index ed29e1d47..fb90f38df 100755 --- a/tests/simulator-tcp.sh +++ b/tests/simulator-tcp.sh @@ -17,7 +17,7 @@ port() { ids="" ports="" -for i in $(seq 1 1000); do +for (( i = 0 ; i < 1000 ; i++ )); do callid=`uuid` test -z "$callid" && exit 1 src=`ip`:`port` From 33bafcfc3c9484b88b7d7f140d0e51f5ae9434cc Mon Sep 17 00:00:00 2001 From: Guillem Jover Date: Wed, 8 Nov 2017 17:43:09 +0100 Subject: [PATCH 18/65] TT#24097 Use $() instead of deprecated `` Change-Id: Ief744bc63928e9eeee72436911e01b7b2a29c260 --- el/rtpengine.init | 2 +- tests/simulator-tcp.sh | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/el/rtpengine.init b/el/rtpengine.init index 4e9dc25ef..43a10d2d6 100644 --- a/el/rtpengine.init +++ b/el/rtpengine.init @@ -39,7 +39,7 @@ MODULE=0 build_opts() { shopt -s nocasematch - RPMS=`rpm -qa | grep rtpengine-kernel` + RPMS=$(rpm -qa | grep rtpengine-kernel) if [[ "$KERNEL" == "yes" && -n "$TABLE" && -n "$RPMS" ]] then MODULE=1 diff --git a/tests/simulator-tcp.sh b/tests/simulator-tcp.sh index fb90f38df..9ab3a02c6 100755 --- a/tests/simulator-tcp.sh +++ b/tests/simulator-tcp.sh @@ -18,16 +18,16 @@ port() { ids="" ports="" for (( i = 0 ; i < 1000 ; i++ )); do - callid=`uuid` + callid=$(uuid) test -z "$callid" && exit 1 - src=`ip`:`port` - dst=`ip`:`port` - gw=`ip` - fromtag=`uuid` - totag=`uuid` + src=$(ip):$(port) + dst=$(ip):$(port) + gw=$(ip) + fromtag=$(uuid) + totag=$(uuid) - src_rel=`echo "request $callid $src:audio $gw voip.inode.at local unknown unknown unknown-agent info=domain:voip.sipwise.local,from:number@voip.inode.at,totag:,to:othernumber@voip.inode.at,fromtag:$fromtag" | pipe_o` - dst_rel=`echo "lookup $callid $dst:audio $gw voip.inode.at local unknown unknown unknown-agent info=domain:voip.sipwise.local,from:number@voip.inode.at,totag:$totag,to:othernumber@voip.inode.at,fromtag:$fromtag" | pipe_o` + src_rel=$(echo "request $callid $src:audio $gw voip.inode.at local unknown unknown unknown-agent info=domain:voip.sipwise.local,from:number@voip.inode.at,totag:,to:othernumber@voip.inode.at,fromtag:$fromtag" | pipe_o) + dst_rel=$(echo "lookup $callid $dst:audio $gw voip.inode.at local unknown unknown unknown-agent info=domain:voip.sipwise.local,from:number@voip.inode.at,totag:$totag,to:othernumber@voip.inode.at,fromtag:$fromtag" | pipe_o) echo "lookup $callid $dst:audio $gw voip.inode.at local unknown unknown unknown-agent info=domain:voip.sipwise.local,from:number@voip.inode.at,totag:$totag,to:othernumber@voip.inode.at,fromtag:$fromtag" | pipe echo version | pipe (echo status | pipe) & From 376df64d80b19d6f125f0d373187ea47e6b613b5 Mon Sep 17 00:00:00 2001 From: Guillem Jover Date: Wed, 8 Nov 2017 17:44:16 +0100 Subject: [PATCH 19/65] =?UTF-8?q?TT#24097=20Use=20=C2=ABgrep=20-E=C2=BB=20?= =?UTF-8?q?instead=20of=20deprecated=20egrep?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Ia4d51ece3aba31777f62c92897d4e7c207e6d07c --- debian/ngcp-rtpengine-recording-daemon.init | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/ngcp-rtpengine-recording-daemon.init b/debian/ngcp-rtpengine-recording-daemon.init index b584cdde3..6dc08318e 100755 --- a/debian/ngcp-rtpengine-recording-daemon.init +++ b/debian/ngcp-rtpengine-recording-daemon.init @@ -96,7 +96,7 @@ case "$1" in log_daemon_msg "Starting $DESC: $NAME" if [ "$MUST_NFS" = yes ]; then - if ! egrep -q '^[^ :]+:[^ :]+ '"$NFS_LOCAL_MOUNT"' nfs.? ' /proc/mounts; then + if ! grep -E -q '^[^ :]+:[^ :]+ '"$NFS_LOCAL_MOUNT"' nfs.? ' /proc/mounts; then log_progress_msg "Mounting NFS share" test -d "$NFS_LOCAL_MOUNT" || mkdir -p "$NFS_LOCAL_MOUNT" mount -t nfs -o "$NFS_OPTIONS" "$NFS_HOST":"$NFS_REMOTE_PATH" "$NFS_LOCAL_MOUNT" From 53b3c36939fbc6e81138fab2814991978dbe8373 Mon Sep 17 00:00:00 2001 From: Guillem Jover Date: Wed, 8 Nov 2017 17:45:44 +0100 Subject: [PATCH 20/65] TT#24097 Fix shell quoting - Add missing quotes. - Switch some problematic usages to use bash arrays. - Override shellcheck errors (these might need fixing in the future). Change-Id: Id451ff9f4c5d5ef9b3826544908d64e9c08c5797 --- debian/ngcp-rtpengine-daemon.init | 2 ++ debian/ngcp-rtpengine-recording-daemon.init | 5 +-- el/rtpengine.init | 36 +++++++++++---------- tests/simulator-tcp.sh | 2 +- utils/build_deps.sh | 8 ++--- utils/patch-kernel | 2 +- 6 files changed, 30 insertions(+), 25 deletions(-) diff --git a/debian/ngcp-rtpengine-daemon.init b/debian/ngcp-rtpengine-daemon.init index 330de4a9c..5bab13150 100755 --- a/debian/ngcp-rtpengine-daemon.init +++ b/debian/ngcp-rtpengine-daemon.init @@ -170,6 +170,7 @@ case "$1" in log_daemon_msg "Starting $DESC: $NAME" if [ "$TABLE" -ge 0 ] && [ "$VIRT" != "yes" ]; then if [ "$MANAGE_IPTABLES" = "yes" ]; then + # shellcheck disable=SC2086 modprobe xt_RTPENGINE $MODPROBE_OPTIONS iptables -N rtpengine 2> /dev/null @@ -188,6 +189,7 @@ case "$1" in fi fi set -e + # shellcheck disable=SC2086 start-stop-daemon --start --quiet --pidfile "$PIDFILE" \ --exec "$DAEMON" $START_OPTIONS -- $OPTIONS || log_progress_msg " already running" log_end_msg $? diff --git a/debian/ngcp-rtpengine-recording-daemon.init b/debian/ngcp-rtpengine-recording-daemon.init index 6dc08318e..92e948ffc 100755 --- a/debian/ngcp-rtpengine-recording-daemon.init +++ b/debian/ngcp-rtpengine-recording-daemon.init @@ -96,13 +96,14 @@ case "$1" in log_daemon_msg "Starting $DESC: $NAME" if [ "$MUST_NFS" = yes ]; then - if ! grep -E -q '^[^ :]+:[^ :]+ '"$NFS_LOCAL_MOUNT"' nfs.? ' /proc/mounts; then + if ! grep -E -q "^[^ :]+:[^ :]+ $NFS_LOCAL_MOUNT nfs.? " /proc/mounts; then log_progress_msg "Mounting NFS share" test -d "$NFS_LOCAL_MOUNT" || mkdir -p "$NFS_LOCAL_MOUNT" - mount -t nfs -o "$NFS_OPTIONS" "$NFS_HOST":"$NFS_REMOTE_PATH" "$NFS_LOCAL_MOUNT" + mount -t nfs -o "$NFS_OPTIONS" "$NFS_HOST:$NFS_REMOTE_PATH" "$NFS_LOCAL_MOUNT" fi fi + # shellcheck disable=SC2086 start-stop-daemon --start --quiet --pidfile "$PIDFILE" \ --exec "$DAEMON" $START_OPTIONS -- $OPTIONS || log_progress_msg " already running" log_end_msg $? diff --git a/el/rtpengine.init b/el/rtpengine.init index 43a10d2d6..f9c95867b 100644 --- a/el/rtpengine.init +++ b/el/rtpengine.init @@ -179,11 +179,11 @@ start() { then if [[ -n "$RE_GROUP" ]] then - proc_gid=$(grep ^$RE_GROUP: /etc/group | cut -f3 -d:) + proc_gid="$(grep "^$RE_GROUP:" /etc/group | cut -f3 -d:)" else - proc_gid=$(id $RE_USER -g) + proc_gid="$(id "$RE_USER" -g)" fi - modprobe xt_RTPENGINE proc_uid=$(id $RE_USER -u) proc_gid=$proc_gid + modprobe xt_RTPENGINE proc_uid="$(id "$RE_USER" -u)" proc_gid="$proc_gid" else modprobe xt_RTPENGINE fi @@ -202,15 +202,15 @@ start() { firewall-cmd --direct --add-chain ipv4 filter rtpengine firewall-cmd --direct --add-rule ipv4 filter INPUT_prefilter 0 -j rtpengine - firewall-cmd --direct --add-rule ipv4 filter rtpengine 0 -p udp -j RTPENGINE --id $TABLE - firewall-cmd --direct --add-rule ipv6 filter rtpengine 0 -p udp -j RTPENGINE --id $TABLE + firewall-cmd --direct --add-rule ipv4 filter rtpengine 0 -p udp -j RTPENGINE --id "$TABLE" + firewall-cmd --direct --add-rule ipv6 filter rtpengine 0 -p udp -j RTPENGINE --id "$TABLE" firewall-cmd --reload else iptables -N rtpengine # We insert the rtpengine rule at the top of the input chain iptables -t filter -I INPUT -j rtpengine - iptables -I rtpengine -p udp -j RTPENGINE --id $TABLE - ip6tables -I rtpengine -p udp -j RTPENGINE --id $TABLE + iptables -I rtpengine -p udp -j RTPENGINE --id "$TABLE" + ip6tables -I rtpengine -p udp -j RTPENGINE --id "$TABLE" fi cat < "$cachefile" @@ -220,19 +220,21 @@ EOF echo -n $"Starting $prog: " if [[ -n "$RE_USER" ]] then - daemon --user $RE_USER --pidfile=${pidfile} $rtpengine $OPTS + # shellcheck disable=SC2086 + daemon --user "$RE_USER" --pidfile="${pidfile}" "$rtpengine" $OPTS else - daemon --pidfile=${pidfile} $rtpengine $OPTS + # shellcheck disable=SC2086 + daemon --pidfile="${pidfile}" "$rtpengine" $OPTS fi RETVAL=$? echo - [ $RETVAL = 0 ] && touch ${lockfile} + [ $RETVAL = 0 ] && touch "${lockfile}" return $RETVAL } stop() { echo -n $"Stopping $prog: " - killproc -p ${pidfile} $rtpengine + killproc -p "${pidfile}" "$rtpengine" RETVAL=$? echo if [ -f "$cachefile" ] @@ -249,16 +251,16 @@ stop() { firewall-cmd --direct --remove-chain ipv4 filter rtpengine firewall-cmd --reload else - iptables -D rtpengine -p udp -j RTPENGINE --id $CUR_TABLE - ip6tables -D rtpengine -p udp -j RTPENGINE --id $CUR_TABLE + iptables -D rtpengine -p udp -j RTPENGINE --id "$CUR_TABLE" + ip6tables -D rtpengine -p udp -j RTPENGINE --id "$CUR_TABLE" iptables -t filter -D INPUT -j rtpengine iptables -X rtpengine fi rmmod xt_RTPENGINE - rm -f $cachefile + rm -f "$cachefile" fi - [ $RETVAL = 0 ] && rm -f ${lockfile} ${pidfile} + [ $RETVAL = 0 ] && rm -f "${lockfile}" "${pidfile}" } # See how we were called. @@ -270,7 +272,7 @@ case "$1" in stop ;; status) - status -p ${pidfile} $rtpengine + status -p "${pidfile}" "$rtpengine" RETVAL=$? ;; restart) @@ -278,7 +280,7 @@ case "$1" in start ;; condrestart|try-restart) - if status -p ${pidfile} $rtpengine >&/dev/null; then + if status -p "${pidfile}" "$rtpengine" >&/dev/null; then stop start fi diff --git a/tests/simulator-tcp.sh b/tests/simulator-tcp.sh index 9ab3a02c6..45a0a78ea 100755 --- a/tests/simulator-tcp.sh +++ b/tests/simulator-tcp.sh @@ -36,7 +36,7 @@ for (( i = 0 ; i < 1000 ; i++ )); do dst_path=${dst_rel/ //} ports="$ports $src_path $dst_path" for port in $ports; do - echo foobar > /dev/udp/$port + echo foobar > "/dev/udp/$port" done ids="$ids $callid" diff --git a/utils/build_deps.sh b/utils/build_deps.sh index 5b299d2e2..ec4016bea 100755 --- a/utils/build_deps.sh +++ b/utils/build_deps.sh @@ -11,12 +11,12 @@ if ! [ -f "${CONTROL_FILE}" ]; then exit 1 fi -BUILD_DEPS=$(/usr/bin/gdebi --quiet --non-interactive \ +BUILD_DEPS=($(/usr/bin/gdebi --quiet --non-interactive \ --option=APT::Install-Recommends=false \ - --apt-line ${CONTROL_FILE}) -if [ -z "${BUILD_DEPS}" ]; then + --apt-line "${CONTROL_FILE}")) +if [ ${#BUILD_DEPS[@]} -eq 0 ]; then echo "Error: no build deps packages resolved" exit 2 fi -apt-get install -y $BUILD_DEPS +apt-get install -y "${BUILD_DEPS[@]}" diff --git a/utils/patch-kernel b/utils/patch-kernel index b9acad660..429a93b6f 100755 --- a/utils/patch-kernel +++ b/utils/patch-kernel @@ -34,7 +34,7 @@ if ! grep -q CONFIG_NETFILTER_XT_TARGET_RTPENGINE "$KERN"/net/netfilter/Makefile ( echo echo "EXTRA_CFLAGS += -DRTPENGINE_VERSION=\"\\\"$4\\\"\"" - echo 'obj-$(CONFIG_NETFILTER_XT_TARGET_RTPENGINE) += xt_RTPENGINE.o' + echo "obj-\$(CONFIG_NETFILTER_XT_TARGET_RTPENGINE) += xt_RTPENGINE.o" ) >> "$KERN"/net/netfilter/Makefile fi From 465f3fe72149f54d09da05a1ecf3dc62ea9e8f34 Mon Sep 17 00:00:00 2001 From: Guillem Jover Date: Wed, 8 Nov 2017 17:46:43 +0100 Subject: [PATCH 21/65] TT#24097 Remove $ from variables inside arithmetic evaluation Change-Id: I51742f8b08f4402016e6c640d289342fcb51b926 --- tests/simulator-tcp.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/simulator-tcp.sh b/tests/simulator-tcp.sh index 45a0a78ea..3f1d7f05e 100755 --- a/tests/simulator-tcp.sh +++ b/tests/simulator-tcp.sh @@ -9,10 +9,10 @@ pipe() { pipe_o > /dev/null } ip() { - echo $(($RANDOM % 254 + 1)).$(($RANDOM % 254 + 1)).$(($RANDOM % 254 + 1)).$(($RANDOM % 254 + 1)) + echo $((RANDOM % 254 + 1)).$((RANDOM % 254 + 1)).$((RANDOM % 254 + 1)).$((RANDOM % 254 + 1)) } port() { - echo $(($RANDOM % 64000 + 1024)) + echo $((RANDOM % 64000 + 1024)) } ids="" From 031921c32270c1540ddd18a5e828fc566c497c24 Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Thu, 9 Nov 2017 14:16:07 -0500 Subject: [PATCH 22/65] purge old entries from SSRC hash table if it gets too full fixes #417 Change-Id: I4da50858d3c4959687b341b7c0856a868c87ffa7 --- daemon/ssrc.c | 12 +++++++----- daemon/ssrc.h | 1 + 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/daemon/ssrc.c b/daemon/ssrc.c index 74c734008..db960a62b 100644 --- a/daemon/ssrc.c +++ b/daemon/ssrc.c @@ -21,6 +21,7 @@ static struct ssrc_entry *create_ssrc_entry(u_int32_t ssrc) { } static void add_ssrc_entry(struct ssrc_entry *ent, struct ssrc_hash *ht) { g_hash_table_replace(ht->ht, &ent->ssrc, ent); + g_queue_push_tail(&ht->q, ent); } static void free_sender_report(struct ssrc_sender_report_item *i) { g_slice_free1(sizeof(*i), i); @@ -78,11 +79,11 @@ restart: rwlock_lock_w(&ht->lock); - if (G_UNLIKELY(g_hash_table_size(ht->ht) > 20)) { // arbitrary limit - rwlock_unlock_w(&ht->lock); - free_ssrc_entry(ent); - ilog(LOG_INFO, "SSRC hash table exceeded size limit (trying to add %u)", ssrc); - return NULL; + while (G_UNLIKELY(ht->q.length > 20)) { // arbitrary limit + struct ssrc_entry *old_ent = g_queue_pop_head(&ht->q); + ilog(LOG_DEBUG, "SSRC hash table exceeded size limit (trying to add %u) - deleting SSRC %u", + ssrc, old_ent->ssrc); + g_hash_table_remove(ht->ht, &old_ent->ssrc); } if (g_hash_table_lookup(ht->ht, &ssrc)) { @@ -101,6 +102,7 @@ void free_ssrc_hash(struct ssrc_hash **ht) { if (!*ht) return; g_hash_table_destroy((*ht)->ht); + g_queue_clear(&(*ht)->q); g_slice_free1(sizeof(**ht), *ht); *ht = NULL; } diff --git a/daemon/ssrc.h b/daemon/ssrc.h index 93755edf3..0d261542f 100644 --- a/daemon/ssrc.h +++ b/daemon/ssrc.h @@ -21,6 +21,7 @@ enum ssrc_dir; struct ssrc_hash { GHashTable *ht; + GQueue q; rwlock_t lock; }; struct ssrc_ctx { From 677c9a52d2bffb83f5ba1fc1d1f5b8d530096bd6 Mon Sep 17 00:00:00 2001 From: Guillem Jover Date: Fri, 10 Nov 2017 20:10:53 +0100 Subject: [PATCH 23/65] TT#22072 Update packaging - Bump Standards-Version to 3.9.8. - Bump debhelper compatibility version 10. - Switch from Priority extra to optional. - Canonicalize Homepage URL. - Add a debian/.gitignore file. - Replace ngcp-rtpengine-dbg with automatic dbgsym packages. Change-Id: I969b608f2c737f62eef0082cad82bec6293af3f1 --- debian/.gitignore | 12 ++++++++++++ debian/compat | 2 +- debian/control | 29 ++++------------------------- debian/rules | 2 +- 4 files changed, 18 insertions(+), 27 deletions(-) create mode 100644 debian/.gitignore diff --git a/debian/.gitignore b/debian/.gitignore new file mode 100644 index 000000000..adcd46ff5 --- /dev/null +++ b/debian/.gitignore @@ -0,0 +1,12 @@ +*.log +*.substvars +*.debhelper +/.debhelper/ +/files +/debhelper-build-stamp +/ngcp-rtpengine-daemon +/ngcp-rtpengine-recording-daemon +/ngcp-rtpengine-iptables +/ngcp-rtpengine-kernel-source +/ngcp-rtpengine-kernel-dkms +/ngcp-rtpengine-utils diff --git a/debian/compat b/debian/compat index ec635144f..f599e28b8 100644 --- a/debian/compat +++ b/debian/compat @@ -1 +1 @@ -9 +10 diff --git a/debian/control b/debian/control index feeadfd7f..f4fcaf556 100644 --- a/debian/control +++ b/debian/control @@ -1,9 +1,11 @@ Source: ngcp-rtpengine Section: net -Priority: extra +Priority: optional Maintainer: Sipwise Development Team +Homepage: https://www.sipwise.com/ +Standards-Version: 3.9.8 Build-Depends: - debhelper (>= 9~), + debhelper (>= 10~), default-libmysqlclient-dev | libmysqlclient-dev, iptables-dev (>= 1.4), libavcodec-dev (>= 6:10), @@ -23,8 +25,6 @@ Build-Depends: libxmlrpc-c3-dev (>= 1.16.07) | libxmlrpc-core-c3-dev (>= 1.16.07), markdown, zlib1g-dev, -Standards-Version: 3.9.7 -Homepage: http://sipwise.com/ Package: ngcp-rtpengine-daemon Architecture: any @@ -122,27 +122,6 @@ Description: IPtables kernel module for the NGCP media proxy - DKMS. performance packet forwarding. This package contains the source to be built with dkms. -Package: ngcp-rtpengine-dbg -Architecture: any -Section: debug -Depends: - ngcp-rtpengine-daemon (= ${binary:Version}), - ngcp-rtpengine-iptables (= ${binary:Version}), - ${misc:Depends}, -Conflicts: - ngcp-mediaproxy-ng-dbg, -Replaces: - ngcp-mediaproxy-ng-dbg, -Description: debugging symbols for ngcp-rtpengine - The ngcp-rtpengine daemon handles the first stages of proxying media streams and talks to - the kernel part of the proxy for eventual high-performance packet forwarding. - . - ngcp-rtpengine-iptables provides the IPtables extension needed - to configure the mediaproxy rule. - . - This package contains the debugging symbols for ngcp-rtpengine-daemon - and ngcp-rtpengine-iptables - Package: ngcp-rtpengine-utils Architecture: all Depends: diff --git a/debian/rules b/debian/rules index cbcf64520..169deb1ce 100755 --- a/debian/rules +++ b/debian/rules @@ -68,6 +68,6 @@ override_dh_install: .PHONY: override_dh_strip override_dh_strip: - dh_strip --dbg-package=ngcp-rtpengine-dbg + dh_strip --dbgsym-migration='ngcp-rtpengine-dbg (<= 6.0.0.0+0~mr6.0.0.0)' override_dh_auto_test: From cc09f4d3def1058da57900aba03f55c239547a83 Mon Sep 17 00:00:00 2001 From: Dmitry Poroh Date: Sun, 3 Dec 2017 19:19:33 +0300 Subject: [PATCH 24/65] Crash stream_packet in case of out_srtp is NULL is fixed --- daemon/media_socket.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/daemon/media_socket.c b/daemon/media_socket.c index f4434dd1f..c6228f238 100644 --- a/daemon/media_socket.c +++ b/daemon/media_socket.c @@ -1274,7 +1274,8 @@ loop_ok: if (G_LIKELY(media->protocol && media->protocol->rtp)) { if (G_LIKELY(!rtcp && !rtp_payload(&rtp_h, NULL, s))) { - __stream_ssrc(in_srtp, out_srtp, rtp_h->ssrc, &ssrc_in, &ssrc_out, call->ssrc_hash); + if (G_LIKELY(out_srtp != NULL)) + __stream_ssrc(in_srtp, out_srtp, rtp_h->ssrc, &ssrc_in, &ssrc_out, call->ssrc_hash); // check the payload type i = (rtp_h->m_pt & 0x7f); @@ -1296,13 +1297,14 @@ loop_ok: } } else if (rtcp && !rtcp_payload(&rtcp_h, NULL, s)) { - __stream_ssrc(in_srtp, out_srtp, rtcp_h->ssrc, &ssrc_in, &ssrc_out, call->ssrc_hash); + if (G_LIKELY(out_srtp != NULL)) + __stream_ssrc(in_srtp, out_srtp, rtcp_h->ssrc, &ssrc_in, &ssrc_out, call->ssrc_hash); } } /* do we have somewhere to forward it to? */ - if (G_UNLIKELY(!sink || !sink->selected_sfd || !out_srtp->selected_sfd || !in_srtp->selected_sfd)) { + if (G_UNLIKELY(!sink || !sink->selected_sfd || !out_srtp || !out_srtp->selected_sfd || !in_srtp->selected_sfd)) { ilog(LOG_WARNING, "RTP packet from %s discarded", endpoint_print_buf(fsin)); atomic64_inc(&stream->stats.errors); atomic64_inc(&cm->statsps.errors); From 6721f3c9732a23e0a8fb9a17852d70c071045960 Mon Sep 17 00:00:00 2001 From: Guillem Jover Date: Tue, 5 Dec 2017 16:43:04 +0100 Subject: [PATCH 25/65] TT#22072 Update debian/.gitignore Change-Id: Ic284326be495c55c0f3b597d72ffc591b79d72ad --- debian/.gitignore | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/debian/.gitignore b/debian/.gitignore index adcd46ff5..6fad2ea3c 100644 --- a/debian/.gitignore +++ b/debian/.gitignore @@ -1,12 +1,13 @@ +*.debhelper *.log *.substvars -*.debhelper /.debhelper/ -/files /debhelper-build-stamp -/ngcp-rtpengine-daemon -/ngcp-rtpengine-recording-daemon -/ngcp-rtpengine-iptables -/ngcp-rtpengine-kernel-source -/ngcp-rtpengine-kernel-dkms -/ngcp-rtpengine-utils +/files +/ngcp-rtpengine-daemon/ +/ngcp-rtpengine-iptables/ +/ngcp-rtpengine-kernel-dkms/ +/ngcp-rtpengine-kernel-source/ +/ngcp-rtpengine-recording-daemon/ +/ngcp-rtpengine-utils/ +/ngcp-rtpengine/ From b637c8f4b708ce0727262a704ff12bad31b6fc6e Mon Sep 17 00:00:00 2001 From: Sipwise Jenkins Builder Date: Wed, 6 Dec 2017 00:14:35 +0100 Subject: [PATCH 26/65] Release new version 6.1.0.0+0~mr6.1.0.0 --- debian/changelog | 52 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/debian/changelog b/debian/changelog index 91ee0f295..c1c9e470b 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,55 @@ +ngcp-rtpengine (6.1.0.0+0~mr6.1.0.0) unstable; urgency=medium + + [ Richard Fuchs ] + * [5bcbf27] fix metadata DB insert without trailing pipe character + * [13d51f0] add extra thread allowance for blocking CLI code + * [cc056c1] add rtcp-mux-require option to force rtcp-mux usage for WebRTC + * [23eebfc] Fix frame PTS when decoder returns multiple frames in a row + * [ba46768] small fixes and improvements for packet forwarding feature #411 + * [031921c] purge old entries from SSRC hash table if it gets too full + + [ Claudiu Boriga ] + * [ca622b4] set TOS for redis streams + * [d5fea12] check call.recording structure before using it + * [3dcddf3] recording-daemon: add option to forward calls + * [2250ab1] make METADATA section appear in the metafile at intialization when recording using the proc method + * [ab0cb0c] don't use g_hash_table_foreach for call_timer_iterator + + [ Pawel Kuzak ] + * [f81fdf4] Deleted outdated graphics + + [ Guillem Jover ] + * [d5f7624] TT#24097 Fix perl filehandle usage + * [4f006a5] TT#24097 Use block form for map and grep + * [aa2eaee] TT#24097 Use a regex for split + * [bf514fb] TT#24097 Do not directly return result from sort + * [d5ad4a9] TT#24097 Do not use magic variable names + * [301af4a] TT#24097 Declare variable as my + * [0c728b2] TT#24097 Localize %ENV variable assignments + * [b4d0ff7] TT#24097 Use upper-case HERE-doc markers + * [0012037] TT#24097 Allow perl builtin homonyms for method names + * [acf84a7] TT#24097 Use semicolon instead of colons for end of statement + * [cff9d29] TT#24097 Reorder hash assignment to make perlcritic life easier + * [0bdc116] TT#24097 Rework perl code flow + * [b2636dc] TT#24097 Enable strict and warnings everywhere + * [19b4df7] TT#24097 Do not use unportable test operators + * [3351821] TT#24097 Remove unused shell variables + * [747661f] TT#24097 Do not use bash builtin names in sh scripts + * [04f5790] TT#24097 Switch for loop to use the i variable + * [33bafcf] TT#24097 Use $() instead of deprecated `` + * [376df64] TT#24097 Use «grep -E» instead of deprecated egrep + * [53b3c36] TT#24097 Fix shell quoting + * [465f3fe] TT#24097 Remove $ from variables inside arithmetic evaluation + * [677c9a5] TT#22072 Update packaging + * [6721f3c] TT#22072 Update debian/.gitignore + + [ Dmitry Poroh ] + * [cc09f4d] Crash stream_packet in case of out_srtp is NULL is fixed + + [ Sipwise Jenkins Builder ] + + -- Sipwise Jenkins Builder Wed, 06 Dec 2017 00:14:35 +0100 + ngcp-rtpengine (6.0.0.0+0~mr6.0.0.0) unstable; urgency=medium [ Richard Fuchs ] From 3472821ccc8e1fa46533125a91d72dbdc9348524 Mon Sep 17 00:00:00 2001 From: Claudiu Boriga Date: Fri, 8 Dec 2017 15:25:21 +0100 Subject: [PATCH 27/65] Add option to set TOS for control-ng interface --- daemon/call.h | 1 + daemon/control_ng.c | 13 +++++++++---- daemon/control_ng.h | 2 +- daemon/main.c | 8 +++++++- daemon/media_socket.h | 4 +--- daemon/socket.h | 4 +++- 6 files changed, 22 insertions(+), 10 deletions(-) diff --git a/daemon/call.h b/daemon/call.h index 73602e688..af6fbd331 100644 --- a/daemon/call.h +++ b/daemon/call.h @@ -405,6 +405,7 @@ struct callmaster_config { unsigned int redis_expires_secs; char *b2b_url; unsigned char default_tos; + unsigned char control_tos; enum xmlrpc_format fmt; endpoint_t graphite_ep; int graphite_interval; diff --git a/daemon/control_ng.c b/daemon/control_ng.c index c956be322..ee46baafd 100644 --- a/daemon/control_ng.c +++ b/daemon/control_ng.c @@ -305,7 +305,7 @@ out: -struct control_ng *control_ng_new(struct poller *p, endpoint_t *ep, struct callmaster *m) { +struct control_ng *control_ng_new(struct poller *p, endpoint_t *ep, struct callmaster *m, unsigned char tos) { struct control_ng *c; if (!p || !m) @@ -318,9 +318,14 @@ struct control_ng *control_ng_new(struct poller *p, endpoint_t *ep, struct callm if (udp_listener_init(&c->udp_listeners[0], p, ep, control_ng_incoming, &c->obj)) goto fail2; - if (ipv46_any_convert(ep) && udp_listener_init(&c->udp_listeners[1], p, ep, control_ng_incoming, &c->obj)) - goto fail2; - + if (tos) + set_tos(&c->udp_listeners[0].sock,tos); + if (ipv46_any_convert(ep)) { + if (udp_listener_init(&c->udp_listeners[1], p, ep, control_ng_incoming, &c->obj)) + goto fail2; + if (tos) + set_tos(&c->udp_listeners[1].sock,tos); + } return c; fail2: diff --git a/daemon/control_ng.h b/daemon/control_ng.h index fe4ee9a6c..027ab8234 100644 --- a/daemon/control_ng.h +++ b/daemon/control_ng.h @@ -30,6 +30,6 @@ struct control_ng { struct udp_listener udp_listeners[2]; }; -struct control_ng *control_ng_new(struct poller *, endpoint_t *, struct callmaster *); +struct control_ng *control_ng_new(struct poller *, endpoint_t *, struct callmaster *, unsigned char); #endif diff --git a/daemon/main.c b/daemon/main.c index a3e05023f..1c3a00c6b 100644 --- a/daemon/main.c +++ b/daemon/main.c @@ -58,6 +58,7 @@ static endpoint_t homer_ep; static int homer_protocol = SOCK_DGRAM; static int homer_id = 2001; static int tos; +static int control_tos; static int table = -1; static int no_fallback; static unsigned int timeout; @@ -268,6 +269,7 @@ static void options(int *argc, char ***argv) { { "graphite-interval", 'G', 0, G_OPTION_ARG_INT, &graphite_interval, "Graphite send interval in seconds", "INT" }, { "graphite-prefix",0, 0, G_OPTION_ARG_STRING, &graphite_prefix_s, "Prefix for graphite line", "STRING"}, { "tos", 'T', 0, G_OPTION_ARG_INT, &tos, "Default TOS value to set on streams", "INT" }, + { "control-tos",0 , 0, G_OPTION_ARG_INT, &control_tos, "Default TOS value to set on control-ng", "INT" }, { "timeout", 'o', 0, G_OPTION_ARG_INT, &timeout, "RTP timeout", "SECS" }, { "silent-timeout",'s',0,G_OPTION_ARG_INT, &silent_timeout,"RTP timeout for muted", "SECS" }, { "final-timeout",'a',0,G_OPTION_ARG_INT, &final_timeout, "Call timeout", "SECS" }, @@ -371,6 +373,9 @@ static void options(int *argc, char ***argv) { if (tos < 0 || tos > 255) die("Invalid TOS value"); + if (control_tos < 0 || control_tos > 255) + die("Invalid control-ng TOS value"); + if (timeout <= 0) timeout = 60; @@ -528,6 +533,7 @@ no_kernel: mc.final_timeout = final_timeout; mc.delete_delay = delete_delay; mc.default_tos = tos; + mc.control_tos = control_tos; mc.b2b_url = b2b_url; mc.fmt = xmlrpc_fmt; mc.graphite_ep = graphite_ep; @@ -562,7 +568,7 @@ no_kernel: cn = NULL; if (ng_listen_ep.port) { interfaces_exclude_port(ng_listen_ep.port); - cn = control_ng_new(ctx->p, &ng_listen_ep, ctx->m); + cn = control_ng_new(ctx->p, &ng_listen_ep, ctx->m, control_tos); if (!cn) die("Failed to open UDP control connection port"); } diff --git a/daemon/media_socket.h b/daemon/media_socket.h index 6e27679b5..7886a2a5b 100644 --- a/daemon/media_socket.h +++ b/daemon/media_socket.h @@ -78,9 +78,7 @@ int is_local_endpoint(const struct intf_address *addr, unsigned int port); //int get_port(socket_t *r, unsigned int port, const struct local_intf *lif, const struct call *c); //void release_port(socket_t *r, const struct local_intf *); -INLINE void set_tos(socket_t *s, unsigned int tos) { - s->family->tos(s, tos); -} + int __get_consecutive_ports(GQueue *out, unsigned int num_ports, unsigned int wanted_start_port, struct intf_spec *spec, const str *); int get_consecutive_ports(GQueue *out, unsigned int num_ports, const struct logical_intf *log, const str *); diff --git a/daemon/socket.h b/daemon/socket.h index 424e529c5..5c57fa5a5 100644 --- a/daemon/socket.h +++ b/daemon/socket.h @@ -261,7 +261,9 @@ INLINE int ipv46_any_convert(endpoint_t *ep) { #define endpoint_packet_header(o, src, dst, len) (dst)->address.family->packet_header(o, src, dst, len) - +INLINE void set_tos(socket_t *s, unsigned int tos) { + s->family->tos(s, tos); +} socktype_t *get_socket_type(const str *s); socktype_t *get_socket_type_c(const char *s); From 172bd1f637e643b49f3e47c5c39dc213891088e6 Mon Sep 17 00:00:00 2001 From: Guillem Jover Date: Mon, 11 Dec 2017 18:52:27 +0100 Subject: [PATCH 28/65] TT#26513 debian: Simplify upstream version fetching Change-Id: Ia1e99d197b2f63d5fa36edf0475e2aa3f4c83053 --- debian/rules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/rules b/debian/rules index 169deb1ce..6747ecbe0 100755 --- a/debian/rules +++ b/debian/rules @@ -12,7 +12,7 @@ pdkms:=ngcp-rtpengine-kernel-dkms # short upstream name, used for module source directory sname:=ngcp-rtpengine # Source version -sversion:=$(shell dpkg-parsechangelog|grep "^Version:"|cut -d" " -f2|rev|cut -d- -f2-|rev|cut -d':' -f2) +sversion:=$(shell dpkg-parsechangelog -SVersion | sed -e 's/^[^:]\+://;s/-[^-]\+$$//') PACKAGE=ngcp-rtpengine-kernel ## end of kernel package specific stuff From a456e201cfad5ce0d8181aaa2b4aae33bfbeaf26 Mon Sep 17 00:00:00 2001 From: Guillem Jover Date: Tue, 5 Dec 2017 17:21:56 +0100 Subject: [PATCH 29/65] TT#26513 Remove unused modprobe variables Change-Id: Ic52f2e4fc4bca1f76d67178be9d553b0321a8160 --- debian/ngcp-rtpengine-recording-daemon.init | 8 -------- 1 file changed, 8 deletions(-) diff --git a/debian/ngcp-rtpengine-recording-daemon.init b/debian/ngcp-rtpengine-recording-daemon.init index 92e948ffc..813149903 100755 --- a/debian/ngcp-rtpengine-recording-daemon.init +++ b/debian/ngcp-rtpengine-recording-daemon.init @@ -57,19 +57,11 @@ fi if ! test -z "$SET_USER"; then START_OPTIONS="$START_OPTIONS --chuid $SET_USER" - PUID=$(id -u "$SET_USER" 2> /dev/null) - test -z "$PUID" || MODPROBE_OPTIONS="$MODPROBE_OPTIONS proc_uid=$PUID" - if test -z "$SET_GROUP"; then - PGID=$(id -g "$SET_USER" 2> /dev/null) - test -z "$PGID" || MODPROBE_OPTIONS="$MODPROBE_OPTIONS proc_gid=$PGID" - fi test "$DO_DIR_CHOWN" = 1 && chown "$SET_USER": "$PIDDIR" fi if ! test -z "$SET_GROUP"; then START_OPTIONS="$START_OPTIONS --group $SET_GROUP" - PGID=$(grep "^$SET_GROUP:" /etc/group | cut -d: -f3 2> /dev/null) - test -z "$PGID" || MODPROBE_OPTIONS="$MODPROBE_OPTIONS proc_gid=$PGID" test "$DO_DIR_CHOWN" = 1 && chgrp "$SET_GROUP" "$PIDDIR" fi From 0d3e69387c0d9ba9f02d177919edd430dfac5a7d Mon Sep 17 00:00:00 2001 From: Guillem Jover Date: Tue, 5 Dec 2017 16:45:50 +0100 Subject: [PATCH 30/65] TT#26513 Improve sysvinit output messages Change-Id: I57162bba42a84a99cd47fe94abdd92b33436c286 --- debian/ngcp-rtpengine-daemon.init | 17 ++++++++--------- debian/ngcp-rtpengine-recording-daemon.init | 17 ++++++++--------- 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/debian/ngcp-rtpengine-daemon.init b/debian/ngcp-rtpengine-daemon.init index 5bab13150..a4e39cadb 100755 --- a/debian/ngcp-rtpengine-daemon.init +++ b/debian/ngcp-rtpengine-daemon.init @@ -10,6 +10,7 @@ # Description: Proxy for RTP and other media streams ### END INIT INFO +set -e PATH=/sbin:/bin:/usr/sbin:/usr/bin NAME=ngcp-rtpengine-daemon @@ -22,21 +23,19 @@ DEFAULTS=/etc/default/${NAME} test -f "$DAEMON" || exit 0 +. /lib/lsb/init-functions + # Load startup options if available if [ -f "$DEFAULTS" ]; then . "$DEFAULTS" || true fi if [ "$RUN_RTPENGINE" != "yes" ]; then - echo "rtpengine not yet configured. Edit $DEFAULTS first." + log_action_msg "rtpengine not yet configured. Edit $DEFAULTS first." exit 0 fi [ -z "$PIDFILE" ] && PIDFILE="/var/run/rtpengine.pid" -set -e - -. /lib/lsb/init-functions - OPTIONS="" START_OPTIONS="" MODPROBE_OPTIONS="" @@ -159,15 +158,14 @@ case "$1" in status=$? case "${status}" in 0|3) - echo "Active node or transition." + log_action_msg "Active node or transition." ;; *) - echo "Ignored start action in inactive node ($status)" + log_action_msg "Ignored start action in inactive node ($status)" exit 0 ;; esac fi - log_daemon_msg "Starting $DESC: $NAME" if [ "$TABLE" -ge 0 ] && [ "$VIRT" != "yes" ]; then if [ "$MANAGE_IPTABLES" = "yes" ]; then # shellcheck disable=SC2086 @@ -189,13 +187,14 @@ case "$1" in fi fi set -e + log_daemon_msg "Starting $DESC" "$NAME" # shellcheck disable=SC2086 start-stop-daemon --start --quiet --pidfile "$PIDFILE" \ --exec "$DAEMON" $START_OPTIONS -- $OPTIONS || log_progress_msg " already running" log_end_msg $? ;; stop) - log_daemon_msg "Stopping $DESC: $NAME" + log_daemon_msg "Stopping $DESC" "$NAME" start-stop-daemon --oknodo --stop --quiet --pidfile $PIDFILE \ --exec "$DAEMON" if [ "$?" -ne 0 ]; then diff --git a/debian/ngcp-rtpengine-recording-daemon.init b/debian/ngcp-rtpengine-recording-daemon.init index 813149903..ac07a84c2 100755 --- a/debian/ngcp-rtpengine-recording-daemon.init +++ b/debian/ngcp-rtpengine-recording-daemon.init @@ -10,6 +10,7 @@ # Description: Recording daemon for RTP and other media streams ### END INIT INFO +set -e PATH=/sbin:/bin:/usr/sbin:/usr/bin NAME=ngcp-rtpengine-recording-daemon @@ -20,22 +21,20 @@ DEFAULTS=/etc/default/${NAME} test -f "$DAEMON" || exit 0 +. /lib/lsb/init-functions + # Load startup options if available if [ -f "$DEFAULTS" ]; then . "$DEFAULTS" || true fi if [ "$RUN_RTPENGINE_RECORDING" != "yes" ]; then - echo "rtpengine-recording not yet configured. Edit $DEFAULTS first." + log_action_msg "rtpengine-recording not yet configured. Edit $DEFAULTS first." exit 0 fi [ -z "$PIDFILE" ] && PIDFILE="/var/run/rtpengine-recording.pid" [ -z "$NFS_OPTIONS" ] && NFS_OPTIONS="hard,tcp,intr" -set -e - -. /lib/lsb/init-functions - OPTIONS="" START_OPTIONS="" @@ -75,17 +74,17 @@ case "$1" in status=$? case "${status}" in 0|3) - echo "Active node or transition." + log_action_msg "Active node or transition." ;; *) - echo "Ignored start action in inactive node ($status)" + log_action_msg "Ignored start action in inactive node ($status)" exit 0 ;; esac fi set -e - log_daemon_msg "Starting $DESC: $NAME" + log_daemon_msg "Starting $DESC" "$NAME" if [ "$MUST_NFS" = yes ]; then if ! grep -E -q "^[^ :]+:[^ :]+ $NFS_LOCAL_MOUNT nfs.? " /proc/mounts; then @@ -101,7 +100,7 @@ case "$1" in log_end_msg $? ;; stop) - log_daemon_msg "Stopping $DESC: $NAME" + log_daemon_msg "Stopping $DESC" "$NAME" start-stop-daemon --oknodo --stop --quiet --pidfile $PIDFILE \ --exec "$DAEMON" if [ "$?" -ne 0 ]; then From 708231858f6a087b21495acd9af603962661c400 Mon Sep 17 00:00:00 2001 From: Guillem Jover Date: Tue, 5 Dec 2017 16:46:25 +0100 Subject: [PATCH 31/65] TT#26513 Pass --retry=5 to start-stop-daemon and avoid sleeping Change-Id: I8221d1b48b9d3d76f1421f47f6dc02c509b4d7bb --- debian/ngcp-rtpengine-daemon.init | 3 +-- debian/ngcp-rtpengine-recording-daemon.init | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/debian/ngcp-rtpengine-daemon.init b/debian/ngcp-rtpengine-daemon.init index a4e39cadb..62a5a9778 100755 --- a/debian/ngcp-rtpengine-daemon.init +++ b/debian/ngcp-rtpengine-daemon.init @@ -196,7 +196,7 @@ case "$1" in stop) log_daemon_msg "Stopping $DESC" "$NAME" start-stop-daemon --oknodo --stop --quiet --pidfile $PIDFILE \ - --exec "$DAEMON" + --retry 5 --exec "$DAEMON" if [ "$?" -ne 0 ]; then return $? fi @@ -218,7 +218,6 @@ case "$1" in ;; restart|force-reload) $0 stop - sleep 1 $0 start ;; status) diff --git a/debian/ngcp-rtpengine-recording-daemon.init b/debian/ngcp-rtpengine-recording-daemon.init index ac07a84c2..77d0da233 100755 --- a/debian/ngcp-rtpengine-recording-daemon.init +++ b/debian/ngcp-rtpengine-recording-daemon.init @@ -102,7 +102,7 @@ case "$1" in stop) log_daemon_msg "Stopping $DESC" "$NAME" start-stop-daemon --oknodo --stop --quiet --pidfile $PIDFILE \ - --exec "$DAEMON" + --retry 5 --exec "$DAEMON" if [ "$?" -ne 0 ]; then return $? fi From 43f527fb820322b5aabcbc9493b50753872a81ac Mon Sep 17 00:00:00 2001 From: Claudiu Boriga Date: Tue, 12 Dec 2017 12:47:35 +0100 Subject: [PATCH 32/65] Add documentation for the control-tos option --- README.md | 6 ++++++ etc/rtpengine.sample.conf | 1 + 2 files changed, 7 insertions(+) diff --git a/README.md b/README.md index 9ca3e4d92..32c3804e6 100644 --- a/README.md +++ b/README.md @@ -169,6 +169,7 @@ option and which are reproduced below: -G, --graphite-interval=INT Graphite data statistics send interval --graphite-prefix=STRING Graphite prefix for every line -T, --tos=INT TOS value to set on streams + --control-tos=INT TOS value to set on control-ng interface -o, --timeout=SECS RTP timeout -s, --silent-timeout=SECS RTP timeout for muted -a, --final-timeout=SECS Call timeout @@ -308,6 +309,11 @@ The options are described in more detail below. Takes an integer as argument and if given, specifies the TOS value that should be set in outgoing packets. The default is to leave the TOS field untouched. A typical value is 184 (*Expedited Forwarding*). +* --control-tos + + Takes an integer as argument and if given, specifies the TOS value that should be set in the control-ng + interface packets. The default is to leave the TOS field untouched. + * -o, --timeout Takes the number of seconds as argument after which a media stream should be considered dead if no media diff --git a/etc/rtpengine.sample.conf b/etc/rtpengine.sample.conf index 14df93156..a8ee15e19 100644 --- a/etc/rtpengine.sample.conf +++ b/etc/rtpengine.sample.conf @@ -21,6 +21,7 @@ listen-ng = 127.0.0.1:2223 timeout = 60 silent-timeout = 3600 tos = 184 +#control-tos = 184 # delete-delay = 30 # final-timeout = 10800 From 1b8f5e4a55bda4923f9cbaa1d161d1c6f71321c0 Mon Sep 17 00:00:00 2001 From: Guillem Jover Date: Thu, 14 Dec 2017 16:51:56 +0100 Subject: [PATCH 33/65] TT#26513 Preserve errno on error returns We should preserve the errno value so that the caller can report accurate error information, as the close() call could fail too. Change-Id: I1a36ace8f47ad3ea550aa3e2e272922633abfdca --- daemon/kernel.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/daemon/kernel.c b/daemon/kernel.c index 0b17700ee..397f98ae8 100644 --- a/daemon/kernel.c +++ b/daemon/kernel.c @@ -30,6 +30,7 @@ struct kernel_interface kernel; static int kernel_create_table(unsigned int id) { char str[64]; + int saved_errno; int fd; int i; @@ -45,12 +46,15 @@ static int kernel_create_table(unsigned int id) { return 0; fail: + saved_errno = errno; close(fd); + errno = saved_errno; return -1; } static int kernel_open_table(unsigned int id) { char str[64]; + int saved_errno; int fd; struct rtpengine_message msg; int i; @@ -69,7 +73,9 @@ static int kernel_open_table(unsigned int id) { return fd; fail: + saved_errno = errno; close(fd); + errno = saved_errno; return -1; } From fd3c1d2519f2e55483725b40e4a06b14b63d828f Mon Sep 17 00:00:00 2001 From: Guillem Jover Date: Wed, 13 Dec 2017 11:30:06 +0100 Subject: [PATCH 34/65] TT#26513 Delete the kernel forwarding table on startup If we are creating the kernel forwarding table, we have to make sure it has been deleted already, otherwise we can get into collisions with the already setup forwardings, and the subsequent add will fail anyway. Change-Id: I2601c602543ff3e3493bae296d263dde545ff352 --- daemon/kernel.c | 19 +++++++++++++++++-- debian/ngcp-rtpengine-daemon.init | 3 --- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/daemon/kernel.c b/daemon/kernel.c index 397f98ae8..7ce3fefca 100644 --- a/daemon/kernel.c +++ b/daemon/kernel.c @@ -28,7 +28,7 @@ struct kernel_interface kernel; -static int kernel_create_table(unsigned int id) { +static int kernel_action_table(const char *action, unsigned int id) { char str[64]; int saved_errno; int fd; @@ -37,7 +37,9 @@ static int kernel_create_table(unsigned int id) { fd = open(PREFIX "/control", O_WRONLY | O_TRUNC); if (fd == -1) return -1; - sprintf(str, "add %u\n", id); + i = snprintf(str, sizeof(str), "%s %u\n", action, id); + if (i >= sizeof(str)) + goto fail; i = write(fd, str, strlen(str)); if (i == -1) goto fail; @@ -52,6 +54,14 @@ fail: return -1; } +static int kernel_create_table(unsigned int id) { + return kernel_action_table("add", id); +} + +static int kernel_delete_table(unsigned int id) { + return kernel_action_table("del", id); +} + static int kernel_open_table(unsigned int id) { char str[64]; int saved_errno; @@ -85,6 +95,11 @@ int kernel_setup_table(unsigned int id) { kernel.is_wanted = 1; + if (kernel_delete_table(id) && errno != ENOENT) { + ilog(LOG_ERR, "FAILED TO DELETE KERNEL TABLE %i (%s), KERNEL FORWARDING DISABLED", + id, strerror(errno)); + return -1; + } if (kernel_create_table(id)) { ilog(LOG_ERR, "FAILED TO CREATE KERNEL TABLE %i (%s), KERNEL FORWARDING DISABLED", id, strerror(errno)); diff --git a/debian/ngcp-rtpengine-daemon.init b/debian/ngcp-rtpengine-daemon.init index 62a5a9778..875aaa31f 100755 --- a/debian/ngcp-rtpengine-daemon.init +++ b/debian/ngcp-rtpengine-daemon.init @@ -182,9 +182,6 @@ case "$1" in ip6tables -D rtpengine -p udp -j RTPENGINE --id "$TABLE" 2>/dev/null ip6tables -I rtpengine -p udp -j RTPENGINE --id "$TABLE" fi - if [ -e /proc/rtpengine/control ]; then - echo "del $TABLE" > /proc/rtpengine/control 2>/dev/null - fi fi set -e log_daemon_msg "Starting $DESC" "$NAME" From d10952a02975782c78b5b41af46d98eb9e5aa310 Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Fri, 15 Dec 2017 11:21:22 -0500 Subject: [PATCH 35/65] TT#26757 add tcp_listener framework Change-Id: I402d36637235ba0cc03e77d426f4dd9cbc4722a9 --- daemon/Makefile | 2 +- daemon/call_interfaces.c | 10 +- daemon/call_interfaces.h | 4 +- daemon/control_ng.c | 8 +- daemon/control_ng.h | 2 +- daemon/control_tcp.c | 254 ++++++++++----------------------------- daemon/control_tcp.h | 5 +- daemon/control_udp.c | 10 +- daemon/control_udp.h | 2 +- daemon/socket.c | 32 +++++ daemon/socket.h | 2 + daemon/streambuf.c | 58 +++++++-- daemon/streambuf.h | 3 + daemon/tcp_listener.c | 227 ++++++++++++++++++++++++++++++++++ daemon/tcp_listener.h | 47 ++++++++ daemon/udp_listener.c | 20 ++- daemon/udp_listener.h | 11 +- 17 files changed, 452 insertions(+), 245 deletions(-) create mode 100644 daemon/tcp_listener.c create mode 100644 daemon/tcp_listener.h diff --git a/daemon/Makefile b/daemon/Makefile index a93bb134a..21c5870c0 100644 --- a/daemon/Makefile +++ b/daemon/Makefile @@ -55,7 +55,7 @@ include ../lib/lib.Makefile SRCS= main.c kernel.c poller.c aux.c control_tcp.c streambuf.c call.c control_udp.c redis.c \ bencode.c cookie_cache.c udp_listener.c control_ng.c sdp.c str.c stun.c rtcp.c \ crypto.c rtp.c call_interfaces.c dtls.c log.c cli.c graphite.c ice.c socket.c \ - media_socket.c homer.c recording.c statistics.c cdr.c ssrc.c iptables.c + media_socket.c homer.c recording.c statistics.c cdr.c ssrc.c iptables.c tcp_listener.c LIBSRCS= loglib.c auxlib.c rtplib.c OBJS= $(SRCS:.c=.o) $(LIBSRCS:.c=.o) diff --git a/daemon/call_interfaces.c b/daemon/call_interfaces.c index af3191c82..13492005f 100644 --- a/daemon/call_interfaces.c +++ b/daemon/call_interfaces.c @@ -22,6 +22,8 @@ #include "recording.h" #include "rtplib.h" #include "ssrc.h" +#include "tcp_listener.h" +#include "streambuf.h" @@ -417,7 +419,7 @@ void call_delete_tcp(char **out, struct callmaster *m) { call_delete_branch(m, &callid, NULL, NULL, NULL, NULL, -1); } -static void call_status_iterator(struct call *c, struct control_stream *s) { +static void call_status_iterator(struct call *c, struct streambuf_stream *s) { // GList *l; // struct callstream *cs; // struct peer *p; @@ -429,7 +431,7 @@ static void call_status_iterator(struct call *c, struct control_stream *s) { // m = c->callmaster; // mutex_lock(&c->master_lock); - control_stream_printf(s, "session "STR_FORMAT" - - - - %lli\n", + streambuf_printf(s->outbuf, "session "STR_FORMAT" - - - - %lli\n", STR_FMT(&c->callid), timeval_diff(&g_now, &c->created) / 1000000); @@ -438,13 +440,13 @@ static void call_status_iterator(struct call *c, struct control_stream *s) { // mutex_unlock(&c->master_lock); } -void calls_status_tcp(struct callmaster *m, struct control_stream *s) { +void calls_status_tcp(struct callmaster *m, struct streambuf_stream *s) { GQueue q = G_QUEUE_INIT; struct call *c; callmaster_get_all_calls(m, &q); - control_stream_printf(s, "proxy %u "UINT64F"/%i/%i\n", + streambuf_printf(s->outbuf, "proxy %u "UINT64F"/%i/%i\n", g_queue_get_length(&q), atomic64_get(&m->stats.bytes), 0, 0); diff --git a/daemon/call_interfaces.h b/daemon/call_interfaces.h index 4887dc971..c87af22d1 100644 --- a/daemon/call_interfaces.h +++ b/daemon/call_interfaces.h @@ -14,7 +14,7 @@ struct call; struct call_stats; struct callmaster; -struct control_stream; +struct streambuf_stream; struct sockaddr_in6; struct sdp_ng_flags { @@ -69,7 +69,7 @@ extern int dtls_passive_def; str *call_request_tcp(char **, struct callmaster *); str *call_lookup_tcp(char **, struct callmaster *); void call_delete_tcp(char **, struct callmaster *); -void calls_status_tcp(struct callmaster *, struct control_stream *); +void calls_status_tcp(struct callmaster *, struct streambuf_stream *); str *call_update_udp(char **, struct callmaster *, const char*, const endpoint_t *); str *call_lookup_udp(char **, struct callmaster *); diff --git a/daemon/control_ng.c b/daemon/control_ng.c index ee46baafd..0c5d37930 100644 --- a/daemon/control_ng.c +++ b/daemon/control_ng.c @@ -104,7 +104,7 @@ struct control_ng_stats* get_control_ng_stats(struct control_ng* c, const sockad } static void control_ng_incoming(struct obj *obj, str *buf, const endpoint_t *sin, char *addr, - struct udp_listener *ul) + socket_t *ul) { struct control_ng *c = (void *) obj; bencode_buffer_t bencbuf; @@ -289,7 +289,7 @@ send_only: iov[2].iov_base = to_send->s; iov[2].iov_len = to_send->len; - socket_sendiov(&ul->sock, iov, iovlen, sin); + socket_sendiov(ul, iov, iovlen, sin); if (resp) cookie_cache_insert(&c->cookie_cache, &cookie, &reply); @@ -319,12 +319,12 @@ struct control_ng *control_ng_new(struct poller *p, endpoint_t *ep, struct callm if (udp_listener_init(&c->udp_listeners[0], p, ep, control_ng_incoming, &c->obj)) goto fail2; if (tos) - set_tos(&c->udp_listeners[0].sock,tos); + set_tos(&c->udp_listeners[0],tos); if (ipv46_any_convert(ep)) { if (udp_listener_init(&c->udp_listeners[1], p, ep, control_ng_incoming, &c->obj)) goto fail2; if (tos) - set_tos(&c->udp_listeners[1].sock,tos); + set_tos(&c->udp_listeners[1],tos); } return c; diff --git a/daemon/control_ng.h b/daemon/control_ng.h index 027ab8234..9851fdae7 100644 --- a/daemon/control_ng.h +++ b/daemon/control_ng.h @@ -27,7 +27,7 @@ struct control_ng { struct obj obj; struct callmaster *callmaster; struct cookie_cache cookie_cache; - struct udp_listener udp_listeners[2]; + socket_t udp_listeners[2]; }; struct control_ng *control_ng_new(struct poller *, endpoint_t *, struct callmaster *, unsigned char); diff --git a/daemon/control_tcp.c b/daemon/control_tcp.c index f65a048cb..6ffb29d3f 100644 --- a/daemon/control_tcp.c +++ b/daemon/control_tcp.c @@ -18,35 +18,19 @@ #include "call_interfaces.h" #include "socket.h" #include "log_funcs.h" +#include "tcp_listener.h" -struct control_stream { - struct obj obj; - - int fd; - mutex_t lock; - struct streambuf *inbuf; - struct streambuf *outbuf; - struct sockaddr_in inaddr; - - struct control_tcp *control; - struct poller *poller; - int linked:1; -}; - - struct control_tcp { struct obj obj; - int fd; + struct streambuf_listener listeners[2]; + pcre *parse_re; pcre_extra *parse_ree; - mutex_t lock; - GList *streams; - struct poller *poller; struct callmaster *callmaster; }; @@ -54,65 +38,48 @@ struct control_tcp { -static void control_stream_closed(int fd, void *p, uintptr_t u) { - struct control_stream *s = p; - struct control_tcp *c; - GList *l = NULL; +//static void control_stream_closed(int fd, void *p, uintptr_t u) { +static void control_stream_closed(struct streambuf_stream *s) { + ilog(LOG_INFO, "Control connection from %s closed", s->addr); +} - ilog(LOG_INFO, "Control connection from " DF " closed", DP(s->inaddr)); - c = s->control; +static void control_list(struct control_tcp *c, struct streambuf_stream *s) { + for (int i = 0; i < G_N_ELEMENTS(c->listeners); i++) { + if (!c->listeners[i].listener.family || !c->listeners[i].poller) + continue; // not used -restart: - mutex_lock(&c->lock); - if (s->linked) { - /* we might get called when it's not quite linked yet */ - l = g_list_find(c->streams, s); - if (!l) { - mutex_unlock(&c->lock); - goto restart; - } - c->streams = g_list_delete_link(c->streams, l); - s->linked = 0; - } - mutex_unlock(&c->lock); - if (l) - obj_put(s); - poller_del_item(s->poller, fd); -} + mutex_lock(&c->listeners[i].lock); + GList *streams = g_hash_table_get_values(c->listeners[i].streams); + for (GList *l = streams; l; l = l->next) { + struct streambuf_stream *cl = l->data; + streambuf_printf(s->outbuf, "%s\n", cl->addr); + } -static void control_list(struct control_tcp *c, struct control_stream *s) { - struct control_stream *i; - GList *l; + mutex_unlock(&c->listeners[i].lock); - mutex_lock(&c->lock); - for (l = c->streams; l; l = l->next) { - i = l->data; - mutex_lock(&s->lock); - streambuf_printf(s->outbuf, DF "\n", DP(i->inaddr)); - mutex_unlock(&s->lock); + g_list_free(streams); } - mutex_unlock(&c->lock); streambuf_printf(s->outbuf, "End.\n"); } -static int control_stream_parse(struct control_stream *s, char *line) { +static int control_stream_parse(struct streambuf_stream *s, char *line) { int ovec[60]; int ret; char **out; - struct control_tcp *c = s->control; + struct control_tcp *c = (void *) s->parent; str *output = NULL; ret = pcre_exec(c->parse_re, c->parse_ree, line, strlen(line), 0, 0, ovec, G_N_ELEMENTS(ovec)); if (ret <= 0) { - ilog(LOG_WARNING, "Unable to parse command line from " DF ": %s", DP(s->inaddr), line); + ilog(LOG_WARNING, "Unable to parse command line from %s: %s", s->addr, line); return -1; } - ilog(LOG_INFO, "Got valid command from " DF ": %s", DP(s->inaddr), line); + ilog(LOG_INFO, "Got valid command from %s: %s", s->addr, line); pcre_get_substring_list(line, ovec, ret, (const char ***) &out); @@ -132,151 +99,64 @@ static int control_stream_parse(struct control_stream *s, char *line) { else if (!strcmp(out[RE_TCP_DIV_CMD], "status")) calls_status_tcp(c->callmaster, s); else if (!strcmp(out[RE_TCP_DIV_CMD], "build") || !strcmp(out[RE_TCP_DIV_CMD], "version")) - control_stream_printf(s, "Version: %s\n", RTPENGINE_VERSION); + streambuf_printf(s->outbuf, "Version: %s\n", RTPENGINE_VERSION); else if (!strcmp(out[RE_TCP_DIV_CMD], "controls")) control_list(c, s); else if (!strcmp(out[RE_TCP_DIV_CMD], "quit") || !strcmp(out[RE_TCP_DIV_CMD], "exit")) ; if (output) { - mutex_lock(&s->lock); streambuf_write_str(s->outbuf, output); - mutex_unlock(&s->lock); free(output); } pcre_free(out); log_info_clear(); - return -1; + return 1; } -static void control_stream_timer(int fd, void *p, uintptr_t u) { - struct control_stream *s = p; - int i; - - mutex_lock(&s->lock); - i = (poller_now - s->inbuf->active) >= 60 || (poller_now - s->outbuf->active) >= 60; - mutex_unlock(&s->lock); - - if (i) - control_stream_closed(s->fd, s, 0); +static void control_stream_timer(struct streambuf_stream *s) { + if ((poller_now - s->inbuf->active) >= 60 || (poller_now - s->outbuf->active) >= 60) + control_stream_closed(s); } -static void control_stream_readable(int fd, void *p, uintptr_t u) { - struct control_stream *s = p; +//static void control_stream_readable(int fd, void *p, uintptr_t u) { +static void control_stream_readable(struct streambuf_stream *s) { char *line; int ret; - mutex_lock(&s->lock); - - if (streambuf_readable(s->inbuf)) - goto close; - while ((line = streambuf_getline(s->inbuf))) { - mutex_unlock(&s->lock); - ilog(LOG_DEBUG, "Got control line from " DF ": %s", DP(s->inaddr), line); + ilog(LOG_DEBUG, "Got control line from %s: %s", s->addr, line); ret = control_stream_parse(s, line); free(line); + if (ret == 1) { + streambuf_stream_shutdown(s); + break; + } if (ret) - goto close_nolock; - mutex_lock(&s->lock); + goto close; } if (streambuf_bufsize(s->inbuf) > 1024) { - ilog(LOG_WARNING, "Buffer length exceeded in control connection from " DF, DP(s->inaddr)); + ilog(LOG_WARNING, "Buffer length exceeded in control connection from %s", s->addr); goto close; } - mutex_unlock(&s->lock); return; close: - mutex_unlock(&s->lock); -close_nolock: - control_stream_closed(fd, s, 0); -} - -static void control_stream_writeable(int fd, void *p, uintptr_t u) { - struct control_stream *s = p; - - if (streambuf_writeable(s->outbuf)) - control_stream_closed(fd, s, 0); -} - -static void control_closed(int fd, void *p, uintptr_t u) { - abort(); + streambuf_stream_close(s); } -static void control_stream_free(void *p) { - struct control_stream *s = p; - - close(s->fd); - streambuf_destroy(s->inbuf); - streambuf_destroy(s->outbuf); - mutex_destroy(&s->lock); +static void control_incoming(struct streambuf_stream *s) { + ilog(LOG_INFO, "New TCP control connection from %s", s->addr); } -static void control_incoming(int fd, void *p, uintptr_t u) { - int nfd; - struct control_tcp *c = p; - struct control_stream *s; - struct poller_item i; - struct sockaddr_in sin; - socklen_t sinl; - -next: - sinl = sizeof(sin); - nfd = accept(fd, (struct sockaddr *) &sin, &sinl); - if (nfd == -1) { - if (errno == EAGAIN || errno == EWOULDBLOCK) - return; - goto next; - } - nonblock(nfd); - - ilog(LOG_INFO, "New control connection from " DF, DP(sin)); - - s = obj_alloc0("control_stream", sizeof(*s), control_stream_free); - - s->fd = nfd; - s->control = c; - s->poller = c->poller; - s->inbuf = streambuf_new(c->poller, nfd); - s->outbuf = streambuf_new(c->poller, nfd); - memcpy(&s->inaddr, &sin, sizeof(s->inaddr)); - mutex_init(&s->lock); - s->linked = 1; - - ZERO(i); - i.fd = nfd; - i.closed = control_stream_closed; - i.readable = control_stream_readable; - i.writeable = control_stream_writeable; - i.timer = control_stream_timer; - i.obj = &s->obj; - - if (poller_add_item(c->poller, &i)) - goto fail; - mutex_lock(&c->lock); - /* let the list steal our own ref */ - c->streams = g_list_prepend(c->streams, s); - mutex_unlock(&c->lock); - - goto next; - -fail: - obj_put(s); - goto next; -} - - -struct control_tcp *control_tcp_new(struct poller *p, const endpoint_t *ep, struct callmaster *m) { - socket_t sock; +struct control_tcp *control_tcp_new(struct poller *p, endpoint_t *ep, struct callmaster *m) { struct control_tcp *c; - struct poller_item i; const char *errptr; int erroff; @@ -285,14 +165,28 @@ struct control_tcp *control_tcp_new(struct poller *p, const endpoint_t *ep, stru if (!m) return NULL; - if (open_socket(&sock, SOCK_STREAM, ep->port, &ep->address)) - return NULL; + c = obj_alloc0("control", sizeof(*c), NULL); - if (listen(sock.fd, 5)) + if (streambuf_listener_init(&c->listeners[0], p, ep, + control_incoming, control_stream_readable, + control_stream_closed, + control_stream_timer, + &c->obj)) + { + ilog(LOG_ERR, "Failed to open TCP control port: %s", strerror(errno)); goto fail; - - - c = obj_alloc0("control", sizeof(*c), NULL); + } + if (ipv46_any_convert(ep)) { + if (streambuf_listener_init(&c->listeners[1], p, ep, + control_incoming, control_stream_readable, + control_stream_closed, + control_stream_timer, + &c->obj)) + { + ilog(LOG_ERR, "Failed to open TCP control port: %s", strerror(errno)); + goto fail; + } + } c->parse_re = pcre_compile( /* reqtype callid streams ip fromdom fromtype todom totype agent info |reqtype callid info | reqtype */ @@ -300,36 +194,14 @@ struct control_tcp *control_tcp_new(struct poller *p, const endpoint_t *ep, stru PCRE_DOLLAR_ENDONLY | PCRE_DOTALL, &errptr, &erroff, NULL); c->parse_ree = pcre_study(c->parse_re, 0, &errptr); - c->fd = sock.fd; c->poller = p; c->callmaster = m; - mutex_init(&c->lock); - - ZERO(i); - i.fd = sock.fd; - i.closed = control_closed; - i.readable = control_incoming; - i.obj = &c->obj; - if (poller_add_item(p, &i)) - goto fail2; obj_put(c); return c; -fail2: - obj_put(c); fail: - close_socket(&sock); + // XXX streambuf_listener_close ... + obj_put(c); return NULL; } - - -void control_stream_printf(struct control_stream *s, const char *f, ...) { - va_list va; - - va_start(va, f); - mutex_lock(&s->lock); - streambuf_vprintf(s->outbuf, f, va); - mutex_unlock(&s->lock); - va_end(va); -} diff --git a/daemon/control_tcp.h b/daemon/control_tcp.h index 06b3c298f..9ca94c969 100644 --- a/daemon/control_tcp.h +++ b/daemon/control_tcp.h @@ -32,12 +32,11 @@ struct poller; struct callmaster; struct control_tcp; -struct control_stream; +struct streambuf_stream; -struct control_tcp *control_tcp_new(struct poller *, const endpoint_t *, struct callmaster *); -void control_stream_printf(struct control_stream *, const char *, ...) __attribute__ ((format (printf, 2, 3))); +struct control_tcp *control_tcp_new(struct poller *, endpoint_t *, struct callmaster *); diff --git a/daemon/control_udp.c b/daemon/control_udp.c index 0cf4eeee4..c64a3e6c4 100644 --- a/daemon/control_udp.c +++ b/daemon/control_udp.c @@ -22,7 +22,7 @@ static void control_udp_incoming(struct obj *obj, str *buf, const endpoint_t *sin, char *addr, - struct udp_listener *ul) { + socket_t *ul) { struct control_udp *u = (void *) obj; int ret; int ovec[100]; @@ -60,7 +60,7 @@ static void control_udp_incoming(struct obj *obj, str *buf, const endpoint_t *si iovlen = 2; } - socket_sendiov(&ul->sock, iov, iovlen, sin); + socket_sendiov(ul, iov, iovlen, sin); pcre_free(out); @@ -75,7 +75,7 @@ static void control_udp_incoming(struct obj *obj, str *buf, const endpoint_t *si reply = cookie_cache_lookup(&u->cookie_cache, &cookie); if (reply) { ilog(LOG_INFO, "Detected command from udp:%s as a duplicate", addr); - socket_sendto(&ul->sock, reply->s, reply->len, sin); + socket_sendto(ul, reply->s, reply->len, sin); free(reply); goto out; } @@ -118,11 +118,11 @@ static void control_udp_incoming(struct obj *obj, str *buf, const endpoint_t *si iov[2].iov_len = 9; iovlen++; } - socket_sendiov(&ul->sock, iov, iovlen, sin); + socket_sendiov(ul, iov, iovlen, sin); } if (reply) { - socket_sendto(&ul->sock, reply->s, reply->len, sin); + socket_sendto(ul, reply->s, reply->len, sin); cookie_cache_insert(&u->cookie_cache, &cookie, reply); free(reply); } diff --git a/daemon/control_udp.h b/daemon/control_udp.h index 0381c39e0..f30a45c14 100644 --- a/daemon/control_udp.h +++ b/daemon/control_udp.h @@ -50,7 +50,7 @@ struct control_udp { struct callmaster *callmaster; struct cookie_cache cookie_cache; - struct udp_listener udp_listeners[2]; + socket_t udp_listeners[2]; pcre *parse_re; pcre_extra *parse_ree; diff --git a/daemon/socket.c b/daemon/socket.c index 00f731c49..b1fe71f94 100644 --- a/daemon/socket.c +++ b/daemon/socket.c @@ -25,6 +25,8 @@ static int __ip4_is_specified(const sockaddr_t *a); static int __ip6_is_specified(const sockaddr_t *a); static int __ip_bind(socket_t *s, unsigned int, const sockaddr_t *); static int __ip_connect(socket_t *s, const endpoint_t *); +static int __ip_listen(socket_t *s, int backlog); +static int __ip_accept(socket_t *s, socket_t *new_sock); static int __ip_timestamping(socket_t *s); static int __ip4_sockaddr2endpoint(endpoint_t *, const void *); static int __ip6_sockaddr2endpoint(endpoint_t *, const void *); @@ -76,6 +78,8 @@ static struct socket_family __socket_families[__SF_LAST] = { .addrport2sockaddr = __ip4_addrport2sockaddr, .bind = __ip_bind, .connect = __ip_connect, + .listen = __ip_listen, + .accept = __ip_accept, .timestamping = __ip_timestamping, .recvfrom = __ip_recvfrom, .recvfrom_ts = __ip_recvfrom_ts, @@ -105,6 +109,8 @@ static struct socket_family __socket_families[__SF_LAST] = { .addrport2sockaddr = __ip6_addrport2sockaddr, .bind = __ip_bind, .connect = __ip_connect, + .listen = __ip_listen, + .accept = __ip_accept, .timestamping = __ip_timestamping, .recvfrom = __ip_recvfrom, .recvfrom_ts = __ip_recvfrom_ts, @@ -261,6 +267,30 @@ static int __ip_connect(socket_t *s, const endpoint_t *ep) { } return 0; } +static int __ip_listen(socket_t *s, int backlog) { + return listen(s->fd, backlog); +} +static int __ip_accept(socket_t *s, socket_t *newsock) { + int nfd; + struct sockaddr_storage sin; + socklen_t sinlen; + + ZERO(*newsock); + + sinlen = sizeof(sin); + nfd = accept(s->fd, (struct sockaddr *) &sin, &sinlen); + if (nfd == -1) { + __C_DBG("accept fail, fd=%d, port=%d", s->fd, s->local.port); + return -1; + } + + newsock->fd = nfd; + newsock->family = s->family; + newsock->local = s->local; + s->family->sockaddr2endpoint(&newsock->remote, &sin); + + return 0; +} static ssize_t __ip_recvfrom_ts(socket_t *s, void *buf, size_t len, endpoint_t *ep, struct timeval *tv) { ssize_t ret; struct sockaddr_storage sin; @@ -619,6 +649,8 @@ int open_socket(socket_t *r, int type, unsigned int port, const sockaddr_t *sa) nonblock(r->fd); reuseaddr(r->fd); + if (r->family->af == AF_INET6) + ipv6only(r->fd, 1); if (port > 0xffff) { __C_DBG("open socket fail, port=%d > 0xfffffd", port); diff --git a/daemon/socket.h b/daemon/socket.h index 5c57fa5a5..7a010d849 100644 --- a/daemon/socket.h +++ b/daemon/socket.h @@ -64,6 +64,8 @@ struct socket_family { int (*addrport2sockaddr)(void *, const sockaddr_t *, unsigned int); int (*bind)(socket_t *, unsigned int, const sockaddr_t *); int (*connect)(socket_t *, const endpoint_t *); + int (*listen)(socket_t *, int); + int (*accept)(socket_t *, socket_t *); int (*timestamping)(socket_t *); ssize_t (*recvfrom)(socket_t *, void *, size_t, endpoint_t *); ssize_t (*recvfrom_ts)(socket_t *, void *, size_t, endpoint_t *, struct timeval *); diff --git a/daemon/streambuf.c b/daemon/streambuf.c index 24a7c241d..c7da2dfc1 100644 --- a/daemon/streambuf.c +++ b/daemon/streambuf.c @@ -13,12 +13,15 @@ + + struct streambuf *streambuf_new(struct poller *p, int fd) { struct streambuf *b; b = malloc(sizeof(*b)); ZERO(*b); + mutex_init(&b->lock); b->buf = g_string_new(""); b->fd = fd; b->poller = p; @@ -38,6 +41,8 @@ int streambuf_writeable(struct streambuf *b) { int ret; unsigned int out; + mutex_lock(&b->lock); + for (;;) { if (!b->buf->len) break; @@ -48,8 +53,10 @@ int streambuf_writeable(struct streambuf *b) { if (ret < 0) { if (errno == EINTR) continue; - if (errno != EAGAIN && errno != EWOULDBLOCK) + if (errno != EAGAIN && errno != EWOULDBLOCK) { + mutex_unlock(&b->lock); return -1; + } ret = 0; } @@ -64,6 +71,7 @@ int streambuf_writeable(struct streambuf *b) { } } + mutex_unlock(&b->lock); return 0; } @@ -71,16 +79,24 @@ int streambuf_readable(struct streambuf *b) { int ret; char buf[1024]; + mutex_lock(&b->lock); + for (;;) { ret = read(b->fd, buf, 1024); - if (ret == 0) - return -1; + if (ret == 0) { + // don't discard already read data in the buffer + b->eof = 1; + ret = b->buf->len ? -2 : -1; + mutex_unlock(&b->lock); + return ret; + } if (ret < 0) { if (errno == EINTR) continue; if (errno == EAGAIN || errno == EWOULDBLOCK) break; + mutex_unlock(&b->lock); return -1; } @@ -88,15 +104,18 @@ int streambuf_readable(struct streambuf *b) { b->active = poller_now; } + mutex_unlock(&b->lock); return 0; } char *streambuf_getline(struct streambuf *b) { char *p; - int len; + int len, to_del; char *s = NULL; + mutex_lock(&b->lock); + for (;;) { if (s) { free(s); @@ -104,19 +123,29 @@ char *streambuf_getline(struct streambuf *b) { } p = memchr(b->buf->str, '\n', b->buf->len); - if (!p) - return NULL; - - len = p - b->buf->str; - if (len == 0) { - g_string_erase(b->buf, 0, 1); - continue; + if (!p) { + if (b->eof) { + // use entire string + len = b->buf->len; + to_del = len; + } + else + break; + } + else { + len = p - b->buf->str; + to_del = len + 1; + if (len == 0) { + // blank line, skip it + g_string_erase(b->buf, 0, 1); + continue; + } } s = malloc(len + 1); memcpy(s, b->buf->str, len); s[len] = '\0'; - g_string_erase(b->buf, 0, len + 1); + g_string_erase(b->buf, 0, to_del); if (s[--len] == '\r') { if (len == 0) @@ -127,6 +156,7 @@ char *streambuf_getline(struct streambuf *b) { break; } + mutex_unlock(&b->lock); return s; } @@ -157,6 +187,8 @@ void streambuf_write(struct streambuf *b, const char *s, unsigned int len) { unsigned int out; int ret; + mutex_lock(&b->lock); + while (len && !poller_isblocked(b->poller, b->fd)) { out = (len > 1024) ? 1024 : len; ret = write(b->fd, s, out); @@ -183,4 +215,6 @@ void streambuf_write(struct streambuf *b, const char *s, unsigned int len) { poller_error(b->poller, b->fd); else if (len) g_string_append_len(b->buf, s, len); + + mutex_unlock(&b->lock); } diff --git a/daemon/streambuf.h b/daemon/streambuf.h index a7f50ef26..0b79d95e2 100644 --- a/daemon/streambuf.h +++ b/daemon/streambuf.h @@ -10,6 +10,7 @@ #include "compat.h" #include "str.h" +#include "aux.h" @@ -18,10 +19,12 @@ struct poller; struct streambuf { + mutex_t lock; GString *buf; int fd; struct poller *poller; time_t active; + int eof; }; diff --git a/daemon/tcp_listener.c b/daemon/tcp_listener.c new file mode 100644 index 000000000..c7fd6a155 --- /dev/null +++ b/daemon/tcp_listener.c @@ -0,0 +1,227 @@ +#include "tcp_listener.h" + +#include + +#include "poller.h" +#include "obj.h" +#include "socket.h" +#include "aux.h" +#include "log.h" +#include "streambuf.h" + +struct tcp_listener_callback { + struct obj obj; + tcp_listener_callback_t func; + socket_t *ul; + struct obj *p; +}; +struct streambuf_callback { + struct obj obj; + streambuf_callback_t newconn_func; + streambuf_callback_t newdata_func; + streambuf_callback_t closed_func; + streambuf_callback_t timer_func; + struct streambuf_listener *listener; + struct obj *parent; +}; + +static void tcp_listener_incoming(int fd, void *p, uintptr_t x) { + struct tcp_listener_callback *cb = p; + int ret; + char addr[64]; + socket_t *listener; + socket_t newsock; + + listener = cb->ul; + + for (;;) { + ret = listener->family->accept(listener, &newsock); + if (ret == -1) { + if (errno == EINTR) + continue; + if (errno != EWOULDBLOCK && errno != EAGAIN) + ilog(LOG_WARNING, "Error accepting TCP connection: %s", strerror(errno)); + return; + } + nonblock(newsock.fd); + + endpoint_print(&newsock.remote, addr, sizeof(addr)); + + cb->func(cb->p, &newsock, addr, listener); + } +} + +static void tcp_listener_closed(int fd, void *p, uintptr_t u) { + abort(); +} + +int tcp_listener_init(socket_t *sock, struct poller *p, const endpoint_t *ep, + tcp_listener_callback_t func, struct obj *obj) +{ + struct poller_item i; + struct tcp_listener_callback *cb; + + cb = obj_alloc("tcp_listener_callback", sizeof(*cb), NULL); + cb->func = func; + cb->p = obj_get_o(obj); + cb->ul = sock; + + if (open_socket(sock, SOCK_STREAM, ep->port, &ep->address)) + goto fail; + if (sock->family->listen(sock, 5)) + goto fail; + + ZERO(i); + i.fd = sock->fd; + i.closed = tcp_listener_closed; + i.readable = tcp_listener_incoming; + i.obj = &cb->obj; + if (poller_add_item(p, &i)) + goto fail; + + return 0; + +fail: + close_socket(sock); + obj_put_o(obj); + obj_put(cb); + return -1; +} + +static void streambuf_stream_free(void *p) { + struct streambuf_stream *s = p; + close_socket(&s->sock); + streambuf_destroy(s->inbuf); + streambuf_destroy(s->outbuf); + obj_put(s->cb); + obj_put_o(s->parent); + free(s->addr); +} + +static void streambuf_stream_closed(int fd, void *p, uintptr_t u) { + struct streambuf_stream *s = p; + + if (s->sock.fd == -1) + return; + + s->cb->closed_func(s); + + struct streambuf_listener *l = s->listener; + mutex_lock(&l->lock); + int ret = g_hash_table_remove(l->streams, s); + mutex_unlock(&l->lock); + poller_del_item(s->listener->poller, s->sock.fd); + if (ret) + obj_put(s); +} + +static void streambuf_stream_timer(int fd, void *p, uintptr_t u) { + struct streambuf_stream *s = p; + s->cb->timer_func(s); +} + + +static void streambuf_stream_readable(int fd, void *p, uintptr_t u) { + struct streambuf_stream *s = p; + + int ret = streambuf_readable(s->inbuf); + if (ret == -1) + goto close; + s->cb->newdata_func(s); + if (ret == -2) + goto close; + + return; + +close: + streambuf_stream_closed(fd, s, 0); +} + +static void streambuf_stream_writeable(int fd, void *p, uintptr_t u) { + struct streambuf_stream *s = p; + + if (streambuf_writeable(s->outbuf)) + streambuf_stream_closed(fd, s, 0); +} + + +static void streambuf_listener_newconn(struct obj *p, socket_t *newsock, char *addr, socket_t *listener_sock) { + struct streambuf_callback *cb = (void *) p; + struct streambuf_stream *s; + struct streambuf_listener *listener; + struct poller_item i; + + listener = cb->listener; + + s = obj_alloc0("streambuf_stream", sizeof(*s), streambuf_stream_free); + s->sock = *newsock; + s->inbuf = streambuf_new(listener->poller, newsock->fd); + s->outbuf = streambuf_new(listener->poller, newsock->fd); + s->listener = listener; + s->cb = obj_get(cb); + s->parent = obj_get_o(cb->parent); + s->addr = strdup(addr); + + ZERO(i); + i.fd = newsock->fd; + i.closed = streambuf_stream_closed; + i.readable = streambuf_stream_readable; + i.writeable = streambuf_stream_writeable; + i.timer = streambuf_stream_timer; + i.obj = &s->obj; + + if (poller_add_item(listener->poller, &i)) + goto fail; + + if (cb->newconn_func) + cb->newconn_func(s); + + mutex_lock(&listener->lock); + g_hash_table_insert(listener->streams, s, s); // hand over ref + mutex_unlock(&listener->lock); + + return; + +fail: + obj_put(s); +} + +int streambuf_listener_init(struct streambuf_listener *listener, struct poller *p, const endpoint_t *ep, + streambuf_callback_t newconn_func, + streambuf_callback_t newdata_func, + streambuf_callback_t closed_func, + streambuf_callback_t timer_func, + struct obj *obj) +{ + struct streambuf_callback *cb; + + ZERO(*listener); + + listener->poller = p; + mutex_init(&listener->lock); + listener->streams = g_hash_table_new(g_direct_hash, g_direct_equal); + + cb = obj_alloc("streambuf_callback", sizeof(*cb), NULL); + cb->newconn_func = newconn_func; + cb->newdata_func = newdata_func; + cb->closed_func = closed_func; + cb->timer_func = timer_func; + cb->parent = obj_get_o(obj); + cb->listener = listener; + + if (tcp_listener_init(&listener->listener, p, ep, streambuf_listener_newconn, &cb->obj)) + goto fail; + + return 0; + +fail: + obj_put(cb); + return -1; +} + +void streambuf_stream_close(struct streambuf_stream *s) { + streambuf_stream_closed(s->sock.fd, s, 0); +} +void streambuf_stream_shutdown(struct streambuf_stream *s) { + shutdown(s->sock.fd, SHUT_WR); +} diff --git a/daemon/tcp_listener.h b/daemon/tcp_listener.h new file mode 100644 index 000000000..0bb297a79 --- /dev/null +++ b/daemon/tcp_listener.h @@ -0,0 +1,47 @@ +#ifndef _TCP_LISTENER_H_ +#define _TCP_LISTENER_H_ + +#include "socket.h" +#include "obj.h" + + +struct poller; +struct obj; +struct streambuf_callback; +struct streambuf_stream; + +typedef void (*tcp_listener_callback_t)(struct obj *p, socket_t *sock, char *addr, socket_t *); +typedef void (*streambuf_callback_t)(struct streambuf_stream *); + +struct streambuf_listener { + socket_t listener; + struct poller *poller; + mutex_t lock; + GHashTable *streams; +}; +struct streambuf_stream { + struct obj obj; + socket_t sock; + struct streambuf_listener *listener; + struct streambuf_callback *cb; + struct obj *parent; + char *addr; + struct streambuf *inbuf, + *outbuf; + +}; + +int tcp_listener_init(socket_t *, struct poller *p, const endpoint_t *, tcp_listener_callback_t, struct obj *); + +int streambuf_listener_init(struct streambuf_listener *listener, struct poller *p, const endpoint_t *ep, + streambuf_callback_t newconn_func, + streambuf_callback_t newdata_func, + streambuf_callback_t closed_func, + streambuf_callback_t timer_func, + struct obj *obj); + +void streambuf_stream_close(struct streambuf_stream *); +void streambuf_stream_shutdown(struct streambuf_stream *); + + +#endif diff --git a/daemon/udp_listener.c b/daemon/udp_listener.c index 209038dc4..656df6e70 100644 --- a/daemon/udp_listener.c +++ b/daemon/udp_listener.c @@ -17,7 +17,7 @@ struct udp_listener_callback { struct obj obj; udp_listener_callback_t func; - struct udp_listener *ul; + socket_t *ul; struct obj *p; }; @@ -31,13 +31,11 @@ static void udp_listener_incoming(int fd, void *p, uintptr_t x) { char buf[0x10000]; char addr[64]; str str; - struct udp_listener *ul; socket_t *listener; endpoint_t sin; str.s = buf; - ul = cb->ul; - listener = &ul->sock; + listener = cb->ul; for (;;) { len = socket_recvfrom(listener, buf, sizeof(buf)-1, &sin); @@ -53,11 +51,11 @@ static void udp_listener_incoming(int fd, void *p, uintptr_t x) { endpoint_print(&sin, addr, sizeof(addr)); str.len = len; - cb->func(cb->p, &str, &sin, addr, ul); + cb->func(cb->p, &str, &sin, addr, listener); } } -int udp_listener_init(struct udp_listener *u, struct poller *p, const endpoint_t *ep, +int udp_listener_init(socket_t *sock, struct poller *p, const endpoint_t *ep, udp_listener_callback_t func, struct obj *obj) { struct poller_item i; @@ -66,15 +64,13 @@ int udp_listener_init(struct udp_listener *u, struct poller *p, const endpoint_t cb = obj_alloc("udp_listener_callback", sizeof(*cb), NULL); cb->func = func; cb->p = obj_get_o(obj); - cb->ul = u; + cb->ul = sock; - if (open_socket(&u->sock, SOCK_DGRAM, ep->port, &ep->address)) + if (open_socket(sock, SOCK_DGRAM, ep->port, &ep->address)) goto fail; - ipv6only(u->sock.fd, 1); - ZERO(i); - i.fd = u->sock.fd; + i.fd = sock->fd; i.closed = udp_listener_closed; i.readable = udp_listener_incoming; i.obj = &cb->obj; @@ -84,7 +80,7 @@ int udp_listener_init(struct udp_listener *u, struct poller *p, const endpoint_t return 0; fail: - close_socket(&u->sock); + close_socket(sock); obj_put_o(obj); obj_put(cb); return -1; diff --git a/daemon/udp_listener.h b/daemon/udp_listener.h index d69ef6d82..5aa44c107 100644 --- a/daemon/udp_listener.h +++ b/daemon/udp_listener.h @@ -9,16 +9,9 @@ struct poller; struct obj; -struct udp_listener; -typedef void (*udp_listener_callback_t)(struct obj *p, str *buf, const endpoint_t *ep, char *addr, - struct udp_listener *); +typedef void (*udp_listener_callback_t)(struct obj *p, str *buf, const endpoint_t *ep, char *addr, socket_t *); -struct udp_listener { - socket_t sock; - struct poller *poller; -}; - -int udp_listener_init(struct udp_listener *, struct poller *p, const endpoint_t *, udp_listener_callback_t, struct obj *); +int udp_listener_init(socket_t *, struct poller *p, const endpoint_t *, udp_listener_callback_t, struct obj *); #endif From 2eb01695bbb9d99a9fe6ccdb4d399028d0dc9ca0 Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Fri, 15 Dec 2017 11:22:27 -0500 Subject: [PATCH 36/65] TT#26756 clean up CLI code using streambuf Change-Id: I0e6c264d5cbd569fb35fab3ad2b0a4f6413949b0 --- daemon/cli.c | 464 +++++++++++++++--------------------------- daemon/cli.h | 6 +- daemon/tcp_listener.c | 6 +- 3 files changed, 174 insertions(+), 302 deletions(-) diff --git a/daemon/cli.c b/daemon/cli.c index 8ea48eaa5..0c29ac74e 100644 --- a/daemon/cli.c +++ b/daemon/cli.c @@ -19,6 +19,8 @@ #include "control_ng.h" #include "media_socket.h" #include "cdr.h" +#include "streambuf.h" +#include "tcp_listener.h" #include "rtpengine_config.h" @@ -89,8 +91,7 @@ static void destroy_keyspace_foreign_calls(struct callmaster *m, unsigned int ui destroy_own_foreign_calls(m, CT_FOREIGN_CALL, uint_keyspace_db); } -static void cli_incoming_list_totals(char* buffer, int len, struct callmaster* m, char* replybuffer, const char* outbufend) { - int printlen=0; +static void cli_incoming_list_totals(char* buffer, int len, struct callmaster* m, struct streambuf *replybuffer) { struct timeval avg, calls_dur_iv; u_int64_t num_sessions, min_sess_iv, max_sess_iv; struct request_time offer_iv, answer_iv, delete_iv; @@ -100,34 +101,20 @@ static void cli_incoming_list_totals(char* buffer, int len, struct callmaster* m num_sessions = m->totalstats.total_managed_sess; mutex_unlock(&m->totalstats.total_average_lock); - printlen = snprintf(replybuffer,(outbufend-replybuffer), "\nTotal statistics (does not include current running sessions):\n\n"); - ADJUSTLEN(printlen,outbufend,replybuffer); - printlen = snprintf(replybuffer,(outbufend-replybuffer), " Uptime of rtpengine :%llu seconds\n", (unsigned long long)time(NULL)-m->totalstats.started); - ADJUSTLEN(printlen,outbufend,replybuffer); - printlen = snprintf(replybuffer,(outbufend-replybuffer), " Total managed sessions :"UINT64F"\n", num_sessions); - ADJUSTLEN(printlen,outbufend,replybuffer); - printlen = snprintf(replybuffer,(outbufend-replybuffer), " Total rejected sessions :"UINT64F"\n", atomic64_get(&m->totalstats.total_rejected_sess)); - ADJUSTLEN(printlen,outbufend,replybuffer); - printlen = snprintf(replybuffer,(outbufend-replybuffer), " Total timed-out sessions via TIMEOUT :"UINT64F"\n",atomic64_get(&m->totalstats.total_timeout_sess)); - ADJUSTLEN(printlen,outbufend,replybuffer); - printlen = snprintf(replybuffer,(outbufend-replybuffer), " Total timed-out sessions via SILENT_TIMEOUT :"UINT64F"\n",atomic64_get(&m->totalstats.total_silent_timeout_sess)); - ADJUSTLEN(printlen,outbufend,replybuffer); - printlen = snprintf(replybuffer,(outbufend-replybuffer), " Total timed-out sessions via FINAL_TIMEOUT :"UINT64F"\n",atomic64_get(&m->totalstats.total_final_timeout_sess)); - ADJUSTLEN(printlen,outbufend,replybuffer); - printlen = snprintf(replybuffer,(outbufend-replybuffer), " Total regular terminated sessions :"UINT64F"\n",atomic64_get(&m->totalstats.total_regular_term_sess)); - ADJUSTLEN(printlen,outbufend,replybuffer); - printlen = snprintf(replybuffer,(outbufend-replybuffer), " Total forced terminated sessions :"UINT64F"\n",atomic64_get(&m->totalstats.total_forced_term_sess)); - ADJUSTLEN(printlen,outbufend,replybuffer); - printlen = snprintf(replybuffer,(outbufend-replybuffer), " Total relayed packets :"UINT64F"\n",atomic64_get(&m->totalstats.total_relayed_packets)); - ADJUSTLEN(printlen,outbufend,replybuffer); - printlen = snprintf(replybuffer,(outbufend-replybuffer), " Total relayed packet errors :"UINT64F"\n",atomic64_get(&m->totalstats.total_relayed_errors)); - ADJUSTLEN(printlen,outbufend,replybuffer); - printlen = snprintf(replybuffer,(outbufend-replybuffer), " Total number of streams with no relayed packets :"UINT64F"\n", atomic64_get(&m->totalstats.total_nopacket_relayed_sess)); - ADJUSTLEN(printlen,outbufend,replybuffer); - printlen = snprintf(replybuffer,(outbufend-replybuffer), " Total number of 1-way streams :"UINT64F"\n",atomic64_get(&m->totalstats.total_oneway_stream_sess)); - ADJUSTLEN(printlen,outbufend,replybuffer); - printlen = snprintf(replybuffer,(outbufend-replybuffer), " Average call duration :%ld.%06ld\n\n",avg.tv_sec,avg.tv_usec); - ADJUSTLEN(printlen,outbufend,replybuffer); + streambuf_printf(replybuffer, "\nTotal statistics (does not include current running sessions):\n\n"); + streambuf_printf(replybuffer, " Uptime of rtpengine :%llu seconds\n", (unsigned long long)time(NULL)-m->totalstats.started); + streambuf_printf(replybuffer, " Total managed sessions :"UINT64F"\n", num_sessions); + streambuf_printf(replybuffer, " Total rejected sessions :"UINT64F"\n", atomic64_get(&m->totalstats.total_rejected_sess)); + streambuf_printf(replybuffer, " Total timed-out sessions via TIMEOUT :"UINT64F"\n",atomic64_get(&m->totalstats.total_timeout_sess)); + streambuf_printf(replybuffer, " Total timed-out sessions via SILENT_TIMEOUT :"UINT64F"\n",atomic64_get(&m->totalstats.total_silent_timeout_sess)); + streambuf_printf(replybuffer, " Total timed-out sessions via FINAL_TIMEOUT :"UINT64F"\n",atomic64_get(&m->totalstats.total_final_timeout_sess)); + streambuf_printf(replybuffer, " Total regular terminated sessions :"UINT64F"\n",atomic64_get(&m->totalstats.total_regular_term_sess)); + streambuf_printf(replybuffer, " Total forced terminated sessions :"UINT64F"\n",atomic64_get(&m->totalstats.total_forced_term_sess)); + streambuf_printf(replybuffer, " Total relayed packets :"UINT64F"\n",atomic64_get(&m->totalstats.total_relayed_packets)); + streambuf_printf(replybuffer, " Total relayed packet errors :"UINT64F"\n",atomic64_get(&m->totalstats.total_relayed_errors)); + streambuf_printf(replybuffer, " Total number of streams with no relayed packets :"UINT64F"\n", atomic64_get(&m->totalstats.total_nopacket_relayed_sess)); + streambuf_printf(replybuffer, " Total number of 1-way streams :"UINT64F"\n",atomic64_get(&m->totalstats.total_oneway_stream_sess)); + streambuf_printf(replybuffer, " Average call duration :%ld.%06ld\n\n",avg.tv_sec,avg.tv_usec); mutex_lock(&m->totalstats_lastinterval_lock); calls_dur_iv = m->totalstats_lastinterval.total_calls_duration_interval; @@ -143,49 +130,38 @@ static void cli_incoming_list_totals(char* buffer, int len, struct callmaster* m timeval_divide(&answer_iv.time_avg, &answer_iv.time_avg, answer_iv.count); timeval_divide(&delete_iv.time_avg, &delete_iv.time_avg, delete_iv.count); - printlen = snprintf(replybuffer,(outbufend-replybuffer), "\nGraphite interval statistics (last reported values to graphite):\n"); - ADJUSTLEN(printlen,outbufend,replybuffer); - printlen = snprintf(replybuffer,(outbufend-replybuffer), " Total calls duration :%ld.%06ld\n\n",calls_dur_iv.tv_sec,calls_dur_iv.tv_usec); - ADJUSTLEN(printlen,outbufend,replybuffer); - printlen = snprintf(replybuffer,(outbufend-replybuffer), " Min managed sessions :"UINT64F"\n", min_sess_iv); - ADJUSTLEN(printlen,outbufend,replybuffer); - printlen = snprintf(replybuffer,(outbufend-replybuffer), " Max managed sessions :"UINT64F"\n", max_sess_iv); - ADJUSTLEN(printlen,outbufend,replybuffer); - printlen = snprintf(replybuffer,(outbufend-replybuffer), " Min/Max/Avg offer processing delay :%llu.%06llu/%llu.%06llu/%llu.%06llu sec\n", + streambuf_printf(replybuffer, "\nGraphite interval statistics (last reported values to graphite):\n"); + streambuf_printf(replybuffer, " Total calls duration :%ld.%06ld\n\n",calls_dur_iv.tv_sec,calls_dur_iv.tv_usec); + streambuf_printf(replybuffer, " Min managed sessions :"UINT64F"\n", min_sess_iv); + streambuf_printf(replybuffer, " Max managed sessions :"UINT64F"\n", max_sess_iv); + streambuf_printf(replybuffer, " Min/Max/Avg offer processing delay :%llu.%06llu/%llu.%06llu/%llu.%06llu sec\n", (unsigned long long)offer_iv.time_min.tv_sec,(unsigned long long)offer_iv.time_min.tv_usec, (unsigned long long)offer_iv.time_max.tv_sec,(unsigned long long)offer_iv.time_max.tv_usec, (unsigned long long)offer_iv.time_avg.tv_sec,(unsigned long long)offer_iv.time_avg.tv_usec); - ADJUSTLEN(printlen,outbufend,replybuffer); - printlen = snprintf(replybuffer,(outbufend-replybuffer), " Min/Max/Avg answer processing delay :%llu.%06llu/%llu.%06llu/%llu.%06llu sec\n", + streambuf_printf(replybuffer, " Min/Max/Avg answer processing delay :%llu.%06llu/%llu.%06llu/%llu.%06llu sec\n", (unsigned long long)answer_iv.time_min.tv_sec,(unsigned long long)answer_iv.time_min.tv_usec, (unsigned long long)answer_iv.time_max.tv_sec,(unsigned long long)answer_iv.time_max.tv_usec, (unsigned long long)answer_iv.time_avg.tv_sec,(unsigned long long)answer_iv.time_avg.tv_usec); - ADJUSTLEN(printlen,outbufend,replybuffer); - printlen = snprintf(replybuffer,(outbufend-replybuffer), " Min/Max/Avg delete processing delay :%llu.%06llu/%llu.%06llu/%llu.%06llu sec\n", + streambuf_printf(replybuffer, " Min/Max/Avg delete processing delay :%llu.%06llu/%llu.%06llu/%llu.%06llu sec\n", (unsigned long long)delete_iv.time_min.tv_sec,(unsigned long long)delete_iv.time_min.tv_usec, (unsigned long long)delete_iv.time_max.tv_sec,(unsigned long long)delete_iv.time_max.tv_usec, (unsigned long long)delete_iv.time_avg.tv_sec,(unsigned long long)delete_iv.time_avg.tv_usec); - ADJUSTLEN(printlen,outbufend,replybuffer); - printlen = snprintf(replybuffer,(outbufend-replybuffer), "\n\n"); - ADJUSTLEN(printlen,outbufend,replybuffer); + streambuf_printf(replybuffer, "\n\n"); - printlen = snprintf(replybuffer,(outbufend-replybuffer), "Control statistics:\n\n"); - ADJUSTLEN(printlen,outbufend,replybuffer); - printlen = snprintf(replybuffer,(outbufend-replybuffer), " %20s | %10s | %10s | %10s | %10s | %10s | %10s | %10s | %10s | %10s \n", + streambuf_printf(replybuffer, "Control statistics:\n\n"); + streambuf_printf(replybuffer, " %20s | %10s | %10s | %10s | %10s | %10s | %10s | %10s | %10s | %10s \n", "Proxy", "Offer", "Answer", "Delete", "Ping", "List", "Query", "StartRec", "StopRec", "Errors"); - ADJUSTLEN(printlen,outbufend,replybuffer); mutex_lock(&m->cngs_lock); GList *list = g_hash_table_get_values(m->cngs_hash); if (!list) { - printlen = snprintf(replybuffer,(outbufend-replybuffer), "\n No proxies have yet tried to send data."); - ADJUSTLEN(printlen,outbufend,replybuffer); + streambuf_printf(replybuffer, "\n No proxies have yet tried to send data."); } for (GList *l = list; l; l = l->next) { struct control_ng_stats* cur = l->data; - printlen = snprintf(replybuffer,(outbufend-replybuffer), " %20s | %10u | %10u | %10u | %10u | %10u | %10u | %10u | %10u | %10u \n", + streambuf_printf(replybuffer, " %20s | %10u | %10u | %10u | %10u | %10u | %10u | %10u | %10u | %10u \n", sockaddr_print_buf(&cur->proxy), cur->offer, cur->answer, @@ -196,65 +172,51 @@ static void cli_incoming_list_totals(char* buffer, int len, struct callmaster* m cur->start_recording, cur->stop_recording, cur->errors); - ADJUSTLEN(printlen,outbufend,replybuffer); } - printlen = snprintf(replybuffer,(outbufend-replybuffer), "\n\n"); - ADJUSTLEN(printlen,outbufend,replybuffer); + streambuf_printf(replybuffer, "\n\n"); mutex_unlock(&m->cngs_lock); g_list_free(list); } -static void cli_incoming_list_maxsessions(char* buffer, int len, struct callmaster* m, char* replybuffer, const char* outbufend) { - int printlen=0; - +static void cli_incoming_list_maxsessions(char* buffer, int len, struct callmaster* m, struct streambuf *replybuffer) { /* don't lock anything while reading the value */ - printlen = snprintf(replybuffer,(outbufend-replybuffer), "Maximum sessions configured on rtpengine: %d\n", m->conf.max_sessions); - ADJUSTLEN(printlen,outbufend,replybuffer); + streambuf_printf(replybuffer, "Maximum sessions configured on rtpengine: %d\n", m->conf.max_sessions); return ; } -static void cli_incoming_list_maxopenfiles(char* buffer, int len, struct callmaster* m, char* replybuffer, const char* outbufend) { - int printlen=0; +static void cli_incoming_list_maxopenfiles(char* buffer, int len, struct callmaster* m, struct streambuf *replybuffer) { struct rlimit rlim; pid_t pid = getpid(); if (getrlimit(RLIMIT_NOFILE, &rlim) == -1) { - printlen = snprintf(replybuffer,(outbufend-replybuffer), "Fail getting rtpengine configured limits; cat /proc/%u/limits\n", pid); - ADJUSTLEN(printlen,outbufend,replybuffer); + streambuf_printf(replybuffer, "Fail getting rtpengine configured limits; cat /proc/%u/limits\n", pid); return ; } if (rlim.rlim_cur == RLIM_INFINITY) { - printlen = snprintf(replybuffer,(outbufend-replybuffer), "Maximum open-files configured on rtpengine: infinite; cat /proc/%u/limits\n", pid); - ADJUSTLEN(printlen,outbufend,replybuffer); + streambuf_printf(replybuffer, "Maximum open-files configured on rtpengine: infinite; cat /proc/%u/limits\n", pid); } else { - printlen = snprintf(replybuffer,(outbufend-replybuffer), "Maximum open-files configured on rtpengine: %lld; cat /proc/%u/limits\n", (long long) rlim.rlim_cur, pid); - ADJUSTLEN(printlen,outbufend,replybuffer); + streambuf_printf(replybuffer, "Maximum open-files configured on rtpengine: %lld; cat /proc/%u/limits\n", (long long) rlim.rlim_cur, pid); } return ; } -static void cli_incoming_list_timeout(char* buffer, int len, struct callmaster* m, char* replybuffer, const char* outbufend) { - int printlen=0; - +static void cli_incoming_list_timeout(char* buffer, int len, struct callmaster* m, struct streambuf *replybuffer) { rwlock_lock_r(&m->conf.config_lock); /* don't lock anything while reading the value */ - printlen = snprintf(replybuffer,(outbufend-replybuffer), "TIMEOUT=%u\n", m->conf.timeout); - ADJUSTLEN(printlen,outbufend,replybuffer); - printlen = snprintf(replybuffer,(outbufend-replybuffer), "SILENT_TIMEOUT=%u\n", m->conf.silent_timeout); - ADJUSTLEN(printlen,outbufend,replybuffer); - printlen = snprintf(replybuffer,(outbufend-replybuffer), "FINAL_TIMEOUT=%u\n", m->conf.final_timeout); - ADJUSTLEN(printlen,outbufend,replybuffer); + streambuf_printf(replybuffer, "TIMEOUT=%u\n", m->conf.timeout); + streambuf_printf(replybuffer, "SILENT_TIMEOUT=%u\n", m->conf.silent_timeout); + streambuf_printf(replybuffer, "FINAL_TIMEOUT=%u\n", m->conf.final_timeout); rwlock_unlock_r(&m->conf.config_lock); return ; } -static void cli_incoming_list_callid(char* buffer, int len, struct callmaster* m, char* replybuffer, const char* outbufend) { +static void cli_incoming_list_callid(char* buffer, int len, struct callmaster* m, struct streambuf *replybuffer) { str callid; struct call* c=0; struct call_monologue *ml; @@ -262,14 +224,12 @@ static void cli_incoming_list_callid(char* buffer, int len, struct callmaster* m struct packet_stream *ps; GList *l; GList *k, *o; - int printlen=0; struct timeval tim_result_duration; struct timeval now; char * local_addr; if (len<=1) { - printlen = snprintf(replybuffer,(outbufend-replybuffer), "%s\n", "More parameters required."); - ADJUSTLEN(printlen,outbufend,replybuffer); + streambuf_printf(replybuffer, "%s\n", "More parameters required."); return; } // ++buffer; --len; // one space @@ -278,14 +238,12 @@ static void cli_incoming_list_callid(char* buffer, int len, struct callmaster* m c = call_get(&callid, m); if (!c) { - printlen = snprintf(replybuffer,(outbufend-replybuffer), "\nCall Id not found (%s).\n\n",callid.s); - ADJUSTLEN(printlen,outbufend,replybuffer); + streambuf_printf(replybuffer, "\nCall Id not found (%s).\n\n",callid.s); return; } - printlen = snprintf (replybuffer,(outbufend-replybuffer), "\ncallid: %60s | deletionmark:%4s | created:%12i | proxy:%s | tos:%u | last_signal:%llu | redis_keyspace:%i | foreign:%s\n\n", + streambuf_printf(replybuffer, "\ncallid: %60s | deletionmark:%4s | created:%12i | proxy:%s | tos:%u | last_signal:%llu | redis_keyspace:%i | foreign:%s\n\n", c->callid.s , c->ml_deleted?"yes":"no", (int)c->created.tv_sec, c->created_from, (unsigned int)c->tos, (unsigned long long)c->last_signal, c->redis_hosted_db, IS_FOREIGN_CALL(c)?"yes":"no"); - ADJUSTLEN(printlen,outbufend,replybuffer); for (l = c->monologues.head; l; l = l->next) { ml = l->data; @@ -295,14 +253,13 @@ static void cli_incoming_list_callid(char* buffer, int len, struct callmaster* m now = ml->terminated; } timeval_subtract(&tim_result_duration,&now,&ml->started); - printlen = snprintf(replybuffer,(outbufend-replybuffer), "--- Tag '"STR_FORMAT"' type: %s, callduration " + streambuf_printf(replybuffer, "--- Tag '"STR_FORMAT"' type: %s, callduration " "%ld.%06ld , in dialogue with '"STR_FORMAT"'\n", STR_FMT(&ml->tag), get_tag_type_text(ml->tagtype), tim_result_duration.tv_sec, tim_result_duration.tv_usec, ml->active_dialogue ? ml->active_dialogue->tag.len : 6, ml->active_dialogue ? ml->active_dialogue->tag.s : "(none)"); - ADJUSTLEN(printlen,outbufend,replybuffer); for (k = ml->medias.head; k; k = k->next) { md = k->data; @@ -316,7 +273,7 @@ static void cli_incoming_list_callid(char* buffer, int len, struct callmaster* m local_addr = ps->selected_sfd ? sockaddr_print_buf(&ps->selected_sfd->socket.local.address) : "0.0.0.0"; #if (RE_HAS_MEASUREDELAY) if (!PS_ISSET(ps, RTP) && PS_ISSET(ps, RTCP)) { - printlen = snprintf(replybuffer,(outbufend-replybuffer), "------ Media #%u, %15s:%-5hu <> %15s:%-5hu%s, " + streambuf_printf(replybuffer, "------ Media #%u, %15s:%-5hu <> %15s:%-5hu%s, " ""UINT64F" p, "UINT64F" b, "UINT64F" e, "UINT64F" last_packet\n", md->index, local_addr, (unsigned int) (ps->sfd ? ps->sfd->fd.localport : 0), @@ -327,7 +284,7 @@ static void cli_incoming_list_callid(char* buffer, int len, struct callmaster* m atomic64_get(&ps->stats.errors), atomic64_get(&ps->last_packet)); } else { - printlen = snprintf(replybuffer,(outbufend-replybuffer), "------ Media #%u, %15s:%-5hu <> %15s:%-5hu%s, " + streambuf_printf(replybuffer, "------ Media #%u, %15s:%-5hu <> %15s:%-5hu%s, " ""UINT64F" p, "UINT64F" b, "UINT64F" e, "UINT64F" last_packet, %.9f delay_min, %.9f delay_avg, %.9f delay_max\n", md->index, local_addr, (unsigned int) (ps->sfd ? ps->sfd->fd.localport : 0), @@ -342,7 +299,7 @@ static void cli_incoming_list_callid(char* buffer, int len, struct callmaster* m (double) ps->stats.delay_max / 1000000); } #else - printlen = snprintf(replybuffer,(outbufend-replybuffer), "------ Media #%u, %15s:%-5u <> %15s:%-5u%s, " + streambuf_printf(replybuffer, "------ Media #%u, %15s:%-5u <> %15s:%-5u%s, " ""UINT64F" p, "UINT64F" b, "UINT64F" e, "UINT64F" last_packet\n", md->index, local_addr, (unsigned int) (ps->selected_sfd ? ps->selected_sfd->socket.local.port : 0), @@ -353,19 +310,16 @@ static void cli_incoming_list_callid(char* buffer, int len, struct callmaster* m atomic64_get(&ps->stats.errors), atomic64_get(&ps->last_packet)); #endif - ADJUSTLEN(printlen,outbufend,replybuffer); } } } - printlen = snprintf(replybuffer,(outbufend-replybuffer), "\n"); - ADJUSTLEN(printlen,outbufend,replybuffer); + streambuf_printf(replybuffer, "\n"); rwlock_unlock_w(&c->master_lock); // because of call_get(..) obj_put(c); } -static void cli_incoming_list_sessions(char* buffer, int len, struct callmaster* m, char* replybuffer, const char* outbufend) { - int printlen=0; +static void cli_incoming_list_sessions(char* buffer, int len, struct callmaster* m, struct streambuf *replybuffer) { GHashTableIter iter; gpointer key, value; str *ptrkey; @@ -377,8 +331,7 @@ static void cli_incoming_list_sessions(char* buffer, int len, struct callmaster* static const char* LIST_FOREIGN = "foreign"; if (len<=1) { - printlen = snprintf(replybuffer, outbufend-replybuffer, "%s\n", "More parameters required."); - ADJUSTLEN(printlen,outbufend,replybuffer); + streambuf_printf(replybuffer, "%s\n", "More parameters required."); return; } ++buffer; --len; // one space @@ -386,8 +339,7 @@ static void cli_incoming_list_sessions(char* buffer, int len, struct callmaster* rwlock_lock_r(&m->hashlock); if (g_hash_table_size(m->callhash)==0) { - printlen = snprintf(replybuffer, outbufend-replybuffer, "No sessions on this media relay.\n"); - ADJUSTLEN(printlen,outbufend,replybuffer); + streambuf_printf(replybuffer, "No sessions on this media relay.\n"); rwlock_unlock_r(&m->hashlock); return; } @@ -418,8 +370,7 @@ static void cli_incoming_list_sessions(char* buffer, int len, struct callmaster* break; } - printlen = snprintf(replybuffer, outbufend-replybuffer, "callid: %60s | deletionmark:%4s | created:%12i | proxy:%s | redis_keyspace:%i | foreign:%s\n", ptrkey->s, call->ml_deleted?"yes":"no", (int)call->created.tv_sec, call->created_from, call->redis_hosted_db, IS_FOREIGN_CALL(call)?"yes":"no"); - ADJUSTLEN(printlen,outbufend,replybuffer); + streambuf_printf(replybuffer, "callid: %60s | deletionmark:%4s | created:%12i | proxy:%s | redis_keyspace:%i | foreign:%s\n", ptrkey->s, call->ml_deleted?"yes":"no", (int)call->created.tv_sec, call->created_from, call->redis_hosted_db, IS_FOREIGN_CALL(call)?"yes":"no"); } rwlock_unlock_r(&m->hashlock); @@ -427,24 +378,21 @@ static void cli_incoming_list_sessions(char* buffer, int len, struct callmaster* ; } else if (len>=strlen(LIST_OWN) && strncmp(buffer,LIST_OWN,strlen(LIST_OWN)) == 0) { if (!found_own) { - printlen = snprintf(replybuffer, outbufend-replybuffer, "No own sessions on this media relay.\n"); - ADJUSTLEN(printlen,outbufend,replybuffer); + streambuf_printf(replybuffer, "No own sessions on this media relay.\n"); } } else if (len>=strlen(LIST_FOREIGN) && strncmp(buffer,LIST_FOREIGN,strlen(LIST_FOREIGN)) == 0) { if (!found_foreign) { - printlen = snprintf(replybuffer, outbufend-replybuffer, "No foreign sessions on this media relay.\n"); - ADJUSTLEN(printlen,outbufend,replybuffer); + streambuf_printf(replybuffer, "No foreign sessions on this media relay.\n"); } } else { // list session for callid - cli_incoming_list_callid(buffer, len, m, replybuffer, outbufend); + cli_incoming_list_callid(buffer, len, m, replybuffer); } return; } -static void cli_incoming_set_maxopenfiles(char* buffer, int len, struct callmaster* m, char* replybuffer, const char* outbufend) { - int printlen = 0; +static void cli_incoming_set_maxopenfiles(char* buffer, int len, struct callmaster* m, struct streambuf *replybuffer) { unsigned long open_files_num; str open_files; pid_t pid; @@ -454,8 +402,7 @@ static void cli_incoming_set_maxopenfiles(char* buffer, int len, struct callmast unsigned long min_open_files_num = (1 << 16); if (len <= 1) { - printlen = snprintf(replybuffer,(outbufend-replybuffer), "%s\n", "More parameters required."); - ADJUSTLEN(printlen,outbufend,replybuffer); + streambuf_printf(replybuffer, "%s\n", "More parameters required."); return; } @@ -465,38 +412,31 @@ static void cli_incoming_set_maxopenfiles(char* buffer, int len, struct callmast open_files_num = strtoul(open_files.s, &endptr, 10); if ((errno == ERANGE && (open_files_num == ULONG_MAX)) || (errno != 0 && open_files_num == 0)) { - printlen = snprintf (replybuffer,(outbufend-replybuffer), "Fail setting open_files to %.*s; errno=%d\n", open_files.len, open_files.s, errno); - ADJUSTLEN(printlen,outbufend,replybuffer); + streambuf_printf(replybuffer, "Fail setting open_files to %.*s; errno=%d\n", open_files.len, open_files.s, errno); return; } else if (endptr == open_files.s) { - printlen = snprintf (replybuffer,(outbufend-replybuffer), "Fail setting open_files to %.*s; no digists found\n", open_files.len, open_files.s); - ADJUSTLEN(printlen,outbufend,replybuffer); + streambuf_printf(replybuffer, "Fail setting open_files to %.*s; no digists found\n", open_files.len, open_files.s); return; } else if (open_files_num < min_open_files_num) { - printlen = snprintf (replybuffer,(outbufend-replybuffer), "Fail setting open_files to %lu; can't set it under %lu\n", open_files_num, min_open_files_num); - ADJUSTLEN(printlen,outbufend,replybuffer); + streambuf_printf(replybuffer, "Fail setting open_files to %lu; can't set it under %lu\n", open_files_num, min_open_files_num); return; } else if (rlim(RLIMIT_NOFILE, open_files_num) == -1){ - printlen = snprintf (replybuffer,(outbufend-replybuffer), "Fail setting open_files to %lu; errno = %d\n", open_files_num, errno); - ADJUSTLEN(printlen,outbufend,replybuffer); + streambuf_printf(replybuffer, "Fail setting open_files to %lu; errno = %d\n", open_files_num, errno); return; } else { pid = getpid(); - printlen = snprintf (replybuffer,(outbufend-replybuffer), "Success setting open_files to %lu; cat /proc/%u/limits\n", open_files_num, pid); - ADJUSTLEN(printlen,outbufend,replybuffer); + streambuf_printf(replybuffer, "Success setting open_files to %lu; cat /proc/%u/limits\n", open_files_num, pid); } } -static void cli_incoming_set_maxsessions(char* buffer, int len, struct callmaster* m, char* replybuffer, const char* outbufend) { - int printlen = 0; +static void cli_incoming_set_maxsessions(char* buffer, int len, struct callmaster* m, struct streambuf *replybuffer) { long maxsessions_num; int disabled = -1; str maxsessions; char *endptr; if (len <= 1) { - printlen = snprintf(replybuffer,(outbufend-replybuffer), "%s\n", "More parameters required."); - ADJUSTLEN(printlen,outbufend,replybuffer); + streambuf_printf(replybuffer, "%s\n", "More parameters required."); return; } @@ -506,42 +446,35 @@ static void cli_incoming_set_maxsessions(char* buffer, int len, struct callmaste maxsessions_num = strtol(maxsessions.s, &endptr, 10); if ((errno == ERANGE && (maxsessions_num == LONG_MAX || maxsessions_num == LONG_MIN)) || (errno != 0 && maxsessions_num == 0)) { - printlen = snprintf (replybuffer,(outbufend-replybuffer), "Fail setting maxsessions to %.*s; errno=%d\n", maxsessions.len, maxsessions.s, errno); - ADJUSTLEN(printlen,outbufend,replybuffer); + streambuf_printf(replybuffer, "Fail setting maxsessions to %.*s; errno=%d\n", maxsessions.len, maxsessions.s, errno); return; } else if (endptr == maxsessions.s) { - printlen = snprintf (replybuffer,(outbufend-replybuffer), "Fail setting maxsessions to %.*s; no digists found\n", maxsessions.len, maxsessions.s); - ADJUSTLEN(printlen,outbufend,replybuffer); + streambuf_printf(replybuffer, "Fail setting maxsessions to %.*s; no digists found\n", maxsessions.len, maxsessions.s); return; } else if (maxsessions_num < disabled) { - printlen = snprintf (replybuffer,(outbufend-replybuffer), "Fail setting maxsessions to %ld; either positive or -1 values allowed\n", maxsessions_num); - ADJUSTLEN(printlen,outbufend,replybuffer); + streambuf_printf(replybuffer, "Fail setting maxsessions to %ld; either positive or -1 values allowed\n", maxsessions_num); } else if (maxsessions_num == disabled) { rwlock_lock_w(&m->conf.config_lock); m->conf.max_sessions = maxsessions_num; rwlock_unlock_w(&m->conf.config_lock); - printlen = snprintf (replybuffer,(outbufend-replybuffer), "Success setting maxsessions to %ld; disable feature\n", maxsessions_num); - ADJUSTLEN(printlen,outbufend,replybuffer); + streambuf_printf(replybuffer, "Success setting maxsessions to %ld; disable feature\n", maxsessions_num); } else { rwlock_lock_w(&m->conf.config_lock); m->conf.max_sessions = maxsessions_num; rwlock_unlock_w(&m->conf.config_lock); - printlen = snprintf (replybuffer,(outbufend-replybuffer), "Success setting maxsessions to %ld\n", maxsessions_num); - ADJUSTLEN(printlen,outbufend,replybuffer); + streambuf_printf(replybuffer, "Success setting maxsessions to %ld\n", maxsessions_num); } return; } -static void cli_incoming_set_timeout(char* buffer, int len, struct callmaster* m, char* replybuffer, const char* outbufend, unsigned int *conf_timeout) { - int printlen = 0; +static void cli_incoming_set_timeout(char* buffer, int len, struct callmaster* m, struct streambuf *replybuffer, unsigned int *conf_timeout) { unsigned long timeout_num; str timeout; char *endptr; if (len <= 1) { - printlen = snprintf(replybuffer,(outbufend-replybuffer), "%s\n", "More parameters required."); - ADJUSTLEN(printlen,outbufend,replybuffer); + streambuf_printf(replybuffer, "%s\n", "More parameters required."); return; } @@ -551,26 +484,21 @@ static void cli_incoming_set_timeout(char* buffer, int len, struct callmaster* m timeout_num = strtoul(timeout.s, &endptr, 10); if ((errno == ERANGE && (timeout_num == ULONG_MAX)) || (errno != 0 && timeout_num == 0)) { - printlen = snprintf (replybuffer,(outbufend-replybuffer), "Fail setting timeout to %.*s; errno=%d\n", timeout.len, timeout.s, errno); - ADJUSTLEN(printlen,outbufend,replybuffer); + streambuf_printf(replybuffer, "Fail setting timeout to %.*s; errno=%d\n", timeout.len, timeout.s, errno); return; } else if (endptr == timeout.s) { - printlen = snprintf (replybuffer,(outbufend-replybuffer), "Fail setting timeout to %.*s; no digists found\n", timeout.len, timeout.s); - ADJUSTLEN(printlen,outbufend,replybuffer); + streambuf_printf(replybuffer, "Fail setting timeout to %.*s; no digists found\n", timeout.len, timeout.s); return; } else { /* don't lock anything while writing the value - only this command modifies its value */ rwlock_lock_w(&m->conf.config_lock); *conf_timeout = timeout_num; rwlock_unlock_w(&m->conf.config_lock); - printlen = snprintf (replybuffer,(outbufend-replybuffer), "Success setting timeout to %lu\n", timeout_num); - ADJUSTLEN(printlen,outbufend,replybuffer); + streambuf_printf(replybuffer, "Success setting timeout to %lu\n", timeout_num); } } -static void cli_incoming_list(char* buffer, int len, struct callmaster* m, char* replybuffer, const char* outbufend) { - int printlen=0; - +static void cli_incoming_list(char* buffer, int len, struct callmaster* m, struct streambuf *replybuffer) { static const char* LIST_NUMSESSIONS = "numsessions"; static const char* LIST_SESSIONS = "sessions"; static const char* LIST_TOTALS = "totals"; @@ -579,40 +507,33 @@ static void cli_incoming_list(char* buffer, int len, struct callmaster* m, char* static const char* LIST_TIMEOUT = "timeout"; if (len<=1) { - printlen = snprintf(replybuffer, outbufend-replybuffer, "%s\n", "More parameters required."); - ADJUSTLEN(printlen,outbufend,replybuffer); + streambuf_printf(replybuffer, "%s\n", "More parameters required."); return; } ++buffer; --len; // one space if (len>=strlen(LIST_NUMSESSIONS) && strncmp(buffer,LIST_NUMSESSIONS,strlen(LIST_NUMSESSIONS)) == 0) { rwlock_lock_r(&m->hashlock); - printlen = snprintf(replybuffer, outbufend-replybuffer, "Current sessions own: "UINT64F"\n", g_hash_table_size(m->callhash) - atomic64_get(&m->stats.foreign_sessions)); - ADJUSTLEN(printlen,outbufend,replybuffer); - printlen = snprintf(replybuffer, outbufend-replybuffer, "Current sessions foreign: "UINT64F"\n", atomic64_get(&m->stats.foreign_sessions)); - ADJUSTLEN(printlen,outbufend,replybuffer); - printlen = snprintf(replybuffer, outbufend-replybuffer, "Current sessions total: %i\n", g_hash_table_size(m->callhash)); - ADJUSTLEN(printlen,outbufend,replybuffer); + streambuf_printf(replybuffer, "Current sessions own: "UINT64F"\n", g_hash_table_size(m->callhash) - atomic64_get(&m->stats.foreign_sessions)); + streambuf_printf(replybuffer, "Current sessions foreign: "UINT64F"\n", atomic64_get(&m->stats.foreign_sessions)); + streambuf_printf(replybuffer, "Current sessions total: %i\n", g_hash_table_size(m->callhash)); rwlock_unlock_r(&m->hashlock); } else if (len>=strlen(LIST_SESSIONS) && strncmp(buffer,LIST_SESSIONS,strlen(LIST_SESSIONS)) == 0) { - cli_incoming_list_sessions(buffer+strlen(LIST_SESSIONS), len-strlen(LIST_SESSIONS), m, replybuffer, outbufend); + cli_incoming_list_sessions(buffer+strlen(LIST_SESSIONS), len-strlen(LIST_SESSIONS), m, replybuffer); } else if (len>=strlen(LIST_TOTALS) && strncmp(buffer,LIST_TOTALS,strlen(LIST_TOTALS)) == 0) { - cli_incoming_list_totals(buffer+strlen(LIST_TOTALS), len-strlen(LIST_TOTALS), m, replybuffer, outbufend); + cli_incoming_list_totals(buffer+strlen(LIST_TOTALS), len-strlen(LIST_TOTALS), m, replybuffer); } else if (len>=strlen(LIST_MAX_SESSIONS) && strncmp(buffer,LIST_MAX_SESSIONS,strlen(LIST_MAX_SESSIONS)) == 0) { - cli_incoming_list_maxsessions(buffer+strlen(LIST_MAX_SESSIONS), len-strlen(LIST_MAX_SESSIONS), m, replybuffer, outbufend); + cli_incoming_list_maxsessions(buffer+strlen(LIST_MAX_SESSIONS), len-strlen(LIST_MAX_SESSIONS), m, replybuffer); } else if (len>=strlen(LIST_MAX_OPEN_FILES) && strncmp(buffer,LIST_MAX_OPEN_FILES,strlen(LIST_MAX_OPEN_FILES)) == 0) { - cli_incoming_list_maxopenfiles(buffer+strlen(LIST_MAX_OPEN_FILES), len-strlen(LIST_MAX_OPEN_FILES), m, replybuffer, outbufend); + cli_incoming_list_maxopenfiles(buffer+strlen(LIST_MAX_OPEN_FILES), len-strlen(LIST_MAX_OPEN_FILES), m, replybuffer); } else if (len>=strlen(LIST_TIMEOUT) && strncmp(buffer,LIST_TIMEOUT,strlen(LIST_TIMEOUT)) == 0) { - cli_incoming_list_timeout(buffer+strlen(LIST_TIMEOUT), len-strlen(LIST_TIMEOUT), m, replybuffer, outbufend); + cli_incoming_list_timeout(buffer+strlen(LIST_TIMEOUT), len-strlen(LIST_TIMEOUT), m, replybuffer); } else { - printlen = snprintf(replybuffer, outbufend-replybuffer, "%s:%s\n", "Unknown 'list' command", buffer); - ADJUSTLEN(printlen,outbufend,replybuffer); + streambuf_printf(replybuffer, "%s:%s\n", "Unknown 'list' command", buffer); } } -static void cli_incoming_set(char* buffer, int len, struct callmaster* m, char* replybuffer, const char* outbufend) { - int printlen=0; - +static void cli_incoming_set(char* buffer, int len, struct callmaster* m, struct streambuf *replybuffer) { static const char* SET_MAX_OPEN_FILES = "maxopenfiles"; static const char* SET_MAX_SESSIONS = "maxsessions"; static const char* SET_TIMEOUT = "timeout"; @@ -620,38 +541,34 @@ static void cli_incoming_set(char* buffer, int len, struct callmaster* m, char* static const char* SET_FINAL_TIMEOUT = "finaltimeout"; if (len<=1) { - printlen = snprintf(replybuffer, outbufend-replybuffer, "%s\n", "More parameters required."); - ADJUSTLEN(printlen,outbufend,replybuffer); + streambuf_printf(replybuffer, "%s\n", "More parameters required."); return; } ++buffer; --len; // one space if (len>=strlen(SET_MAX_OPEN_FILES) && strncmp(buffer,SET_MAX_OPEN_FILES,strlen(SET_MAX_OPEN_FILES)) == 0) { - cli_incoming_set_maxopenfiles(buffer+strlen(SET_MAX_OPEN_FILES), len-strlen(SET_MAX_OPEN_FILES), m, replybuffer, outbufend); + cli_incoming_set_maxopenfiles(buffer+strlen(SET_MAX_OPEN_FILES), len-strlen(SET_MAX_OPEN_FILES), m, replybuffer); } else if (len>=strlen(SET_MAX_SESSIONS) && strncmp(buffer,SET_MAX_SESSIONS,strlen(SET_MAX_SESSIONS)) == 0) { - cli_incoming_set_maxsessions(buffer+strlen(SET_MAX_SESSIONS), len-strlen(SET_MAX_SESSIONS), m, replybuffer, outbufend); + cli_incoming_set_maxsessions(buffer+strlen(SET_MAX_SESSIONS), len-strlen(SET_MAX_SESSIONS), m, replybuffer); } else if (len>=strlen(SET_TIMEOUT) && strncmp(buffer,SET_TIMEOUT,strlen(SET_TIMEOUT)) == 0) { - cli_incoming_set_timeout(buffer+strlen(SET_TIMEOUT), len-strlen(SET_TIMEOUT), m, replybuffer, outbufend, &m->conf.timeout); + cli_incoming_set_timeout(buffer+strlen(SET_TIMEOUT), len-strlen(SET_TIMEOUT), m, replybuffer, &m->conf.timeout); } else if (len>=strlen(SET_SILENT_TIMEOUT) && strncmp(buffer,SET_SILENT_TIMEOUT,strlen(SET_SILENT_TIMEOUT)) == 0) { - cli_incoming_set_timeout(buffer+strlen(SET_SILENT_TIMEOUT), len-strlen(SET_SILENT_TIMEOUT), m, replybuffer, outbufend, &m->conf.silent_timeout); + cli_incoming_set_timeout(buffer+strlen(SET_SILENT_TIMEOUT), len-strlen(SET_SILENT_TIMEOUT), m, replybuffer, &m->conf.silent_timeout); } else if (len>=strlen(SET_FINAL_TIMEOUT) && strncmp(buffer,SET_FINAL_TIMEOUT,strlen(SET_FINAL_TIMEOUT)) == 0) { - cli_incoming_set_timeout(buffer+strlen(SET_FINAL_TIMEOUT), len-strlen(SET_FINAL_TIMEOUT), m, replybuffer, outbufend, &m->conf.final_timeout); + cli_incoming_set_timeout(buffer+strlen(SET_FINAL_TIMEOUT), len-strlen(SET_FINAL_TIMEOUT), m, replybuffer, &m->conf.final_timeout); } else { - printlen = snprintf(replybuffer, outbufend-replybuffer, "%s:%s\n", "Unknown 'set' command", buffer); - ADJUSTLEN(printlen,outbufend,replybuffer); + streambuf_printf(replybuffer, "%s:%s\n", "Unknown 'set' command", buffer); } } -static void cli_incoming_terminate(char* buffer, int len, struct callmaster* m, char* replybuffer, const char* outbufend) { +static void cli_incoming_terminate(char* buffer, int len, struct callmaster* m, struct streambuf *replybuffer) { str termparam; struct call* c=0; - int printlen=0; struct call_monologue *ml; GList *i; if (len<=1) { - printlen = snprintf(replybuffer, outbufend-replybuffer, "%s\n", "More parameters required."); - ADJUSTLEN(printlen,outbufend,replybuffer); + streambuf_printf(replybuffer, "%s\n", "More parameters required."); return; } ++buffer; --len; // one space @@ -667,8 +584,7 @@ static void cli_incoming_terminate(char* buffer, int len, struct callmaster* m, // update cli ilog(LOG_INFO,"All calls terminated by operator."); - printlen = snprintf(replybuffer, outbufend-replybuffer, "%s\n", "All calls terminated by operator."); - ADJUSTLEN(printlen,outbufend,replybuffer); + streambuf_printf(replybuffer, "%s\n", "All calls terminated by operator."); return; @@ -679,8 +595,7 @@ static void cli_incoming_terminate(char* buffer, int len, struct callmaster* m, // update cli ilog(LOG_INFO,"All own calls terminated by operator."); - printlen = snprintf(replybuffer, outbufend-replybuffer, "%s\n", "All own calls terminated by operator."); - ADJUSTLEN(printlen,outbufend,replybuffer); + streambuf_printf(replybuffer, "%s\n", "All own calls terminated by operator."); return; @@ -691,8 +606,7 @@ static void cli_incoming_terminate(char* buffer, int len, struct callmaster* m, // update cli ilog(LOG_INFO,"All foreign calls terminated by operator."); - printlen = snprintf(replybuffer, outbufend-replybuffer, "%s\n", "All foreign calls terminated by operator."); - ADJUSTLEN(printlen,outbufend,replybuffer); + streambuf_printf(replybuffer, "%s\n", "All foreign calls terminated by operator."); return; } @@ -701,8 +615,7 @@ static void cli_incoming_terminate(char* buffer, int len, struct callmaster* m, c = call_get(&termparam, m); if (!c) { - printlen = snprintf(replybuffer, outbufend-replybuffer, "\nCall Id not found (%s).\n\n",termparam.s); - ADJUSTLEN(printlen,outbufend,replybuffer); + streambuf_printf(replybuffer, "\nCall Id not found (%s).\n\n",termparam.s); return; } @@ -714,8 +627,7 @@ static void cli_incoming_terminate(char* buffer, int len, struct callmaster* m, } } - printlen = snprintf(replybuffer, outbufend-replybuffer, "\nCall Id (%s) successfully terminated by operator.\n\n",termparam.s); - ADJUSTLEN(printlen,outbufend,replybuffer); + streambuf_printf(replybuffer, "\nCall Id (%s) successfully terminated by operator.\n\n",termparam.s); ilog(LOG_WARN, "Call Id (%s) successfully terminated by operator.",termparam.s); rwlock_unlock_w(&c->master_lock); @@ -724,15 +636,13 @@ static void cli_incoming_terminate(char* buffer, int len, struct callmaster* m, obj_put(c); } -static void cli_incoming_ksadd(char* buffer, int len, struct callmaster* m, char* replybuffer, const char* outbufend) { - int printlen=0; +static void cli_incoming_ksadd(char* buffer, int len, struct callmaster* m, struct streambuf *replybuffer) { unsigned long uint_keyspace_db; str str_keyspace_db; char *endptr; if (len<=1) { - printlen = snprintf(replybuffer, outbufend-replybuffer, "%s\n", "More parameters required."); - ADJUSTLEN(printlen,outbufend,replybuffer); + streambuf_printf(replybuffer, "%s\n", "More parameters required."); return; } ++buffer; --len; // one space @@ -742,33 +652,30 @@ static void cli_incoming_ksadd(char* buffer, int len, struct callmaster* m, char uint_keyspace_db = strtoul(str_keyspace_db.s, &endptr, 10); if ((errno == ERANGE && (uint_keyspace_db == ULONG_MAX)) || (errno != 0 && uint_keyspace_db == 0)) { - printlen = snprintf(replybuffer, outbufend-replybuffer, "Fail adding keyspace %.*s to redis notifications; errono=%d\n", str_keyspace_db.len, str_keyspace_db.s, errno); + streambuf_printf(replybuffer, "Fail adding keyspace %.*s to redis notifications; errono=%d\n", str_keyspace_db.len, str_keyspace_db.s, errno); } else if (endptr == str_keyspace_db.s) { - printlen = snprintf(replybuffer, outbufend-replybuffer, "Fail adding keyspace %.*s to redis notifications; no digists found\n", str_keyspace_db.len, str_keyspace_db.s); + streambuf_printf(replybuffer, "Fail adding keyspace %.*s to redis notifications; no digists found\n", str_keyspace_db.len, str_keyspace_db.s); } else { rwlock_lock_w(&m->conf.config_lock); if (!g_queue_find(m->conf.redis_subscribed_keyspaces, GUINT_TO_POINTER(uint_keyspace_db))) { g_queue_push_tail(m->conf.redis_subscribed_keyspaces, GUINT_TO_POINTER(uint_keyspace_db)); redis_notify_subscribe_action(m, SUBSCRIBE_KEYSPACE, uint_keyspace_db); - printlen = snprintf(replybuffer, outbufend-replybuffer, "Success adding keyspace %lu to redis notifications.\n", uint_keyspace_db); + streambuf_printf(replybuffer, "Success adding keyspace %lu to redis notifications.\n", uint_keyspace_db); } else { - printlen = snprintf(replybuffer, outbufend-replybuffer, "Keyspace %lu is already among redis notifications.\n", uint_keyspace_db); + streambuf_printf(replybuffer, "Keyspace %lu is already among redis notifications.\n", uint_keyspace_db); } rwlock_unlock_w(&m->conf.config_lock); } - ADJUSTLEN(printlen,outbufend,replybuffer); } -static void cli_incoming_ksrm(char* buffer, int len, struct callmaster* m, char* replybuffer, const char* outbufend) { - int printlen = 0; +static void cli_incoming_ksrm(char* buffer, int len, struct callmaster* m, struct streambuf *replybuffer) { GList *l; unsigned long uint_keyspace_db; str str_keyspace_db; char *endptr; if (len <= 1) { - printlen = snprintf(replybuffer, outbufend-replybuffer, "%s\n", "More parameters required."); - ADJUSTLEN(printlen,outbufend,replybuffer); + streambuf_printf(replybuffer, "%s\n", "More parameters required."); return; } ++buffer; --len; // one space @@ -779,90 +686,62 @@ static void cli_incoming_ksrm(char* buffer, int len, struct callmaster* m, char* rwlock_lock_w(&m->conf.config_lock); if ((errno == ERANGE && (uint_keyspace_db == ULONG_MAX)) || (errno != 0 && uint_keyspace_db == 0)) { - printlen = snprintf(replybuffer, outbufend-replybuffer, "Fail removing keyspace %.*s to redis notifications; errono=%d\n", str_keyspace_db.len, str_keyspace_db.s, errno); + streambuf_printf(replybuffer, "Fail removing keyspace %.*s to redis notifications; errono=%d\n", str_keyspace_db.len, str_keyspace_db.s, errno); } else if (endptr == str_keyspace_db.s) { - printlen = snprintf(replybuffer, outbufend-replybuffer, "Fail removing keyspace %.*s to redis notifications; no digists found\n", str_keyspace_db.len, str_keyspace_db.s); + streambuf_printf(replybuffer, "Fail removing keyspace %.*s to redis notifications; no digists found\n", str_keyspace_db.len, str_keyspace_db.s); } else if ((l = g_queue_find(m->conf.redis_subscribed_keyspaces, GUINT_TO_POINTER(uint_keyspace_db)))) { // remove this keyspace redis_notify_subscribe_action(m, UNSUBSCRIBE_KEYSPACE, uint_keyspace_db); g_queue_remove(m->conf.redis_subscribed_keyspaces, l->data); - printlen = snprintf(replybuffer, outbufend-replybuffer, "Successfully unsubscribed from keyspace %lu.\n", uint_keyspace_db); + streambuf_printf(replybuffer, "Successfully unsubscribed from keyspace %lu.\n", uint_keyspace_db); // destroy foreign calls for this keyspace destroy_keyspace_foreign_calls(m, uint_keyspace_db); // update cli - printlen = snprintf(replybuffer, outbufend-replybuffer, "Successfully removed all foreign calls for keyspace %lu.\n", uint_keyspace_db); + streambuf_printf(replybuffer, "Successfully removed all foreign calls for keyspace %lu.\n", uint_keyspace_db); } else { - printlen = snprintf(replybuffer, outbufend-replybuffer, "Keyspace %lu is not among redis notifications.\n", uint_keyspace_db); + streambuf_printf(replybuffer, "Keyspace %lu is not among redis notifications.\n", uint_keyspace_db); } rwlock_unlock_w(&m->conf.config_lock); - ADJUSTLEN(printlen,outbufend,replybuffer); } -static void cli_incoming_kslist(char* buffer, int len, struct callmaster* m, char* replybuffer, const char* outbufend) { - int printlen=0; +static void cli_incoming_kslist(char* buffer, int len, struct callmaster* m, struct streambuf *replybuffer) { GList *l; - printlen = snprintf(replybuffer,(outbufend-replybuffer), "\nSubscribed-on keyspaces:\n"); - ADJUSTLEN(printlen,outbufend,replybuffer); + streambuf_printf(replybuffer, "\nSubscribed-on keyspaces:\n"); rwlock_lock_r(&m->conf.config_lock); for (l = m->conf.redis_subscribed_keyspaces->head; l; l = l->next) { - printlen = snprintf(replybuffer,(outbufend-replybuffer), "%u ", GPOINTER_TO_UINT(l->data)); - ADJUSTLEN(printlen,outbufend,replybuffer); + streambuf_printf(replybuffer, "%u ", GPOINTER_TO_UINT(l->data)); } rwlock_unlock_r(&m->conf.config_lock); - printlen = snprintf(replybuffer, outbufend-replybuffer, "\n"); - ADJUSTLEN(printlen,outbufend,replybuffer); + streambuf_printf(replybuffer, "\n"); +} + +static void cli_incoming(struct streambuf_stream *s) { + ilog(LOG_INFO, "New cli connection from %s", s->addr); } -static void cli_incoming(int fd, void *p, uintptr_t u) { - int nfd; - struct sockaddr_in sin; - struct cli *cli = (void *) p; - socklen_t sinl; - static const int BUFLENGTH = 4096*1024; - char replybuffer[BUFLENGTH]; - char* outbuf = replybuffer; - const char* outbufend = replybuffer+BUFLENGTH; +static void cli_stream_readable(struct streambuf_stream *s) { + struct cli *cli = (void *) s->parent; static const int MAXINPUT = 1024; - char inbuf[MAXINPUT+1]; - int inlen = 0, readbytes = 0; - int rc=0; - - memset(replybuffer, 0, BUFLENGTH); - - mutex_lock(&cli->lock); -next: - sinl = sizeof(sin); - nfd = accept(fd, (struct sockaddr *) &sin, &sinl); - if (nfd == -1) { - if (errno == EAGAIN || errno == EWOULDBLOCK) { - goto cleanup2; + int inlen = 0; + char *inbuf; + + inbuf = streambuf_getline(s->inbuf); + if (!inbuf) { + if (streambuf_bufsize(s->inbuf) > MAXINPUT) { + ilog(LOG_INFO, "Buffer length exceeded in CLI connection from %s", s->addr); + streambuf_stream_close(s); } - ilog(LOG_INFO, "Accept error:%s", strerror(errno)); - goto next; + return; } - ilog(LOG_INFO, "New cli connection from " DF, DP(sin)); - - do { - readbytes = read(nfd, inbuf+inlen, MAXINPUT-inlen); - if (readbytes == -1) { - if (errno == EAGAIN || errno == EWOULDBLOCK) { - ilog(LOG_INFO, "Could currently not read CLI commands. Reason:%s", strerror(errno)); - goto cleanup; - } - ilog(LOG_INFO, "Could currently not read CLI commands. Reason:%s", strerror(errno)); - } - inlen += readbytes; - } while (readbytes > 0 && inlen < sizeof(inbuf)-1); - - inbuf[inlen] = 0; ilog(LOG_INFO, "Got CLI command:%s",inbuf); + inlen = strlen(inbuf); static const char* LIST = "list"; static const char* TERMINATE = "terminate"; @@ -872,72 +751,63 @@ next: static const char* KSLIST = "kslist"; if (strncmp(inbuf,LIST,strlen(LIST)) == 0) { - cli_incoming_list(inbuf+strlen(LIST), inlen-strlen(LIST), cli->callmaster, outbuf, outbufend); + cli_incoming_list(inbuf+strlen(LIST), inlen-strlen(LIST), cli->callmaster, s->outbuf); } else if (strncmp(inbuf,TERMINATE,strlen(TERMINATE)) == 0) { - cli_incoming_terminate(inbuf+strlen(TERMINATE), inlen-strlen(TERMINATE), cli->callmaster, outbuf, outbufend); + cli_incoming_terminate(inbuf+strlen(TERMINATE), inlen-strlen(TERMINATE), cli->callmaster, s->outbuf); } else if (strncmp(inbuf,SET,strlen(SET)) == 0) { - cli_incoming_set(inbuf+strlen(SET), inlen-strlen(SET), cli->callmaster, outbuf, outbufend); + cli_incoming_set(inbuf+strlen(SET), inlen-strlen(SET), cli->callmaster, s->outbuf); } else if (strncmp(inbuf,KSADD,strlen(KSADD)) == 0) { - cli_incoming_ksadd(inbuf+strlen(KSADD), inlen-strlen(KSADD), cli->callmaster, outbuf, outbufend); + cli_incoming_ksadd(inbuf+strlen(KSADD), inlen-strlen(KSADD), cli->callmaster, s->outbuf); } else if (strncmp(inbuf,KSRM,strlen(KSRM)) == 0) { - cli_incoming_ksrm(inbuf+strlen(KSRM), inlen-strlen(KSRM), cli->callmaster, outbuf, outbufend); + cli_incoming_ksrm(inbuf+strlen(KSRM), inlen-strlen(KSRM), cli->callmaster, s->outbuf); } else if (strncmp(inbuf,KSLIST,strlen(KSLIST)) == 0) { - cli_incoming_kslist(inbuf+strlen(KSLIST), inlen-strlen(KSLIST), cli->callmaster, outbuf, outbufend); + cli_incoming_kslist(inbuf+strlen(KSLIST), inlen-strlen(KSLIST), cli->callmaster, s->outbuf); } else { - sprintf(replybuffer, "%s:%s\n", "Unknown or incomplete command:", inbuf); + streambuf_printf(s->outbuf, "%s:%s\n", "Unknown or incomplete command:", inbuf); } - do { - rc += write( nfd, (char *)&replybuffer, strlen(replybuffer) ); - } while (rc < strlen(replybuffer)); - -cleanup: - close(nfd); - /* in case multiple incoming connections exist, read all of them */ - goto next; -cleanup2: - mutex_unlock(&cli->lock); + free(inbuf); + streambuf_stream_shutdown(s); log_info_clear(); } -static void control_closed(int fd, void *p, uintptr_t u) { - abort(); -} - -struct cli *cli_new(struct poller *p, const endpoint_t *ep, struct callmaster *m) { +struct cli *cli_new(struct poller *p, endpoint_t *ep, struct callmaster *m) { struct cli *c; - socket_t sock; - struct poller_item i; if (!p || !m) return NULL; - if (open_socket(&sock, SOCK_STREAM, ep->port, &ep->address)) - return NULL; + c = obj_alloc0("cli", sizeof(*c), NULL); - if (listen(sock.fd, 5)) - goto fail; + if (streambuf_listener_init(&c->listeners[0], p, ep, + cli_incoming, cli_stream_readable, + NULL, + NULL, + &c->obj)) + { + ilog(LOG_ERR, "Failed to open TCP control port: %s", strerror(errno)); + goto fail; + } + if (ipv46_any_convert(ep)) { + if (streambuf_listener_init(&c->listeners[1], p, ep, + cli_incoming, cli_stream_readable, + NULL, + NULL, + &c->obj)) + { + ilog(LOG_ERR, "Failed to open TCP control port: %s", strerror(errno)); + goto fail; + } + } - c = obj_alloc0("cli_udp", sizeof(*c), NULL); - c->sock = sock; c->poller = p; c->callmaster = m; - mutex_init(&c->lock); - - ZERO(i); - i.fd = sock.fd; - i.closed = control_closed; - i.readable = cli_incoming; - i.obj = &c->obj; - if (poller_add_item(p, &i)) - goto fail2; obj_put(c); return c; -fail2: - obj_put(c); fail: - close_socket(&sock); + // XXX streambuf_listener_close ... + obj_put(c); return NULL; } diff --git a/daemon/cli.h b/daemon/cli.h index e5065b4ca..5ce263d4b 100644 --- a/daemon/cli.h +++ b/daemon/cli.h @@ -3,17 +3,17 @@ #include "socket.h" #include "obj.h" +#include "tcp_listener.h" struct cli { struct obj obj; struct callmaster *callmaster; - socket_t sock; struct poller *poller; - mutex_t lock; + struct streambuf_listener listeners[2]; }; -struct cli *cli_new(struct poller *p, const endpoint_t *, struct callmaster *m); +struct cli *cli_new(struct poller *p, endpoint_t *, struct callmaster *m); #endif /* CLI_UDP_H_ */ diff --git a/daemon/tcp_listener.c b/daemon/tcp_listener.c index c7fd6a155..e232f2bb8 100644 --- a/daemon/tcp_listener.c +++ b/daemon/tcp_listener.c @@ -104,7 +104,8 @@ static void streambuf_stream_closed(int fd, void *p, uintptr_t u) { if (s->sock.fd == -1) return; - s->cb->closed_func(s); + if (s->cb->closed_func) + s->cb->closed_func(s); struct streambuf_listener *l = s->listener; mutex_lock(&l->lock); @@ -117,7 +118,8 @@ static void streambuf_stream_closed(int fd, void *p, uintptr_t u) { static void streambuf_stream_timer(int fd, void *p, uintptr_t u) { struct streambuf_stream *s = p; - s->cb->timer_func(s); + if (s->cb->timer_func) + s->cb->timer_func(s); } From e1ce74985f789e0f91b96e9837699332e9ed3fdd Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Mon, 18 Dec 2017 15:14:32 -0500 Subject: [PATCH 37/65] TT#28354 consolidate CLI string handling Change-Id: Icb0734f94d5910427a57c85e31e85782a62b22fe --- daemon/cli.c | 314 +++++++++++++++++++++++++-------------------------- 1 file changed, 154 insertions(+), 160 deletions(-) diff --git a/daemon/cli.c b/daemon/cli.c index 0c29ac74e..25d095175 100644 --- a/daemon/cli.c +++ b/daemon/cli.c @@ -21,10 +21,79 @@ #include "cdr.h" #include "streambuf.h" #include "tcp_listener.h" +#include "str.h" #include "rtpengine_config.h" +typedef void (*cli_handler_func)(str *, struct callmaster *, struct streambuf *); +typedef struct { + const char *cmd; + cli_handler_func handler; +} cli_handler_t; + +static void cli_incoming_list(str *instr, struct callmaster* m, struct streambuf *replybuffer); +static void cli_incoming_set(str *instr, struct callmaster* m, struct streambuf *replybuffer); +static void cli_incoming_terminate(str *instr, struct callmaster* m, struct streambuf *replybuffer); +static void cli_incoming_ksadd(str *instr, struct callmaster* m, struct streambuf *replybuffer); +static void cli_incoming_ksrm(str *instr, struct callmaster* m, struct streambuf *replybuffer); +static void cli_incoming_kslist(str *instr, struct callmaster* m, struct streambuf *replybuffer); + +static void cli_incoming_set_maxopenfiles(str *instr, struct callmaster* m, struct streambuf *replybuffer); +static void cli_incoming_set_maxsessions(str *instr, struct callmaster* m, struct streambuf *replybuffer); +static void cli_incoming_set_timeout(str *instr, struct callmaster* m, struct streambuf *replybuffer); +static void cli_incoming_set_silenttimeout(str *instr, struct callmaster* m, struct streambuf *replybuffer); +static void cli_incoming_set_finaltimeout(str *instr, struct callmaster* m, struct streambuf *replybuffer); + +static void cli_incoming_list_numsessions(str *instr, struct callmaster* m, struct streambuf *replybuffer); +static void cli_incoming_list_maxsessions(str *instr, struct callmaster* m, struct streambuf *replybuffer); +static void cli_incoming_list_maxopenfiles(str *instr, struct callmaster* m, struct streambuf *replybuffer); +static void cli_incoming_list_totals(str *instr, struct callmaster* m, struct streambuf *replybuffer); +static void cli_incoming_list_sessions(str *instr, struct callmaster* m, struct streambuf *replybuffer); +static void cli_incoming_list_timeout(str *instr, struct callmaster* m, struct streambuf *replybuffer); + +static const cli_handler_t cli_top_handlers[] = { + { "list", cli_incoming_list }, + { "terminate", cli_incoming_terminate }, + { "set", cli_incoming_set }, + { "ksadd", cli_incoming_ksadd }, + { "ksrm", cli_incoming_ksrm }, + { "kslist", cli_incoming_kslist }, + { NULL, }, +}; +static const cli_handler_t cli_set_handlers[] = { + { "maxopenfiles", cli_incoming_set_maxopenfiles }, + { "maxsessions", cli_incoming_set_maxsessions }, + { "timeout", cli_incoming_set_timeout }, + { "silenttimeout", cli_incoming_set_silenttimeout }, + { "finaltimeout", cli_incoming_set_finaltimeout }, + { NULL, }, +}; +static const cli_handler_t cli_list_handlers[] = { + { "numsessions", cli_incoming_list_numsessions }, + { "sessions", cli_incoming_list_sessions }, + { "totals", cli_incoming_list_totals }, + { "maxopenfiles", cli_incoming_list_maxopenfiles }, + { "maxsessions", cli_incoming_list_maxsessions }, + { "timeout", cli_incoming_list_timeout }, +}; + + +static void cli_handler_do(const cli_handler_t *handlers, str *instr, struct callmaster *m, + struct streambuf *replybuffer) +{ + const cli_handler_t *h; + + for (h = handlers; h->cmd; h++) { + if (str_shift_cmp(instr, h->cmd)) + continue; + h->handler(instr, m, replybuffer); + return; + } + + streambuf_printf(replybuffer, "%s:%s\n", "Unknown or incomplete command:", instr->s); +} + static void destroy_own_foreign_calls(struct callmaster *m, unsigned int foreign_call, unsigned int uint_keyspace_db) { struct call *c = NULL; struct call_monologue *ml = NULL; @@ -91,7 +160,7 @@ static void destroy_keyspace_foreign_calls(struct callmaster *m, unsigned int ui destroy_own_foreign_calls(m, CT_FOREIGN_CALL, uint_keyspace_db); } -static void cli_incoming_list_totals(char* buffer, int len, struct callmaster* m, struct streambuf *replybuffer) { +static void cli_incoming_list_totals(str *instr, struct callmaster* m, struct streambuf *replybuffer) { struct timeval avg, calls_dur_iv; u_int64_t num_sessions, min_sess_iv, max_sess_iv; struct request_time offer_iv, answer_iv, delete_iv; @@ -178,14 +247,22 @@ static void cli_incoming_list_totals(char* buffer, int len, struct callmaster* m g_list_free(list); } -static void cli_incoming_list_maxsessions(char* buffer, int len, struct callmaster* m, struct streambuf *replybuffer) { +static void cli_incoming_list_numsessions(str *instr, struct callmaster* m, struct streambuf *replybuffer) { + rwlock_lock_r(&m->hashlock); + streambuf_printf(replybuffer, "Current sessions own: "UINT64F"\n", g_hash_table_size(m->callhash) - atomic64_get(&m->stats.foreign_sessions)); + streambuf_printf(replybuffer, "Current sessions foreign: "UINT64F"\n", atomic64_get(&m->stats.foreign_sessions)); + streambuf_printf(replybuffer, "Current sessions total: %i\n", g_hash_table_size(m->callhash)); + rwlock_unlock_r(&m->hashlock); +} + +static void cli_incoming_list_maxsessions(str *instr, struct callmaster* m, struct streambuf *replybuffer) { /* don't lock anything while reading the value */ streambuf_printf(replybuffer, "Maximum sessions configured on rtpengine: %d\n", m->conf.max_sessions); return ; } -static void cli_incoming_list_maxopenfiles(char* buffer, int len, struct callmaster* m, struct streambuf *replybuffer) { +static void cli_incoming_list_maxopenfiles(str *instr, struct callmaster* m, struct streambuf *replybuffer) { struct rlimit rlim; pid_t pid = getpid(); @@ -203,7 +280,7 @@ static void cli_incoming_list_maxopenfiles(char* buffer, int len, struct callmas return ; } -static void cli_incoming_list_timeout(char* buffer, int len, struct callmaster* m, struct streambuf *replybuffer) { +static void cli_incoming_list_timeout(str *instr, struct callmaster* m, struct streambuf *replybuffer) { rwlock_lock_r(&m->conf.config_lock); /* don't lock anything while reading the value */ @@ -216,8 +293,7 @@ static void cli_incoming_list_timeout(char* buffer, int len, struct callmaster* return ; } -static void cli_incoming_list_callid(char* buffer, int len, struct callmaster* m, struct streambuf *replybuffer) { - str callid; +static void cli_incoming_list_callid(str *instr, struct callmaster* m, struct streambuf *replybuffer) { struct call* c=0; struct call_monologue *ml; struct call_media *md; @@ -228,17 +304,15 @@ static void cli_incoming_list_callid(char* buffer, int len, struct callmaster* m struct timeval now; char * local_addr; - if (len<=1) { + if (str_shift(instr, 1)) { streambuf_printf(replybuffer, "%s\n", "More parameters required."); return; } -// ++buffer; --len; // one space - str_init_len(&callid,buffer,len); - c = call_get(&callid, m); + c = call_get(instr, m); if (!c) { - streambuf_printf(replybuffer, "\nCall Id not found (%s).\n\n",callid.s); + streambuf_printf(replybuffer, "\nCall Id not found (%s).\n\n",instr->s); return; } @@ -319,7 +393,7 @@ static void cli_incoming_list_callid(char* buffer, int len, struct callmaster* m obj_put(c); } -static void cli_incoming_list_sessions(char* buffer, int len, struct callmaster* m, struct streambuf *replybuffer) { +static void cli_incoming_list_sessions(str *instr, struct callmaster* m, struct streambuf *replybuffer) { GHashTableIter iter; gpointer key, value; str *ptrkey; @@ -330,11 +404,10 @@ static void cli_incoming_list_sessions(char* buffer, int len, struct callmaster* static const char* LIST_OWN = "own"; static const char* LIST_FOREIGN = "foreign"; - if (len<=1) { + if (str_shift(instr, 1)) { streambuf_printf(replybuffer, "%s\n", "More parameters required."); return; } - ++buffer; --len; // one space rwlock_lock_r(&m->hashlock); @@ -349,17 +422,17 @@ static void cli_incoming_list_sessions(char* buffer, int len, struct callmaster* ptrkey = (str*)key; call = (struct call*)value; - if (len>=strlen(LIST_ALL) && strncmp(buffer,LIST_ALL,strlen(LIST_ALL)) == 0) { + if (str_cmp(instr, LIST_ALL) == 0) { if (!call) { continue; } - } else if (len>=strlen(LIST_OWN) && strncmp(buffer,LIST_OWN,strlen(LIST_OWN)) == 0) { + } else if (str_cmp(instr, LIST_OWN) == 0) { if (!call || IS_FOREIGN_CALL(call)) { continue; } else { found_own = 1; } - } else if (len>=strlen(LIST_FOREIGN) && strncmp(buffer,LIST_FOREIGN,strlen(LIST_FOREIGN)) == 0) { + } else if (str_cmp(instr, LIST_FOREIGN) == 0) { if (!call || !IS_FOREIGN_CALL(call)) { continue; } else { @@ -374,48 +447,44 @@ static void cli_incoming_list_sessions(char* buffer, int len, struct callmaster* } rwlock_unlock_r(&m->hashlock); - if (len>=strlen(LIST_ALL) && strncmp(buffer,LIST_ALL,strlen(LIST_ALL)) == 0) { + if (str_cmp(instr, LIST_ALL) == 0) { ; - } else if (len>=strlen(LIST_OWN) && strncmp(buffer,LIST_OWN,strlen(LIST_OWN)) == 0) { + } else if (str_cmp(instr, LIST_OWN) == 0) { if (!found_own) { streambuf_printf(replybuffer, "No own sessions on this media relay.\n"); } - } else if (len>=strlen(LIST_FOREIGN) && strncmp(buffer,LIST_FOREIGN,strlen(LIST_FOREIGN)) == 0) { + } else if (str_cmp(instr, LIST_FOREIGN) == 0) { if (!found_foreign) { streambuf_printf(replybuffer, "No foreign sessions on this media relay.\n"); } } else { // list session for callid - cli_incoming_list_callid(buffer, len, m, replybuffer); + cli_incoming_list_callid(instr, m, replybuffer); } return; } -static void cli_incoming_set_maxopenfiles(char* buffer, int len, struct callmaster* m, struct streambuf *replybuffer) { +static void cli_incoming_set_maxopenfiles(str *instr, struct callmaster* m, struct streambuf *replybuffer) { unsigned long open_files_num; - str open_files; pid_t pid; char *endptr; // limit the minimum number of open files to avoid rtpengine freeze for low open_files_num values unsigned long min_open_files_num = (1 << 16); - if (len <= 1) { + if (str_shift(instr, 1)) { streambuf_printf(replybuffer, "%s\n", "More parameters required."); return; } - ++buffer; --len; // one space - open_files.s = buffer; - open_files.len = len; - open_files_num = strtoul(open_files.s, &endptr, 10); + open_files_num = strtoul(instr->s, &endptr, 10); if ((errno == ERANGE && (open_files_num == ULONG_MAX)) || (errno != 0 && open_files_num == 0)) { - streambuf_printf(replybuffer, "Fail setting open_files to %.*s; errno=%d\n", open_files.len, open_files.s, errno); + streambuf_printf(replybuffer, "Fail setting open_files to %s; errno=%d\n", instr->s, errno); return; - } else if (endptr == open_files.s) { - streambuf_printf(replybuffer, "Fail setting open_files to %.*s; no digists found\n", open_files.len, open_files.s); + } else if (endptr == instr->s) { + streambuf_printf(replybuffer, "Fail setting open_files to %s; no digists found\n", instr->s); return; } else if (open_files_num < min_open_files_num) { streambuf_printf(replybuffer, "Fail setting open_files to %lu; can't set it under %lu\n", open_files_num, min_open_files_num); @@ -429,27 +498,23 @@ static void cli_incoming_set_maxopenfiles(char* buffer, int len, struct callmast } } -static void cli_incoming_set_maxsessions(char* buffer, int len, struct callmaster* m, struct streambuf *replybuffer) { +static void cli_incoming_set_maxsessions(str *instr, struct callmaster* m, struct streambuf *replybuffer) { long maxsessions_num; int disabled = -1; - str maxsessions; char *endptr; - if (len <= 1) { + if (str_shift(instr, 1)) { streambuf_printf(replybuffer, "%s\n", "More parameters required."); return; } - ++buffer; --len; // one space - maxsessions.s = buffer; - maxsessions.len = len; - maxsessions_num = strtol(maxsessions.s, &endptr, 10); + maxsessions_num = strtol(instr->s, &endptr, 10); if ((errno == ERANGE && (maxsessions_num == LONG_MAX || maxsessions_num == LONG_MIN)) || (errno != 0 && maxsessions_num == 0)) { - streambuf_printf(replybuffer, "Fail setting maxsessions to %.*s; errno=%d\n", maxsessions.len, maxsessions.s, errno); + streambuf_printf(replybuffer, "Fail setting maxsessions to %s; errno=%d\n", instr->s, errno); return; - } else if (endptr == maxsessions.s) { - streambuf_printf(replybuffer, "Fail setting maxsessions to %.*s; no digists found\n", maxsessions.len, maxsessions.s); + } else if (endptr == instr->s) { + streambuf_printf(replybuffer, "Fail setting maxsessions to %s; no digists found\n", instr->s); return; } else if (maxsessions_num < disabled) { streambuf_printf(replybuffer, "Fail setting maxsessions to %ld; either positive or -1 values allowed\n", maxsessions_num); @@ -468,26 +533,22 @@ static void cli_incoming_set_maxsessions(char* buffer, int len, struct callmaste return; } -static void cli_incoming_set_timeout(char* buffer, int len, struct callmaster* m, struct streambuf *replybuffer, unsigned int *conf_timeout) { +static void cli_incoming_set_gentimeout(str *instr, struct callmaster* m, struct streambuf *replybuffer, unsigned int *conf_timeout) { unsigned long timeout_num; - str timeout; char *endptr; - if (len <= 1) { + if (str_shift(instr, 1)) { streambuf_printf(replybuffer, "%s\n", "More parameters required."); return; } - ++buffer; --len; // one space - timeout.s = buffer; - timeout.len = len; - timeout_num = strtoul(timeout.s, &endptr, 10); + timeout_num = strtoul(instr->s, &endptr, 10); if ((errno == ERANGE && (timeout_num == ULONG_MAX)) || (errno != 0 && timeout_num == 0)) { - streambuf_printf(replybuffer, "Fail setting timeout to %.*s; errno=%d\n", timeout.len, timeout.s, errno); + streambuf_printf(replybuffer, "Fail setting timeout to %s; errno=%d\n", instr->s, errno); return; - } else if (endptr == timeout.s) { - streambuf_printf(replybuffer, "Fail setting timeout to %.*s; no digists found\n", timeout.len, timeout.s); + } else if (endptr == instr->s) { + streambuf_printf(replybuffer, "Fail setting timeout to %s; no digists found\n", instr->s); return; } else { /* don't lock anything while writing the value - only this command modifies its value */ @@ -498,84 +559,46 @@ static void cli_incoming_set_timeout(char* buffer, int len, struct callmaster* m } } -static void cli_incoming_list(char* buffer, int len, struct callmaster* m, struct streambuf *replybuffer) { - static const char* LIST_NUMSESSIONS = "numsessions"; - static const char* LIST_SESSIONS = "sessions"; - static const char* LIST_TOTALS = "totals"; - static const char* LIST_MAX_OPEN_FILES = "maxopenfiles"; - static const char* LIST_MAX_SESSIONS = "maxsessions"; - static const char* LIST_TIMEOUT = "timeout"; +static void cli_incoming_set_timeout(str *instr, struct callmaster* m, struct streambuf *replybuffer) { + cli_incoming_set_gentimeout(instr, m, replybuffer, &m->conf.timeout); +} +static void cli_incoming_set_silenttimeout(str *instr, struct callmaster* m, struct streambuf *replybuffer) { + cli_incoming_set_gentimeout(instr, m, replybuffer, &m->conf.silent_timeout); +} +static void cli_incoming_set_finaltimeout(str *instr, struct callmaster* m, struct streambuf *replybuffer) { + cli_incoming_set_gentimeout(instr, m, replybuffer, &m->conf.final_timeout); +} - if (len<=1) { +static void cli_incoming_list(str *instr, struct callmaster* m, struct streambuf *replybuffer) { + if (str_shift(instr, 1)) { streambuf_printf(replybuffer, "%s\n", "More parameters required."); return; } - ++buffer; --len; // one space - if (len>=strlen(LIST_NUMSESSIONS) && strncmp(buffer,LIST_NUMSESSIONS,strlen(LIST_NUMSESSIONS)) == 0) { - rwlock_lock_r(&m->hashlock); - streambuf_printf(replybuffer, "Current sessions own: "UINT64F"\n", g_hash_table_size(m->callhash) - atomic64_get(&m->stats.foreign_sessions)); - streambuf_printf(replybuffer, "Current sessions foreign: "UINT64F"\n", atomic64_get(&m->stats.foreign_sessions)); - streambuf_printf(replybuffer, "Current sessions total: %i\n", g_hash_table_size(m->callhash)); - rwlock_unlock_r(&m->hashlock); - } else if (len>=strlen(LIST_SESSIONS) && strncmp(buffer,LIST_SESSIONS,strlen(LIST_SESSIONS)) == 0) { - cli_incoming_list_sessions(buffer+strlen(LIST_SESSIONS), len-strlen(LIST_SESSIONS), m, replybuffer); - } else if (len>=strlen(LIST_TOTALS) && strncmp(buffer,LIST_TOTALS,strlen(LIST_TOTALS)) == 0) { - cli_incoming_list_totals(buffer+strlen(LIST_TOTALS), len-strlen(LIST_TOTALS), m, replybuffer); - } else if (len>=strlen(LIST_MAX_SESSIONS) && strncmp(buffer,LIST_MAX_SESSIONS,strlen(LIST_MAX_SESSIONS)) == 0) { - cli_incoming_list_maxsessions(buffer+strlen(LIST_MAX_SESSIONS), len-strlen(LIST_MAX_SESSIONS), m, replybuffer); - } else if (len>=strlen(LIST_MAX_OPEN_FILES) && strncmp(buffer,LIST_MAX_OPEN_FILES,strlen(LIST_MAX_OPEN_FILES)) == 0) { - cli_incoming_list_maxopenfiles(buffer+strlen(LIST_MAX_OPEN_FILES), len-strlen(LIST_MAX_OPEN_FILES), m, replybuffer); - } else if (len>=strlen(LIST_TIMEOUT) && strncmp(buffer,LIST_TIMEOUT,strlen(LIST_TIMEOUT)) == 0) { - cli_incoming_list_timeout(buffer+strlen(LIST_TIMEOUT), len-strlen(LIST_TIMEOUT), m, replybuffer); - } else { - streambuf_printf(replybuffer, "%s:%s\n", "Unknown 'list' command", buffer); - } + cli_handler_do(cli_list_handlers, instr, m, replybuffer); } -static void cli_incoming_set(char* buffer, int len, struct callmaster* m, struct streambuf *replybuffer) { - static const char* SET_MAX_OPEN_FILES = "maxopenfiles"; - static const char* SET_MAX_SESSIONS = "maxsessions"; - static const char* SET_TIMEOUT = "timeout"; - static const char* SET_SILENT_TIMEOUT = "silenttimeout"; - static const char* SET_FINAL_TIMEOUT = "finaltimeout"; - - if (len<=1) { +static void cli_incoming_set(str *instr, struct callmaster* m, struct streambuf *replybuffer) { + if (str_shift(instr, 1)) { streambuf_printf(replybuffer, "%s\n", "More parameters required."); return; } - ++buffer; --len; // one space - - if (len>=strlen(SET_MAX_OPEN_FILES) && strncmp(buffer,SET_MAX_OPEN_FILES,strlen(SET_MAX_OPEN_FILES)) == 0) { - cli_incoming_set_maxopenfiles(buffer+strlen(SET_MAX_OPEN_FILES), len-strlen(SET_MAX_OPEN_FILES), m, replybuffer); - } else if (len>=strlen(SET_MAX_SESSIONS) && strncmp(buffer,SET_MAX_SESSIONS,strlen(SET_MAX_SESSIONS)) == 0) { - cli_incoming_set_maxsessions(buffer+strlen(SET_MAX_SESSIONS), len-strlen(SET_MAX_SESSIONS), m, replybuffer); - } else if (len>=strlen(SET_TIMEOUT) && strncmp(buffer,SET_TIMEOUT,strlen(SET_TIMEOUT)) == 0) { - cli_incoming_set_timeout(buffer+strlen(SET_TIMEOUT), len-strlen(SET_TIMEOUT), m, replybuffer, &m->conf.timeout); - } else if (len>=strlen(SET_SILENT_TIMEOUT) && strncmp(buffer,SET_SILENT_TIMEOUT,strlen(SET_SILENT_TIMEOUT)) == 0) { - cli_incoming_set_timeout(buffer+strlen(SET_SILENT_TIMEOUT), len-strlen(SET_SILENT_TIMEOUT), m, replybuffer, &m->conf.silent_timeout); - } else if (len>=strlen(SET_FINAL_TIMEOUT) && strncmp(buffer,SET_FINAL_TIMEOUT,strlen(SET_FINAL_TIMEOUT)) == 0) { - cli_incoming_set_timeout(buffer+strlen(SET_FINAL_TIMEOUT), len-strlen(SET_FINAL_TIMEOUT), m, replybuffer, &m->conf.final_timeout); - } else { - streambuf_printf(replybuffer, "%s:%s\n", "Unknown 'set' command", buffer); - } + + cli_handler_do(cli_set_handlers, instr, m, replybuffer); } -static void cli_incoming_terminate(char* buffer, int len, struct callmaster* m, struct streambuf *replybuffer) { - str termparam; +static void cli_incoming_terminate(str *instr, struct callmaster* m, struct streambuf *replybuffer) { struct call* c=0; struct call_monologue *ml; GList *i; - if (len<=1) { + if (str_shift(instr, 1)) { streambuf_printf(replybuffer, "%s\n", "More parameters required."); return; } - ++buffer; --len; // one space - str_init_len(&termparam,buffer,len); // --- terminate all calls - if (!str_memcmp(&termparam,"all")) { + if (!str_memcmp(instr,"all")) { // destroy own calls destroy_all_own_calls(m); @@ -589,7 +612,7 @@ static void cli_incoming_terminate(char* buffer, int len, struct callmaster* m, return; // --- terminate own calls - } else if (!str_memcmp(&termparam,"own")) { + } else if (!str_memcmp(instr,"own")) { // destroy own calls destroy_all_own_calls(m); @@ -600,7 +623,7 @@ static void cli_incoming_terminate(char* buffer, int len, struct callmaster* m, return; // --- terminate foreign calls - } else if (!str_memcmp(&termparam,"foreign")) { + } else if (!str_memcmp(instr,"foreign")) { // destroy foreign calls destroy_all_foreign_calls(m); @@ -612,10 +635,10 @@ static void cli_incoming_terminate(char* buffer, int len, struct callmaster* m, } // --- terminate a dedicated call id - c = call_get(&termparam, m); + c = call_get(instr, m); if (!c) { - streambuf_printf(replybuffer, "\nCall Id not found (%s).\n\n",termparam.s); + streambuf_printf(replybuffer, "\nCall Id not found (%s).\n\n",instr->s); return; } @@ -627,8 +650,8 @@ static void cli_incoming_terminate(char* buffer, int len, struct callmaster* m, } } - streambuf_printf(replybuffer, "\nCall Id (%s) successfully terminated by operator.\n\n",termparam.s); - ilog(LOG_WARN, "Call Id (%s) successfully terminated by operator.",termparam.s); + streambuf_printf(replybuffer, "\nCall Id (%s) successfully terminated by operator.\n\n",instr->s); + ilog(LOG_WARN, "Call Id (%s) successfully terminated by operator.",instr->s); rwlock_unlock_w(&c->master_lock); @@ -636,25 +659,21 @@ static void cli_incoming_terminate(char* buffer, int len, struct callmaster* m, obj_put(c); } -static void cli_incoming_ksadd(char* buffer, int len, struct callmaster* m, struct streambuf *replybuffer) { +static void cli_incoming_ksadd(str *instr, struct callmaster* m, struct streambuf *replybuffer) { unsigned long uint_keyspace_db; - str str_keyspace_db; char *endptr; - if (len<=1) { + if (str_shift(instr, 1)) { streambuf_printf(replybuffer, "%s\n", "More parameters required."); return; } - ++buffer; --len; // one space - str_keyspace_db.s = buffer; - str_keyspace_db.len = len; - uint_keyspace_db = strtoul(str_keyspace_db.s, &endptr, 10); + uint_keyspace_db = strtoul(instr->s, &endptr, 10); if ((errno == ERANGE && (uint_keyspace_db == ULONG_MAX)) || (errno != 0 && uint_keyspace_db == 0)) { - streambuf_printf(replybuffer, "Fail adding keyspace %.*s to redis notifications; errono=%d\n", str_keyspace_db.len, str_keyspace_db.s, errno); - } else if (endptr == str_keyspace_db.s) { - streambuf_printf(replybuffer, "Fail adding keyspace %.*s to redis notifications; no digists found\n", str_keyspace_db.len, str_keyspace_db.s); + streambuf_printf(replybuffer, "Fail adding keyspace %s to redis notifications; errono=%d\n", instr->s, errno); + } else if (endptr == instr->s) { + streambuf_printf(replybuffer, "Fail adding keyspace %s to redis notifications; no digists found\n", instr->s); } else { rwlock_lock_w(&m->conf.config_lock); if (!g_queue_find(m->conf.redis_subscribed_keyspaces, GUINT_TO_POINTER(uint_keyspace_db))) { @@ -668,27 +687,23 @@ static void cli_incoming_ksadd(char* buffer, int len, struct callmaster* m, stru } } -static void cli_incoming_ksrm(char* buffer, int len, struct callmaster* m, struct streambuf *replybuffer) { +static void cli_incoming_ksrm(str *instr, struct callmaster* m, struct streambuf *replybuffer) { GList *l; unsigned long uint_keyspace_db; - str str_keyspace_db; char *endptr; - if (len <= 1) { + if (str_shift(instr, 1)) { streambuf_printf(replybuffer, "%s\n", "More parameters required."); return; } - ++buffer; --len; // one space - str_keyspace_db.s = buffer; - str_keyspace_db.len = len; - uint_keyspace_db = strtoul(str_keyspace_db.s, &endptr, 10); + uint_keyspace_db = strtoul(instr->s, &endptr, 10); rwlock_lock_w(&m->conf.config_lock); if ((errno == ERANGE && (uint_keyspace_db == ULONG_MAX)) || (errno != 0 && uint_keyspace_db == 0)) { - streambuf_printf(replybuffer, "Fail removing keyspace %.*s to redis notifications; errono=%d\n", str_keyspace_db.len, str_keyspace_db.s, errno); - } else if (endptr == str_keyspace_db.s) { - streambuf_printf(replybuffer, "Fail removing keyspace %.*s to redis notifications; no digists found\n", str_keyspace_db.len, str_keyspace_db.s); + streambuf_printf(replybuffer, "Fail removing keyspace %s to redis notifications; errono=%d\n", instr->s, errno); + } else if (endptr == instr->s) { + streambuf_printf(replybuffer, "Fail removing keyspace %s to redis notifications; no digists found\n", instr->s); } else if ((l = g_queue_find(m->conf.redis_subscribed_keyspaces, GUINT_TO_POINTER(uint_keyspace_db)))) { // remove this keyspace redis_notify_subscribe_action(m, UNSUBSCRIBE_KEYSPACE, uint_keyspace_db); @@ -707,7 +722,7 @@ static void cli_incoming_ksrm(char* buffer, int len, struct callmaster* m, struc } -static void cli_incoming_kslist(char* buffer, int len, struct callmaster* m, struct streambuf *replybuffer) { +static void cli_incoming_kslist(str *instr, struct callmaster* m, struct streambuf *replybuffer) { GList *l; streambuf_printf(replybuffer, "\nSubscribed-on keyspaces:\n"); @@ -728,8 +743,8 @@ static void cli_incoming(struct streambuf_stream *s) { static void cli_stream_readable(struct streambuf_stream *s) { struct cli *cli = (void *) s->parent; static const int MAXINPUT = 1024; - int inlen = 0; char *inbuf; + str instr; inbuf = streambuf_getline(s->inbuf); if (!inbuf) { @@ -741,30 +756,9 @@ static void cli_stream_readable(struct streambuf_stream *s) { } ilog(LOG_INFO, "Got CLI command:%s",inbuf); - inlen = strlen(inbuf); - - static const char* LIST = "list"; - static const char* TERMINATE = "terminate"; - static const char* SET = "set"; - static const char* KSADD = "ksadd"; - static const char* KSRM = "ksrm"; - static const char* KSLIST = "kslist"; - - if (strncmp(inbuf,LIST,strlen(LIST)) == 0) { - cli_incoming_list(inbuf+strlen(LIST), inlen-strlen(LIST), cli->callmaster, s->outbuf); - } else if (strncmp(inbuf,TERMINATE,strlen(TERMINATE)) == 0) { - cli_incoming_terminate(inbuf+strlen(TERMINATE), inlen-strlen(TERMINATE), cli->callmaster, s->outbuf); - } else if (strncmp(inbuf,SET,strlen(SET)) == 0) { - cli_incoming_set(inbuf+strlen(SET), inlen-strlen(SET), cli->callmaster, s->outbuf); - } else if (strncmp(inbuf,KSADD,strlen(KSADD)) == 0) { - cli_incoming_ksadd(inbuf+strlen(KSADD), inlen-strlen(KSADD), cli->callmaster, s->outbuf); - } else if (strncmp(inbuf,KSRM,strlen(KSRM)) == 0) { - cli_incoming_ksrm(inbuf+strlen(KSRM), inlen-strlen(KSRM), cli->callmaster, s->outbuf); - } else if (strncmp(inbuf,KSLIST,strlen(KSLIST)) == 0) { - cli_incoming_kslist(inbuf+strlen(KSLIST), inlen-strlen(KSLIST), cli->callmaster, s->outbuf); - } else { - streambuf_printf(s->outbuf, "%s:%s\n", "Unknown or incomplete command:", inbuf); - } + str_init(&instr, inbuf); + + cli_handler_do(cli_top_handlers, &instr, cli->callmaster, s->outbuf); free(inbuf); streambuf_stream_shutdown(s); From b7aeff9a1cffaeaa503f5b3fa671a97fb3e4e182 Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Tue, 19 Dec 2017 11:11:44 -0500 Subject: [PATCH 38/65] TT#24550 implement CLI get/set log level Change-Id: Ifedc8561f08fe75af210346f5032e8d893f2e0d5 --- daemon/cli.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/daemon/cli.c b/daemon/cli.c index 25d095175..ff7beb9f9 100644 --- a/daemon/cli.c +++ b/daemon/cli.c @@ -44,6 +44,7 @@ static void cli_incoming_set_maxsessions(str *instr, struct callmaster* m, struc static void cli_incoming_set_timeout(str *instr, struct callmaster* m, struct streambuf *replybuffer); static void cli_incoming_set_silenttimeout(str *instr, struct callmaster* m, struct streambuf *replybuffer); static void cli_incoming_set_finaltimeout(str *instr, struct callmaster* m, struct streambuf *replybuffer); +static void cli_incoming_set_loglevel(str *instr, struct callmaster* m, struct streambuf *replybuffer); static void cli_incoming_list_numsessions(str *instr, struct callmaster* m, struct streambuf *replybuffer); static void cli_incoming_list_maxsessions(str *instr, struct callmaster* m, struct streambuf *replybuffer); @@ -51,6 +52,7 @@ static void cli_incoming_list_maxopenfiles(str *instr, struct callmaster* m, str static void cli_incoming_list_totals(str *instr, struct callmaster* m, struct streambuf *replybuffer); static void cli_incoming_list_sessions(str *instr, struct callmaster* m, struct streambuf *replybuffer); static void cli_incoming_list_timeout(str *instr, struct callmaster* m, struct streambuf *replybuffer); +static void cli_incoming_list_loglevel(str *instr, struct callmaster* m, struct streambuf *replybuffer); static const cli_handler_t cli_top_handlers[] = { { "list", cli_incoming_list }, @@ -67,6 +69,7 @@ static const cli_handler_t cli_set_handlers[] = { { "timeout", cli_incoming_set_timeout }, { "silenttimeout", cli_incoming_set_silenttimeout }, { "finaltimeout", cli_incoming_set_finaltimeout }, + { "loglevel", cli_incoming_set_loglevel }, { NULL, }, }; static const cli_handler_t cli_list_handlers[] = { @@ -76,6 +79,8 @@ static const cli_handler_t cli_list_handlers[] = { { "maxopenfiles", cli_incoming_list_maxopenfiles }, { "maxsessions", cli_incoming_list_maxsessions }, { "timeout", cli_incoming_list_timeout }, + { "loglevel", cli_incoming_list_loglevel }, + { NULL, }, }; @@ -805,3 +810,25 @@ fail: obj_put(c); return NULL; } + +static void cli_incoming_list_loglevel(str *instr, struct callmaster* m, struct streambuf *replybuffer) { + streambuf_printf(replybuffer, "%i\n", g_atomic_int_get(&log_level)); +} +static void cli_incoming_set_loglevel(str *instr, struct callmaster* m, struct streambuf *replybuffer) { + int nl; + + if (str_shift(instr, 1)) { + streambuf_printf(replybuffer, "%s\n", "More parameters required."); + return; + } + + nl = atoi(instr->s); + if (nl < 1 || nl > 7) { + streambuf_printf(replybuffer, "Invalid log level '%s', must be number between 1 and 7\n", + instr->s); + return; + } + + g_atomic_int_set(&log_level, nl); + streambuf_printf(replybuffer, "Success setting loglevel to %i\n", nl); +} From 7b757ffd8c82a82d7b089a8c26c9af58f10b129c Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Wed, 20 Dec 2017 09:25:31 -0500 Subject: [PATCH 39/65] allow -ip host:port syntax in rtpengine-ctl, and document loglevel cmds Change-Id: I8004e2bd002ceeee56bb9cc974bbeef533001c0d --- utils/rtpengine-ctl | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/utils/rtpengine-ctl b/utils/rtpengine-ctl index 4eccff63f..db6d77487 100755 --- a/utils/rtpengine-ctl +++ b/utils/rtpengine-ctl @@ -22,6 +22,9 @@ for (my $argnum=0; $argnum <= $#ARGV; $argnum++) { die "No argument after -ip\n" unless $argnum+1<=$#ARGV; $argnum = $argnum+1; $ip = $ARGV[$argnum]; + if ($ip =~ s/:(\d)$//) { + $port = $1; + } } elsif ($ARGV[$argnum] eq "-port") { die "No argument after -port\n" unless $argnum+1<=$#ARGV; $argnum = $argnum+1; @@ -64,11 +67,12 @@ $socket->close(); sub showusage { print "\n"; - print " rtpengine-ctl [ -ip -port ] \n"; + print " rtpengine-ctl [ -ip [:] -port ] \n"; print "\n"; print " Supported commands are:\n"; print "\n"; - print " list [ numsessions | maxsessions | maxopenfiles | sessions [ | all | own | foreign ] | totals ]\n"; + print " list [ numsessions | maxsessions | maxopenfiles\n"; + print " | sessions [ | all | own | foreign ] | totals | loglevel ]\n"; print " numsessions : print the number of sessions\n"; print " maxsessions : print the number of allowed sessions\n"; print " maxopenfiles : print the number of allowed open files\n"; @@ -78,6 +82,7 @@ sub showusage { print " sessions foreign : print one-liner foreign sessions information\n"; print " totals : print total statistics\n"; print " timeout : print timeout parameters\n"; + print " loglevel : print current log level\n"; print "\n"; print " terminate [ | all | own | foreign ]\n"; print " : session is immediately terminated\n"; @@ -85,12 +90,14 @@ sub showusage { print " own : terminates own current sessions\n"; print " foreign : terminates foreign current sessions\n"; print "\n"; - print " set [ maxsessions | maxopenfiles | timeout | silent_timeout | final_timeout ]\n"; + print " set [ maxsessions | maxopenfiles | timeout \n"; + print " | silent_timeout | final_timeout | loglevel ]\n"; print " maxsessions : set the max nr of allowed sessions\n"; print " maxopenfiles : set the max nr of allowed open files\n"; print " timeout : set the --timeout parameter \n"; print " silenttimeout : set the --silent-timeout parameter \n"; print " finaltimeout : set the --final-timeout parameter \n"; + print " loglevel : set the log level to new value (1-7)\n"; print "\n"; print " ksadd [ keyspace ]\n"; print " keyspace : subscribe to 'keyspace' database\n"; From 61d828a48f4a56b0a8cde1a92330a226d9fcb8d2 Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Fri, 22 Dec 2017 11:25:23 -0500 Subject: [PATCH 40/65] change str_chr_str() semantics Change-Id: I0fb541215a1bb1a248693a6258e953827258b7ec --- daemon/call_interfaces.c | 3 +-- daemon/sdp.c | 21 +++++++-------------- daemon/stun.c | 3 +-- lib/str.h | 8 ++++---- 4 files changed, 13 insertions(+), 22 deletions(-) diff --git a/daemon/call_interfaces.c b/daemon/call_interfaces.c index 13492005f..277e9b969 100644 --- a/daemon/call_interfaces.c +++ b/daemon/call_interfaces.c @@ -483,8 +483,7 @@ INLINE void str_hyphenate(bencode_item_t *it) { if (!bencode_get_str(it, &s)) return; while (s.len) { - str_chr_str(&s, &s, ' '); - if (!s.s || !s.len) + if (!str_chr_str(&s, &s, ' ')) break; *s.s = '-'; str_shift(&s, 1); diff --git a/daemon/sdp.c b/daemon/sdp.c index ef8fa61ff..54e6ac9ee 100644 --- a/daemon/sdp.c +++ b/daemon/sdp.c @@ -391,8 +391,7 @@ static int parse_attribute_ssrc(struct sdp_attribute *output) { return -1; s->attr = s->attr_str; - str_chr_str(&s->value, &s->attr, ':'); - if (s->value.s) { + if (str_chr_str(&s->value, &s->attr, ':')) { s->attr.len = s->value.s - s->attr.s; str_shift(&s->value, 1); } @@ -471,8 +470,7 @@ static int parse_attribute_crypto(struct sdp_attribute *output) { if (c->lifetime_str.s[0] != '|') goto error; str_shift(&c->lifetime_str, 1); - str_chr_str(&c->mki_str, &c->lifetime_str, '|'); - if (!c->mki_str.s) { + if (!str_chr_str(&c->mki_str, &c->lifetime_str, '|')) { if (str_chr(&c->lifetime_str, ':')) { c->mki_str = c->lifetime_str; c->lifetime_str = STR_NULL; @@ -507,9 +505,8 @@ static int parse_attribute_crypto(struct sdp_attribute *output) { } if (c->mki_str.s) { - str_chr_str(&s, &c->mki_str, ':'); err = "invalid MKI specification"; - if (!s.s) + if (!str_chr_str(&s, &c->mki_str, ':')) goto error; u32 = htonl(strtoul(c->mki_str.s, NULL, 10)); c->mki_len = strtoul(s.s + 1, NULL, 10); @@ -723,16 +720,14 @@ static int parse_attribute_rtpmap(struct sdp_attribute *output) { if (ep == a->payload_type_str.s) return -1; - str_chr_str(&a->clock_rate_str, &a->encoding_str, '/'); - if (!a->clock_rate_str.s) + if (!str_chr_str(&a->clock_rate_str, &a->encoding_str, '/')) return -1; pt->encoding = a->encoding_str; pt->encoding.len -= a->clock_rate_str.len; str_shift(&a->clock_rate_str, 1); - str_chr_str(&pt->encoding_parameters, &a->clock_rate_str, '/'); - if (pt->encoding_parameters.s) { + if (str_chr_str(&pt->encoding_parameters, &a->clock_rate_str, '/')) { a->clock_rate_str.len -= pt->encoding_parameters.len; str_shift(&pt->encoding_parameters, 1); } @@ -751,15 +746,13 @@ static int parse_attribute(struct sdp_attribute *a) { int ret; a->name = a->line_value; - str_chr_str(&a->value, &a->name, ':'); - if (a->value.s) { + if (str_chr_str(&a->value, &a->name, ':')) { a->name.len -= a->value.len; a->value.s++; a->value.len--; a->key = a->name; - str_chr_str(&a->param, &a->value, ' '); - if (a->param.s) { + if (str_chr_str(&a->param, &a->value, ' ')) { a->key.len += 1 + (a->value.len - a->param.len); diff --git a/daemon/stun.c b/daemon/stun.c index a236f0e98..ce4823870 100644 --- a/daemon/stun.c +++ b/daemon/stun.c @@ -437,8 +437,7 @@ static int check_auth(str *msg, struct stun_attrs *attrs, struct call_media *med if (attrs->username.s) { /* request */ ufrag[dst] = attrs->username; - str_chr_str(&ufrag[src], &ufrag[dst], ':'); - if (!ufrag[src].s) + if (!str_chr_str(&ufrag[src], &ufrag[dst], ':')) return -1; ufrag[dst].len -= ufrag[src].len; str_shift(&ufrag[src], 1); diff --git a/lib/str.h b/lib/str.h index 1a02b26bc..ee3318ea7 100644 --- a/lib/str.h +++ b/lib/str.h @@ -35,7 +35,7 @@ INLINE char *str_end(const str *s); /* returns pointer to first occurrence of "c" in s */ INLINE char *str_chr(const str *s, int c); /* sets "out" to point to first occurrence of c in s. adjusts len also */ -INLINE str *str_chr_str(str *out, const str *s, int c); +INLINE char *str_chr_str(str *out, const str *s, int c); /* compares a str to a regular string */ INLINE int str_cmp(const str *a, const char *b); /* compares a str to a non-null-terminated string */ @@ -132,16 +132,16 @@ INLINE int str_shift_cmp(str *s, const char *t) { INLINE char *str_chr(const str *s, int c) { return memchr(s->s, c, s->len); } -INLINE str *str_chr_str(str *out, const str *s, int c) { +INLINE char *str_chr_str(str *out, const str *s, int c) { char *p; p = str_chr(s, c); if (!p) { *out = STR_NULL; - return out; + return NULL; } *out = *s; str_shift(out, p - out->s); - return out; + return out->s; } INLINE int str_cmp_len(const str *a, const char *b, int l) { if (a->len < l) From 1aa9944fe4c98707eaae43155ca3dc2541dddb15 Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Thu, 21 Dec 2017 11:18:08 -0500 Subject: [PATCH 41/65] TT#27550 implement interface round-robin selection Change-Id: Id5cf290cc9d044716b5f55cf416dc40b87f23f24 --- README.md | 117 ++++++++++++++++--------- daemon/aux.h | 3 - daemon/call.c | 62 +++----------- daemon/main.c | 4 + daemon/media_socket.c | 164 +++++++++++++++++++++--------------- daemon/media_socket.h | 7 +- lib/str.h | 2 +- perl/NGCP/Rtpengine/Test.pm | 16 ++-- t/test-interfaces.pl | 55 ++++++++++++ 9 files changed, 260 insertions(+), 170 deletions(-) create mode 100755 t/test-interfaces.pl diff --git a/README.md b/README.md index 32c3804e6..b92bcd470 100644 --- a/README.md +++ b/README.md @@ -228,46 +228,7 @@ The options are described in more detail below. * -i, --interface Specifies a local network interface for RTP. At least one must be given, but multiple can be specified. - The format of the value is `[NAME/]IP[!IP]` with `IP` being either an IPv4 address or an IPv6 address. - - The second IP address after the exclamation point is optional and can be used if the address to advertise - in outgoing SDP bodies should be different from the actual local address. This can be useful in certain - cases, such as your SIP proxy being behind NAT. For example, `--interface=10.65.76.2!192.0.2.4` means - that 10.65.76.2 is the actual local address on the server, but outgoing SDP bodies should advertise - 192.0.2.4 as the address that endpoints should talk to. Note that you may have to escape the exlamation - point from your shell, e.g. using `\!`. - - Giving an interface a name (separated from the address by a slash) is optional; if omitted, the name - `default` is used. Names are useful to create logical interfaces which consist of one or more local - addresses. It is then possible to instruct *rtpengine* to use particular interfaces when processing - an SDP message, to use different local addresses when talking to different endpoints. The most common use - case for this is to bridge between one or more private IP networks and the public internet. - - For example, if clients coming from a private IP network must communicate their RTP with the local - address 10.35.2.75, while clients coming from the public internet must communicate with your other - local address 192.0.2.67, you could create one logical interface `pub` and a second one `priv` by - using `--interface=pub/192.0.2.67 --interface=priv/10.35.2.75`. You can then use the `direction` - option to tell *rtpengine* which local address to use for which endpoints (either `pub` or `priv`). - - If multiple logical interfaces are configured, but the `direction` option isn't given in a - particular call, then the first interface given on the command line will be used. - - It is possible to specify multiple addresses for the same logical interface (the same name). Most - commonly this would be one IPv4 addrsess and one IPv6 address, for example: - `--interface=192.168.63.1 --interface=fe80::800:27ff:fe00:0`. In this example, no interface name - is given, therefore both addresses will be added to a logical interface named `default`. You would use - the `address family` option to tell *rtpengine* which address to use in a particular case. - - It is also possible to have multiple addresses of the same family in a logical network interface. In - this case, the first address (of a particular family) given for an interface will be the primary address - used by *rtpengine* for most purposes. Any additional addresses will be advertised as additional ICE - candidates with increasingly lower priority. This is useful on multi-homed systems and allows endpoints - to choose the best possible path to reach the RTP proxy. If ICE is not being used, then additional - addresses will go unused. - - If you're not using the NG protocol but rather the legacy UDP protocol used by the *rtpproxy* module, - the interfaces must be named `internal` and `external` corresponding to the `i` and `e` flags if you - wish to use network bridging in this mode. + See the section *Interfaces configuration* just below for details. * -l, --listen-tcp, -u, --listen-udp, -n, --listen-ng @@ -591,6 +552,82 @@ A typical command line (enabling both UDP and NG protocols) thus may look like: --listen-udp=127.0.0.1:22222 --listen-ng=127.0.0.1:2223 --tos=184 \ --pidfile=/var/run/rtpengine.pid + +Interfaces configuration +------------------------ + +The command-line options `-i` or `--interface=`, or equivalently the `interface=` config file option, +specifie a local network interfaces for RTP. At least one must be given, but multiple can be specified. +The format of the value is `[NAME/]IP[!IP]` with `IP` being either an IPv4 address or an IPv6 address. + +To configure multiple interfaces using the command-line options, simply present multiple `-i` or +`--interface=` options. When using the config file, only use a single `interface=` line, but specify +multiple values separated by semicolons (e.g. `interface = internal/12.23.34.45;external/23.34.45.54`). + +The second IP address after the exclamation point is optional and can be used if the address to advertise +in outgoing SDP bodies should be different from the actual local address. This can be useful in certain +cases, such as your SIP proxy being behind NAT. For example, `--interface=10.65.76.2!192.0.2.4` means +that 10.65.76.2 is the actual local address on the server, but outgoing SDP bodies should advertise +192.0.2.4 as the address that endpoints should talk to. Note that you may have to escape the exlamation +point from your shell when using command-line options, e.g. using `\!`. + +Giving an interface a name (separated from the address by a slash) is optional; if omitted, the name +`default` is used. Names are useful to create logical interfaces which consist of one or more local +addresses. It is then possible to instruct *rtpengine* to use particular interfaces when processing +an SDP message, to use different local addresses when talking to different endpoints. The most common use +case for this is to bridge between one or more private IP networks and the public internet. + +For example, if clients coming from a private IP network must communicate their RTP with the local +address 10.35.2.75, while clients coming from the public internet must communicate with your other +local address 192.0.2.67, you could create one logical interface `pub` and a second one `priv` by +using `--interface=pub/192.0.2.67 --interface=priv/10.35.2.75`. You can then use the `direction` +option to tell *rtpengine* which local address to use for which endpoints (either `pub` or `priv`). + +If multiple logical interfaces are configured, but the `direction` option isn't given in a +particular call, then the first interface given on the command line will be used. + +It is possible to specify multiple addresses for the same logical interface (the same name). Most +commonly this would be one IPv4 addrsess and one IPv6 address, for example: +`--interface=192.168.63.1 --interface=fe80::800:27ff:fe00:0`. In this example, no interface name +is given, therefore both addresses will be added to a logical interface named `default`. You would use +the `address family` option to tell *rtpengine* which address to use in a particular case. + +It is also possible to have multiple addresses of the same family in a logical network interface. In +this case, the first address (of a particular family) given for an interface will be the primary address +used by *rtpengine* for most purposes. Any additional addresses will be advertised as additional ICE +candidates with increasingly lower priority. This is useful on multi-homed systems and allows endpoints +to choose the best possible path to reach the RTP proxy. If ICE is not being used, then additional +addresses will go unused, even though ports would still get allocated on those interfaces. + +Another option is to give interface names in the format `BASE:SUFFIX`. This allows interfaces to be +used in a round-robin fashion, useful for load-balancing the port ranges of multiple interfaces. +For example, consider the following configuration: +`--interface=pub:1/192.0.2.67 --interface=pub:2/10.35.2.75`. These two interfaces can still be +referenced directly by name (e.g. `direction=pub:1`), but it is now also possible to reference only +the base name (i.e. `direction=pub`). If the base name is used, one of the two interfaces is selected +in a round-robin fashion, and only if the interface actually has enough open ports available. This +makes it possible to effectively increase the number of available media ports across multiple IP +addresses. There is no limit on how many interfaces can share the same base name. + +It is possible to combine the `BASE:SUFFIX` notation with specifying multiple addresses for the same +interface name. An advanced example could be (using config file notation, and omitting actual +network addresses): + +``` +interface = pub:1/IPv4 pub:1/IPv4 pub:1/IPv6 pub:2/IPv4 pub:2/IPv6 pub:3/IPv6 pub:4/IPv4 +``` + +In this example, when `direction=pub` is IPv4 is needed as a primary address, either `pub:1`, `pub:2`, +or `pub:4` might be selected. When `pub:1` is selected, one IPv4 and one IPv6 address will be used +as additional ICE alternatives. For `pub:2`, only one IPv6 is used as ICE alternative, and for `pub:4` +no alternatives would be used. When IPv6 is needed as a primary address, either `pub:1`, `pub:2`, or +`pub:3` might be selected. If at any given time not enough ports are available on any interface, +it will not be selected by the round-robin algorithm. + +If you're not using the NG protocol but rather the legacy UDP protocol used by the *rtpproxy* module, +the interfaces must be named `internal` and `external` corresponding to the `i` and `e` flags if you +wish to use network bridging in this mode. + In-kernel Packet Forwarding --------------------------- diff --git a/daemon/aux.h b/daemon/aux.h index 1b15dfe4c..1fe463c3a 100644 --- a/daemon/aux.h +++ b/daemon/aux.h @@ -60,9 +60,6 @@ G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \ #define NUM_THREAD_BUFS 8 -#define ALGORITHM_DEFAULT "" -#define ALGORITHM_ROUND_ROBIN_CALLS "round-robin-calls" - /*** GLOBALS ***/ extern __thread struct timeval g_now; diff --git a/daemon/call.c b/daemon/call.c index 54a1da980..8e992965a 100644 --- a/daemon/call.c +++ b/daemon/call.c @@ -1381,7 +1381,9 @@ static void __init_interface(struct call_media *media, const str *ifname, int nu goto get; if (!ifname || !ifname->s) return; - if (!str_cmp_str(&media->logical_intf->name, ifname) || !str_cmp(ifname, ALGORITHM_ROUND_ROBIN_CALLS)) + if (!str_cmp_str(&media->logical_intf->name, ifname)) + return; + if (g_hash_table_lookup(media->logical_intf->rr_specs, ifname)) return; get: media->logical_intf = get_logical_interface(ifname, media->desired_family, num_ports); @@ -1471,33 +1473,6 @@ static void __ice_start(struct call_media *media) { ice_agent_init(&media->ice_agent, media); } -static int get_algorithm_num_ports(GQueue *streams, char *algorithm) { - unsigned int algorithm_ports = 0; - struct stream_params *sp; - GList *media_iter; - - if (algorithm == NULL) { - return 0; - } - - for (media_iter = streams->head; media_iter; media_iter = media_iter->next) { - sp = media_iter->data; - - if (!str_cmp(&sp->direction[0], algorithm)) { - algorithm_ports += sp->consecutive_ports; - } - - if (!str_cmp(&sp->direction[1], algorithm)) { - algorithm_ports += sp->consecutive_ports; - } - } - - // XXX only do *=2 for RTP streams? - algorithm_ports *= 2; - - return algorithm_ports; -} - static void __endpoint_loop_protect(struct stream_params *sp, struct call_media *media) { struct intf_address intf_addr; @@ -1529,7 +1504,6 @@ int monologue_offer_answer(struct call_monologue *other_ml, GQueue *streams, GList *media_iter, *ml_media, *other_ml_media; struct call_media *media, *other_media; unsigned int num_ports; - unsigned int rr_calls_ports; struct call_monologue *monologue; struct endpoint_map *em; struct call *call; @@ -1547,9 +1521,6 @@ int monologue_offer_answer(struct call_monologue *other_ml, GQueue *streams, call->last_signal = poller_now; call->deleted = 0; - // get the total number of ports needed for ALGORITHM_ROUND_ROBIN_CALLS algorithm - rr_calls_ports = get_algorithm_num_ports(streams, ALGORITHM_ROUND_ROBIN_CALLS); - __C_DBG("this="STR_FORMAT" other="STR_FORMAT, STR_FMT(&monologue->tag), STR_FMT(&other_ml->tag)); __tos_change(call, flags); @@ -1559,7 +1530,6 @@ int monologue_offer_answer(struct call_monologue *other_ml, GQueue *streams, for (media_iter = streams->head; media_iter; media_iter = media_iter->next) { sp = media_iter->data; __C_DBG("processing media stream #%u", sp->index); - __C_DBG("free ports needed for round-robin-calls, left for this call %u", rr_calls_ports); /* first, check for existence of call_media struct on both sides of * the dialogue */ @@ -1639,9 +1609,15 @@ int monologue_offer_answer(struct call_monologue *other_ml, GQueue *streams, media->desired_family = sp->desired_family; } + /* determine number of consecutive ports needed locally. + * XXX only do *=2 for RTP streams? */ + num_ports = sp->consecutive_ports; + num_ports *= 2; + + /* local interface selection */ - __init_interface(media, &sp->direction[1], rr_calls_ports); - __init_interface(other_media, &sp->direction[0], rr_calls_ports); + __init_interface(media, &sp->direction[1], num_ports); + __init_interface(other_media, &sp->direction[0], num_ports); if (media->logical_intf == NULL || other_media->logical_intf == NULL) { goto error_intf; @@ -1658,12 +1634,6 @@ int monologue_offer_answer(struct call_monologue *other_ml, GQueue *streams, MEDIA_SET(other_media, INITIALIZED); - /* determine number of consecutive ports needed locally. - * XXX only do *=2 for RTP streams? */ - num_ports = sp->consecutive_ports; - num_ports *= 2; - - if (!sp->rtp_endpoint.port) { /* Zero port: stream has been rejected. * RFC 3264, chapter 6: @@ -1686,11 +1656,6 @@ int monologue_offer_answer(struct call_monologue *other_ml, GQueue *streams, em = __get_endpoint_map(media, num_ports, &sp->rtp_endpoint, flags); if (!em) { goto error_ports; - } else { - // update the ports needed for ALGORITHM_ROUND_ROBIN_CALLS algorithm - if (str_cmp(&sp->direction[1], ALGORITHM_ROUND_ROBIN_CALLS) == 0) { - rr_calls_ports -= num_ports; - } } __num_media_streams(media, num_ports); @@ -1702,11 +1667,6 @@ int monologue_offer_answer(struct call_monologue *other_ml, GQueue *streams, * when the answer comes. */ if (__wildcard_endpoint_map(other_media, num_ports)) goto error_ports; - - // update the ports needed for ALGORITHM_ROUND_ROBIN_CALLS algorithm - if (str_cmp(&sp->direction[0], ALGORITHM_ROUND_ROBIN_CALLS) == 0) { - rr_calls_ports -= num_ports; - } } init: diff --git a/daemon/main.c b/daemon/main.c index 1c3a00c6b..b90e70b83 100644 --- a/daemon/main.c +++ b/daemon/main.c @@ -196,6 +196,10 @@ static struct intf_config *if_addr_parse(char *s) { ifa->port_min = port_min; ifa->port_max = port_max; + // handle "base:suffix" separation for round-robin selection + ifa->name_rr_spec = ifa->name; + str_token(&ifa->name_base, &ifa->name_rr_spec, ':'); // sets name_rr_spec to null string if no ':' found + return ifa; } diff --git a/daemon/media_socket.c b/daemon/media_socket.c index c6228f238..b9381ab52 100644 --- a/daemon/media_socket.c +++ b/daemon/media_socket.c @@ -48,6 +48,12 @@ struct streamhandler { const struct streamhandler_io *in; const struct streamhandler_io *out; }; +struct intf_rr { + struct logical_intf hash_key; + mutex_t lock; + GQueue logical_intfs; + struct logical_intf *singular; // set iff only one is present in the list - no lock needed +}; static void determine_handler(struct packet_stream *in, const struct packet_stream *out); @@ -74,6 +80,9 @@ static int call_savpf2avp_rtcp(str *s, struct packet_stream *, struct stream_fd //static int call_savpf2savp_rtcp(str *s, struct packet_stream *); +static struct logical_intf *__get_logical_interface(const str *name, sockfamily_t *fam); + + @@ -256,13 +265,12 @@ static const struct rtpengine_srtp __res_null = { static GQueue *__interface_list_for_family(sockfamily_t *fam); -static GHashTable *__logical_intf_name_family_hash; -static GHashTable *__intf_spec_addr_type_hash; -static GHashTable *__local_intf_addr_type_hash; // hash of lists +static GHashTable *__logical_intf_name_family_hash; // name + family -> struct logical_intf +static GHashTable *__logical_intf_name_family_rr_hash; // name + family -> struct intf_rr +static GHashTable *__intf_spec_addr_type_hash; // addr + type -> struct intf_spec +static GHashTable *__local_intf_addr_type_hash; // addr + type -> GList of struct local_intf static GQueue __preferred_lists_for_family[__SF_LAST]; -static __thread unsigned int selection_index = 0; -static __thread unsigned int selection_count = 0; /* checks for free no_ports on a local interface */ @@ -272,7 +280,7 @@ static int has_free_ports_loc(struct local_intf *loc, unsigned int num_ports) { return 0; } - if (num_ports > loc->spec->port_pool.free_ports) { + if (num_ports > g_atomic_int_get(&loc->spec->port_pool.free_ports)) { ilog(LOG_ERR, "Didn't found %d ports available for %.*s/%s", num_ports, loc->logical->name.len, loc->logical->name.s, sockaddr_print_buf(&loc->spec->local_address.addr)); @@ -332,64 +340,49 @@ static int has_free_ports_log_all(struct logical_intf *log, unsigned int num_por } /* run round-robin-calls algorithm */ -static struct logical_intf* run_round_robin_calls(GQueue *q, unsigned int num_ports) { +static struct logical_intf* run_round_robin_calls(struct intf_rr *rr, unsigned int num_ports) { struct logical_intf *log = NULL; - volatile unsigned int nr_tries = 0; - unsigned int nr_logs = 0; - nr_logs = g_queue_get_length(q); + mutex_lock(&rr->lock); -select_log: - // choose the next logical interface - log = g_queue_peek_nth(q, selection_index); - if (!log) { - if (selection_index == 0) - return NULL; - selection_index = 0; - goto select_log; - } - __C_DBG("Trying %d ports on logical interface %.*s", num_ports, log->name.len, log->name.s); + unsigned int max_tries = rr->logical_intfs.length; + unsigned int num_tries = 0; - // test for free ports for the logical interface - if(!has_free_ports_log_all(log, num_ports)) { - // count the logical interfaces tried - nr_tries++; + while (num_tries++ < max_tries) { + log = g_queue_pop_head(&rr->logical_intfs); + g_queue_push_tail(&rr->logical_intfs, log); - // the logical interface selected has no ports available, try another one - selection_index ++; - selection_index = selection_index % nr_logs; + mutex_unlock(&rr->lock); - // all the logical interfaces have no ports available - if (nr_tries == nr_logs) { - ilog(LOG_ERR, "No logical interface with free ports found; fallback to default behaviour"); - return NULL; - } + __C_DBG("Trying %d ports on logical interface " STR_FORMAT, num_ports, STR_FMT(&log->name)); + + if (has_free_ports_log_all(log, num_ports)) + goto done; + log = NULL; - goto select_log; + mutex_lock(&rr->lock); } - __C_DBG("Round Robin Calls algorithm found logical %.*s; count=%u index=%u", log->name.len, log->name.s, selection_count, selection_index); + mutex_unlock(&rr->lock); - // 1 stream => 2 x get_logical_interface calls at offer - // 2 streams => 4 x get_logical_interface calls at offer - selection_count ++; - if (selection_count % (num_ports / 2) == 0) { - selection_count = 0; - selection_index ++; - selection_index = selection_index % nr_logs; +done: + if (!log) { + ilog(LOG_ERR, "No logical interface with free ports found; fallback to default behaviour"); + return NULL; } - + __C_DBG("Round Robin Calls algorithm found logical " STR_FORMAT, STR_FMT(&log->name)); return log; } +// 'fam' may only be NULL if 'name' is also NULL struct logical_intf *get_logical_interface(const str *name, sockfamily_t *fam, int num_ports) { - struct logical_intf d, *log = NULL; + struct logical_intf *log = NULL; __C_DBG("Get logical interface for %d ports", num_ports); - if (G_UNLIKELY(!name || !name->s || - str_cmp(name, ALGORITHM_ROUND_ROBIN_CALLS) == 0)) { - + if (G_UNLIKELY(!name || !name->s)) { + // trivial case: no interface given. just pick one suitable for the address family. + // always used for legacy TCP and UDP protocols. GQueue *q; if (fam) q = __interface_list_for_family(fam); @@ -404,35 +397,46 @@ got_some: ; } - // round-robin-calls behaviour - return next interface with free ports - if (name && name->s && str_cmp(name, ALGORITHM_ROUND_ROBIN_CALLS) == 0 && num_ports > 0) { - log = run_round_robin_calls(q, num_ports); - if (log) { - __C_DBG("Choose logical interface %.*s because of direction %.*s", - log->name.len, log->name.s, - name->len, name->s); - } else { - __C_DBG("Choose logical interface NULL because of direction %.*s", - name->len, name->s); - } - return log; - } - - // default behaviour - return first logical interface return q->head ? q->head->data : NULL; } + // check if round-robin is desired + struct logical_intf key; + key.name = *name; + key.preferred_family = fam; + struct intf_rr *rr = g_hash_table_lookup(__logical_intf_name_family_rr_hash, &key); + if (!rr) + return __get_logical_interface(name, fam); + if (rr->singular) { + __C_DBG("Returning non-RR logical interface '" STR_FORMAT "' based on direction '" \ + STR_FORMAT "'", + STR_FMT(&rr->singular->name), + STR_FMT(name)); + return rr->singular; + } + + __C_DBG("Running RR interface selection for direction '" STR_FORMAT "'", + STR_FMT(name)); + + log = run_round_robin_calls(rr, num_ports); + if (log) + return log; + return __get_logical_interface(name, fam); +} +static struct logical_intf *__get_logical_interface(const str *name, sockfamily_t *fam) { + struct logical_intf d, *log = NULL; + d.name = *name; d.preferred_family = fam; log = g_hash_table_lookup(__logical_intf_name_family_hash, &d); if (log) { - __C_DBG("Choose logical interface %.*s because of direction %.*s", - log->name.len, log->name.s, - name->len, name->s); + __C_DBG("Choose logical interface " STR_FORMAT " because of direction " STR_FORMAT, + STR_FMT(&log->name), + STR_FMT(name)); } else { - __C_DBG("Choose logical interface NULL because of direction %.*s", - name->len, name->s); + __C_DBG("Choose logical interface NULL because of direction " STR_FORMAT, + STR_FMT(name)); } return log; @@ -482,26 +486,50 @@ int is_local_endpoint(const struct intf_address *addr, unsigned int port) { } +// called during single-threaded startup only +static void __add_intf_rr_1(struct logical_intf *lif, str *name_base, sockfamily_t *fam) { + struct logical_intf key; + key.name = *name_base; + key.preferred_family = fam; + struct intf_rr *rr = g_hash_table_lookup(__logical_intf_name_family_rr_hash, &key); + if (!rr) { + rr = g_slice_alloc0(sizeof(*rr)); + rr->hash_key = key; + mutex_init(&rr->lock); + g_hash_table_insert(__logical_intf_name_family_rr_hash, &rr->hash_key, rr); + } + g_queue_push_tail(&rr->logical_intfs, lif); + rr->singular = (rr->logical_intfs.length == 1) ? lif : NULL; + g_hash_table_insert(lif->rr_specs, &rr->hash_key.name, lif); +} +static void __add_intf_rr(struct logical_intf *lif, str *name_base, sockfamily_t *fam) { + __add_intf_rr_1(lif, name_base, fam); + static str legacy_rr_str = STR_CONST_INIT("round-robin-calls"); + __add_intf_rr_1(lif, &legacy_rr_str, fam); +} static GQueue *__interface_list_for_family(sockfamily_t *fam) { return &__preferred_lists_for_family[fam->idx]; } +// called during single-threaded startup only static void __interface_append(struct intf_config *ifa, sockfamily_t *fam) { struct logical_intf *lif; GQueue *q; struct local_intf *ifc; struct intf_spec *spec; - lif = get_logical_interface(&ifa->name, fam, 0); + lif = __get_logical_interface(&ifa->name, fam); if (!lif) { lif = g_slice_alloc0(sizeof(*lif)); lif->name = ifa->name; lif->preferred_family = fam; lif->addr_hash = g_hash_table_new(__addr_type_hash, __addr_type_eq); + lif->rr_specs = g_hash_table_new(str_hash, str_equal); g_hash_table_insert(__logical_intf_name_family_hash, lif, lif); if (ifa->local_address.addr.family == fam) { q = __interface_list_for_family(fam); g_queue_push_tail(q, lif); + __add_intf_rr(lif, &ifa->name_base, fam); } } @@ -527,6 +555,7 @@ static void __interface_append(struct intf_config *ifa, sockfamily_t *fam) { __insert_local_intf_addr_type(&ifc->advertised_address, ifc); } +// called during single-threaded startup only void interfaces_init(GQueue *interfaces) { int i; GList *l; @@ -535,6 +564,7 @@ void interfaces_init(GQueue *interfaces) { /* init everything */ __logical_intf_name_family_hash = g_hash_table_new(__name_family_hash, __name_family_eq); + __logical_intf_name_family_rr_hash = g_hash_table_new(__name_family_hash, __name_family_eq); __intf_spec_addr_type_hash = g_hash_table_new(__addr_type_hash, __addr_type_eq); __local_intf_addr_type_hash = g_hash_table_new(__addr_type_hash, __addr_type_eq); diff --git a/daemon/media_socket.h b/daemon/media_socket.h index 7886a2a5b..173f8e9f6 100644 --- a/daemon/media_socket.h +++ b/daemon/media_socket.h @@ -21,7 +21,8 @@ struct logical_intf { str name; sockfamily_t *preferred_family; GQueue list; /* struct local_intf */ - GHashTable *addr_hash; + GHashTable *addr_hash; // addr + type -> struct local_intf XXX obsolete? + GHashTable *rr_specs; }; struct port_pool { BIT_ARRAY_DECLARE(ports_used, 0x10000); @@ -35,7 +36,9 @@ struct intf_address { sockaddr_t addr; }; struct intf_config { - str name; + str name; // full name (before the '/' separator in config) + str name_base; // if name is "foo:bar", this is "foo" + str name_rr_spec; // if name is "foo:bar", this is "bar" struct intf_address local_address; struct intf_address advertised_address; unsigned int port_min, port_max; diff --git a/lib/str.h b/lib/str.h index ee3318ea7..0ebe2cf4b 100644 --- a/lib/str.h +++ b/lib/str.h @@ -70,7 +70,7 @@ INLINE void str_swap(str *a, str *b); INLINE int str_to_i(str *s, int def); /* parses a string uinto an int, returns default if conversion fails */ INLINE uint str_to_ui(str *s, int def); -/* extracts the first/next token into "new_token" and modifies "ori_and_remainer" in place */ +/* extracts the first/next token into "new_token" and modifies "ori_and_remaidner" in place */ INLINE int str_token(str *new_token, str *ori_and_remainder, int sep); /* same as str_token but allows for a trailing non-empty token (e.g. "foo,bar" -> "foo", "bar" ) */ INLINE int str_token_sep(str *new_token, str *ori_and_remainder, int sep); diff --git a/perl/NGCP/Rtpengine/Test.pm b/perl/NGCP/Rtpengine/Test.pm index ab090d04a..4a572abef 100644 --- a/perl/NGCP/Rtpengine/Test.pm +++ b/perl/NGCP/Rtpengine/Test.pm @@ -50,7 +50,7 @@ sub new { $self->{mux} = IO::Multiplex->new(); $self->{mux}->set_callback_object($self); - $self->{media_port} = 2000; + $self->{media_port} = $args{media_port} // 2000; $self->{timers} = []; $self->{clients} = []; @@ -149,11 +149,13 @@ sub _new { ($args{sockdomain} && $args{sockdomain} != $address->{sockdomain}) and next; my $rtp = IO::Socket::IP->new(Type => &SOCK_DGRAM, Proto => 'udp', - LocalHost => $address->{address}, LocalPort => $parent->{media_port}++) - or die($address->{address}); + LocalHost => $address->{address}, LocalPort => $parent->{media_port}) + or die("$address->{address}:$parent->{media_port}"); + $parent->{media_port}++; my $rtcp = IO::Socket::IP->new(Type => &SOCK_DGRAM, Proto => 'udp', - LocalHost => $address->{address}, LocalPort => $parent->{media_port}++) - or die($address->{address}); + LocalHost => $address->{address}, LocalPort => $parent->{media_port}) + or die("$address->{address}:$parent->{media_port}"); + $parent->{media_port}++; push(@sockets, [$rtp, $rtcp]); # component 0 and 1 push(@rtp, $rtp); @@ -271,7 +273,7 @@ sub _default_req_args { my $req = { command => $cmd, 'call-id' => $self->{parent}->{callid} }; - for my $cp (qw(sdp from-tag to-tag ICE transport-protocol address-family label)) { + for my $cp (qw(sdp from-tag to-tag ICE transport-protocol address-family label direction)) { $args{$cp} and $req->{$cp} = $args{$cp}; } for my $cp (@{$args{flags}}) { @@ -298,6 +300,7 @@ sub _offered { my ($self, $req) = @_; my $sdp_body = $req->{sdp} or die; + $self->{remote_sdp_raw} = $sdp_body; $self->{remote_sdp} = NGCP::Rtpclient::SDP->decode($sdp_body); # XXX validate SDP @{$self->{remote_sdp}->{medias}} == 1 or die; @@ -323,6 +326,7 @@ sub _answered { my ($self, $req) = @_; my $sdp_body = $req->{sdp} or die; + $self->{remote_sdp_raw} = $sdp_body; $self->{remote_sdp} = NGCP::Rtpclient::SDP->decode($sdp_body); # XXX validate SDP @{$self->{remote_sdp}->{medias}} == 1 or die; diff --git a/t/test-interfaces.pl b/t/test-interfaces.pl new file mode 100755 index 000000000..a4fb31658 --- /dev/null +++ b/t/test-interfaces.pl @@ -0,0 +1,55 @@ +#!/usr/bin/perl + +use strict; +use warnings; +use NGCP::Rtpengine::Test; +use IO::Socket; + +my $iterations = 10; +my @interfaces = qw(int ext); +my @domains = (&Socket::AF_INET); + +my $r = NGCP::Rtpengine::Test->new(media_port => 50000); + +for my $a_domain (@domains) { + for my $b_domain (@domains) { + if (!@interfaces) { + for (1 .. $iterations) { + run_test([], $a_domain, $b_domain); + } + } + else { + for my $a_interface (@interfaces) { + for my $b_interface (@interfaces) { + for (1 .. $iterations) { + run_test([$a_interface, $b_interface], $a_domain, $b_domain); + } + } + } + } + } +} + +sub run_test { + my ($directions, $a_domain, $b_domain) = @_; + print("Testing directions @{$directions} between $a_domain and $b_domain\n"); + + my ($a, $b) = $r->client_pair( + {sockdomain => $a_domain}, + {sockdomain => $b_domain} + ); + + print("Offering with address: " . $a->{sockets}->[0]->[0]->sockhost . "\n"); + my %dir_arg = (); + $dir_arg{direction} = $directions if @{$directions}; + $a->offer($b, ICE => 'remove', label => "caller", %dir_arg); + print("Offer out with address: " . $b->{remote_media}->connection->{address} . "\n"); + + print("Answering with address: " . $b->{sockets}->[0]->[0]->sockhost . "\n"); + $b->answer($a, ICE => 'remove', label => "callee"); + print("Answer out with address: " . $a->{remote_media}->connection->{address} . "\n"); + + $a->teardown(); + + print("\n"); +} From 2e5b80fe7db76b6606557750e0e929100a78e467 Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Fri, 22 Dec 2017 11:17:37 -0500 Subject: [PATCH 42/65] add config file options to README Change-Id: I1e12497c3cdf09d4a7ff28609477bfea023f55d9 --- README.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/README.md b/README.md index b92bcd470..0013f722f 100644 --- a/README.md +++ b/README.md @@ -214,6 +214,24 @@ The options are described in more detail below. If called with this option, the *rtpengine* daemon will simply print its version number and exit. +* --config-file + + Specifies the location of a config file to be used. The config file is an *.ini* style config file, + with all command-line options listed here also being valid options in the config file. For all + command-line options, the long name version instead of the single-character version + (e.g. `table` instead of just `t`) must be used in the config file. For boolean options that are + either present or not (e.g. `no-fallback`), a boolean value (either `true` or `false`) must be + used in the config file. If an option is given in both the config file and at the command line, + the command-line value overrides the value from the config file. Options that can be specified + multiple times on the command line must be given only once in the config file, with the multiple + values separated by semicolons (see section *Interfaces configuration* below for an example). + +* --config-section + + Specifies the *.ini* style section to be used in the config file. Multiple sections can be + present in the config file, but only one can be used at a time. The default value is `rtpengine`. + A config file section is started in the config file using square brackets (e.g. `[rtpengine]`). + * -t, --table Takes an integer argument and specifies which kernel table to use for in-kernel packet forwarding. See From 8733875b36cbc0e33a10e4f8012c171d4c7bfa6d Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Fri, 22 Dec 2017 11:50:03 -0500 Subject: [PATCH 43/65] README updates Change-Id: I201d91626210d5c558c19d5421ebf2a1a0b34985 --- README.md | 48 ++++++++++++++++++++++-------------------------- 1 file changed, 22 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index 0013f722f..134ad934f 100644 --- a/README.md +++ b/README.md @@ -575,7 +575,7 @@ Interfaces configuration ------------------------ The command-line options `-i` or `--interface=`, or equivalently the `interface=` config file option, -specifie a local network interfaces for RTP. At least one must be given, but multiple can be specified. +specify local network interfaces for RTP. At least one must be given, but multiple can be specified. The format of the value is `[NAME/]IP[!IP]` with `IP` being either an IPv4 address or an IPv6 address. To configure multiple interfaces using the command-line options, simply present multiple `-i` or @@ -631,9 +631,7 @@ It is possible to combine the `BASE:SUFFIX` notation with specifying multiple ad interface name. An advanced example could be (using config file notation, and omitting actual network addresses): -``` -interface = pub:1/IPv4 pub:1/IPv4 pub:1/IPv6 pub:2/IPv4 pub:2/IPv6 pub:3/IPv6 pub:4/IPv4 -``` + interface = pub:1/IPv4 pub:1/IPv4 pub:1/IPv6 pub:2/IPv4 pub:2/IPv6 pub:3/IPv6 pub:4/IPv4 In this example, when `direction=pub` is IPv4 is needed as a primary address, either `pub:1`, `pub:2`, or `pub:4` might be selected. When `pub:1` is selected, one IPv4 and one IPv6 address will be used @@ -676,7 +674,8 @@ actually add the required rule to the tables. In short, the prerequisites for in-kernel packet forwarding are: 1. The `xt_RTPENGINE` kernel module must be loaded. -2. An `iptables` and/or `ip6tables` rule must be present in the `INPUT` chain to send packets +2. An `iptables` and/or `ip6tables` rule must be present in the `INPUT` chain (or in a custom user-defined + chain which is then called by the `INPUT` chain) to send packets to the `RTPENGINE` target. This rule should be limited to UDP packets, but otherwise there are no restrictions. 3. The `rtpengine` daemon must be running. @@ -765,6 +764,15 @@ like `--dport 30000:40000`. If the kernel module receives a packet that it doesn to an active media stream, it will simply ignore it and hand it back to the network stack for normal processing. +The `RTPENGINE` rule need not necessarily be present directly in the `INPUT` chain. It can also be in a +user-defined chain which is then referenced by the `INPUT` chain, like so: + + iptables -N rtpengine + iptables -I INPUT -p udp -j rtpengine + iptables -I rtpengine -j RTPENGINE --id 42 + +This can be a useful setup if certain firewall scripts are being used. + Summary ------- @@ -780,7 +788,7 @@ A typical start-up sequence including in-kernel forwarding might look like this: echo 'del 0' > /proc/rtpengine/control # start daemon - /usr/sbin/rtpengine --table=0 --ip=10.64.73.31 --ip6=2001:db8::4f3:3d \ + /usr/sbin/rtpengine --table=0 --interface=10.64.73.31 --interface=2001:db8::4f3:3d \ --listen-ng=127.0.0.1:2223 --tos=184 --pidfile=/var/run/rtpengine.pid --no-fallback Running Multiple Instances @@ -802,9 +810,9 @@ then the start-up sequence might look like this: echo 'del 0' > /proc/rtpengine/control echo 'del 1' > /proc/rtpengine/control - /usr/sbin/rtpengine --table=0 --ip=10.64.73.31 \ + /usr/sbin/rtpengine --table=0 --interface=10.64.73.31 \ --listen-ng=127.0.0.1:2223 --tos=184 --pidfile=/var/run/rtpengine-10.pid --no-fallback - /usr/sbin/rtpengine --table=1 --ip=192.168.65.73 \ + /usr/sbin/rtpengine --table=1 --interface=192.168.65.73 \ --listen-ng=127.0.0.1:2224 --tos=184 --pidfile=/var/run/rtpengine-192.pid --no-fallback With this setup, the SIP proxy can choose which instance of *rtpengine* to talk to and thus which local @@ -1005,24 +1013,12 @@ Optionally included keys are: However, this mechanism for selecting the address family is now obsolete and the `address family` dictionary key should be used instead. - A direction keyword is *round-robin-calls*. If this is received, a round robin algorithm runs for - choosing the logical interface for the current stream(e.g. audio, video). - The algorithm checks that all local interfaces of the tried logical interface have free ports for - call streams. If a logical interface fails the check, the next one is tried. If there is no logical - interface found with this property, it fallbacks to the default behaviour (e.g. return first logical - interface in --interface list even if no free ports are available). The attribute is ignored for - answers() because the logical interface was already selected at offers(). - Naming an interface "round-robin-calls" and trying to select it using direction will - __run the above algorithm__! - - Round robin for both legs of the stream: - { ..., "direction": [ "round-robin-calls", "round-robin-calls" ], ... } - - Round robin for first leg and and select "pub" for the second leg of the stream: - { ..., "direction": [ "round-robin-calls", "pub" ], ... } - - Round robin for first leg and and default behaviour for the second leg of the stream: - { ..., "direction": [ "round-robin-calls" ], ... } + For legacy support, the special direction keyword `round-robin-calls` can be used to invoke the + round-robin interface selection algorithm described in the section *Interfaces configuration*. + If this special keyword is used, the round-robin selection will run over all configured + interfaces, whether or not they are configured using the `BASE:SUFFIX` interface name notation. + This special keyword is provided only for legacy support and should be considered obsolete. + It will be removed in future versions. * `received from` From c17f4fe53db7ff02a5abe1c9883bd79dec714a67 Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Mon, 25 Dec 2017 08:27:10 -0500 Subject: [PATCH 44/65] avoid side effects in assert() closes #434 Change-Id: I6aad7ccb556453650d80cf588ae80daf98d3369d --- daemon/aux.h | 3 ++- daemon/control_ng.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/daemon/aux.h b/daemon/aux.h index 1fe463c3a..91315274b 100644 --- a/daemon/aux.h +++ b/daemon/aux.h @@ -183,7 +183,8 @@ INLINE int strmemcmp(const void *mem, int len, const char *str) { } INLINE void random_string(unsigned char *buf, int len) { - assert(RAND_bytes(buf, len) == 1); + int ret = RAND_bytes(buf, len); + assert(ret == 1); } INLINE long unsigned int ssl_random() { long unsigned int ret; diff --git a/daemon/control_ng.c b/daemon/control_ng.c index 0c5d37930..8b1b48ef0 100644 --- a/daemon/control_ng.c +++ b/daemon/control_ng.c @@ -126,7 +126,8 @@ static void control_ng_incoming(struct obj *obj, str *buf, const endpoint_t *sin return; } - assert( bencode_buffer_init(&bencbuf) == 0 ); + int ret = bencode_buffer_init(&bencbuf); + assert(ret == 0); resp = bencode_dictionary(&bencbuf); assert(resp != NULL); From 018e35cba8e3268457bfc81728f822f35cc170e1 Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Tue, 2 Jan 2018 10:57:38 -0500 Subject: [PATCH 45/65] TT#27200 add option to omit a=rtcp attribute closes #428 Change-Id: Ie186291b7b0107d67488facbfea42cd4915556b4 --- README.md | 4 ++++ daemon/call_interfaces.c | 2 ++ daemon/call_interfaces.h | 1 + daemon/sdp.c | 28 +++++++++++++++++++--------- utils/rtpengine-ng-client | 3 ++- 5 files changed, 28 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 134ad934f..bc9790e50 100644 --- a/README.md +++ b/README.md @@ -977,6 +977,10 @@ Optionally included keys are: Identical to setting `record call` to `on` (see below). + - `no rtcp attribute` + + Omit the `a=rtcp` line from the outgoing SDP. + * `replace` diff --git a/daemon/call_interfaces.c b/daemon/call_interfaces.c index 277e9b969..4814d38c5 100644 --- a/daemon/call_interfaces.c +++ b/daemon/call_interfaces.c @@ -562,6 +562,8 @@ static void call_ng_process_flags(struct sdp_ng_flags *out, bencode_item_t *inpu out->port_latching = 1; else if (!bencode_strcmp(it, "record-call")) out->record_call = 1; + else if (!bencode_strcmp(it, "no-rtcp-attribute")) + out->no_rtcp_attr = 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 c87af22d1..f414b489a 100644 --- a/daemon/call_interfaces.h +++ b/daemon/call_interfaces.h @@ -47,6 +47,7 @@ struct sdp_ng_flags { rtcp_mux_demux:1, rtcp_mux_accept:1, rtcp_mux_reject:1, + no_rtcp_attr:1, strict_source:1, media_handover:1, dtls_passive:1, diff --git a/daemon/sdp.c b/daemon/sdp.c index 54e6ac9ee..4583f0a8d 100644 --- a/daemon/sdp.c +++ b/daemon/sdp.c @@ -1991,18 +1991,28 @@ int sdp_replace(struct sdp_chopper *chop, GQueue *sessions, struct call_monologu || (flags->opmode == OP_OFFER && flags->rtcp_mux_require))) { - chopper_append_c(chop, "a=rtcp:"); - chopper_append_printf(chop, "%u", ps->selected_sfd->socket.local.port); - chopper_append_c(chop, "\r\na=rtcp-mux\r\n"); + if (!flags->no_rtcp_attr) { + chopper_append_c(chop, "a=rtcp:"); + chopper_append_printf(chop, "%u", ps->selected_sfd->socket.local.port); + chopper_append_c(chop, "\r\na=rtcp-mux\r\n"); + } + else + chopper_append_c(chop, "a=rtcp-mux\r\n"); ps_rtcp = NULL; } else if (ps_rtcp && !flags->ice_force_relay) { - chopper_append_c(chop, "a=rtcp:"); - chopper_append_printf(chop, "%u", ps_rtcp->selected_sfd->socket.local.port); - if (!MEDIA_ISSET(call_media, RTCP_MUX)) - chopper_append_c(chop, "\r\n"); - else - chopper_append_c(chop, "\r\na=rtcp-mux\r\n"); + if (!flags->no_rtcp_attr) { + chopper_append_c(chop, "a=rtcp:"); + chopper_append_printf(chop, "%u", ps_rtcp->selected_sfd->socket.local.port); + if (!MEDIA_ISSET(call_media, RTCP_MUX)) + chopper_append_c(chop, "\r\n"); + else + chopper_append_c(chop, "\r\na=rtcp-mux\r\n"); + } + else { + if (MEDIA_ISSET(call_media, RTCP_MUX)) + chopper_append_c(chop, "a=rtcp-mux\r\n"); + } } } else diff --git a/utils/rtpengine-ng-client b/utils/rtpengine-ng-client index 8d80a91c4..b99dd6025 100755 --- a/utils/rtpengine-ng-client +++ b/utils/rtpengine-ng-client @@ -21,6 +21,7 @@ GetOptions( 'protocol=s' => \$options{'transport protocol'}, 'trust-address' => \$options{'trust address'}, 'sip-source-address' => \$options{'sip source address'}, + 'no-rtcp-attribute' => \$options{'no rtcp attribute'}, 'symmetric' => \$options{'symmetric'}, 'asymmetric' => \$options{'asymmetric'}, 'replace-origin' => \$options{'replace-origin'}, @@ -55,7 +56,7 @@ for my $x (split(/,/, 'from-tag,to-tag,call-id,transport protocol,media address, for my $x (split(/,/, 'TOS,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,port latching')) { +for my $x (split(/,/, 'trust address,symmetric,asymmetric,force,strict source,media handover,sip source address,reset,port latching,no rtcp attribute')) { defined($options{$x}) and push(@{$packet{flags}}, $x); } for my $x (split(/,/, 'origin,session connection')) { From acba2751f82b4a3f0106f4016b9183a07630eb5b Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Wed, 3 Jan 2018 09:25:36 -0500 Subject: [PATCH 46/65] suppress log message on "comprehension option" STUN attributes closes #436 Change-Id: I3b5583a83500b7cbfaf1317cae18d5f186554672 --- daemon/stun.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/daemon/stun.c b/daemon/stun.c index ce4823870..dfecde7cd 100644 --- a/daemon/stun.c +++ b/daemon/stun.c @@ -222,9 +222,12 @@ static int stun_attributes(struct stun_attrs *out, str *s, u_int16_t *unknowns, break; default: - ilog(LOG_NOTICE, "Unknown STUN attribute: 0x%04x", type); - if ((type & 0x8000)) + if ((type & 0x8000)) { + // comprehension optional + ilog(LOG_DEBUG, "Unknown STUN attribute: 0x%04x", type); break; + } + ilog(LOG_NOTICE, "Unknown STUN attribute: 0x%04x", type); unknowns[uc] = tlv->type; unknowns[++uc] = 0xffff; if (uc >= UNKNOWNS_COUNT - 1) From 399e15b39aff7e2336aa0860ca3de2b22cc32113 Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Wed, 3 Jan 2018 10:19:54 -0500 Subject: [PATCH 47/65] make the callhash global Change-Id: Ifa1fbb5d1b1f623dbc6a1bfac556342735b40161 --- daemon/call.c | 107 ++++++++++++--------------------------- daemon/call.h | 8 +-- daemon/call_interfaces.c | 14 ++--- daemon/cli.c | 24 ++++----- daemon/graphite.c | 6 +-- daemon/statistics.c | 4 +- 6 files changed, 62 insertions(+), 101 deletions(-) diff --git a/daemon/call.c b/daemon/call.c index 8e992965a..17d5132bf 100644 --- a/daemon/call.c +++ b/daemon/call.c @@ -115,6 +115,10 @@ const struct transport_protocol transport_protocols[] = { }; const int num_transport_protocols = G_N_ELEMENTS(transport_protocols); + +rwlock_t rtpe_callhash_lock; +GHashTable *rtpe_callhash; + /* ********** */ static void __monologue_destroy(struct call_monologue *monologue); @@ -477,14 +481,14 @@ static void callmaster_timer(void *ptr) { hlp.addr_sfd = g_hash_table_new(g_endpoint_hash, g_endpoint_eq); /* obtain the call list and make a copy from it so not to hold the lock */ - rwlock_lock_r(&m->hashlock); - l = g_hash_table_get_values(m->callhash); + rwlock_lock_r(&rtpe_callhash_lock); + l = g_hash_table_get_values(rtpe_callhash); if (l) { calls = g_list_copy(l); g_list_free(l); g_list_foreach(calls, call_obj_get, NULL); } - rwlock_unlock_r(&m->hashlock); + rwlock_unlock_r(&rtpe_callhash_lock); if (calls) { g_list_foreach(calls, call_timer_iterator, &hlp); @@ -611,11 +615,11 @@ struct callmaster *callmaster_new(struct poller *p) { c = obj_alloc0("callmaster", sizeof(*c), NULL); - c->callhash = g_hash_table_new(str_hash, str_equal); - if (!c->callhash) + rtpe_callhash = g_hash_table_new(str_hash, str_equal); + if (!rtpe_callhash) goto fail; c->poller = p; - rwlock_init(&c->hashlock); + rwlock_init(&rtpe_callhash_lock); c->info_re = pcre_compile("^([^:,]+)(?::(.*?))?(?:$|,)", PCRE_DOLLAR_ENDONLY | PCRE_DOTALL, &errptr, &erroff, NULL); if (!c->info_re) @@ -1755,8 +1759,8 @@ static struct timeval add_ongoing_calls_dur_in_interval(struct callmaster *m, struct call *call; struct call_monologue *ml; - rwlock_lock_r(&m->hashlock); - g_hash_table_iter_init(&iter, m->callhash); + rwlock_lock_r(&rtpe_callhash_lock); + g_hash_table_iter_init(&iter, rtpe_callhash); while (g_hash_table_iter_next(&iter, &key, &value)) { call = (struct call*) value; @@ -1770,7 +1774,7 @@ static struct timeval add_ongoing_calls_dur_in_interval(struct callmaster *m, timeval_add(&res, &res, &call_duration); } } - rwlock_unlock_r(&m->hashlock); + rwlock_unlock_r(&rtpe_callhash_lock); return res; } @@ -1794,11 +1798,11 @@ void call_destroy(struct call *c) { m = c->callmaster; p = m->poller; - rwlock_lock_w(&m->hashlock); - ret = (g_hash_table_lookup(m->callhash, &c->callid) == c); + rwlock_lock_w(&rtpe_callhash_lock); + ret = (g_hash_table_lookup(rtpe_callhash, &c->callid) == c); if (ret) - g_hash_table_remove(m->callhash, &c->callid); - rwlock_unlock_w(&m->hashlock); + g_hash_table_remove(rtpe_callhash, &c->callid); + rwlock_unlock_w(&rtpe_callhash_lock); // if call not found in callhash => previously deleted if (!ret) @@ -2047,20 +2051,20 @@ struct call *call_get_or_create(const str *callid, struct callmaster *m, enum ca struct call *c; restart: - rwlock_lock_r(&m->hashlock); - c = g_hash_table_lookup(m->callhash, callid); + rwlock_lock_r(&rtpe_callhash_lock); + c = g_hash_table_lookup(rtpe_callhash, callid); if (!c) { - rwlock_unlock_r(&m->hashlock); + rwlock_unlock_r(&rtpe_callhash_lock); /* completely new call-id, create call */ c = call_create(callid, m); - rwlock_lock_w(&m->hashlock); - if (g_hash_table_lookup(m->callhash, callid)) { + rwlock_lock_w(&rtpe_callhash_lock); + if (g_hash_table_lookup(rtpe_callhash, callid)) { /* preempted */ - rwlock_unlock_w(&m->hashlock); + rwlock_unlock_w(&rtpe_callhash_lock); obj_put(c); goto restart; } - g_hash_table_insert(m->callhash, &c->callid, obj_get(c)); + g_hash_table_insert(rtpe_callhash, &c->callid, obj_get(c)); if (type == CT_FOREIGN_CALL) /* foreign call*/ c->foreign_call = 1; @@ -2068,12 +2072,12 @@ restart: statistics_update_foreignown_inc(m,c); rwlock_lock_w(&c->master_lock); - rwlock_unlock_w(&m->hashlock); + rwlock_unlock_w(&rtpe_callhash_lock); } else { obj_hold(c); rwlock_lock_w(&c->master_lock); - rwlock_unlock_r(&m->hashlock); + rwlock_unlock_r(&rtpe_callhash_lock); } log_info_call(c); @@ -2084,16 +2088,16 @@ restart: struct call *call_get(const str *callid, struct callmaster *m) { struct call *ret; - rwlock_lock_r(&m->hashlock); - ret = g_hash_table_lookup(m->callhash, callid); + rwlock_lock_r(&rtpe_callhash_lock); + ret = g_hash_table_lookup(rtpe_callhash, callid); if (!ret) { - rwlock_unlock_r(&m->hashlock); + rwlock_unlock_r(&rtpe_callhash_lock); return NULL; } rwlock_lock_w(&ret->master_lock); obj_hold(ret); - rwlock_unlock_r(&m->hashlock); + rwlock_unlock_r(&rtpe_callhash_lock); log_info_call(ret); return ret; @@ -2488,57 +2492,12 @@ static void callmaster_get_all_calls_interator(void *key, void *val, void *ptr) } void callmaster_get_all_calls(struct callmaster *m, GQueue *q) { - rwlock_lock_r(&m->hashlock); - g_hash_table_foreach(m->callhash, callmaster_get_all_calls_interator, q); - rwlock_unlock_r(&m->hashlock); - -} - + rwlock_lock_r(&rtpe_callhash_lock); + g_hash_table_foreach(rtpe_callhash, callmaster_get_all_calls_interator, q); + rwlock_unlock_r(&rtpe_callhash_lock); -#if 0 -// unused -// simplifty redis_write <> redis if put back into use -static void calls_dump_iterator(void *key, void *val, void *ptr) { - struct call *c = val; - struct callmaster *m = c->callmaster; - - if (m->conf.redis_write) { - redis_update(c, m->conf.redis_write); - } else if (m->conf.redis) { - redis_update(c, m->conf.redis); - } } -void calls_dump_redis(struct callmaster *m) { - if (!m->conf.redis) - return; - - ilog(LOG_DEBUG, "Start dumping all call data to Redis...\n"); - redis_wipe(m->conf.redis); - g_hash_table_foreach(m->callhash, calls_dump_iterator, NULL); - ilog(LOG_DEBUG, "Finished dumping all call data to Redis\n"); -} - -void calls_dump_redis_read(struct callmaster *m) { - if (!m->conf.redis_read) - return; - - ilog(LOG_DEBUG, "Start dumping all call data to read Redis...\n"); - redis_wipe(m->conf.redis_read); - g_hash_table_foreach(m->callhash, calls_dump_iterator, NULL); - ilog(LOG_DEBUG, "Finished dumping all call data to read Redis\n"); -} - -void calls_dump_redis_write(struct callmaster *m) { - if (!m->conf.redis_write) - return; - - ilog(LOG_DEBUG, "Start dumping all call data to write Redis...\n"); - redis_wipe(m->conf.redis_write); - g_hash_table_foreach(m->callhash, calls_dump_iterator, NULL); - ilog(LOG_DEBUG, "Finished dumping all call data to write Redis\n"); -} -#endif const struct transport_protocol *transport_protocol(const str *s) { int i; diff --git a/daemon/call.h b/daemon/call.h index af6fbd331..05b7e4afe 100644 --- a/daemon/call.h +++ b/daemon/call.h @@ -416,9 +416,6 @@ struct callmaster_config { struct callmaster { struct obj obj; - rwlock_t hashlock; - GHashTable *callhash; - /* XXX rework these */ struct stats statsps; /* per second stats, running timer */ struct stats stats; /* copied from statsps once a second */ @@ -441,6 +438,11 @@ struct callmaster { struct timeval latest_graphite_interval_start; }; + +extern rwlock_t rtpe_callhash_lock; +extern GHashTable *rtpe_callhash; + + struct callmaster *callmaster_new(struct poller *); void callmaster_get_all_calls(struct callmaster *m, GQueue *q); diff --git a/daemon/call_interfaces.c b/daemon/call_interfaces.c index 4814d38c5..34ffb033e 100644 --- a/daemon/call_interfaces.c +++ b/daemon/call_interfaces.c @@ -812,10 +812,10 @@ const char *call_offer_ng(bencode_item_t *input, struct callmaster *m, bencode_i { rwlock_lock_r(&m->conf.config_lock); if (m->conf.max_sessions>=0) { - rwlock_lock_r(&m->hashlock); - if (g_hash_table_size(m->callhash) - + rwlock_lock_r(&rtpe_callhash_lock); + if (g_hash_table_size(rtpe_callhash) - atomic64_get(&m->stats.foreign_sessions) >= m->conf.max_sessions) { - rwlock_unlock_r(&m->hashlock); + rwlock_unlock_r(&rtpe_callhash_lock); /* foreign calls can't get rejected * total_rejected_sess applies only to "own" sessions */ atomic64_inc(&m->totalstats.total_rejected_sess); @@ -825,7 +825,7 @@ const char *call_offer_ng(bencode_item_t *input, struct callmaster *m, bencode_i rwlock_unlock_r(&m->conf.config_lock); return "Parallel session limit reached"; } - rwlock_unlock_r(&m->hashlock); + rwlock_unlock_r(&rtpe_callhash_lock); } rwlock_unlock_r(&m->conf.config_lock); @@ -1144,14 +1144,14 @@ static void ng_list_calls( struct callmaster *m, bencode_item_t *output, long lo GHashTableIter iter; gpointer key, value; - rwlock_lock_r(&m->hashlock); + rwlock_lock_r(&rtpe_callhash_lock); - g_hash_table_iter_init (&iter, m->callhash); + g_hash_table_iter_init (&iter, rtpe_callhash); while (limit-- && g_hash_table_iter_next (&iter, &key, &value)) { bencode_list_add_str_dup(output, key); } - rwlock_unlock_r(&m->hashlock); + rwlock_unlock_r(&rtpe_callhash_lock); } diff --git a/daemon/cli.c b/daemon/cli.c index ff7beb9f9..91047f67a 100644 --- a/daemon/cli.c +++ b/daemon/cli.c @@ -108,9 +108,9 @@ static void destroy_own_foreign_calls(struct callmaster *m, unsigned int foreign GList *i; // lock read - rwlock_lock_r(&m->hashlock); + rwlock_lock_r(&rtpe_callhash_lock); - g_hash_table_iter_init(&iter, m->callhash); + g_hash_table_iter_init(&iter, rtpe_callhash); while (g_hash_table_iter_next(&iter, &key, &value)) { c = (struct call*)value; if (!c) { @@ -135,7 +135,7 @@ static void destroy_own_foreign_calls(struct callmaster *m, unsigned int foreign } // unlock read - rwlock_unlock_r(&m->hashlock); + rwlock_unlock_r(&rtpe_callhash_lock); // destroy calls while ((c = g_queue_pop_head(&call_list))) { @@ -253,11 +253,11 @@ static void cli_incoming_list_totals(str *instr, struct callmaster* m, struct st } static void cli_incoming_list_numsessions(str *instr, struct callmaster* m, struct streambuf *replybuffer) { - rwlock_lock_r(&m->hashlock); - streambuf_printf(replybuffer, "Current sessions own: "UINT64F"\n", g_hash_table_size(m->callhash) - atomic64_get(&m->stats.foreign_sessions)); + rwlock_lock_r(&rtpe_callhash_lock); + streambuf_printf(replybuffer, "Current sessions own: "UINT64F"\n", g_hash_table_size(rtpe_callhash) - atomic64_get(&m->stats.foreign_sessions)); streambuf_printf(replybuffer, "Current sessions foreign: "UINT64F"\n", atomic64_get(&m->stats.foreign_sessions)); - streambuf_printf(replybuffer, "Current sessions total: %i\n", g_hash_table_size(m->callhash)); - rwlock_unlock_r(&m->hashlock); + streambuf_printf(replybuffer, "Current sessions total: %i\n", g_hash_table_size(rtpe_callhash)); + rwlock_unlock_r(&rtpe_callhash_lock); } static void cli_incoming_list_maxsessions(str *instr, struct callmaster* m, struct streambuf *replybuffer) { @@ -414,15 +414,15 @@ static void cli_incoming_list_sessions(str *instr, struct callmaster* m, struct return; } - rwlock_lock_r(&m->hashlock); + rwlock_lock_r(&rtpe_callhash_lock); - if (g_hash_table_size(m->callhash)==0) { + if (g_hash_table_size(rtpe_callhash)==0) { streambuf_printf(replybuffer, "No sessions on this media relay.\n"); - rwlock_unlock_r(&m->hashlock); + rwlock_unlock_r(&rtpe_callhash_lock); return; } - g_hash_table_iter_init (&iter, m->callhash); + g_hash_table_iter_init (&iter, rtpe_callhash); while (g_hash_table_iter_next(&iter, &key, &value)) { ptrkey = (str*)key; call = (struct call*)value; @@ -450,7 +450,7 @@ static void cli_incoming_list_sessions(str *instr, struct callmaster* m, struct streambuf_printf(replybuffer, "callid: %60s | deletionmark:%4s | created:%12i | proxy:%s | redis_keyspace:%i | foreign:%s\n", ptrkey->s, call->ml_deleted?"yes":"no", (int)call->created.tv_sec, call->created_from, call->redis_hosted_db, IS_FOREIGN_CALL(call)?"yes":"no"); } - rwlock_unlock_r(&m->hashlock); + rwlock_unlock_r(&rtpe_callhash_lock); if (str_cmp(instr, LIST_ALL) == 0) { ; diff --git a/daemon/graphite.c b/daemon/graphite.c index 4003d5eb0..d634fa831 100644 --- a/daemon/graphite.c +++ b/daemon/graphite.c @@ -131,17 +131,17 @@ int send_graphite_data(struct callmaster *cm, struct totalstats *sent_data) { ts->answer = timeval_clear_request_time(&cm->totalstats_interval.answer); ts->delete = timeval_clear_request_time(&cm->totalstats_interval.delete); - rwlock_lock_r(&cm->hashlock); + rwlock_lock_r(&rtpe_callhash_lock); mutex_lock(&cm->totalstats_interval.managed_sess_lock); ts->managed_sess_max = cm->totalstats_interval.managed_sess_max; ts->managed_sess_min = cm->totalstats_interval.managed_sess_min; - ts->total_sessions = g_hash_table_size(cm->callhash); + ts->total_sessions = g_hash_table_size(rtpe_callhash); ts->foreign_sessions = atomic64_get(&cm->stats.foreign_sessions); ts->own_sessions = ts->total_sessions - ts->foreign_sessions; cm->totalstats_interval.managed_sess_max = ts->own_sessions;; cm->totalstats_interval.managed_sess_min = ts->own_sessions; mutex_unlock(&cm->totalstats_interval.managed_sess_lock); - rwlock_unlock_r(&cm->hashlock); + rwlock_unlock_r(&rtpe_callhash_lock); // compute average offer/answer/delete time timeval_divide(&ts->offer.time_avg, &ts->offer.time_avg, ts->offer.count); diff --git a/daemon/statistics.c b/daemon/statistics.c index a785fd06b..af536550c 100644 --- a/daemon/statistics.c +++ b/daemon/statistics.c @@ -82,7 +82,7 @@ void statistics_update_foreignown_dec(struct call* c) { if(IS_OWN_CALL(c)) { mutex_lock(&m->totalstats_interval.managed_sess_lock); m->totalstats_interval.managed_sess_min = MIN(m->totalstats_interval.managed_sess_min, - g_hash_table_size(m->callhash) - atomic64_get(&m->stats.foreign_sessions)); + g_hash_table_size(rtpe_callhash) - atomic64_get(&m->stats.foreign_sessions)); mutex_unlock(&m->totalstats_interval.managed_sess_lock); } @@ -93,7 +93,7 @@ void statistics_update_foreignown_inc(struct callmaster *m, struct call* c) { mutex_lock(&m->totalstats_interval.managed_sess_lock); m->totalstats_interval.managed_sess_max = MAX( m->totalstats_interval.managed_sess_max, - g_hash_table_size(m->callhash) + g_hash_table_size(rtpe_callhash) - atomic64_get(&m->stats.foreign_sessions)); mutex_unlock(&m->totalstats_interval.managed_sess_lock); } From 790e596c582a4cd4fd44222b134e0fd895219806 Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Wed, 3 Jan 2018 10:28:45 -0500 Subject: [PATCH 48/65] move cngs out of callmaster into global scope Change-Id: I138ca8756dfc576451bc7c3fca1db89d6616fb1e --- daemon/call.c | 2 -- daemon/call.h | 4 ---- daemon/cli.c | 6 +++--- daemon/control_ng.c | 19 ++++++++++++++----- daemon/control_ng.h | 4 ++++ daemon/main.c | 1 + 6 files changed, 22 insertions(+), 14 deletions(-) diff --git a/daemon/call.c b/daemon/call.c index 17d5132bf..2e6b8687d 100644 --- a/daemon/call.c +++ b/daemon/call.c @@ -643,8 +643,6 @@ struct callmaster *callmaster_new(struct poller *p) { //c->totalstats_interval.managed_sess_max = 0; mutex_init(&c->totalstats_lastinterval_lock); - mutex_init(&c->cngs_lock); - c->cngs_hash = g_hash_table_new(g_sockaddr_hash, g_sockaddr_eq); return c; diff --git a/daemon/call.h b/daemon/call.h index 05b7e4afe..a552a7035 100644 --- a/daemon/call.h +++ b/daemon/call.h @@ -424,10 +424,6 @@ struct callmaster { mutex_t totalstats_lastinterval_lock; struct totalstats totalstats_lastinterval; - /* control_ng_stats stuff */ - mutex_t cngs_lock; - GHashTable *cngs_hash; - struct poller *poller; pcre *info_re; pcre_extra *info_ree; diff --git a/daemon/cli.c b/daemon/cli.c index 91047f67a..4c282c380 100644 --- a/daemon/cli.c +++ b/daemon/cli.c @@ -227,8 +227,8 @@ static void cli_incoming_list_totals(str *instr, struct callmaster* m, struct st streambuf_printf(replybuffer, " %20s | %10s | %10s | %10s | %10s | %10s | %10s | %10s | %10s | %10s \n", "Proxy", "Offer", "Answer", "Delete", "Ping", "List", "Query", "StartRec", "StopRec", "Errors"); - mutex_lock(&m->cngs_lock); - GList *list = g_hash_table_get_values(m->cngs_hash); + mutex_lock(&rtpe_cngs_lock); + GList *list = g_hash_table_get_values(rtpe_cngs_hash); if (!list) { streambuf_printf(replybuffer, "\n No proxies have yet tried to send data."); @@ -248,7 +248,7 @@ static void cli_incoming_list_totals(str *instr, struct callmaster* m, struct st cur->errors); } streambuf_printf(replybuffer, "\n\n"); - mutex_unlock(&m->cngs_lock); + mutex_unlock(&rtpe_cngs_lock); g_list_free(list); } diff --git a/daemon/control_ng.c b/daemon/control_ng.c index 8b1b48ef0..b8ccc8f6a 100644 --- a/daemon/control_ng.c +++ b/daemon/control_ng.c @@ -16,6 +16,10 @@ #include "log_funcs.h" +mutex_t rtpe_cngs_lock; +GHashTable *rtpe_cngs_hash; + + static void timeval_update_request_time(struct request_time *request, const struct timeval *offer_diff) { // lock offers @@ -88,18 +92,17 @@ static void pretty_print(bencode_item_t *el, GString *s) { } struct control_ng_stats* get_control_ng_stats(struct control_ng* c, const sockaddr_t *addr) { - struct callmaster *m = c->callmaster; struct control_ng_stats* cur; - mutex_lock(&m->cngs_lock); - cur = g_hash_table_lookup(m->cngs_hash, addr); + mutex_lock(&rtpe_cngs_lock); + cur = g_hash_table_lookup(rtpe_cngs_hash, addr); if (!cur) { cur = g_slice_alloc0(sizeof(struct control_ng_stats)); cur->proxy = *addr; ilog(LOG_DEBUG,"Adding a proxy for control ng stats:%s", sockaddr_print_buf(addr)); - g_hash_table_insert(m->cngs_hash, &cur->proxy, cur); + g_hash_table_insert(rtpe_cngs_hash, &cur->proxy, cur); } - mutex_unlock(&m->cngs_lock); + mutex_unlock(&rtpe_cngs_lock); return cur; } @@ -334,3 +337,9 @@ fail2: return NULL; } + + +void control_ng_init() { + mutex_init(&rtpe_cngs_lock); + rtpe_cngs_hash = g_hash_table_new(g_sockaddr_hash, g_sockaddr_eq); +} diff --git a/daemon/control_ng.h b/daemon/control_ng.h index 9851fdae7..8f22bb58c 100644 --- a/daemon/control_ng.h +++ b/daemon/control_ng.h @@ -31,5 +31,9 @@ struct control_ng { }; struct control_ng *control_ng_new(struct poller *, endpoint_t *, struct callmaster *, unsigned char); +void control_ng_init(void); + +extern mutex_t rtpe_cngs_lock; +extern GHashTable *rtpe_cngs_hash; #endif diff --git a/daemon/main.c b/daemon/main.c index b90e70b83..03bfa822c 100644 --- a/daemon/main.c +++ b/daemon/main.c @@ -492,6 +492,7 @@ static void init_everything() { crypto_init_main(); interfaces_init(&interfaces); iptables_init(); + control_ng_init(); } From e87b2710c8ad242bc0763e8534e9bab9479b98cd Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Wed, 3 Jan 2018 10:33:45 -0500 Subject: [PATCH 49/65] move matching regexps out of callmaster into global Change-Id: I42779b3a1b9aef8b98ddecce6fa4093589ab6d62 --- daemon/call.c | 12 ------------ daemon/call.h | 4 ---- daemon/call_interfaces.c | 25 +++++++++++++++++++++++-- daemon/call_interfaces.h | 2 ++ daemon/main.c | 2 ++ 5 files changed, 27 insertions(+), 18 deletions(-) diff --git a/daemon/call.c b/daemon/call.c index 2e6b8687d..bee0f0aa8 100644 --- a/daemon/call.c +++ b/daemon/call.c @@ -610,8 +610,6 @@ next: struct callmaster *callmaster_new(struct poller *p) { struct callmaster *c; - const char *errptr; - int erroff; c = obj_alloc0("callmaster", sizeof(*c), NULL); @@ -621,16 +619,6 @@ struct callmaster *callmaster_new(struct poller *p) { c->poller = p; rwlock_init(&rtpe_callhash_lock); - c->info_re = pcre_compile("^([^:,]+)(?::(.*?))?(?:$|,)", PCRE_DOLLAR_ENDONLY | PCRE_DOTALL, &errptr, &erroff, NULL); - if (!c->info_re) - goto fail; - c->info_ree = pcre_study(c->info_re, 0, &errptr); - - c->streams_re = pcre_compile("^([\\d.]+):(\\d+)(?::(.*?))?(?:$|,)", PCRE_DOLLAR_ENDONLY | PCRE_DOTALL, &errptr, &erroff, NULL); - if (!c->streams_re) - goto fail; - c->streams_ree = pcre_study(c->streams_re, 0, &errptr); - poller_add_timer(p, callmaster_timer, &c->obj); mutex_init(&c->totalstats.total_average_lock); diff --git a/daemon/call.h b/daemon/call.h index a552a7035..ed6e26031 100644 --- a/daemon/call.h +++ b/daemon/call.h @@ -425,10 +425,6 @@ struct callmaster { struct totalstats totalstats_lastinterval; struct poller *poller; - pcre *info_re; - pcre_extra *info_ree; - pcre *streams_re; - pcre_extra *streams_ree; struct callmaster_config conf; struct timeval latest_graphite_interval_start; diff --git a/daemon/call_interfaces.c b/daemon/call_interfaces.c index 34ffb033e..8a8f117db 100644 --- a/daemon/call_interfaces.c +++ b/daemon/call_interfaces.c @@ -26,6 +26,10 @@ #include "streambuf.h" +static pcre *info_re; +static pcre_extra *info_ree; +static pcre *streams_re; +static pcre_extra *streams_ree; int trust_address_def; int dtls_passive_def; @@ -231,7 +235,7 @@ static int info_parse_func(char **a, void **ret, void *p) { } static void info_parse(const char *s, GHashTable *ih, struct callmaster *m) { - pcre_multi_match(m->info_re, m->info_ree, s, 2, info_parse_func, ih, NULL); + pcre_multi_match(info_re, info_ree, s, 2, info_parse_func, ih, NULL); } @@ -271,7 +275,7 @@ fail: static void streams_parse(const char *s, struct callmaster *m, GQueue *q) { int i; i = 0; - pcre_multi_match(m->streams_re, m->streams_ree, s, 3, streams_parse_func, &i, q); + pcre_multi_match(streams_re, streams_ree, s, 3, streams_parse_func, &i, q); } /* XXX move these somewhere else */ @@ -1230,3 +1234,20 @@ const char *call_stop_recording_ng(bencode_item_t *input, struct callmaster *m, return NULL; } + +int call_interfaces_init() { + const char *errptr; + int erroff; + + info_re = pcre_compile("^([^:,]+)(?::(.*?))?(?:$|,)", PCRE_DOLLAR_ENDONLY | PCRE_DOTALL, &errptr, &erroff, NULL); + if (!info_re) + return -1; + info_ree = pcre_study(info_re, 0, &errptr); + + streams_re = pcre_compile("^([\\d.]+):(\\d+)(?::(.*?))?(?:$|,)", PCRE_DOLLAR_ENDONLY | PCRE_DOTALL, &errptr, &erroff, NULL); + if (!streams_re) + return -1; + streams_ree = pcre_study(streams_re, 0, &errptr); + + return 0; +} diff --git a/daemon/call_interfaces.h b/daemon/call_interfaces.h index f414b489a..997329022 100644 --- a/daemon/call_interfaces.h +++ b/daemon/call_interfaces.h @@ -88,5 +88,7 @@ const char *call_stop_recording_ng(bencode_item_t *, struct callmaster *, bencod void ng_call_stats(struct call *call, const str *fromtag, const str *totag, bencode_item_t *output, struct call_stats *totals); +int call_interfaces_init(void); + #endif diff --git a/daemon/main.c b/daemon/main.c index 03bfa822c..ac27cd25b 100644 --- a/daemon/main.c +++ b/daemon/main.c @@ -493,6 +493,8 @@ static void init_everything() { interfaces_init(&interfaces); iptables_init(); control_ng_init(); + if (call_interfaces_init()) + abort(); } From dffbddb2d6c8c52a420bd6b88bc1fe70b5658c44 Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Wed, 3 Jan 2018 10:48:41 -0500 Subject: [PATCH 50/65] don't use g_ prefix for global variables Change-Id: Ifd843b01d7fccf294f97fdf48308c71268e1b8ae --- daemon/aux.c | 4 +-- daemon/aux.h | 4 +-- daemon/call.c | 34 ++++++++++----------- daemon/call_interfaces.c | 4 +-- daemon/control_tcp.c | 2 +- daemon/cookie_cache.c | 6 ++-- daemon/dtls.c | 2 +- daemon/graphite.c | 66 ++++++++++++++++++++-------------------- daemon/ice.c | 34 ++++++++++----------- daemon/iptables.c | 20 ++++++------ daemon/iptables.h | 2 +- daemon/main.c | 8 ++--- daemon/media_socket.c | 4 +-- daemon/poller.c | 12 ++++---- daemon/poller.h | 4 --- daemon/recording.c | 4 +-- daemon/redis.c | 10 +++--- daemon/statistics.c | 2 +- daemon/streambuf.c | 8 ++--- 19 files changed, 113 insertions(+), 117 deletions(-) diff --git a/daemon/aux.c b/daemon/aux.c index 459f781a6..c01c8c027 100644 --- a/daemon/aux.c +++ b/daemon/aux.c @@ -34,8 +34,8 @@ static cond_t threads_cond = COND_STATIC_INIT; static struct thread_buf __thread t_bufs[NUM_THREAD_BUFS]; static int __thread t_buf_idx; -__thread struct timeval g_now; -volatile int g_shutdown; +__thread struct timeval rtpe_now; +volatile int rtpe_shutdown; #ifdef NEED_ATOMIC64_MUTEX mutex_t __atomic64_mutex = MUTEX_STATIC_INIT; diff --git a/daemon/aux.h b/daemon/aux.h index 91315274b..4feb1250b 100644 --- a/daemon/aux.h +++ b/daemon/aux.h @@ -62,8 +62,8 @@ G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \ /*** GLOBALS ***/ -extern __thread struct timeval g_now; -extern volatile int g_shutdown; +extern __thread struct timeval rtpe_now; +extern volatile int rtpe_shutdown; diff --git a/daemon/call.c b/daemon/call.c index bee0f0aa8..92401f2fb 100644 --- a/daemon/call.c +++ b/daemon/call.c @@ -142,7 +142,7 @@ static int call_timer_delete_monologues(struct call *c) { if (!ml->deleted) continue; - if (ml->deleted > poller_now) { + if (ml->deleted > rtpe_now.tv_sec) { if (!min_deleted || ml->deleted < min_deleted) min_deleted = ml->deleted; continue; @@ -188,7 +188,7 @@ static void call_timer_iterator(gpointer data, gpointer user_data) { rwlock_lock_r(&cm->conf.config_lock); // final timeout applicable to all calls (own and foreign) - if (cm->conf.final_timeout && poller_now >= (c->created.tv_sec + cm->conf.final_timeout)) { + if (cm->conf.final_timeout && rtpe_now.tv_sec >= (c->created.tv_sec + cm->conf.final_timeout)) { ilog(LOG_INFO, "Closing call due to final timeout"); tmp_t_reason = FINAL_TIMEOUT; for (it = c->monologues.head; it; it = it->next) { @@ -205,11 +205,11 @@ static void call_timer_iterator(gpointer data, gpointer user_data) { goto out; } - if (c->deleted && poller_now >= c->deleted + if (c->deleted && rtpe_now.tv_sec >= c->deleted && c->last_signal <= c->deleted) goto delete; - if (c->ml_deleted && poller_now >= c->ml_deleted) { + if (c->ml_deleted && rtpe_now.tv_sec >= c->ml_deleted) { if (call_timer_delete_monologues(c)) goto delete; } @@ -250,7 +250,7 @@ no_sfd: tmp_t_reason = SILENT_TIMEOUT; } - if (poller_now - atomic64_get(timestamp) < check) + if (rtpe_now.tv_sec - atomic64_get(timestamp) < check) good = 1; next: @@ -525,7 +525,7 @@ static void callmaster_timer(void *ptr) { if (ke->stats.packets != atomic64_get(&ps->kernel_stats.packets)) - atomic64_set(&ps->last_packet, poller_now); + atomic64_set(&ps->last_packet, rtpe_now.tv_sec); ps->stats.in_tos_tclass = ke->stats.in_tos; @@ -626,7 +626,7 @@ struct callmaster *callmaster_new(struct poller *p) { mutex_init(&c->totalstats_interval.managed_sess_lock); mutex_init(&c->totalstats_interval.total_calls_duration_lock); - c->totalstats.started = poller_now; + c->totalstats.started = rtpe_now.tv_sec; //c->totalstats_interval.managed_sess_min = 0; // already zeroed //c->totalstats_interval.managed_sess_max = 0; @@ -834,7 +834,7 @@ struct packet_stream *__packet_stream_new(struct call *call) { mutex_init(&stream->in_lock); mutex_init(&stream->out_lock); stream->call = call; - atomic64_set_na(&stream->last_packet, poller_now); + atomic64_set_na(&stream->last_packet, rtpe_now.tv_sec); stream->rtp_stats = g_hash_table_new_full(g_int_hash, g_int_equal, NULL, __rtp_stats_free); recording_init_stream(stream); @@ -1508,7 +1508,7 @@ int monologue_offer_answer(struct call_monologue *other_ml, GQueue *streams, monologue = other_ml->active_dialogue; call = monologue->call; - call->last_signal = poller_now; + call->last_signal = rtpe_now.tv_sec; call->deleted = 0; __C_DBG("this="STR_FORMAT" other="STR_FORMAT, STR_FMT(&monologue->tag), STR_FMT(&other_ml->tag)); @@ -1756,7 +1756,7 @@ static struct timeval add_ongoing_calls_dur_in_interval(struct callmaster *m, if (timercmp(interval_start, &ml->started, >)) { timeval_add(&res, &res, interval_duration); } else { - timeval_subtract(&call_duration, &g_now, &ml->started); + timeval_subtract(&call_duration, &rtpe_now, &ml->started); timeval_add(&res, &res, &call_duration); } } @@ -1820,8 +1820,8 @@ void call_destroy(struct call *c) { ml->label.s ? " (label '" : "", STR_FMT(ml->label.s ? &ml->label : &STR_EMPTY), ml->label.s ? "')" : "", - (unsigned int) (poller_now - ml->created) / 60, - (unsigned int) (poller_now - ml->created) % 60, + (unsigned int) (rtpe_now.tv_sec - ml->created) / 60, + (unsigned int) (rtpe_now.tv_sec - ml->created) % 60, STR_FMT(&ml->viabranch), ml->active_dialogue ? ml->active_dialogue->tag.len : 6, ml->active_dialogue ? ml->active_dialogue->tag.s : "(none)"); @@ -1860,7 +1860,7 @@ void call_destroy(struct call *c) { atomic64_get(&ps->stats.packets), atomic64_get(&ps->stats.bytes), atomic64_get(&ps->stats.errors), - g_now.tv_sec - atomic64_get(&ps->last_packet)); + rtpe_now.tv_sec - atomic64_get(&ps->last_packet)); statistics_update_totals(m,ps); @@ -2024,7 +2024,7 @@ static struct call *call_create(const str *callid, struct callmaster *m) { c->tags = g_hash_table_new(str_hash, str_equal); c->viabranches = g_hash_table_new(str_hash, str_equal); call_str_cpy(c, &c->callid, callid); - c->created = g_now; + c->created = rtpe_now; c->dtls_cert = dtls_cert(); c->tos = m->conf.default_tos; c->ssrc_hash = create_ssrc_hash(); @@ -2104,7 +2104,7 @@ struct call_monologue *__monologue_create(struct call *call) { ret = uid_slice_alloc0(ret, &call->monologues); ret->call = call; - ret->created = poller_now; + ret->created = rtpe_now.tv_sec; ret->other_tags = g_hash_table_new(str_hash, str_equal); g_queue_init(&ret->medias); @@ -2428,7 +2428,7 @@ do_delete: ilog(LOG_INFO, "Scheduling deletion of call branch '"STR_FORMAT"' " "(via-branch '"STR_FORMAT"') in %d seconds", STR_FMT(&ml->tag), STR_FMT0(branch), delete_delay); - ml->deleted = poller_now + delete_delay; + ml->deleted = rtpe_now.tv_sec + delete_delay; if (!c->ml_deleted || c->ml_deleted > ml->deleted) c->ml_deleted = ml->deleted; } @@ -2443,7 +2443,7 @@ do_delete: del_all: if (delete_delay > 0) { ilog(LOG_INFO, "Scheduling deletion of entire call in %d seconds", delete_delay); - c->deleted = poller_now + delete_delay; + c->deleted = rtpe_now.tv_sec + delete_delay; rwlock_unlock_w(&c->master_lock); } else { diff --git a/daemon/call_interfaces.c b/daemon/call_interfaces.c index 8a8f117db..dc91ca24c 100644 --- a/daemon/call_interfaces.c +++ b/daemon/call_interfaces.c @@ -398,7 +398,7 @@ str *call_query_udp(char **out, struct callmaster *m) { rwlock_lock_r(&m->conf.config_lock); ret = str_sprintf("%s %lld "UINT64F" "UINT64F" "UINT64F" "UINT64F"\n", out[RE_UDP_COOKIE], - (long long int) m->conf.silent_timeout - (poller_now - stats.last_packet), + (long long int) m->conf.silent_timeout - (rtpe_now.tv_sec - stats.last_packet), atomic64_get_na(&stats.totals[0].packets), atomic64_get_na(&stats.totals[1].packets), atomic64_get_na(&stats.totals[2].packets), atomic64_get_na(&stats.totals[3].packets)); rwlock_unlock_r(&m->conf.config_lock); @@ -437,7 +437,7 @@ static void call_status_iterator(struct call *c, struct streambuf_stream *s) { streambuf_printf(s->outbuf, "session "STR_FORMAT" - - - - %lli\n", STR_FMT(&c->callid), - timeval_diff(&g_now, &c->created) / 1000000); + timeval_diff(&rtpe_now, &c->created) / 1000000); /* XXX restore function */ diff --git a/daemon/control_tcp.c b/daemon/control_tcp.c index 6ffb29d3f..c5a893fdb 100644 --- a/daemon/control_tcp.c +++ b/daemon/control_tcp.c @@ -117,7 +117,7 @@ static int control_stream_parse(struct streambuf_stream *s, char *line) { static void control_stream_timer(struct streambuf_stream *s) { - if ((poller_now - s->inbuf->active) >= 60 || (poller_now - s->outbuf->active) >= 60) + if ((rtpe_now.tv_sec - s->inbuf->active) >= 60 || (rtpe_now.tv_sec - s->outbuf->active) >= 60) control_stream_closed(s); } diff --git a/daemon/cookie_cache.c b/daemon/cookie_cache.c index 8f5b2052d..bbcf7c552 100644 --- a/daemon/cookie_cache.c +++ b/daemon/cookie_cache.c @@ -18,19 +18,19 @@ INLINE void cookie_cache_state_init(struct cookie_cache_state *s) { void cookie_cache_init(struct cookie_cache *c) { cookie_cache_state_init(&c->current); cookie_cache_state_init(&c->old); - c->swap_time = poller_now; + c->swap_time = rtpe_now.tv_sec; mutex_init(&c->lock); cond_init(&c->cond); } /* lock must be held */ static void __cookie_cache_check_swap(struct cookie_cache *c) { - if (poller_now - c->swap_time >= 30) { + if (rtpe_now.tv_sec - c->swap_time >= 30) { g_hash_table_remove_all(c->old.cookies); g_string_chunk_clear(c->old.chunks); swap_ptrs(&c->old.chunks, &c->current.chunks); swap_ptrs(&c->old.cookies, &c->current.cookies); - c->swap_time = poller_now; + c->swap_time = rtpe_now.tv_sec; } } diff --git a/daemon/dtls.c b/daemon/dtls.c index 9943901e7..3915b39fe 100644 --- a/daemon/dtls.c +++ b/daemon/dtls.c @@ -317,7 +317,7 @@ static void __dtls_timer(void *p) { long int left; c = dtls_cert(); - left = c->expires - poller_now; + left = c->expires - rtpe_now.tv_sec; if (left > CERT_EXPIRY_TIME/2) goto out; diff --git a/daemon/graphite.c b/daemon/graphite.c index d634fa831..8502eec6c 100644 --- a/daemon/graphite.c +++ b/daemon/graphite.c @@ -25,7 +25,7 @@ static socket_t graphite_sock; static int connection_state = STATE_DISCONNECTED; //struct totalstats totalstats_prev; static time_t next_run; -// HEAD: static time_t g_now, next_run; +// HEAD: static time_t rtpe_now, next_run; static char* graphite_prefix = NULL; static struct timeval graphite_interval_tv; static struct totalstats graphite_stats; @@ -149,69 +149,69 @@ int send_graphite_data(struct callmaster *cm, struct totalstats *sent_data) { timeval_divide(&ts->delete.time_avg, &ts->delete.time_avg, ts->delete.count); if (graphite_prefix!=NULL) { rc = sprintf(ptr,"%s",graphite_prefix); ptr += rc; } - rc = sprintf(ptr,"offer_time_min %llu.%06llu %llu\n",(unsigned long long)ts->offer.time_min.tv_sec,(unsigned long long)ts->offer.time_min.tv_usec,(unsigned long long)g_now.tv_sec); ptr += rc; + rc = sprintf(ptr,"offer_time_min %llu.%06llu %llu\n",(unsigned long long)ts->offer.time_min.tv_sec,(unsigned long long)ts->offer.time_min.tv_usec,(unsigned long long)rtpe_now.tv_sec); ptr += rc; if (graphite_prefix!=NULL) { rc = sprintf(ptr,"%s",graphite_prefix); ptr += rc; } - rc = sprintf(ptr,"offer_time_max %llu.%06llu %llu\n",(unsigned long long)ts->offer.time_max.tv_sec,(unsigned long long)ts->offer.time_max.tv_usec,(unsigned long long)g_now.tv_sec); ptr += rc; + rc = sprintf(ptr,"offer_time_max %llu.%06llu %llu\n",(unsigned long long)ts->offer.time_max.tv_sec,(unsigned long long)ts->offer.time_max.tv_usec,(unsigned long long)rtpe_now.tv_sec); ptr += rc; if (graphite_prefix!=NULL) { rc = sprintf(ptr,"%s",graphite_prefix); ptr += rc; } - rc = sprintf(ptr,"offer_time_avg %llu.%06llu %llu\n",(unsigned long long)ts->offer.time_avg.tv_sec,(unsigned long long)ts->offer.time_avg.tv_usec,(unsigned long long)g_now.tv_sec); ptr += rc; + rc = sprintf(ptr,"offer_time_avg %llu.%06llu %llu\n",(unsigned long long)ts->offer.time_avg.tv_sec,(unsigned long long)ts->offer.time_avg.tv_usec,(unsigned long long)rtpe_now.tv_sec); ptr += rc; if (graphite_prefix!=NULL) { rc = sprintf(ptr,"%s",graphite_prefix); ptr += rc; } - rc = sprintf(ptr,"answer_time_min %llu.%06llu %llu\n",(unsigned long long)ts->answer.time_min.tv_sec,(unsigned long long)ts->answer.time_min.tv_usec,(unsigned long long)g_now.tv_sec); ptr += rc; + rc = sprintf(ptr,"answer_time_min %llu.%06llu %llu\n",(unsigned long long)ts->answer.time_min.tv_sec,(unsigned long long)ts->answer.time_min.tv_usec,(unsigned long long)rtpe_now.tv_sec); ptr += rc; if (graphite_prefix!=NULL) { rc = sprintf(ptr,"%s",graphite_prefix); ptr += rc; } - rc = sprintf(ptr,"answer_time_max %llu.%06llu %llu\n",(unsigned long long)ts->answer.time_max.tv_sec,(unsigned long long)ts->answer.time_max.tv_usec,(unsigned long long)g_now.tv_sec); ptr += rc; + rc = sprintf(ptr,"answer_time_max %llu.%06llu %llu\n",(unsigned long long)ts->answer.time_max.tv_sec,(unsigned long long)ts->answer.time_max.tv_usec,(unsigned long long)rtpe_now.tv_sec); ptr += rc; if (graphite_prefix!=NULL) { rc = sprintf(ptr,"%s",graphite_prefix); ptr += rc; } - rc = sprintf(ptr,"answer_time_avg %llu.%06llu %llu\n",(unsigned long long)ts->answer.time_avg.tv_sec,(unsigned long long)ts->answer.time_avg.tv_usec,(unsigned long long)g_now.tv_sec); ptr += rc; + rc = sprintf(ptr,"answer_time_avg %llu.%06llu %llu\n",(unsigned long long)ts->answer.time_avg.tv_sec,(unsigned long long)ts->answer.time_avg.tv_usec,(unsigned long long)rtpe_now.tv_sec); ptr += rc; if (graphite_prefix!=NULL) { rc = sprintf(ptr,"%s",graphite_prefix); ptr += rc; } - rc = sprintf(ptr,"delete_time_min %llu.%06llu %llu\n",(unsigned long long)ts->delete.time_min.tv_sec,(unsigned long long)ts->delete.time_min.tv_usec,(unsigned long long)g_now.tv_sec); ptr += rc; + rc = sprintf(ptr,"delete_time_min %llu.%06llu %llu\n",(unsigned long long)ts->delete.time_min.tv_sec,(unsigned long long)ts->delete.time_min.tv_usec,(unsigned long long)rtpe_now.tv_sec); ptr += rc; if (graphite_prefix!=NULL) { rc = sprintf(ptr,"%s",graphite_prefix); ptr += rc; } - rc = sprintf(ptr,"delete_time_max %llu.%06llu %llu\n",(unsigned long long)ts->delete.time_max.tv_sec,(unsigned long long)ts->delete.time_max.tv_usec,(unsigned long long)g_now.tv_sec); ptr += rc; + rc = sprintf(ptr,"delete_time_max %llu.%06llu %llu\n",(unsigned long long)ts->delete.time_max.tv_sec,(unsigned long long)ts->delete.time_max.tv_usec,(unsigned long long)rtpe_now.tv_sec); ptr += rc; if (graphite_prefix!=NULL) { rc = sprintf(ptr,"%s",graphite_prefix); ptr += rc; } - rc = sprintf(ptr,"delete_time_avg %llu.%06llu %llu\n",(unsigned long long)ts->delete.time_avg.tv_sec,(unsigned long long)ts->delete.time_avg.tv_usec,(unsigned long long)g_now.tv_sec); ptr += rc; + rc = sprintf(ptr,"delete_time_avg %llu.%06llu %llu\n",(unsigned long long)ts->delete.time_avg.tv_sec,(unsigned long long)ts->delete.time_avg.tv_usec,(unsigned long long)rtpe_now.tv_sec); ptr += rc; if (graphite_prefix!=NULL) { rc = sprintf(ptr,"%s",graphite_prefix); ptr += rc; } - rc = sprintf(ptr, "call_dur %llu.%06llu %llu\n",(unsigned long long)ts->total_calls_duration_interval.tv_sec,(unsigned long long)ts->total_calls_duration_interval.tv_usec,(unsigned long long)g_now.tv_sec); ptr += rc; + rc = sprintf(ptr, "call_dur %llu.%06llu %llu\n",(unsigned long long)ts->total_calls_duration_interval.tv_sec,(unsigned long long)ts->total_calls_duration_interval.tv_usec,(unsigned long long)rtpe_now.tv_sec); ptr += rc; if (graphite_prefix!=NULL) { rc = sprintf(ptr,"%s",graphite_prefix); ptr += rc; } - rc = sprintf(ptr,"average_call_dur %llu.%06llu %llu\n",(unsigned long long)ts->total_average_call_dur.tv_sec,(unsigned long long)ts->total_average_call_dur.tv_usec,(unsigned long long)g_now.tv_sec); ptr += rc; + rc = sprintf(ptr,"average_call_dur %llu.%06llu %llu\n",(unsigned long long)ts->total_average_call_dur.tv_sec,(unsigned long long)ts->total_average_call_dur.tv_usec,(unsigned long long)rtpe_now.tv_sec); ptr += rc; if (graphite_prefix!=NULL) { rc = sprintf(ptr,"%s",graphite_prefix); ptr += rc; } - rc = sprintf(ptr,"forced_term_sess "UINT64F" %llu\n", atomic64_get_na(&ts->total_forced_term_sess),(unsigned long long)g_now.tv_sec); ptr += rc; + rc = sprintf(ptr,"forced_term_sess "UINT64F" %llu\n", atomic64_get_na(&ts->total_forced_term_sess),(unsigned long long)rtpe_now.tv_sec); ptr += rc; if (graphite_prefix!=NULL) { rc = sprintf(ptr,"%s",graphite_prefix); ptr += rc; } - rc = sprintf(ptr,"managed_sess "UINT64F" %llu\n", ts->total_managed_sess,(unsigned long long)g_now.tv_sec); ptr += rc; + rc = sprintf(ptr,"managed_sess "UINT64F" %llu\n", ts->total_managed_sess,(unsigned long long)rtpe_now.tv_sec); ptr += rc; if (graphite_prefix!=NULL) { rc = sprintf(ptr,"%s",graphite_prefix); ptr += rc; } - rc = sprintf(ptr,"managed_sess_min "UINT64F" %llu\n", ts->managed_sess_min,(unsigned long long)g_now.tv_sec); ptr += rc; + rc = sprintf(ptr,"managed_sess_min "UINT64F" %llu\n", ts->managed_sess_min,(unsigned long long)rtpe_now.tv_sec); ptr += rc; if (graphite_prefix!=NULL) { rc = sprintf(ptr,"%s",graphite_prefix); ptr += rc; } - rc = sprintf(ptr,"managed_sess_max "UINT64F" %llu\n", ts->managed_sess_max,(unsigned long long)g_now.tv_sec); ptr += rc; + rc = sprintf(ptr,"managed_sess_max "UINT64F" %llu\n", ts->managed_sess_max,(unsigned long long)rtpe_now.tv_sec); ptr += rc; if (graphite_prefix!=NULL) { rc = sprintf(ptr,"%s",graphite_prefix); ptr += rc; } - rc = sprintf(ptr,"current_sessions_total "UINT64F" %llu\n", ts->total_sessions,(unsigned long long)g_now.tv_sec); ptr += rc; + rc = sprintf(ptr,"current_sessions_total "UINT64F" %llu\n", ts->total_sessions,(unsigned long long)rtpe_now.tv_sec); ptr += rc; if (graphite_prefix!=NULL) { rc = sprintf(ptr,"%s",graphite_prefix); ptr += rc; } - rc = sprintf(ptr,"current_sessions_own "UINT64F" %llu\n", ts->own_sessions,(unsigned long long)g_now.tv_sec); ptr += rc; + rc = sprintf(ptr,"current_sessions_own "UINT64F" %llu\n", ts->own_sessions,(unsigned long long)rtpe_now.tv_sec); ptr += rc; if (graphite_prefix!=NULL) { rc = sprintf(ptr,"%s",graphite_prefix); ptr += rc; } - rc = sprintf(ptr,"current_sessions_foreign "UINT64F" %llu\n", ts->foreign_sessions,(unsigned long long)g_now.tv_sec); ptr += rc; + rc = sprintf(ptr,"current_sessions_foreign "UINT64F" %llu\n", ts->foreign_sessions,(unsigned long long)rtpe_now.tv_sec); ptr += rc; if (graphite_prefix!=NULL) { rc = sprintf(ptr,"%s",graphite_prefix); ptr += rc; } - rc = sprintf(ptr,"nopacket_relayed_sess "UINT64F" %llu\n", atomic64_get_na(&ts->total_nopacket_relayed_sess),(unsigned long long)g_now.tv_sec); ptr += rc; + rc = sprintf(ptr,"nopacket_relayed_sess "UINT64F" %llu\n", atomic64_get_na(&ts->total_nopacket_relayed_sess),(unsigned long long)rtpe_now.tv_sec); ptr += rc; if (graphite_prefix!=NULL) { rc = sprintf(ptr,"%s",graphite_prefix); ptr += rc; } - rc = sprintf(ptr,"oneway_stream_sess "UINT64F" %llu\n", atomic64_get_na(&ts->total_oneway_stream_sess),(unsigned long long)g_now.tv_sec); ptr += rc; + rc = sprintf(ptr,"oneway_stream_sess "UINT64F" %llu\n", atomic64_get_na(&ts->total_oneway_stream_sess),(unsigned long long)rtpe_now.tv_sec); ptr += rc; if (graphite_prefix!=NULL) { rc = sprintf(ptr,"%s",graphite_prefix); ptr += rc; } - rc = sprintf(ptr,"regular_term_sess "UINT64F" %llu\n", atomic64_get_na(&ts->total_regular_term_sess),(unsigned long long)g_now.tv_sec); ptr += rc; + rc = sprintf(ptr,"regular_term_sess "UINT64F" %llu\n", atomic64_get_na(&ts->total_regular_term_sess),(unsigned long long)rtpe_now.tv_sec); ptr += rc; if (graphite_prefix!=NULL) { rc = sprintf(ptr,"%s",graphite_prefix); ptr += rc; } - rc = sprintf(ptr,"relayed_errors "UINT64F" %llu\n", atomic64_get_na(&ts->total_relayed_errors),(unsigned long long)g_now.tv_sec); ptr += rc; + rc = sprintf(ptr,"relayed_errors "UINT64F" %llu\n", atomic64_get_na(&ts->total_relayed_errors),(unsigned long long)rtpe_now.tv_sec); ptr += rc; if (graphite_prefix!=NULL) { rc = sprintf(ptr,"%s",graphite_prefix); ptr += rc; } - rc = sprintf(ptr,"relayed_packets "UINT64F" %llu\n", atomic64_get_na(&ts->total_relayed_packets),(unsigned long long)g_now.tv_sec); ptr += rc; + rc = sprintf(ptr,"relayed_packets "UINT64F" %llu\n", atomic64_get_na(&ts->total_relayed_packets),(unsigned long long)rtpe_now.tv_sec); ptr += rc; if (graphite_prefix!=NULL) { rc = sprintf(ptr,"%s",graphite_prefix); ptr += rc; } - rc = sprintf(ptr,"silent_timeout_sess "UINT64F" %llu\n", atomic64_get_na(&ts->total_silent_timeout_sess),(unsigned long long)g_now.tv_sec); ptr += rc; + rc = sprintf(ptr,"silent_timeout_sess "UINT64F" %llu\n", atomic64_get_na(&ts->total_silent_timeout_sess),(unsigned long long)rtpe_now.tv_sec); ptr += rc; if (graphite_prefix!=NULL) { rc = sprintf(ptr,"%s",graphite_prefix); ptr += rc; } - rc = sprintf(ptr,"final_timeout_sess "UINT64F" %llu\n", atomic64_get_na(&ts->total_final_timeout_sess),(unsigned long long)g_now.tv_sec); ptr += rc; + rc = sprintf(ptr,"final_timeout_sess "UINT64F" %llu\n", atomic64_get_na(&ts->total_final_timeout_sess),(unsigned long long)rtpe_now.tv_sec); ptr += rc; if (graphite_prefix!=NULL) { rc = sprintf(ptr,"%s",graphite_prefix); ptr += rc; } - rc = sprintf(ptr,"timeout_sess "UINT64F" %llu\n", atomic64_get_na(&ts->total_timeout_sess),(unsigned long long)g_now.tv_sec); ptr += rc; + rc = sprintf(ptr,"timeout_sess "UINT64F" %llu\n", atomic64_get_na(&ts->total_timeout_sess),(unsigned long long)rtpe_now.tv_sec); ptr += rc; if (graphite_prefix!=NULL) { rc = sprintf(ptr,"%s",graphite_prefix); ptr += rc; } - rc = sprintf(ptr,"reject_sess "UINT64F" %llu\n", atomic64_get_na(&ts->total_rejected_sess),(unsigned long long)g_now.tv_sec); ptr += rc; + rc = sprintf(ptr,"reject_sess "UINT64F" %llu\n", atomic64_get_na(&ts->total_rejected_sess),(unsigned long long)rtpe_now.tv_sec); ptr += rc; ilog(LOG_DEBUG, "min_sessions:%llu max_sessions:%llu, call_dur_per_interval:%llu.%06llu at time %llu\n", (unsigned long long) ts->managed_sess_min, (unsigned long long) ts->managed_sess_max, (unsigned long long ) ts->total_calls_duration_interval.tv_sec, (unsigned long long ) ts->total_calls_duration_interval.tv_usec, - (unsigned long long ) g_now.tv_sec); + (unsigned long long ) rtpe_now.tv_sec); ilog(LOG_DEBUG, "Min/Max/Avg offer processing delay: %llu.%06llu/%llu.%06llu/%llu.%06llu sec", (unsigned long long)ts->offer.time_min.tv_sec,(unsigned long long)ts->offer.time_min.tv_usec, @@ -294,13 +294,13 @@ void graphite_loop_run(struct callmaster *cm, endpoint_t *graphite_ep, int secon } } - gettimeofday(&g_now, NULL); - if (g_now.tv_sec < next_run) { + gettimeofday(&rtpe_now, NULL); + if (rtpe_now.tv_sec < next_run) { usleep(100000); return; } - next_run = g_now.tv_sec + seconds; + next_run = rtpe_now.tv_sec + seconds; if (graphite_sock.fd < 0 && connection_state == STATE_DISCONNECTED) { connect_to_graphite_server(graphite_ep); @@ -338,6 +338,6 @@ void graphite_loop(void *d) { connect_to_graphite_server(&cm->conf.graphite_ep); - while (!g_shutdown) + while (!rtpe_shutdown) graphite_loop_run(cm, &cm->conf.graphite_ep, cm->conf.graphite_interval); // time in seconds } diff --git a/daemon/ice.c b/daemon/ice.c index 7b9171138..7238f562e 100644 --- a/daemon/ice.c +++ b/daemon/ice.c @@ -240,7 +240,7 @@ static void __ice_agent_initialize(struct ice_agent *ag) { create_random_ice_string(call, &ag->ufrag[1], 8); create_random_ice_string(call, &ag->pwd[1], 26); - atomic64_set(&ag->last_activity, poller_now); + atomic64_set(&ag->last_activity, rtpe_now.tv_sec); } static struct ice_agent *__ice_agent_new(struct call_media *media) { @@ -315,7 +315,7 @@ void ice_update(struct ice_agent *ag, struct stream_params *sp) { if (!ag) return; - atomic64_set(&ag->last_activity, poller_now); + atomic64_set(&ag->last_activity, rtpe_now.tv_sec); media = ag->media; call = media->call; @@ -519,7 +519,7 @@ static void __ice_agent_free(void *p) { static void __agent_schedule(struct ice_agent *ag, unsigned long usec) { struct timeval nxt; - nxt = g_now; + nxt = rtpe_now; timeval_add_usec(&nxt, usec); __agent_schedule_abs(ag, &nxt); } @@ -622,7 +622,7 @@ static void __do_ice_check(struct ice_candidate_pair *pair) { mutex_lock(&ag->lock); - pair->retransmit = g_now; + pair->retransmit = rtpe_now; if (!PAIR_SET(pair, IN_PROGRESS)) { PAIR_CLEAR2(pair, FROZEN, FAILED); pair->retransmit_ms = STUN_RETRANSMIT_INTERVAL; @@ -721,7 +721,7 @@ static void __do_ice_checks(struct ice_agent *ag) { if (!ag->pwd[0].s) return; - atomic64_set(&ag->last_activity, poller_now); + atomic64_set(&ag->last_activity, rtpe_now.tv_sec); __DBG("running checks, call "STR_FORMAT" tag "STR_FORMAT"", STR_FMT(&ag->call->callid), STR_FMT(&ag->media->monologue->tag)); @@ -730,7 +730,7 @@ static void __do_ice_checks(struct ice_agent *ag) { /* check if we're done and should start nominating pairs */ if (AGENT_ISSET(ag, CONTROLLING) && !AGENT_ISSET(ag, NOMINATING) && ag->start_nominating.tv_sec) { - if (timeval_cmp(&g_now, &ag->start_nominating) >= 0) + if (timeval_cmp(&rtpe_now, &ag->start_nominating) >= 0) __nominate_pairs(ag); timeval_lowest(&next_run, &ag->start_nominating); } @@ -739,7 +739,7 @@ static void __do_ice_checks(struct ice_agent *ag) { pair = g_queue_pop_head(&ag->triggered); if (pair) { PAIR_CLEAR(pair, TRIGGERED); - next_run = g_now; + next_run = rtpe_now; goto check; } @@ -764,7 +764,7 @@ static void __do_ice_checks(struct ice_agent *ag) { if (valid && valid->pair_priority > pair->pair_priority) continue; - if (timeval_cmp(&pair->retransmit, &g_now) <= 0) + if (timeval_cmp(&pair->retransmit, &rtpe_now) <= 0) g_queue_push_tail(&retransmits, pair); /* can't run check directly due to locks */ else @@ -1090,7 +1090,7 @@ int ice_request(struct stream_fd *sfd, const endpoint_t *src, if (!ag) return -1; - atomic64_set(&ag->last_activity, poller_now); + atomic64_set(&ag->last_activity, rtpe_now.tv_sec); /* determine candidate pair */ mutex_lock(&ag->lock); @@ -1198,7 +1198,7 @@ int ice_response(struct stream_fd *sfd, const endpoint_t *src, if (!ag) return -1; - atomic64_set(&ag->last_activity, poller_now); + atomic64_set(&ag->last_activity, rtpe_now.tv_sec); mutex_lock(&ag->lock); @@ -1261,7 +1261,7 @@ int ice_response(struct stream_fd *sfd, const endpoint_t *src, if (!ag->start_nominating.tv_sec) { if (__check_succeeded_complete(ag)) { - ag->start_nominating = g_now; + ag->start_nominating = rtpe_now; timeval_add_usec(&ag->start_nominating, 100000); __agent_schedule_abs(ag, &ag->start_nominating); } @@ -1323,8 +1323,8 @@ void ice_thread_run(void *p) { mutex_lock(&ice_agents_timers_lock); - while (!g_shutdown) { - gettimeofday(&g_now, NULL); + while (!rtpe_shutdown) { + gettimeofday(&rtpe_now, NULL); /* lock our list and get the first element */ ag = g_tree_find_first(ice_agents_timers, NULL, NULL); @@ -1332,12 +1332,12 @@ void ice_thread_run(void *p) { * steal the reference and run it */ if (!ag) goto sleep; - if (timeval_cmp(&g_now, &ag->next_check) < 0) + if (timeval_cmp(&rtpe_now, &ag->next_check) < 0) goto sleep; g_tree_remove(ice_agents_timers, ag); ZERO(ag->next_check); - ag->last_run = g_now; + ag->last_run = rtpe_now; mutex_unlock(&ice_agents_timers_lock); /* this agent is scheduled to run right now */ @@ -1359,9 +1359,9 @@ void ice_thread_run(void *p) { sleep: /* figure out how long we should sleep */ - sleeptime = ag ? timeval_diff(&ag->next_check, &g_now) : 100000; + sleeptime = ag ? timeval_diff(&ag->next_check, &rtpe_now) : 100000; sleeptime = MIN(100000, sleeptime); /* 100 ms at the most */ - tv = g_now; + tv = rtpe_now; timeval_add_usec(&tv, sleeptime); cond_timedwait(&ice_agents_timers_cond, &ice_agents_timers_lock, &tv); continue; diff --git a/daemon/iptables.c b/daemon/iptables.c index 84981113f..7a81e5476 100644 --- a/daemon/iptables.c +++ b/daemon/iptables.c @@ -1,6 +1,6 @@ #include "iptables.h" -char *g_iptables_chain; +char *rtpe_iptables_chain; int (*iptables_add_rule)(const socket_t *local_sock, const str *comment); int (*iptables_del_rule)(const socket_t *local_sock); @@ -139,7 +139,7 @@ static const char *ip4tables_add_rule(const socket_t *local_sock, const str *com ip4_fill_entry(&entry, local_sock, comment); err = "failed to append iptables entry"; - if (!iptc_append_entry(g_iptables_chain, &entry.entry, h)) + if (!iptc_append_entry(rtpe_iptables_chain, &entry.entry, h)) goto err; err = "failed to commit iptables changes"; if (!iptc_commit(h)) @@ -169,7 +169,7 @@ static const char *ip6tables_add_rule(const socket_t *local_sock, const str *com ip6_fill_entry(&entry, local_sock, comment); err = "failed to append ip6tables entry"; - if (!ip6tc_append_entry(g_iptables_chain, &entry.entry, h)) + if (!ip6tc_append_entry(rtpe_iptables_chain, &entry.entry, h)) goto err; err = "failed to commit ip6tables changes"; if (!ip6tc_commit(h)) @@ -207,7 +207,7 @@ static const char *ip4tables_del_rule(const socket_t *local_sock) { memset(&mask.matches.target, 0xff, sizeof(mask.matches.target)); err = "failed to delete iptables entry"; - if (!iptc_delete_entry(g_iptables_chain, &entry.entry, (unsigned char *) &mask, h)) + if (!iptc_delete_entry(rtpe_iptables_chain, &entry.entry, (unsigned char *) &mask, h)) goto err; err = "failed to commit iptables changes"; if (!iptc_commit(h)) @@ -245,7 +245,7 @@ static const char *ip6tables_del_rule(const socket_t *local_sock) { memset(&mask.matches.target, 0xff, sizeof(mask.matches.target)); err = "failed to delete ip6tables entry"; - if (!ip6tc_delete_entry(g_iptables_chain, &entry.entry, (unsigned char *) &mask, h)) + if (!ip6tc_delete_entry(rtpe_iptables_chain, &entry.entry, (unsigned char *) &mask, h)) goto err; err = "failed to commit ip6tables changes"; if (!ip6tc_commit(h)) @@ -313,10 +313,10 @@ static int __iptables_stub(void) { void iptables_init(void) { - if (g_iptables_chain && !g_iptables_chain[0]) - g_iptables_chain = NULL; + if (rtpe_iptables_chain && !rtpe_iptables_chain[0]) + rtpe_iptables_chain = NULL; - if (!g_iptables_chain) { + if (!rtpe_iptables_chain) { iptables_add_rule = (void *) __iptables_stub; iptables_del_rule = (void *) __iptables_stub; return; @@ -340,7 +340,7 @@ void iptables_init(void) { if (!h) goto out; err = "could not flush iptables chain"; - if (!iptc_flush_entries(g_iptables_chain, h)) + if (!iptc_flush_entries(rtpe_iptables_chain, h)) goto err2; err = "could not commit iptables changes"; if (!iptc_commit(h)) @@ -352,7 +352,7 @@ void iptables_init(void) { if (!h) goto out; err = "could not flush ip6tables chain"; - if (!ip6tc_flush_entries(g_iptables_chain, h)) + if (!ip6tc_flush_entries(rtpe_iptables_chain, h)) goto err1; err = "could not commit iptables changes"; if (!ip6tc_commit(h)) diff --git a/daemon/iptables.h b/daemon/iptables.h index 77f988550..96cd24e26 100644 --- a/daemon/iptables.h +++ b/daemon/iptables.h @@ -6,7 +6,7 @@ #include "str.h" -extern char *g_iptables_chain; +extern char *rtpe_iptables_chain; void iptables_init(void); extern int (*iptables_add_rule)(const socket_t *local_sock, const str *comment); diff --git a/daemon/main.c b/daemon/main.c index ac27cd25b..73e1729d9 100644 --- a/daemon/main.c +++ b/daemon/main.c @@ -97,7 +97,7 @@ static void sighandler(gpointer x) { ts.tv_sec = 0; ts.tv_nsec = 100000000; /* 0.1 sec */ - while (!g_shutdown) { + while (!rtpe_shutdown) { ret = sigtimedwait(&ss, NULL, &ts); if (ret == -1) { if (errno == EAGAIN || errno == EINTR) @@ -106,7 +106,7 @@ static void sighandler(gpointer x) { } if (ret == SIGINT || ret == SIGTERM) - g_shutdown = 1; + rtpe_shutdown = 1; else if (ret == SIGUSR1) { if (get_log_level() > 0) { g_atomic_int_add(&log_level, -1); @@ -300,7 +300,7 @@ static void options(int *argc, char ***argv) { { "recording-method",0, 0, G_OPTION_ARG_STRING, &rec_method, "Strategy for call recording", "pcap|proc" }, { "recording-format",0, 0, G_OPTION_ARG_STRING, &rec_format, "File format for stored pcap files", "raw|eth" }, #ifdef WITH_IPTABLES_OPTION - { "iptables-chain",0,0, G_OPTION_ARG_STRING, &g_iptables_chain,"Add explicit firewall rules to this iptables chain","STRING" }, + { "iptables-chain",0,0, G_OPTION_ARG_STRING, &rtpe_iptables_chain,"Add explicit firewall rules to this iptables chain","STRING" }, #endif { NULL, } }; @@ -674,7 +674,7 @@ int main(int argc, char **argv) { thread_create_detach(poller_loop, ctx.p); } - while (!g_shutdown) { + while (!rtpe_shutdown) { usleep(100000); threads_join_all(0); } diff --git a/daemon/media_socket.c b/daemon/media_socket.c index b9381ab52..4582e13cc 100644 --- a/daemon/media_socket.c +++ b/daemon/media_socket.c @@ -1435,7 +1435,7 @@ loop_ok: /* wait at least 3 seconds after last signal before committing to a particular * endpoint address */ - if (!call->last_signal || poller_now <= call->last_signal + 3) + if (!call->last_signal || rtpe_now.tv_sec <= call->last_signal + 3) goto update_peerinfo; ilog(LOG_INFO, "Confirmed peer address as %s", endpoint_print_buf(fsin)); @@ -1522,7 +1522,7 @@ drop: ret = 0; atomic64_inc(&stream->stats.packets); atomic64_add(&stream->stats.bytes, s->len); - atomic64_set(&stream->last_packet, poller_now); + atomic64_set(&stream->last_packet, rtpe_now.tv_sec); atomic64_inc(&cm->statsps.packets); atomic64_add(&cm->statsps.bytes, s->len); diff --git a/daemon/poller.c b/daemon/poller.c index 9382acf91..ccdbf7a9f 100644 --- a/daemon/poller.c +++ b/daemon/poller.c @@ -55,7 +55,7 @@ struct poller *poller_new(void) { p = malloc(sizeof(*p)); memset(p, 0, sizeof(*p)); - gettimeofday(&g_now, NULL); + gettimeofday(&rtpe_now, NULL); p->fd = epoll_create1(0); if (p->fd == -1) abort(); @@ -311,7 +311,7 @@ int poller_poll(struct poller *p, int timeout) { if (ret <= 0) goto out; - gettimeofday(&g_now, NULL); + gettimeofday(&rtpe_now, NULL); for (i = 0; i < ret; i++) { ev = &evs[i]; @@ -482,9 +482,9 @@ void poller_timer_loop(void *d) { struct timeval tv; int wt; - while (!g_shutdown) { + while (!rtpe_shutdown) { gettimeofday(&tv, NULL); - if (tv.tv_sec != poller_now) + if (tv.tv_sec != rtpe_now.tv_sec) goto now; wt = 1000000 - tv.tv_usec; @@ -493,7 +493,7 @@ void poller_timer_loop(void *d) { continue; now: - gettimeofday(&g_now, NULL); + gettimeofday(&rtpe_now, NULL); poller_timers_run(p); } } @@ -501,6 +501,6 @@ now: void poller_loop(void *d) { struct poller *p = d; - while (!g_shutdown) + while (!rtpe_shutdown) poller_poll(p, 100); } diff --git a/daemon/poller.h b/daemon/poller.h index 41a29e751..8ede2f343 100644 --- a/daemon/poller.h +++ b/daemon/poller.h @@ -30,10 +30,6 @@ struct poller_item { struct poller; -/* XXX replace all occurrences with g_now */ -#define poller_now g_now.tv_sec - - struct poller *poller_new(void); int poller_add_item(struct poller *, struct poller_item *); int poller_update_item(struct poller *, struct poller_item *); diff --git a/daemon/recording.c b/daemon/recording.c index 464f4a241..46b83d785 100644 --- a/daemon/recording.c +++ b/daemon/recording.c @@ -373,7 +373,7 @@ static int pcap_meta_finish_file(struct call *call) { // Print start timestamp and end timestamp // YYYY-MM-DDThh:mm:ss time_t start = call->created.tv_sec; - time_t end = g_now.tv_sec; + time_t end = rtpe_now.tv_sec; char timebuffer[20]; struct tm *timeinfo; timeinfo = localtime(&start); @@ -503,7 +503,7 @@ static void stream_pcap_dump(pcap_dumper_t *pdumper, struct packet_stream *strea // Set up PCAP packet header struct pcap_pkthdr header; ZERO(header); - header.ts = g_now; + header.ts = rtpe_now; header.caplen = pkt_len; header.len = pkt_len; diff --git a/daemon/redis.c b/daemon/redis.c index 26b4ff5b7..f3c258286 100644 --- a/daemon/redis.c +++ b/daemon/redis.c @@ -560,7 +560,7 @@ static int redis_notify(struct callmaster *cm) { void redis_notify_loop(void *d) { int seconds = 1, redis_notify_return = 0; - time_t next_run = g_now.tv_sec; + time_t next_run = rtpe_now.tv_sec; struct callmaster *cm = (struct callmaster *)d; struct redis *r; @@ -598,14 +598,14 @@ void redis_notify_loop(void *d) { } // loop redis_notify => in case of lost connection - while (!g_shutdown) { - gettimeofday(&g_now, NULL); - if (g_now.tv_sec < next_run) { + while (!rtpe_shutdown) { + gettimeofday(&rtpe_now, NULL); + if (rtpe_now.tv_sec < next_run) { usleep(100000); continue; } - next_run = g_now.tv_sec + seconds; + next_run = rtpe_now.tv_sec + seconds; if (redis_check_conn(r) == REDIS_STATE_RECONNECTED || redis_notify_return < 0) { // alloc new redis async context upon redis breakdown diff --git a/daemon/statistics.c b/daemon/statistics.c index af536550c..bf4eaf173 100644 --- a/daemon/statistics.c +++ b/daemon/statistics.c @@ -180,7 +180,7 @@ void statistics_update_oneway(struct call* c) { if (c->monologues.head) { ml = c->monologues.head->data; - timeval_subtract(&tim_result_duration, &g_now, &ml->started); + timeval_subtract(&tim_result_duration, &rtpe_now, &ml->started); if (IS_OWN_CALL(c)) { if (ml->term_reason==TIMEOUT) { diff --git a/daemon/streambuf.c b/daemon/streambuf.c index c7da2dfc1..073609fbe 100644 --- a/daemon/streambuf.c +++ b/daemon/streambuf.c @@ -25,7 +25,7 @@ struct streambuf *streambuf_new(struct poller *p, int fd) { b->buf = g_string_new(""); b->fd = fd; b->poller = p; - b->active = poller_now; + b->active = rtpe_now.tv_sec; return b; } @@ -62,7 +62,7 @@ int streambuf_writeable(struct streambuf *b) { if (ret > 0) { g_string_erase(b->buf, 0, ret); - b->active = poller_now; + b->active = rtpe_now.tv_sec; } if (ret != out) { @@ -101,7 +101,7 @@ int streambuf_readable(struct streambuf *b) { } g_string_append_len(b->buf, buf, ret); - b->active = poller_now; + b->active = rtpe_now.tv_sec; } mutex_unlock(&b->lock); @@ -208,7 +208,7 @@ void streambuf_write(struct streambuf *b, const char *s, unsigned int len) { s += ret; len -= ret; - b->active = poller_now; + b->active = rtpe_now.tv_sec; } if (b->buf->len > 5242880) From cf3a8f9e16ee48f9d164f4c7ebfa45027efceeba Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Wed, 3 Jan 2018 10:58:06 -0500 Subject: [PATCH 51/65] move 'poller' member of callmaster into global scope Change-Id: Ide88caff59529278e45ceef4f9664bfc07f67b3d --- daemon/call.c | 10 ++++------ daemon/call.h | 4 +--- daemon/main.c | 25 ++++++++++++++----------- daemon/main.h | 7 +++++++ daemon/media_socket.c | 4 ++-- 5 files changed, 28 insertions(+), 22 deletions(-) create mode 100644 daemon/main.h diff --git a/daemon/call.c b/daemon/call.c index 92401f2fb..30a10e93a 100644 --- a/daemon/call.c +++ b/daemon/call.c @@ -41,6 +41,7 @@ #include "cdr.h" #include "statistics.h" #include "ssrc.h" +#include "main.h" /* also serves as array index for callstream->peers[] */ @@ -608,7 +609,7 @@ next: #undef DS -struct callmaster *callmaster_new(struct poller *p) { +struct callmaster *callmaster_new() { struct callmaster *c; c = obj_alloc0("callmaster", sizeof(*c), NULL); @@ -616,10 +617,9 @@ struct callmaster *callmaster_new(struct poller *p) { rtpe_callhash = g_hash_table_new(str_hash, str_equal); if (!rtpe_callhash) goto fail; - c->poller = p; rwlock_init(&rtpe_callhash_lock); - poller_add_timer(p, callmaster_timer, &c->obj); + poller_add_timer(rtpe_poller, callmaster_timer, &c->obj); mutex_init(&c->totalstats.total_average_lock); mutex_init(&c->totalstats_interval.total_average_lock); @@ -1769,7 +1769,6 @@ void call_destroy(struct call *c) { struct callmaster *m; struct packet_stream *ps=0; struct stream_fd *sfd; - struct poller *p; GList *l; int ret; struct call_monologue *ml; @@ -1782,7 +1781,6 @@ void call_destroy(struct call *c) { } m = c->callmaster; - p = m->poller; rwlock_lock_w(&rtpe_callhash_lock); ret = (g_hash_table_lookup(rtpe_callhash, &c->callid) == c); @@ -1914,7 +1912,7 @@ no_stats_output: while (c->stream_fds.head) { sfd = g_queue_pop_head(&c->stream_fds); - poller_del_item(p, sfd->socket.fd); + poller_del_item(rtpe_poller, sfd->socket.fd); obj_put(sfd); } diff --git a/daemon/call.h b/daemon/call.h index ed6e26031..ec12136cb 100644 --- a/daemon/call.h +++ b/daemon/call.h @@ -424,8 +424,6 @@ struct callmaster { mutex_t totalstats_lastinterval_lock; struct totalstats totalstats_lastinterval; - struct poller *poller; - struct callmaster_config conf; struct timeval latest_graphite_interval_start; }; @@ -435,7 +433,7 @@ extern rwlock_t rtpe_callhash_lock; extern GHashTable *rtpe_callhash; -struct callmaster *callmaster_new(struct poller *); +struct callmaster *callmaster_new(void); void callmaster_get_all_calls(struct callmaster *m, GQueue *q); //void calls_dump_redis(struct callmaster *); diff --git a/daemon/main.c b/daemon/main.c index 73e1729d9..b258d4d05 100644 --- a/daemon/main.c +++ b/daemon/main.c @@ -1,3 +1,5 @@ +#include "main.h" + #include #include #include @@ -38,11 +40,12 @@ struct main_context { - struct poller *p; struct callmaster *m; }; +struct poller *rtpe_poller; + static GQueue interfaces = G_QUEUE_INIT; @@ -519,15 +522,15 @@ static void create_everything(struct main_context *ctx) { } no_kernel: - ctx->p = poller_new(); - if (!ctx->p) + rtpe_poller = poller_new(); + if (!rtpe_poller) die("poller creation failed"); - ctx->m = callmaster_new(ctx->p); + ctx->m = callmaster_new(); if (!ctx->m) die("callmaster creation failed"); - dtls_timer(ctx->p); + dtls_timer(rtpe_poller); ZERO(mc); rwlock_init(&mc.config_lock); @@ -559,7 +562,7 @@ no_kernel: ct = NULL; if (tcp_listen_ep.port) { - ct = control_tcp_new(ctx->p, &tcp_listen_ep, ctx->m); + ct = control_tcp_new(rtpe_poller, &tcp_listen_ep, ctx->m); if (!ct) die("Failed to open TCP control connection port"); } @@ -567,7 +570,7 @@ no_kernel: cu = NULL; if (udp_listen_ep.port) { interfaces_exclude_port(udp_listen_ep.port); - cu = control_udp_new(ctx->p, &udp_listen_ep, ctx->m); + cu = control_udp_new(rtpe_poller, &udp_listen_ep, ctx->m); if (!cu) die("Failed to open UDP control connection port"); } @@ -575,7 +578,7 @@ no_kernel: cn = NULL; if (ng_listen_ep.port) { interfaces_exclude_port(ng_listen_ep.port); - cn = control_ng_new(ctx->p, &ng_listen_ep, ctx->m, control_tos); + cn = control_ng_new(rtpe_poller, &ng_listen_ep, ctx->m, control_tos); if (!cn) die("Failed to open UDP control connection port"); } @@ -583,7 +586,7 @@ no_kernel: cl = NULL; if (cli_listen_ep.port) { interfaces_exclude_port(cli_listen_ep.port); - cl = cli_new(ctx->p, &cli_listen_ep, ctx->m); + cl = cli_new(rtpe_poller, &cli_listen_ep, ctx->m); if (!cl) die("Failed to open UDP CLI connection port"); } @@ -652,7 +655,7 @@ int main(int argc, char **argv) { ilog(LOG_INFO, "Startup complete, version %s", RTPENGINE_VERSION); thread_create_detach(sighandler, NULL); - thread_create_detach(poller_timer_loop, ctx.p); + thread_create_detach(poller_timer_loop, rtpe_poller); if (!is_addr_unspecified(&redis_ep.address)) thread_create_detach(redis_notify_loop, ctx.m); @@ -671,7 +674,7 @@ int main(int argc, char **argv) { } for (;idxcallmaster->poller; sfd = obj_alloc0("stream_fd", sizeof(*sfd), stream_fd_free); sfd->unique_id = g_queue_get_length(&call->stream_fds); @@ -1637,7 +1637,7 @@ struct stream_fd *stream_fd_new(socket_t *fd, struct call *call, const struct lo pi.readable = stream_fd_readable; pi.closed = stream_fd_closed; - if (poller_add_item(po, &pi)) + if (poller_add_item(rtpe_poller, &pi)) ilog(LOG_ERR, "Failed to add stream_fd to poller"); return sfd; From c969ea1e5766ee3e01c50a9315f41b7253c71787 Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Wed, 3 Jan 2018 11:03:44 -0500 Subject: [PATCH 52/65] move stats and statsps into global scope Change-Id: I02d16e31f8980bd0ef3ff3a190b23dc61c087018 --- daemon/call.c | 17 ++++++++++------- daemon/call.h | 6 +++--- daemon/call_interfaces.c | 4 ++-- daemon/cli.c | 4 ++-- daemon/graphite.c | 2 +- daemon/media_socket.c | 12 +++++------- daemon/statistics.c | 8 ++++---- 7 files changed, 27 insertions(+), 26 deletions(-) diff --git a/daemon/call.c b/daemon/call.c index 30a10e93a..3b7f9fc69 100644 --- a/daemon/call.c +++ b/daemon/call.c @@ -116,6 +116,9 @@ const struct transport_protocol transport_protocols[] = { }; const int num_transport_protocols = G_N_ELEMENTS(transport_protocols); +/* XXX rework these */ +struct stats rtpe_statsps; +struct stats rtpe_stats; rwlock_t rtpe_callhash_lock; GHashTable *rtpe_callhash; @@ -463,7 +466,7 @@ destroy: else \ d = ke->stats.x - ks_val; \ atomic64_add(&ps->stats.x, d); \ - atomic64_add(&m->statsps.x, d); \ + atomic64_add(&rtpe_statsps.x, d); \ } while (0) static void callmaster_timer(void *ptr) { struct callmaster *m = ptr; @@ -495,13 +498,13 @@ static void callmaster_timer(void *ptr) { g_list_foreach(calls, call_timer_iterator, &hlp); g_list_free_full(calls, call_obj_put); } - atomic64_local_copy_zero_struct(&tmpstats, &m->statsps, bytes); - atomic64_local_copy_zero_struct(&tmpstats, &m->statsps, packets); - atomic64_local_copy_zero_struct(&tmpstats, &m->statsps, errors); + atomic64_local_copy_zero_struct(&tmpstats, &rtpe_statsps, bytes); + atomic64_local_copy_zero_struct(&tmpstats, &rtpe_statsps, packets); + atomic64_local_copy_zero_struct(&tmpstats, &rtpe_statsps, errors); - atomic64_set(&m->stats.bytes, atomic64_get_na(&tmpstats.bytes)); - atomic64_set(&m->stats.packets, atomic64_get_na(&tmpstats.packets)); - atomic64_set(&m->stats.errors, atomic64_get_na(&tmpstats.errors)); + atomic64_set(&rtpe_stats.bytes, atomic64_get_na(&tmpstats.bytes)); + atomic64_set(&rtpe_stats.packets, atomic64_get_na(&tmpstats.packets)); + atomic64_set(&rtpe_stats.errors, atomic64_get_na(&tmpstats.errors)); i = kernel_list(); while (i) { diff --git a/daemon/call.h b/daemon/call.h index ec12136cb..051fb7ba7 100644 --- a/daemon/call.h +++ b/daemon/call.h @@ -416,9 +416,6 @@ struct callmaster_config { struct callmaster { struct obj obj; - /* XXX rework these */ - struct stats statsps; /* per second stats, running timer */ - struct stats stats; /* copied from statsps once a second */ struct totalstats totalstats; struct totalstats totalstats_interval; mutex_t totalstats_lastinterval_lock; @@ -432,6 +429,9 @@ struct callmaster { extern rwlock_t rtpe_callhash_lock; extern GHashTable *rtpe_callhash; +extern struct stats rtpe_statsps; /* per second stats, running timer */ +extern struct stats rtpe_stats; /* copied from statsps once a second */ + struct callmaster *callmaster_new(void); void callmaster_get_all_calls(struct callmaster *m, GQueue *q); diff --git a/daemon/call_interfaces.c b/daemon/call_interfaces.c index dc91ca24c..050130615 100644 --- a/daemon/call_interfaces.c +++ b/daemon/call_interfaces.c @@ -452,7 +452,7 @@ void calls_status_tcp(struct callmaster *m, struct streambuf_stream *s) { streambuf_printf(s->outbuf, "proxy %u "UINT64F"/%i/%i\n", g_queue_get_length(&q), - atomic64_get(&m->stats.bytes), 0, 0); + atomic64_get(&rtpe_stats.bytes), 0, 0); while (q.head) { c = g_queue_pop_head(&q); @@ -818,7 +818,7 @@ const char *call_offer_ng(bencode_item_t *input, struct callmaster *m, bencode_i if (m->conf.max_sessions>=0) { rwlock_lock_r(&rtpe_callhash_lock); if (g_hash_table_size(rtpe_callhash) - - atomic64_get(&m->stats.foreign_sessions) >= m->conf.max_sessions) { + atomic64_get(&rtpe_stats.foreign_sessions) >= m->conf.max_sessions) { rwlock_unlock_r(&rtpe_callhash_lock); /* foreign calls can't get rejected * total_rejected_sess applies only to "own" sessions */ diff --git a/daemon/cli.c b/daemon/cli.c index 4c282c380..055728a4a 100644 --- a/daemon/cli.c +++ b/daemon/cli.c @@ -254,8 +254,8 @@ static void cli_incoming_list_totals(str *instr, struct callmaster* m, struct st static void cli_incoming_list_numsessions(str *instr, struct callmaster* m, struct streambuf *replybuffer) { rwlock_lock_r(&rtpe_callhash_lock); - streambuf_printf(replybuffer, "Current sessions own: "UINT64F"\n", g_hash_table_size(rtpe_callhash) - atomic64_get(&m->stats.foreign_sessions)); - streambuf_printf(replybuffer, "Current sessions foreign: "UINT64F"\n", atomic64_get(&m->stats.foreign_sessions)); + streambuf_printf(replybuffer, "Current sessions own: "UINT64F"\n", g_hash_table_size(rtpe_callhash) - atomic64_get(&rtpe_stats.foreign_sessions)); + streambuf_printf(replybuffer, "Current sessions foreign: "UINT64F"\n", atomic64_get(&rtpe_stats.foreign_sessions)); streambuf_printf(replybuffer, "Current sessions total: %i\n", g_hash_table_size(rtpe_callhash)); rwlock_unlock_r(&rtpe_callhash_lock); } diff --git a/daemon/graphite.c b/daemon/graphite.c index 8502eec6c..2595c2c88 100644 --- a/daemon/graphite.c +++ b/daemon/graphite.c @@ -136,7 +136,7 @@ int send_graphite_data(struct callmaster *cm, struct totalstats *sent_data) { ts->managed_sess_max = cm->totalstats_interval.managed_sess_max; ts->managed_sess_min = cm->totalstats_interval.managed_sess_min; ts->total_sessions = g_hash_table_size(rtpe_callhash); - ts->foreign_sessions = atomic64_get(&cm->stats.foreign_sessions); + ts->foreign_sessions = atomic64_get(&rtpe_stats.foreign_sessions); ts->own_sessions = ts->total_sessions - ts->foreign_sessions; cm->totalstats_interval.managed_sess_max = ts->own_sessions;; cm->totalstats_interval.managed_sess_min = ts->own_sessions; diff --git a/daemon/media_socket.c b/daemon/media_socket.c index 774d8961d..a7be8dbaa 100644 --- a/daemon/media_socket.c +++ b/daemon/media_socket.c @@ -1198,7 +1198,6 @@ static int stream_packet(struct stream_fd *sfd, str *s, const endpoint_t *fsin, unk = 0; int i; struct call *call; - struct callmaster *cm; /*unsigned char cc;*/ struct endpoint endpoint; rewrite_func rwf_in, rwf_out; @@ -1209,7 +1208,6 @@ static int stream_packet(struct stream_fd *sfd, str *s, const endpoint_t *fsin, struct ssrc_ctx *ssrc_in = NULL, *ssrc_out = NULL; call = sfd->call; - cm = call->callmaster; rwlock_lock_r(&call->master_lock); @@ -1319,7 +1317,7 @@ loop_ok: ilog(LOG_WARNING | LOG_FLAG_LIMIT, "RTP packet with unknown payload type %u received", i); atomic64_inc(&stream->stats.errors); - atomic64_inc(&cm->statsps.errors); + atomic64_inc(&rtpe_statsps.errors); } else { @@ -1338,7 +1336,7 @@ loop_ok: if (G_UNLIKELY(!sink || !sink->selected_sfd || !out_srtp || !out_srtp->selected_sfd || !in_srtp->selected_sfd)) { ilog(LOG_WARNING, "RTP packet from %s discarded", endpoint_print_buf(fsin)); atomic64_inc(&stream->stats.errors); - atomic64_inc(&cm->statsps.errors); + atomic64_inc(&rtpe_statsps.errors); goto unlock_out; } @@ -1511,7 +1509,7 @@ forward: ret = -errno; ilog(LOG_DEBUG,"Error when sending message. Error: %s",strerror(errno)); atomic64_inc(&stream->stats.errors); - atomic64_inc(&cm->statsps.errors); + atomic64_inc(&rtpe_statsps.errors); goto out; } @@ -1524,8 +1522,8 @@ drop: atomic64_inc(&stream->stats.packets); atomic64_add(&stream->stats.bytes, s->len); atomic64_set(&stream->last_packet, rtpe_now.tv_sec); - atomic64_inc(&cm->statsps.packets); - atomic64_add(&cm->statsps.bytes, s->len); + atomic64_inc(&rtpe_statsps.packets); + atomic64_add(&rtpe_statsps.bytes, s->len); out: if (ret == 0 && update) diff --git a/daemon/statistics.c b/daemon/statistics.c index bf4eaf173..15d5ee72d 100644 --- a/daemon/statistics.c +++ b/daemon/statistics.c @@ -76,13 +76,13 @@ void statistics_update_foreignown_dec(struct call* c) { m = c->callmaster; if (IS_FOREIGN_CALL(c)) { - atomic64_dec(&m->stats.foreign_sessions); + atomic64_dec(&rtpe_stats.foreign_sessions); } if(IS_OWN_CALL(c)) { mutex_lock(&m->totalstats_interval.managed_sess_lock); m->totalstats_interval.managed_sess_min = MIN(m->totalstats_interval.managed_sess_min, - g_hash_table_size(rtpe_callhash) - atomic64_get(&m->stats.foreign_sessions)); + g_hash_table_size(rtpe_callhash) - atomic64_get(&rtpe_stats.foreign_sessions)); mutex_unlock(&m->totalstats_interval.managed_sess_lock); } @@ -94,11 +94,11 @@ void statistics_update_foreignown_inc(struct callmaster *m, struct call* c) { m->totalstats_interval.managed_sess_max = MAX( m->totalstats_interval.managed_sess_max, g_hash_table_size(rtpe_callhash) - - atomic64_get(&m->stats.foreign_sessions)); + - atomic64_get(&rtpe_stats.foreign_sessions)); mutex_unlock(&m->totalstats_interval.managed_sess_lock); } else if (IS_FOREIGN_CALL(c)) { /* foreign call*/ - atomic64_inc(&m->stats.foreign_sessions); + atomic64_inc(&rtpe_stats.foreign_sessions); atomic64_inc(&m->totalstats.total_foreign_sessions); } From 741140341f001eb84f2ca5e4944c73d85669e31b Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Wed, 3 Jan 2018 11:17:40 -0500 Subject: [PATCH 53/65] move "totalstats" out of callmaster into global scope Change-Id: Ia5b95e788c1d486a86b6f916dcff5b88022f5897 --- daemon/call.c | 23 +++-------- daemon/call.h | 5 --- daemon/call_interfaces.c | 4 +- daemon/cli.c | 47 +++++++++++----------- daemon/control_ng.c | 6 +-- daemon/graphite.c | 71 ++++++++++++++++----------------- daemon/main.c | 2 + daemon/statistics.c | 85 +++++++++++++++++++++++----------------- daemon/statistics.h | 12 ++++-- 9 files changed, 131 insertions(+), 124 deletions(-) diff --git a/daemon/call.c b/daemon/call.c index 3b7f9fc69..03ad9c61d 100644 --- a/daemon/call.c +++ b/daemon/call.c @@ -624,17 +624,6 @@ struct callmaster *callmaster_new() { poller_add_timer(rtpe_poller, callmaster_timer, &c->obj); - mutex_init(&c->totalstats.total_average_lock); - mutex_init(&c->totalstats_interval.total_average_lock); - mutex_init(&c->totalstats_interval.managed_sess_lock); - mutex_init(&c->totalstats_interval.total_calls_duration_lock); - - c->totalstats.started = rtpe_now.tv_sec; - //c->totalstats_interval.managed_sess_min = 0; // already zeroed - //c->totalstats_interval.managed_sess_max = 0; - - mutex_init(&c->totalstats_lastinterval_lock); - return c; fail: @@ -1733,11 +1722,11 @@ void add_total_calls_duration_in_interval(struct callmaster *cm, struct timeval ongoing_calls_dur = add_ongoing_calls_dur_in_interval(cm, &cm->latest_graphite_interval_start, interval_tv); - mutex_lock(&cm->totalstats_interval.total_calls_duration_lock); - timeval_add(&cm->totalstats_interval.total_calls_duration_interval, - &cm->totalstats_interval.total_calls_duration_interval, + mutex_lock(&rtpe_totalstats_interval.total_calls_duration_lock); + timeval_add(&rtpe_totalstats_interval.total_calls_duration_interval, + &rtpe_totalstats_interval.total_calls_duration_interval, &ongoing_calls_dur); - mutex_unlock(&cm->totalstats_interval.total_calls_duration_lock); + mutex_unlock(&rtpe_totalstats_interval.total_calls_duration_lock); } static struct timeval add_ongoing_calls_dur_in_interval(struct callmaster *m, @@ -1863,7 +1852,7 @@ void call_destroy(struct call *c) { atomic64_get(&ps->stats.errors), rtpe_now.tv_sec - atomic64_get(&ps->last_packet)); - statistics_update_totals(m,ps); + statistics_update_totals(ps); } @@ -2056,7 +2045,7 @@ restart: if (type == CT_FOREIGN_CALL) /* foreign call*/ c->foreign_call = 1; - statistics_update_foreignown_inc(m,c); + statistics_update_foreignown_inc(c); rwlock_lock_w(&c->master_lock); rwlock_unlock_w(&rtpe_callhash_lock); diff --git a/daemon/call.h b/daemon/call.h index 051fb7ba7..274fd70ac 100644 --- a/daemon/call.h +++ b/daemon/call.h @@ -416,11 +416,6 @@ struct callmaster_config { struct callmaster { struct obj obj; - struct totalstats totalstats; - struct totalstats totalstats_interval; - mutex_t totalstats_lastinterval_lock; - struct totalstats totalstats_lastinterval; - struct callmaster_config conf; struct timeval latest_graphite_interval_start; }; diff --git a/daemon/call_interfaces.c b/daemon/call_interfaces.c index 050130615..a6334df3d 100644 --- a/daemon/call_interfaces.c +++ b/daemon/call_interfaces.c @@ -822,8 +822,8 @@ const char *call_offer_ng(bencode_item_t *input, struct callmaster *m, bencode_i rwlock_unlock_r(&rtpe_callhash_lock); /* foreign calls can't get rejected * total_rejected_sess applies only to "own" sessions */ - atomic64_inc(&m->totalstats.total_rejected_sess); - atomic64_inc(&m->totalstats_interval.total_rejected_sess); + atomic64_inc(&rtpe_totalstats.total_rejected_sess); + atomic64_inc(&rtpe_totalstats_interval.total_rejected_sess); ilog(LOG_ERROR, "Parallel session limit reached (%i)",m->conf.max_sessions); rwlock_unlock_r(&m->conf.config_lock); diff --git a/daemon/cli.c b/daemon/cli.c index 055728a4a..dec6102bb 100644 --- a/daemon/cli.c +++ b/daemon/cli.c @@ -22,6 +22,7 @@ #include "streambuf.h" #include "tcp_listener.h" #include "str.h" +#include "statistics.h" #include "rtpengine_config.h" @@ -170,34 +171,34 @@ static void cli_incoming_list_totals(str *instr, struct callmaster* m, struct st u_int64_t num_sessions, min_sess_iv, max_sess_iv; struct request_time offer_iv, answer_iv, delete_iv; - mutex_lock(&m->totalstats.total_average_lock); - avg = m->totalstats.total_average_call_dur; - num_sessions = m->totalstats.total_managed_sess; - mutex_unlock(&m->totalstats.total_average_lock); + mutex_lock(&rtpe_totalstats.total_average_lock); + avg = rtpe_totalstats.total_average_call_dur; + num_sessions = rtpe_totalstats.total_managed_sess; + mutex_unlock(&rtpe_totalstats.total_average_lock); streambuf_printf(replybuffer, "\nTotal statistics (does not include current running sessions):\n\n"); - streambuf_printf(replybuffer, " Uptime of rtpengine :%llu seconds\n", (unsigned long long)time(NULL)-m->totalstats.started); + streambuf_printf(replybuffer, " Uptime of rtpengine :%llu seconds\n", (unsigned long long)time(NULL)-rtpe_totalstats.started); streambuf_printf(replybuffer, " Total managed sessions :"UINT64F"\n", num_sessions); - streambuf_printf(replybuffer, " Total rejected sessions :"UINT64F"\n", atomic64_get(&m->totalstats.total_rejected_sess)); - streambuf_printf(replybuffer, " Total timed-out sessions via TIMEOUT :"UINT64F"\n",atomic64_get(&m->totalstats.total_timeout_sess)); - streambuf_printf(replybuffer, " Total timed-out sessions via SILENT_TIMEOUT :"UINT64F"\n",atomic64_get(&m->totalstats.total_silent_timeout_sess)); - streambuf_printf(replybuffer, " Total timed-out sessions via FINAL_TIMEOUT :"UINT64F"\n",atomic64_get(&m->totalstats.total_final_timeout_sess)); - streambuf_printf(replybuffer, " Total regular terminated sessions :"UINT64F"\n",atomic64_get(&m->totalstats.total_regular_term_sess)); - streambuf_printf(replybuffer, " Total forced terminated sessions :"UINT64F"\n",atomic64_get(&m->totalstats.total_forced_term_sess)); - streambuf_printf(replybuffer, " Total relayed packets :"UINT64F"\n",atomic64_get(&m->totalstats.total_relayed_packets)); - streambuf_printf(replybuffer, " Total relayed packet errors :"UINT64F"\n",atomic64_get(&m->totalstats.total_relayed_errors)); - streambuf_printf(replybuffer, " Total number of streams with no relayed packets :"UINT64F"\n", atomic64_get(&m->totalstats.total_nopacket_relayed_sess)); - streambuf_printf(replybuffer, " Total number of 1-way streams :"UINT64F"\n",atomic64_get(&m->totalstats.total_oneway_stream_sess)); + streambuf_printf(replybuffer, " Total rejected sessions :"UINT64F"\n", atomic64_get(&rtpe_totalstats.total_rejected_sess)); + streambuf_printf(replybuffer, " Total timed-out sessions via TIMEOUT :"UINT64F"\n",atomic64_get(&rtpe_totalstats.total_timeout_sess)); + streambuf_printf(replybuffer, " Total timed-out sessions via SILENT_TIMEOUT :"UINT64F"\n",atomic64_get(&rtpe_totalstats.total_silent_timeout_sess)); + streambuf_printf(replybuffer, " Total timed-out sessions via FINAL_TIMEOUT :"UINT64F"\n",atomic64_get(&rtpe_totalstats.total_final_timeout_sess)); + streambuf_printf(replybuffer, " Total regular terminated sessions :"UINT64F"\n",atomic64_get(&rtpe_totalstats.total_regular_term_sess)); + streambuf_printf(replybuffer, " Total forced terminated sessions :"UINT64F"\n",atomic64_get(&rtpe_totalstats.total_forced_term_sess)); + streambuf_printf(replybuffer, " Total relayed packets :"UINT64F"\n",atomic64_get(&rtpe_totalstats.total_relayed_packets)); + streambuf_printf(replybuffer, " Total relayed packet errors :"UINT64F"\n",atomic64_get(&rtpe_totalstats.total_relayed_errors)); + streambuf_printf(replybuffer, " Total number of streams with no relayed packets :"UINT64F"\n", atomic64_get(&rtpe_totalstats.total_nopacket_relayed_sess)); + streambuf_printf(replybuffer, " Total number of 1-way streams :"UINT64F"\n",atomic64_get(&rtpe_totalstats.total_oneway_stream_sess)); streambuf_printf(replybuffer, " Average call duration :%ld.%06ld\n\n",avg.tv_sec,avg.tv_usec); - mutex_lock(&m->totalstats_lastinterval_lock); - calls_dur_iv = m->totalstats_lastinterval.total_calls_duration_interval; - min_sess_iv = m->totalstats_lastinterval.managed_sess_min; - max_sess_iv = m->totalstats_lastinterval.managed_sess_max; - offer_iv = m->totalstats_lastinterval.offer; - answer_iv = m->totalstats_lastinterval.answer; - delete_iv = m->totalstats_lastinterval.delete; - mutex_unlock(&m->totalstats_lastinterval_lock); + mutex_lock(&rtpe_totalstats_lastinterval_lock); + calls_dur_iv = rtpe_totalstats_lastinterval.total_calls_duration_interval; + min_sess_iv = rtpe_totalstats_lastinterval.managed_sess_min; + max_sess_iv = rtpe_totalstats_lastinterval.managed_sess_max; + offer_iv = rtpe_totalstats_lastinterval.offer; + answer_iv = rtpe_totalstats_lastinterval.answer; + delete_iv = rtpe_totalstats_lastinterval.delete; + mutex_unlock(&rtpe_totalstats_lastinterval_lock); // compute average offer/answer/delete time timeval_divide(&offer_iv.time_avg, &offer_iv.time_avg, offer_iv.count); diff --git a/daemon/control_ng.c b/daemon/control_ng.c index b8ccc8f6a..49508c473 100644 --- a/daemon/control_ng.c +++ b/daemon/control_ng.c @@ -247,11 +247,11 @@ static void control_ng_incoming(struct obj *obj, str *buf, const endpoint_t *sin // update interval statistics if (!str_cmp(&cmd, "offer")) { - timeval_update_request_time(&c->callmaster->totalstats_interval.offer, &offer_stop); + timeval_update_request_time(&rtpe_totalstats_interval.offer, &offer_stop); } else if (!str_cmp(&cmd, "answer")) { - timeval_update_request_time(&c->callmaster->totalstats_interval.answer, &answer_stop); + timeval_update_request_time(&rtpe_totalstats_interval.answer, &answer_stop); } else if (!str_cmp(&cmd, "delete")) { - timeval_update_request_time(&c->callmaster->totalstats_interval.delete, &delete_stop); + timeval_update_request_time(&rtpe_totalstats_interval.delete, &delete_stop); } goto send_resp; diff --git a/daemon/graphite.c b/daemon/graphite.c index 2595c2c88..227dbf877 100644 --- a/daemon/graphite.c +++ b/daemon/graphite.c @@ -20,6 +20,7 @@ #include "call.h" #include "graphite.h" #include "socket.h" +#include "statistics.h" static socket_t graphite_sock; static int connection_state = STATE_DISCONNECTED; @@ -102,45 +103,45 @@ int send_graphite_data(struct callmaster *cm, struct totalstats *sent_data) { struct totalstats *ts = sent_data; /* atomically copy values to stack and reset to zero */ - atomic64_local_copy_zero_struct(ts, &cm->totalstats_interval, total_timeout_sess); - atomic64_local_copy_zero_struct(ts, &cm->totalstats_interval, total_rejected_sess); - atomic64_local_copy_zero_struct(ts, &cm->totalstats_interval, total_silent_timeout_sess); - atomic64_local_copy_zero_struct(ts, &cm->totalstats_interval, total_final_timeout_sess); - atomic64_local_copy_zero_struct(ts, &cm->totalstats_interval, total_regular_term_sess); - atomic64_local_copy_zero_struct(ts, &cm->totalstats_interval, total_forced_term_sess); - atomic64_local_copy_zero_struct(ts, &cm->totalstats_interval, total_relayed_packets); - atomic64_local_copy_zero_struct(ts, &cm->totalstats_interval, total_relayed_errors); - atomic64_local_copy_zero_struct(ts, &cm->totalstats_interval, total_nopacket_relayed_sess); - atomic64_local_copy_zero_struct(ts, &cm->totalstats_interval, total_oneway_stream_sess); - - mutex_lock(&cm->totalstats_interval.total_average_lock); - ts->total_average_call_dur = cm->totalstats_interval.total_average_call_dur; - ts->total_managed_sess = cm->totalstats_interval.total_managed_sess; - ZERO(cm->totalstats_interval.total_average_call_dur); - ZERO(cm->totalstats_interval.total_managed_sess); - mutex_unlock(&cm->totalstats_interval.total_average_lock); - - mutex_lock(&cm->totalstats_interval.total_calls_duration_lock); - ts->total_calls_duration_interval = cm->totalstats_interval.total_calls_duration_interval; - cm->totalstats_interval.total_calls_duration_interval.tv_sec = 0; - cm->totalstats_interval.total_calls_duration_interval.tv_usec = 0; - //ZERO(cm->totalstats_interval.total_calls_duration_interval); - mutex_unlock(&cm->totalstats_interval.total_calls_duration_lock); - - ts->offer = timeval_clear_request_time(&cm->totalstats_interval.offer); - ts->answer = timeval_clear_request_time(&cm->totalstats_interval.answer); - ts->delete = timeval_clear_request_time(&cm->totalstats_interval.delete); + atomic64_local_copy_zero_struct(ts, &rtpe_totalstats_interval, total_timeout_sess); + atomic64_local_copy_zero_struct(ts, &rtpe_totalstats_interval, total_rejected_sess); + atomic64_local_copy_zero_struct(ts, &rtpe_totalstats_interval, total_silent_timeout_sess); + atomic64_local_copy_zero_struct(ts, &rtpe_totalstats_interval, total_final_timeout_sess); + atomic64_local_copy_zero_struct(ts, &rtpe_totalstats_interval, total_regular_term_sess); + atomic64_local_copy_zero_struct(ts, &rtpe_totalstats_interval, total_forced_term_sess); + atomic64_local_copy_zero_struct(ts, &rtpe_totalstats_interval, total_relayed_packets); + atomic64_local_copy_zero_struct(ts, &rtpe_totalstats_interval, total_relayed_errors); + atomic64_local_copy_zero_struct(ts, &rtpe_totalstats_interval, total_nopacket_relayed_sess); + atomic64_local_copy_zero_struct(ts, &rtpe_totalstats_interval, total_oneway_stream_sess); + + mutex_lock(&rtpe_totalstats_interval.total_average_lock); + ts->total_average_call_dur = rtpe_totalstats_interval.total_average_call_dur; + ts->total_managed_sess = rtpe_totalstats_interval.total_managed_sess; + ZERO(rtpe_totalstats_interval.total_average_call_dur); + ZERO(rtpe_totalstats_interval.total_managed_sess); + mutex_unlock(&rtpe_totalstats_interval.total_average_lock); + + mutex_lock(&rtpe_totalstats_interval.total_calls_duration_lock); + ts->total_calls_duration_interval = rtpe_totalstats_interval.total_calls_duration_interval; + rtpe_totalstats_interval.total_calls_duration_interval.tv_sec = 0; + rtpe_totalstats_interval.total_calls_duration_interval.tv_usec = 0; + //ZERO(rtpe_totalstats_interval.total_calls_duration_interval); + mutex_unlock(&rtpe_totalstats_interval.total_calls_duration_lock); + + ts->offer = timeval_clear_request_time(&rtpe_totalstats_interval.offer); + ts->answer = timeval_clear_request_time(&rtpe_totalstats_interval.answer); + ts->delete = timeval_clear_request_time(&rtpe_totalstats_interval.delete); rwlock_lock_r(&rtpe_callhash_lock); - mutex_lock(&cm->totalstats_interval.managed_sess_lock); - ts->managed_sess_max = cm->totalstats_interval.managed_sess_max; - ts->managed_sess_min = cm->totalstats_interval.managed_sess_min; + mutex_lock(&rtpe_totalstats_interval.managed_sess_lock); + ts->managed_sess_max = rtpe_totalstats_interval.managed_sess_max; + ts->managed_sess_min = rtpe_totalstats_interval.managed_sess_min; ts->total_sessions = g_hash_table_size(rtpe_callhash); ts->foreign_sessions = atomic64_get(&rtpe_stats.foreign_sessions); ts->own_sessions = ts->total_sessions - ts->foreign_sessions; - cm->totalstats_interval.managed_sess_max = ts->own_sessions;; - cm->totalstats_interval.managed_sess_min = ts->own_sessions; - mutex_unlock(&cm->totalstats_interval.managed_sess_lock); + rtpe_totalstats_interval.managed_sess_max = ts->own_sessions;; + rtpe_totalstats_interval.managed_sess_min = ts->own_sessions; + mutex_unlock(&rtpe_totalstats_interval.managed_sess_lock); rwlock_unlock_r(&rtpe_callhash_lock); // compute average offer/answer/delete time @@ -317,7 +318,7 @@ void graphite_loop_run(struct callmaster *cm, endpoint_t *graphite_ep, int secon connection_state = STATE_DISCONNECTED; } - copy_with_lock(&cm->totalstats_lastinterval, &graphite_stats, &cm->totalstats_lastinterval.total_average_lock); + copy_with_lock(&rtpe_totalstats_lastinterval, &graphite_stats, &rtpe_totalstats_lastinterval.total_average_lock); } } diff --git a/daemon/main.c b/daemon/main.c index b258d4d05..345e81beb 100644 --- a/daemon/main.c +++ b/daemon/main.c @@ -36,6 +36,7 @@ #include "auxlib.h" #include "rtcp.h" #include "iptables.h" +#include "statistics.h" @@ -498,6 +499,7 @@ static void init_everything() { control_ng_init(); if (call_interfaces_init()) abort(); + statistics_init(); } diff --git a/daemon/statistics.c b/daemon/statistics.c index 15d5ee72d..1c39a797f 100644 --- a/daemon/statistics.c +++ b/daemon/statistics.c @@ -1,6 +1,12 @@ #include "call.h" #include "statistics.h" +struct totalstats rtpe_totalstats; +struct totalstats rtpe_totalstats_interval; +mutex_t rtpe_totalstats_lastinterval_lock; +struct totalstats rtpe_totalstats_lastinterval; + + static void timeval_totalstats_average_add(struct totalstats *s, const struct timeval *add) { struct timeval dp, oa; @@ -59,47 +65,43 @@ static void timeval_totalstats_interval_call_duration_add(struct totalstats *s, } -void statistics_update_totals(struct callmaster* m, struct packet_stream *ps) { - atomic64_add(&m->totalstats.total_relayed_packets, +void statistics_update_totals(struct packet_stream *ps) { + atomic64_add(&rtpe_totalstats.total_relayed_packets, atomic64_get(&ps->stats.packets)); - atomic64_add(&m->totalstats_interval.total_relayed_packets, + atomic64_add(&rtpe_totalstats_interval.total_relayed_packets, atomic64_get(&ps->stats.packets)); - atomic64_add(&m->totalstats.total_relayed_errors, + atomic64_add(&rtpe_totalstats.total_relayed_errors, atomic64_get(&ps->stats.errors)); - atomic64_add(&m->totalstats_interval.total_relayed_errors, + atomic64_add(&rtpe_totalstats_interval.total_relayed_errors, atomic64_get(&ps->stats.errors)); } void statistics_update_foreignown_dec(struct call* c) { - struct callmaster *m; - - m = c->callmaster; - if (IS_FOREIGN_CALL(c)) { atomic64_dec(&rtpe_stats.foreign_sessions); } if(IS_OWN_CALL(c)) { - mutex_lock(&m->totalstats_interval.managed_sess_lock); - m->totalstats_interval.managed_sess_min = MIN(m->totalstats_interval.managed_sess_min, + mutex_lock(&rtpe_totalstats_interval.managed_sess_lock); + rtpe_totalstats_interval.managed_sess_min = MIN(rtpe_totalstats_interval.managed_sess_min, g_hash_table_size(rtpe_callhash) - atomic64_get(&rtpe_stats.foreign_sessions)); - mutex_unlock(&m->totalstats_interval.managed_sess_lock); + mutex_unlock(&rtpe_totalstats_interval.managed_sess_lock); } } -void statistics_update_foreignown_inc(struct callmaster *m, struct call* c) { +void statistics_update_foreignown_inc(struct call* c) { if (IS_OWN_CALL(c)) { - mutex_lock(&m->totalstats_interval.managed_sess_lock); - m->totalstats_interval.managed_sess_max = MAX( - m->totalstats_interval.managed_sess_max, + mutex_lock(&rtpe_totalstats_interval.managed_sess_lock); + rtpe_totalstats_interval.managed_sess_max = MAX( + rtpe_totalstats_interval.managed_sess_max, g_hash_table_size(rtpe_callhash) - atomic64_get(&rtpe_stats.foreign_sessions)); - mutex_unlock(&m->totalstats_interval.managed_sess_lock); + mutex_unlock(&rtpe_totalstats_interval.managed_sess_lock); } else if (IS_FOREIGN_CALL(c)) { /* foreign call*/ atomic64_inc(&rtpe_stats.foreign_sessions); - atomic64_inc(&m->totalstats.total_foreign_sessions); + atomic64_inc(&rtpe_totalstats.total_foreign_sessions); } } @@ -162,8 +164,8 @@ void statistics_update_oneway(struct call* c) { if (ps && ps2 && atomic64_get(&ps2->stats.packets)==0) { if (atomic64_get(&ps->stats.packets)!=0 && IS_OWN_CALL(c)){ if (atomic64_get(&ps->stats.packets)!=0) { - atomic64_inc(&m->totalstats.total_oneway_stream_sess); - atomic64_inc(&m->totalstats_interval.total_oneway_stream_sess); + atomic64_inc(&rtpe_totalstats.total_oneway_stream_sess); + atomic64_inc(&rtpe_totalstats_interval.total_oneway_stream_sess); } } else { @@ -173,8 +175,8 @@ void statistics_update_oneway(struct call* c) { } if (IS_OWN_CALL(c)) { - atomic64_add(&m->totalstats.total_nopacket_relayed_sess, total_nopacket_relayed_sess / 2); - atomic64_add(&m->totalstats_interval.total_nopacket_relayed_sess, total_nopacket_relayed_sess / 2); + atomic64_add(&rtpe_totalstats.total_nopacket_relayed_sess, total_nopacket_relayed_sess / 2); + atomic64_add(&rtpe_totalstats_interval.total_nopacket_relayed_sess, total_nopacket_relayed_sess / 2); } if (c->monologues.head) { @@ -184,31 +186,44 @@ void statistics_update_oneway(struct call* c) { if (IS_OWN_CALL(c)) { if (ml->term_reason==TIMEOUT) { - atomic64_inc(&m->totalstats.total_timeout_sess); - atomic64_inc(&m->totalstats_interval.total_timeout_sess); + atomic64_inc(&rtpe_totalstats.total_timeout_sess); + atomic64_inc(&rtpe_totalstats_interval.total_timeout_sess); } else if (ml->term_reason==SILENT_TIMEOUT) { - atomic64_inc(&m->totalstats.total_silent_timeout_sess); - atomic64_inc(&m->totalstats_interval.total_silent_timeout_sess); + atomic64_inc(&rtpe_totalstats.total_silent_timeout_sess); + atomic64_inc(&rtpe_totalstats_interval.total_silent_timeout_sess); } else if (ml->term_reason==REGULAR) { - atomic64_inc(&m->totalstats.total_regular_term_sess); - atomic64_inc(&m->totalstats_interval.total_regular_term_sess); + atomic64_inc(&rtpe_totalstats.total_regular_term_sess); + atomic64_inc(&rtpe_totalstats_interval.total_regular_term_sess); } else if (ml->term_reason==FORCED) { - atomic64_inc(&m->totalstats.total_forced_term_sess); - atomic64_inc(&m->totalstats_interval.total_forced_term_sess); + atomic64_inc(&rtpe_totalstats.total_forced_term_sess); + atomic64_inc(&rtpe_totalstats_interval.total_forced_term_sess); } - timeval_totalstats_average_add(&m->totalstats, &tim_result_duration); - timeval_totalstats_average_add(&m->totalstats_interval, &tim_result_duration); + timeval_totalstats_average_add(&rtpe_totalstats, &tim_result_duration); + timeval_totalstats_average_add(&rtpe_totalstats_interval, &tim_result_duration); timeval_totalstats_interval_call_duration_add( - &m->totalstats_interval, &ml->started, &ml->terminated, + &rtpe_totalstats_interval, &ml->started, &ml->terminated, &m->latest_graphite_interval_start, m->conf.graphite_interval); } if (ml->term_reason==FINAL_TIMEOUT) { - atomic64_inc(&m->totalstats.total_final_timeout_sess); - atomic64_inc(&m->totalstats_interval.total_final_timeout_sess); + atomic64_inc(&rtpe_totalstats.total_final_timeout_sess); + atomic64_inc(&rtpe_totalstats_interval.total_final_timeout_sess); } } } + +void statistics_init() { + mutex_init(&rtpe_totalstats.total_average_lock); + mutex_init(&rtpe_totalstats_interval.total_average_lock); + mutex_init(&rtpe_totalstats_interval.managed_sess_lock); + mutex_init(&rtpe_totalstats_interval.total_calls_duration_lock); + + rtpe_totalstats.started = rtpe_now.tv_sec; + //rtpe_totalstats_interval.managed_sess_min = 0; // already zeroed + //rtpe_totalstats_interval.managed_sess_max = 0; + + mutex_init(&rtpe_totalstats_lastinterval_lock); +} diff --git a/daemon/statistics.h b/daemon/statistics.h index 333a1e7ba..0f3bf4150 100644 --- a/daemon/statistics.h +++ b/daemon/statistics.h @@ -69,12 +69,16 @@ struct call_stats { struct stats totals[4]; /* rtp in, rtcp in, rtp out, rtcp out */ }; - -struct callmaster; +extern struct totalstats rtpe_totalstats; +extern struct totalstats rtpe_totalstats_interval; +extern mutex_t rtpe_totalstats_lastinterval_lock; +extern struct totalstats rtpe_totalstats_lastinterval; void statistics_update_oneway(struct call *); void statistics_update_foreignown_dec(struct call *); -void statistics_update_foreignown_inc(struct callmaster *m, struct call* c); -void statistics_update_totals(struct callmaster *, struct packet_stream *) ; +void statistics_update_foreignown_inc(struct call* c); +void statistics_update_totals(struct packet_stream *) ; + +void statistics_init(void); #endif /* STATISTICS_H_ */ From d65a6bbbdc483de09d418235b5a5f8acad310fee Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Wed, 3 Jan 2018 11:26:09 -0500 Subject: [PATCH 54/65] move latest_graphite_interval_start to global scope Change-Id: I1eb5ea8d6faafe40383d3bb92517307e47ceca9a --- daemon/call.c | 3 ++- daemon/call.h | 1 - daemon/graphite.c | 4 +++- daemon/graphite.h | 2 ++ daemon/main.c | 3 ++- daemon/statistics.c | 3 ++- 6 files changed, 11 insertions(+), 5 deletions(-) diff --git a/daemon/call.c b/daemon/call.c index 03ad9c61d..f34e30072 100644 --- a/daemon/call.c +++ b/daemon/call.c @@ -42,6 +42,7 @@ #include "statistics.h" #include "ssrc.h" #include "main.h" +#include "graphite.h" /* also serves as array index for callstream->peers[] */ @@ -1720,7 +1721,7 @@ out: void add_total_calls_duration_in_interval(struct callmaster *cm, struct timeval *interval_tv) { struct timeval ongoing_calls_dur = add_ongoing_calls_dur_in_interval(cm, - &cm->latest_graphite_interval_start, interval_tv); + &rtpe_latest_graphite_interval_start, interval_tv); mutex_lock(&rtpe_totalstats_interval.total_calls_duration_lock); timeval_add(&rtpe_totalstats_interval.total_calls_duration_interval, diff --git a/daemon/call.h b/daemon/call.h index 274fd70ac..ca77b17f8 100644 --- a/daemon/call.h +++ b/daemon/call.h @@ -417,7 +417,6 @@ struct callmaster { struct obj obj; struct callmaster_config conf; - struct timeval latest_graphite_interval_start; }; diff --git a/daemon/graphite.c b/daemon/graphite.c index 227dbf877..3699c6a0e 100644 --- a/daemon/graphite.c +++ b/daemon/graphite.c @@ -22,6 +22,8 @@ #include "socket.h" #include "statistics.h" +struct timeval rtpe_latest_graphite_interval_start; + static socket_t graphite_sock; static int connection_state = STATE_DISCONNECTED; //struct totalstats totalstats_prev; @@ -311,7 +313,7 @@ void graphite_loop_run(struct callmaster *cm, endpoint_t *graphite_ep, int secon add_total_calls_duration_in_interval(cm, &graphite_interval_tv); rc = send_graphite_data(cm, &graphite_stats); - gettimeofday(&cm->latest_graphite_interval_start, NULL); + gettimeofday(&rtpe_latest_graphite_interval_start, NULL); if (rc < 0) { ilog(LOG_ERROR,"Sending graphite data failed."); close_socket(&graphite_sock); diff --git a/daemon/graphite.h b/daemon/graphite.h index 9ffd34c70..d83ccbc2d 100644 --- a/daemon/graphite.h +++ b/daemon/graphite.h @@ -16,6 +16,8 @@ enum connection_state { STATE_CONNECTED, }; +extern struct timeval rtpe_latest_graphite_interval_start; + int connect_to_graphite_server(const endpoint_t *ep); int send_graphite_data(struct callmaster *cm, struct totalstats *sent_data); void graphite_loop_run(struct callmaster *cm, endpoint_t *graphite_ep, int seconds); diff --git a/daemon/main.c b/daemon/main.c index 345e81beb..9689a9dd9 100644 --- a/daemon/main.c +++ b/daemon/main.c @@ -37,6 +37,7 @@ #include "rtcp.h" #include "iptables.h" #include "statistics.h" +#include "graphite.h" @@ -638,7 +639,7 @@ no_kernel: ilog(LOG_INFO, "Redis restore time = %.0lf ms", redis_diff); } - gettimeofday(&ctx->m->latest_graphite_interval_start, NULL); + gettimeofday(&rtpe_latest_graphite_interval_start, NULL); timeval_from_us(&tmp_tv, (long long) graphite_interval*1000000); set_graphite_interval_tv(&tmp_tv); diff --git a/daemon/statistics.c b/daemon/statistics.c index 1c39a797f..de788b554 100644 --- a/daemon/statistics.c +++ b/daemon/statistics.c @@ -1,5 +1,6 @@ #include "call.h" #include "statistics.h" +#include "graphite.h" struct totalstats rtpe_totalstats; struct totalstats rtpe_totalstats_interval; @@ -203,7 +204,7 @@ void statistics_update_oneway(struct call* c) { timeval_totalstats_average_add(&rtpe_totalstats_interval, &tim_result_duration); timeval_totalstats_interval_call_duration_add( &rtpe_totalstats_interval, &ml->started, &ml->terminated, - &m->latest_graphite_interval_start, + &rtpe_latest_graphite_interval_start, m->conf.graphite_interval); } From f2b93f9ef8e5b2fa1e198034dc8024bc6881f9b5 Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Wed, 3 Jan 2018 12:01:27 -0500 Subject: [PATCH 55/65] move config options into global struct rtpengine_config Change-Id: Ie566efb6a1b8bedbe33f768bc4cd979b2d2b46cc --- daemon/call.c | 24 ++++--- daemon/call.h | 26 +------- daemon/call_interfaces.c | 19 +++--- daemon/cli.c | 68 +++++++++---------- daemon/graphite.c | 9 +-- daemon/main.c | 137 ++++++++++++++++----------------------- daemon/main.h | 36 ++++++++++ daemon/redis.c | 13 ++-- daemon/statistics.c | 7 +- 9 files changed, 165 insertions(+), 174 deletions(-) diff --git a/daemon/call.c b/daemon/call.c index f34e30072..3603ec640 100644 --- a/daemon/call.c +++ b/daemon/call.c @@ -176,7 +176,6 @@ static void call_timer_iterator(gpointer data, gpointer user_data) { struct call *c = data; struct iterator_helper *hlp = user_data; GList *it; - struct callmaster *cm; unsigned int check; int good = 0; struct packet_stream *ps; @@ -189,11 +188,10 @@ static void call_timer_iterator(gpointer data, gpointer user_data) { rwlock_lock_r(&c->master_lock); log_info_call(c); - cm = c->callmaster; - rwlock_lock_r(&cm->conf.config_lock); + rwlock_lock_r(&rtpe_config.config_lock); // final timeout applicable to all calls (own and foreign) - if (cm->conf.final_timeout && rtpe_now.tv_sec >= (c->created.tv_sec + cm->conf.final_timeout)) { + if (rtpe_config.final_timeout && rtpe_now.tv_sec >= (c->created.tv_sec + rtpe_config.final_timeout)) { ilog(LOG_INFO, "Closing call due to final timeout"); tmp_t_reason = FINAL_TIMEOUT; for (it = c->monologues.head; it; it = it->next) { @@ -248,10 +246,10 @@ no_sfd: if (good) goto next; - check = cm->conf.timeout; + check = rtpe_config.timeout; tmp_t_reason = TIMEOUT; if (!MEDIA_ISSET(ps->media, RECV) || !sfd || !PS_ISSET(ps, FILLED)) { - check = cm->conf.silent_timeout; + check = rtpe_config.silent_timeout; tmp_t_reason = SILENT_TIMEOUT; } @@ -286,7 +284,7 @@ delete: goto out; out: - rwlock_unlock_r(&cm->conf.config_lock); + rwlock_unlock_r(&rtpe_config.config_lock); rwlock_unlock_r(&c->master_lock); log_info_clear(); } @@ -397,7 +395,7 @@ void kill_calls_timer(GSList *list, struct callmaster *m) { return; /* if m is NULL, it's the scheduled deletions, otherwise it's the timeouts */ - url = m ? m->conf.b2b_url : NULL; + url = m ? rtpe_config.b2b_url : NULL; if (url) { xh = g_slice_alloc(sizeof(*xh)); xh->c = g_string_chunk_new(64); @@ -410,7 +408,7 @@ void kill_calls_timer(GSList *list, struct callmaster *m) { else url_suffix = g_string_chunk_insert(xh->c, url); xh->tags_urls = NULL; - xh->fmt = m->conf.fmt; + xh->fmt = rtpe_config.fmt; } while (list) { @@ -429,7 +427,7 @@ void kill_calls_timer(GSList *list, struct callmaster *m) { else snprintf(url_buf, sizeof(url_buf), "%s", url_suffix); - switch (m->conf.fmt) { + switch (rtpe_config.fmt) { case XF_SEMS: for (csl = ca->monologues.head; csl; csl = csl->next) { cm = csl->data; @@ -1343,7 +1341,7 @@ static void __tos_change(struct call *call, const struct sdp_ng_flags *flags) { return; if (!flags || flags->tos > 255) - new_tos = call->callmaster->conf.default_tos; + new_tos = rtpe_config.default_tos; else new_tos = flags->tos; @@ -2017,7 +2015,7 @@ static struct call *call_create(const str *callid, struct callmaster *m) { call_str_cpy(c, &c->callid, callid); c->created = rtpe_now; c->dtls_cert = dtls_cert(); - c->tos = m->conf.default_tos; + c->tos = rtpe_config.default_tos; c->ssrc_hash = create_ssrc_hash(); return c; @@ -2363,7 +2361,7 @@ int call_delete_branch(struct callmaster *m, const str *callid, const str *branc GList *i; if (delete_delay < 0) - delete_delay = m->conf.delete_delay; + delete_delay = rtpe_config.delete_delay; c = call_get(callid, m); if (!c) { diff --git a/daemon/call.h b/daemon/call.h index ca77b17f8..b11ad5452 100644 --- a/daemon/call.h +++ b/daemon/call.h @@ -61,11 +61,6 @@ enum transport_protocol_index { __PROTO_LAST, }; -enum xmlrpc_format { - XF_SEMS = 0, - XF_CALLID, -}; - enum call_stream_state { CSS_UNKNOWN = 0, CSS_SHUTDOWN, @@ -388,29 +383,12 @@ struct call { }; struct callmaster_config { - /* everything below protected by config_lock */ - rwlock_t config_lock; - int max_sessions; - unsigned int timeout; - unsigned int silent_timeout; - unsigned int final_timeout; - - unsigned int delete_delay; struct redis *redis; struct redis *redis_write; struct redis *redis_notify; - struct event_base *redis_notify_event_base; - GQueue *redis_subscribed_keyspaces; + + struct event_base *redis_notify_event_base; struct redisAsyncContext *redis_notify_async_context; - unsigned int redis_expires_secs; - char *b2b_url; - unsigned char default_tos; - unsigned char control_tos; - enum xmlrpc_format fmt; - endpoint_t graphite_ep; - int graphite_interval; - - int redis_num_threads; }; struct callmaster { diff --git a/daemon/call_interfaces.c b/daemon/call_interfaces.c index a6334df3d..6eecb0fc0 100644 --- a/daemon/call_interfaces.c +++ b/daemon/call_interfaces.c @@ -24,6 +24,7 @@ #include "ssrc.h" #include "tcp_listener.h" #include "streambuf.h" +#include "main.h" static pcre *info_re; @@ -396,12 +397,12 @@ str *call_query_udp(char **out, struct callmaster *m) { rwlock_unlock_w(&c->master_lock); - rwlock_lock_r(&m->conf.config_lock); + rwlock_lock_r(&rtpe_config.config_lock); ret = str_sprintf("%s %lld "UINT64F" "UINT64F" "UINT64F" "UINT64F"\n", out[RE_UDP_COOKIE], - (long long int) m->conf.silent_timeout - (rtpe_now.tv_sec - stats.last_packet), + (long long int) rtpe_config.silent_timeout - (rtpe_now.tv_sec - stats.last_packet), atomic64_get_na(&stats.totals[0].packets), atomic64_get_na(&stats.totals[1].packets), atomic64_get_na(&stats.totals[2].packets), atomic64_get_na(&stats.totals[3].packets)); - rwlock_unlock_r(&m->conf.config_lock); + rwlock_unlock_r(&rtpe_config.config_lock); goto out; err: @@ -814,25 +815,25 @@ out: const char *call_offer_ng(bencode_item_t *input, struct callmaster *m, bencode_item_t *output, const char* addr, const endpoint_t *sin) { - rwlock_lock_r(&m->conf.config_lock); - if (m->conf.max_sessions>=0) { + rwlock_lock_r(&rtpe_config.config_lock); + if (rtpe_config.max_sessions>=0) { rwlock_lock_r(&rtpe_callhash_lock); if (g_hash_table_size(rtpe_callhash) - - atomic64_get(&rtpe_stats.foreign_sessions) >= m->conf.max_sessions) { + atomic64_get(&rtpe_stats.foreign_sessions) >= rtpe_config.max_sessions) { rwlock_unlock_r(&rtpe_callhash_lock); /* foreign calls can't get rejected * total_rejected_sess applies only to "own" sessions */ atomic64_inc(&rtpe_totalstats.total_rejected_sess); atomic64_inc(&rtpe_totalstats_interval.total_rejected_sess); - ilog(LOG_ERROR, "Parallel session limit reached (%i)",m->conf.max_sessions); + ilog(LOG_ERROR, "Parallel session limit reached (%i)",rtpe_config.max_sessions); - rwlock_unlock_r(&m->conf.config_lock); + rwlock_unlock_r(&rtpe_config.config_lock); return "Parallel session limit reached"; } rwlock_unlock_r(&rtpe_callhash_lock); } - rwlock_unlock_r(&m->conf.config_lock); + rwlock_unlock_r(&rtpe_config.config_lock); return call_offer_answer_ng(input, m, output, OP_OFFER, addr, sin); } diff --git a/daemon/cli.c b/daemon/cli.c index dec6102bb..b6a82397f 100644 --- a/daemon/cli.c +++ b/daemon/cli.c @@ -23,6 +23,7 @@ #include "tcp_listener.h" #include "str.h" #include "statistics.h" +#include "main.h" #include "rtpengine_config.h" @@ -263,7 +264,7 @@ static void cli_incoming_list_numsessions(str *instr, struct callmaster* m, stru static void cli_incoming_list_maxsessions(str *instr, struct callmaster* m, struct streambuf *replybuffer) { /* don't lock anything while reading the value */ - streambuf_printf(replybuffer, "Maximum sessions configured on rtpengine: %d\n", m->conf.max_sessions); + streambuf_printf(replybuffer, "Maximum sessions configured on rtpengine: %d\n", rtpe_config.max_sessions); return ; } @@ -287,14 +288,14 @@ static void cli_incoming_list_maxopenfiles(str *instr, struct callmaster* m, str } static void cli_incoming_list_timeout(str *instr, struct callmaster* m, struct streambuf *replybuffer) { - rwlock_lock_r(&m->conf.config_lock); + rwlock_lock_r(&rtpe_config.config_lock); /* don't lock anything while reading the value */ - streambuf_printf(replybuffer, "TIMEOUT=%u\n", m->conf.timeout); - streambuf_printf(replybuffer, "SILENT_TIMEOUT=%u\n", m->conf.silent_timeout); - streambuf_printf(replybuffer, "FINAL_TIMEOUT=%u\n", m->conf.final_timeout); + streambuf_printf(replybuffer, "TIMEOUT=%u\n", rtpe_config.timeout); + streambuf_printf(replybuffer, "SILENT_TIMEOUT=%u\n", rtpe_config.silent_timeout); + streambuf_printf(replybuffer, "FINAL_TIMEOUT=%u\n", rtpe_config.final_timeout); - rwlock_unlock_r(&m->conf.config_lock); + rwlock_unlock_r(&rtpe_config.config_lock); return ; } @@ -525,22 +526,22 @@ static void cli_incoming_set_maxsessions(str *instr, struct callmaster* m, struc } else if (maxsessions_num < disabled) { streambuf_printf(replybuffer, "Fail setting maxsessions to %ld; either positive or -1 values allowed\n", maxsessions_num); } else if (maxsessions_num == disabled) { - rwlock_lock_w(&m->conf.config_lock); - m->conf.max_sessions = maxsessions_num; - rwlock_unlock_w(&m->conf.config_lock); + rwlock_lock_w(&rtpe_config.config_lock); + rtpe_config.max_sessions = maxsessions_num; + rwlock_unlock_w(&rtpe_config.config_lock); streambuf_printf(replybuffer, "Success setting maxsessions to %ld; disable feature\n", maxsessions_num); } else { - rwlock_lock_w(&m->conf.config_lock); - m->conf.max_sessions = maxsessions_num; - rwlock_unlock_w(&m->conf.config_lock); + rwlock_lock_w(&rtpe_config.config_lock); + rtpe_config.max_sessions = maxsessions_num; + rwlock_unlock_w(&rtpe_config.config_lock); streambuf_printf(replybuffer, "Success setting maxsessions to %ld\n", maxsessions_num); } return; } -static void cli_incoming_set_gentimeout(str *instr, struct callmaster* m, struct streambuf *replybuffer, unsigned int *conf_timeout) { - unsigned long timeout_num; +static void cli_incoming_set_gentimeout(str *instr, struct callmaster* m, struct streambuf *replybuffer, int *conf_timeout) { + long timeout_num; char *endptr; if (str_shift(instr, 1)) { @@ -548,31 +549,30 @@ static void cli_incoming_set_gentimeout(str *instr, struct callmaster* m, struct return; } - timeout_num = strtoul(instr->s, &endptr, 10); + timeout_num = strtol(instr->s, &endptr, 10); - if ((errno == ERANGE && (timeout_num == ULONG_MAX)) || (errno != 0 && timeout_num == 0)) { + if ((errno == ERANGE && (timeout_num == ULONG_MAX)) || (errno != 0 && timeout_num == 0) || timeout_num < 0 || timeout_num >= INT_MAX) { streambuf_printf(replybuffer, "Fail setting timeout to %s; errno=%d\n", instr->s, errno); return; } else if (endptr == instr->s) { streambuf_printf(replybuffer, "Fail setting timeout to %s; no digists found\n", instr->s); return; } else { - /* don't lock anything while writing the value - only this command modifies its value */ - rwlock_lock_w(&m->conf.config_lock); - *conf_timeout = timeout_num; - rwlock_unlock_w(&m->conf.config_lock); + rwlock_lock_w(&rtpe_config.config_lock); + *conf_timeout = (int) timeout_num; + rwlock_unlock_w(&rtpe_config.config_lock); streambuf_printf(replybuffer, "Success setting timeout to %lu\n", timeout_num); } } static void cli_incoming_set_timeout(str *instr, struct callmaster* m, struct streambuf *replybuffer) { - cli_incoming_set_gentimeout(instr, m, replybuffer, &m->conf.timeout); + cli_incoming_set_gentimeout(instr, m, replybuffer, &rtpe_config.timeout); } static void cli_incoming_set_silenttimeout(str *instr, struct callmaster* m, struct streambuf *replybuffer) { - cli_incoming_set_gentimeout(instr, m, replybuffer, &m->conf.silent_timeout); + cli_incoming_set_gentimeout(instr, m, replybuffer, &rtpe_config.silent_timeout); } static void cli_incoming_set_finaltimeout(str *instr, struct callmaster* m, struct streambuf *replybuffer) { - cli_incoming_set_gentimeout(instr, m, replybuffer, &m->conf.final_timeout); + cli_incoming_set_gentimeout(instr, m, replybuffer, &rtpe_config.final_timeout); } static void cli_incoming_list(str *instr, struct callmaster* m, struct streambuf *replybuffer) { @@ -681,15 +681,15 @@ static void cli_incoming_ksadd(str *instr, struct callmaster* m, struct streambu } else if (endptr == instr->s) { streambuf_printf(replybuffer, "Fail adding keyspace %s to redis notifications; no digists found\n", instr->s); } else { - rwlock_lock_w(&m->conf.config_lock); - if (!g_queue_find(m->conf.redis_subscribed_keyspaces, GUINT_TO_POINTER(uint_keyspace_db))) { - g_queue_push_tail(m->conf.redis_subscribed_keyspaces, GUINT_TO_POINTER(uint_keyspace_db)); + rwlock_lock_w(&rtpe_config.config_lock); + if (!g_queue_find(&rtpe_config.redis_subscribed_keyspaces, GUINT_TO_POINTER(uint_keyspace_db))) { + g_queue_push_tail(&rtpe_config.redis_subscribed_keyspaces, GUINT_TO_POINTER(uint_keyspace_db)); redis_notify_subscribe_action(m, SUBSCRIBE_KEYSPACE, uint_keyspace_db); streambuf_printf(replybuffer, "Success adding keyspace %lu to redis notifications.\n", uint_keyspace_db); } else { streambuf_printf(replybuffer, "Keyspace %lu is already among redis notifications.\n", uint_keyspace_db); } - rwlock_unlock_w(&m->conf.config_lock); + rwlock_unlock_w(&rtpe_config.config_lock); } } @@ -705,15 +705,15 @@ static void cli_incoming_ksrm(str *instr, struct callmaster* m, struct streambuf uint_keyspace_db = strtoul(instr->s, &endptr, 10); - rwlock_lock_w(&m->conf.config_lock); + rwlock_lock_w(&rtpe_config.config_lock); if ((errno == ERANGE && (uint_keyspace_db == ULONG_MAX)) || (errno != 0 && uint_keyspace_db == 0)) { streambuf_printf(replybuffer, "Fail removing keyspace %s to redis notifications; errono=%d\n", instr->s, errno); } else if (endptr == instr->s) { streambuf_printf(replybuffer, "Fail removing keyspace %s to redis notifications; no digists found\n", instr->s); - } else if ((l = g_queue_find(m->conf.redis_subscribed_keyspaces, GUINT_TO_POINTER(uint_keyspace_db)))) { + } else if ((l = g_queue_find(&rtpe_config.redis_subscribed_keyspaces, GUINT_TO_POINTER(uint_keyspace_db)))) { // remove this keyspace redis_notify_subscribe_action(m, UNSUBSCRIBE_KEYSPACE, uint_keyspace_db); - g_queue_remove(m->conf.redis_subscribed_keyspaces, l->data); + g_queue_remove(&rtpe_config.redis_subscribed_keyspaces, l->data); streambuf_printf(replybuffer, "Successfully unsubscribed from keyspace %lu.\n", uint_keyspace_db); // destroy foreign calls for this keyspace @@ -724,7 +724,7 @@ static void cli_incoming_ksrm(str *instr, struct callmaster* m, struct streambuf } else { streambuf_printf(replybuffer, "Keyspace %lu is not among redis notifications.\n", uint_keyspace_db); } - rwlock_unlock_w(&m->conf.config_lock); + rwlock_unlock_w(&rtpe_config.config_lock); } @@ -733,11 +733,11 @@ static void cli_incoming_kslist(str *instr, struct callmaster* m, struct streamb streambuf_printf(replybuffer, "\nSubscribed-on keyspaces:\n"); - rwlock_lock_r(&m->conf.config_lock); - for (l = m->conf.redis_subscribed_keyspaces->head; l; l = l->next) { + rwlock_lock_r(&rtpe_config.config_lock); + for (l = rtpe_config.redis_subscribed_keyspaces.head; l; l = l->next) { streambuf_printf(replybuffer, "%u ", GPOINTER_TO_UINT(l->data)); } - rwlock_unlock_r(&m->conf.config_lock); + rwlock_unlock_r(&rtpe_config.config_lock); streambuf_printf(replybuffer, "\n"); } diff --git a/daemon/graphite.c b/daemon/graphite.c index 3699c6a0e..af6141a5a 100644 --- a/daemon/graphite.c +++ b/daemon/graphite.c @@ -21,6 +21,7 @@ #include "graphite.h" #include "socket.h" #include "statistics.h" +#include "main.h" struct timeval rtpe_latest_graphite_interval_start; @@ -334,13 +335,13 @@ void graphite_loop(void *d) { return ; } - if (cm->conf.graphite_interval <= 0) { + if (rtpe_config.graphite_interval <= 0) { ilog(LOG_WARNING,"Graphite send interval was not set. Setting it to 1 second."); - cm->conf.graphite_interval=1; + rtpe_config.graphite_interval=1; } - connect_to_graphite_server(&cm->conf.graphite_ep); + connect_to_graphite_server(&rtpe_config.graphite_ep); while (!rtpe_shutdown) - graphite_loop_run(cm, &cm->conf.graphite_ep, cm->conf.graphite_interval); // time in seconds + graphite_loop_run(cm, &rtpe_config.graphite_ep, rtpe_config.graphite_interval); // time in seconds } diff --git a/daemon/main.c b/daemon/main.c index 9689a9dd9..8d4797312 100644 --- a/daemon/main.c +++ b/daemon/main.c @@ -50,40 +50,36 @@ struct poller *rtpe_poller; +struct rtpengine_config rtpe_config = { + // non-zero defaults + .kernel_table = -1, + .max_sessions = -1, + .delete_delay = 30, + .redis_subscribed_keyspaces = G_QUEUE_INIT, + .redis_expires_secs = 86400, +}; + + + static GQueue interfaces = G_QUEUE_INIT; -static GQueue keyspaces = G_QUEUE_INIT; static endpoint_t tcp_listen_ep; static endpoint_t udp_listen_ep; static endpoint_t ng_listen_ep; static endpoint_t cli_listen_ep; -static endpoint_t graphite_ep; static endpoint_t redis_ep; static endpoint_t redis_write_ep; static endpoint_t homer_ep; static int homer_protocol = SOCK_DGRAM; static int homer_id = 2001; -static int tos; -static int control_tos; -static int table = -1; static int no_fallback; -static unsigned int timeout; -static unsigned int silent_timeout; -static unsigned int final_timeout; -static unsigned int redis_expires = 86400; static int port_min = 30000; static int port_max = 40000; -static int max_sessions = -1; static int redis_db = -1; static int redis_write_db = -1; -static int redis_num_threads; static int no_redis_required; static char *redis_auth; static char *redis_write_auth; -static char *b2b_url; -static enum xmlrpc_format xmlrpc_fmt = XF_SEMS; static int num_threads; -static int delete_delay = 30; -static int graphite_interval = 0; static char *spooldir; static char *rec_method = "pcap"; static char *rec_format = "raw"; @@ -266,7 +262,7 @@ static void options(int *argc, char ***argv) { char *endptr; GOptionEntry e[] = { - { "table", 't', 0, G_OPTION_ARG_INT, &table, "Kernel table to use", "INT" }, + { "table", 't', 0, G_OPTION_ARG_INT, &rtpe_config.kernel_table, "Kernel table to use", "INT" }, { "no-fallback",'F', 0, G_OPTION_ARG_NONE, &no_fallback, "Only start when kernel module is available", NULL }, { "interface", 'i', 0, G_OPTION_ARG_STRING_ARRAY,&if_a, "Local interface for RTP", "[NAME/]IP[!IP]"}, { "subscribe-keyspace", 'k', 0, G_OPTION_ARG_STRING_ARRAY,&ks_a, "Subscription keyspace list", "INT INT ..."}, @@ -275,29 +271,29 @@ static void options(int *argc, char ***argv) { { "listen-ng", 'n', 0, G_OPTION_ARG_STRING, &listenngs, "UDP port to listen on, NG protocol", "[IP46|HOSTNAME:]PORT" }, { "listen-cli", 'c', 0, G_OPTION_ARG_STRING, &listencli, "UDP port to listen on, CLI", "[IP46|HOSTNAME:]PORT" }, { "graphite", 'g', 0, G_OPTION_ARG_STRING, &graphitep, "Address of the graphite server", "IP46|HOSTNAME:PORT" }, - { "graphite-interval", 'G', 0, G_OPTION_ARG_INT, &graphite_interval, "Graphite send interval in seconds", "INT" }, + { "graphite-interval", 'G', 0, G_OPTION_ARG_INT, &rtpe_config.graphite_interval, "Graphite send interval in seconds", "INT" }, { "graphite-prefix",0, 0, G_OPTION_ARG_STRING, &graphite_prefix_s, "Prefix for graphite line", "STRING"}, - { "tos", 'T', 0, G_OPTION_ARG_INT, &tos, "Default TOS value to set on streams", "INT" }, - { "control-tos",0 , 0, G_OPTION_ARG_INT, &control_tos, "Default TOS value to set on control-ng", "INT" }, - { "timeout", 'o', 0, G_OPTION_ARG_INT, &timeout, "RTP timeout", "SECS" }, - { "silent-timeout",'s',0,G_OPTION_ARG_INT, &silent_timeout,"RTP timeout for muted", "SECS" }, - { "final-timeout",'a',0,G_OPTION_ARG_INT, &final_timeout, "Call timeout", "SECS" }, + { "tos", 'T', 0, G_OPTION_ARG_INT, &rtpe_config.default_tos, "Default TOS value to set on streams", "INT" }, + { "control-tos",0 , 0, G_OPTION_ARG_INT, &rtpe_config.control_tos, "Default TOS value to set on control-ng", "INT" }, + { "timeout", 'o', 0, G_OPTION_ARG_INT, &rtpe_config.timeout, "RTP timeout", "SECS" }, + { "silent-timeout",'s',0,G_OPTION_ARG_INT, &rtpe_config.silent_timeout,"RTP timeout for muted", "SECS" }, + { "final-timeout",'a',0,G_OPTION_ARG_INT, &rtpe_config.final_timeout, "Call timeout", "SECS" }, { "port-min", 'm', 0, G_OPTION_ARG_INT, &port_min, "Lowest port to use for RTP", "INT" }, { "port-max", 'M', 0, G_OPTION_ARG_INT, &port_max, "Highest port to use for RTP", "INT" }, { "redis", 'r', 0, G_OPTION_ARG_STRING, &redisps, "Connect to Redis database", "[PW@]IP:PORT/INT" }, { "redis-write",'w', 0, G_OPTION_ARG_STRING, &redisps_write, "Connect to Redis write database", "[PW@]IP:PORT/INT" }, - { "redis-num-threads", 0, 0, G_OPTION_ARG_INT, &redis_num_threads, "Number of Redis restore threads", "INT" }, - { "redis-expires", 0, 0, G_OPTION_ARG_INT, &redis_expires, "Expire time in seconds for redis keys", "INT" }, + { "redis-num-threads", 0, 0, G_OPTION_ARG_INT, &rtpe_config.redis_num_threads, "Number of Redis restore threads", "INT" }, + { "redis-expires", 0, 0, G_OPTION_ARG_INT, &rtpe_config.redis_expires_secs, "Expire time in seconds for redis keys", "INT" }, { "no-redis-required", 'q', 0, G_OPTION_ARG_NONE, &no_redis_required, "Start no matter of redis connection state", NULL }, - { "b2b-url", 'b', 0, G_OPTION_ARG_STRING, &b2b_url, "XMLRPC URL of B2B UA" , "STRING" }, + { "b2b-url", 'b', 0, G_OPTION_ARG_STRING, &rtpe_config.b2b_url, "XMLRPC URL of B2B UA" , "STRING" }, { "log-facility-cdr",0, 0, G_OPTION_ARG_STRING, &log_facility_cdr_s, "Syslog facility to use for logging CDRs", "daemon|local0|...|local7"}, { "log-facility-rtcp",0, 0, G_OPTION_ARG_STRING, &log_facility_rtcp_s, "Syslog facility to use for logging RTCP", "daemon|local0|...|local7"}, - { "xmlrpc-format",'x', 0, G_OPTION_ARG_INT, &xmlrpc_fmt, "XMLRPC timeout request format to use. 0: SEMS DI, 1: call-id only", "INT" }, + { "xmlrpc-format",'x', 0, G_OPTION_ARG_INT, &rtpe_config.fmt, "XMLRPC timeout request format to use. 0: SEMS DI, 1: call-id only", "INT" }, { "num-threads", 0, 0, G_OPTION_ARG_INT, &num_threads, "Number of worker threads to create", "INT" }, - { "delete-delay", 'd', 0, G_OPTION_ARG_INT, &delete_delay, "Delay for deleting a session from memory.", "INT" }, + { "delete-delay", 'd', 0, G_OPTION_ARG_INT, &rtpe_config.delete_delay, "Delay for deleting a session from memory.", "INT" }, { "sip-source", 0, 0, G_OPTION_ARG_NONE, &sip_source, "Use SIP source address by default", NULL }, { "dtls-passive", 0, 0, G_OPTION_ARG_NONE, &dtls_passive_def,"Always prefer DTLS passive role", NULL }, - { "max-sessions", 0, 0, G_OPTION_ARG_INT, &max_sessions, "Limit of maximum number of sessions", "INT" }, + { "max-sessions", 0, 0, G_OPTION_ARG_INT, &rtpe_config.max_sessions, "Limit of maximum number of sessions", "INT" }, { "homer", 0, 0, G_OPTION_ARG_STRING, &homerp, "Address of Homer server for RTCP stats","IP46|HOSTNAME:PORT"}, { "homer-protocol",0,0,G_OPTION_ARG_STRING, &homerproto, "Transport protocol for Homer (default udp)", "udp|tcp" }, { "homer-id", 0, 0, G_OPTION_ARG_STRING, &homer_id, "'Capture ID' to use within the HEP protocol", "INT" }, @@ -337,7 +333,7 @@ static void options(int *argc, char ***argv) { } else if (endptr == str_keyspace_db.s) { ilog(LOG_ERR, "Fail adding keyspace %.*s to redis notifications; no digits found\n", str_keyspace_db.len, str_keyspace_db.s); } else { - g_queue_push_tail(&keyspaces, GUINT_TO_POINTER(uint_keyspace_db)); + g_queue_push_tail(&rtpe_config.redis_subscribed_keyspaces, GUINT_TO_POINTER(uint_keyspace_db)); } } } @@ -359,7 +355,7 @@ static void options(int *argc, char ***argv) { die("Invalid IP or port (--listen-cli)"); } - if (graphitep) {if (endpoint_parse_any_getaddrinfo_full(&graphite_ep, graphitep)) + if (graphitep) {if (endpoint_parse_any_getaddrinfo_full(&rtpe_config.graphite_ep, graphitep)) die("Invalid IP or port (--graphite)"); } @@ -379,20 +375,20 @@ static void options(int *argc, char ***argv) { die("Invalid protocol (--homer-protocol)"); } - if (tos < 0 || tos > 255) + if (rtpe_config.default_tos < 0 || rtpe_config.default_tos > 255) die("Invalid TOS value"); - if (control_tos < 0 || control_tos > 255) + if (rtpe_config.control_tos < 0 || rtpe_config.control_tos > 255) die("Invalid control-ng TOS value"); - if (timeout <= 0) - timeout = 60; + if (rtpe_config.timeout <= 0) + rtpe_config.timeout = 60; - if (silent_timeout <= 0) - silent_timeout = 3600; + if (rtpe_config.silent_timeout <= 0) + rtpe_config.silent_timeout = 3600; - if (final_timeout <= 0) - final_timeout = 0; + if (rtpe_config.final_timeout <= 0) + rtpe_config.final_timeout = 0; if (redisps) if (redis_ep_parse(&redis_ep, &redis_db, &redis_auth, "RTPENGINE_REDIS_AUTH_PW", redisps)) @@ -403,7 +399,7 @@ static void options(int *argc, char ***argv) { "RTPENGINE_REDIS_WRITE_AUTH_PW", redisps_write)) die("Invalid Redis endpoint [IP:PORT/INT] (--redis-write)"); - if (xmlrpc_fmt > 1) + if (rtpe_config.fmt > 1) die("Invalid XMLRPC format"); if ((log_level < LOG_EMERG) || (log_level > LOG_DEBUG)) @@ -505,7 +501,6 @@ static void init_everything() { static void create_everything(struct main_context *ctx) { - struct callmaster_config mc; struct control_tcp *ct; struct control_udp *cu; struct control_ng *cn; @@ -514,9 +509,9 @@ static void create_everything(struct main_context *ctx) { struct timeval redis_start, redis_stop; double redis_diff = 0; - if (table < 0) + if (rtpe_config.kernel_table < 0) goto no_kernel; - if (kernel_setup_table(table)) { + if (kernel_setup_table(rtpe_config.kernel_table)) { if (no_fallback) { ilog(LOG_CRIT, "Userspace fallback disallowed - exiting"); exit(-1); @@ -535,33 +530,19 @@ no_kernel: dtls_timer(rtpe_poller); - ZERO(mc); - rwlock_init(&mc.config_lock); - if (max_sessions < -1) { - max_sessions = -1; + rwlock_init(&rtpe_config.config_lock); + if (rtpe_config.max_sessions < -1) { + rtpe_config.max_sessions = -1; } - mc.max_sessions = max_sessions; - mc.timeout = timeout; - mc.silent_timeout = silent_timeout; - mc.final_timeout = final_timeout; - mc.delete_delay = delete_delay; - mc.default_tos = tos; - mc.control_tos = control_tos; - mc.b2b_url = b2b_url; - mc.fmt = xmlrpc_fmt; - mc.graphite_ep = graphite_ep; - mc.graphite_interval = graphite_interval; - mc.redis_subscribed_keyspaces = g_queue_copy(&keyspaces); - - if (redis_num_threads < 1) { + + if (rtpe_config.redis_num_threads < 1) { #ifdef _SC_NPROCESSORS_ONLN - redis_num_threads = sysconf( _SC_NPROCESSORS_ONLN ); + rtpe_config.redis_num_threads = sysconf( _SC_NPROCESSORS_ONLN ); #endif - if (redis_num_threads < 1) { - redis_num_threads = REDIS_RESTORE_NUM_THREADS; + if (rtpe_config.redis_num_threads < 1) { + rtpe_config.redis_num_threads = REDIS_RESTORE_NUM_THREADS; } } - mc.redis_num_threads = redis_num_threads; ct = NULL; if (tcp_listen_ep.port) { @@ -581,7 +562,7 @@ no_kernel: cn = NULL; if (ng_listen_ep.port) { interfaces_exclude_port(ng_listen_ep.port); - cn = control_ng_new(rtpe_poller, &ng_listen_ep, ctx->m, control_tos); + cn = control_ng_new(rtpe_poller, &ng_listen_ep, ctx->m, rtpe_config.control_tos); if (!cn) die("Failed to open UDP control connection port"); } @@ -595,27 +576,23 @@ no_kernel: } if (!is_addr_unspecified(&redis_write_ep.address)) { - mc.redis_write = redis_new(&redis_write_ep, redis_write_db, redis_write_auth, ANY_REDIS_ROLE, no_redis_required); - if (!mc.redis_write) + ctx->m->conf.redis_write = redis_new(&redis_write_ep, redis_write_db, redis_write_auth, ANY_REDIS_ROLE, no_redis_required); + if (!ctx->m->conf.redis_write) die("Cannot start up without running Redis %s write database! See also NO_REDIS_REQUIRED parameter.", endpoint_print_buf(&redis_write_ep)); } if (!is_addr_unspecified(&redis_ep.address)) { - mc.redis = redis_new(&redis_ep, redis_db, redis_auth, mc.redis_write ? ANY_REDIS_ROLE : MASTER_REDIS_ROLE, no_redis_required); - mc.redis_notify = redis_new(&redis_ep, redis_db, redis_auth, mc.redis_write ? ANY_REDIS_ROLE : MASTER_REDIS_ROLE, no_redis_required); - if (!mc.redis || !mc.redis_notify) + ctx->m->conf.redis = redis_new(&redis_ep, redis_db, redis_auth, ctx->m->conf.redis_write ? ANY_REDIS_ROLE : MASTER_REDIS_ROLE, no_redis_required); + ctx->m->conf.redis_notify = redis_new(&redis_ep, redis_db, redis_auth, ctx->m->conf.redis_write ? ANY_REDIS_ROLE : MASTER_REDIS_ROLE, no_redis_required); + if (!ctx->m->conf.redis || !ctx->m->conf.redis_notify) die("Cannot start up without running Redis %s database! See also NO_REDIS_REQUIRED parameter.", endpoint_print_buf(&redis_ep)); - if (!mc.redis_write) - mc.redis_write = mc.redis; + if (!ctx->m->conf.redis_write) + ctx->m->conf.redis_write = ctx->m->conf.redis; } - mc.redis_expires_secs = redis_expires; - - ctx->m->conf = mc; - daemonize(); wpidfile(); @@ -623,12 +600,12 @@ no_kernel: rtcp_init(); // must come after Homer init - if (mc.redis) { + if (ctx->m->conf.redis) { // start redis restore timer gettimeofday(&redis_start, NULL); // restore - if (redis_restore(ctx->m, mc.redis)) + if (redis_restore(ctx->m, ctx->m->conf.redis)) die("Refusing to continue without working Redis database"); // stop redis restore timer @@ -641,7 +618,7 @@ no_kernel: gettimeofday(&rtpe_latest_graphite_interval_start, NULL); - timeval_from_us(&tmp_tv, (long long) graphite_interval*1000000); + timeval_from_us(&tmp_tv, (long long) rtpe_config.graphite_interval*1000000); set_graphite_interval_tv(&tmp_tv); } @@ -663,7 +640,7 @@ int main(int argc, char **argv) { if (!is_addr_unspecified(&redis_ep.address)) thread_create_detach(redis_notify_loop, ctx.m); - if (!is_addr_unspecified(&graphite_ep.address)) + if (!is_addr_unspecified(&rtpe_config.graphite_ep.address)) thread_create_detach(graphite_loop, ctx.m); thread_create_detach(ice_thread_run, NULL); diff --git a/daemon/main.h b/daemon/main.h index 3ddba0c7a..55124f1cc 100644 --- a/daemon/main.h +++ b/daemon/main.h @@ -1,7 +1,43 @@ #ifndef _MAIN_H_ #define _MAIN_H_ + +#include "aux.h" +#include +#include "socket.h" + +enum xmlrpc_format { + XF_SEMS = 0, + XF_CALLID, +}; + +struct rtpengine_config { + /* everything below protected by config_lock */ + rwlock_t config_lock; + int kernel_table; + int max_sessions; + int timeout; + int silent_timeout; + int final_timeout; + int delete_delay; + GQueue redis_subscribed_keyspaces; + int redis_expires_secs; + char *b2b_url; + int default_tos; + int control_tos; + enum xmlrpc_format fmt; + endpoint_t graphite_ep; + int graphite_interval; + int redis_num_threads; +}; + + struct poller; extern struct poller *rtpe_poller; // main global poller instance XXX convert to struct instead of pointer? + +extern struct rtpengine_config rtpe_config; + + + #endif diff --git a/daemon/redis.c b/daemon/redis.c index f3c258286..5649e099e 100644 --- a/daemon/redis.c +++ b/daemon/redis.c @@ -30,6 +30,7 @@ #include "rtplib.h" #include "str.h" #include "ssrc.h" +#include "main.h" INLINE redisReply *redis_expect(int type, redisReply *r) { @@ -543,11 +544,11 @@ static int redis_notify(struct callmaster *cm) { } // subscribe to the values in the configured keyspaces - rwlock_lock_r(&cm->conf.config_lock); - for (l = cm->conf.redis_subscribed_keyspaces->head; l; l = l->next) { + rwlock_lock_r(&rtpe_config.config_lock); + for (l = rtpe_config.redis_subscribed_keyspaces.head; l; l = l->next) { redis_notify_subscribe_action(cm, SUBSCRIBE_KEYSPACE, GPOINTER_TO_UINT(l->data)); } - rwlock_unlock_r(&cm->conf.config_lock); + rwlock_unlock_r(&rtpe_config.config_lock); // dispatch event base => thread blocks here if (event_base_dispatch(cm->conf.redis_notify_event_base) < 0) { @@ -1649,9 +1650,9 @@ int redis_restore(struct callmaster *m, struct redis *r) { ctx.m = m; mutex_init(&ctx.r_m); g_queue_init(&ctx.r_q); - for (i = 0; i < m->conf.redis_num_threads; i++) + for (i = 0; i < rtpe_config.redis_num_threads; i++) g_queue_push_tail(&ctx.r_q, redis_new(&r->endpoint, r->db, r->auth, r->role, r->no_redis_required)); - gtp = g_thread_pool_new(restore_thread, &ctx, m->conf.redis_num_threads, TRUE, NULL); + gtp = g_thread_pool_new(restore_thread, &ctx, rtpe_config.redis_num_threads, TRUE, NULL); for (i = 0; i < calls->elements; i++) { call = calls->element[i]; @@ -2073,7 +2074,7 @@ void redis_update_onekey(struct call *c, struct redis *r) { rwlock_lock_r(&c->master_lock); - redis_expires_s = c->callmaster->conf.redis_expires_secs; + redis_expires_s = rtpe_config.redis_expires_secs; c->redis_hosted_db = r->db; if (redisCommandNR(r->ctx, "SELECT %i", c->redis_hosted_db)) { diff --git a/daemon/statistics.c b/daemon/statistics.c index de788b554..74bfd04de 100644 --- a/daemon/statistics.c +++ b/daemon/statistics.c @@ -1,6 +1,8 @@ #include "call.h" #include "statistics.h" #include "graphite.h" +#include "main.h" + struct totalstats rtpe_totalstats; struct totalstats rtpe_totalstats_interval; @@ -108,7 +110,6 @@ void statistics_update_foreignown_inc(struct call* c) { } void statistics_update_oneway(struct call* c) { - struct callmaster *m; struct packet_stream *ps = NULL, *ps2 = NULL; struct call_monologue *ml; struct call_media *md; @@ -117,8 +118,6 @@ void statistics_update_oneway(struct call* c) { GList *l; struct timeval tim_result_duration; - m = c->callmaster; - // --- for statistics getting one way stream or no relay at all int total_nopacket_relayed_sess = 0; @@ -205,7 +204,7 @@ void statistics_update_oneway(struct call* c) { timeval_totalstats_interval_call_duration_add( &rtpe_totalstats_interval, &ml->started, &ml->terminated, &rtpe_latest_graphite_interval_start, - m->conf.graphite_interval); + rtpe_config.graphite_interval); } if (ml->term_reason==FINAL_TIMEOUT) { From 75056a8dd14d7f5d2f819d2976878d201dfeab84 Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Wed, 3 Jan 2018 12:30:58 -0500 Subject: [PATCH 56/65] eliminate the callmaster struct Change-Id: I9151dbe8f47b3bb9ab67d6fea2fc3783bdc558da --- daemon/call.c | 76 ++++++++----------- daemon/call.h | 33 ++------- daemon/call_interfaces.c | 94 ++++++++++++------------ daemon/call_interfaces.h | 31 ++++---- daemon/cli.c | 142 ++++++++++++++++++----------------- daemon/cli.h | 3 +- daemon/control_ng.c | 19 +++-- daemon/control_ng.h | 4 +- daemon/control_tcp.c | 14 ++-- daemon/control_tcp.h | 3 +- daemon/control_udp.c | 13 ++-- daemon/control_udp.h | 4 +- daemon/graphite.c | 30 ++------ daemon/graphite.h | 4 +- daemon/main.c | 48 +++++------- daemon/media_socket.c | 2 +- daemon/redis.c | 155 +++++++++++++++------------------------ daemon/redis.h | 16 +++- 18 files changed, 294 insertions(+), 397 deletions(-) diff --git a/daemon/call.c b/daemon/call.c index 3603ec640..8f10fdf1e 100644 --- a/daemon/call.c +++ b/daemon/call.c @@ -128,8 +128,8 @@ GHashTable *rtpe_callhash; static void __monologue_destroy(struct call_monologue *monologue); static int monologue_destroy(struct call_monologue *ml); -static struct timeval add_ongoing_calls_dur_in_interval(struct callmaster *m, - struct timeval *interval_start, struct timeval *interval_duration); +static struct timeval add_ongoing_calls_dur_in_interval(struct timeval *interval_start, + struct timeval *interval_duration); /* called with call->master_lock held in R */ static int call_timer_delete_monologues(struct call *c) { @@ -171,7 +171,7 @@ out: -/* called with callmaster->hashlock held */ +/* called with hashlock held */ static void call_timer_iterator(gpointer data, gpointer user_data) { struct call *c = data; struct iterator_helper *hlp = user_data; @@ -383,19 +383,18 @@ fault: g_slice_free1(sizeof(*xh), xh); } -void kill_calls_timer(GSList *list, struct callmaster *m) { +void kill_calls_timer(GSList *list, const char *url) { struct call *ca; GList *csl; struct call_monologue *cm; - const char *url, *url_prefix, *url_suffix; + const char *url_prefix, *url_suffix; struct xmlrpc_helper *xh = NULL; char url_buf[128]; if (!list) return; - /* if m is NULL, it's the scheduled deletions, otherwise it's the timeouts */ - url = m ? rtpe_config.b2b_url : NULL; + /* if url is NULL, it's the scheduled deletions, otherwise it's the timeouts */ if (url) { xh = g_slice_alloc(sizeof(*xh)); xh->c = g_string_chunk_new(64); @@ -467,8 +466,7 @@ destroy: atomic64_add(&ps->stats.x, d); \ atomic64_add(&rtpe_statsps.x, d); \ } while (0) -static void callmaster_timer(void *ptr) { - struct callmaster *m = ptr; +static void call_timer(void *ptr) { struct iterator_helper hlp; GList *i, *l, *calls = NULL; struct rtpengine_list_entry *ke; @@ -588,7 +586,7 @@ static void callmaster_timer(void *ptr) { rwlock_unlock_r(&sfd->call->master_lock); if (update) { - redis_update_onekey(ps->call, m->conf.redis_write); + redis_update_onekey(ps->call, rtpe_redis_write); } next: @@ -606,28 +604,20 @@ next: g_hash_table_destroy(hlp.addr_sfd); kill_calls_timer(hlp.del_scheduled, NULL); - kill_calls_timer(hlp.del_timeout, m); + kill_calls_timer(hlp.del_timeout, rtpe_config.b2b_url); } #undef DS -struct callmaster *callmaster_new() { - struct callmaster *c; - - c = obj_alloc0("callmaster", sizeof(*c), NULL); - +int call_init() { rtpe_callhash = g_hash_table_new(str_hash, str_equal); if (!rtpe_callhash) - goto fail; + return -1; rwlock_init(&rtpe_callhash_lock); - poller_add_timer(rtpe_poller, callmaster_timer, &c->obj); - - return c; + poller_add_timer(rtpe_poller, call_timer, NULL); -fail: - obj_put(c); - return NULL; + return 0; } @@ -1716,9 +1706,8 @@ out: return rtp_pt; /* may be NULL */ } -void add_total_calls_duration_in_interval(struct callmaster *cm, - struct timeval *interval_tv) { - struct timeval ongoing_calls_dur = add_ongoing_calls_dur_in_interval(cm, +void add_total_calls_duration_in_interval(struct timeval *interval_tv) { + struct timeval ongoing_calls_dur = add_ongoing_calls_dur_in_interval( &rtpe_latest_graphite_interval_start, interval_tv); mutex_lock(&rtpe_totalstats_interval.total_calls_duration_lock); @@ -1728,8 +1717,9 @@ void add_total_calls_duration_in_interval(struct callmaster *cm, mutex_unlock(&rtpe_totalstats_interval.total_calls_duration_lock); } -static struct timeval add_ongoing_calls_dur_in_interval(struct callmaster *m, - struct timeval *interval_start, struct timeval *interval_duration) { +static struct timeval add_ongoing_calls_dur_in_interval(struct timeval *interval_start, + struct timeval *interval_duration) +{ GHashTableIter iter; gpointer key, value; struct timeval call_duration, res = {0}; @@ -1757,7 +1747,6 @@ static struct timeval add_ongoing_calls_dur_in_interval(struct callmaster *m, /* called lock-free, but must hold a reference to the call */ void call_destroy(struct call *c) { - struct callmaster *m; struct packet_stream *ps=0; struct stream_fd *sfd; GList *l; @@ -1771,8 +1760,6 @@ void call_destroy(struct call *c) { return; } - m = c->callmaster; - rwlock_lock_w(&rtpe_callhash_lock); ret = (g_hash_table_lookup(rtpe_callhash, &c->callid) == c); if (ret) @@ -1789,7 +1776,7 @@ void call_destroy(struct call *c) { statistics_update_foreignown_dec(c); if (IS_OWN_CALL(c)) { - redis_delete(c, m->conf.redis_write); + redis_delete(c, rtpe_redis_write); } rwlock_lock_w(&c->master_lock); @@ -2001,12 +1988,11 @@ static void __call_free(void *p) { assert(c->stream_fds.head == NULL); } -static struct call *call_create(const str *callid, struct callmaster *m) { +static struct call *call_create(const str *callid) { struct call *c; ilog(LOG_NOTICE, "Creating new call"); c = obj_alloc0("call", sizeof(*c), __call_free); - c->callmaster = m; mutex_init(&c->buffer_lock); call_buffer_init(&c->buffer); rwlock_init(&c->master_lock); @@ -2022,7 +2008,7 @@ static struct call *call_create(const str *callid, struct callmaster *m) { } /* returns call with master_lock held in W */ -struct call *call_get_or_create(const str *callid, struct callmaster *m, enum call_type type) { +struct call *call_get_or_create(const str *callid, enum call_type type) { struct call *c; restart: @@ -2031,7 +2017,7 @@ restart: if (!c) { rwlock_unlock_r(&rtpe_callhash_lock); /* completely new call-id, create call */ - c = call_create(callid, m); + c = call_create(callid); rwlock_lock_w(&rtpe_callhash_lock); if (g_hash_table_lookup(rtpe_callhash, callid)) { /* preempted */ @@ -2060,7 +2046,7 @@ restart: } /* returns call with master_lock held in W, or NULL if not found */ -struct call *call_get(const str *callid, struct callmaster *m) { +struct call *call_get(const str *callid) { struct call *ret; rwlock_lock_r(&rtpe_callhash_lock); @@ -2079,10 +2065,10 @@ struct call *call_get(const str *callid, struct callmaster *m) { } /* returns call with master_lock held in W, or possibly NULL iff opmode == OP_ANSWER */ -struct call *call_get_opmode(const str *callid, struct callmaster *m, enum call_opmode opmode) { +struct call *call_get_opmode(const str *callid, enum call_opmode opmode) { if (opmode == OP_OFFER) - return call_get_or_create(callid, m, CT_OWN_CALL); - return call_get(callid, m); + return call_get_or_create(callid, CT_OWN_CALL); + return call_get(callid); } /* must be called with call->master_lock held in W */ @@ -2351,7 +2337,7 @@ struct call_monologue *call_get_mono_dialogue(struct call *call, const str *from } -int call_delete_branch(struct callmaster *m, const str *callid, const str *branch, +int call_delete_branch(const str *callid, const str *branch, const str *fromtag, const str *totag, bencode_item_t *output, int delete_delay) { struct call *c; @@ -2363,7 +2349,7 @@ int call_delete_branch(struct callmaster *m, const str *callid, const str *branc if (delete_delay < 0) delete_delay = rtpe_config.delete_delay; - c = call_get(callid, m); + c = call_get(callid); if (!c) { ilog(LOG_INFO, "Call-ID to delete not found"); goto err; @@ -2461,14 +2447,14 @@ out: } -static void callmaster_get_all_calls_interator(void *key, void *val, void *ptr) { +static void call_get_all_calls_interator(void *key, void *val, void *ptr) { GQueue *q = ptr; g_queue_push_tail(q, obj_get_o(val)); } -void callmaster_get_all_calls(struct callmaster *m, GQueue *q) { +void call_get_all_calls(GQueue *q) { rwlock_lock_r(&rtpe_callhash_lock); - g_hash_table_foreach(rtpe_callhash, callmaster_get_all_calls_interator, q); + g_hash_table_foreach(rtpe_callhash, call_get_all_calls_interator, q); rwlock_unlock_r(&rtpe_callhash_lock); } diff --git a/daemon/call.h b/daemon/call.h index b11ad5452..8a8cfe105 100644 --- a/daemon/call.h +++ b/daemon/call.h @@ -350,8 +350,6 @@ struct call_monologue { struct call { struct obj obj; - struct callmaster *callmaster; /* RO */ - mutex_t buffer_lock; call_buffer_t buffer; @@ -382,20 +380,6 @@ struct call { struct recording *recording; }; -struct callmaster_config { - struct redis *redis; - struct redis *redis_write; - struct redis *redis_notify; - - struct event_base *redis_notify_event_base; - struct redisAsyncContext *redis_notify_async_context; -}; - -struct callmaster { - struct obj obj; - - struct callmaster_config conf; -}; extern rwlock_t rtpe_callhash_lock; @@ -405,25 +389,22 @@ extern struct stats rtpe_statsps; /* per second stats, running timer */ extern struct stats rtpe_stats; /* copied from statsps once a second */ -struct callmaster *callmaster_new(void); -void callmaster_get_all_calls(struct callmaster *m, GQueue *q); +int call_init(void); +void call_get_all_calls(GQueue *q); -//void calls_dump_redis(struct callmaster *); -//void calls_dump_redis_read(struct callmaster *); -//void calls_dump_redis_write(struct callmaster *); struct call_monologue *__monologue_create(struct call *call); void __monologue_tag(struct call_monologue *ml, const str *tag); void __monologue_viabranch(struct call_monologue *ml, const str *viabranch); struct packet_stream *__packet_stream_new(struct call *call); -struct call *call_get_or_create(const str *callid, struct callmaster *m, enum call_type); -struct call *call_get_opmode(const str *callid, struct callmaster *m, enum call_opmode opmode); +struct call *call_get_or_create(const str *callid, enum call_type); +struct call *call_get_opmode(const str *callid, enum call_opmode opmode); struct call_monologue *call_get_mono_dialogue(struct call *call, const str *fromtag, const str *totag, const str *viabranch); -struct call *call_get(const str *callid, struct callmaster *m); +struct call *call_get(const str *callid); int monologue_offer_answer(struct call_monologue *monologue, GQueue *streams, const struct sdp_ng_flags *flags); -int call_delete_branch(struct callmaster *m, const str *callid, const str *branch, +int call_delete_branch(const str *callid, const str *branch, const str *fromtag, const str *totag, bencode_item_t *output, int delete_delay); void call_destroy(struct call *); enum call_stream_state call_stream_state_machine(struct packet_stream *); @@ -434,7 +415,7 @@ int call_stream_address46(char *o, struct packet_stream *ps, enum stream_address int *len, const struct local_intf *ifa, int keep_unspec); const struct transport_protocol *transport_protocol(const str *s); -void add_total_calls_duration_in_interval(struct callmaster *cm, struct timeval *interval_tv); +void add_total_calls_duration_in_interval(struct timeval *interval_tv); void __payload_type_free(void *p); void __rtp_stats_update(GHashTable *dst, GHashTable *src); diff --git a/daemon/call_interfaces.c b/daemon/call_interfaces.c index 6eecb0fc0..fce3be8f4 100644 --- a/daemon/call_interfaces.c +++ b/daemon/call_interfaces.c @@ -142,7 +142,7 @@ fail: return -1; } -static str *call_update_lookup_udp(char **out, struct callmaster *m, enum call_opmode opmode, const char* addr, +static str *call_update_lookup_udp(char **out, enum call_opmode opmode, const char* addr, const endpoint_t *sin) { struct call *c; @@ -159,7 +159,7 @@ static str *call_update_lookup_udp(char **out, struct callmaster *m, enum call_o if (opmode == OP_ANSWER) str_swap(&fromtag, &totag); - c = call_get_opmode(&callid, m, opmode); + c = call_get_opmode(&callid, opmode); if (!c) { ilog(LOG_WARNING, "["STR_FORMAT"] Got UDP LOOKUP for unknown call-id", STR_FMT(&callid)); @@ -195,7 +195,7 @@ static str *call_update_lookup_udp(char **out, struct callmaster *m, enum call_o sp.index, sp.index, out[RE_UDP_COOKIE], SAF_UDP); rwlock_unlock_w(&c->master_lock); - redis_update_onekey(c, m->conf.redis_write); + redis_update_onekey(c, rtpe_redis_write); gettimeofday(&(monologue->started), NULL); @@ -219,11 +219,11 @@ out: return ret; } -str *call_update_udp(char **out, struct callmaster *m, const char* addr, const endpoint_t *sin) { - return call_update_lookup_udp(out, m, OP_OFFER, addr, sin); +str *call_update_udp(char **out, const char* addr, const endpoint_t *sin) { + return call_update_lookup_udp(out, OP_OFFER, addr, sin); } -str *call_lookup_udp(char **out, struct callmaster *m) { - return call_update_lookup_udp(out, m, OP_ANSWER, NULL, NULL); +str *call_lookup_udp(char **out) { + return call_update_lookup_udp(out, OP_ANSWER, NULL, NULL); } @@ -235,7 +235,7 @@ static int info_parse_func(char **a, void **ret, void *p) { return -1; } -static void info_parse(const char *s, GHashTable *ih, struct callmaster *m) { +static void info_parse(const char *s, GHashTable *ih) { pcre_multi_match(info_re, info_ree, s, 2, info_parse_func, ih, NULL); } @@ -273,7 +273,7 @@ fail: } -static void streams_parse(const char *s, struct callmaster *m, GQueue *q) { +static void streams_parse(const char *s, GQueue *q) { int i; i = 0; pcre_multi_match(streams_re, streams_ree, s, 3, streams_parse_func, &i, q); @@ -298,7 +298,7 @@ static void streams_free(GQueue *q) { -static str *call_request_lookup_tcp(char **out, struct callmaster *m, enum call_opmode opmode) { +static str *call_request_lookup_tcp(char **out, enum call_opmode opmode) { struct call *c; struct call_monologue *monologue; GQueue s = G_QUEUE_INIT; @@ -307,14 +307,14 @@ static str *call_request_lookup_tcp(char **out, struct callmaster *m, enum call_ str_init(&callid, out[RE_TCP_RL_CALLID]); infohash = g_hash_table_new_full(g_str_hash, g_str_equal, free, free); - c = call_get_opmode(&callid, m, opmode); + c = call_get_opmode(&callid, opmode); if (!c) { ilog(LOG_WARNING, "["STR_FORMAT"] Got LOOKUP for unknown call-id", STR_FMT(&callid)); goto out; } - info_parse(out[RE_TCP_RL_INFO], infohash, m); - streams_parse(out[RE_TCP_RL_STREAMS], m, &s); + info_parse(out[RE_TCP_RL_INFO], infohash); + streams_parse(out[RE_TCP_RL_STREAMS], &s); str_init(&fromtag, g_hash_table_lookup(infohash, "fromtag")); if (!fromtag.s) { ilog(LOG_WARNING, "No from-tag in message"); @@ -343,7 +343,7 @@ out2: rwlock_unlock_w(&c->master_lock); streams_free(&s); - redis_update_onekey(c, m->conf.redis_write); + redis_update_onekey(c, rtpe_redis_write); ilog(LOG_INFO, "Returning to SIP proxy: "STR_FORMAT"", STR_FMT0(ret)); obj_put(c); @@ -353,14 +353,14 @@ out: return ret; } -str *call_request_tcp(char **out, struct callmaster *m) { - return call_request_lookup_tcp(out, m, OP_OFFER); +str *call_request_tcp(char **out) { + return call_request_lookup_tcp(out, OP_OFFER); } -str *call_lookup_tcp(char **out, struct callmaster *m) { - return call_request_lookup_tcp(out, m, OP_ANSWER); +str *call_lookup_tcp(char **out) { + return call_request_lookup_tcp(out, OP_ANSWER); } -str *call_delete_udp(char **out, struct callmaster *m) { +str *call_delete_udp(char **out) { str callid, branch, fromtag, totag; __C_DBG("got delete for callid '%s' and viabranch '%s'", @@ -371,12 +371,12 @@ str *call_delete_udp(char **out, struct callmaster *m) { str_init(&fromtag, out[RE_UDP_DQ_FROMTAG]); str_init(&totag, out[RE_UDP_DQ_TOTAG]); - if (call_delete_branch(m, &callid, &branch, &fromtag, &totag, NULL, -1)) + if (call_delete_branch(&callid, &branch, &fromtag, &totag, NULL, -1)) return str_sprintf("%s E8\n", out[RE_UDP_COOKIE]); return str_sprintf("%s 0\n", out[RE_UDP_COOKIE]); } -str *call_query_udp(char **out, struct callmaster *m) { +str *call_query_udp(char **out) { struct call *c; str *ret, callid, fromtag, totag; struct call_stats stats; @@ -387,7 +387,7 @@ str *call_query_udp(char **out, struct callmaster *m) { str_init(&fromtag, out[RE_UDP_DQ_FROMTAG]); str_init(&totag, out[RE_UDP_DQ_TOTAG]); - c = call_get_opmode(&callid, m, OP_OTHER); + c = call_get_opmode(&callid, OP_OTHER); if (!c) { ilog(LOG_INFO, "["STR_FORMAT"] Call-ID to query not found", STR_FMT(&callid)); goto err; @@ -417,11 +417,11 @@ out: return ret; } -void call_delete_tcp(char **out, struct callmaster *m) { +void call_delete_tcp(char **out) { str callid; str_init(&callid, out[RE_TCP_D_CALLID]); - call_delete_branch(m, &callid, NULL, NULL, NULL, NULL, -1); + call_delete_branch(&callid, NULL, NULL, NULL, NULL, -1); } static void call_status_iterator(struct call *c, struct streambuf_stream *s) { @@ -430,10 +430,8 @@ static void call_status_iterator(struct call *c, struct streambuf_stream *s) { // struct peer *p; // struct streamrelay *r1, *r2; // struct streamrelay *rx1, *rx2; -// struct callmaster *m; // char addr1[64], addr2[64], addr3[64]; -// m = c->callmaster; // mutex_lock(&c->master_lock); streambuf_printf(s->outbuf, "session "STR_FORMAT" - - - - %lli\n", @@ -445,11 +443,11 @@ static void call_status_iterator(struct call *c, struct streambuf_stream *s) { // mutex_unlock(&c->master_lock); } -void calls_status_tcp(struct callmaster *m, struct streambuf_stream *s) { +void calls_status_tcp(struct streambuf_stream *s) { GQueue q = G_QUEUE_INIT; struct call *c; - callmaster_get_all_calls(m, &q); + call_get_all_calls(&q); streambuf_printf(s->outbuf, "proxy %u "UINT64F"/%i/%i\n", g_queue_get_length(&q), @@ -661,7 +659,7 @@ static void call_ng_process_flags(struct sdp_ng_flags *out, bencode_item_t *inpu bencode_dictionary_get_str(input, "metadata", &out->metadata); } -static const char *call_offer_answer_ng(bencode_item_t *input, struct callmaster *m, +static const char *call_offer_answer_ng(bencode_item_t *input, bencode_item_t *output, enum call_opmode opmode, const char* addr, const endpoint_t *sin) { @@ -702,7 +700,7 @@ static const char *call_offer_answer_ng(bencode_item_t *input, struct callmaster goto out; /* OP_ANSWER; OP_OFFER && !IS_FOREIGN_CALL */ - call = call_get(&callid, m); + call = call_get(&callid); /* Failover scenario because of timeout on offer response: siprouter tries * to establish session with another rtpengine2 even though rtpengine1 @@ -715,12 +713,12 @@ static const char *call_offer_answer_ng(bencode_item_t *input, struct callmaster rwlock_unlock_w(&call->master_lock); call_destroy(call); obj_put(call); - call = call_get_or_create(&callid, m, CT_OWN_CALL); + call = call_get_or_create(&callid, CT_OWN_CALL); } } else { /* call == NULL, should create call */ - call = call_get_or_create(&callid, m, CT_OWN_CALL); + call = call_get_or_create(&callid, CT_OWN_CALL); } } @@ -783,7 +781,7 @@ static const char *call_offer_answer_ng(bencode_item_t *input, struct callmaster rwlock_unlock_w(&call->master_lock); if (!flags.no_redis_update) { - redis_update_onekey(call,m->conf.redis_write); + redis_update_onekey(call, rtpe_redis_write); } else { ilog(LOG_DEBUG, "Not updating Redis due to present no-redis-update flag"); } @@ -812,7 +810,7 @@ out: return errstr; } -const char *call_offer_ng(bencode_item_t *input, struct callmaster *m, bencode_item_t *output, const char* addr, +const char *call_offer_ng(bencode_item_t *input, bencode_item_t *output, const char* addr, const endpoint_t *sin) { rwlock_lock_r(&rtpe_config.config_lock); @@ -834,14 +832,14 @@ const char *call_offer_ng(bencode_item_t *input, struct callmaster *m, bencode_i } rwlock_unlock_r(&rtpe_config.config_lock); - return call_offer_answer_ng(input, m, output, OP_OFFER, addr, sin); + return call_offer_answer_ng(input, output, OP_OFFER, addr, sin); } -const char *call_answer_ng(bencode_item_t *input, struct callmaster *m, bencode_item_t *output) { - return call_offer_answer_ng(input, m, output, OP_ANSWER, NULL, NULL); +const char *call_answer_ng(bencode_item_t *input, bencode_item_t *output) { + return call_offer_answer_ng(input, output, OP_ANSWER, NULL, NULL); } -const char *call_delete_ng(bencode_item_t *input, struct callmaster *m, bencode_item_t *output) { +const char *call_delete_ng(bencode_item_t *input, bencode_item_t *output) { str fromtag, totag, viabranch, callid; bencode_item_t *flags, *it; int fatal = 0, delete_delay; @@ -871,7 +869,7 @@ const char *call_delete_ng(bencode_item_t *input, struct callmaster *m, bencode_ } } - if (call_delete_branch(m, &callid, &viabranch, &fromtag, &totag, output, delete_delay)) { + if (call_delete_branch(&callid, &viabranch, &fromtag, &totag, output, delete_delay)) { if (fatal) return "Call-ID not found or tags didn't match"; bencode_dictionary_add_string(output, "warning", "Call-ID not found or tags didn't match"); @@ -1145,7 +1143,7 @@ stats: ng_stats(bencode_dictionary_add_dictionary(dict, "RTCP"), &totals->totals[1], NULL); } -static void ng_list_calls( struct callmaster *m, bencode_item_t *output, long long int limit) { +static void ng_list_calls(bencode_item_t *output, long long int limit) { GHashTableIter iter; gpointer key, value; @@ -1161,13 +1159,13 @@ static void ng_list_calls( struct callmaster *m, bencode_item_t *output, long lo -const char *call_query_ng(bencode_item_t *input, struct callmaster *m, bencode_item_t *output) { +const char *call_query_ng(bencode_item_t *input, bencode_item_t *output) { str callid, fromtag, totag; struct call *call; if (!bencode_dictionary_get_str(input, "call-id", &callid)) return "No call-id in message"; - call = call_get_opmode(&callid, m, OP_OTHER); + call = call_get_opmode(&callid, OP_OTHER); if (!call) return "Unknown call-id"; bencode_dictionary_get_str(input, "from-tag", &fromtag); @@ -1181,7 +1179,7 @@ const char *call_query_ng(bencode_item_t *input, struct callmaster *m, bencode_i } -const char *call_list_ng(bencode_item_t *input, struct callmaster *m, bencode_item_t *output) { +const char *call_list_ng(bencode_item_t *input, bencode_item_t *output) { bencode_item_t *calls = NULL; long long int limit; @@ -1192,13 +1190,13 @@ const char *call_list_ng(bencode_item_t *input, struct callmaster *m, bencode_it } calls = bencode_dictionary_add_list(output, "calls"); - ng_list_calls(m, calls, limit); + ng_list_calls(calls, limit); return NULL; } -const char *call_start_recording_ng(bencode_item_t *input, struct callmaster *m, bencode_item_t *output) { +const char *call_start_recording_ng(bencode_item_t *input, bencode_item_t *output) { str callid; struct call *call; str metadata; @@ -1206,7 +1204,7 @@ const char *call_start_recording_ng(bencode_item_t *input, struct callmaster *m, if (!bencode_dictionary_get_str(input, "call-id", &callid)) return "No call-id in message"; bencode_dictionary_get_str(input, "metadata", &metadata); - call = call_get_opmode(&callid, m, OP_OTHER); + call = call_get_opmode(&callid, OP_OTHER); if (!call) return "Unknown call-id"; @@ -1218,13 +1216,13 @@ const char *call_start_recording_ng(bencode_item_t *input, struct callmaster *m, return NULL; } -const char *call_stop_recording_ng(bencode_item_t *input, struct callmaster *m, bencode_item_t *output) { +const char *call_stop_recording_ng(bencode_item_t *input, bencode_item_t *output) { str callid; struct call *call; if (!bencode_dictionary_get_str(input, "call-id", &callid)) return "No call-id in message"; - call = call_get_opmode(&callid, m, OP_OTHER); + call = call_get_opmode(&callid, OP_OTHER); if (!call) return "Unknown call-id"; diff --git a/daemon/call_interfaces.h b/daemon/call_interfaces.h index 997329022..1cff0b1ce 100644 --- a/daemon/call_interfaces.h +++ b/daemon/call_interfaces.h @@ -13,7 +13,6 @@ struct call; struct call_stats; -struct callmaster; struct streambuf_stream; struct sockaddr_in6; @@ -67,24 +66,24 @@ extern int trust_address_def; extern int dtls_passive_def; -str *call_request_tcp(char **, struct callmaster *); -str *call_lookup_tcp(char **, struct callmaster *); -void call_delete_tcp(char **, struct callmaster *); -void calls_status_tcp(struct callmaster *, struct streambuf_stream *); +str *call_request_tcp(char **); +str *call_lookup_tcp(char **); +void call_delete_tcp(char **); +void calls_status_tcp(struct streambuf_stream *); -str *call_update_udp(char **, struct callmaster *, const char*, const endpoint_t *); -str *call_lookup_udp(char **, struct callmaster *); -str *call_delete_udp(char **, struct callmaster *); -str *call_query_udp(char **, struct callmaster *); +str *call_update_udp(char **, const char*, const endpoint_t *); +str *call_lookup_udp(char **); +str *call_delete_udp(char **); +str *call_query_udp(char **); -const char *call_offer_ng(bencode_item_t *, struct callmaster *, bencode_item_t *, const char*, +const char *call_offer_ng(bencode_item_t *, bencode_item_t *, const char*, const endpoint_t *); -const char *call_answer_ng(bencode_item_t *, struct callmaster *, bencode_item_t *); -const char *call_delete_ng(bencode_item_t *, struct callmaster *, bencode_item_t *); -const char *call_query_ng(bencode_item_t *, struct callmaster *, bencode_item_t *); -const char *call_list_ng(bencode_item_t *, struct callmaster *, bencode_item_t *); -const char *call_start_recording_ng(bencode_item_t *, struct callmaster *, bencode_item_t *); -const char *call_stop_recording_ng(bencode_item_t *, struct callmaster *, bencode_item_t *); +const char *call_answer_ng(bencode_item_t *, bencode_item_t *); +const char *call_delete_ng(bencode_item_t *, bencode_item_t *); +const char *call_query_ng(bencode_item_t *, bencode_item_t *); +const char *call_list_ng(bencode_item_t *, bencode_item_t *); +const char *call_start_recording_ng(bencode_item_t *, bencode_item_t *); +const char *call_stop_recording_ng(bencode_item_t *, bencode_item_t *); void ng_call_stats(struct call *call, const str *fromtag, const str *totag, bencode_item_t *output, struct call_stats *totals); diff --git a/daemon/cli.c b/daemon/cli.c index b6a82397f..2678add3a 100644 --- a/daemon/cli.c +++ b/daemon/cli.c @@ -28,33 +28,33 @@ #include "rtpengine_config.h" -typedef void (*cli_handler_func)(str *, struct callmaster *, struct streambuf *); +typedef void (*cli_handler_func)(str *, struct streambuf *); typedef struct { const char *cmd; cli_handler_func handler; } cli_handler_t; -static void cli_incoming_list(str *instr, struct callmaster* m, struct streambuf *replybuffer); -static void cli_incoming_set(str *instr, struct callmaster* m, struct streambuf *replybuffer); -static void cli_incoming_terminate(str *instr, struct callmaster* m, struct streambuf *replybuffer); -static void cli_incoming_ksadd(str *instr, struct callmaster* m, struct streambuf *replybuffer); -static void cli_incoming_ksrm(str *instr, struct callmaster* m, struct streambuf *replybuffer); -static void cli_incoming_kslist(str *instr, struct callmaster* m, struct streambuf *replybuffer); - -static void cli_incoming_set_maxopenfiles(str *instr, struct callmaster* m, struct streambuf *replybuffer); -static void cli_incoming_set_maxsessions(str *instr, struct callmaster* m, struct streambuf *replybuffer); -static void cli_incoming_set_timeout(str *instr, struct callmaster* m, struct streambuf *replybuffer); -static void cli_incoming_set_silenttimeout(str *instr, struct callmaster* m, struct streambuf *replybuffer); -static void cli_incoming_set_finaltimeout(str *instr, struct callmaster* m, struct streambuf *replybuffer); -static void cli_incoming_set_loglevel(str *instr, struct callmaster* m, struct streambuf *replybuffer); - -static void cli_incoming_list_numsessions(str *instr, struct callmaster* m, struct streambuf *replybuffer); -static void cli_incoming_list_maxsessions(str *instr, struct callmaster* m, struct streambuf *replybuffer); -static void cli_incoming_list_maxopenfiles(str *instr, struct callmaster* m, struct streambuf *replybuffer); -static void cli_incoming_list_totals(str *instr, struct callmaster* m, struct streambuf *replybuffer); -static void cli_incoming_list_sessions(str *instr, struct callmaster* m, struct streambuf *replybuffer); -static void cli_incoming_list_timeout(str *instr, struct callmaster* m, struct streambuf *replybuffer); -static void cli_incoming_list_loglevel(str *instr, struct callmaster* m, struct streambuf *replybuffer); +static void cli_incoming_list(str *instr, struct streambuf *replybuffer); +static void cli_incoming_set(str *instr, struct streambuf *replybuffer); +static void cli_incoming_terminate(str *instr, struct streambuf *replybuffer); +static void cli_incoming_ksadd(str *instr, struct streambuf *replybuffer); +static void cli_incoming_ksrm(str *instr, struct streambuf *replybuffer); +static void cli_incoming_kslist(str *instr, struct streambuf *replybuffer); + +static void cli_incoming_set_maxopenfiles(str *instr, struct streambuf *replybuffer); +static void cli_incoming_set_maxsessions(str *instr, struct streambuf *replybuffer); +static void cli_incoming_set_timeout(str *instr, struct streambuf *replybuffer); +static void cli_incoming_set_silenttimeout(str *instr, struct streambuf *replybuffer); +static void cli_incoming_set_finaltimeout(str *instr, struct streambuf *replybuffer); +static void cli_incoming_set_loglevel(str *instr, struct streambuf *replybuffer); + +static void cli_incoming_list_numsessions(str *instr, struct streambuf *replybuffer); +static void cli_incoming_list_maxsessions(str *instr, struct streambuf *replybuffer); +static void cli_incoming_list_maxopenfiles(str *instr, struct streambuf *replybuffer); +static void cli_incoming_list_totals(str *instr, struct streambuf *replybuffer); +static void cli_incoming_list_sessions(str *instr, struct streambuf *replybuffer); +static void cli_incoming_list_timeout(str *instr, struct streambuf *replybuffer); +static void cli_incoming_list_loglevel(str *instr, struct streambuf *replybuffer); static const cli_handler_t cli_top_handlers[] = { { "list", cli_incoming_list }, @@ -86,7 +86,7 @@ static const cli_handler_t cli_list_handlers[] = { }; -static void cli_handler_do(const cli_handler_t *handlers, str *instr, struct callmaster *m, +static void cli_handler_do(const cli_handler_t *handlers, str *instr, struct streambuf *replybuffer) { const cli_handler_t *h; @@ -94,14 +94,14 @@ static void cli_handler_do(const cli_handler_t *handlers, str *instr, struct cal for (h = handlers; h->cmd; h++) { if (str_shift_cmp(instr, h->cmd)) continue; - h->handler(instr, m, replybuffer); + h->handler(instr, replybuffer); return; } streambuf_printf(replybuffer, "%s:%s\n", "Unknown or incomplete command:", instr->s); } -static void destroy_own_foreign_calls(struct callmaster *m, unsigned int foreign_call, unsigned int uint_keyspace_db) { +static void destroy_own_foreign_calls(unsigned int foreign_call, unsigned int uint_keyspace_db) { struct call *c = NULL; struct call_monologue *ml = NULL; GQueue call_list = G_QUEUE_INIT; @@ -155,19 +155,19 @@ static void destroy_own_foreign_calls(struct callmaster *m, unsigned int foreign } } -static void destroy_all_foreign_calls(struct callmaster *m) { - destroy_own_foreign_calls(m, CT_FOREIGN_CALL, UNDEFINED); +static void destroy_all_foreign_calls(void) { + destroy_own_foreign_calls(CT_FOREIGN_CALL, UNDEFINED); } -static void destroy_all_own_calls(struct callmaster *m) { - destroy_own_foreign_calls(m, CT_OWN_CALL, UNDEFINED); +static void destroy_all_own_calls(void) { + destroy_own_foreign_calls(CT_OWN_CALL, UNDEFINED); } -static void destroy_keyspace_foreign_calls(struct callmaster *m, unsigned int uint_keyspace_db) { - destroy_own_foreign_calls(m, CT_FOREIGN_CALL, uint_keyspace_db); +static void destroy_keyspace_foreign_calls(unsigned int uint_keyspace_db) { + destroy_own_foreign_calls(CT_FOREIGN_CALL, uint_keyspace_db); } -static void cli_incoming_list_totals(str *instr, struct callmaster* m, struct streambuf *replybuffer) { +static void cli_incoming_list_totals(str *instr, struct streambuf *replybuffer) { struct timeval avg, calls_dur_iv; u_int64_t num_sessions, min_sess_iv, max_sess_iv; struct request_time offer_iv, answer_iv, delete_iv; @@ -254,7 +254,7 @@ static void cli_incoming_list_totals(str *instr, struct callmaster* m, struct st g_list_free(list); } -static void cli_incoming_list_numsessions(str *instr, struct callmaster* m, struct streambuf *replybuffer) { +static void cli_incoming_list_numsessions(str *instr, struct streambuf *replybuffer) { rwlock_lock_r(&rtpe_callhash_lock); streambuf_printf(replybuffer, "Current sessions own: "UINT64F"\n", g_hash_table_size(rtpe_callhash) - atomic64_get(&rtpe_stats.foreign_sessions)); streambuf_printf(replybuffer, "Current sessions foreign: "UINT64F"\n", atomic64_get(&rtpe_stats.foreign_sessions)); @@ -262,14 +262,14 @@ static void cli_incoming_list_numsessions(str *instr, struct callmaster* m, stru rwlock_unlock_r(&rtpe_callhash_lock); } -static void cli_incoming_list_maxsessions(str *instr, struct callmaster* m, struct streambuf *replybuffer) { +static void cli_incoming_list_maxsessions(str *instr, struct streambuf *replybuffer) { /* don't lock anything while reading the value */ streambuf_printf(replybuffer, "Maximum sessions configured on rtpengine: %d\n", rtpe_config.max_sessions); return ; } -static void cli_incoming_list_maxopenfiles(str *instr, struct callmaster* m, struct streambuf *replybuffer) { +static void cli_incoming_list_maxopenfiles(str *instr, struct streambuf *replybuffer) { struct rlimit rlim; pid_t pid = getpid(); @@ -287,7 +287,7 @@ static void cli_incoming_list_maxopenfiles(str *instr, struct callmaster* m, str return ; } -static void cli_incoming_list_timeout(str *instr, struct callmaster* m, struct streambuf *replybuffer) { +static void cli_incoming_list_timeout(str *instr, struct streambuf *replybuffer) { rwlock_lock_r(&rtpe_config.config_lock); /* don't lock anything while reading the value */ @@ -300,7 +300,7 @@ static void cli_incoming_list_timeout(str *instr, struct callmaster* m, struct s return ; } -static void cli_incoming_list_callid(str *instr, struct callmaster* m, struct streambuf *replybuffer) { +static void cli_incoming_list_callid(str *instr, struct streambuf *replybuffer) { struct call* c=0; struct call_monologue *ml; struct call_media *md; @@ -316,7 +316,7 @@ static void cli_incoming_list_callid(str *instr, struct callmaster* m, struct st return; } - c = call_get(instr, m); + c = call_get(instr); if (!c) { streambuf_printf(replybuffer, "\nCall Id not found (%s).\n\n",instr->s); @@ -400,7 +400,7 @@ static void cli_incoming_list_callid(str *instr, struct callmaster* m, struct st obj_put(c); } -static void cli_incoming_list_sessions(str *instr, struct callmaster* m, struct streambuf *replybuffer) { +static void cli_incoming_list_sessions(str *instr, struct streambuf *replybuffer) { GHashTableIter iter; gpointer key, value; str *ptrkey; @@ -466,13 +466,13 @@ static void cli_incoming_list_sessions(str *instr, struct callmaster* m, struct } } else { // list session for callid - cli_incoming_list_callid(instr, m, replybuffer); + cli_incoming_list_callid(instr, replybuffer); } return; } -static void cli_incoming_set_maxopenfiles(str *instr, struct callmaster* m, struct streambuf *replybuffer) { +static void cli_incoming_set_maxopenfiles(str *instr, struct streambuf *replybuffer) { unsigned long open_files_num; pid_t pid; char *endptr; @@ -505,7 +505,7 @@ static void cli_incoming_set_maxopenfiles(str *instr, struct callmaster* m, stru } } -static void cli_incoming_set_maxsessions(str *instr, struct callmaster* m, struct streambuf *replybuffer) { +static void cli_incoming_set_maxsessions(str *instr, struct streambuf *replybuffer) { long maxsessions_num; int disabled = -1; char *endptr; @@ -540,7 +540,7 @@ static void cli_incoming_set_maxsessions(str *instr, struct callmaster* m, struc return; } -static void cli_incoming_set_gentimeout(str *instr, struct callmaster* m, struct streambuf *replybuffer, int *conf_timeout) { +static void cli_incoming_set_gentimeout(str *instr, struct streambuf *replybuffer, int *conf_timeout) { long timeout_num; char *endptr; @@ -565,35 +565,35 @@ static void cli_incoming_set_gentimeout(str *instr, struct callmaster* m, struct } } -static void cli_incoming_set_timeout(str *instr, struct callmaster* m, struct streambuf *replybuffer) { - cli_incoming_set_gentimeout(instr, m, replybuffer, &rtpe_config.timeout); +static void cli_incoming_set_timeout(str *instr, struct streambuf *replybuffer) { + cli_incoming_set_gentimeout(instr, replybuffer, &rtpe_config.timeout); } -static void cli_incoming_set_silenttimeout(str *instr, struct callmaster* m, struct streambuf *replybuffer) { - cli_incoming_set_gentimeout(instr, m, replybuffer, &rtpe_config.silent_timeout); +static void cli_incoming_set_silenttimeout(str *instr, struct streambuf *replybuffer) { + cli_incoming_set_gentimeout(instr, replybuffer, &rtpe_config.silent_timeout); } -static void cli_incoming_set_finaltimeout(str *instr, struct callmaster* m, struct streambuf *replybuffer) { - cli_incoming_set_gentimeout(instr, m, replybuffer, &rtpe_config.final_timeout); +static void cli_incoming_set_finaltimeout(str *instr, struct streambuf *replybuffer) { + cli_incoming_set_gentimeout(instr, replybuffer, &rtpe_config.final_timeout); } -static void cli_incoming_list(str *instr, struct callmaster* m, struct streambuf *replybuffer) { +static void cli_incoming_list(str *instr, struct streambuf *replybuffer) { if (str_shift(instr, 1)) { streambuf_printf(replybuffer, "%s\n", "More parameters required."); return; } - cli_handler_do(cli_list_handlers, instr, m, replybuffer); + cli_handler_do(cli_list_handlers, instr, replybuffer); } -static void cli_incoming_set(str *instr, struct callmaster* m, struct streambuf *replybuffer) { +static void cli_incoming_set(str *instr, struct streambuf *replybuffer) { if (str_shift(instr, 1)) { streambuf_printf(replybuffer, "%s\n", "More parameters required."); return; } - cli_handler_do(cli_set_handlers, instr, m, replybuffer); + cli_handler_do(cli_set_handlers, instr, replybuffer); } -static void cli_incoming_terminate(str *instr, struct callmaster* m, struct streambuf *replybuffer) { +static void cli_incoming_terminate(str *instr, struct streambuf *replybuffer) { struct call* c=0; struct call_monologue *ml; GList *i; @@ -606,10 +606,10 @@ static void cli_incoming_terminate(str *instr, struct callmaster* m, struct stre // --- terminate all calls if (!str_memcmp(instr,"all")) { // destroy own calls - destroy_all_own_calls(m); + destroy_all_own_calls(); // destroy foreign calls - destroy_all_foreign_calls(m); + destroy_all_foreign_calls(); // update cli ilog(LOG_INFO,"All calls terminated by operator."); @@ -620,7 +620,7 @@ static void cli_incoming_terminate(str *instr, struct callmaster* m, struct stre // --- terminate own calls } else if (!str_memcmp(instr,"own")) { // destroy own calls - destroy_all_own_calls(m); + destroy_all_own_calls(); // update cli ilog(LOG_INFO,"All own calls terminated by operator."); @@ -631,7 +631,7 @@ static void cli_incoming_terminate(str *instr, struct callmaster* m, struct stre // --- terminate foreign calls } else if (!str_memcmp(instr,"foreign")) { // destroy foreign calls - destroy_all_foreign_calls(m); + destroy_all_foreign_calls(); // update cli ilog(LOG_INFO,"All foreign calls terminated by operator."); @@ -641,7 +641,7 @@ static void cli_incoming_terminate(str *instr, struct callmaster* m, struct stre } // --- terminate a dedicated call id - c = call_get(instr, m); + c = call_get(instr); if (!c) { streambuf_printf(replybuffer, "\nCall Id not found (%s).\n\n",instr->s); @@ -665,7 +665,7 @@ static void cli_incoming_terminate(str *instr, struct callmaster* m, struct stre obj_put(c); } -static void cli_incoming_ksadd(str *instr, struct callmaster* m, struct streambuf *replybuffer) { +static void cli_incoming_ksadd(str *instr, struct streambuf *replybuffer) { unsigned long uint_keyspace_db; char *endptr; @@ -684,7 +684,7 @@ static void cli_incoming_ksadd(str *instr, struct callmaster* m, struct streambu rwlock_lock_w(&rtpe_config.config_lock); if (!g_queue_find(&rtpe_config.redis_subscribed_keyspaces, GUINT_TO_POINTER(uint_keyspace_db))) { g_queue_push_tail(&rtpe_config.redis_subscribed_keyspaces, GUINT_TO_POINTER(uint_keyspace_db)); - redis_notify_subscribe_action(m, SUBSCRIBE_KEYSPACE, uint_keyspace_db); + redis_notify_subscribe_action(SUBSCRIBE_KEYSPACE, uint_keyspace_db); streambuf_printf(replybuffer, "Success adding keyspace %lu to redis notifications.\n", uint_keyspace_db); } else { streambuf_printf(replybuffer, "Keyspace %lu is already among redis notifications.\n", uint_keyspace_db); @@ -693,7 +693,7 @@ static void cli_incoming_ksadd(str *instr, struct callmaster* m, struct streambu } } -static void cli_incoming_ksrm(str *instr, struct callmaster* m, struct streambuf *replybuffer) { +static void cli_incoming_ksrm(str *instr, struct streambuf *replybuffer) { GList *l; unsigned long uint_keyspace_db; char *endptr; @@ -712,12 +712,12 @@ static void cli_incoming_ksrm(str *instr, struct callmaster* m, struct streambuf streambuf_printf(replybuffer, "Fail removing keyspace %s to redis notifications; no digists found\n", instr->s); } else if ((l = g_queue_find(&rtpe_config.redis_subscribed_keyspaces, GUINT_TO_POINTER(uint_keyspace_db)))) { // remove this keyspace - redis_notify_subscribe_action(m, UNSUBSCRIBE_KEYSPACE, uint_keyspace_db); + redis_notify_subscribe_action(UNSUBSCRIBE_KEYSPACE, uint_keyspace_db); g_queue_remove(&rtpe_config.redis_subscribed_keyspaces, l->data); streambuf_printf(replybuffer, "Successfully unsubscribed from keyspace %lu.\n", uint_keyspace_db); // destroy foreign calls for this keyspace - destroy_keyspace_foreign_calls(m, uint_keyspace_db); + destroy_keyspace_foreign_calls(uint_keyspace_db); // update cli streambuf_printf(replybuffer, "Successfully removed all foreign calls for keyspace %lu.\n", uint_keyspace_db); @@ -728,7 +728,7 @@ static void cli_incoming_ksrm(str *instr, struct callmaster* m, struct streambuf } -static void cli_incoming_kslist(str *instr, struct callmaster* m, struct streambuf *replybuffer) { +static void cli_incoming_kslist(str *instr, struct streambuf *replybuffer) { GList *l; streambuf_printf(replybuffer, "\nSubscribed-on keyspaces:\n"); @@ -747,7 +747,6 @@ static void cli_incoming(struct streambuf_stream *s) { } static void cli_stream_readable(struct streambuf_stream *s) { - struct cli *cli = (void *) s->parent; static const int MAXINPUT = 1024; char *inbuf; str instr; @@ -764,17 +763,17 @@ static void cli_stream_readable(struct streambuf_stream *s) { ilog(LOG_INFO, "Got CLI command:%s",inbuf); str_init(&instr, inbuf); - cli_handler_do(cli_top_handlers, &instr, cli->callmaster, s->outbuf); + cli_handler_do(cli_top_handlers, &instr, s->outbuf); free(inbuf); streambuf_stream_shutdown(s); log_info_clear(); } -struct cli *cli_new(struct poller *p, endpoint_t *ep, struct callmaster *m) { +struct cli *cli_new(struct poller *p, endpoint_t *ep) { struct cli *c; - if (!p || !m) + if (!p) return NULL; c = obj_alloc0("cli", sizeof(*c), NULL); @@ -801,7 +800,6 @@ struct cli *cli_new(struct poller *p, endpoint_t *ep, struct callmaster *m) { } c->poller = p; - c->callmaster = m; obj_put(c); return c; @@ -812,10 +810,10 @@ fail: return NULL; } -static void cli_incoming_list_loglevel(str *instr, struct callmaster* m, struct streambuf *replybuffer) { +static void cli_incoming_list_loglevel(str *instr, struct streambuf *replybuffer) { streambuf_printf(replybuffer, "%i\n", g_atomic_int_get(&log_level)); } -static void cli_incoming_set_loglevel(str *instr, struct callmaster* m, struct streambuf *replybuffer) { +static void cli_incoming_set_loglevel(str *instr, struct streambuf *replybuffer) { int nl; if (str_shift(instr, 1)) { diff --git a/daemon/cli.h b/daemon/cli.h index 5ce263d4b..7f6264d55 100644 --- a/daemon/cli.h +++ b/daemon/cli.h @@ -8,12 +8,11 @@ struct cli { struct obj obj; - struct callmaster *callmaster; struct poller *poller; struct streambuf_listener listeners[2]; }; -struct cli *cli_new(struct poller *p, endpoint_t *, struct callmaster *m); +struct cli *cli_new(struct poller *p, endpoint_t *); #endif /* CLI_UDP_H_ */ diff --git a/daemon/control_ng.c b/daemon/control_ng.c index 49508c473..3babbe7c4 100644 --- a/daemon/control_ng.c +++ b/daemon/control_ng.c @@ -183,7 +183,7 @@ static void control_ng_incoming(struct obj *obj, str *buf, const endpoint_t *sin // start offer timer gettimeofday(&offer_start, NULL); - errstr = call_offer_ng(dict, c->callmaster, resp, addr, sin); + errstr = call_offer_ng(dict, resp, addr, sin); g_atomic_int_inc(&cur->offer); // stop offer timer @@ -197,7 +197,7 @@ static void control_ng_incoming(struct obj *obj, str *buf, const endpoint_t *sin // start answer timer gettimeofday(&answer_start, NULL); - errstr = call_answer_ng(dict, c->callmaster, resp); + errstr = call_answer_ng(dict, resp); g_atomic_int_inc(&cur->answer); // stop answer timer @@ -211,7 +211,7 @@ static void control_ng_incoming(struct obj *obj, str *buf, const endpoint_t *sin // start delete timer gettimeofday(&delete_start, NULL); - errstr = call_delete_ng(dict, c->callmaster, resp); + errstr = call_delete_ng(dict, resp); g_atomic_int_inc(&cur->delete); // stop delete timer @@ -222,19 +222,19 @@ static void control_ng_incoming(struct obj *obj, str *buf, const endpoint_t *sin ilog(LOG_INFO, "delete time = %llu.%06llu sec", (unsigned long long)delete_stop.tv_sec, (unsigned long long)delete_stop.tv_usec); } else if (!str_cmp(&cmd, "query")) { - errstr = call_query_ng(dict, c->callmaster, resp); + errstr = call_query_ng(dict, resp); g_atomic_int_inc(&cur->query); } else if (!str_cmp(&cmd, "list")) { - errstr = call_list_ng(dict, c->callmaster, resp); + errstr = call_list_ng(dict, resp); g_atomic_int_inc(&cur->list); } else if (!str_cmp(&cmd, "start recording")) { - errstr = call_start_recording_ng(dict, c->callmaster, resp); + errstr = call_start_recording_ng(dict, resp); g_atomic_int_inc(&cur->start_recording); } else if (!str_cmp(&cmd, "stop recording")) { - errstr = call_stop_recording_ng(dict, c->callmaster, resp); + errstr = call_stop_recording_ng(dict, resp); g_atomic_int_inc(&cur->stop_recording); } else @@ -309,15 +309,14 @@ out: -struct control_ng *control_ng_new(struct poller *p, endpoint_t *ep, struct callmaster *m, unsigned char tos) { +struct control_ng *control_ng_new(struct poller *p, endpoint_t *ep, unsigned char tos) { struct control_ng *c; - if (!p || !m) + if (!p) return NULL; c = obj_alloc0("control_ng", sizeof(*c), NULL); - c->callmaster = m; cookie_cache_init(&c->cookie_cache); if (udp_listener_init(&c->udp_listeners[0], p, ep, control_ng_incoming, &c->obj)) diff --git a/daemon/control_ng.h b/daemon/control_ng.h index 8f22bb58c..e5f2d0429 100644 --- a/daemon/control_ng.h +++ b/daemon/control_ng.h @@ -8,7 +8,6 @@ struct poller; -struct callmaster; struct control_ng_stats { sockaddr_t proxy; @@ -25,12 +24,11 @@ struct control_ng_stats { struct control_ng { struct obj obj; - struct callmaster *callmaster; struct cookie_cache cookie_cache; socket_t udp_listeners[2]; }; -struct control_ng *control_ng_new(struct poller *, endpoint_t *, struct callmaster *, unsigned char); +struct control_ng *control_ng_new(struct poller *, endpoint_t *, unsigned char); void control_ng_init(void); extern mutex_t rtpe_cngs_lock; diff --git a/daemon/control_tcp.c b/daemon/control_tcp.c index c5a893fdb..35af4ce45 100644 --- a/daemon/control_tcp.c +++ b/daemon/control_tcp.c @@ -32,7 +32,6 @@ struct control_tcp { pcre_extra *parse_ree; struct poller *poller; - struct callmaster *callmaster; }; @@ -91,13 +90,13 @@ static int control_stream_parse(struct streambuf_stream *s, char *line) { if (!strcmp(out[RE_TCP_RL_CMD], "request")) - output = call_request_tcp(out, c->callmaster); + output = call_request_tcp(out); else if (!strcmp(out[RE_TCP_RL_CMD], "lookup")) - output = call_lookup_tcp(out, c->callmaster); + output = call_lookup_tcp(out); else if (!strcmp(out[RE_TCP_D_CMD], "delete")) - call_delete_tcp(out, c->callmaster); + call_delete_tcp(out); else if (!strcmp(out[RE_TCP_DIV_CMD], "status")) - calls_status_tcp(c->callmaster, s); + calls_status_tcp(s); else if (!strcmp(out[RE_TCP_DIV_CMD], "build") || !strcmp(out[RE_TCP_DIV_CMD], "version")) streambuf_printf(s->outbuf, "Version: %s\n", RTPENGINE_VERSION); else if (!strcmp(out[RE_TCP_DIV_CMD], "controls")) @@ -155,15 +154,13 @@ static void control_incoming(struct streambuf_stream *s) { } -struct control_tcp *control_tcp_new(struct poller *p, endpoint_t *ep, struct callmaster *m) { +struct control_tcp *control_tcp_new(struct poller *p, endpoint_t *ep) { struct control_tcp *c; const char *errptr; int erroff; if (!p) return NULL; - if (!m) - return NULL; c = obj_alloc0("control", sizeof(*c), NULL); @@ -195,7 +192,6 @@ struct control_tcp *control_tcp_new(struct poller *p, endpoint_t *ep, struct cal c->parse_ree = pcre_study(c->parse_re, 0, &errptr); c->poller = p; - c->callmaster = m; obj_put(c); return c; diff --git a/daemon/control_tcp.h b/daemon/control_tcp.h index 9ca94c969..0b5c36268 100644 --- a/daemon/control_tcp.h +++ b/daemon/control_tcp.h @@ -30,13 +30,12 @@ #define RE_TCP_DIV_CMD 14 struct poller; -struct callmaster; struct control_tcp; struct streambuf_stream; -struct control_tcp *control_tcp_new(struct poller *, endpoint_t *, struct callmaster *); +struct control_tcp *control_tcp_new(struct poller *, endpoint_t *); diff --git a/daemon/control_udp.c b/daemon/control_udp.c index c64a3e6c4..ee34c69f8 100644 --- a/daemon/control_udp.c +++ b/daemon/control_udp.c @@ -86,13 +86,13 @@ static void control_udp_incoming(struct obj *obj, str *buf, const endpoint_t *si log_info_c_string(out[RE_UDP_DQ_CALLID]); if (chrtoupper(out[RE_UDP_UL_CMD][0]) == 'U') - reply = call_update_udp(out, u->callmaster, addr, sin); + reply = call_update_udp(out, addr, sin); else if (chrtoupper(out[RE_UDP_UL_CMD][0]) == 'L') - reply = call_lookup_udp(out, u->callmaster); + reply = call_lookup_udp(out); else if (chrtoupper(out[RE_UDP_DQ_CMD][0]) == 'D') - reply = call_delete_udp(out, u->callmaster); + reply = call_delete_udp(out); else if (chrtoupper(out[RE_UDP_DQ_CMD][0]) == 'Q') - reply = call_query_udp(out, u->callmaster); + reply = call_query_udp(out); else if (chrtoupper(out[RE_UDP_V_CMD][0]) == 'V') { iovlen = 2; @@ -134,17 +134,16 @@ out: log_info_clear(); } -struct control_udp *control_udp_new(struct poller *p, endpoint_t *ep, struct callmaster *m) { +struct control_udp *control_udp_new(struct poller *p, endpoint_t *ep) { struct control_udp *c; const char *errptr; int erroff; - if (!p || !m) + if (!p) return NULL; c = obj_alloc0("control_udp", sizeof(*c), NULL); - c->callmaster = m; c->parse_re = pcre_compile( /* cookie cmd flags callid viabranch:5 */ "^(\\S+)\\s+(?:([ul])(\\S*)\\s+([^;]+)(?:;(\\S+))?\\s+" \ diff --git a/daemon/control_udp.h b/daemon/control_udp.h index f30a45c14..420b9fb62 100644 --- a/daemon/control_udp.h +++ b/daemon/control_udp.h @@ -39,7 +39,6 @@ #define RE_UDP_V_PARMS 20 struct poller; -struct callmaster; @@ -48,7 +47,6 @@ struct callmaster; struct control_udp { struct obj obj; - struct callmaster *callmaster; struct cookie_cache cookie_cache; socket_t udp_listeners[2]; @@ -61,7 +59,7 @@ struct control_udp { -struct control_udp *control_udp_new(struct poller *, endpoint_t *, struct callmaster *); +struct control_udp *control_udp_new(struct poller *, endpoint_t *); diff --git a/daemon/graphite.c b/daemon/graphite.c index af6141a5a..39e2343d3 100644 --- a/daemon/graphite.c +++ b/daemon/graphite.c @@ -85,16 +85,10 @@ int connect_to_graphite_server(const endpoint_t *graphite_ep) { return 0; } -int send_graphite_data(struct callmaster *cm, struct totalstats *sent_data) { +int send_graphite_data(struct totalstats *sent_data) { int rc=0; - // sanity checks - if (!cm) { - ilog(LOG_ERROR, "NULL callmaster when trying to send data"); - return -1; - } - if (graphite_sock.fd < 0) { ilog(LOG_ERROR,"Graphite socket is not connected."); return -1; @@ -248,17 +242,11 @@ static inline void copy_with_lock(struct totalstats *ts_dst, struct totalstats * mutex_unlock(ts_lock); } -void graphite_loop_run(struct callmaster *cm, endpoint_t *graphite_ep, int seconds) { +void graphite_loop_run(endpoint_t *graphite_ep, int seconds) { int rc=0; struct pollfd wfds[1]; - // sanity checks - if (!cm) { - ilog(LOG_ERROR, "NULL callmaster"); - return ; - } - if (!graphite_ep) { ilog(LOG_ERROR, "NULL graphite_ep"); return ; @@ -311,9 +299,9 @@ void graphite_loop_run(struct callmaster *cm, endpoint_t *graphite_ep, int secon } if (graphite_sock.fd >= 0 && connection_state == STATE_CONNECTED) { - add_total_calls_duration_in_interval(cm, &graphite_interval_tv); + add_total_calls_duration_in_interval(&graphite_interval_tv); - rc = send_graphite_data(cm, &graphite_stats); + rc = send_graphite_data(&graphite_stats); gettimeofday(&rtpe_latest_graphite_interval_start, NULL); if (rc < 0) { ilog(LOG_ERROR,"Sending graphite data failed."); @@ -327,14 +315,6 @@ void graphite_loop_run(struct callmaster *cm, endpoint_t *graphite_ep, int secon } void graphite_loop(void *d) { - struct callmaster *cm = d; - - // sanity checks - if (!cm) { - ilog(LOG_ERROR, "NULL callmaster"); - return ; - } - if (rtpe_config.graphite_interval <= 0) { ilog(LOG_WARNING,"Graphite send interval was not set. Setting it to 1 second."); rtpe_config.graphite_interval=1; @@ -343,5 +323,5 @@ void graphite_loop(void *d) { connect_to_graphite_server(&rtpe_config.graphite_ep); while (!rtpe_shutdown) - graphite_loop_run(cm, &rtpe_config.graphite_ep, rtpe_config.graphite_interval); // time in seconds + graphite_loop_run(&rtpe_config.graphite_ep, rtpe_config.graphite_interval); // time in seconds } diff --git a/daemon/graphite.h b/daemon/graphite.h index d83ccbc2d..84a6647d9 100644 --- a/daemon/graphite.h +++ b/daemon/graphite.h @@ -19,8 +19,8 @@ enum connection_state { extern struct timeval rtpe_latest_graphite_interval_start; int connect_to_graphite_server(const endpoint_t *ep); -int send_graphite_data(struct callmaster *cm, struct totalstats *sent_data); -void graphite_loop_run(struct callmaster *cm, endpoint_t *graphite_ep, int seconds); +int send_graphite_data(struct totalstats *sent_data); +void graphite_loop_run(endpoint_t *graphite_ep, int seconds); void set_prefix(char* prefix); void graphite_loop(void *d); void set_latest_graphite_interval_start(struct timeval *tv); diff --git a/daemon/main.c b/daemon/main.c index 8d4797312..5633402ff 100644 --- a/daemon/main.c +++ b/daemon/main.c @@ -41,11 +41,6 @@ -struct main_context { - struct callmaster *m; -}; - - struct poller *rtpe_poller; @@ -497,10 +492,12 @@ static void init_everything() { if (call_interfaces_init()) abort(); statistics_init(); + if (call_init()) + abort(); } -static void create_everything(struct main_context *ctx) { +static void create_everything(void) { struct control_tcp *ct; struct control_udp *cu; struct control_ng *cn; @@ -524,10 +521,6 @@ no_kernel: if (!rtpe_poller) die("poller creation failed"); - ctx->m = callmaster_new(); - if (!ctx->m) - die("callmaster creation failed"); - dtls_timer(rtpe_poller); rwlock_init(&rtpe_config.config_lock); @@ -546,7 +539,7 @@ no_kernel: ct = NULL; if (tcp_listen_ep.port) { - ct = control_tcp_new(rtpe_poller, &tcp_listen_ep, ctx->m); + ct = control_tcp_new(rtpe_poller, &tcp_listen_ep); if (!ct) die("Failed to open TCP control connection port"); } @@ -554,7 +547,7 @@ no_kernel: cu = NULL; if (udp_listen_ep.port) { interfaces_exclude_port(udp_listen_ep.port); - cu = control_udp_new(rtpe_poller, &udp_listen_ep, ctx->m); + cu = control_udp_new(rtpe_poller, &udp_listen_ep); if (!cu) die("Failed to open UDP control connection port"); } @@ -562,7 +555,7 @@ no_kernel: cn = NULL; if (ng_listen_ep.port) { interfaces_exclude_port(ng_listen_ep.port); - cn = control_ng_new(rtpe_poller, &ng_listen_ep, ctx->m, rtpe_config.control_tos); + cn = control_ng_new(rtpe_poller, &ng_listen_ep, rtpe_config.control_tos); if (!cn) die("Failed to open UDP control connection port"); } @@ -570,27 +563,27 @@ no_kernel: cl = NULL; if (cli_listen_ep.port) { interfaces_exclude_port(cli_listen_ep.port); - cl = cli_new(rtpe_poller, &cli_listen_ep, ctx->m); + cl = cli_new(rtpe_poller, &cli_listen_ep); if (!cl) die("Failed to open UDP CLI connection port"); } if (!is_addr_unspecified(&redis_write_ep.address)) { - ctx->m->conf.redis_write = redis_new(&redis_write_ep, redis_write_db, redis_write_auth, ANY_REDIS_ROLE, no_redis_required); - if (!ctx->m->conf.redis_write) + rtpe_redis_write = redis_new(&redis_write_ep, redis_write_db, redis_write_auth, ANY_REDIS_ROLE, no_redis_required); + if (!rtpe_redis_write) die("Cannot start up without running Redis %s write database! See also NO_REDIS_REQUIRED parameter.", endpoint_print_buf(&redis_write_ep)); } if (!is_addr_unspecified(&redis_ep.address)) { - ctx->m->conf.redis = redis_new(&redis_ep, redis_db, redis_auth, ctx->m->conf.redis_write ? ANY_REDIS_ROLE : MASTER_REDIS_ROLE, no_redis_required); - ctx->m->conf.redis_notify = redis_new(&redis_ep, redis_db, redis_auth, ctx->m->conf.redis_write ? ANY_REDIS_ROLE : MASTER_REDIS_ROLE, no_redis_required); - if (!ctx->m->conf.redis || !ctx->m->conf.redis_notify) + rtpe_redis = redis_new(&redis_ep, redis_db, redis_auth, rtpe_redis_write ? ANY_REDIS_ROLE : MASTER_REDIS_ROLE, no_redis_required); + rtpe_redis_notify = redis_new(&redis_ep, redis_db, redis_auth, rtpe_redis_write ? ANY_REDIS_ROLE : MASTER_REDIS_ROLE, no_redis_required); + if (!rtpe_redis || !rtpe_redis_notify) die("Cannot start up without running Redis %s database! See also NO_REDIS_REQUIRED parameter.", endpoint_print_buf(&redis_ep)); - if (!ctx->m->conf.redis_write) - ctx->m->conf.redis_write = ctx->m->conf.redis; + if (!rtpe_redis_write) + rtpe_redis_write = rtpe_redis; } daemonize(); @@ -600,12 +593,12 @@ no_kernel: rtcp_init(); // must come after Homer init - if (ctx->m->conf.redis) { + if (rtpe_redis) { // start redis restore timer gettimeofday(&redis_start, NULL); // restore - if (redis_restore(ctx->m, ctx->m->conf.redis)) + if (redis_restore(rtpe_redis)) die("Refusing to continue without working Redis database"); // stop redis restore timer @@ -624,13 +617,12 @@ no_kernel: int main(int argc, char **argv) { - struct main_context ctx; int idx=0; early_init(); options(&argc, &argv); init_everything(); - create_everything(&ctx); + create_everything(); ilog(LOG_INFO, "Startup complete, version %s", RTPENGINE_VERSION); @@ -638,10 +630,10 @@ int main(int argc, char **argv) { thread_create_detach(poller_timer_loop, rtpe_poller); if (!is_addr_unspecified(&redis_ep.address)) - thread_create_detach(redis_notify_loop, ctx.m); + thread_create_detach(redis_notify_loop, NULL); if (!is_addr_unspecified(&rtpe_config.graphite_ep.address)) - thread_create_detach(graphite_loop, ctx.m); + thread_create_detach(graphite_loop, NULL); thread_create_detach(ice_thread_run, NULL); @@ -663,7 +655,7 @@ int main(int argc, char **argv) { } if (!is_addr_unspecified(&redis_ep.address)) - redis_notify_event_base_action(ctx.m, EVENT_BASE_LOOPBREAK); + redis_notify_event_base_action(EVENT_BASE_LOOPBREAK); threads_join_all(1); diff --git a/daemon/media_socket.c b/daemon/media_socket.c index a7be8dbaa..60b5042bf 100644 --- a/daemon/media_socket.c +++ b/daemon/media_socket.c @@ -1596,7 +1596,7 @@ out: ca = sfd->call ? : NULL; if (ca && update) { - redis_update_onekey(ca, ca->callmaster->conf.redis_write); + redis_update_onekey(ca, rtpe_redis_write); } done: log_info_clear(); diff --git a/daemon/redis.c b/daemon/redis.c index 5649e099e..5eeecb5e7 100644 --- a/daemon/redis.c +++ b/daemon/redis.c @@ -32,6 +32,14 @@ #include "ssrc.h" #include "main.h" +struct redis *rtpe_redis; +struct redis *rtpe_redis_write; +struct redis *rtpe_redis_notify; + +struct event_base *rtpe_redis_notify_event_base; +struct redisAsyncContext *rtpe_redis_notify_async_context; + + INLINE redisReply *redis_expect(int type, redisReply *r) { if (!r) @@ -71,7 +79,7 @@ static int redisCommandNR(redisContext *r, const char *fmt, ...) #define REDIS_FMT(x) (x)->len, (x)->str static int redis_check_conn(struct redis *r); -static void json_restore_call(struct redis *r, struct callmaster *m, const str *id, enum call_type type); +static void json_restore_call(struct redis *r, const str *id, enum call_type type); static void redis_pipe(struct redis *r, const char *fmt, ...) { va_list ap; @@ -260,25 +268,17 @@ err: void on_redis_notification(redisAsyncContext *actx, void *reply, void *privdata) { - - struct callmaster *cm = privdata; struct redis *r = 0; struct call *c = NULL; str callid; str keyspace_id; - // sanity checks - if (!cm) { - rlog(LOG_ERROR, "Struct callmaster is NULL on on_redis_notification"); - return; - } - - if (!cm->conf.redis_notify) { + if (!rtpe_redis_notify) { rlog(LOG_ERROR, "A redis notification has been received but no redis_notify database found"); return; } - r = cm->conf.redis_notify; + r = rtpe_redis_notify; mutex_lock(&r->lock); @@ -323,7 +323,7 @@ void on_redis_notification(redisAsyncContext *actx, void *reply, void *privdata) } if (strncmp(rr->element[3]->str,"set",3)==0) { - c = call_get(&callid, cm); + c = call_get(&callid); if (c) { rwlock_unlock_w(&c->master_lock); if (IS_FOREIGN_CALL(c)) @@ -333,11 +333,11 @@ void on_redis_notification(redisAsyncContext *actx, void *reply, void *privdata) goto err; } } - json_restore_call(r, cm, &callid, CT_FOREIGN_CALL); + json_restore_call(r, &callid, CT_FOREIGN_CALL); } if (strncmp(rr->element[3]->str,"del",3)==0) { - c = call_get(&callid, cm); + c = call_get(&callid); if (!c) { rlog(LOG_NOTICE, "Redis-Notifier: DEL did not find call with callid: %s\n", rr->element[2]->str); goto err; @@ -376,36 +376,30 @@ void redis_async_context_disconnect(const redisAsyncContext *redis_notify_async_ } } -int redis_async_context_alloc(struct callmaster *cm) { +int redis_async_context_alloc() { struct redis *r = 0; - // sanity checks - if (!cm) { - rlog(LOG_ERROR, "Struct callmaster is NULL on context free"); - return -1; - } - - if (!cm->conf.redis_notify) { + if (!rtpe_redis_notify) { rlog(LOG_INFO, "redis_notify database is NULL."); return -1; } // get redis_notify database - r = cm->conf.redis_notify; + r = rtpe_redis_notify; rlog(LOG_INFO, "Use Redis %s for notifications", endpoint_print_buf(&r->endpoint)); // alloc async context - cm->conf.redis_notify_async_context = redisAsyncConnect(r->host, r->endpoint.port); - if (!cm->conf.redis_notify_async_context) { + rtpe_redis_notify_async_context = redisAsyncConnect(r->host, r->endpoint.port); + if (!rtpe_redis_notify_async_context) { rlog(LOG_ERROR, "redis_notify_async_context can't create new"); return -1; } - if (cm->conf.redis_notify_async_context->err) { - rlog(LOG_ERROR, "redis_notify_async_context can't create new error: %s", cm->conf.redis_notify_async_context->errstr); + if (rtpe_redis_notify_async_context->err) { + rlog(LOG_ERROR, "redis_notify_async_context can't create new error: %s", rtpe_redis_notify_async_context->errstr); return -1; } - if (redisAsyncSetDisconnectCallback(cm->conf.redis_notify_async_context, redis_async_context_disconnect) != REDIS_OK) { + if (redisAsyncSetDisconnectCallback(rtpe_redis_notify_async_context, redis_async_context_disconnect) != REDIS_OK) { rlog(LOG_ERROR, "redis_notify_async_context can't set disconnect callback"); return -1; } @@ -413,14 +407,8 @@ int redis_async_context_alloc(struct callmaster *cm) { return 0; } -int redis_notify_event_base_action(struct callmaster *cm, enum event_base_action action) { - // sanity checks - if (!cm) { - rlog(LOG_ERROR, "Struct callmaster is NULL on event base action %d", action); - return -1; - } - - if (!cm->conf.redis_notify_event_base && action!=EVENT_BASE_ALLOC) { +int redis_notify_event_base_action(enum event_base_action action) { + if (!rtpe_redis_notify_event_base && action!=EVENT_BASE_ALLOC) { rlog(LOG_ERROR, "redis_notify_event_base is NULL on event base action %d", action); return -1; } @@ -428,8 +416,8 @@ int redis_notify_event_base_action(struct callmaster *cm, enum event_base_action // exec event base action switch (action) { case EVENT_BASE_ALLOC: - cm->conf.redis_notify_event_base = event_base_new(); - if (!cm->conf.redis_notify_event_base) { + rtpe_redis_notify_event_base = event_base_new(); + if (!rtpe_redis_notify_event_base) { rlog(LOG_ERROR, "Fail alloc redis_notify_event_base"); return -1; } else { @@ -438,12 +426,12 @@ int redis_notify_event_base_action(struct callmaster *cm, enum event_base_action break; case EVENT_BASE_FREE: - event_base_free(cm->conf.redis_notify_event_base); + event_base_free(rtpe_redis_notify_event_base); rlog(LOG_DEBUG, "Success free redis_notify_event_base"); break; case EVENT_BASE_LOOPBREAK: - if (event_base_loopbreak(cm->conf.redis_notify_event_base)) { + if (event_base_loopbreak(rtpe_redis_notify_event_base)) { rlog(LOG_ERROR, "Fail loopbreak redis_notify_event_base"); return -1; } else { @@ -459,38 +447,32 @@ int redis_notify_event_base_action(struct callmaster *cm, enum event_base_action return 0; } -int redis_notify_subscribe_action(struct callmaster *cm, enum subscribe_action action, int keyspace) { - // sanity checks - if (!cm) { - rlog(LOG_ERROR, "Struct callmaster is NULL on subscribe action"); - return -1; - } - - if (!cm->conf.redis_notify_async_context) { +int redis_notify_subscribe_action(enum subscribe_action action, int keyspace) { + if (!rtpe_redis_notify_async_context) { rlog(LOG_ERROR, "redis_notify_async_context is NULL on subscribe action"); return -1; } - if (cm->conf.redis_notify_async_context->err) { - rlog(LOG_ERROR, "redis_notify_async_context error on subscribe action: %s", cm->conf.redis_notify_async_context->errstr); + if (rtpe_redis_notify_async_context->err) { + rlog(LOG_ERROR, "redis_notify_async_context error on subscribe action: %s", rtpe_redis_notify_async_context->errstr); return -1; } switch (action) { case SUBSCRIBE_KEYSPACE: - if (redisAsyncCommand(cm->conf.redis_notify_async_context, on_redis_notification, (void*)cm, "psubscribe __keyspace@%i__:*", keyspace) != REDIS_OK) { + if (redisAsyncCommand(rtpe_redis_notify_async_context, on_redis_notification, NULL, "psubscribe __keyspace@%i__:*", keyspace) != REDIS_OK) { rlog(LOG_ERROR, "Fail redisAsyncCommand on JSON SUBSCRIBE_KEYSPACE"); return -1; } break; case UNSUBSCRIBE_KEYSPACE: - if (redisAsyncCommand(cm->conf.redis_notify_async_context, on_redis_notification, (void*)cm, "punsubscribe __keyspace@%i__:*", keyspace) != REDIS_OK) { + if (redisAsyncCommand(rtpe_redis_notify_async_context, on_redis_notification, NULL, "punsubscribe __keyspace@%i__:*", keyspace) != REDIS_OK) { rlog(LOG_ERROR, "Fail redisAsyncCommand on JSON UNSUBSCRIBE_KEYSPACE"); return -1; } break; case UNSUBSCRIBE_ALL: - if (redisAsyncCommand(cm->conf.redis_notify_async_context, on_redis_notification, (void *) cm, "punsubscribe") != REDIS_OK) { + if (redisAsyncCommand(rtpe_redis_notify_async_context, on_redis_notification, NULL, "punsubscribe") != REDIS_OK) { rlog(LOG_ERROR, "Fail redisAsyncCommand on JSON UNSUBSCRIBE_ALL"); return -1; } @@ -503,39 +485,33 @@ int redis_notify_subscribe_action(struct callmaster *cm, enum subscribe_action a return 0; } -static int redis_notify(struct callmaster *cm) { +static int redis_notify() { struct redis *r = 0; GList *l; - // sanity checks - if (!cm) { - rlog(LOG_ERROR, "Struct callmaster is NULL on redis_notify()"); - return -1; - } - - if (!cm->conf.redis_notify) { + if (!rtpe_redis_notify) { rlog(LOG_ERROR, "redis_notify database is NULL on redis_notify()"); return -1; } - if (!cm->conf.redis_notify_async_context) { + if (!rtpe_redis_notify_async_context) { rlog(LOG_ERROR, "redis_notify_async_context is NULL on redis_notify()"); return -1; } - if (!cm->conf.redis_notify_event_base) { + if (!rtpe_redis_notify_event_base) { rlog(LOG_ERROR, "redis_notify_event_base is NULL on redis_notify()"); return -1; } // get redis_notify database - r = cm->conf.redis_notify; + r = rtpe_redis_notify; rlog(LOG_INFO, "Use Redis %s to subscribe to notifications", endpoint_print_buf(&r->endpoint)); // attach event base - if (redisLibeventAttach(cm->conf.redis_notify_async_context, cm->conf.redis_notify_event_base) == REDIS_ERR) { - if (cm->conf.redis_notify_async_context->err) { - rlog(LOG_ERROR, "redis_notify_async_context can't attach event base error: %s", cm->conf.redis_notify_async_context->errstr); + if (redisLibeventAttach(rtpe_redis_notify_async_context, rtpe_redis_notify_event_base) == REDIS_ERR) { + if (rtpe_redis_notify_async_context->err) { + rlog(LOG_ERROR, "redis_notify_async_context can't attach event base error: %s", rtpe_redis_notify_async_context->errstr); } else { rlog(LOG_ERROR, "redis_notify_async_context can't attach event base"); @@ -546,12 +522,12 @@ static int redis_notify(struct callmaster *cm) { // subscribe to the values in the configured keyspaces rwlock_lock_r(&rtpe_config.config_lock); for (l = rtpe_config.redis_subscribed_keyspaces.head; l; l = l->next) { - redis_notify_subscribe_action(cm, SUBSCRIBE_KEYSPACE, GPOINTER_TO_UINT(l->data)); + redis_notify_subscribe_action(SUBSCRIBE_KEYSPACE, GPOINTER_TO_UINT(l->data)); } rwlock_unlock_r(&rtpe_config.config_lock); // dispatch event base => thread blocks here - if (event_base_dispatch(cm->conf.redis_notify_event_base) < 0) { + if (event_base_dispatch(rtpe_redis_notify_event_base) < 0) { rlog(LOG_ERROR, "Fail event_base_dispatch()"); return -1; } @@ -562,16 +538,9 @@ static int redis_notify(struct callmaster *cm) { void redis_notify_loop(void *d) { int seconds = 1, redis_notify_return = 0; time_t next_run = rtpe_now.tv_sec; - struct callmaster *cm = (struct callmaster *)d; struct redis *r; - // sanity checks - if (!cm) { - ilog(LOG_ERROR, "NULL callmaster"); - return ; - } - - r = cm->conf.redis_notify; + r = rtpe_redis_notify; if (!r) { rlog(LOG_ERROR, "Don't use Redis notifications. See --redis-notifications parameter."); return ; @@ -584,18 +553,18 @@ void redis_notify_loop(void *d) { } // alloc redis async context - if (redis_async_context_alloc(cm) < 0) { + if (redis_async_context_alloc() < 0) { return ; } // alloc event base - if (redis_notify_event_base_action(cm, EVENT_BASE_ALLOC) < 0) { + if (redis_notify_event_base_action(EVENT_BASE_ALLOC) < 0) { return ; } // initial redis_notify if (redis_check_conn(r) == REDIS_STATE_CONNECTED) { - redis_notify_return = redis_notify(cm); + redis_notify_return = redis_notify(); } // loop redis_notify => in case of lost connection @@ -610,23 +579,23 @@ void redis_notify_loop(void *d) { if (redis_check_conn(r) == REDIS_STATE_RECONNECTED || redis_notify_return < 0) { // alloc new redis async context upon redis breakdown - if (redis_async_context_alloc(cm) < 0) { + if (redis_async_context_alloc() < 0) { continue; } // prepare notifications - redis_notify_return = redis_notify(cm); + redis_notify_return = redis_notify(); } } // unsubscribe notifications - redis_notify_subscribe_action(cm, UNSUBSCRIBE_ALL, 0); + redis_notify_subscribe_action(UNSUBSCRIBE_ALL, 0); // free async context - redisAsyncDisconnect(cm->conf.redis_notify_async_context); + redisAsyncDisconnect(rtpe_redis_notify_async_context); // free event base - redis_notify_event_base_action(cm, EVENT_BASE_FREE); + redis_notify_event_base_action(EVENT_BASE_FREE); } struct redis *redis_new(const endpoint_t *ep, int db, const char *auth, enum redis_role role, int no_redis_required) { @@ -1436,7 +1405,7 @@ static int json_build_ssrc(struct call *c, JsonReader *root_reader) { return 0; } -static void json_restore_call(struct redis *r, struct callmaster *m, const str *callid, enum call_type type) { +static void json_restore_call(struct redis *r, const str *callid, enum call_type type) { redisReply* rr_jsonStr; struct redis_hash call; struct redis_list tags, sfds, streams, medias, maps; @@ -1462,7 +1431,7 @@ static void json_restore_call(struct redis *r, struct callmaster *m, const str * if (!root_reader) goto err1; - c = call_get_or_create(callid, m, type); + c = call_get_or_create(callid, type); err = "failed to create call struct"; if (!c) goto err1; @@ -1582,9 +1551,9 @@ err1: if (c) call_destroy(c); else { - mutex_lock(&m->conf.redis_write->lock); - redisCommandNR(m->conf.redis_write->ctx, "DEL " PB, STR(callid)); - mutex_unlock(&m->conf.redis_write->lock); + mutex_lock(&rtpe_redis_write->lock); + redisCommandNR(rtpe_redis_write->ctx, "DEL " PB, STR(callid)); + mutex_unlock(&rtpe_redis_write->lock); } } if (c) @@ -1592,7 +1561,6 @@ err1: } struct thread_ctx { - struct callmaster *m; GQueue r_q; mutex_t r_m; }; @@ -1610,14 +1578,14 @@ static void restore_thread(void *call_p, void *ctx_p) { r = g_queue_pop_head(&ctx->r_q); mutex_unlock(&ctx->r_m); - json_restore_call(r, ctx->m, &callid, CT_OWN_CALL); + json_restore_call(r, &callid, CT_OWN_CALL); mutex_lock(&ctx->r_m); g_queue_push_tail(&ctx->r_q, r); mutex_unlock(&ctx->r_m); } -int redis_restore(struct callmaster *m, struct redis *r) { +int redis_restore(struct redis *r) { redisReply *calls = NULL, *call; int i, ret = -1; GThreadPool *gtp; @@ -1647,7 +1615,6 @@ int redis_restore(struct callmaster *m, struct redis *r) { goto err; } - ctx.m = m; mutex_init(&ctx.r_m); g_queue_init(&ctx.r_q); for (i = 0; i < rtpe_config.redis_num_threads; i++) diff --git a/daemon/redis.h b/daemon/redis.h index 1932ea8d3..1b9f8fccd 100644 --- a/daemon/redis.h +++ b/daemon/redis.h @@ -43,7 +43,6 @@ enum subscribe_action { UNSUBSCRIBE_ALL, }; -struct callmaster; struct call; @@ -74,6 +73,15 @@ struct redis_list { }; +extern struct redis *rtpe_redis; +extern struct redis *rtpe_redis_write; +extern struct redis *rtpe_redis_notify; + +extern struct event_base *rtpe_redis_notify_event_base; +extern struct redisAsyncContext *rtpe_redis_notify_async_context; + + + #if !GLIB_CHECK_VERSION(2,40,0) INLINE gboolean g_hash_table_insert_check(GHashTable *h, gpointer k, gpointer v) { gboolean ret = TRUE; @@ -93,13 +101,13 @@ void redis_notify_loop(void *d); struct redis *redis_new(const endpoint_t *, int, const char *, enum redis_role, int no_redis_required); -int redis_restore(struct callmaster *, struct redis *); +int redis_restore(struct redis *); void redis_update(struct call *, struct redis *); void redis_update_onekey(struct call *c, struct redis *r); void redis_delete(struct call *, struct redis *); void redis_wipe(struct redis *); -int redis_notify_event_base_action(struct callmaster *cm, enum event_base_action); -int redis_notify_subscribe_action(struct callmaster *cm, enum subscribe_action action, int keyspace); +int redis_notify_event_base_action(enum event_base_action); +int redis_notify_subscribe_action(enum subscribe_action action, int keyspace); From 0e3f5eb3c2d75f1fc3df74f82376cb56b1266216 Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Wed, 3 Jan 2018 14:24:31 -0500 Subject: [PATCH 57/65] move all remaining config options into global config struct Change-Id: Ib0d7cd3f98929b22ef3726b8712f34706a530456 --- daemon/iptables.c | 20 +++---- daemon/iptables.h | 2 - daemon/main.c | 133 +++++++++++++++++++++------------------------- daemon/main.h | 23 ++++++++ 4 files changed, 93 insertions(+), 85 deletions(-) diff --git a/daemon/iptables.c b/daemon/iptables.c index 7a81e5476..b12efc1ec 100644 --- a/daemon/iptables.c +++ b/daemon/iptables.c @@ -1,6 +1,5 @@ #include "iptables.h" -char *rtpe_iptables_chain; int (*iptables_add_rule)(const socket_t *local_sock, const str *comment); int (*iptables_del_rule)(const socket_t *local_sock); @@ -23,6 +22,7 @@ int (*iptables_del_rule)(const socket_t *local_sock); #include "log.h" #include "socket.h" #include "str.h" +#include "main.h" #undef __ALIGN_KERNEL #define __ALIGN_KERNEL(x, a) __ALIGN_KERNEL_MASK(x, (__typeof(x))(a) - 1) @@ -139,7 +139,7 @@ static const char *ip4tables_add_rule(const socket_t *local_sock, const str *com ip4_fill_entry(&entry, local_sock, comment); err = "failed to append iptables entry"; - if (!iptc_append_entry(rtpe_iptables_chain, &entry.entry, h)) + if (!iptc_append_entry(rtpe_config.iptables_chain, &entry.entry, h)) goto err; err = "failed to commit iptables changes"; if (!iptc_commit(h)) @@ -169,7 +169,7 @@ static const char *ip6tables_add_rule(const socket_t *local_sock, const str *com ip6_fill_entry(&entry, local_sock, comment); err = "failed to append ip6tables entry"; - if (!ip6tc_append_entry(rtpe_iptables_chain, &entry.entry, h)) + if (!ip6tc_append_entry(rtpe_config.iptables_chain, &entry.entry, h)) goto err; err = "failed to commit ip6tables changes"; if (!ip6tc_commit(h)) @@ -207,7 +207,7 @@ static const char *ip4tables_del_rule(const socket_t *local_sock) { memset(&mask.matches.target, 0xff, sizeof(mask.matches.target)); err = "failed to delete iptables entry"; - if (!iptc_delete_entry(rtpe_iptables_chain, &entry.entry, (unsigned char *) &mask, h)) + if (!iptc_delete_entry(rtpe_config.iptables_chain, &entry.entry, (unsigned char *) &mask, h)) goto err; err = "failed to commit iptables changes"; if (!iptc_commit(h)) @@ -245,7 +245,7 @@ static const char *ip6tables_del_rule(const socket_t *local_sock) { memset(&mask.matches.target, 0xff, sizeof(mask.matches.target)); err = "failed to delete ip6tables entry"; - if (!ip6tc_delete_entry(rtpe_iptables_chain, &entry.entry, (unsigned char *) &mask, h)) + if (!ip6tc_delete_entry(rtpe_config.iptables_chain, &entry.entry, (unsigned char *) &mask, h)) goto err; err = "failed to commit ip6tables changes"; if (!ip6tc_commit(h)) @@ -313,10 +313,10 @@ static int __iptables_stub(void) { void iptables_init(void) { - if (rtpe_iptables_chain && !rtpe_iptables_chain[0]) - rtpe_iptables_chain = NULL; + if (rtpe_config.iptables_chain && !rtpe_config.iptables_chain[0]) + rtpe_config.iptables_chain = NULL; - if (!rtpe_iptables_chain) { + if (!rtpe_config.iptables_chain) { iptables_add_rule = (void *) __iptables_stub; iptables_del_rule = (void *) __iptables_stub; return; @@ -340,7 +340,7 @@ void iptables_init(void) { if (!h) goto out; err = "could not flush iptables chain"; - if (!iptc_flush_entries(rtpe_iptables_chain, h)) + if (!iptc_flush_entries(rtpe_config.iptables_chain, h)) goto err2; err = "could not commit iptables changes"; if (!iptc_commit(h)) @@ -352,7 +352,7 @@ void iptables_init(void) { if (!h) goto out; err = "could not flush ip6tables chain"; - if (!ip6tc_flush_entries(rtpe_iptables_chain, h)) + if (!ip6tc_flush_entries(rtpe_config.iptables_chain, h)) goto err1; err = "could not commit iptables changes"; if (!ip6tc_commit(h)) diff --git a/daemon/iptables.h b/daemon/iptables.h index 96cd24e26..e92e178e5 100644 --- a/daemon/iptables.h +++ b/daemon/iptables.h @@ -6,8 +6,6 @@ #include "str.h" -extern char *rtpe_iptables_chain; - void iptables_init(void); extern int (*iptables_add_rule)(const socket_t *local_sock, const str *comment); extern int (*iptables_del_rule)(const socket_t *local_sock); diff --git a/daemon/main.c b/daemon/main.c index 5633402ff..b45404f4b 100644 --- a/daemon/main.c +++ b/daemon/main.c @@ -52,32 +52,19 @@ struct rtpengine_config rtpe_config = { .delete_delay = 30, .redis_subscribed_keyspaces = G_QUEUE_INIT, .redis_expires_secs = 86400, + .interfaces = G_QUEUE_INIT, + .homer_protocol = SOCK_DGRAM, + .homer_id = 2001, + .port_min = 30000, + .port_max = 40000, + .redis_db = -1, + .redis_write_db = -1, + .rec_method = "pcap", + .rec_format = "raw", }; -static GQueue interfaces = G_QUEUE_INIT; -static endpoint_t tcp_listen_ep; -static endpoint_t udp_listen_ep; -static endpoint_t ng_listen_ep; -static endpoint_t cli_listen_ep; -static endpoint_t redis_ep; -static endpoint_t redis_write_ep; -static endpoint_t homer_ep; -static int homer_protocol = SOCK_DGRAM; -static int homer_id = 2001; -static int no_fallback; -static int port_min = 30000; -static int port_max = 40000; -static int redis_db = -1; -static int redis_write_db = -1; -static int no_redis_required; -static char *redis_auth; -static char *redis_write_auth; -static int num_threads; -static char *spooldir; -static char *rec_method = "pcap"; -static char *rec_format = "raw"; static void sighandler(gpointer x) { sigset_t ss; @@ -189,8 +176,8 @@ static struct intf_config *if_addr_parse(char *s) { ifa->local_address.type = socktype_udp; ifa->advertised_address.addr = adv; ifa->advertised_address.type = ifa->local_address.type; - ifa->port_min = port_min; - ifa->port_max = port_max; + ifa->port_min = rtpe_config.port_min; + ifa->port_max = rtpe_config.port_max; // handle "base:suffix" separation for round-robin selection ifa->name_rr_spec = ifa->name; @@ -258,7 +245,7 @@ static void options(int *argc, char ***argv) { GOptionEntry e[] = { { "table", 't', 0, G_OPTION_ARG_INT, &rtpe_config.kernel_table, "Kernel table to use", "INT" }, - { "no-fallback",'F', 0, G_OPTION_ARG_NONE, &no_fallback, "Only start when kernel module is available", NULL }, + { "no-fallback",'F', 0, G_OPTION_ARG_NONE, &rtpe_config.no_fallback, "Only start when kernel module is available", NULL }, { "interface", 'i', 0, G_OPTION_ARG_STRING_ARRAY,&if_a, "Local interface for RTP", "[NAME/]IP[!IP]"}, { "subscribe-keyspace", 'k', 0, G_OPTION_ARG_STRING_ARRAY,&ks_a, "Subscription keyspace list", "INT INT ..."}, { "listen-tcp", 'l', 0, G_OPTION_ARG_STRING, &listenps, "TCP port to listen on", "[IP:]PORT" }, @@ -273,30 +260,30 @@ static void options(int *argc, char ***argv) { { "timeout", 'o', 0, G_OPTION_ARG_INT, &rtpe_config.timeout, "RTP timeout", "SECS" }, { "silent-timeout",'s',0,G_OPTION_ARG_INT, &rtpe_config.silent_timeout,"RTP timeout for muted", "SECS" }, { "final-timeout",'a',0,G_OPTION_ARG_INT, &rtpe_config.final_timeout, "Call timeout", "SECS" }, - { "port-min", 'm', 0, G_OPTION_ARG_INT, &port_min, "Lowest port to use for RTP", "INT" }, - { "port-max", 'M', 0, G_OPTION_ARG_INT, &port_max, "Highest port to use for RTP", "INT" }, + { "port-min", 'm', 0, G_OPTION_ARG_INT, &rtpe_config.port_min, "Lowest port to use for RTP", "INT" }, + { "port-max", 'M', 0, G_OPTION_ARG_INT, &rtpe_config.port_max, "Highest port to use for RTP", "INT" }, { "redis", 'r', 0, G_OPTION_ARG_STRING, &redisps, "Connect to Redis database", "[PW@]IP:PORT/INT" }, { "redis-write",'w', 0, G_OPTION_ARG_STRING, &redisps_write, "Connect to Redis write database", "[PW@]IP:PORT/INT" }, { "redis-num-threads", 0, 0, G_OPTION_ARG_INT, &rtpe_config.redis_num_threads, "Number of Redis restore threads", "INT" }, { "redis-expires", 0, 0, G_OPTION_ARG_INT, &rtpe_config.redis_expires_secs, "Expire time in seconds for redis keys", "INT" }, - { "no-redis-required", 'q', 0, G_OPTION_ARG_NONE, &no_redis_required, "Start no matter of redis connection state", NULL }, + { "no-redis-required", 'q', 0, G_OPTION_ARG_NONE, &rtpe_config.no_redis_required, "Start no matter of redis connection state", NULL }, { "b2b-url", 'b', 0, G_OPTION_ARG_STRING, &rtpe_config.b2b_url, "XMLRPC URL of B2B UA" , "STRING" }, { "log-facility-cdr",0, 0, G_OPTION_ARG_STRING, &log_facility_cdr_s, "Syslog facility to use for logging CDRs", "daemon|local0|...|local7"}, { "log-facility-rtcp",0, 0, G_OPTION_ARG_STRING, &log_facility_rtcp_s, "Syslog facility to use for logging RTCP", "daemon|local0|...|local7"}, { "xmlrpc-format",'x', 0, G_OPTION_ARG_INT, &rtpe_config.fmt, "XMLRPC timeout request format to use. 0: SEMS DI, 1: call-id only", "INT" }, - { "num-threads", 0, 0, G_OPTION_ARG_INT, &num_threads, "Number of worker threads to create", "INT" }, + { "num-threads", 0, 0, G_OPTION_ARG_INT, &rtpe_config.num_threads, "Number of worker threads to create", "INT" }, { "delete-delay", 'd', 0, G_OPTION_ARG_INT, &rtpe_config.delete_delay, "Delay for deleting a session from memory.", "INT" }, { "sip-source", 0, 0, G_OPTION_ARG_NONE, &sip_source, "Use SIP source address by default", NULL }, { "dtls-passive", 0, 0, G_OPTION_ARG_NONE, &dtls_passive_def,"Always prefer DTLS passive role", NULL }, { "max-sessions", 0, 0, G_OPTION_ARG_INT, &rtpe_config.max_sessions, "Limit of maximum number of sessions", "INT" }, { "homer", 0, 0, G_OPTION_ARG_STRING, &homerp, "Address of Homer server for RTCP stats","IP46|HOSTNAME:PORT"}, { "homer-protocol",0,0,G_OPTION_ARG_STRING, &homerproto, "Transport protocol for Homer (default udp)", "udp|tcp" }, - { "homer-id", 0, 0, G_OPTION_ARG_STRING, &homer_id, "'Capture ID' to use within the HEP protocol", "INT" }, - { "recording-dir", 0, 0, G_OPTION_ARG_STRING, &spooldir, "Directory for storing pcap and metadata files", "FILE" }, - { "recording-method",0, 0, G_OPTION_ARG_STRING, &rec_method, "Strategy for call recording", "pcap|proc" }, - { "recording-format",0, 0, G_OPTION_ARG_STRING, &rec_format, "File format for stored pcap files", "raw|eth" }, + { "homer-id", 0, 0, G_OPTION_ARG_STRING, &rtpe_config.homer_id, "'Capture ID' to use within the HEP protocol", "INT" }, + { "recording-dir", 0, 0, G_OPTION_ARG_STRING, &rtpe_config.spooldir, "Directory for storing pcap and metadata files", "FILE" }, + { "recording-method",0, 0, G_OPTION_ARG_STRING, &rtpe_config.rec_method, "Strategy for call recording", "pcap|proc" }, + { "recording-format",0, 0, G_OPTION_ARG_STRING, &rtpe_config.rec_format, "File format for stored pcap files", "raw|eth" }, #ifdef WITH_IPTABLES_OPTION - { "iptables-chain",0,0, G_OPTION_ARG_STRING, &rtpe_iptables_chain,"Add explicit firewall rules to this iptables chain","STRING" }, + { "iptables-chain",0,0, G_OPTION_ARG_STRING, &rtpe_config.iptables_chain,"Add explicit firewall rules to this iptables chain","STRING" }, #endif { NULL, } }; @@ -313,7 +300,7 @@ static void options(int *argc, char ***argv) { ifa = if_addr_parse(*iter); if (!ifa) die("Invalid interface specification: %s", *iter); - g_queue_push_tail(&interfaces, ifa); + g_queue_push_tail(&rtpe_config.interfaces, ifa); } if (ks_a) { @@ -334,19 +321,19 @@ static void options(int *argc, char ***argv) { } if (listenps) { - if (endpoint_parse_any_getaddrinfo(&tcp_listen_ep, listenps)) + if (endpoint_parse_any_getaddrinfo(&rtpe_config.tcp_listen_ep, listenps)) die("Invalid IP or port (--listen-tcp)"); } if (listenudps) { - if (endpoint_parse_any_getaddrinfo(&udp_listen_ep, listenudps)) + if (endpoint_parse_any_getaddrinfo(&rtpe_config.udp_listen_ep, listenudps)) die("Invalid IP or port (--listen-udp)"); } if (listenngs) { - if (endpoint_parse_any_getaddrinfo(&ng_listen_ep, listenngs)) + if (endpoint_parse_any_getaddrinfo(&rtpe_config.ng_listen_ep, listenngs)) die("Invalid IP or port (--listen-ng)"); } - if (listencli) {if (endpoint_parse_any_getaddrinfo(&cli_listen_ep, listencli)) + if (listencli) {if (endpoint_parse_any_getaddrinfo(&rtpe_config.cli_listen_ep, listencli)) die("Invalid IP or port (--listen-cli)"); } @@ -358,14 +345,14 @@ static void options(int *argc, char ***argv) { set_prefix(graphite_prefix_s); if (homerp) { - if (endpoint_parse_any_getaddrinfo_full(&homer_ep, homerp)) + if (endpoint_parse_any_getaddrinfo_full(&rtpe_config.homer_ep, homerp)) die("Invalid IP or port (--homer)"); } if (homerproto) { if (!strcmp(homerproto, "tcp")) - homer_protocol = SOCK_STREAM; + rtpe_config.homer_protocol = SOCK_STREAM; else if (!strcmp(homerproto, "udp")) - homer_protocol = SOCK_DGRAM; + rtpe_config.homer_protocol = SOCK_DGRAM; else die("Invalid protocol (--homer-protocol)"); } @@ -386,11 +373,11 @@ static void options(int *argc, char ***argv) { rtpe_config.final_timeout = 0; if (redisps) - if (redis_ep_parse(&redis_ep, &redis_db, &redis_auth, "RTPENGINE_REDIS_AUTH_PW", redisps)) + if (redis_ep_parse(&rtpe_config.redis_ep, &rtpe_config.redis_db, &rtpe_config.redis_auth, "RTPENGINE_REDIS_AUTH_PW", redisps)) die("Invalid Redis endpoint [IP:PORT/INT] (--redis)"); if (redisps_write) - if (redis_ep_parse(&redis_write_ep, &redis_write_db, &redis_write_auth, + if (redis_ep_parse(&rtpe_config.redis_write_ep, &rtpe_config.redis_write_db, &rtpe_config.redis_write_auth, "RTPENGINE_REDIS_WRITE_AUTH_PW", redisps_write)) die("Invalid Redis endpoint [IP:PORT/INT] (--redis-write)"); @@ -465,7 +452,7 @@ static void init_everything() { struct timespec ts; log_init("rtpengine"); - recording_fs_init(spooldir, rec_method, rec_format); + recording_fs_init(rtpe_config.spooldir, rtpe_config.rec_method, rtpe_config.rec_format); clock_gettime(CLOCK_REALTIME, &ts); srandom(ts.tv_sec ^ ts.tv_nsec); SSL_library_init(); @@ -486,7 +473,7 @@ static void init_everything() { dtls_init(); ice_init(); crypto_init_main(); - interfaces_init(&interfaces); + interfaces_init(&rtpe_config.interfaces); iptables_init(); control_ng_init(); if (call_interfaces_init()) @@ -509,7 +496,7 @@ static void create_everything(void) { if (rtpe_config.kernel_table < 0) goto no_kernel; if (kernel_setup_table(rtpe_config.kernel_table)) { - if (no_fallback) { + if (rtpe_config.no_fallback) { ilog(LOG_CRIT, "Userspace fallback disallowed - exiting"); exit(-1); } @@ -538,49 +525,49 @@ no_kernel: } ct = NULL; - if (tcp_listen_ep.port) { - ct = control_tcp_new(rtpe_poller, &tcp_listen_ep); + if (rtpe_config.tcp_listen_ep.port) { + ct = control_tcp_new(rtpe_poller, &rtpe_config.tcp_listen_ep); if (!ct) die("Failed to open TCP control connection port"); } cu = NULL; - if (udp_listen_ep.port) { - interfaces_exclude_port(udp_listen_ep.port); - cu = control_udp_new(rtpe_poller, &udp_listen_ep); + if (rtpe_config.udp_listen_ep.port) { + interfaces_exclude_port(rtpe_config.udp_listen_ep.port); + cu = control_udp_new(rtpe_poller, &rtpe_config.udp_listen_ep); if (!cu) die("Failed to open UDP control connection port"); } cn = NULL; - if (ng_listen_ep.port) { - interfaces_exclude_port(ng_listen_ep.port); - cn = control_ng_new(rtpe_poller, &ng_listen_ep, rtpe_config.control_tos); + if (rtpe_config.ng_listen_ep.port) { + interfaces_exclude_port(rtpe_config.ng_listen_ep.port); + cn = control_ng_new(rtpe_poller, &rtpe_config.ng_listen_ep, rtpe_config.control_tos); if (!cn) die("Failed to open UDP control connection port"); } cl = NULL; - if (cli_listen_ep.port) { - interfaces_exclude_port(cli_listen_ep.port); - cl = cli_new(rtpe_poller, &cli_listen_ep); + if (rtpe_config.cli_listen_ep.port) { + interfaces_exclude_port(rtpe_config.cli_listen_ep.port); + cl = cli_new(rtpe_poller, &rtpe_config.cli_listen_ep); if (!cl) die("Failed to open UDP CLI connection port"); } - if (!is_addr_unspecified(&redis_write_ep.address)) { - rtpe_redis_write = redis_new(&redis_write_ep, redis_write_db, redis_write_auth, ANY_REDIS_ROLE, no_redis_required); + if (!is_addr_unspecified(&rtpe_config.redis_write_ep.address)) { + rtpe_redis_write = redis_new(&rtpe_config.redis_write_ep, rtpe_config.redis_write_db, rtpe_config.redis_write_auth, ANY_REDIS_ROLE, rtpe_config.no_redis_required); if (!rtpe_redis_write) die("Cannot start up without running Redis %s write database! See also NO_REDIS_REQUIRED parameter.", - endpoint_print_buf(&redis_write_ep)); + endpoint_print_buf(&rtpe_config.redis_write_ep)); } - if (!is_addr_unspecified(&redis_ep.address)) { - rtpe_redis = redis_new(&redis_ep, redis_db, redis_auth, rtpe_redis_write ? ANY_REDIS_ROLE : MASTER_REDIS_ROLE, no_redis_required); - rtpe_redis_notify = redis_new(&redis_ep, redis_db, redis_auth, rtpe_redis_write ? ANY_REDIS_ROLE : MASTER_REDIS_ROLE, no_redis_required); + if (!is_addr_unspecified(&rtpe_config.redis_ep.address)) { + rtpe_redis = redis_new(&rtpe_config.redis_ep, rtpe_config.redis_db, rtpe_config.redis_auth, rtpe_redis_write ? ANY_REDIS_ROLE : MASTER_REDIS_ROLE, rtpe_config.no_redis_required); + rtpe_redis_notify = redis_new(&rtpe_config.redis_ep, rtpe_config.redis_db, rtpe_config.redis_auth, rtpe_redis_write ? ANY_REDIS_ROLE : MASTER_REDIS_ROLE, rtpe_config.no_redis_required); if (!rtpe_redis || !rtpe_redis_notify) die("Cannot start up without running Redis %s database! See also NO_REDIS_REQUIRED parameter.", - endpoint_print_buf(&redis_ep)); + endpoint_print_buf(&rtpe_config.redis_ep)); if (!rtpe_redis_write) rtpe_redis_write = rtpe_redis; @@ -589,7 +576,7 @@ no_kernel: daemonize(); wpidfile(); - homer_sender_init(&homer_ep, homer_protocol, homer_id); + homer_sender_init(&rtpe_config.homer_ep, rtpe_config.homer_protocol, rtpe_config.homer_id); rtcp_init(); // must come after Homer init @@ -629,7 +616,7 @@ int main(int argc, char **argv) { thread_create_detach(sighandler, NULL); thread_create_detach(poller_timer_loop, rtpe_poller); - if (!is_addr_unspecified(&redis_ep.address)) + if (!is_addr_unspecified(&rtpe_config.redis_ep.address)) thread_create_detach(redis_notify_loop, NULL); if (!is_addr_unspecified(&rtpe_config.graphite_ep.address)) @@ -637,15 +624,15 @@ int main(int argc, char **argv) { thread_create_detach(ice_thread_run, NULL); - if (num_threads < 1) { + if (rtpe_config.num_threads < 1) { #ifdef _SC_NPROCESSORS_ONLN - num_threads = sysconf( _SC_NPROCESSORS_ONLN ) + 3; + rtpe_config.num_threads = sysconf( _SC_NPROCESSORS_ONLN ) + 3; #endif - if (num_threads <= 1) - num_threads = 4; + if (rtpe_config.num_threads <= 1) + rtpe_config.num_threads = 4; } - for (;idx Date: Thu, 4 Jan 2018 09:45:40 -0500 Subject: [PATCH 58/65] move lib/ config options into struct Change-Id: I563b38cd64daea5f9137debff2fc7881a3cdaa9d --- daemon/call.c | 2 +- daemon/cli.c | 4 +-- daemon/main.c | 14 ++++---- daemon/main.h | 4 +++ daemon/redis.c | 4 +-- lib/auxlib.c | 71 ++++++++++++++++++++++++----------------- lib/auxlib.h | 15 ++++++++- lib/loglib.c | 12 ++----- lib/loglib.h | 6 ++-- recording-daemon/main.c | 5 ++- recording-daemon/main.h | 6 ++++ 11 files changed, 84 insertions(+), 59 deletions(-) diff --git a/daemon/call.c b/daemon/call.c index 8f10fdf1e..e92214d7b 100644 --- a/daemon/call.c +++ b/daemon/call.c @@ -337,7 +337,7 @@ retry: for (i = 0; i < 100; i++) close(i); - if (!ilog_stderr) { + if (!rtpe_config.common.log_stderr) { openlog("rtpengine/child", LOG_PID | LOG_NDELAY, LOG_DAEMON); } ilog(LOG_INFO, "Initiating XMLRPC call for tag "STR_FORMAT"", STR_FMT(tag)); diff --git a/daemon/cli.c b/daemon/cli.c index 2678add3a..1af68c888 100644 --- a/daemon/cli.c +++ b/daemon/cli.c @@ -811,7 +811,7 @@ fail: } static void cli_incoming_list_loglevel(str *instr, struct streambuf *replybuffer) { - streambuf_printf(replybuffer, "%i\n", g_atomic_int_get(&log_level)); + streambuf_printf(replybuffer, "%i\n", get_log_level()); } static void cli_incoming_set_loglevel(str *instr, struct streambuf *replybuffer) { int nl; @@ -828,6 +828,6 @@ static void cli_incoming_set_loglevel(str *instr, struct streambuf *replybuffer) return; } - g_atomic_int_set(&log_level, nl); + g_atomic_int_set(&rtpe_config.common.log_level, nl); streambuf_printf(replybuffer, "Success setting loglevel to %i\n", nl); } diff --git a/daemon/main.c b/daemon/main.c index b45404f4b..dc164b881 100644 --- a/daemon/main.c +++ b/daemon/main.c @@ -92,14 +92,14 @@ static void sighandler(gpointer x) { rtpe_shutdown = 1; else if (ret == SIGUSR1) { if (get_log_level() > 0) { - g_atomic_int_add(&log_level, -1); + g_atomic_int_add(&rtpe_config.common.log_level, -1); ilog(get_log_level(), "Set log level to %d\n", get_log_level()); } } else if (ret == SIGUSR2) { if (get_log_level() < 7) { - g_atomic_int_add(&log_level, 1); + g_atomic_int_add(&rtpe_config.common.log_level, 1); ilog(get_log_level(), "Set log level to %d\n", get_log_level()); } @@ -289,7 +289,7 @@ static void options(int *argc, char ***argv) { }; config_load(argc, argv, e, " - next-generation media proxy", - "/etc/rtpengine/rtpengine.conf", "rtpengine"); + "/etc/rtpengine/rtpengine.conf", "rtpengine", &rtpe_config.common); if (!if_a) die("Missing option --interface"); @@ -384,9 +384,6 @@ static void options(int *argc, char ***argv) { if (rtpe_config.fmt > 1) die("Invalid XMLRPC format"); - if ((log_level < LOG_EMERG) || (log_level > LOG_DEBUG)) - die("Invalid log level (--log_level)"); - if (log_facility_cdr_s) { if (!parse_log_facility(log_facility_cdr_s, &_log_facility_cdr)) { print_available_log_facilities(); @@ -479,8 +476,6 @@ static void init_everything() { if (call_interfaces_init()) abort(); statistics_init(); - if (call_init()) - abort(); } @@ -510,6 +505,9 @@ no_kernel: dtls_timer(rtpe_poller); + if (call_init()) + abort(); + rwlock_init(&rtpe_config.config_lock); if (rtpe_config.max_sessions < -1) { rtpe_config.max_sessions = -1; diff --git a/daemon/main.h b/daemon/main.h index b939e9dc0..9cfd07f73 100644 --- a/daemon/main.h +++ b/daemon/main.h @@ -5,6 +5,7 @@ #include "aux.h" #include #include "socket.h" +#include "auxlib.h" enum xmlrpc_format { XF_SEMS = 0, @@ -14,6 +15,9 @@ enum xmlrpc_format { struct rtpengine_config { /* everything below protected by config_lock */ rwlock_t config_lock; + + struct rtpengine_common_config common; + int kernel_table; int max_sessions; int timeout; diff --git a/daemon/redis.c b/daemon/redis.c index 5eeecb5e7..8e2dd14bb 100644 --- a/daemon/redis.c +++ b/daemon/redis.c @@ -1594,7 +1594,7 @@ int redis_restore(struct redis *r) { if (!r) return 0; - log_level |= LOG_FLAG_RESTORE; + rtpe_config.common.log_level |= LOG_FLAG_RESTORE; rlog(LOG_DEBUG, "Restoring calls from Redis..."); @@ -1637,7 +1637,7 @@ int redis_restore(struct redis *r) { freeReplyObject(calls); err: - log_level &= ~LOG_FLAG_RESTORE; + rtpe_config.common.log_level &= ~LOG_FLAG_RESTORE; return ret; } diff --git a/lib/auxlib.c b/lib/auxlib.c index 8f24fb0fb..9c724176b 100644 --- a/lib/auxlib.c +++ b/lib/auxlib.c @@ -7,18 +7,15 @@ #include #include #include "log.h" +#include "loglib.h" -static const char *config_file; -static const char *config_section; -static const char *pid_file; -static const char *log_facility; -static int foreground; static int version; +struct rtpengine_common_config *rtpe_common_config_ptr; void daemonize(void) { - if (foreground) + if (rtpe_common_config_ptr->foreground) return; if (fork()) _exit(0); @@ -32,10 +29,10 @@ void daemonize(void) { void wpidfile() { FILE *fp; - if (!pid_file) + if (!rtpe_common_config_ptr->pidfile) return; - fp = fopen(pid_file, "w"); + fp = fopen(rtpe_common_config_ptr->pidfile, "w"); if (!fp) { ilog(LOG_CRIT, "Failed to create PID file (%s), aborting startup", strerror(errno)); exit(-1); @@ -54,22 +51,10 @@ static unsigned int options_length(const GOptionEntry *arr) { } -static const GOptionEntry shared_options[] = { - { "version", 'v', 0, G_OPTION_ARG_NONE, &version, "Print build time and exit", NULL }, - { "config-file", 0, 0, G_OPTION_ARG_STRING, &config_file, "Load config from this file", "FILE" }, - { "config-section", 0, 0, G_OPTION_ARG_STRING, &config_section,"Config file section to use", "STRING" }, - { "log-facility", 0, 0, G_OPTION_ARG_STRING, &log_facility, "Syslog facility to use for logging", "daemon|local0|...|local7"}, - { "log-level", 'L', 0, G_OPTION_ARG_INT, (void *)&log_level,"Mask log priorities above this level","INT" }, - { "log-stderr", 'E', 0, G_OPTION_ARG_NONE, &ilog_stderr, "Log on stderr instead of syslog", NULL }, - { "pidfile", 'p', 0, G_OPTION_ARG_FILENAME, &pid_file, "Write PID to file", "FILE" }, - { "foreground", 'f', 0, G_OPTION_ARG_NONE, &foreground, "Don't fork to background", NULL }, - { NULL, } -}; - #define CONF_OPTION_GLUE(get_func, data_type, ...) \ { \ data_type *varptr = e->arg_data; \ - data_type var = g_key_file_get_ ## get_func(kf, config_section, e->long_name, \ + data_type var = g_key_file_get_ ## get_func(kf, rtpe_common_config_ptr->config_section, e->long_name, \ ##__VA_ARGS__, &er); \ if (er && g_error_matches(er, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_KEY_NOT_FOUND)) { \ g_error_free(er); \ @@ -83,7 +68,8 @@ static const GOptionEntry shared_options[] = { } void config_load(int *argc, char ***argv, GOptionEntry *app_entries, const char *description, - const char *default_config, const char *default_section) + char *default_config, char *default_section, + struct rtpengine_common_config *cconfig) { GOptionContext *c; GError *er = NULL; @@ -92,6 +78,28 @@ void config_load(int *argc, char ***argv, GOptionEntry *app_entries, const char int saved_argc = *argc; char **saved_argv = g_strdupv(*argv); + rtpe_common_config_ptr = cconfig; + + // defaults +#ifndef __DEBUG + rtpe_common_config_ptr->log_level = LOG_INFO; +#else + rtpe_common_config_ptr->log_level = LOG_DEBUG; +#endif + + GOptionEntry shared_options[] = { + { "version", 'v', 0, G_OPTION_ARG_NONE, &version, "Print build time and exit", NULL }, + { "config-file", 0, 0, G_OPTION_ARG_STRING, &rtpe_common_config_ptr->config_file, "Load config from this file", "FILE" }, + { "config-section", 0, 0, G_OPTION_ARG_STRING, &rtpe_common_config_ptr->config_section,"Config file section to use", "STRING" }, + { "log-facility", 0, 0, G_OPTION_ARG_STRING, &rtpe_common_config_ptr->log_facility, "Syslog facility to use for logging", "daemon|local0|...|local7"}, + { "log-level", 'L', 0, G_OPTION_ARG_INT, (void *)&rtpe_common_config_ptr->log_level,"Mask log priorities above this level","INT" }, + { "log-stderr", 'E', 0, G_OPTION_ARG_NONE, &rtpe_common_config_ptr->log_stderr, "Log on stderr instead of syslog", NULL }, + { "pidfile", 'p', 0, G_OPTION_ARG_FILENAME, &rtpe_common_config_ptr->pidfile, "Write PID to file", "FILE" }, + { "foreground", 'f', 0, G_OPTION_ARG_NONE, &rtpe_common_config_ptr->foreground, "Don't fork to background", NULL }, + { NULL, } + }; + + // prepend shared CLI options unsigned int shared_len = options_length(shared_options); unsigned int app_len = options_length(app_entries); @@ -99,8 +107,8 @@ void config_load(int *argc, char ***argv, GOptionEntry *app_entries, const char memcpy(entries, shared_options, sizeof(*entries) * shared_len); memcpy(&entries[shared_len], app_entries, sizeof(*entries) * (app_len + 1)); - if (!config_section) - config_section = default_section; + if (!rtpe_common_config_ptr->config_section) + rtpe_common_config_ptr->config_section = default_section; c = g_option_context_new(description); g_option_context_add_main_entries(c, entries, NULL); @@ -109,8 +117,8 @@ void config_load(int *argc, char ***argv, GOptionEntry *app_entries, const char // is there a config file to load? use_config = default_config; - if (config_file) { - use_config = config_file; + if (rtpe_common_config_ptr->config_file) { + use_config = rtpe_common_config_ptr->config_file; fatal = 1; } @@ -153,14 +161,17 @@ out: } - if (log_facility) { - if (!parse_log_facility(log_facility, &ilog_facility)) { + if (rtpe_common_config_ptr->log_facility) { + if (!parse_log_facility(rtpe_common_config_ptr->log_facility, &ilog_facility)) { print_available_log_facilities(); - die ("Invalid log facility '%s' (--log-facility)", log_facility); + die ("Invalid log facility '%s' (--log-facility)", rtpe_common_config_ptr->log_facility); } } - if (ilog_stderr) { + if ((rtpe_common_config_ptr->log_level < LOG_EMERG) || (rtpe_common_config_ptr->log_level > LOG_DEBUG)) + die("Invalid log level (--log_level)"); + + if (rtpe_common_config_ptr->log_stderr) { write_log = log_to_stderr; max_log_line_length = 0; } diff --git a/lib/auxlib.h b/lib/auxlib.h index 3e29c7223..eae9ef72f 100644 --- a/lib/auxlib.h +++ b/lib/auxlib.h @@ -3,10 +3,23 @@ #include +struct rtpengine_common_config { + char *config_file; + char *config_section; + char *log_facility; + volatile int log_level; + int log_stderr; + char *pidfile; + int foreground; +}; + +extern struct rtpengine_common_config *rtpe_common_config_ptr; + void daemonize(void); void wpidfile(void); void config_load(int *argc, char ***argv, GOptionEntry *entries, const char *description, - const char *default_config, const char *default_section); + char *default_config, char *default_section, + struct rtpengine_common_config *); #endif diff --git a/lib/loglib.c b/lib/loglib.c index 2f80e4f41..2837567e9 100644 --- a/lib/loglib.c +++ b/lib/loglib.c @@ -8,6 +8,7 @@ #include #include #include +#include "auxlib.h" struct log_limiter_entry { @@ -22,14 +23,6 @@ typedef struct _fac_code { -#ifndef __DEBUG -volatile gint log_level = LOG_INFO; -#else -volatile gint log_level = LOG_DEBUG; -#endif - - - static write_log_t log_both; unsigned int max_log_line_length = 500; @@ -73,7 +66,6 @@ static const char* const prio_str[] = { "DEBUG" }; -gboolean ilog_stderr = 0; int ilog_facility = LOG_DAEMON; @@ -230,7 +222,7 @@ void log_init(const char *handle) { __log_limiter = g_hash_table_new(log_limiter_entry_hash, log_limiter_entry_equal); __log_limiter_strings = g_string_chunk_new(1024); - if (!ilog_stderr) + if (!rtpe_common_config_ptr->log_stderr) openlog(handle, LOG_PID | LOG_NDELAY, ilog_facility); } diff --git a/lib/loglib.h b/lib/loglib.h index 72aeffd67..04ebbea7b 100644 --- a/lib/loglib.h +++ b/lib/loglib.h @@ -6,13 +6,11 @@ #include #include #include "compat.h" +#include "auxlib.h" -extern gboolean ilog_stderr; extern int ilog_facility; - -extern volatile gint log_level; extern unsigned int max_log_line_length; @@ -46,7 +44,7 @@ void __ilog_np(int prio, const char *format, ...) __attribute__ ((format (printf INLINE int get_log_level(void) { - return g_atomic_int_get(&log_level); + return g_atomic_int_get(&rtpe_common_config_ptr->log_level); } diff --git a/recording-daemon/main.c b/recording-daemon/main.c index 4a18a1f26..55bfd610d 100644 --- a/recording-daemon/main.c +++ b/recording-daemon/main.c @@ -45,6 +45,9 @@ static GQueue threads = G_QUEUE_INIT; // only accessed from main thread volatile int shutdown_flag; +struct rtpengine_common_config rtpe_common_config; + + static void signals(void) { sigset_t ss; @@ -186,7 +189,7 @@ static void options(int *argc, char ***argv) { }; config_load(argc, argv, e, " - rtpengine recording daemon", - "/etc/rtpengine/rtpengine-recording.conf", "rtpengine-recording"); + "/etc/rtpengine/rtpengine-recording.conf", "rtpengine-recording", &rtpe_common_config); if (!strcmp(output_format, "none")) { output_enabled = 0; diff --git a/recording-daemon/main.h b/recording-daemon/main.h index bf33b8309..f11b39105 100644 --- a/recording-daemon/main.h +++ b/recording-daemon/main.h @@ -2,6 +2,9 @@ #define _MAIN_H_ +#include "auxlib.h" + + extern int ktable; extern int num_threads; extern const char *spool_dir; @@ -19,4 +22,7 @@ extern const char *forward_to; extern volatile int shutdown_flag; +extern struct rtpengine_common_config rtpe_common_config; + + #endif From 74bae6a9a9fedafced6475d74037a39b44fdba0f Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Tue, 16 Jan 2018 11:24:10 -0500 Subject: [PATCH 59/65] TT#30150 add option for different logging styles closes #442 Change-Id: I338afc58e10b056718e086dbcd232f3324984bf0 --- README.md | 8 ++++++ daemon/log.c | 72 +++++++++++++++++++++++++++++++++++++++++++++------ daemon/log.h | 2 ++ daemon/main.c | 12 +++++++++ daemon/main.h | 7 +++++ 5 files changed, 93 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index bc9790e50..12b6a4420 100644 --- a/README.md +++ b/README.md @@ -189,6 +189,7 @@ option and which are reproduced below: --log-facility=daemon|local0|... Syslog facility to use for logging --log-facility-cdr=local0|... Syslog facility to use for logging CDRs --log-facility-rtcp=local0|... Syslog facility to use for logging RTCP data (take care of traffic amount) + --log-format=default|parsable Log prefix format -E, --log-stderr Log on stderr instead of syslog -x, --xmlrpc-format=INT XMLRPC timeout request format to use. 0: SEMS DI, 1: call-id only --num-threads=INT Number of worker threads to create @@ -345,6 +346,13 @@ The options are described in more detail below. Same as --log-facility with the difference that only RTCP data is written to this log facility. Be careful with this parameter since there may be a lot of information written to it. +* --log-format=default|parsable + + Selects between multiple log output styles. The default is to prefix log lines with a description + of the relevant entity, such as `[CALLID]` or `[CALLID port 12345]`. The `parsable` output style + is similar, but makes the ID easier to parse by enclosing it in quotes, such as `[ID="CALLID"]` + or `[ID="CALLID" port="12345"]`. + * -E, --log-stderr Log to stderr instead of syslog. Only useful in combination with `--foreground`. diff --git a/daemon/log.c b/daemon/log.c index e096284ba..6f2038c73 100644 --- a/daemon/log.c +++ b/daemon/log.c @@ -8,6 +8,7 @@ #include "poller.h" #include "ice.h" #include "loglib.h" +#include "main.h" @@ -17,46 +18,101 @@ struct log_info __thread log_info; int _log_facility_cdr = 0; int _log_facility_rtcp = 0; +typedef void (ilog_prefix_func)(char *prefix, size_t prefix_len); +static ilog_prefix_func ilog_prefix_default; +static ilog_prefix_func ilog_prefix_parsable; + +static ilog_prefix_func *ilog_prefix = ilog_prefix_default; + +static ilog_prefix_func * const ilog_prefix_funcs[__LF_LAST] = { + [LF_DEFAULT] = ilog_prefix_default, + [LF_PARSABLE] = ilog_prefix_parsable, +}; -void __ilog(int prio, const char *fmt, ...) { - char prefix[300]; - va_list ap; + +static void ilog_prefix_default(char *prefix, size_t prefix_len) { switch (log_info.e) { case LOG_INFO_NONE: prefix[0] = 0; break; case LOG_INFO_CALL: - snprintf(prefix, sizeof(prefix), "["STR_FORMAT"]: ", + snprintf(prefix, prefix_len, "["STR_FORMAT"]: ", STR_FMT(&log_info.u.call->callid)); break; case LOG_INFO_STREAM_FD: if (log_info.u.stream_fd->call) - snprintf(prefix, sizeof(prefix), "["STR_FORMAT" port %5u]: ", + snprintf(prefix, prefix_len, "["STR_FORMAT" port %5u]: ", STR_FMT(&log_info.u.stream_fd->call->callid), log_info.u.stream_fd->socket.local.port); break; case LOG_INFO_STR: - snprintf(prefix, sizeof(prefix), "["STR_FORMAT"]: ", + snprintf(prefix, prefix_len, "["STR_FORMAT"]: ", STR_FMT(log_info.u.str)); break; case LOG_INFO_C_STRING: - snprintf(prefix, sizeof(prefix), "[%s]: ", log_info.u.cstr); + snprintf(prefix, prefix_len, "[%s]: ", log_info.u.cstr); break; case LOG_INFO_ICE_AGENT: - snprintf(prefix, sizeof(prefix), "["STR_FORMAT"/"STR_FORMAT"/%u]: ", + snprintf(prefix, prefix_len, "["STR_FORMAT"/"STR_FORMAT"/%u]: ", STR_FMT(&log_info.u.ice_agent->call->callid), STR_FMT(&log_info.u.ice_agent->media->monologue->tag), log_info.u.ice_agent->media->index); break; } +} + +static void ilog_prefix_parsable(char *prefix, size_t prefix_len) { + switch (log_info.e) { + case LOG_INFO_NONE: + prefix[0] = 0; + break; + case LOG_INFO_CALL: + snprintf(prefix, prefix_len, "[ID=\""STR_FORMAT"\"]: ", + STR_FMT(&log_info.u.call->callid)); + break; + case LOG_INFO_STREAM_FD: + if (log_info.u.stream_fd->call) + snprintf(prefix, prefix_len, "[ID=\""STR_FORMAT"\" port=\"%5u\"]: ", + STR_FMT(&log_info.u.stream_fd->call->callid), + log_info.u.stream_fd->socket.local.port); + break; + case LOG_INFO_STR: + snprintf(prefix, prefix_len, "[ID=\""STR_FORMAT"\"]: ", + STR_FMT(log_info.u.str)); + break; + case LOG_INFO_C_STRING: + snprintf(prefix, prefix_len, "[ID=\"%s\"]: ", log_info.u.cstr); + break; + case LOG_INFO_ICE_AGENT: + snprintf(prefix, prefix_len, "[ID=\""STR_FORMAT"\" tag=\""STR_FORMAT"\" index=\"%u\"]: ", + STR_FMT(&log_info.u.ice_agent->call->callid), + STR_FMT(&log_info.u.ice_agent->media->monologue->tag), + log_info.u.ice_agent->media->index); + break; + } +} + +void __ilog(int prio, const char *fmt, ...) { + char prefix[300]; + va_list ap; + + ilog_prefix(prefix, sizeof(prefix)); va_start(ap, fmt); __vpilog(prio, prefix, fmt, ap); va_end(ap); } +void log_format(enum log_format f) { + if (f < 0 || f >= __LF_LAST) + die("Invalid log format enum"); + ilog_prefix = ilog_prefix_funcs[f]; + if (!ilog_prefix) + die("Invalid log format enum"); +} + void cdrlog(const char* cdrbuffer) { if (_log_facility_cdr) { syslog(LOG_INFO | _log_facility_cdr, "%s", cdrbuffer); diff --git a/daemon/log.h b/daemon/log.h index 881cb3e8c..626f41373 100644 --- a/daemon/log.h +++ b/daemon/log.h @@ -10,6 +10,7 @@ struct call; struct stream_fd; struct ice_agent; +enum log_format; struct log_info { union { @@ -42,6 +43,7 @@ void cdrlog(const char* cdrbuffer); void rtcplog(const char* cdrbuffer); +void log_format(enum log_format); void __ilog(int prio, const char *fmt, ...) __attribute__ ((format (printf, 2, 3))); diff --git a/daemon/main.c b/daemon/main.c index dc164b881..4fc6d3f07 100644 --- a/daemon/main.c +++ b/daemon/main.c @@ -238,6 +238,7 @@ static void options(int *argc, char ***argv) { char *redisps_write = NULL; char *log_facility_cdr_s = NULL; char *log_facility_rtcp_s = NULL; + char *log_format = NULL; int sip_source = 0; char *homerp = NULL; char *homerproto = NULL; @@ -270,6 +271,7 @@ static void options(int *argc, char ***argv) { { "b2b-url", 'b', 0, G_OPTION_ARG_STRING, &rtpe_config.b2b_url, "XMLRPC URL of B2B UA" , "STRING" }, { "log-facility-cdr",0, 0, G_OPTION_ARG_STRING, &log_facility_cdr_s, "Syslog facility to use for logging CDRs", "daemon|local0|...|local7"}, { "log-facility-rtcp",0, 0, G_OPTION_ARG_STRING, &log_facility_rtcp_s, "Syslog facility to use for logging RTCP", "daemon|local0|...|local7"}, + { "log-format", 0, 0, G_OPTION_ARG_STRING, &log_format, "Log prefix format", "default|parsable"}, { "xmlrpc-format",'x', 0, G_OPTION_ARG_INT, &rtpe_config.fmt, "XMLRPC timeout request format to use. 0: SEMS DI, 1: call-id only", "INT" }, { "num-threads", 0, 0, G_OPTION_ARG_INT, &rtpe_config.num_threads, "Number of worker threads to create", "INT" }, { "delete-delay", 'd', 0, G_OPTION_ARG_INT, &rtpe_config.delete_delay, "Delay for deleting a session from memory.", "INT" }, @@ -398,6 +400,15 @@ static void options(int *argc, char ***argv) { } } + if (log_format) { + if (!strcmp(log_format, "default")) + rtpe_config.log_format = LF_DEFAULT; + else if (!strcmp(log_format, "parsable")) + rtpe_config.log_format = LF_PARSABLE; + else + die("Invalid --log-format option"); + } + if (!sip_source) trust_address_def = 1; } @@ -449,6 +460,7 @@ static void init_everything() { struct timespec ts; log_init("rtpengine"); + log_format(rtpe_config.log_format); recording_fs_init(rtpe_config.spooldir, rtpe_config.rec_method, rtpe_config.rec_format); clock_gettime(CLOCK_REALTIME, &ts); srandom(ts.tv_sec ^ ts.tv_nsec); diff --git a/daemon/main.h b/daemon/main.h index 9cfd07f73..fad9eb470 100644 --- a/daemon/main.h +++ b/daemon/main.h @@ -11,6 +11,12 @@ enum xmlrpc_format { XF_SEMS = 0, XF_CALLID, }; +enum log_format { + LF_DEFAULT = 0, + LF_PARSABLE, + + __LF_LAST +}; struct rtpengine_config { /* everything below protected by config_lock */ @@ -30,6 +36,7 @@ struct rtpengine_config { int default_tos; int control_tos; enum xmlrpc_format fmt; + enum log_format log_format; endpoint_t graphite_ep; int graphite_interval; int redis_num_threads; From b8dbd997e939e23d0515d0bf5c73111890a1bdf4 Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Thu, 4 Jan 2018 11:10:33 -0500 Subject: [PATCH 60/65] TT#30403 consolidate NG flags processing functions Change-Id: Id200b0f064b72d8e60a6a744f764a8bb63655014 --- daemon/call_interfaces.c | 147 ++++++++++++++++++++------------------- daemon/control_ng.c | 1 + 2 files changed, 77 insertions(+), 71 deletions(-) diff --git a/daemon/call_interfaces.c b/daemon/call_interfaces.c index fce3be8f4..7f80b7810 100644 --- a/daemon/call_interfaces.c +++ b/daemon/call_interfaces.c @@ -526,6 +526,78 @@ INLINE void ng_sdes_option(struct sdp_ng_flags *out, bencode_item_t *it, unsigne STR_FMT(&s)); } + +static void call_ng_flags_list(struct sdp_ng_flags *out, bencode_item_t *input, const char *key, + void (*callback)(struct sdp_ng_flags *out, bencode_item_t *input)) +{ + bencode_item_t *list, *it; + if ((list = bencode_dictionary_get_expect(input, key, BENCODE_LIST))) { + for (it = list->child; it; it = it->sibling) + callback(out, it); + } +} +static void call_ng_flags_sdes(struct sdp_ng_flags *out, bencode_item_t *it) { + ng_sdes_option(out, it, 0); +} +static void call_ng_flags_rtcp_mux(struct sdp_ng_flags *out, bencode_item_t *it) { + if (!bencode_strcmp(it, "offer")) + out->rtcp_mux_offer = 1; + else if (!bencode_strcmp(it, "require")) + out->rtcp_mux_require = 1; + else if (!bencode_strcmp(it, "demux")) + out->rtcp_mux_demux = 1; + else if (!bencode_strcmp(it, "accept")) + out->rtcp_mux_accept = 1; + else if (!bencode_strcmp(it, "reject")) + out->rtcp_mux_reject = 1; + else + ilog(LOG_WARN, "Unknown 'rtcp-mux' flag encountered: '"BENCODE_FORMAT"'", + BENCODE_FMT(it)); +} +static void call_ng_flags_replace(struct sdp_ng_flags *out, bencode_item_t *it) { + str_hyphenate(it); + if (!bencode_strcmp(it, "origin")) + out->replace_origin = 1; + else if (!bencode_strcmp(it, "session-connection")) + out->replace_sess_conn = 1; + else + ilog(LOG_WARN, "Unknown 'replace' flag encountered: '"BENCODE_FORMAT"'", + BENCODE_FMT(it)); +} +static void call_ng_flags_flags(struct sdp_ng_flags *out, bencode_item_t *it) { + if (it->type != BENCODE_STRING) + return; + + str_hyphenate(it); + + if (!bencode_strcmp(it, "trust-address")) + out->trust_address = 1; + else if (!bencode_strcmp(it, "SIP-source-address")) + out->trust_address = 0; + else if (!bencode_strcmp(it, "asymmetric")) + out->asymmetric = 1; + else if (!bencode_strcmp(it, "no-redis-update")) + out->no_redis_update = 1; + else if (!bencode_strcmp(it, "unidirectional")) + out->unidirectional = 1; + else if (!bencode_strcmp(it, "strict-source")) + out->strict_source = 1; + else if (!bencode_strcmp(it, "media-handover")) + out->media_handover = 1; + else if (!bencode_strcmp(it, "reset")) + 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 if (!bencode_strcmp(it, "record-call")) + out->record_call = 1; + else if (!bencode_strcmp(it, "no-rtcp-attribute")) + out->no_rtcp_attr = 1; + else + ilog(LOG_WARN, "Unknown flag encountered: '"BENCODE_FORMAT"'", + BENCODE_FMT(it)); +} static void call_ng_process_flags(struct sdp_ng_flags *out, bencode_item_t *input) { bencode_item_t *list, *it; int diridx; @@ -536,55 +608,8 @@ static void call_ng_process_flags(struct sdp_ng_flags *out, bencode_item_t *inpu out->trust_address = trust_address_def; out->dtls_passive = dtls_passive_def; - if ((list = bencode_dictionary_get_expect(input, "flags", BENCODE_LIST))) { - for (it = list->child; it; it = it->sibling) { - if (it->type != BENCODE_STRING) - continue; - - str_hyphenate(it); - - if (!bencode_strcmp(it, "trust-address")) - out->trust_address = 1; - else if (!bencode_strcmp(it, "SIP-source-address")) - out->trust_address = 0; - else if (!bencode_strcmp(it, "asymmetric")) - out->asymmetric = 1; - else if (!bencode_strcmp(it, "no-redis-update")) - out->no_redis_update = 1; - else if (!bencode_strcmp(it, "unidirectional")) - out->unidirectional = 1; - else if (!bencode_strcmp(it, "strict-source")) - out->strict_source = 1; - else if (!bencode_strcmp(it, "media-handover")) - out->media_handover = 1; - else if (!bencode_strcmp(it, "reset")) - 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 if (!bencode_strcmp(it, "record-call")) - out->record_call = 1; - else if (!bencode_strcmp(it, "no-rtcp-attribute")) - out->no_rtcp_attr = 1; - else - ilog(LOG_WARN, "Unknown flag encountered: '"BENCODE_FORMAT"'", - BENCODE_FMT(it)); - } - } - - if ((list = bencode_dictionary_get_expect(input, "replace", BENCODE_LIST))) { - for (it = list->child; it; it = it->sibling) { - str_hyphenate(it); - if (!bencode_strcmp(it, "origin")) - out->replace_origin = 1; - else if (!bencode_strcmp(it, "session-connection")) - out->replace_sess_conn = 1; - else - ilog(LOG_WARN, "Unknown 'replace' flag encountered: '"BENCODE_FORMAT"'", - BENCODE_FMT(it)); - } - } + call_ng_flags_list(out, input, "flags", call_ng_flags_flags); + call_ng_flags_list(out, input, "replace", call_ng_flags_replace); diridx = 0; if ((list = bencode_dictionary_get_expect(input, "direction", BENCODE_LIST))) { @@ -624,30 +649,10 @@ static void call_ng_process_flags(struct sdp_ng_flags *out, bencode_item_t *inpu STR_FMT(&s)); } - if ((list = bencode_dictionary_get_expect(input, "rtcp-mux", BENCODE_LIST))) { - for (it = list->child; it; it = it->sibling) { - if (!bencode_strcmp(it, "offer")) - out->rtcp_mux_offer = 1; - else if (!bencode_strcmp(it, "require")) - out->rtcp_mux_require = 1; - else if (!bencode_strcmp(it, "demux")) - out->rtcp_mux_demux = 1; - else if (!bencode_strcmp(it, "accept")) - out->rtcp_mux_accept = 1; - else if (!bencode_strcmp(it, "reject")) - out->rtcp_mux_reject = 1; - else - ilog(LOG_WARN, "Unknown 'rtcp-mux' flag encountered: '"BENCODE_FORMAT"'", - BENCODE_FMT(it)); - } - } + call_ng_flags_list(out, input, "rtcp-mux", call_ng_flags_rtcp_mux); - /* XXX abstractize the other list walking functions using callbacks */ /* XXX module still needs to support this list */ - if ((list = bencode_dictionary_get_expect(input, "SDES", BENCODE_LIST))) { - for (it = list->child; it; it = it->sibling) - ng_sdes_option(out, it, 0); - } + call_ng_flags_list(out, input, "SDES", call_ng_flags_sdes); bencode_get_alt(input, "transport-protocol", "transport protocol", &out->transport_protocol_str); out->transport_protocol = transport_protocol(&out->transport_protocol_str); diff --git a/daemon/control_ng.c b/daemon/control_ng.c index 3babbe7c4..fc10944b2 100644 --- a/daemon/control_ng.c +++ b/daemon/control_ng.c @@ -173,6 +173,7 @@ static void control_ng_incoming(struct obj *obj, str *buf, const endpoint_t *sin g_string_free(log_str, TRUE); } + // XXX do the strcmp's only once errstr = NULL; resultstr = "ok"; if (!str_cmp(&cmd, "ping")) { From d7dd7421e6e4e72b1347da9b189b290865b4390a Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Thu, 4 Jan 2018 13:34:27 -0500 Subject: [PATCH 61/65] TT#30403 implement codec stripping Change-Id: I384aa353b43986656145c443e40a2b96f04c489f --- README.md | 13 ++++++++ daemon/call.c | 20 ++++++++++-- daemon/call.h | 2 ++ daemon/call_interfaces.c | 59 +++++++++++++++++++++++++++++------- daemon/call_interfaces.h | 2 ++ daemon/sdp.c | 64 +++++++++++++++++++++++++++++++++++++++ utils/rtpengine-ng-client | 8 +++++ 7 files changed, 154 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 12b6a4420..edff85a05 100644 --- a/README.md +++ b/README.md @@ -1180,6 +1180,19 @@ Optionally included keys are: See the `--recording-dir` option above. +* `codec` + + Contains a dictionary controlling various aspects of codecs (or RTP payload types). + The following keys are understood: + + * `strip` + + Contains a list of strings. Each string is the name of a codec or RTP payload + type that should be removed from the SDP. Codec names are case sensitive, and + can be either from the list of codecs explicitly defined by the SDP through + an `a=rtpmap` attribute, or can be from the list of RFC-defined codecs. Examples + are `PCMU`, `opus`, or `telephone-event`. + An example of a complete `offer` request dictionary could be (SDP body abbreviated): diff --git a/daemon/call.c b/daemon/call.c index e92214d7b..a9da7d5c5 100644 --- a/daemon/call.c +++ b/daemon/call.c @@ -1419,17 +1419,30 @@ static void __dtls_logic(const struct sdp_ng_flags *flags, MEDIA_SET(other_media, DTLS); } -static void __rtp_payload_types(struct call_media *media, GQueue *types) { +static void __rtp_payload_types(struct call_media *media, GQueue *types, GHashTable *strip) { struct rtp_payload_type *pt; struct call *call = media->call; + static const str __all = STR_CONST_INIT("all"); + + // start fresh + g_queue_clear(&media->rtp_payload_types_prefs); /* we steal the entire list to avoid duplicate allocs */ while ((pt = g_queue_pop_head(types))) { - /* but we must duplicate the contents */ + // codec stripping + if (strip) { + if (g_hash_table_lookup(strip, &pt->encoding) + || g_hash_table_lookup(strip, &__all)) { + __payload_type_free(pt); + continue; + } + } + /* we must duplicate the contents */ call_str_cpy(call, &pt->encoding_with_params, &pt->encoding_with_params); call_str_cpy(call, &pt->encoding, &pt->encoding); call_str_cpy(call, &pt->encoding_parameters, &pt->encoding_parameters); g_hash_table_replace(media->rtp_payload_types, &pt->payload_type, pt); + g_queue_push_tail(&media->rtp_payload_types_prefs, pt); } } @@ -1553,7 +1566,7 @@ int monologue_offer_answer(struct call_monologue *other_ml, GQueue *streams, MEDIA_SET(other_media, SDES); } - __rtp_payload_types(media, &sp->rtp_payload_types); + __rtp_payload_types(media, &sp->rtp_payload_types, flags->codec_strip); /* send and recv are from our POV */ bf_copy_same(&media->media_flags, &sp->sp_flags, @@ -1963,6 +1976,7 @@ static void __call_free(void *p) { g_queue_clear(&md->streams); g_queue_clear(&md->endpoint_maps); g_hash_table_destroy(md->rtp_payload_types); + g_queue_clear(&md->rtp_payload_types_prefs); g_slice_free1(sizeof(*md), md); } diff --git a/daemon/call.h b/daemon/call.h index 8a8cfe105..ccb679203 100644 --- a/daemon/call.h +++ b/daemon/call.h @@ -322,7 +322,9 @@ struct call_media { GQueue streams; /* normally RTP + RTCP */ GQueue endpoint_maps; + GHashTable *rtp_payload_types; + GQueue rtp_payload_types_prefs; volatile unsigned int media_flags; }; diff --git a/daemon/call_interfaces.c b/daemon/call_interfaces.c index 7f80b7810..b01b096ff 100644 --- a/daemon/call_interfaces.c +++ b/daemon/call_interfaces.c @@ -528,18 +528,18 @@ INLINE void ng_sdes_option(struct sdp_ng_flags *out, bencode_item_t *it, unsigne static void call_ng_flags_list(struct sdp_ng_flags *out, bencode_item_t *input, const char *key, - void (*callback)(struct sdp_ng_flags *out, bencode_item_t *input)) + void (*callback)(struct sdp_ng_flags *, bencode_item_t *, void *), void *parm) { bencode_item_t *list, *it; if ((list = bencode_dictionary_get_expect(input, key, BENCODE_LIST))) { for (it = list->child; it; it = it->sibling) - callback(out, it); + callback(out, it, parm); } } -static void call_ng_flags_sdes(struct sdp_ng_flags *out, bencode_item_t *it) { +static void call_ng_flags_sdes(struct sdp_ng_flags *out, bencode_item_t *it, void *dummy) { ng_sdes_option(out, it, 0); } -static void call_ng_flags_rtcp_mux(struct sdp_ng_flags *out, bencode_item_t *it) { +static void call_ng_flags_rtcp_mux(struct sdp_ng_flags *out, bencode_item_t *it, void *dummy) { if (!bencode_strcmp(it, "offer")) out->rtcp_mux_offer = 1; else if (!bencode_strcmp(it, "require")) @@ -554,7 +554,7 @@ static void call_ng_flags_rtcp_mux(struct sdp_ng_flags *out, bencode_item_t *it) ilog(LOG_WARN, "Unknown 'rtcp-mux' flag encountered: '"BENCODE_FORMAT"'", BENCODE_FMT(it)); } -static void call_ng_flags_replace(struct sdp_ng_flags *out, bencode_item_t *it) { +static void call_ng_flags_replace(struct sdp_ng_flags *out, bencode_item_t *it, void *dummy) { str_hyphenate(it); if (!bencode_strcmp(it, "origin")) out->replace_origin = 1; @@ -564,7 +564,29 @@ static void call_ng_flags_replace(struct sdp_ng_flags *out, bencode_item_t *it) ilog(LOG_WARN, "Unknown 'replace' flag encountered: '"BENCODE_FORMAT"'", BENCODE_FMT(it)); } -static void call_ng_flags_flags(struct sdp_ng_flags *out, bencode_item_t *it) { +static void call_ng_flags_codec_list(struct sdp_ng_flags *out, bencode_item_t *it, void *qp) { + str *s; + s = g_slice_alloc(sizeof(*s)); + if (!bencode_get_str(it, s)) { + g_slice_free1(sizeof(*s), s); + return; + } + g_queue_push_tail((GQueue *) qp, s); +} +static void call_ng_flags_codec_ht_strip(bencode_item_t *it, GHashTable *ht, unsigned int strip) { + str *s; + s = g_slice_alloc(sizeof(*s)); + if (!bencode_get_str(it, s)) { + g_slice_free1(sizeof(*s), s); + return; + } + str_shift(s, strip); + g_hash_table_replace(ht, s, s); +} +static void call_ng_flags_codec_ht(struct sdp_ng_flags *out, bencode_item_t *it, void *htp) { + call_ng_flags_codec_ht_strip(it, htp, 0); +} +static void call_ng_flags_flags(struct sdp_ng_flags *out, bencode_item_t *it, void *dummy) { if (it->type != BENCODE_STRING) return; @@ -586,8 +608,11 @@ static void call_ng_flags_flags(struct sdp_ng_flags *out, bencode_item_t *it) { out->media_handover = 1; else if (!bencode_strcmp(it, "reset")) out->reset = 1; + // XXX unify these else if (it->iov[1].iov_len >= 5 && !memcmp(it->iov[1].iov_base, "SDES-", 5)) ng_sdes_option(out, it, 5); + else if (it->iov[1].iov_len >= 12 && !memcmp(it->iov[1].iov_base, "codec-strip-", 12)) + call_ng_flags_codec_ht_strip(it, out->codec_strip, 12); else if (!bencode_strcmp(it, "port-latching")) out->port_latching = 1; else if (!bencode_strcmp(it, "record-call")) @@ -599,17 +624,18 @@ static void call_ng_flags_flags(struct sdp_ng_flags *out, bencode_item_t *it) { BENCODE_FMT(it)); } static void call_ng_process_flags(struct sdp_ng_flags *out, bencode_item_t *input) { - bencode_item_t *list, *it; + bencode_item_t *list, *it, *dict; int diridx; str s; ZERO(*out); + out->codec_strip = g_hash_table_new_full(str_hash, str_equal, str_slice_free, NULL); out->trust_address = trust_address_def; out->dtls_passive = dtls_passive_def; - call_ng_flags_list(out, input, "flags", call_ng_flags_flags); - call_ng_flags_list(out, input, "replace", call_ng_flags_replace); + call_ng_flags_list(out, input, "flags", call_ng_flags_flags, NULL); + call_ng_flags_list(out, input, "replace", call_ng_flags_replace, NULL); diridx = 0; if ((list = bencode_dictionary_get_expect(input, "direction", BENCODE_LIST))) { @@ -649,10 +675,10 @@ static void call_ng_process_flags(struct sdp_ng_flags *out, bencode_item_t *inpu STR_FMT(&s)); } - call_ng_flags_list(out, input, "rtcp-mux", call_ng_flags_rtcp_mux); + call_ng_flags_list(out, input, "rtcp-mux", call_ng_flags_rtcp_mux, NULL); /* XXX module still needs to support this list */ - call_ng_flags_list(out, input, "SDES", call_ng_flags_sdes); + call_ng_flags_list(out, input, "SDES", call_ng_flags_sdes, NULL); bencode_get_alt(input, "transport-protocol", "transport protocol", &out->transport_protocol_str); out->transport_protocol = transport_protocol(&out->transport_protocol_str); @@ -662,6 +688,15 @@ static void call_ng_process_flags(struct sdp_ng_flags *out, bencode_item_t *inpu out->tos = bencode_dictionary_get_integer(input, "TOS", 256); bencode_get_alt(input, "record-call", "record call", &out->record_call_str); bencode_dictionary_get_str(input, "metadata", &out->metadata); + + if ((dict = bencode_dictionary_get_expect(input, "codec", BENCODE_DICTIONARY))) { + call_ng_flags_list(out, dict, "strip", call_ng_flags_codec_ht, out->codec_strip); + call_ng_flags_list(out, dict, "offer", call_ng_flags_codec_list, &out->codec_offer); + } +} +static void call_ng_free_flags(struct sdp_ng_flags *flags) { + g_hash_table_destroy(flags->codec_strip); + g_queue_clear_full(&flags->codec_offer, str_slice_free); } static const char *call_offer_answer_ng(bencode_item_t *input, @@ -798,6 +833,7 @@ static const char *call_offer_answer_ng(bencode_item_t *input, if (ret == ERROR_NO_FREE_PORTS || ret == ERROR_NO_FREE_LOGS) { ilog(LOG_ERR, "Destroying call"); + errstr = "Ran out of ports"; call_destroy(call); } @@ -811,6 +847,7 @@ static const char *call_offer_answer_ng(bencode_item_t *input, out: sdp_free(&parsed); streams_free(&streams); + call_ng_free_flags(&flags); return errstr; } diff --git a/daemon/call_interfaces.h b/daemon/call_interfaces.h index 1cff0b1ce..7114bd9eb 100644 --- a/daemon/call_interfaces.h +++ b/daemon/call_interfaces.h @@ -31,6 +31,8 @@ struct sdp_ng_flags { int tos; str record_call_str; str metadata; + GHashTable *codec_strip; + GQueue codec_offer; int asymmetric:1, no_redis_update:1, unidirectional:1, diff --git a/daemon/sdp.c b/daemon/sdp.c index 4583f0a8d..b0315e2c4 100644 --- a/daemon/sdp.c +++ b/daemon/sdp.c @@ -162,6 +162,13 @@ struct attribute_rtpmap { struct rtp_payload_type rtp_pt; }; +struct attribute_fmtp { + str payload_type_str; + str format_parms_str; + + unsigned int payload_type; +}; + struct sdp_attribute { str full_line, /* including a= and \r\n */ line_value, /* without a= and without \r\n */ @@ -192,6 +199,7 @@ struct sdp_attribute { ATTR_FINGERPRINT, ATTR_SETUP, ATTR_RTPMAP, + ATTR_FMTP, ATTR_IGNORE, ATTR_END_OF_CANDIDATES, } attr; @@ -205,6 +213,7 @@ struct sdp_attribute { struct attribute_fingerprint fingerprint; struct attribute_setup setup; struct attribute_rtpmap rtpmap; + struct attribute_fmtp fmtp; } u; }; @@ -742,6 +751,26 @@ static int parse_attribute_rtpmap(struct sdp_attribute *output) { return 0; } +static int parse_attribute_fmtp(struct sdp_attribute *output) { + PARSE_DECL; + char *ep; + struct attribute_fmtp *a; + + output->attr = ATTR_FMTP; + + PARSE_INIT; + EXTRACT_TOKEN(u.fmtp.payload_type_str); + EXTRACT_TOKEN(u.fmtp.format_parms_str); + + a = &output->u.fmtp; + + a->payload_type = strtoul(a->payload_type_str.s, &ep, 10); + if (ep == a->payload_type_str.s) + return -1; + + return 0; +} + static int parse_attribute(struct sdp_attribute *a) { int ret; @@ -777,6 +806,8 @@ static int parse_attribute(struct sdp_attribute *a) { ret = parse_attribute_rtcp(a); else if (!str_cmp(&a->name, "ssrc")) ret = parse_attribute_ssrc(a); + else if (!str_cmp(&a->name, "fmtp")) + ret = parse_attribute_fmtp(a); break; case 5: if (!str_cmp(&a->name, "group")) @@ -1408,6 +1439,21 @@ static int replace_transport_protocol(struct sdp_chopper *chop, return 0; } +static int replace_codec_list(struct sdp_chopper *chop, + struct sdp_media *media, struct call_media *cm) +{ + if (cm->rtp_payload_types_prefs.length == 0) + return 0; // legacy protocol or usage error + + for (GList *l = cm->rtp_payload_types_prefs.head; l; l = l->next) { + struct rtp_payload_type *pt = l->data; + chopper_append_printf(chop, " %u", pt->payload_type); + } + if (skip_over(chop, &media->formats)) + return -1; + return 0; +} + static int replace_media_port(struct sdp_chopper *chop, struct sdp_media *media, struct packet_stream *ps) { str *port = &media->port; unsigned int p; @@ -1643,6 +1689,22 @@ static int process_media_attributes(struct sdp_chopper *chop, struct sdp_media * goto strip; // hack/workaround: always remove a=mid break; + case ATTR_RTPMAP: + if (media->rtp_payload_types_prefs.length == 0) + break; // legacy protocol or usage error + if (!g_hash_table_lookup(media->rtp_payload_types, + &attr->u.rtpmap.rtp_pt.payload_type)) + goto strip; + break; + + case ATTR_FMTP: + if (media->rtp_payload_types_prefs.length == 0) + break; // legacy protocol or usage error + if (!g_hash_table_lookup(media->rtp_payload_types, + &attr->u.fmtp.payload_type)) + goto strip; + break; + default: break; } @@ -1951,6 +2013,8 @@ int sdp_replace(struct sdp_chopper *chop, GQueue *sessions, struct call_monologu goto error; if (replace_transport_protocol(chop, sdp_media, call_media)) goto error; + if (replace_codec_list(chop, sdp_media, call_media)) + goto error; if (sdp_media->connection.parsed) { if (replace_network_address(chop, &sdp_media->connection.address, ps, diff --git a/utils/rtpengine-ng-client b/utils/rtpengine-ng-client index b99dd6025..f778d5ce2 100755 --- a/utils/rtpengine-ng-client +++ b/utils/rtpengine-ng-client @@ -44,6 +44,8 @@ GetOptions( 'reset' => \$options{'reset'}, 'port-latching' => \$options{'port latching'}, 'media-address=s' => \$options{'media address'}, + 'codec-strip=s@' => \$options{'codec-strip'}, + 'flags=s@' => \$options{'flags'}, ) or die; my $cmd = shift(@ARGV) or die; @@ -70,6 +72,12 @@ if (defined($options{direction})) { $options{direction} =~ /(.*),(.*)/ or die; $packet{direction} = [$1,$2]; } +if ($options{'codec-strip'} && @{$options{'codec-strip'}}) { + $packet{codec}{strip} = $options{'codec-strip'}; +} +if ($options{'flags'} && @{$options{'flags'}}) { + push(@{$packet{flags}}, @{$options{'flags'}}); +} if (defined($options{sdp})) { $packet{sdp} = $options{sdp}; From d31fb36f6edc3ffabeaf59e6f8c27e92a5349d0e Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Thu, 4 Jan 2018 14:16:32 -0500 Subject: [PATCH 62/65] TT#30403 parse and retain a=fmtp infos Change-Id: I81b2afdfac7f65833fa5260add823fcf7680c879 --- daemon/call.c | 1 + daemon/redis.c | 17 ++++++++++++----- daemon/sdp.c | 24 ++++++++++++++++++------ lib/rtplib.h | 1 + 4 files changed, 32 insertions(+), 11 deletions(-) diff --git a/daemon/call.c b/daemon/call.c index a9da7d5c5..a548fbc06 100644 --- a/daemon/call.c +++ b/daemon/call.c @@ -1441,6 +1441,7 @@ static void __rtp_payload_types(struct call_media *media, GQueue *types, GHashTa call_str_cpy(call, &pt->encoding_with_params, &pt->encoding_with_params); call_str_cpy(call, &pt->encoding, &pt->encoding); call_str_cpy(call, &pt->encoding_parameters, &pt->encoding_parameters); + call_str_cpy(call, &pt->format_parameters, &pt->format_parameters); g_hash_table_replace(media->rtp_payload_types, &pt->payload_type, pt); g_queue_push_tail(&media->rtp_payload_types_prefs, pt); } diff --git a/daemon/redis.c b/daemon/redis.c index 8e2dd14bb..379bee9e4 100644 --- a/daemon/redis.c +++ b/daemon/redis.c @@ -1133,7 +1133,7 @@ static int redis_tags(struct call *c, struct redis_list *tags) { static int rbl_cb_plts(str *s, GQueue *q, struct redis_list *list, void *ptr) { struct rtp_payload_type *pt; - str ptype, enc, clock, parms; + str ptype, enc, clock, enc_parms, fmt_parms; struct call_media *med = ptr; struct call *call = med->call; @@ -1143,7 +1143,12 @@ static int rbl_cb_plts(str *s, GQueue *q, struct redis_list *list, void *ptr) { return -1; if (str_token(&clock, s, '/')) return -1; - parms = *s; + if (str_token(&enc_parms, s, '/')) { + enc_parms = *s; + fmt_parms = STR_EMPTY; + } + else + fmt_parms = *s; // from call.c // XXX remove all the duplicate code @@ -1151,7 +1156,8 @@ static int rbl_cb_plts(str *s, GQueue *q, struct redis_list *list, void *ptr) { pt->payload_type = str_to_ui(&ptype, 0); call_str_cpy(call, &pt->encoding, &enc); pt->clock_rate = str_to_ui(&clock, 0); - call_str_cpy(call, &pt->encoding_parameters, &parms); + call_str_cpy(call, &pt->encoding_parameters, &enc_parms); + call_str_cpy(call, &pt->format_parameters, &fmt_parms); g_hash_table_replace(med->rtp_payload_types, &pt->payload_type, pt); return 0; } @@ -1939,9 +1945,10 @@ char* redis_encode_json(struct call *c) { json_builder_begin_array (builder); for (m = k; m; m = m->next) { pt = m->data; - JSON_ADD_STRING("%u/" STR_FORMAT "/%u/" STR_FORMAT, + JSON_ADD_STRING("%u/" STR_FORMAT "/%u/" STR_FORMAT "/" STR_FORMAT, pt->payload_type, STR_FMT(&pt->encoding), - pt->clock_rate, STR_FMT(&pt->encoding_parameters)); + pt->clock_rate, STR_FMT(&pt->encoding_parameters), + STR_FMT(&pt->format_parameters)); } json_builder_end_array (builder); diff --git a/daemon/sdp.c b/daemon/sdp.c index b0315e2c4..3487ca521 100644 --- a/daemon/sdp.c +++ b/daemon/sdp.c @@ -1104,7 +1104,7 @@ static int fill_endpoint(struct endpoint *ep, const struct sdp_media *media, str static int __rtp_payload_types(struct stream_params *sp, struct sdp_media *media) { - GHashTable *ht; + GHashTable *ht_rtpmap, *ht_fmtp; GQueue *q; GList *ql; struct sdp_attribute *attr; @@ -1114,15 +1114,21 @@ static int __rtp_payload_types(struct stream_params *sp, struct sdp_media *media return 0; /* first go through a=rtpmap and build a hash table of attrs */ - ht = g_hash_table_new(g_int_hash, g_int_equal); + ht_rtpmap = g_hash_table_new(g_int_hash, g_int_equal); q = attr_list_get_by_id(&media->attributes, ATTR_RTPMAP); for (ql = q ? q->head : NULL; ql; ql = ql->next) { struct rtp_payload_type *pt; attr = ql->data; pt = &attr->u.rtpmap.rtp_pt; - g_hash_table_insert(ht, &pt->payload_type, pt); + g_hash_table_insert(ht_rtpmap, &pt->payload_type, pt); + } + // do the same for a=fmtp + ht_fmtp = g_hash_table_new(g_int_hash, g_int_equal); + q = attr_list_get_by_id(&media->attributes, ATTR_FMTP); + for (ql = q ? q->head : NULL; ql; ql = ql->next) { + attr = ql->data; + g_hash_table_insert(ht_fmtp, &attr->u.fmtp.payload_type, &attr->u.fmtp.format_parms_str); } - /* a=fmtp processing would go here */ /* then go through the format list and associate */ for (ql = media->format_list.head; ql; ql = ql->next) { @@ -1139,13 +1145,18 @@ static int __rtp_payload_types(struct stream_params *sp, struct sdp_media *media /* first look in rtpmap for a match, then check RFC types, * else fall back to an "unknown" type */ - ptl = rtp_payload_type(i, ht); + ptl = rtp_payload_type(i, ht_rtpmap); pt = g_slice_alloc0(sizeof(*pt)); if (ptl) *pt = *ptl; else pt->payload_type = i; + + s = g_hash_table_lookup(ht_fmtp, &i); + if (s) + pt->format_parameters = *s; + g_queue_push_tail(&sp->rtp_payload_types, pt); } @@ -1155,7 +1166,8 @@ error: ret = -1; goto out; out: - g_hash_table_destroy(ht); + g_hash_table_destroy(ht_rtpmap); + g_hash_table_destroy(ht_fmtp); return ret; } diff --git a/lib/rtplib.h b/lib/rtplib.h index 3ef82c753..6e525b90e 100644 --- a/lib/rtplib.h +++ b/lib/rtplib.h @@ -21,6 +21,7 @@ struct rtp_payload_type { str encoding; unsigned int clock_rate; str encoding_parameters; + str format_parameters; }; From f625d48ed3e646df12b6cab9d81f893006b1e57c Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Fri, 5 Jan 2018 10:48:33 -0500 Subject: [PATCH 63/65] TT#30403 consolidate dictionary and alias "flags" values handling Change-Id: Ic5f2e84f7482b8c98db8e08603d32955185549f2 --- daemon/call_interfaces.c | 164 +++++++++++++++++++-------------------- 1 file changed, 81 insertions(+), 83 deletions(-) diff --git a/daemon/call_interfaces.c b/daemon/call_interfaces.c index b01b096ff..41aa4ec69 100644 --- a/daemon/call_interfaces.c +++ b/daemon/call_interfaces.c @@ -481,10 +481,9 @@ INLINE void call_bencode_hold_ref(struct call *c, bencode_item_t *bi) { bencode_buffer_destroy_add(bi->buffer, call_release_ref, obj_get(c)); } -INLINE void str_hyphenate(bencode_item_t *it) { +INLINE void str_hyphenate(str *s_ori) { str s; - if (!bencode_get_str(it, &s)) - return; + s = *s_ori; while (s.len) { if (!str_chr_str(&s, &s, ' ')) break; @@ -499,129 +498,127 @@ INLINE char *bencode_get_alt(bencode_item_t *i, const char *one, const char *two return bencode_dictionary_get_str(i, two, out); } -INLINE void ng_sdes_option(struct sdp_ng_flags *out, bencode_item_t *it, unsigned int strip) { - str s; - - if (!bencode_get_str(it, &s)) - return; - str_shift(&s, strip); - - if (!str_cmp(&s, "no") || !str_cmp(&s, "off") || !str_cmp(&s, "disabled") - || !str_cmp(&s, "disable")) +INLINE void ng_sdes_option(struct sdp_ng_flags *out, str *s, void *dummy) { + if (!str_cmp(s, "no") || !str_cmp(s, "off") || !str_cmp(s, "disabled") + || !str_cmp(s, "disable")) out->sdes_off = 1; - else if (!str_cmp(&s, "unencrypted_srtp") || !str_cmp(&s, "UNENCRYPTED_SRTP")) + else if (!str_cmp(s, "unencrypted_srtp") || !str_cmp(s, "UNENCRYPTED_SRTP")) out->sdes_unencrypted_srtp = 1; - else if (!str_cmp(&s, "unencrypted_srtcp") || !str_cmp(&s, "UNENCRYPTED_SRTCP")) + else if (!str_cmp(s, "unencrypted_srtcp") || !str_cmp(s, "UNENCRYPTED_SRTCP")) out->sdes_unencrypted_srtcp = 1; - else if (!str_cmp(&s, "unauthenticated_srtp") || !str_cmp(&s, "UNAUTHENTICATED_SRTP")) + else if (!str_cmp(s, "unauthenticated_srtp") || !str_cmp(s, "UNAUTHENTICATED_SRTP")) out->sdes_unauthenticated_srtp = 1; - else if (!str_cmp(&s, "encrypted_srtp") || !str_cmp(&s, "ENCRYPTED_SRTP")) + else if (!str_cmp(s, "encrypted_srtp") || !str_cmp(s, "ENCRYPTED_SRTP")) out->sdes_encrypted_srtp = 1; - else if (!str_cmp(&s, "encrypted_srtcp") || !str_cmp(&s, "ENCRYPTED_SRTCP")) + else if (!str_cmp(s, "encrypted_srtcp") || !str_cmp(s, "ENCRYPTED_SRTCP")) out->sdes_encrypted_srtcp = 1; - else if (!str_cmp(&s, "authenticated_srtp") || !str_cmp(&s, "AUTHENTICATED_SRTP")) + else if (!str_cmp(s, "authenticated_srtp") || !str_cmp(s, "AUTHENTICATED_SRTP")) out->sdes_authenticated_srtp = 1; else ilog(LOG_WARN, "Unknown 'SDES' flag encountered: '"STR_FORMAT"'", - STR_FMT(&s)); + STR_FMT(s)); } static void call_ng_flags_list(struct sdp_ng_flags *out, bencode_item_t *input, const char *key, - void (*callback)(struct sdp_ng_flags *, bencode_item_t *, void *), void *parm) + void (*callback)(struct sdp_ng_flags *, str *, void *), void *parm) { bencode_item_t *list, *it; + str s; if ((list = bencode_dictionary_get_expect(input, key, BENCODE_LIST))) { - for (it = list->child; it; it = it->sibling) - callback(out, it, parm); + for (it = list->child; it; it = it->sibling) { + if (!bencode_get_str(it, &s)) + continue; + callback(out, &s, parm); + } } } -static void call_ng_flags_sdes(struct sdp_ng_flags *out, bencode_item_t *it, void *dummy) { - ng_sdes_option(out, it, 0); -} -static void call_ng_flags_rtcp_mux(struct sdp_ng_flags *out, bencode_item_t *it, void *dummy) { - if (!bencode_strcmp(it, "offer")) +static void call_ng_flags_rtcp_mux(struct sdp_ng_flags *out, str *s, void *dummy) { + if (!str_cmp(s, "offer")) out->rtcp_mux_offer = 1; - else if (!bencode_strcmp(it, "require")) + else if (!str_cmp(s, "require")) out->rtcp_mux_require = 1; - else if (!bencode_strcmp(it, "demux")) + else if (!str_cmp(s, "demux")) out->rtcp_mux_demux = 1; - else if (!bencode_strcmp(it, "accept")) + else if (!str_cmp(s, "accept")) out->rtcp_mux_accept = 1; - else if (!bencode_strcmp(it, "reject")) + else if (!str_cmp(s, "reject")) out->rtcp_mux_reject = 1; else - ilog(LOG_WARN, "Unknown 'rtcp-mux' flag encountered: '"BENCODE_FORMAT"'", - BENCODE_FMT(it)); + ilog(LOG_WARN, "Unknown 'rtcp-mux' flag encountered: '" STR_FORMAT "'", + STR_FMT(s)); } -static void call_ng_flags_replace(struct sdp_ng_flags *out, bencode_item_t *it, void *dummy) { - str_hyphenate(it); - if (!bencode_strcmp(it, "origin")) +static void call_ng_flags_replace(struct sdp_ng_flags *out, str *s, void *dummy) { + str_hyphenate(s); + if (!str_cmp(s, "origin")) out->replace_origin = 1; - else if (!bencode_strcmp(it, "session-connection")) + else if (!str_cmp(s, "session-connection")) out->replace_sess_conn = 1; else - ilog(LOG_WARN, "Unknown 'replace' flag encountered: '"BENCODE_FORMAT"'", - BENCODE_FMT(it)); + ilog(LOG_WARN, "Unknown 'replace' flag encountered: '" STR_FORMAT "'", + STR_FMT(s)); } -static void call_ng_flags_codec_list(struct sdp_ng_flags *out, bencode_item_t *it, void *qp) { - str *s; - s = g_slice_alloc(sizeof(*s)); - if (!bencode_get_str(it, s)) { - g_slice_free1(sizeof(*s), s); - return; - } - g_queue_push_tail((GQueue *) qp, s); +static void call_ng_flags_codec_list(struct sdp_ng_flags *out, str *s, void *qp) { + str *s_copy; + s_copy = g_slice_alloc(sizeof(*s_copy)); + *s_copy = *s; + g_queue_push_tail((GQueue *) qp, s_copy); } -static void call_ng_flags_codec_ht_strip(bencode_item_t *it, GHashTable *ht, unsigned int strip) { - str *s; - s = g_slice_alloc(sizeof(*s)); - if (!bencode_get_str(it, s)) { - g_slice_free1(sizeof(*s), s); - return; - } - str_shift(s, strip); - g_hash_table_replace(ht, s, s); +static void call_ng_flags_codec_ht(struct sdp_ng_flags *out, str *s, void *htp) { + str *s_copy; + s_copy = g_slice_alloc(sizeof(*s_copy)); + *s_copy = *s; + g_hash_table_replace((GHashTable *) htp, s_copy, s_copy); } -static void call_ng_flags_codec_ht(struct sdp_ng_flags *out, bencode_item_t *it, void *htp) { - call_ng_flags_codec_ht_strip(it, htp, 0); +// helper to alias values from other dictionaries into the "flags" dictionary +INLINE int call_ng_flags_prefix(struct sdp_ng_flags *out, str *s_ori, const char *prefix, + void (*cb)(struct sdp_ng_flags *, str *, void *), void *ptr) +{ + size_t len = strlen(prefix); + str s = *s_ori; + if (len > 0) + if (str_shift_cmp(&s, prefix)) + return 0; + cb(out, &s, ptr); + return 1; } -static void call_ng_flags_flags(struct sdp_ng_flags *out, bencode_item_t *it, void *dummy) { - if (it->type != BENCODE_STRING) - return; +static void call_ng_flags_flags(struct sdp_ng_flags *out, str *s, void *dummy) { + str_hyphenate(s); - str_hyphenate(it); - - if (!bencode_strcmp(it, "trust-address")) + if (!str_cmp(s, "trust-address")) out->trust_address = 1; - else if (!bencode_strcmp(it, "SIP-source-address")) + else if (!str_cmp(s, "SIP-source-address")) out->trust_address = 0; - else if (!bencode_strcmp(it, "asymmetric")) + else if (!str_cmp(s, "asymmetric")) out->asymmetric = 1; - else if (!bencode_strcmp(it, "no-redis-update")) + else if (!str_cmp(s, "no-redis-update")) out->no_redis_update = 1; - else if (!bencode_strcmp(it, "unidirectional")) + else if (!str_cmp(s, "unidirectional")) out->unidirectional = 1; - else if (!bencode_strcmp(it, "strict-source")) + else if (!str_cmp(s, "strict-source")) out->strict_source = 1; - else if (!bencode_strcmp(it, "media-handover")) + else if (!str_cmp(s, "media-handover")) out->media_handover = 1; - else if (!bencode_strcmp(it, "reset")) + else if (!str_cmp(s, "reset")) out->reset = 1; - // XXX unify these - else if (it->iov[1].iov_len >= 5 && !memcmp(it->iov[1].iov_base, "SDES-", 5)) - ng_sdes_option(out, it, 5); - else if (it->iov[1].iov_len >= 12 && !memcmp(it->iov[1].iov_base, "codec-strip-", 12)) - call_ng_flags_codec_ht_strip(it, out->codec_strip, 12); - else if (!bencode_strcmp(it, "port-latching")) + else if (!str_cmp(s, "port-latching")) out->port_latching = 1; - else if (!bencode_strcmp(it, "record-call")) + else if (!str_cmp(s, "record-call")) out->record_call = 1; - else if (!bencode_strcmp(it, "no-rtcp-attribute")) + else if (!str_cmp(s, "no-rtcp-attribute")) out->no_rtcp_attr = 1; - else - ilog(LOG_WARN, "Unknown flag encountered: '"BENCODE_FORMAT"'", - BENCODE_FMT(it)); + else { + // handle values aliases from other dictionaries + if (call_ng_flags_prefix(out, s, "SDES-", ng_sdes_option, NULL)) + return; + if (call_ng_flags_prefix(out, s, "codec-strip-", call_ng_flags_codec_ht, out->codec_strip)) + return; + if (call_ng_flags_prefix(out, s, "codec-offer-", call_ng_flags_codec_list, &out->codec_offer)) + return; + + ilog(LOG_WARN, "Unknown flag encountered: '" STR_FORMAT "'", + STR_FMT(s)); + } } static void call_ng_process_flags(struct sdp_ng_flags *out, bencode_item_t *input) { bencode_item_t *list, *it, *dict; @@ -678,7 +675,7 @@ static void call_ng_process_flags(struct sdp_ng_flags *out, bencode_item_t *inpu call_ng_flags_list(out, input, "rtcp-mux", call_ng_flags_rtcp_mux, NULL); /* XXX module still needs to support this list */ - call_ng_flags_list(out, input, "SDES", call_ng_flags_sdes, NULL); + call_ng_flags_list(out, input, "SDES", ng_sdes_option, NULL); bencode_get_alt(input, "transport-protocol", "transport protocol", &out->transport_protocol_str); out->transport_protocol = transport_protocol(&out->transport_protocol_str); @@ -690,6 +687,7 @@ static void call_ng_process_flags(struct sdp_ng_flags *out, bencode_item_t *inpu bencode_dictionary_get_str(input, "metadata", &out->metadata); if ((dict = bencode_dictionary_get_expect(input, "codec", BENCODE_DICTIONARY))) { + /* XXX module still needs to support these */ call_ng_flags_list(out, dict, "strip", call_ng_flags_codec_ht, out->codec_strip); call_ng_flags_list(out, dict, "offer", call_ng_flags_codec_list, &out->codec_offer); } From 2540c5d501b8fb98a3b972cbc69b2af34a84bffb Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Fri, 5 Jan 2018 11:25:19 -0500 Subject: [PATCH 64/65] TT#30403 support codec-offer only codecs from the original list for now Change-Id: I884775a5b337ed3533972f4361ecb50e329b126e --- README.md | 13 ++++++++++ daemon/call.c | 52 ++++++++++++++++++++++++++++----------- utils/rtpengine-ng-client | 4 +++ 3 files changed, 55 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index edff85a05..443996d34 100644 --- a/README.md +++ b/README.md @@ -1193,6 +1193,19 @@ Optionally included keys are: an `a=rtpmap` attribute, or can be from the list of RFC-defined codecs. Examples are `PCMU`, `opus`, or `telephone-event`. + As a special keyword, `all` can be used to remove all codecs, except the ones + that should explicitly offered (see below). Note that it is an error to strip + all codecs and leave none that could be offered. In this case, the original + list of codecs will be left unchanged. + + * `offer` + + Contains a list of strings. Each string is the name of a codec that should be + included in the list of codecs offered. This is primarily useful to block all + codecs (`strip -> all`) except the ones given in the `offer` whitelist. + Currently codecs that were not present in the original list of codecs + offered by the client will be ignored. + An example of a complete `offer` request dictionary could be (SDP body abbreviated): diff --git a/daemon/call.c b/daemon/call.c index a548fbc06..ed1580da5 100644 --- a/daemon/call.c +++ b/daemon/call.c @@ -1419,32 +1419,56 @@ static void __dtls_logic(const struct sdp_ng_flags *flags, MEDIA_SET(other_media, DTLS); } -static void __rtp_payload_types(struct call_media *media, GQueue *types, GHashTable *strip) { - struct rtp_payload_type *pt; +static void __rtp_payload_type_add(struct call_media *media, struct rtp_payload_type *pt) { struct call *call = media->call; - static const str __all = STR_CONST_INIT("all"); + /* we must duplicate the contents */ + call_str_cpy(call, &pt->encoding_with_params, &pt->encoding_with_params); + call_str_cpy(call, &pt->encoding, &pt->encoding); + call_str_cpy(call, &pt->encoding_parameters, &pt->encoding_parameters); + call_str_cpy(call, &pt->format_parameters, &pt->format_parameters); + g_hash_table_replace(media->rtp_payload_types, &pt->payload_type, pt); + g_queue_push_tail(&media->rtp_payload_types_prefs, pt); +} + +static void __rtp_payload_types(struct call_media *media, GQueue *types, GHashTable *strip, + const GQueue *offer) +{ + struct rtp_payload_type *pt; + static const str str_all = STR_CONST_INIT("all"); + GHashTable *removed = g_hash_table_new_full(str_hash, str_equal, NULL, __payload_type_free); + int remove_all = 0; // start fresh g_queue_clear(&media->rtp_payload_types_prefs); + if (strip && g_hash_table_lookup(strip, &str_all)) + remove_all = 1; + /* we steal the entire list to avoid duplicate allocs */ while ((pt = g_queue_pop_head(types))) { // codec stripping if (strip) { - if (g_hash_table_lookup(strip, &pt->encoding) - || g_hash_table_lookup(strip, &__all)) { - __payload_type_free(pt); + if (remove_all || g_hash_table_lookup(strip, &pt->encoding)) { + g_hash_table_replace(removed, &pt->encoding, pt); continue; } } - /* we must duplicate the contents */ - call_str_cpy(call, &pt->encoding_with_params, &pt->encoding_with_params); - call_str_cpy(call, &pt->encoding, &pt->encoding); - call_str_cpy(call, &pt->encoding_parameters, &pt->encoding_parameters); - call_str_cpy(call, &pt->format_parameters, &pt->format_parameters); - g_hash_table_replace(media->rtp_payload_types, &pt->payload_type, pt); - g_queue_push_tail(&media->rtp_payload_types_prefs, pt); + __rtp_payload_type_add(media, pt); } + + if (offer) { + // now restore codecs that have been removed, but should be offered + for (GList *l = offer->head; l; l = l->next) { + str *codec = l->data; + pt = g_hash_table_lookup(removed, codec); + if (!pt) + continue; + g_hash_table_steal(removed, codec); + __rtp_payload_type_add(media, pt); + } + } + + g_hash_table_destroy(removed); } static void __ice_start(struct call_media *media) { @@ -1567,7 +1591,7 @@ int monologue_offer_answer(struct call_monologue *other_ml, GQueue *streams, MEDIA_SET(other_media, SDES); } - __rtp_payload_types(media, &sp->rtp_payload_types, flags->codec_strip); + __rtp_payload_types(media, &sp->rtp_payload_types, flags->codec_strip, &flags->codec_offer); /* send and recv are from our POV */ bf_copy_same(&media->media_flags, &sp->sp_flags, diff --git a/utils/rtpengine-ng-client b/utils/rtpengine-ng-client index f778d5ce2..6082bf5ec 100755 --- a/utils/rtpengine-ng-client +++ b/utils/rtpengine-ng-client @@ -45,6 +45,7 @@ GetOptions( 'port-latching' => \$options{'port latching'}, 'media-address=s' => \$options{'media address'}, 'codec-strip=s@' => \$options{'codec-strip'}, + 'codec-offer=s@' => \$options{'codec-offer'}, 'flags=s@' => \$options{'flags'}, ) or die; @@ -75,6 +76,9 @@ if (defined($options{direction})) { if ($options{'codec-strip'} && @{$options{'codec-strip'}}) { $packet{codec}{strip} = $options{'codec-strip'}; } +if ($options{'codec-offer'} && @{$options{'codec-offer'}}) { + $packet{codec}{offer} = $options{'codec-offer'}; +} if ($options{'flags'} && @{$options{'flags'}}) { push(@{$packet{flags}}, @{$options{'flags'}}); } From ca78747c8c122e40c6317772a6a86a54d1e63635 Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Fri, 5 Jan 2018 13:32:31 -0500 Subject: [PATCH 65/65] TT#30405 rename media->rtp_payload_types to ->codecs for brevity Change-Id: If89d774a6ab62855118eec74d21123ba61b48e9e --- daemon/call.c | 18 +++++++++--------- daemon/call.h | 4 ++-- daemon/call_interfaces.c | 1 + daemon/recording.c | 2 +- daemon/redis.c | 8 ++++---- daemon/sdp.c | 13 +++++++------ daemon/ssrc.c | 2 +- 7 files changed, 25 insertions(+), 23 deletions(-) diff --git a/daemon/call.c b/daemon/call.c index ed1580da5..a3f60af96 100644 --- a/daemon/call.c +++ b/daemon/call.c @@ -653,7 +653,7 @@ static struct call_media *__get_media(struct call_monologue *ml, GList **it, con med->call = ml->call; med->index = sp->index; call_str_cpy(ml->call, &med->type, &sp->type); - med->rtp_payload_types = g_hash_table_new_full(g_int_hash, g_int_equal, NULL, __payload_type_free); + med->codecs = g_hash_table_new_full(g_int_hash, g_int_equal, NULL, __payload_type_free); g_queue_push_tail(&ml->medias, med); @@ -950,7 +950,7 @@ void __rtp_stats_update(GHashTable *dst, GHashTable *src) { struct rtp_payload_type *pt; GList *values, *l; - /* "src" is a call_media->rtp_payload_types table, while "dst" is a + /* "src" is a call_media->codecs table, while "dst" is a * packet_stream->rtp_stats table */ values = g_hash_table_get_values(src); @@ -988,7 +988,7 @@ static int __init_streams(struct call_media *A, struct call_media *B, const stru a->rtp_sink = b; PS_SET(a, RTP); /* XXX technically not correct, could be udptl too */ - __rtp_stats_update(a->rtp_stats, A->rtp_payload_types); + __rtp_stats_update(a->rtp_stats, A->codecs); if (sp) { __fill_stream(a, &sp->rtp_endpoint, port_off, sp); @@ -1426,8 +1426,8 @@ static void __rtp_payload_type_add(struct call_media *media, struct rtp_payload_ call_str_cpy(call, &pt->encoding, &pt->encoding); call_str_cpy(call, &pt->encoding_parameters, &pt->encoding_parameters); call_str_cpy(call, &pt->format_parameters, &pt->format_parameters); - g_hash_table_replace(media->rtp_payload_types, &pt->payload_type, pt); - g_queue_push_tail(&media->rtp_payload_types_prefs, pt); + g_hash_table_replace(media->codecs, &pt->payload_type, pt); + g_queue_push_tail(&media->codecs_prefs, pt); } static void __rtp_payload_types(struct call_media *media, GQueue *types, GHashTable *strip, @@ -1439,7 +1439,7 @@ static void __rtp_payload_types(struct call_media *media, GQueue *types, GHashTa int remove_all = 0; // start fresh - g_queue_clear(&media->rtp_payload_types_prefs); + g_queue_clear(&media->codecs_prefs); if (strip && g_hash_table_lookup(strip, &str_all)) remove_all = 1; @@ -1737,7 +1737,7 @@ const struct rtp_payload_type *__rtp_stats_codec(struct call_media *m) { if (atomic64_get(&rtp_s->packets) == 0) goto out; - rtp_pt = rtp_payload_type(rtp_s->payload_type, m->rtp_payload_types); + rtp_pt = rtp_payload_type(rtp_s->payload_type, m->codecs); out: g_list_free(values); @@ -2000,8 +2000,8 @@ static void __call_free(void *p) { crypto_params_cleanup(&md->sdes_out.params); g_queue_clear(&md->streams); g_queue_clear(&md->endpoint_maps); - g_hash_table_destroy(md->rtp_payload_types); - g_queue_clear(&md->rtp_payload_types_prefs); + g_hash_table_destroy(md->codecs); + g_queue_clear(&md->codecs_prefs); g_slice_free1(sizeof(*md), md); } diff --git a/daemon/call.h b/daemon/call.h index ccb679203..f6d88fd86 100644 --- a/daemon/call.h +++ b/daemon/call.h @@ -323,8 +323,8 @@ struct call_media { GQueue streams; /* normally RTP + RTCP */ GQueue endpoint_maps; - GHashTable *rtp_payload_types; - GQueue rtp_payload_types_prefs; + GHashTable *codecs; + GQueue codecs_prefs; volatile unsigned int media_flags; }; diff --git a/daemon/call_interfaces.c b/daemon/call_interfaces.c index 41aa4ec69..c6d760dc1 100644 --- a/daemon/call_interfaces.c +++ b/daemon/call_interfaces.c @@ -585,6 +585,7 @@ INLINE int call_ng_flags_prefix(struct sdp_ng_flags *out, str *s_ori, const char static void call_ng_flags_flags(struct sdp_ng_flags *out, str *s, void *dummy) { str_hyphenate(s); + // XXX use internal hash tables for these if (!str_cmp(s, "trust-address")) out->trust_address = 1; else if (!str_cmp(s, "SIP-source-address")) diff --git a/daemon/recording.c b/daemon/recording.c index 46b83d785..f1047c7af 100644 --- a/daemon/recording.c +++ b/daemon/recording.c @@ -730,7 +730,7 @@ static void setup_media_proc(struct call_media *media) { if (!recording) return; - GList *pltypes = g_hash_table_get_values(media->rtp_payload_types); + GList *pltypes = g_hash_table_get_values(media->codecs); for (GList *l = pltypes; l; l = l->next) { struct rtp_payload_type *pt = l->data; diff --git a/daemon/redis.c b/daemon/redis.c index 379bee9e4..8b4fd7854 100644 --- a/daemon/redis.c +++ b/daemon/redis.c @@ -1158,7 +1158,7 @@ static int rbl_cb_plts(str *s, GQueue *q, struct redis_list *list, void *ptr) { pt->clock_rate = str_to_ui(&clock, 0); call_str_cpy(call, &pt->encoding_parameters, &enc_parms); call_str_cpy(call, &pt->format_parameters, &fmt_parms); - g_hash_table_replace(med->rtp_payload_types, &pt->payload_type, pt); + g_hash_table_replace(med->codecs, &pt->payload_type, pt); return 0; } static int json_medias(struct call *c, struct redis_list *medias, JsonReader *root_reader) { @@ -1173,7 +1173,7 @@ static int json_medias(struct call *c, struct redis_list *medias, JsonReader *ro /* from call.c:__get_media() */ med = uid_slice_alloc0(med, &c->medias); med->call = c; - med->rtp_payload_types = g_hash_table_new_full(g_int_hash, g_int_equal, NULL, + med->codecs = g_hash_table_new_full(g_int_hash, g_int_equal, NULL, __payload_type_free); if (redis_hash_get_unsigned(&med->index, rh, "index")) @@ -1318,7 +1318,7 @@ static int json_link_streams(struct call *c, struct redis_list *streams, return -1; if (ps->media) - __rtp_stats_update(ps->rtp_stats, ps->media->rtp_payload_types); + __rtp_stats_update(ps->rtp_stats, ps->media->codecs); } return 0; @@ -1939,7 +1939,7 @@ char* redis_encode_json(struct call *c) { } json_builder_end_array (builder); - k = g_hash_table_get_values(media->rtp_payload_types); + k = g_hash_table_get_values(media->codecs); snprintf(tmp, sizeof(tmp), "payload_types-%u", media->unique_id); json_builder_set_member_name(builder, tmp); json_builder_begin_array (builder); diff --git a/daemon/sdp.c b/daemon/sdp.c index 3487ca521..8702d6475 100644 --- a/daemon/sdp.c +++ b/daemon/sdp.c @@ -1348,6 +1348,7 @@ error: return -1; } +// XXX iovec can probably be eliminated now and this moved to a regular string builder struct sdp_chopper *sdp_chopper_new(str *input) { struct sdp_chopper *c = g_slice_alloc0(sizeof(*c)); c->input = input; @@ -1454,10 +1455,10 @@ static int replace_transport_protocol(struct sdp_chopper *chop, static int replace_codec_list(struct sdp_chopper *chop, struct sdp_media *media, struct call_media *cm) { - if (cm->rtp_payload_types_prefs.length == 0) + if (cm->codecs_prefs.length == 0) return 0; // legacy protocol or usage error - for (GList *l = cm->rtp_payload_types_prefs.head; l; l = l->next) { + for (GList *l = cm->codecs_prefs.head; l; l = l->next) { struct rtp_payload_type *pt = l->data; chopper_append_printf(chop, " %u", pt->payload_type); } @@ -1702,17 +1703,17 @@ static int process_media_attributes(struct sdp_chopper *chop, struct sdp_media * break; case ATTR_RTPMAP: - if (media->rtp_payload_types_prefs.length == 0) + if (media->codecs_prefs.length == 0) break; // legacy protocol or usage error - if (!g_hash_table_lookup(media->rtp_payload_types, + if (!g_hash_table_lookup(media->codecs, &attr->u.rtpmap.rtp_pt.payload_type)) goto strip; break; case ATTR_FMTP: - if (media->rtp_payload_types_prefs.length == 0) + if (media->codecs_prefs.length == 0) break; // legacy protocol or usage error - if (!g_hash_table_lookup(media->rtp_payload_types, + if (!g_hash_table_lookup(media->codecs, &attr->u.fmtp.payload_type)) goto strip; break; diff --git a/daemon/ssrc.c b/daemon/ssrc.c index db960a62b..ba856350a 100644 --- a/daemon/ssrc.c +++ b/daemon/ssrc.c @@ -251,7 +251,7 @@ void ssrc_receiver_report(struct call_media *m, const struct ssrc_receiver_repor } } - const struct rtp_payload_type *rpt = rtp_payload_type(pt, m->rtp_payload_types); + const struct rtp_payload_type *rpt = rtp_payload_type(pt, m->codecs); if (!rpt) { ilog(LOG_INFO, "Invalid RTP payload type %i, discarding RTCP RR", pt); goto out_nl;