Skip to content

quic/quic/include/quic_funcs.h

Functions

Name
int quic_select(const char * name)
const char * quic_engine_name(void )
size_t quic_engine_count(void )
const char * quic_engine_name_at(size_t i)
const quic_api * quic_selected(void )
void quic_settings_default(quic_settings * s)
void quic_io_udp_init(quic_io * io, int fd)
quic_engine * quic_engine_create(const quic_config * cfg, char * err, size_t errlen)
void quic_engine_destroy(quic_engine * engine)
int quic_engine_pump(quic_engine * engine)
void quic_engine_want(quic_engine * engine, int * want_read, int * want_write, int * timeout_ms)
quic_conn * quic_engine_accept_conn(quic_engine * engine)
int quic_engine_peer_addr(quic_engine * engine, quic_conn * conn, struct sockaddr_storage * addr, socklen_t * addr_len)
const char * quic_engine_last_error(quic_engine * engine)
int quic_conn_prepare(quic_conn * conn, uint32_t idle_timeout_secs)
void quic_conn_set_user(quic_conn * conn, void * user)
quic_stream * quic_conn_open_uni_stream(quic_conn * conn, int64_t * out_id)
quic_stream * quic_conn_accept_stream(quic_conn * conn)
int quic_conn_is_handshake_done(quic_conn * conn)
int quic_conn_is_closed(quic_conn * conn)
int quic_conn_shutdown(quic_conn * conn, int is_rapid, uint64_t app_error, const char * reason)
void quic_conn_free(quic_conn * conn)
int64_t quic_stream_id(quic_stream * st)
quic_write_result quic_stream_write(quic_stream * st, const quic_vec * vec, size_t nvec, int fin)
int quic_stream_is_write_blocked(quic_stream * st)
int quic_stream_read(quic_stream * st, unsigned char * buf, size_t read_size, size_t * nread, int * fin)
void quic_stream_is_read_finished(quic_stream * st, int * read_finished, int * write_finished)
void quic_stream_stop_sending(quic_stream * st, uint64_t err)
void quic_stream_reset(quic_stream * st, uint64_t err)
void quic_stream_free(quic_stream * st)
void quic_stream_consumed(quic_stream * st, size_t nbytes)

Functions Documentation

function quic_select

int quic_select(
    const char * name
)

Parameters:

  • name Engine name, matched case-insensitively.

Return: 1 if this build contains name, 0 otherwise, leaving the previous selection alone.

Make name the engine every later call dispatches to. Until this succeeds the first engine compiled in is the one in use.

function quic_engine_name

const char * quic_engine_name(
    void 
)

Return: Engine name; never NULL.

Name of the engine currently selected.

function quic_engine_count

size_t quic_engine_count(
    void 
)

Return: At least one.

How many engines this build contains.

function quic_engine_name_at

const char * quic_engine_name_at(
    size_t i
)

Parameters:

Return: Engine name, or NULL when i is out of range.

Name of the engine at i, for listing what a build offers.

function quic_selected

const quic_api * quic_selected(
    void 
)

Return: Never NULL.

The selected engine's API.

function quic_settings_default

void quic_settings_default(
    quic_settings * s
)

Parameters:

  • s Settings to overwrite.

Fill s with the transport parameters an engine uses when told nothing else.

function quic_io_udp_init

void quic_io_udp_init(
    quic_io * io,
    int fd
)

Parameters:

  • io Table to fill.
  • fd Pre-opened non-blocking UDP socket bound to the listen port.

Point io at the ordinary UDP implementation over fd, which the caller keeps ownership of.

function quic_engine_create

static inline quic_engine * quic_engine_create(
    const quic_config * cfg,
    char * err,
    size_t errlen
)

Parameters:

  • cfg Credentials, settings, callbacks and io the engine runs with.
  • err Buffer receiving the reason on failure; may be NULL.
  • errlen Capacity of err.

Return: New engine, or NULL on failure.

