1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
|
#!/usr/bin/perl
# make sure that RTP and SIP fds are closed after the Objects are no
# no longer needed, even if the connection was not closed cleanly
# -----------------------------------------------------------------------------
# not done with Test::More, because this allocates some unexpected fd, which
# make this test harder
use strict;
use warnings;
do './testlib.pl' || do './t/testlib.pl' || die "no testlib: $@";
use Net::SIP ':all';
my ($ssock,$saddr) = create_socket();
my $tfn = fileno( newfd() );
if ( fileno($ssock) != $tfn-1 ) {
print "1..0 # Platform does not give fds in order fn,fn+1,fn+2...\n";
exit;
} else {
print "1..7\n";
}
my $uas = fork_sub( 'uas' );
my $uac = fork_sub( 'uac' );
fd_grep_ok( 'Listening', $uas );
my $match = fd_grep( qr/allocated \d+ sockets/, $uac );
like( $match, qr/ 1 sockets/, "uac allocated 1 socket for SIP" );
$match = fd_grep( qr/allocated \d+ sockets/, $uac );
like( $match, qr/ 3 sockets/, "uac allocated 2 sockets for RTP" );
$match = fd_grep( qr/allocated \d+ sockets/, $uac );
like( $match, qr/ 1 sockets/, "uac closed RTP socket" );
$match = fd_grep( qr/allocated \d+ sockets/, $uac );
like( $match, qr/ 0 sockets/, "uac closed SIP socket" );
killall();
sub uas {
my $ua = Simple->new( leg => $ssock, from => "sip:uas\@i$saddr" );
$ua->listen;
print "Listening\n";
$ua->loop;
}
sub uac {
( my $caddr = $saddr ) =~s{:\d+}{:0}; # same ip, port will be picked
# for some strange reason on glib2.7 or whatever the cause is this not
# only allocates a new fd, but a pipe too. So just ignore the first fd
# and use the next
my $tfd_ignore = newfd();
my $tfd = newfd();
my $fnbase = fileno($tfd) +1;
my $show_diff = sub {
my $expect = shift;
my $fd = newfd();
my $fn = fileno($fd)-1;
printf "allocated %d sockets %s\n", $fn+1-$fnbase, $fn == $fnbase ? "($fn)" :
$fn > $fnbase ? "($fnbase..$fn)" : "";
system( "lsof -n -p$$" ) if $fn+1-$fnbase != $expect;
};
# this should allocate 1 socket for SIP
my $ua = Simple->new( leg => $caddr, from => "sip:uac\@$caddr" );
$show_diff->(1);
# this should allocate 2 sockets for RTP
my $call = $ua->invite( "sip:uas\@$saddr" );
$show_diff->(3);
# this should close the RTP sockets
$call->cleanup;
$show_diff->(1);
# and this should close the SIP socket too
$ua->cleanup;
$show_diff->(0);
}
sub newfd {
# dup STDOUT to create new fd
open( my $fd,'>&STDOUT' );
return $fd;
}
|