Skip to content

mod_http3/include/h3_io.h

Structs

Name
struct h3_io_t
struct h3_pending_handshake

Types

Name
typedef struct h3_session h3_session
typedef struct h3_io_t h3_io_t
typedef struct h3_pending_handshake h3_pending_handshake

Functions

Name
APR_DECLARE_OPTIONAL_FN(void , ap_mpm_note_extra_connection_added , (void) )
Optional MPM hooks; crash at runtime if unsupported.
APR_DECLARE_OPTIONAL_FN(void , ap_mpm_note_extra_connection_removed , (void) )
apr_status_t h3_io_listen_start(apr_pool_t * pchild, server_rec * s, h3_server_conf * conf, int udp_fd)
void h3_io_listen_stop(h3_io_t * io)
int h3_io_at_connection_limit(h3_io_t * io)
int service_session_pass(h3_io_t * io, h3_session * session)
void wait_for_event(h3_io_t * io)
void remove_pending_handshake(h3_io_t * io, int index, int free_conn)
int prepare_accepted_connection(h3_io_t * io, quic_conn * conn)
void progress_pending_handshakes(h3_io_t * io)

Attributes

Name
h3_io_t * child_h3_io

Types Documentation

typedef h3_session

typedef struct h3_session h3_session;

typedef h3_io_t

typedef struct h3_io_t h3_io_t;

typedef h3_pending_handshake

typedef struct h3_pending_handshake h3_pending_handshake;

Functions Documentation

function APR_DECLARE_OPTIONAL_FN

APR_DECLARE_OPTIONAL_FN(
    void ,
    ap_mpm_note_extra_connection_added ,
    (void) 
)

Optional MPM hooks; crash at runtime if unsupported.

function APR_DECLARE_OPTIONAL_FN

APR_DECLARE_OPTIONAL_FN(
    void ,
    ap_mpm_note_extra_connection_removed ,
    (void) 
)

function h3_io_listen_start

apr_status_t h3_io_listen_start(
    apr_pool_t * pchild,
    server_rec * s,
    h3_server_conf * conf,
    int udp_fd
)

Parameters:

  • pchild Child process pool.
  • s The server_rec this listener is associated with.
  • conf The vhost's h3_server_conf (cert/key paths, port).
  • udp_fd Pre-opened non-blocking UDP socket bound to the listen port.

Return: APR_SUCCESS on success, APR_EAGAIN if the port is already owned, or another APR error code.

Build the listener, bind the UDP socket via udp_fd, and spawn the event thread. Idempotent on the same port: returns APR_EAGAIN if another child already owns it.

function h3_io_listen_stop

void h3_io_listen_stop(
    h3_io_t * io
)

Parameters:

Stop the event thread, join all worker threads, and release the UDP fd and engine. Safe to call with NULL.

function h3_io_at_connection_limit

int h3_io_at_connection_limit(
    h3_io_t * io
)

Parameters:

  • io The h3_io_t instance to check.

Return: Non-zero if at the limit, zero otherwise.

Check if the active connection limit (H3MaxConnections) is reached.

function service_session_pass

int service_session_pass(
    h3_io_t * io,
    h3_session * session
)

Parameters:

Return: Non-zero when stream input made progress and another pass should run without polling.

Service the newly established session connection. Drives HTTP/3 request processing.

function wait_for_event

void wait_for_event(
    h3_io_t * io
)

Parameters:

  • io The listener whose socket and wakeup pipe should be polled.

Wait for network read/write events using poll().

function remove_pending_handshake

void remove_pending_handshake(
    h3_io_t * io,
    int index,
    int free_conn
)

Parameters:

  • io The owning h3_io_t listener instance.
  • index The index of the connection in the array.
  • free_conn If non-zero, the connection object is freed.

Remove a connection from the pending handshake array.

function prepare_accepted_connection

int prepare_accepted_connection(
    h3_io_t * io,
    quic_conn * conn
)

Parameters:

  • io The owning h3_io_t listener instance.
  • conn The newly accepted QUIC connection instance.

Return: 1 on success, 0 otherwise.

Prepare a newly accepted connection before starting the handshake. Sets stream modes, Incoming Stream policies, and pushes it to the pending array.

function progress_pending_handshakes

void progress_pending_handshakes(
    h3_io_t * io
)

Parameters:

  • io The owning h3_io_t listener instance.

Progress handshakes for all pending connections, timing out stalled connections and adding completed connections to the event loop.

Attributes Documentation

variable child_h3_io

h3_io_t * child_h3_io;

Source code

/*
 * Copyright (c) 2026 The mod_http3 Project Authors. All rights reserved.
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef H3_IO_H
#define H3_IO_H

#include <httpd.h>

#include <mpm_common.h>

#include <apr_atomic.h>
#include <apr_optional.h>
#include <apr_pools.h>
#include <apr_thread_proc.h>
#include <apr_thread_pool.h>

#include "h3_config.h"
#include "quic.h"

APR_DECLARE_OPTIONAL_FN(void, ap_mpm_note_extra_connection_added, (void));
APR_DECLARE_OPTIONAL_FN(void, ap_mpm_note_extra_connection_removed, (void));

typedef struct h3_session h3_session;

typedef struct h3_io_t
{
    quic_engine* qengine;
    quic_io qio;
    apr_pool_t* pool;
    server_rec* server;
    int udp_fd;
    apr_thread_t* event_thread;
    apr_array_header_t* active_sessions;
    volatile apr_uint32_t active_session_count;
    volatile apr_uint32_t total_connections;
    volatile apr_uint32_t total_streams;
    volatile apr_uint64_t total_bytes_read;
    volatile apr_uint64_t total_bytes_written;
    volatile int thread_running;
    apr_file_t* wakeup_pipe[2];

    APR_OPTIONAL_FN_TYPE(ap_mpm_note_extra_connection_added) * note_conn_added;
    APR_OPTIONAL_FN_TYPE(ap_mpm_note_extra_connection_removed) * note_conn_removed;

    apr_array_header_t* pending_handshakes;
    apr_thread_pool_t* h3_worker_pool;
} h3_io_t;

typedef struct h3_pending_handshake
{
    quic_conn* conn;
    apr_time_t accepted_at;
} h3_pending_handshake;

extern h3_io_t* child_h3_io;

apr_status_t h3_io_listen_start(apr_pool_t* pchild, server_rec* s, h3_server_conf* conf, int udp_fd);

void h3_io_listen_stop(h3_io_t* io);

int h3_io_at_connection_limit(h3_io_t* io);

int service_session_pass(h3_io_t* io, h3_session* session);

void wait_for_event(h3_io_t* io);

void remove_pending_handshake(h3_io_t* io, int index, int free_conn);

int prepare_accepted_connection(h3_io_t* io, quic_conn* conn);

void progress_pending_handshakes(h3_io_t* io);

#endif /* H3_IO_H */