#!/usr/bin/perl

use 5.022;
use warnings;

use AnyEvent;
use AnyEvent::Socket;
use AnyEvent::Handle;
use Crypter;

use Pod::Usage qw(pod2usage);

$| = 1;

usage() if scalar @ARGV != 5;
my ($password, $local, $port, $remote, $remoteport) = @ARGV;

my $cv = AE::cv;


sub crypt_data {
	my $data = shift;
	my $crypter = new Crypter(password => $password);
	return $crypter->crypt($data);	
}

my @connections;
my $server = tcp_server $local, $port, sub {
	my ($fh, $host, $port) = @_;
	
	my $hdl1;
	my $hdl2;
	
	$hdl1 = AnyEvent::Handle->new (fh => $fh, on_eof => sub {},
		on_read => sub {
			my ($handle) = @_;
			my $data = $handle->rbuf;
			
			$data = crypt_data($data);
			eval {
				$hdl2->push_write($data);
			};
			warn $@ if $@;
		}	
	);

	tcp_connect $remote, $remoteport, sub {
		my ($fh) = @_;
		
		$hdl2 = AnyEvent::Handle->new (
			fh => $fh, 
			on_eof => sub {},
			on_read => sub {
				my ($handle) = @_;
				my $data = $handle->rbuf;
				$data = crypt_data($data);
				eval {
					$hdl1->push_write($data);
				};
				warn $@ if $@;
			}
		);
	};
};

$cv->recv;


sub usage {
	my $file = @_ ? "$_[0]" : (caller)[1];
	open my $handle, '>', \my $output;
	pod2usage -exitval => 'noexit', -input => $file, -output => $handle;
	$output =~ s/^.*\n|\n$//;
	$output =~ s/\n$//g;
	say $output;
	exit;
}

1;

=encoding utf8

=head1 NAME

piped - secured tunnel for a jammers

=head1 SYNOPSIS

    Usage: piped [password] [local] [port] [remote] [remoreport]
    
    Options:
    
        password      Password for Crypter
        local         Bind address
        port          Bind port
        remote        Remote server
        remoteport    Remote port

=head1 AUTHOR

piped developed by Ivan Trunaev, Russia, 2026

Contacts <ivan@trunaev.ru>

=cut