Create a QUIC engine over the datagram transport named in cfg.

function quic_engine_destroy

static inline void quic_engine_destroy(
    quic_engine * engine
)

Parameters:

  • engine Engine to destroy; NULL is ignored.

Destroy an engine and release its resources.

function quic_engine_pump

static inline int quic_engine_pump(
    quic_engine * engine
)

Parameters:

  • engine Engine to pump; NULL reports no work.

Return: 1 if work was done and another pass may be useful, 0 otherwise.

Drive one round of engine work: read packets, run timers, send.

function quic_engine_want

static inline void quic_engine_want(
    quic_engine * engine,
    int * want_read,
    int * want_write,
    int * timeout_ms
)

Parameters:

  • engine Engine to query; NULL leaves the outputs untouched.
  • want_read Out: non-zero if the socket should be polled for reads.
  • want_write Out: non-zero if the socket should be polled for writes.
  • timeout_ms Out: milliseconds to wait before the next timer is due.

Report what the engine needs from the next event-loop wait.

function quic_engine_accept_conn

static inline quic_conn * quic_engine_accept_conn(
    quic_engine * engine
)

Parameters:

  • engine Engine to accept from; NULL yields NULL.

Return: Accepted connection, or NULL if none is ready.

Take the next fully handshaken connection.

function quic_engine_peer_addr

static inline int quic_engine_peer_addr(
    quic_engine * engine,
    quic_conn * conn,
    struct sockaddr_storage * addr,
    socklen_t * addr_len
)

Parameters:

  • engine Engine owning conn; NULL reports failure.
  • conn Connection to inspect.
  • addr Out: peer socket address.
  • addr_len Out: bytes of addr that are meaningful.

Return: 1 if the address was resolved, 0 otherwise.

Resolve a connection's peer address.

function quic_engine_last_error

static inline const char * quic_engine_last_error(
    quic_engine * engine
)

Parameters:

  • engine Engine to query; NULL reports nothing.

Return: Message, empty when the engine has reported nothing since the last call.

The last error the engine recorded, for the caller to log.

function quic_conn_prepare

static inline int quic_conn_prepare(
    quic_conn * conn,
    uint32_t idle_timeout_secs
)

Parameters:

  • conn Connection to prepare; NULL reports failure.
  • idle_timeout_secs Idle timeout to apply, in seconds.

Return: 1 on success, 0 on failure.

Prepare an accepted connection for use.

function quic_conn_set_user

static inline void quic_conn_set_user(
    quic_conn * conn,
    void * user
)

Parameters:

  • conn Connection to attach to; NULL is ignored.
  • user Caller's handle, or NULL to detach.

Attach the caller's handle to a connection, for callbacks to pass back.

function quic_conn_open_uni_stream

static inline quic_stream * quic_conn_open_uni_stream(
    quic_conn * conn,
    int64_t * out_id
)

Parameters:

  • conn Connection to open on.
  • out_id Out: the new stream's id.

Return: New stream, or NULL on failure.

Open a server-initiated unidirectional stream.

function quic_conn_accept_stream

static inline quic_stream * quic_conn_accept_stream(
    quic_conn * conn
)

Parameters:

  • conn Connection to accept from.

Return: Accepted stream, or NULL if none is ready.

Take the next peer-initiated stream.

function quic_conn_is_handshake_done

static inline int quic_conn_is_handshake_done(
    quic_conn * conn
)

Parameters:

  • conn Connection to query.

Return: Non-zero once the handshake is done.

Whether the TLS handshake has completed.

function quic_conn_is_closed

static inline int quic_conn_is_closed(
    quic_conn * conn
)

Parameters:

  • conn Connection to query; NULL counts as closed.

Return: Non-zero once closed.

Whether the connection has finished closing.

function quic_conn_shutdown

static inline int quic_conn_shutdown(
    quic_conn * conn,
    int is_rapid,
    uint64_t app_error,
    const char * reason
)

Parameters:

  • conn Connection to close; NULL counts as already closed.
  • is_rapid Non-zero to skip the drain, as on server exit.
  • app_error Application error code to report to the peer.
  • reason Text accompanying app_error, or NULL to close cleanly.

Return: 1 when shutdown has completed, 0 while still in progress.

Begin or continue connection shutdown.

function quic_conn_free

static inline void quic_conn_free(
    quic_conn * conn
)

Parameters:

  • conn Connection to free; NULL is ignored.

Release a connection handle.

function quic_stream_id

static inline int64_t quic_stream_id(
    quic_stream * st
)

Parameters:

  • st Stream to query.

Return: The stream's id, or -1 if it has none.

Stream id.

function quic_stream_write

static inline quic_write_result quic_stream_write(
    quic_stream * st,
    const quic_vec * vec,
    size_t nvec,
    int fin
)

Parameters:

  • st Stream to write to.
  • vec Buffers to send.
  • nvec Number of buffers in vec.
  • fin Non-zero to close the stream after these bytes.

Return: What the engine accepted, and whether it blocked or broke.

Write buffers to a stream, optionally closing it.

function quic_stream_is_write_blocked

static inline int quic_stream_is_write_blocked(
    quic_stream * st
)

Parameters:

  • st Stream to query.

Return: Non-zero when blocked.

Whether the stream can currently accept more bytes.

function quic_stream_read

static inline int quic_stream_read(
    quic_stream * st,
    unsigned char * buf,
    size_t read_size,
    size_t * nread,
    int * fin
)

Parameters:

  • st Stream to read from.
  • buf Destination buffer.
  • read_size Capacity of buf.
  • nread Out: bytes written to buf.
  • fin Out: non-zero once the peer has finished sending.

Return: 1 if the call succeeded, 0 on failure.

Read from a stream.

function quic_stream_is_read_finished

static inline void quic_stream_is_read_finished(
    quic_stream * st,
    int * read_finished,
    int * write_finished
)

Parameters:

  • st Stream to query.
  • read_finished Out: non-zero if reading is finished or reset.
  • write_finished Out: non-zero if writing is finished or reset.

Report whether each direction of a stream has finished.

function quic_stream_stop_sending

static inline void quic_stream_stop_sending(
    quic_stream * st,
    uint64_t err
)

Parameters:

  • st Stream to stop; NULL is ignored.
  • err Application error code to report.

Ask the peer to stop sending on a stream.

function quic_stream_reset

static inline void quic_stream_reset(
    quic_stream * st,
    uint64_t err
)

Parameters:

  • st Stream to reset; NULL is ignored.
  • err Application error code to report.

Abort the sending half of a stream.

function quic_stream_free

static inline void quic_stream_free(
    quic_stream * st
)

Parameters:

  • st Stream to free; NULL is ignored.

Free a stream handle.

function quic_stream_consumed

static inline void quic_stream_consumed(
    quic_stream * st,
    size_t nbytes
)

Parameters:

  • st Stream that was read from.
  • nbytes Bytes consumed.

Credit stream flow control for bytes the application consumed.

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 QUIC_FUNCS_H
#define QUIC_FUNCS_H

#include "quic_types.h"

int quic_select(const char* name);

const char* quic_engine_name(void);

size_t quic_engine_count(void);

const char* quic_engine_name_at(size_t i);

const quic_api* quic_selected(void);

void quic_settings_default(quic_settings* s);

void quic_io_udp_init(quic_io* io, int fd);

static inline quic_engine* quic_engine_create(const quic_config* cfg, char* err, size_t errlen)
{
    return quic_selected()->engine.create(cfg, err, errlen);
}

static inline void quic_engine_destroy(quic_engine* engine)
{
    if (engine && quic_selected()->engine.destroy)
    {
        quic_selected()->engine.destroy(engine);
    }
}

static inline int quic_engine_pump(quic_engine* engine)
{
    return engine ? quic_selected()->engine.pump(engine) : 0;
}

