Created
June 5, 2015 14:21
-
-
Save igorcoding/3e7293548db3c44f3c6f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use 5.010; | |
use strict; | |
use warnings; | |
use AnyEvent; | |
use AnyEvent::Handle; | |
use AnyEvent::Socket; | |
use AnyEvent::Log; | |
use Data::Dumper; | |
$AnyEvent::Log::FILTER->level("info"); | |
sub start_server { | |
my ($server_port, $remote_host, $remote_port) = @_; | |
# say Dumper \@_; | |
my $cb = pop; | |
my %handlers; | |
my $w; $w = AnyEvent->signal ( | |
signal => "INT", | |
cb => sub { | |
undef $w; | |
AE::log info => "Shutting down..."; | |
for my $k (keys %handlers) { | |
$handlers{$k}->destroy; | |
} | |
%handlers = (); | |
undef %handlers; | |
$cb->(); | |
} | |
); | |
tcp_server undef, $server_port, sub { | |
my ($client_fh, $host, $port) = @_; | |
AE::log info => "Client connected: $host:$port."; | |
tcp_connect $remote_host, $remote_port, sub { | |
my ($remote_fh) = @_ or die "$remote_host:$remote_port connect failed: $!"; | |
AE::log info => "Connected to remote host: $remote_host:$remote_port."; | |
my $remote_hdl; | |
my $client_hdl; | |
my $destroy = sub { | |
$remote_hdl->destroy; | |
$client_hdl->destroy; | |
delete @handlers{$remote_hdl, $client_hdl}; | |
}; | |
$remote_hdl = new AnyEvent::Handle( | |
fh => $remote_fh, | |
on_error => sub { | |
my ($hdl, $fatal, $msg) = @_; | |
AE::log error => $msg; | |
$destroy->(); | |
}, | |
on_eof => sub { | |
my $hdl = shift; | |
AE::log info => "Remote host $remote_host:$remote_port disconnected."; | |
$destroy->(); | |
} | |
); | |
$handlers{$remote_hdl} = $remote_hdl; | |
$client_hdl = new AnyEvent::Handle( | |
fh => $client_fh, | |
on_error => sub { | |
my ($hdl, $fatal, $msg) = @_; | |
AE::log error => $msg; | |
$destroy->(); | |
}, | |
on_eof => sub { | |
my $hdl = shift; | |
AE::log info => "Client $host:$port disconnected."; | |
$destroy->(); | |
} | |
); | |
$handlers{$client_hdl} = $client_hdl; | |
$client_hdl->on_read(sub { | |
my $rbuf = $client_hdl->rbuf; | |
$client_hdl->rbuf = ''; | |
$remote_hdl->push_write($rbuf); | |
}); | |
$remote_hdl->on_read(sub { | |
my $rbuf = $remote_hdl->rbuf; | |
$remote_hdl->rbuf = ''; | |
$client_hdl->push_write($rbuf); | |
}); | |
}; | |
}, sub { | |
my ($fh, $thishost, $thisport) = @_; | |
AE::log info => "Listening on $thishost:$thisport."; | |
}; | |
} | |
sub main { | |
my ($port, $remote_host, $remote_port) = @ARGV; | |
my $cv = AE::cv(); | |
start_server($port, $remote_host, $remote_port, sub { | |
$cv->send(); | |
}); | |
$cv->recv(); | |
} | |
main(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment