AnyEvent-MP
view release on metacpan or search on metacpan
MP/Transport.pm view on Meta::CPAN
release => $release,
@args,
;
}
=item new AnyEvent::MP::Transport
Create a new transport - usually used via C<mp_server> or C<mp_connect>
instead.
# immediately starts negotiation
my $transport = new AnyEvent::MP::Transport
# mandatory
fh => $filehandle,
local_id => $identifier,
on_recv => sub { receive-callback },
on_error => sub { error-callback },
# optional
on_greet => sub { before sending greeting },
on_greeted => sub { after receiving greeting },
on_connect => sub { successful-connect-callback },
greeting => { key => value },
# tls support
tls_ctx => AnyEvent::TLS,
peername => $peername, # for verification
;
=cut
sub hmac_sha3_512_hex($$) {
Digest::HMAC::hmac_hex $_[1], $_[0], \&Digest::SHA3::sha3_512, 72
}
sub new {
my ($class, %arg) = @_;
my $self = bless \%arg, $class;
{
Scalar::Util::weaken (my $self = $self);
my $config = $AnyEvent::MP::Kernel::CONFIG;
my $timeout = $config->{monitor_timeout};
my $lframing = $config->{framing_format};
my $auth_snd = $config->{auth_offer};
my $auth_rcv = $config->{auth_accept};
$self->{secret} = $config->{secret}
unless exists $self->{secret};
my $secret = $self->{secret};
if (exists $config->{cert}) {
$self->{tls_ctx} = {
sslv2 => 0,
sslv3 => 0,
tlsv1 => 1,
verify => 1,
cert => $config->{cert},
ca_cert => $config->{cert},
verify_require_client_cert => 1,
};
}
$self->{hdl} = new AnyEvent::Handle
+($self->{fh} ? (fh => $self->{fh}) : (connect => $self->{connect})),
autocork => $config->{autocork},
no_delay => exists $config->{nodelay} ? $config->{nodelay} : 1,
keepalive => 1,
on_error => sub {
$self->error ($_[2]);
},
rtimeout => $timeout,
;
my $greeting_kv = $self->{local_greeting} ||= {};
$greeting_kv->{tls} = "1.0" if $self->{tls_ctx};
$greeting_kv->{provider} = "AE-$AnyEvent::MP::Config::VERSION";
$greeting_kv->{peeraddr} = AnyEvent::Socket::format_hostport $self->{peerhost}, $self->{peerport};
my $protocol = $self->{protocol} || "aemp";
# can modify greeting_kv
$_->($self) for $protocol eq "aemp" ? @HOOK_GREET : ();
(delete $self->{on_greet})->($self)
if exists $self->{on_greet};
# send greeting
my $lgreeting1 = "$protocol;$PROTOCOL_VERSION"
. ";$AnyEvent::MP::Kernel::NODE"
. ";" . (join ",", @$auth_rcv)
. ";" . (join ",", @$lframing)
. (join "", map ";$_=$greeting_kv->{$_}", keys %$greeting_kv);
my $lgreeting2 = MIME::Base64::encode_base64 AnyEvent::MP::Kernel::nonce (66), "";
$self->{hdl}->push_write ("$lgreeting1\012$lgreeting2\012");
return unless $self;
# expect greeting
$self->{hdl}->rbuf_max (4 * 1024);
$self->{hdl}->push_read (line => sub {
my $rgreeting1 = $_[1];
my ($aemp, $version, $rnode, $auths, $framings, @kv) = split /;/, $rgreeting1;
$self->{remote_node} = $rnode;
$self->{remote_greeting} = {
map /^([^=]+)(?:=(.*))?/ ? ($1 => $2) : (),
@kv
};
# maybe upgrade the protocol
if ($protocol eq "aemp" and $aemp =~ /^aemp-\w+$/) {
# maybe check for existence of the protocol handler?
$self->{protocol} = $protocol = $aemp;
}
$_->($self) for $protocol eq "aemp" ? @HOOK_GREETED : ();
( run in 1.423 second using v1.01-cache-2.11-cpan-13bb782fe5a )