static inline void quic_engine_want(quic_engine* engine, int* want_read, int* want_write, int* timeout_ms)
{
    if (engine && quic_selected()->engine.want)
    {
        quic_selected()->engine.want(engine, want_read, want_write, timeout_ms);
    }
}

static inline quic_conn* quic_engine_accept_conn(quic_engine* engine)
{
    return engine ? quic_selected()->engine.accept_conn(engine) : NULL;
}

static inline int quic_engine_peer_addr(quic_engine* engine, quic_conn* conn, struct sockaddr_storage* addr, socklen_t* addr_len)
{
    return engine ? quic_selected()->engine.peer_addr(engine, conn, addr, addr_len) : 0;
}

static inline const char* quic_engine_last_error(quic_engine* engine)
{
    return engine ? quic_selected()->engine.last_error(engine) : "";
}

static inline int quic_conn_prepare(quic_conn* conn, uint32_t idle_timeout_secs)
{
    return conn ? quic_selected()->conn.prepare(conn, idle_timeout_secs) : 0;
}

static inline void quic_conn_set_user(quic_conn* conn, void* user)
{
    if (conn && quic_selected()->conn.set_user)
    {
        quic_selected()->conn.set_user(conn, user);
    }
}

static inline quic_stream* quic_conn_open_uni_stream(quic_conn* conn, int64_t* out_id)
{
    return quic_selected()->conn.open_uni_stream(conn, out_id);
}

static inline quic_stream* quic_conn_accept_stream(quic_conn* conn)
{
    return quic_selected()->conn.accept_stream(conn);
}

static inline int quic_conn_is_handshake_done(quic_conn* conn)
{
    return quic_selected()->conn.is_handshake_done(conn);
}

static inline int quic_conn_is_closed(quic_conn* conn)
{
    return conn ? quic_selected()->conn.is_closed(conn) : 1;
}

static inline int quic_conn_shutdown(quic_conn* conn, int is_rapid, uint64_t app_error, const char* reason)
{
    return conn ? quic_selected()->conn.shutdown(conn, is_rapid, app_error, reason) : 1;
}

static inline void quic_conn_free(quic_conn* conn)
{
    if (conn && quic_selected()->conn.free)
    {
        quic_selected()->conn.free(conn);
    }
}

static inline int64_t quic_stream_id(quic_stream* st)
{
    return quic_selected()->stream.id(st);
}

static inline quic_write_result quic_stream_write(quic_stream* st, const quic_vec* vec, size_t nvec, int fin)
{
    return quic_selected()->stream.write(st, vec, nvec, fin);
}

static inline int quic_stream_is_write_blocked(quic_stream* st)
{
    return quic_selected()->stream.is_write_blocked(st);
}

static inline int quic_stream_read(quic_stream* st, unsigned char* buf, size_t read_size, size_t* nread, int* fin)
{
    return quic_selected()->stream.read(st, buf, read_size, nread, fin);
}

static inline void quic_stream_is_read_finished(quic_stream* st, int* read_finished, int* write_finished)
{
    quic_selected()->stream.is_read_finished(st, read_finished, write_finished);
}

static inline void quic_stream_stop_sending(quic_stream* st, uint64_t err)
{
    if (st && quic_selected()->stream.stop_sending)
    {
        quic_selected()->stream.stop_sending(st, err);
    }
}

static inline void quic_stream_reset(quic_stream* st, uint64_t err)
{
    if (st && quic_selected()->stream.reset)
    {
        quic_selected()->stream.reset(st, err);
    }
}

static inline void quic_stream_free(quic_stream* st)
{
    if (st && quic_selected()->stream.free)
    {
        quic_selected()->stream.free(st);
    }
}

static inline void quic_stream_consumed(quic_stream* st, size_t nbytes)
{
    if (quic_selected()->stream.consumed)
    {
        quic_selected()->stream.consumed(st, nbytes);
    }
}

#endif /* QUIC_FUNCS_H */