ARCv2
view release on metacpan or search on metacpan
lib/Arc/Connection.pm view on Meta::CPAN
package Arc::Connection;
use strict;
use warnings;
use Carp;
use MIME::Base64;
use Arc qw(LOG_AUTH LOG_USER LOG_ERR LOG_CMD LOG_SIDE LOG_DEBUG);
use Authen::SASL;
@Arc::Connection::ISA = qw(Arc);
sub members
{
my $this = shift;
return { %{$this->SUPER::members},
# private:
__sasl => undef, # Authen::SASL Handle
__linequeue => [], # internal line buffer (idea From Net::Cmd)
__partial => "", # a partial line (idea From Net::Cmd)
# protected:
_connection => undef, # IO::Socket for the ARCv2 Connection
_cmdclientsock => undef, # IO::Socket for the command connection (encrypted)
_select => undef, # IO::Select for the ARCv2 Connection
_authenticated => 0, # Are we authenticated
#_sasl => undef, # Authen::SASL::Cyrus Handle
#_saslmech => "", # SASL mechnanism used at authentication
_cmdparameter => undef, # parameter after the command
_expectedcmds => undef, # array, which ARCv2 protocol commands are allowed to come next
_connected => 0, # are we connected
_username => "anonymous", # username extracted from SASL
# public:
protocol => undef, # Which protocol is used (0 = ARC/2.0, 1 = ARC/2.1)
timeout => undef, # timeout for all connections (ARCv2 and command) in seconds
service => undef, # name of the server (for SASL)
};
}
sub _Init
{
my $this = shift;
return $this->_SetError("Initialization failed.") unless $this->SUPER::_Init(@_);
# timeout
# unless (defined $this->{timeout}) {
# $this->Log(LOG_SIDE,"Setting timeout to 30 secs since no time specified.");
# $this->{timeout} = 30;
# }
return $this->_SetError("No service name for SASL authentication specified.")
unless defined $this->{service};
return 1;
}
## initializes command connection. (protocol)
## Starts listen on the Command socket and sends the B<CMDPASV> command.
##out> true if everything went like expected, otherwise false.
##eg> $this->_CommandConnection();
sub _CommandConnection
{
my $this = shift;
my $consock = IO::Socket::INET->new(
Listen => 1,
Proto => 'tcp',
LocalAddr => $this->{_connection}->sockhost,
ReuseAddr => 1,
) || return $this->_SetError("Socket creation for CommandConnection failed.");
unless ($this->_SendCommand("CMDPASV",$consock->sockhost.':'.$consock->sockport)) {
return;
}
my $sel = new IO::Select($consock);
if (my @socks = $sel->can_read(10)) {
foreach my $sock (@socks) {
if ($sock == $consock) {
$this->{_cmdclientsock} = $consock->accept() || last;
return 1;
}
}
} else {
return $this->_SetError("No CommandConnection received (Client died?).");
}
}
## function for reading and writing on the command connection.
## This function is always used by the C<Arc::Connection::Server> to handle
## command data. When calling the C<ProcessCommand> from C<Arc::Connection::Client>
## this function is also used.
## Data is read from the local socket resp. pipe and is written encrypted
## to the network socket. The other side reads the data from network socket,
## decrypts it and writes it to its local socket. This function behaves differently on
## client and server sides, when the local or network socket is closed.
##in> *locfdin, *locfdout
##out> always true
##eg> $this->ReadWriteBinary(*STDIN,*STDOUT);
sub _ReadWriteBinary
{
my $this = shift;
my $locin = shift;
my $locout = shift;
my $client = ref ($this) eq "Arc::Connection::Client";
my $netsock = $this->{_cmdclientsock};
( run in 0.415 second using v1.01-cache-2.11-cpan-39bf76dae61 )