# XQUIC Callback Functions: Required Server vs Client Implementation Guide

> Understand XQUIC callback functions for server and client modes. Learn which callbacks are mandatory for each to ensure proper connection and session management.

- Repository: [Alibaba/xquic](https://github.com/alibaba/xquic)
- Tags: how-to-guide
- Published: 2026-02-24

---

**Server and client modes in XQUIC require distinct mandatory callback functions—servers must implement connection and stream creation notifications along with address change handlers, while clients must implement state persistence callbacks for tokens, sessions, and transport parameters to support 0-RTT and connection resumption.**

XQUIC is Alibaba's high-performance QUIC and HTTP/3 implementation. When building applications with this library, understanding which XQUIC callback functions are mandatory for server versus client mode is critical for proper connection lifecycle management. This guide maps the required callbacks based on the actual source code definitions in [`include/xquic/xquic.h`](https://github.com/alibaba/xquic/blob/main/include/xquic/xquic.h) and the reference implementations in the `mini/` directory.

## Understanding XQUIC Callback Architecture

XQUIC separates **engine-level** transport callbacks from **application-layer** callbacks for connections, streams, and datagrams. The library uses several key structures defined in [`include/xquic/xquic.h`](https://github.com/alibaba/xquic/blob/main/include/xquic/xquic.h):

- `xqc_transport_callbacks_t` – Low-level transport events
- `xqc_conn_callbacks_t` – Connection lifecycle events  
- `xqc_stream_callbacks_t` – Stream operations
- `xqc_datagram_callbacks_t` – QUIC datagram extension (optional)
- `xqc_app_proto_callbacks_t` – Bundles the above for ALPN registration

## Required XQUIC Callback Functions for Server Mode

Server implementations must handle incoming connections and address changes. The mandatory callbacks differ significantly from client requirements.

### Engine Transport Callbacks

According to [`include/xquic/xquic.h`](https://github.com/alibaba/xquic/blob/main/include/xquic/xquic.h), servers must implement:

- **`path_created_notify`** – Required when multipath is enabled (lines 90-112)
- **`conn_peer_addr_changed_notify`** – Mandatory for reporting peer address changes
- **`path_peer_addr_changed_notify`** – Mandatory for reporting path-specific address changes

### Connection Callbacks

Servers must provide:

- **`conn_create_notify`** – Invoked immediately after a new connection object is allocated (marked "REQUIRED for server" in [`xquic.h`](https://github.com/alibaba/xquic/blob/main/xquic.h) lines 730-750)
- **`conn_close_notify`** – Required by both server and client for proper cleanup

### Stream Callbacks

For stream handling, servers must implement:

- **`stream_create_notify`** – Called when a peer creates a new stream (required per [`xquic.h`](https://github.com/alibaba/xquic/blob/main/xquic.h) lines 780-800)
- **`stream_read_notify`** – Required by both sides
- **`stream_write_notify`** – Required by both sides  
- **`stream_close_notify`** – Required by both sides

## Required XQUIC Callback Functions for Client Mode

Client implementations focus on state persistence for 0-RTT and connection resumption rather than connection acceptance.

### Engine Transport Callbacks for State Persistence

Clients must implement these callbacks to support 0-RTT and session resumption (defined in [`xquic.h`](https://github.com/alibaba/xquic/blob/main/xquic.h) lines 66-88):

- **`save_token`** – Store the address validation token received from the server
- **`save_session_cb`** – Persist TLS session information for 0-RTT
- **`save_tp_cb`** – Persist transport parameters for subsequent connections

### Connection and Stream Callbacks

Unlike servers, clients treat these as optional:

- **`conn_create_notify`** – Optional for clients (NULL is acceptable)
- **`stream_create_notify`** – Optional for clients

However, clients must still provide:

- **`conn_close_notify`**
- **`stream_read_notify`**, **`stream_write_notify`**, **`stream_close_notify`**

### Multipath Support

If the client enables multipath:

- **`ready_to_create_path_notify`** – Required to signal when additional paths can be established

## Implementation Examples

The `mini/` directory contains reference implementations demonstrating these requirements.

Server callback structure from [`mini/mini_server_cb.h`](https://github.com/alibaba/xquic/blob/main/mini/mini_server_cb.h):

```c
static xqc_conn_callbacks_t sv_conn_cbs = {
    .conn_create_notify   = my_server_conn_create,   /* REQUIRED */
    .conn_close_notify    = my_server_conn_close,    /* REQUIRED */
    .conn_handshake_finished = NULL,
};

static xqc_stream_callbacks_t sv_stream_cbs = {
    .stream_read_notify   = my_server_stream_read,
    .stream_write_notify  = my_server_stream_write,
    .stream_create_notify = my_server_stream_create, /* REQUIRED */
    .stream_close_notify  = my_server_stream_close,
    .stream_closing_notify = NULL,
};

static xqc_transport_callbacks_t sv_transport_cbs = {
    .path_created_notify          = my_server_path_created,          /* REQUIRED for MP */
    .conn_peer_addr_changed_notify = my_server_peer_addr_changed,     /* REQUIRED */
    .path_peer_addr_changed_notify = my_server_path_addr_changed,    /* REQUIRED */
};

```

Client callback structure from [`mini/mini_client_cb.h`](https://github.com/alibaba/xquic/blob/main/mini/mini_client_cb.h):

```c
static xqc_conn_callbacks_t cl_conn_cbs = {
    .conn_create_notify   = NULL,                    /* optional for client */
    .conn_close_notify    = my_client_conn_close,    /* REQUIRED */
    .conn_handshake_finished = NULL,
};

static xqc_stream_callbacks_t cl_stream_cbs = {
    .stream_read_notify   = my_client_stream_read,
    .stream_write_notify  = my_client_stream_write,
    .stream_create_notify = NULL,                    /* optional for client */
    .stream_close_notify  = my_client_stream_close,
};

static xqc_transport_callbacks_t cl_transport_cbs = {
    .save_token          = my_client_save_token,          /* REQUIRED */
    .save_session_cb     = my_client_save_session,        /* REQUIRED */
    .save_tp_cb          = my_client_save_tp,             /* REQUIRED */
    .ready_to_create_path_notify = my_client_ready_path, /* REQUIRED for MP */
};

```

## Key Source Files and References

When implementing XQUIC callback functions, consult these specific files in the Alibaba XQUIC repository:

| File | Purpose |
|------|---------|
| [`include/xquic/xquic.h`](https://github.com/alibaba/xquic/blob/main/include/xquic/xquic.h) | Central definitions of all callback structures (`xqc_transport_callbacks_t`, `xqc_conn_callbacks_t`, `xqc_stream_callbacks_t`, `xqc_datagram_callbacks_t`) with "REQUIRED" annotations |
| [`include/xquic/xquic_typedef.h`](https://github.com/alibaba/xquic/blob/main/include/xquic/xquic_typedef.h) | Type aliases and callback function signatures |
| [`src/transport/xqc_engine.h`](https://github.com/alibaba/xquic/blob/main/src/transport/xqc_engine.h) | Engine configuration and `xqc_engine_callback_t` for timer, log, and CID management |
| [`mini/mini_server_cb.h`](https://github.com/alibaba/xquic/blob/main/mini/mini_server_cb.h) | Reference server callback implementations |
| [`mini/mini_client_cb.h`](https://github.com/alibaba/xquic/blob/main/mini/mini_client_cb.h) | Reference client callback implementations |
| [`mini/mini_server.c`](https://github.com/alibaba/xquic/blob/main/mini/mini_server.c) / [`mini/mini_client.c`](https://github.com/alibaba/xquic/blob/main/mini/mini_client.c) | Complete working examples showing registration via `xqc_engine_register_alpn()` |

## Summary

Implementing XQUIC callback functions correctly depends entirely on whether you are building a server or client:

- **Server mode** requires handling incoming connections via `conn_create_notify` and `stream_create_notify`, plus address change notifications (`conn_peer_addr_changed_notify`, `path_peer_addr_changed_notify`) and multipath creation events when enabled.
- **Client mode** requires state persistence callbacks (`save_token`, `save_session_cb`, `save_tp_cb`) to support 0-RTT and session resumption, while connection and stream creation notifications remain optional.
- **Both modes** must implement `conn_close_notify`, `stream_read_notify`, `stream_write_notify`, and `stream_close_notify` for proper connection lifecycle management.

## Frequently Asked Questions

### What happens if I don't implement the required server callbacks in XQUIC?

If you omit mandatory server callbacks such as `conn_create_notify` or `stream_create_notify`, the XQUIC engine will fail to properly initialize incoming connections or streams, typically resulting in connection timeouts, protocol errors, or null pointer dereferences when the engine attempts to invoke the missing callback.

### Are the XQUIC callback requirements different for HTTP/3 versus raw QUIC?

The core callback requirements remain the same for both HTTP/3 and raw QUIC applications because they operate at the transport layer. However, HTTP/3 implementations typically use additional application-layer callbacks for header processing and request handling, while the underlying `xqc_transport_callbacks_t`, `xqc_conn_callbacks_t`, and `xqc_stream_callbacks_t` requirements follow the same server vs. client rules outlined in this guide.

### Do I need to implement all datagram callbacks for QUIC datagram support?

No, you only need to implement the specific datagram callbacks your application uses. For receiving datagrams, implement `datagram_read_notify`; for sending, implement `datagram_write_notify`. The other datagram callbacks such as `datagram_acked_notify`, `datagram_lost_notify`, and `datagram_mss_updated_notify` are optional and only needed if your application requires acknowledgment tracking or MSS change notifications.

### Can I use the same callback functions for both server and client modes in XQUIC?

While some callbacks like `conn_close_notify`, `stream_read_notify`, `stream_write_notify`, and `stream_close_notify` are universal and can be shared, you cannot use identical callback sets for both modes because each mode has unique mandatory requirements. Servers must implement connection acceptance callbacks (`conn_create_notify`, `stream_create_notify`) and address change handlers, while clients must implement state persistence callbacks (`save_token`, `save_session_cb`, `save_tp_cb`). Attempting to register a server callback structure on a client engine (or vice versa) will result in missing required functionality or connection failures.