NAME
Net::QUIC::Connection - one QUIC connection
DESCRIPTION
A Connection is one secure QUIC relationship with a peer.
It can contain many independent Net::QUIC::Stream objects.
Application protocol code normally works with Connection and Stream. UDP socket and timer handling normally stays in Net::QUIC::Driver.
A client Driver has one Connection.
A server Driver can create many Connections.
BASIC USE
Get the client Connection:
my $connection = $driver->connection;
Wait for the handshake:
return if !$connection->ready;
Open a bidirectional Stream:
my $stream = $connection->open_bidi_stream;
if ($stream) {
$stream->send("hello");
$stream->finish;
}
Accept Streams opened by the peer:
while (my $stream = $connection->next_stream) {
...
}
Close normally:
$connection->close;
HANDSHAKE AND SAVED STATE
ready
if ($connection->ready) {
...
}
Returns true after the QUIC/TLS handshake is ready for normal application work.
A server can expose a Connection before this becomes true.
client_chosen_version
my $version = $connection->client_chosen_version;
Returns 1 or 2 for the QUIC version used by the client's first Initial packet.
This can differ from "version" when Compatible Version Negotiation switches the connection to another supported version during the handshake.
version
my $version = $connection->version;
Returns the final negotiated QUIC version, 1 or 2.
It can be undef before version negotiation is complete.
Most applications do not need to branch on this value.
session_ticket
my $ticket = $connection->session_ticket;
Returns the newest opaque TLS session ticket received by the client, or undef if none is available.
A later client can pass it as:
session_ticket => $ticket
to attempt a faster resumed TLS handshake.
Treat the ticket as opaque bytes.
If it is expired or otherwise unusable, the connection falls back to a normal full handshake.
resumed
if ($connection->resumed) {
...
}
Returns true when the completed TLS handshake actually resumed a previous session.
address_token
my $token = $connection->address_token;
Returns the newest opaque QUIC address-validation token received by the client, or undef if none is available.
A later client can pass it as:
address_token => $token
A valid token can let a server with address validation enabled accept the new connection without another Retry round trip.
Treat the token as opaque bytes.
early_data_state
my $state = $connection->early_data_state;
Returns one opaque value that a client can save for a later 0-RTT attempt.
A later client supplies it as:
early_data => $state
0-RTT allows some application data to be sent before the new handshake completes.
0-RTT data can be replayed. Only use it for operations that are safe to repeat.
early_data_status
my $status = $connection->early_data_status;
Returns one of:
none
pending
accepted
rejected
pending means this client is attempting 0-RTT and does not yet know whether the server accepted it.
If 0-RTT is rejected, the normal TLS handshake can still complete.
Streams created for the rejected early-data attempt become invalid. Open new Streams after ready and resend only operations that are safe to repeat.
OPENING STREAMS
open_bidi_stream
my $stream = $connection->open_bidi_stream;
Opens a bidirectional Stream.
Both endpoints can send on a bidirectional Stream.
Returns undef when the peer's current bidirectional stream limit has been reached.
That is normal QUIC flow control, not a Connection failure.
open_uni_stream
my $stream = $connection->open_uni_stream;
Opens a unidirectional Stream.
Only this endpoint can send application bytes on a locally opened unidirectional Stream.
Returns undef when the peer's current unidirectional stream limit has been reached.
on_stream_available
$connection->on_stream_available(sub {
my ($connection, $type) = @_;
...
});
Registers a callback for new local stream credit.
$type is:
bidi
or:
uni
Use this when open_bidi_stream or open_uni_stream returned undef and the application wants to try again when the peer allows another Stream.
PEER-CREATED STREAMS
next_stream
while (my $stream = $connection->next_stream) {
...
}
Returns the next Stream opened by the peer.
Returns undef when no new peer-created Stream is waiting.
A Stream can be bidirectional or unidirectional. Use:
$stream->can_send
$stream->can_receive
when code needs to handle either kind.
on_stream_activity
$connection->on_stream_activity(sub {
my ($connection) = @_;
...
});
Registers an advanced protocol-engine wake-up callback.
The callback runs when one or more Streams have meaningful new activity, such as received data, FIN, acknowledgement progress, RESET_STREAM, STOP_SENDING, stream close, or a newly peer-created Stream.
The callback does not receive one event object per transport event. Activity is coalesced by Stream.
Drain the changed Stream IDs with "next_active_stream_id".
Pass undef to disable activity tracking:
$connection->on_stream_activity(undef);
Activity tracking is opt-in so ordinary applications pay no queueing cost.
next_active_stream_id
while (defined(my $id = $connection->next_active_stream_id)) {
...
}
Returns the next Stream ID with coalesced activity.
Returns undef when the activity queue is empty.
A protocol engine should normally drain this queue when "on_stream_activity" wakes it. State such as received data, acknowledgement offsets, reset codes, and STOP_SENDING codes remains available on the corresponding Stream object.
BOUNDED TRANSMIT BUFFERING
These methods are for advanced producers that need a hard bound on Stream data retained by Net::QUIC.
send_buffer_limit
$connection->send_buffer_limit(4 * 1024 * 1024);
Enables a connection-wide limit on retained Stream transmit bytes.
The limit counts Stream data that is queued for sending plus data already sent but still retained until peer acknowledgement.
Use:
my $limit = $connection->send_buffer_limit;
to read the current limit.
It returns undef when bounded transmit mode is disabled.
Disable the limit with:
$connection->send_buffer_limit(undef);
A new limit cannot be smaller than the amount of Stream data already retained.
When a limit is enabled, ordinary "send" in Net::QUIC::Stream remains all-or-nothing. It throws instead of exceeding the configured bound. Advanced producers should use "send_some" in Net::QUIC::Stream.
send_buffered_bytes
my $bytes = $connection->send_buffered_bytes;
Returns the total number of Stream data bytes currently retained for transmit across this Connection.
This includes sent data that still has to remain available until it is acknowledged.
NETWORK PATH
A QUIC Connection can survive some network-address changes without being recreated.
Most applications do not need to inspect path state during ordinary use.
path
my $path = $connection->path;
Returns the active network path:
{
local => $packed_local_address,
peer => $packed_peer_address,
}
migrate
$connection->migrate($new_packed_local_address);
Client only.
Starts migration to another local address while keeping the same QUIC Connection.
Net::QUIC validates the new path before switching to it.
If validation fails, the previous working path stays active.
path_validation_status
my $status = $connection->path_validation_status;
Returns:
none
validating
succeeded
failed
aborted
This is the simple path-validation view.
path_validation
my $info = $connection->path_validation;
Returns the detailed current or most recent path-validation state.
The hash includes at least:
status
and, when a validation has occurred:
local
peer
It also reports whether the validation was associated with a server preferred address or a fresh address-validation token.
path_max_udp_payload_size
my $bytes = $connection->path_max_udp_payload_size;
Returns the currently discovered maximum UDP payload size for the active path.
A new path starts at QUIC's safe 1200-byte baseline. The native QUIC engine can raise this value when larger packets work.
This is mainly diagnostic. Applications normally do not need to manage PMTU discovery themselves.
CLOSING
close
$connection->close;
or:
$connection->close($application_error_code);
Starts a normal application-level QUIC close.
The default application error code is zero.
Closing is not immediate destruction. QUIC has a short closing/draining period so late packets can still be handled correctly.
closed
if ($connection->closed) {
...
}
Returns true when the Connection no longer needs network or timer service.
CLOSE AND ERROR INFORMATION
close_info
my $info = $connection->close_info;
Returns undef while no close or failure has been recorded.
Otherwise it returns a hash describing the outcome.
For example, a normal peer application close can look like:
{
type => 'application',
initiator => 'peer',
code => 0,
}
type can be:
application
transport
tls
certificate
handshake
idle
drop
initiator is:
local
peer
code is the application error code, QUIC transport error code, or TLS alert code as appropriate.
A peer transport error can also include frame_type.
A locally detected native transport failure can include native_error.
Remote protocol errors, certificate failures, handshake failures, idle timeout, and normal closes are Connection outcomes rather than ordinary Perl exceptions.
Local programming mistakes, invalid configuration, allocation failure, and internal implementation failures still throw Perl exceptions.
DRIVER NOTIFICATION
Connections obtained through Net::QUIC::Driver automatically notify Driver when application operations create new transport work.
For example:
$stream->send(...);
$stream->finish;
$stream->reset(...);
$connection->close;
do not require a separate service or pump call.