############################################################################ # # Standalone nathelper which can be used with SIP proxy # for transferring RTP data between networks/through a firewall.. # uses Net::SIP::NAT::NATHelper::Server which communicates # with Net::SIP::NAT::NATHelper::Client # # Communication is via sock_stream sockets (unix domain or tcp) and the # commands are are an array-ref consisting of the command name # and the arguments. Commands are 'allocate','activate' and 'close'. # For the arguments of the command and the return values see the # methods in Net::SIP::NATHelper::Base. # For transport the requests and responses will be packet with # Storable::nfreeze and prefixed with a long in network format containing # the length of the freezed packet (necessary, because stream sockets # are used). # ############################################################################ use strict; use warnings; use Getopt::Long qw(:config posix_default bundling); use File::Path; use IO::Socket; use Net::SIP ':debug'; use Net::SIP::NATHelper::Server; ############################################################################ # USAGE ############################################################################ sub usage { print STDERR "ERROR: @_\n" if @_; print STDERR < \$debug, 'h|help' => sub { usage() }, 'R|chroot=s' => \$chroot, ) || usage( 'bad option' ); Net::SIP::Debug->level( $debug || 1 ) if defined $debug; my @sockets = @ARGV; @sockets or usage( "no command sockets" ); my @cfd; foreach my $socket ( @sockets ) { DEBUG( $socket ); if ( $socket =~ m{/} ) { if ( $socket =~m{/$} or -d $socket ) { -d $socket or mkpath( $socket, 0,0700 ) or die $!; $socket = $socket."/socket"; } push @cfd, IO::Socket::UNIX->new( Type => SOCK_STREAM, Local => $socket ) || die $!; } elsif ( $socket =~ m{^(.*):(\d+)$} ) { push @cfd, IO::Socket::INET->new( LocalAddr => $1, LocalPort => $2, Listen => 10, Reuse => 1, ) || die $!; } } # all sockets allocated, now we can change root if necessary if ( $chroot ) { # load Storable::* by eval if chroot eval { Storable::thaw() }; eval { Storable::nfreeze() }; chdir( $chroot ) || die $!; chroot( '.' ) || die $!; } # create wrapper and run Net::SIP::NATHelper::Server->new( @cfd )->loop;