view release on metacpan or search on metacpan
```
## A server
A server Driver uses the same UDP/timer contract:
```perl
my $driver = Net::QUIC::Driver->server(
alpn => 'my-protocol',
certificate_file => 'server-cert.pem',
private_key_file => 'server-key.pem',
send => sub {
my ($datagram) = @_;
send_udp($datagram);
return 1;
},
set_timeout => sub {
my ($seconds) = @_;
replace_timer($seconds);
examples/io-select-echo-server.pl view on Meta::CPAN
1;
}
} @connections;
return;
}
$driver = Net::QUIC::Driver->server(
alpn => $alpn,
certificate_file => $cert_file,
private_key_file => $key_file,
send => sub {
my ($datagram) = @_;
push @udp_out, $datagram;
if (!flush_udp()) {
$writable->add($socket);
return 0;
}
lib/Net/QUIC/Driver.pm view on Meta::CPAN
Other client options are passed to L<Net::QUIC::Endpoint/client>. This includes
session resumption, 0-RTT, address-token reuse, QUIC version selection, and
transport limits.
=head2 server
my $driver = Net::QUIC::Driver->server(
alpn => 'my-protocol',
certificate_file => 'server-cert.pem',
private_key_file => 'server-key.pem',
send => sub { ... },
set_timeout => sub { ... },
);
Creates a server Driver.
One server Driver can manage many QUIC Connections on one UDP socket.
Pull newly created Connections with L</next_connection>.
lib/Net/QUIC/Endpoint.pm view on Meta::CPAN
return bless {
mode => 'client',
connection => $connection,
}, $class;
}
sub server {
my ($class, %args) = @_;
for my $name (qw(alpn certificate_file private_key_file)) {
croak "missing required $name argument"
if !defined $args{$name};
}
my $server_tls = Net::QUIC::_ServerTLS->_new(
$args{certificate_file},
$args{private_key_file},
$args{accept_early_data} ? 1 : 0,
);
my $transport = $class->_transport_config(delete $args{transport});
my $preferred_address = delete $args{preferred_address};
my $preferred_version = delete $args{preferred_version};
$preferred_version = $class->_quic_version(
$preferred_version,
'preferred_version',
lib/Net/QUIC/Endpoint.pm view on Meta::CPAN
See L<Net::QUIC::Connection/QUIC DATAGRAM>.
The Stream values are flow-control starting values, not lifetime byte or
stream limits.
=head2 server
my $endpoint = Net::QUIC::Endpoint->server(
alpn => 'my-protocol',
certificate_file => 'server-cert.pem',
private_key_file => 'server-key.pem',
);
Creates a server Endpoint.
One server Endpoint can manage many QUIC Connections.
Required options are:
alpn
certificate_file
private_key_file
=head3 Address validation
To require a new client to prove that it can receive packets at its source
address:
validate_address => 1
A new client may receive QUIC Retry before a full Connection is created.
t/06-server-endpoint.t view on Meta::CPAN
pack_sockaddr_in(40003, inet_aton('127.0.0.1')),
pack_sockaddr_in(40004, inet_aton('127.0.0.1')),
);
my $alpn = 'net-quic-server-endpoint-test';
my $cert_file = "$FindBin::Bin/data/server-cert.pem";
my $key_file = "$FindBin::Bin/data/server-key.pem";
my $server = Net::QUIC::Endpoint->server(
alpn => $alpn,
certificate_file => $cert_file,
private_key_file => $key_file,
);
$server->receive_datagram(
"not a QUIC packet",
$server_local,
$client_local[0],
);
ok(!defined($server->next_connection), 'invalid datagram does not create a connection');
my @client = map {
t/07-server-front-door.t view on Meta::CPAN
peer => $server_local,
alpn => $alpn,
server_name => 'localhost',
ca_file => $cert_file,
);
}
my $vn_server = Net::QUIC::Endpoint->server(
alpn => $alpn,
certificate_file => $cert_file,
private_key_file => $key_file,
);
my $vn_client = make_client();
my $initial = $vn_client->next_datagram;
ok(defined($initial), 'client produces Initial for version negotiation test');
my $unsupported = $initial->data;
substr($unsupported, 1, 4, pack('N', 0x1a2a3a4a));
$vn_server->receive_datagram(
t/07-server-front-door.t view on Meta::CPAN
'Version Negotiation advertises QUIC v1',
);
ok(
!defined($vn_server->next_datagram),
'Version Negotiation response is drained from stateless queue',
);
my $server = Net::QUIC::Endpoint->server(
alpn => $alpn,
certificate_file => $cert_file,
private_key_file => $key_file,
validate_address => 1,
);
my $client = make_client();
$initial = $client->next_datagram;
ok(defined($initial), 'client produces Initial for Retry test');
$server->receive_datagram(
$initial->data,
$server_local,
t/08-certificate-verification.t view on Meta::CPAN
qr/unable to load client CA file/,
'bad CA file is rejected during client construction',
);
sub run_handshake {
my (%args) = @_;
my $server = Net::QUIC::Endpoint->server(
alpn => defined($args{server_alpn}) ? $args{server_alpn} : $alpn,
certificate_file => $cert_file,
private_key_file => $key_file,
);
my %client_args = (
local => $client_local,
peer => $server_local,
alpn => defined($args{client_alpn}) ? $args{client_alpn} : $alpn,
server_name => $args{server_name},
);
$client_args{ca_file} = $args{ca_file}
if defined $args{ca_file};
t/09-connection-retirement.t view on Meta::CPAN
my $server_local = pack_sockaddr_in(4439, inet_aton('127.0.0.1'));
my $client_local = pack_sockaddr_in(40008, inet_aton('127.0.0.1'));
my $alpn = 'net-quic-connection-retirement-test';
my $cert_file = "$FindBin::Bin/data/server-cert.pem";
my $key_file = "$FindBin::Bin/data/server-key.pem";
my $server = Net::QUIC::Endpoint->server(
alpn => $alpn,
certificate_file => $cert_file,
private_key_file => $key_file,
);
my $client = Net::QUIC::Endpoint->client(
local => $client_local,
peer => $server_local,
alpn => $alpn,
server_name => 'localhost',
ca_file => $cert_file,
);
t/10-shared-server-tls.t view on Meta::CPAN
my $dir = tempdir(CLEANUP => 1);
my $cert_file = "$dir/server-cert.pem";
my $key_file = "$dir/server-key.pem";
copy_file($source_cert, $cert_file);
copy_file($source_key, $key_file);
my $server = Net::QUIC::Endpoint->server(
alpn => $alpn,
certificate_file => $cert_file,
private_key_file => $key_file,
);
ok(unlink($cert_file), 'certificate file can be removed after server construction');
ok(unlink($key_file), 'private key file can be removed after server construction');
my @client = map {
Net::QUIC::Endpoint->client(
local => $_,
peer => $server_local,
alpn => $alpn,
t/10-shared-server-tls.t view on Meta::CPAN
ok($client[0]->connection->ready, 'first client handshake completes');
ok($client[1]->connection->ready, 'second client handshake completes');
ok($accepted[0]->ready, 'first server connection uses shared TLS context');
ok($accepted[1]->ready, 'second server connection uses shared TLS context');
like(
dies {
Net::QUIC::Endpoint->server(
alpn => $alpn,
certificate_file => "$dir/missing-cert.pem",
private_key_file => "$dir/missing-key.pem",
);
},
qr/unable to load Picotls server certificate/,
'missing certificate fails when Endpoint is constructed',
);
my $valid_cert = "$dir/valid-cert.pem";
copy_file($source_cert, $valid_cert);
like(
dies {
Net::QUIC::Endpoint->server(
alpn => $alpn,
certificate_file => $valid_cert,
private_key_file => "$dir/missing-key.pem",
);
},
qr/unable to open Picotls server private key/,
'missing private key fails when Endpoint is constructed',
);
done_testing;
t/11-stateless-reset.t view on Meta::CPAN
my $server_local = pack_sockaddr_in(4441, inet_aton('127.0.0.1'));
my $client_local = pack_sockaddr_in(40010, inet_aton('127.0.0.1'));
my $alpn = 'net-quic-stateless-reset-test';
my $cert_file = "$FindBin::Bin/data/server-cert.pem";
my $key_file = "$FindBin::Bin/data/server-key.pem";
sub make_server {
return Net::QUIC::Endpoint->server(
alpn => $alpn,
certificate_file => $cert_file,
private_key_file => $key_file,
);
}
sub make_client {
return Net::QUIC::Endpoint->client(
local => $client_local,
peer => $server_local,
alpn => $alpn,
server_name => 'localhost',
ca_file => $cert_file,
t/15-driver-loopback.t view on Meta::CPAN
ok(defined($server_local), 'server UDP socket has a local address');
ok(defined($client_local), 'client UDP socket has a local address');
my ($server_deadline, $client_deadline);
my ($server_tx, $client_tx) = (0, 0);
my ($server_rx, $client_rx) = (0, 0);
my $server = Net::QUIC::Driver->server(
alpn => $alpn,
certificate_file => $cert_file,
private_key_file => $key_file,
send => sub {
my ($datagram) = @_;
return send_datagram($server_socket, $datagram, \$server_tx);
},
set_timeout => sub {
my ($after) = @_;
$server_deadline = defined($after)
? time() + $after
t/16-stream-limits.t view on Meta::CPAN
my $server_local = pack_sockaddr_in(4450, inet_aton('127.0.0.1'));
my $client_local = pack_sockaddr_in(40050, inet_aton('127.0.0.1'));
my $alpn = 'net-quic-stream-limit-test';
my $cert_file = "$FindBin::Bin/data/server-cert.pem";
my $key_file = "$FindBin::Bin/data/server-key.pem";
my $server = Net::QUIC::Endpoint->server(
alpn => $alpn,
certificate_file => $cert_file,
private_key_file => $key_file,
);
my $client = Net::QUIC::Endpoint->client(
local => $client_local,
peer => $server_local,
alpn => $alpn,
server_name => 'localhost',
ca_file => $cert_file,
);
t/17-transport-tuning.t view on Meta::CPAN
is(
$short_handshake->connection->close_info->{type},
'handshake',
'configured handshake timeout becomes a handshake close outcome',
);
my $server = Net::QUIC::Endpoint->server(
alpn => $alpn,
certificate_file => $cert_file,
private_key_file => $key_file,
transport => {
max_bidi_streams => 1,
max_uni_streams => 1,
},
);
my $client = make_client();
my $accepted;
sub pump_pair {
t/18-destructive-lifecycle.t view on Meta::CPAN
sub make_ready_pair {
my ($port, $name) = @_;
my $server_local = pack_sockaddr_in($port, inet_aton('127.0.0.1'));
my $client_local = pack_sockaddr_in($port + 10000, inet_aton('127.0.0.1'));
my $alpn = "net-quic-lifecycle-$name";
my $server = Net::QUIC::Endpoint->server(
alpn => $alpn,
certificate_file => $cert_file,
private_key_file => $key_file,
);
my $client = Net::QUIC::Endpoint->client(
local => $client_local,
peer => $server_local,
alpn => $alpn,
server_name => 'localhost',
ca_file => $cert_file,
);
t/18-destructive-lifecycle.t view on Meta::CPAN
return $progress;
}
subtest 'staggered multi-connection retirement' => sub {
my $server_local = pack_sockaddr_in(4463, inet_aton('127.0.0.1'));
my $alpn = 'net-quic-lifecycle-many';
my $server = Net::QUIC::Endpoint->server(
alpn => $alpn,
certificate_file => $cert_file,
private_key_file => $key_file,
);
my @locals = map {
pack_sockaddr_in(41000 + $_, inet_aton('127.0.0.1'))
} 0 .. 2;
my @clients = map {
Net::QUIC::Endpoint->client(
local => $locals[$_],
peer => $server_local,
t/19-local-address.t view on Meta::CPAN
ca_file => $cert_file,
);
},
qr/local must be a concrete IPv4 or IPv6 address/,
'client rejects an IPv4 wildcard as its QUIC local path',
);
my $server = Net::QUIC::Endpoint->server(
alpn => 'local-address-test',
certificate_file => $cert_file,
private_key_file => $key_file,
);
like(
dies {
$server->receive_datagram(
"not a QUIC packet",
$wildcard_v4,
$loopback_v4,
);
},
t/19-local-address.t view on Meta::CPAN
$loopback_v4,
$loopback_v4,
);
},
'server receive accepts a concrete IPv4 local path',
);
my $driver = Net::QUIC::Driver->server(
alpn => 'local-address-test',
certificate_file => $cert_file,
private_key_file => $key_file,
send => sub { 1 },
set_timeout => sub { return },
);
$driver->start;
like(
dies {
$driver->receive(
"not a QUIC packet",
t/19-local-address.t view on Meta::CPAN
},
qr/local must be a concrete IPv4 or IPv6 address/,
'client rejects an IPv6 wildcard as its QUIC local path',
);
ok(
!dies {
my $ipv6_server = Net::QUIC::Endpoint->server(
alpn => 'local-address-test',
certificate_file => $cert_file,
private_key_file => $key_file,
);
$ipv6_server->receive_datagram(
"not a QUIC packet",
$loopback_v6,
$loopback_v6,
);
},
'server receive accepts a concrete IPv6 local path',
);
t/24-preferred-address.t view on Meta::CPAN
my $alpn = 'net-quic-preferred-address-test';
my $cert_file = "$FindBin::Bin/data/server-cert.pem";
my $key_file = "$FindBin::Bin/data/server-key.pem";
my $saw_client_to_preferred = 0;
my $saw_server_from_preferred = 0;
my $server = Net::QUIC::Endpoint->server(
alpn => $alpn,
certificate_file => $cert_file,
private_key_file => $key_file,
preferred_address => $server_preferred,
);
my $client = Net::QUIC::Endpoint->client(
local => $client_local,
peer => $server_initial,
alpn => $alpn,
server_name => 'localhost',
ca_file => $cert_file,
);
t/25-new-token.t view on Meta::CPAN
my $client_a = pack_sockaddr_in(40200, inet_aton('127.0.0.1'));
my $client_b = pack_sockaddr_in(40201, inet_aton('127.0.0.1'));
my $client_wrong_ip = pack_sockaddr_in(40202, inet_aton('127.0.0.2'));
my $alpn = 'net-quic-new-token-test';
my $cert_file = "$FindBin::Bin/data/server-cert.pem";
my $key_file = "$FindBin::Bin/data/server-key.pem";
my $server = Net::QUIC::Endpoint->server(
alpn => $alpn,
certificate_file => $cert_file,
private_key_file => $key_file,
validate_address => 1,
);
my %client_for_local;
my @clients;
sub make_client {
my ($local, $token) = @_;
my %args = (
t/27-quic-v2-cvn.t view on Meta::CPAN
my ($datagram) = @_;
return unpack('N', substr($datagram->data, 1, 4));
}
sub make_server {
my (%extra) = @_;
return Net::QUIC::Endpoint->server(
alpn => $alpn,
certificate_file => $cert_file,
private_key_file => $key_file,
%extra,
);
}
sub make_client {
my ($local, %extra) = @_;
return Net::QUIC::Endpoint->client(
local => $local,
peer => $server_local,
inet_aton('127.0.0.1'),
);
my $server_local = pack_sockaddr_in(
$server_port,
inet_aton('127.0.0.1'),
);
my $server = Net::QUIC::Endpoint->server(
alpn => $alpn,
certificate_file => $cert_file,
private_key_file => $key_file,
);
my $client = Net::QUIC::Endpoint->client(
local => $client_local,
peer => $server_local,
alpn => $alpn,
server_name => 'localhost',
ca_file => $cert_file,
);
t/29-protocol-rx.t view on Meta::CPAN
my $server_local = pack_sockaddr_in(4470, inet_aton('127.0.0.1'));
my $client_local = pack_sockaddr_in(4070, inet_aton('127.0.0.1'));
my $alpn = 'net-quic-protocol-rx-test';
my $cert_file = "$FindBin::Bin/data/server-cert.pem";
my $key_file = "$FindBin::Bin/data/server-key.pem";
my $server = Net::QUIC::Endpoint->server(
alpn => $alpn,
certificate_file => $cert_file,
private_key_file => $key_file,
transport => {
connection_window => 64 * 1024,
stream_window => 2048,
},
);
my $client = Net::QUIC::Endpoint->client(
local => $client_local,
peer => $server_local,
alpn => $alpn,
t/30-acked-offset.t view on Meta::CPAN
my $server_local = pack_sockaddr_in(4471, inet_aton('127.0.0.1'));
my $client_local = pack_sockaddr_in(4071, inet_aton('127.0.0.1'));
my $alpn = 'net-quic-acked-offset-test';
my $cert_file = "$FindBin::Bin/data/server-cert.pem";
my $key_file = "$FindBin::Bin/data/server-key.pem";
my $server = Net::QUIC::Endpoint->server(
alpn => $alpn,
certificate_file => $cert_file,
private_key_file => $key_file,
);
my $client = Net::QUIC::Endpoint->client(
local => $client_local,
peer => $server_local,
alpn => $alpn,
server_name => 'localhost',
ca_file => $cert_file,
);
t/31-stream-activity.t view on Meta::CPAN
my $server_local = pack_sockaddr_in(4472, inet_aton('127.0.0.1'));
my $client_local = pack_sockaddr_in(4072, inet_aton('127.0.0.1'));
my $alpn = 'net-quic-stream-activity-test';
my $cert_file = "$FindBin::Bin/data/server-cert.pem";
my $key_file = "$FindBin::Bin/data/server-key.pem";
my $server = Net::QUIC::Endpoint->server(
alpn => $alpn,
certificate_file => $cert_file,
private_key_file => $key_file,
);
my $client = Net::QUIC::Endpoint->client(
local => $client_local,
peer => $server_local,
alpn => $alpn,
server_name => 'localhost',
ca_file => $cert_file,
);
t/32-bounded-tx.t view on Meta::CPAN
my $server_local = pack_sockaddr_in(4473, inet_aton('127.0.0.1'));
my $client_local = pack_sockaddr_in(4073, inet_aton('127.0.0.1'));
my $alpn = 'net-quic-bounded-tx-test';
my $cert_file = "$FindBin::Bin/data/server-cert.pem";
my $key_file = "$FindBin::Bin/data/server-key.pem";
my $server = Net::QUIC::Endpoint->server(
alpn => $alpn,
certificate_file => $cert_file,
private_key_file => $key_file,
transport => {
connection_window => 64 * 1024,
stream_window => 1024,
},
);
my $client = Net::QUIC::Endpoint->client(
local => $client_local,
peer => $server_local,
alpn => $alpn,
t/33-rx-reclaim-credit.t view on Meta::CPAN
my $server_local = pack_sockaddr_in(4474, inet_aton('127.0.0.1'));
my $client_local = pack_sockaddr_in(4074, inet_aton('127.0.0.1'));
my $alpn = 'net-quic-rx-reclaim-credit-test';
my $cert_file = "$FindBin::Bin/data/server-cert.pem";
my $key_file = "$FindBin::Bin/data/server-key.pem";
my $server = Net::QUIC::Endpoint->server(
alpn => $alpn,
certificate_file => $cert_file,
private_key_file => $key_file,
transport => {
connection_window => 1024,
stream_window => 1024,
},
);
my $client = Net::QUIC::Endpoint->client(
local => $client_local,
peer => $server_local,
alpn => $alpn,
t/34-protocol-engine-v2.t view on Meta::CPAN
my $server_local = pack_sockaddr_in(4475, inet_aton('127.0.0.1'));
my $client_local = pack_sockaddr_in(4075, inet_aton('127.0.0.1'));
my $alpn = 'net-quic-protocol-engine-v2-test';
my $cert_file = "$FindBin::Bin/data/server-cert.pem";
my $key_file = "$FindBin::Bin/data/server-key.pem";
my $server = Net::QUIC::Endpoint->server(
alpn => $alpn,
certificate_file => $cert_file,
private_key_file => $key_file,
transport => {
connection_window => 64 * 1024,
stream_window => 1024,
},
);
my $client = Net::QUIC::Endpoint->client(
local => $client_local,
peer => $server_local,
alpn => $alpn,
t/35-stream-index.t view on Meta::CPAN
my $server_local = pack_sockaddr_in(4476, inet_aton('127.0.0.1'));
my $client_local = pack_sockaddr_in(4076, inet_aton('127.0.0.1'));
my $alpn = 'net-quic-stream-index-test';
my $cert_file = "$FindBin::Bin/data/server-cert.pem";
my $key_file = "$FindBin::Bin/data/server-key.pem";
my $server = Net::QUIC::Endpoint->server(
alpn => $alpn,
certificate_file => $cert_file,
private_key_file => $key_file,
transport => {
max_bidi_streams => 2500,
max_uni_streams => 2500,
},
);
my $client = Net::QUIC::Endpoint->client(
local => $client_local,
peer => $server_local,
alpn => $alpn,
t/36-quic-datagram.t view on Meta::CPAN
inet_aton('127.0.0.1'),
);
my $server_local = pack_sockaddr_in(
$args{server_port},
inet_aton('127.0.0.1'),
);
my $server = Net::QUIC::Endpoint->server(
alpn => $alpn,
certificate_file => $cert_file,
private_key_file => $key_file,
transport => {
max_datagram_frame_size => $args{server_datagram_size} // 65535,
},
(defined($args{version})
? (preferred_version => $args{version})
: ()),
);
my $client = Net::QUIC::Endpoint->client(
local => $client_local,
t/36-quic-datagram.t view on Meta::CPAN
'v2-datagram',
'QUIC v2 DATAGRAM is delivered',
);
};
like(
dies {
Net::QUIC::Endpoint->server(
alpn => $alpn,
certificate_file => $cert_file,
private_key_file => $key_file,
transport => {
max_datagram_frame_size => 65536,
},
);
},
qr/max_datagram_frame_size cannot exceed 65535/,
'impossible DATAGRAM frame size is rejected',
);
done_testing;