diff options
author | markster <markster@f38db490-d61c-443f-a65b-d21fe96a405b> | 2004-10-26 04:02:57 +0000 |
---|---|---|
committer | markster <markster@f38db490-d61c-443f-a65b-d21fe96a405b> | 2004-10-26 04:02:57 +0000 |
commit | b561eb0a2d237ca6c387b60011d55fc38bec1c2c (patch) | |
tree | 225dba91590548663e63e9894f9b566cbd208b25 /contrib | |
parent | 3129534c8ac921c46e2ff0805ea742002a02cf4f (diff) |
Add manager proxy (bug #2506)
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@4102 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'contrib')
-rwxr-xr-x | contrib/scripts/managerproxy.pl | 242 |
1 files changed, 242 insertions, 0 deletions
diff --git a/contrib/scripts/managerproxy.pl b/contrib/scripts/managerproxy.pl new file mode 100755 index 000000000..75cef8540 --- /dev/null +++ b/contrib/scripts/managerproxy.pl @@ -0,0 +1,242 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> +<!-- saved from url=(0027)http://homey/simpleproxy.pl --> +<HTML><HEAD> +<META http-equiv=Content-Type content="text/html; charset=utf-8"> +<META content="MSHTML 6.00.2900.2180" name=GENERATOR></HEAD> +<BODY><PRE>#!/usr/bin/perl -w +# +# Simple Asterisk Manager Proxy, Version 1.01 +# 2004-09-26 +# Copyright (c) 2004 David C. Troy <dave@popvox.com> +# +# This code is based on Flash Operator Panel 'op_server.pl' +# by Nicol᳠GudiCopyright (C) 2004. +# +# David C. Troy <dave@popvox.com> +# Nicol᳠Gudinicolas@house.com.ar> +# +# This program is free software, distributed under the terms of +# the GNU General Public License. +# +############################# + +############################# +# Perl Prerequisites +############################# +use strict; +use IO::Socket; +use IO::Select; +use POSIX qw(setsid); + +############################# +# User Configurable Options +############################# +my $manager_host = '127.0.0.1'; +my $listen_port = 1234; +my $manager_port = 5038; +my $manager_user = 'your_username'; +my $manager_secret = 'your_secret'; + +############################# +# Declarations +############################# +my %proxy_clients; +my $O; +my $p; +my @S; +my %blocks; +my $debug = 0; + +$SIG{PIPE} = 'IGNORE'; +$SIG{INT} = 'close_all'; +$SIG{USR1} = 'list_clients'; + +if (defined($ARGV[0])) +{ + if ($ARGV[0] eq "-d") + { + defined(my $pid = fork) or die "Can't Fork: $!"; + exit if $pid; + setsid or die "Can't start a new session: $!"; + open MYPIDFILE, ">/var/run/op_panel.pid"; + print MYPIDFILE $$; + close MYPIDFILE; + } +} else { + $debug = 1; +} + + +# Connect to manager +$p = + new IO::Socket::INET->new( + PeerAddr => $manager_host, + PeerPort => $manager_port, + Proto => "tcp", + Type => SOCK_STREAM + ) + or die "\nCould not connect to Asterisk Manager Port\n"; + +$p->autoflush(1); + +# Login to Manager +send_command_to_manager( "Action: Login\r\nUsername: $manager_user\r\nSecret: $manager_secret\r\n\r\n" ); + +# Start up listener for new connections +my $m = + new IO::Socket::INET(Listen => 1, LocalPort => $listen_port, ReuseAddr => 1) + or die "\nCan't listen to port $listen_port\n"; +$O = new IO::Select(); +$O->add($m); +$O->add($p); +$/ = "\0"; + +sub manager_reconnect() +{ + my $attempt = 1; + my $total_attempts = 60; + + do + { + log_debug("** Attempt reconnection to manager port # $attempt", 16); + $p = + new IO::Socket::INET->new( + PeerAddr => $manager_host, + PeerPort => $manager_port, + Proto => "tcp", + Type => SOCK_STREAM + ); + $attempt++; + if ($attempt > $total_attempts) + { + die("!! Could not reconnect to Asterisk Manager port"); + } + sleep(10); # wait 10 seconds before trying to reconnect + } until $p; + $O->add($p); + send_command_to_manager( + "Action: Login\r\nUsername: $manager_user\r\nSecret: $manager_secret\r\n\r\n" + ); +} + +# Loop, continuously processing new connections, input from those connections, and input from Manager conn +while (1) +{ + while (@S = $O->can_read) + { + foreach (@S) + { + if ($_ == $m) + { + log_debug("** New client connection", 16); + my $C = $m->accept; + $proxy_clients{$C} = \$C; + print "New Connection: $C\n" if $debug; + $O->add($C); + } else { + # It's not a new client connection + my $i; + my $R = sysread($_, $i, 2); # 2048; interleave every two bytes? + if (defined($R) && $R == 0) + { + # Confirm it's really dead by trying to write to it? + my $T = syswrite($_, ' ', 2); # 2048 + if (!defined($T)) + { + # connection went away... + $O->remove($_); + $_->close; + + # If we lost the socket for the Asterisk Mgr, then reconnect + if ($_ == $p) + { + log_debug( + "** Asterisk Manager connection lost!!!!!", + 16); + manager_reconnect(); + } else { + # Remove handle from proxy_clients hash + print "Closed Connection: $_\n" if $debug; + delete $proxy_clients{$_}; + } + } + } + else # Socket is active and we are ready to read something from it + { + $blocks{$_} .= $i; + next if ($blocks{$_} !~ /\r\n\r\n$/); + # do a 'next' unless we have completed a block; we are not ready to continue + + # Process the completed block + # If block is from asterisk, send to clients + if ($_ == $p) { + # block is from asterisk, send to clients + print "asterisk: $_\n$blocks{$_}" if $debug; + my $cnt = 0; + foreach my $client (values %proxy_clients) { + print "writing to $$client...\n" if $debug; + syswrite($$client, $blocks{$_}); + $cnt++; + } + print "sent block to $cnt clients\n" if $debug; + } else { + # Blocks are from clients, send to asterisk + syswrite($p, $blocks{$_}); + print "client: $_\n$blocks{$_}\n" if $debug; + } + delete $blocks{$_}; + + } # end if read succeeded + } # end if new client connection + } # end foreach @S -> can read + } # while can read +} # endless loop + +sub close_all +{ + log_debug("Exiting...", 0); + + foreach my $hd ($O->handles) + { + $O->remove($hd); + close($hd); + } + + exit(0); +} + +sub send_command_to_manager +{ + my $comando = shift; + if (defined $p) + { + my @lineas = split("\r\n", $comando); + foreach my $linea (@lineas) + { + syswrite($p, "$linea\r\n"); + log_debug("-> $linea", 2); + } + log_debug(" ", 2); + syswrite($p, "\r\n"); + } +} + +sub log_debug +{ + my $texto = shift; + $texto =~ s/\0//g; + print "$texto\n" if $debug; +} + +sub list_clients() +{ + my $cnt = 0; + foreach my $client (values %proxy_clients) { + print "client: $$client\n"; + $cnt++; + } + print "$cnt clients.\n\n"; +} + + +</PRE></BODY></HTML> |