use 5.12.0;
use warnings;
use UniEvent;
use Net::SSLeay;
# To launch echo server in ssl mode executed something like
# perl examples/echo-server.plx 1234 examples/ca.pem examples/ca.key
# non-ssl-clients can be tested via:
# - telnet 127.0.0.1 1234
# - nc 127.0.0.1 1234
# - perl examples/echo-client-simple.plx 1234
#
# ssl-clients can be tested via:
# - openssl s_client -connect 127.0.0.1:1234
# - perl examples/echo-client-simple.plx 1234 examples/ca.pem
my ($port, $ca, $key) = @ARGV;
$port //= 9999;
my $server = UniEvent::Tcp->new;
if ($ca && $key) {
require Net::SSLeay;
my $ssl_err = sub {
die Net::SSLeay::ERR_error_string(Net::SSLeay::ERR_get_error);
};
my $serv_ctx = Net::SSLeay::CTX_new();
Net::SSLeay::CTX_use_certificate_file($serv_ctx, $ca, &Net::SSLeay::FILETYPE_PEM) or $ssl_err->();
Net::SSLeay::CTX_use_PrivateKey_file($serv_ctx, $key, &Net::SSLeay::FILETYPE_PEM) or $ssl_err->();
Net::SSLeay::CTX_check_private_key($serv_ctx) or $ssl_err->();
$server->use_ssl($serv_ctx);
}
$server->bind('127.0.0.1', $port);
$server->listen;
say "$$ listening on port $port";
my %clients;
$server->connection_callback(sub {
my ($server, $client, $error_code) = @_;
say "client ", $client->sockaddr, "::", $client->peeraddr, " has connected";
return say "... but with error: $error_code" if $error_code;
$client->eof_callback(sub {
my $client = shift;
say "eof happend with client ($client) ", $client->sockaddr; # xxx
delete $clients{$client->sockaddr};
});
$client->read_callback(sub {
my ($client, $data, $error_code) = @_;
if ($error_code) {
say "error happen with client ", $client->sockaddr, " :: $error_code";
delete $clients{$client->sockaddr};
}
$client->write($data);
say "echoed ", length($data), " bytes back to the ", $client->sockaddr;
});
$clients{$client->sockaddr} = $client;
});
UniEvent::Loop->default_loop->run;