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.

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.

SEE ALSO

Net::QUIC

Net::QUIC::Driver

Net::QUIC::Stream

Net::QUIC::Endpoint