Created
July 19, 2011 12:08
-
-
Save woosley/1092111 to your computer and use it in GitHub Desktop.
POE port forward
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
#!/usr/bin/perl | |
use strict; | |
use warnings; | |
use Smart::Comments; | |
use POE | |
qw/Wheel::SocketFactory Wheel::ReadWrite Filter::Stream Driver::SysRW/; | |
POE::Session->create( | |
inline_states => { | |
_start => \&_create_socket, | |
on_client_accept => \&client_accept, | |
on_server_error => \&server_error, | |
on_client_error => \&client_error, | |
}, | |
); | |
POE::Kernel->run; | |
sub _create_socket { | |
my ($kernel, $heap) = @_[KERNEL, HEAP]; | |
$heap->{server} = POE::Wheel::SocketFactory->new( | |
BindPort => '10086', | |
Reuse => 1, | |
SuccessEvent => 'on_client_accept', | |
FailureEvent => 'on_server_error', | |
); | |
} | |
sub client_accept { | |
my ($client, $heap) = @_[ARG0, HEAP]; | |
#create new session handle remote host | |
POE::Session->create( | |
inline_states => { | |
_start => \&connect_to_remote, | |
on_remote_connect => \&remote_connected, | |
on_remote_fail => \&remote_fail, | |
forward_out => \&forward_out, | |
forward_in => \&forward_in, | |
remote_flush => \&remote_flush, | |
}, | |
args => [$client], | |
); | |
} | |
sub connect_to_remote { | |
my ($heap, $local_socket) = @_[HEAP, ARG0]; | |
#create socket connect to port we want to forward | |
my $remote = POE::Wheel::SocketFactory->new( | |
RemoteAddress => 'localhost', | |
RemotePort => '80', | |
SuccessEvent => 'on_remote_connect', | |
FailureEvent => 'on_remote_fail', | |
); | |
$heap->{remote} = $remote; | |
# create wheel to read the local socket | |
$heap->{local_wheel} = POE::Wheel::ReadWrite->new( | |
Handle => $local_socket, | |
Filter => POE::Filter::Stream->new(), | |
InputEvent => 'forward_out', | |
); | |
$heap->{local_socket} = $local_socket; | |
} | |
sub remote_connected { | |
my ($heap, $socket) = @_[HEAP, ARG0]; | |
my $wheel = POE::Wheel::ReadWrite->new( | |
Handle => $socket, | |
Driver => POE::Driver::SysRW->new(), | |
Filter => POE::Filter::Stream->new(), | |
InputEvent => 'forward_in', | |
#FlushedEvent => 'remote_flush', | |
); | |
$heap->{remote_wheel} = $wheel; | |
} | |
sub server_erorr { | |
my ($operation, $errnum, $errstr) = @_[ARG0, ARG1, ARG2]; | |
warn "server opeartion: $operation failed with number: $errnum\n\t | |
string: $errstr"; | |
delete $_[HEAP]{server}; | |
} | |
sub client_error { | |
my $id = $_[ARG3]; | |
delete $_[HEAP]{client}{$id}{x}; | |
} | |
sub forward_out { | |
my ($heap, $data, $wheel) = @_[HEAP, ARG0]; | |
$heap->{remote_wheel}->put($data); | |
} | |
sub forward_in { | |
my ($heap, $data) = @_[HEAP, ARG0]; | |
$heap->{local_wheel}->put($data); | |
$_[KERNEL]->yield('remote_flush') | |
} | |
sub port_fail { | |
print "failed to connnect to port\n"; | |
} | |
sub remote_fail { | |
delete $_[HEAP]->{remote}; | |
} | |
sub remote_flush { | |
my $heap = $_[HEAP]; | |
print "remote flushed\n"; | |
print "remote have no remote\n" if !exists $heap->{remote}; | |
if (!$heap->{remote_wheel}->get_driver_out_octets) { | |
$heap->{remote_wheel}->flush; | |
delete $heap->{remote}; | |
$heap->{local_wheel}->put("remote server Disconnected\n"); | |
#delete $heap->{local_wheel}; | |
$heap->{local_socket}->flush ; | |
close $heap->{local_socket}; | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment