File: nathelper.pl

package info (click to toggle)
libnet-sip-perl 0.838-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,132 kB
  • sloc: perl: 11,988; makefile: 6
file content (105 lines) | stat: -rw-r--r-- 3,357 bytes parent folder | download | duplicates (6)
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
############################################################################
#
#  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 <<USAGE;

NAT Helper for SIP proxy.
Reads cmds from cmd-socket, allocates sockets for RTP and send
information about sockets back to caller, which then rewrites the
SDP bodies in the SIP packets.

$0 [options] cmd-socket+
Options:
    -d|--debug [level]           Enable debugging
    -h|--help                    Help (this info)
    -R|--chroot cage-dir         run chrooted (after opening sockets)

cmd-socket is a UNIX domain socket if it contains '/'. If it points
to an existing directory or contains a trailing '/' cmd-socket will be
interpreted as a directory name and a file 'socket' will be created below
the directory.
If the syntax is 'host:port' a TCP socket will be created.
Multiple cmd-sockets can be specified.

USAGE
    exit( @_ ? 1:0 );
}

############################################################################
#  Read Options
############################################################################

my ($debug,$chroot);
GetOptions(
    'd|debug:i' => \$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;