listener.rs

Overview

The listener.rs file implements a robust asynchronous network listener designed to handle incoming connections over QUIC transport, leveraging the msquic library. It provides mechanisms to create, start, accept connections from, and stop a network listener while maintaining internal synchronization and state management. This listener supports asynchronous polling of new connections and graceful shutdown, integrating with futures and wakers for efficient async runtime compatibility.


Main Structs and Enums

Listener

The central struct representing the network listener. It encapsulates:

ListenerInner

Holds the internal state of the listener, divided into:

ListenerInnerExclusive

Contains mutable state protected by a mutex:

ListenerInnerShared

Contains immutable shared data:

ListenerState (enum)

Represents the lifecycle state of the listener:

Accept<'a>

A future returned by Listener::accept() for asynchronously awaiting a new incoming connection.

Stop<'a>

A future returned by Listener::stop() for asynchronously awaiting listener shutdown.

ListenError (enum)

Defines error states for listener operations:


Detailed API and Methods

Listener

pub fn new(registration: &msquic::Registration, configuration: msquic::Configuration, credential: NetCredential) -> Result<Self, ListenError>

Constructs a new listener instance. It sets up the underlying msquic::Listener with an event callback closure to handle new connections and stop completion events.

pub fn start<T: AsRef<[msquic::BufferRef]>>(&self, alpn: &T, local_address: Option<SocketAddr>) -> Result<(), ListenError>

Starts the listener bound to an optional local address and configured with the specified ALPN protocols.

pub fn accept(&self) -> Accept<'_>

Returns a future that resolves to the next incoming Connection.

pub fn poll_accept(&self, cx: &mut Context<'_>) -> Poll<Result<Connection, ListenError>>

Polls for an incoming connection, waking the task when one is available.

pub fn stop(&self) -> Stop<'_>

Returns a future that resolves when the listener has stopped.

pub fn poll_stop(&self, cx: &mut Context<'_>) -> Poll<Result<(), ListenError>>

Polls to stop the listener.

pub fn local_addr(&self) -> Result<SocketAddr, ListenError>

Retrieves the local socket address the listener is bound to.


ListenerInner

fn new(configuration: msquic::Configuration, credential: NetCredential) -> Self

Initializes a new ListenerInner with default state and shared data.

fn handle_event_new_connection(&self, _info: msquic::NewConnectionInfo<'_>, connection: msquic::ConnectionRef) -> Result<(), msquic::Status>

Handles NewConnection events from msquic.

fn handle_event_stop_complete(&self, app_close_in_progress: bool) -> Result<(), msquic::Status>

Handles the StopComplete event indicating the listener has fully stopped.


Futures: Accept and Stop

Both implement std::future::Future by delegating to Listener's polling methods.


ListenError

Defines error types for listener operations with human-readable messages.


Implementation Details and Algorithms


Interaction with Other System Components


Usage Example

let registration = msquic::Registration::new("MyApp")?;
let config = msquic::Configuration::new(...)?;
let credential = NetCredential::new(...)?;

let listener = Listener::new(&registration, config, credential)?;
listener.start(&["hq-29"], Some("0.0.0.0:4433".parse().unwrap()))?;

loop {
    match listener.accept().await {
        Ok(connection) => {
            // Handle the connection
        }
        Err(ListenError::Finished) => break,
        Err(e) => eprintln!("Error accepting connection: {:?}", e),
    }
}

listener.stop().await?;

Mermaid Diagram: Listener Structure and Workflow

classDiagram
class Listener {
+new()
+start()
+accept()
+poll_accept()
+stop()
+poll_stop()
+local_addr()
}
class ListenerInner {
-exclusive: Mutex~ListenerInnerExclusive~
-shared: ListenerInnerShared
+new()
+handle_event_new_connection()
+handle_event_stop_complete()
}
class ListenerInnerExclusive {
-state: ListenerState
-new_connections: VecDeque~Connection~
-new_connection_waiters: Vec~Waker~
-shutdown_complete_waiters: Vec~Waker~
}
class ListenerInnerShared {
-credential: NetCredential
-configuration: msquic::Configuration
}
class Accept {
<<future>>
+poll()
}
class Stop {
<<future>>
+poll()
}
Listener --> ListenerInner : contains
ListenerInner --> ListenerInnerExclusive : mutex guards
ListenerInner --> ListenerInnerShared : contains
Listener --> Accept : returns future
Listener --> Stop : returns future

This diagram illustrates the core structures, their key members, and their relationships, emphasizing the flow from the Listener to internal state and the async futures Accept and Stop.


References