File Coverage

blib/lib/Net/Forward.pm
Criterion Covered Total %
statement 15 59 25.4
branch 0 22 0.0
condition 0 28 0.0
subroutine 5 9 55.5
pod 1 2 50.0
total 21 120 17.5


line stmt bran cond sub pod time code
1             package Net::Forward;
2 1     1   23919 use 5.014002;
  1         4  
  1         39  
3 1     1   6 use strict;
  1         2  
  1         46  
4 1     1   5 use warnings;
  1         12  
  1         41  
5             require Exporter;
6 1     1   954 use IO::Socket;
  1         29586  
  1         5  
7 1     1   1907 use AutoLoader qw(AUTOLOAD);
  1         1553  
  1         5  
8             our @ISA = qw(Exporter IO::Socket);
9             our @EXPORT = qw();
10             our $VERSION = '0.1';
11             sub new{
12 0     0 1   my ($class,$self) = @_;
13 0           return bless $self, $class;
14             }
15             sub activate{
16 0     0 0   my $self = shift;
17 0 0         $self->{Proto} = 'tcp' unless defined $self->{Proto};
18 0           _listen($self->{LocalHost},$self->{LocalPort},$self->{RemoteHost},$self->{RemotePort},$self->{Proto});
19             }
20             sub _listen{
21 0     0     my ($local_host,$local_port,$remote_host,$remote_port,$proto) = @_;
22 0   0       my $server = new IO::Socket::INET (LocalHost => $local_host,
23             LocalPort => $local_port,
24             Proto => $proto,
25             Listen => 1,
26             Reuse => 1) || die qq,Cannot listen on "$local_host:$local_port"\n,;
27 0           while (my $client = $server->accept()) {
28 0           $client->autoflush(1);
29 0 0         if(fork()){
30 0           $client->close();
31             }else{
32 0           $server->close();
33 0   0       _pipe($server,$client,IO::Socket::INET->new(PeerAddr => $remote_host, PeerPort => $remote_port, Proto => $proto, Type => SOCK_STREAM) || die qq,Cannot connect to "$remote_host:$remote_port"\n,);
34 0           exit();
35             }
36             }
37             }
38             sub _pipe{
39 0     0     my($server,$client,$remote) = @_;
40 0           $remote->autoflush();
41 0   0       while($client || $remote) {
42 0           my $rin = "";
43 0 0         vec($rin, fileno($client), 1) = 1 if $client;
44 0 0         vec($rin, fileno($remote), 1) = 1 if $remote;
45 0           my($rout, $eout);
46 0           select($rout = $rin, undef, $eout = $rin, 120);
47 0 0 0       if (!$rout && !$eout) { return; }
  0            
48 0           my $cbuffer = "";
49 0           my $tbuffer = "";
50 0 0 0       if ($client && (vec($eout, fileno($client), 1) || vec($rout, fileno($client), 1))) {
      0        
51 0           my $result = sysread($client, $tbuffer, 1024);
52 0 0 0       if (!defined($result) || !$result) { return; }
  0            
53             }
54 0 0 0       if ($remote && (vec($eout, fileno($remote), 1) || vec($rout, fileno($remote), 1))) {
      0        
55 0           my $result = sysread($remote, $cbuffer, 1024);
56 0 0 0       if (!defined($result) || !$result) { return; }
  0            
57             }
58              
59 0           while (my $len = length($tbuffer)) {
60 0           my $res = syswrite($remote, $tbuffer, $len);
61 0 0         if ($res > 0) { $tbuffer = substr($tbuffer, $res); } else { return; }
  0            
  0            
62             }
63 0           while (my $len = length($cbuffer)) {
64 0           my $res = syswrite($client, $cbuffer, $len);
65 0 0         if ($res > 0) { $cbuffer = substr($cbuffer, $res); } else { return; }
  0            
  0            
66             }
67             }
68             }
69             1;
70             __END__