Home | History | Annotate | Line # | Download | only in internal
      1 /*
      2  * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved.
      3  *
      4  * Licensed under the Apache License 2.0 (the "License").  You may not use
      5  * this file except in compliance with the License.  You can obtain a copy
      6  * in the file LICENSE in the source distribution or at
      7  * https://www.openssl.org/source/license.html
      8  */
      9 
     10 #ifndef OSSL_QUIC_CHANNEL_H
     11 #define OSSL_QUIC_CHANNEL_H
     12 
     13 #include <openssl/ssl.h>
     14 #include "internal/quic_types.h"
     15 #include "internal/quic_record_tx.h"
     16 #include "internal/quic_wire.h"
     17 #include "internal/quic_predef.h"
     18 #include "internal/qlog.h"
     19 #include "internal/time.h"
     20 #include "internal/thread.h"
     21 
     22 #ifndef OPENSSL_NO_QUIC
     23 
     24 /*
     25  * QUIC Channel
     26  * ============
     27  *
     28  * A QUIC channel (QUIC_CHANNEL) is an object which binds together all of the
     29  * various pieces of QUIC into a single top-level object, and handles connection
     30  * state which is not specific to the client or server roles. In particular, it
     31  * is strictly separated from the libssl front end I/O API personality layer,
     32  * and is not an SSL object.
     33  *
     34  * The name QUIC_CHANNEL is chosen because QUIC_CONNECTION is already in use,
     35  * but functionally these relate to the same thing (a QUIC connection). The use
     36  * of two separate objects ensures clean separation between the API personality
     37  * layer and common code for handling connections, and between the functionality
     38  * which is specific to clients and which is specific to servers, and the
     39  * functionality which is common to both.
     40  *
     41  * The API personality layer provides SSL objects (e.g. a QUIC_CONNECTION) which
     42  * consume a QUIC channel and implement a specific public API. Things which are
     43  * handled by the API personality layer include emulation of blocking semantics,
     44  * handling of SSL object mode flags like non-partial write mode, etc.
     45  *
     46  * Where the QUIC_CHANNEL is used in a server role, there is one QUIC_CHANNEL
     47  * per connection. In the future a QUIC Channel Manager will probably be defined
     48  * to handle ownership of resources which are shared between connections (e.g.
     49  * demuxers). Since we only use server-side functionality for dummy test servers
     50  * for now, which only need to handle one connection at a time, this is not
     51  * currently modelled.
     52  *
     53  * Synchronisation
     54  * ---------------
     55  *
     56  * To support thread assisted mode, QUIC_CHANNEL can be used by multiple
     57  * threads. **It is the caller's responsibility to ensure that the QUIC_CHANNEL
     58  * is only accessed (whether via its methods or via direct access to its state)
     59  * while the channel mutex is held**, except for methods explicitly marked as
     60  * not requiring prior locking. This is an unchecked precondition.
     61  *
     62  * The instantiator of the channel is responsible for providing a suitable
     63  * mutex which then serves as the channel mutex; see QUIC_CHANNEL_ARGS.
     64  */
     65 
     66 /*
     67  * The function does not acquire the channel mutex and assumes it is already
     68  * held by the calling thread.
     69  *
     70  * Any function tagged with this has the following precondition:
     71  *
     72  *   Precondition: must hold channel mutex (unchecked)
     73  */
     74 #define QUIC_NEEDS_LOCK
     75 
     76 /*
     77  * The function acquires the channel mutex and releases it before returning in
     78  * all circumstances.
     79  *
     80  * Any function tagged with this has the following precondition and
     81  * postcondition:
     82  *
     83  *   Precondition: must not hold channel mutex (unchecked)
     84  *   Postcondition: channel mutex is not held (by calling thread)
     85  */
     86 #define QUIC_TAKES_LOCK
     87 
     88 /*
     89  * The function acquires the channel mutex and leaves it acquired
     90  * when returning success.
     91  *
     92  * Any function tagged with this has the following precondition and
     93  * postcondition:
     94  *
     95  *   Precondition: must not hold channel mutex (unchecked)
     96  *   Postcondition: channel mutex is held by calling thread
     97  *      or function returned failure
     98  */
     99 #define QUIC_ACQUIRES_LOCK
    100 
    101 #define QUIC_TODO_LOCK
    102 
    103 #define QUIC_CHANNEL_STATE_IDLE 0
    104 #define QUIC_CHANNEL_STATE_ACTIVE 1
    105 #define QUIC_CHANNEL_STATE_TERMINATING_CLOSING 2
    106 #define QUIC_CHANNEL_STATE_TERMINATING_DRAINING 3
    107 #define QUIC_CHANNEL_STATE_TERMINATED 4
    108 
    109 typedef struct quic_channel_args_st {
    110     /*
    111      * The QUIC_PORT which the channel is to belong to. The lifetime of the
    112      * QUIC_PORT must exceed that of the created channel.
    113      */
    114     QUIC_PORT *port;
    115     /* LCIDM to register LCIDs with. */
    116     QUIC_LCIDM *lcidm;
    117     /* SRTM to register SRTs with. */
    118     QUIC_SRTM *srtm;
    119     OSSL_QRX *qrx;
    120 
    121     int is_server;
    122     SSL *tls;
    123 
    124     /* Whether to use qlog. */
    125     int use_qlog;
    126 
    127     int is_tserver_ch;
    128 
    129     /* Title to use for the qlog session, or NULL. */
    130     const char *qlog_title;
    131 } QUIC_CHANNEL_ARGS;
    132 
    133 /* Represents the cause for a connection's termination. */
    134 typedef struct quic_terminate_cause_st {
    135     /*
    136      * If we are in a TERMINATING or TERMINATED state, this is the error code
    137      * associated with the error. This field is valid iff we are in the
    138      * TERMINATING or TERMINATED states.
    139      */
    140     uint64_t error_code;
    141 
    142     /*
    143      * If terminate_app is set and this is nonzero, this is the frame type which
    144      * caused the connection to be terminated.
    145      */
    146     uint64_t frame_type;
    147 
    148     /*
    149      * Optional reason string. When calling ossl_quic_channel_local_close, if a
    150      * reason string pointer is passed, it is copied and stored inside
    151      * QUIC_CHANNEL for the remainder of the lifetime of the channel object.
    152      * Thus the string pointed to by this value, if non-NULL, is valid for the
    153      * lifetime of the QUIC_CHANNEL object.
    154      */
    155     const char *reason;
    156 
    157     /*
    158      * Length of reason in bytes. The reason is supposed to contain a UTF-8
    159      * string but may be arbitrary data if the reason came from the network.
    160      */
    161     size_t reason_len;
    162 
    163     /* Is this error code in the transport (0) or application (1) space? */
    164     unsigned int app : 1;
    165 
    166     /*
    167      * If set, the cause of the termination is a received CONNECTION_CLOSE
    168      * frame. Otherwise, we decided to terminate ourselves and sent a
    169      * CONNECTION_CLOSE frame (regardless of whether the peer later also sends
    170      * one).
    171      */
    172     unsigned int remote : 1;
    173 } QUIC_TERMINATE_CAUSE;
    174 
    175 /*
    176  * Create a new QUIC channel using the given arguments. The argument structure
    177  * does not need to remain allocated. Returns NULL on failure.
    178  *
    179  * Only QUIC_PORT should use this function.
    180  */
    181 QUIC_CHANNEL *ossl_quic_channel_alloc(const QUIC_CHANNEL_ARGS *args);
    182 int ossl_quic_channel_init(QUIC_CHANNEL *ch);
    183 void ossl_quic_channel_bind_qrx(QUIC_CHANNEL *tserver_ch, OSSL_QRX *qrx);
    184 
    185 /* No-op if ch is NULL. */
    186 void ossl_quic_channel_free(QUIC_CHANNEL *ch);
    187 
    188 /* Set mutator callbacks for test framework support */
    189 int ossl_quic_channel_set_mutator(QUIC_CHANNEL *ch,
    190     ossl_mutate_packet_cb mutatecb,
    191     ossl_finish_mutate_cb finishmutatecb,
    192     void *mutatearg);
    193 
    194 /*
    195  * Connection Lifecycle Events
    196  * ===========================
    197  *
    198  * Various events that can be raised on the channel by other parts of the QUIC
    199  * implementation. Some of these are suitable for general use by any part of the
    200  * code (e.g. ossl_quic_channel_raise_protocol_error), others are for very
    201  * specific use by particular components only (e.g.
    202  * ossl_quic_channel_on_handshake_confirmed).
    203  */
    204 
    205 /*
    206  * To be used by a QUIC connection. Starts the channel. For a client-mode
    207  * channel, this starts sending the first handshake layer message, etc. Can only
    208  * be called in the idle state; successive calls are ignored.
    209  */
    210 int ossl_quic_channel_start(QUIC_CHANNEL *ch);
    211 
    212 /* Start a locally initiated connection shutdown. */
    213 void ossl_quic_channel_local_close(QUIC_CHANNEL *ch, uint64_t app_error_code,
    214     const char *app_reason);
    215 
    216 /**
    217  * @brief schedules a NEW_TOKEN frame for sending on the channel
    218  */
    219 int ossl_quic_channel_schedule_new_token(QUIC_CHANNEL *ch,
    220     const unsigned char *token,
    221     size_t token_len);
    222 
    223 /*
    224  * Called when the handshake is confirmed.
    225  */
    226 int ossl_quic_channel_on_handshake_confirmed(QUIC_CHANNEL *ch);
    227 
    228 /*
    229  * Raises a protocol error. This is intended to be the universal call suitable
    230  * for handling of all peer-triggered protocol violations or errors detected by
    231  * us. We specify a QUIC transport-scope error code and optional frame type
    232  * which was responsible. If a frame type is not applicable, specify zero. The
    233  * reason string is not currently handled, but should be a string of static
    234  * storage duration. If the connection has already terminated due to a previous
    235  * protocol error, this is a no-op; first error wins.
    236  *
    237  * Usually the ossl_quic_channel_raise_protocol_error() function should be used.
    238  * The ossl_quic_channel_raise_protocol_error_loc() function can be used
    239  * directly for passing through existing call site information from an existing
    240  * error.
    241  */
    242 void ossl_quic_channel_raise_protocol_error_loc(QUIC_CHANNEL *ch,
    243     uint64_t error_code,
    244     uint64_t frame_type,
    245     const char *reason,
    246     ERR_STATE *err_state,
    247     const char *src_file,
    248     int src_line,
    249     const char *src_func);
    250 
    251 #define ossl_quic_channel_raise_protocol_error(ch, error_code, frame_type, reason) \
    252     ossl_quic_channel_raise_protocol_error_loc((ch), (error_code),                 \
    253         (frame_type),                                                              \
    254         (reason),                                                                  \
    255         NULL,                                                                      \
    256         OPENSSL_FILE,                                                              \
    257         OPENSSL_LINE,                                                              \
    258         OPENSSL_FUNC)
    259 
    260 #define ossl_quic_channel_raise_protocol_error_state(ch, error_code, frame_type, reason, state) \
    261     ossl_quic_channel_raise_protocol_error_loc((ch), (error_code),                              \
    262         (frame_type),                                                                           \
    263         (reason),                                                                               \
    264         (state),                                                                                \
    265         OPENSSL_FILE,                                                                           \
    266         OPENSSL_LINE,                                                                           \
    267         OPENSSL_FUNC)
    268 
    269 /*
    270  * Returns 1 if permanent net error was detected on the QUIC_CHANNEL,
    271  * 0 otherwise.
    272  */
    273 int ossl_quic_channel_net_error(QUIC_CHANNEL *ch);
    274 
    275 /* Restore saved error state (best effort) */
    276 void ossl_quic_channel_restore_err_state(QUIC_CHANNEL *ch);
    277 
    278 /* For RXDP use. */
    279 void ossl_quic_channel_on_remote_conn_close(QUIC_CHANNEL *ch,
    280     OSSL_QUIC_FRAME_CONN_CLOSE *f);
    281 void ossl_quic_channel_on_new_conn_id(QUIC_CHANNEL *ch,
    282     OSSL_QUIC_FRAME_NEW_CONN_ID *f);
    283 
    284 /* Temporarily exposed during QUIC_PORT transition. */
    285 int ossl_quic_channel_on_new_conn(QUIC_CHANNEL *ch, const BIO_ADDR *peer,
    286     const QUIC_CONN_ID *peer_dcid);
    287 
    288 /* For use by QUIC_PORT. You should not need to call this directly. */
    289 void ossl_quic_channel_subtick(QUIC_CHANNEL *ch, QUIC_TICK_RESULT *r,
    290     uint32_t flags);
    291 
    292 /* For use by QUIC_PORT only. */
    293 void ossl_quic_channel_raise_net_error(QUIC_CHANNEL *ch);
    294 
    295 /* For use by QUIC_PORT only. */
    296 void ossl_quic_channel_on_stateless_reset(QUIC_CHANNEL *ch);
    297 
    298 void ossl_quic_channel_inject(QUIC_CHANNEL *ch, QUIC_URXE *e);
    299 
    300 void ossl_quic_channel_inject_pkt(QUIC_CHANNEL *ch, OSSL_QRX_PKT *qpkt);
    301 
    302 /*
    303  * Queries and Accessors
    304  * =====================
    305  */
    306 
    307 /* Gets the reactor which can be used to tick/poll on the channel. */
    308 QUIC_REACTOR *ossl_quic_channel_get_reactor(QUIC_CHANNEL *ch);
    309 
    310 /* Gets the QSM used with the channel. */
    311 QUIC_STREAM_MAP *ossl_quic_channel_get_qsm(QUIC_CHANNEL *ch);
    312 
    313 /* Gets the statistics manager used with the channel. */
    314 OSSL_STATM *ossl_quic_channel_get_statm(QUIC_CHANNEL *ch);
    315 
    316 /* Gets the TLS handshake layer used with the channel. */
    317 SSL *ossl_quic_channel_get0_tls(QUIC_CHANNEL *ch);
    318 
    319 /* Gets the channels short header connection id length */
    320 size_t ossl_quic_channel_get_short_header_conn_id_len(QUIC_CHANNEL *ch);
    321 
    322 /*
    323  * Gets/sets the current peer address. Generally this should be used before
    324  * starting a channel in client mode.
    325  */
    326 int ossl_quic_channel_get_peer_addr(QUIC_CHANNEL *ch, BIO_ADDR *peer_addr);
    327 int ossl_quic_channel_set_peer_addr(QUIC_CHANNEL *ch, const BIO_ADDR *peer_addr);
    328 
    329 /*
    330  * Returns an existing stream by stream ID. Returns NULL if the stream does not
    331  * exist.
    332  */
    333 QUIC_STREAM *ossl_quic_channel_get_stream_by_id(QUIC_CHANNEL *ch,
    334     uint64_t stream_id);
    335 
    336 /* Returns 1 if channel is terminating or terminated. */
    337 int ossl_quic_channel_is_term_any(const QUIC_CHANNEL *ch);
    338 const QUIC_TERMINATE_CAUSE *
    339 ossl_quic_channel_get_terminate_cause(const QUIC_CHANNEL *ch);
    340 int ossl_quic_channel_is_closing(const QUIC_CHANNEL *ch);
    341 int ossl_quic_channel_is_terminated(const QUIC_CHANNEL *ch);
    342 int ossl_quic_channel_is_active(const QUIC_CHANNEL *ch);
    343 int ossl_quic_channel_is_handshake_complete(const QUIC_CHANNEL *ch);
    344 int ossl_quic_channel_is_handshake_confirmed(const QUIC_CHANNEL *ch);
    345 
    346 QUIC_PORT *ossl_quic_channel_get0_port(QUIC_CHANNEL *ch);
    347 QUIC_ENGINE *ossl_quic_channel_get0_engine(QUIC_CHANNEL *ch);
    348 QUIC_DEMUX *ossl_quic_channel_get0_demux(QUIC_CHANNEL *ch);
    349 
    350 SSL *ossl_quic_channel_get0_ssl(QUIC_CHANNEL *ch);
    351 
    352 /*
    353  * Retrieves a pointer to the channel mutex which was provided at the time the
    354  * channel was instantiated. In order to allow locks to be acquired and released
    355  * with the correct granularity, it is the caller's responsibility to ensure
    356  * this lock is held for write while calling any QUIC_CHANNEL method, except for
    357  * methods explicitly designed otherwise.
    358  *
    359  * This method is thread safe and does not require prior locking. It can also be
    360  * called while the lock is already held. Note that this is simply a convenience
    361  * function to access the mutex which was passed to the channel at instantiation
    362  * time; it does not belong to the channel but rather is presumed to belong to
    363  * the owner of the channel.
    364  */
    365 CRYPTO_MUTEX *ossl_quic_channel_get_mutex(QUIC_CHANNEL *ch);
    366 
    367 /*
    368  * Creates a new locally-initiated stream in the stream mapper, choosing an
    369  * appropriate stream ID. If is_uni is 1, creates a unidirectional stream, else
    370  * creates a bidirectional stream. Returns NULL on failure.
    371  */
    372 QUIC_STREAM *ossl_quic_channel_new_stream_local(QUIC_CHANNEL *ch, int is_uni);
    373 
    374 /*
    375  * Creates a new remotely-initiated stream in the stream mapper. The stream ID
    376  * is used to confirm the initiator and determine the stream type. The stream is
    377  * automatically added to the QSM's accept queue. A pointer to the stream is
    378  * also returned. Returns NULL on failure.
    379  */
    380 QUIC_STREAM *ossl_quic_channel_new_stream_remote(QUIC_CHANNEL *ch,
    381     uint64_t stream_id);
    382 
    383 /*
    384  * Configures incoming stream auto-reject. If enabled, incoming streams have
    385  * both their sending and receiving parts automatically rejected using
    386  * STOP_SENDING and STREAM_RESET frames. aec is the application error
    387  * code to be used for those frames.
    388  */
    389 void ossl_quic_channel_set_incoming_stream_auto_reject(QUIC_CHANNEL *ch,
    390     int enable,
    391     uint64_t aec);
    392 
    393 /*
    394  * Causes the channel to reject the sending and receiving parts of a stream,
    395  * as though autorejected. Can be used if a stream has already been
    396  * accepted.
    397  */
    398 void ossl_quic_channel_reject_stream(QUIC_CHANNEL *ch, QUIC_STREAM *qs);
    399 
    400 /* Replace local connection ID in TXP and DEMUX for testing purposes. */
    401 int ossl_quic_channel_replace_local_cid(QUIC_CHANNEL *ch,
    402     const QUIC_CONN_ID *conn_id);
    403 
    404 /* Setters for the msg_callback and msg_callback_arg */
    405 void ossl_quic_channel_set_msg_callback(QUIC_CHANNEL *ch,
    406     ossl_msg_cb msg_callback,
    407     SSL *msg_callback_ssl);
    408 void ossl_quic_channel_set_msg_callback_arg(QUIC_CHANNEL *ch,
    409     void *msg_callback_arg);
    410 
    411 /* Testing use only - sets a TXKU threshold packet count override value. */
    412 void ossl_quic_channel_set_txku_threshold_override(QUIC_CHANNEL *ch,
    413     uint64_t tx_pkt_threshold);
    414 
    415 /* Testing use only - gets current 1-RTT key epochs for QTX and QRX. */
    416 uint64_t ossl_quic_channel_get_tx_key_epoch(QUIC_CHANNEL *ch);
    417 uint64_t ossl_quic_channel_get_rx_key_epoch(QUIC_CHANNEL *ch);
    418 
    419 /* Artificially trigger a spontaneous TXKU if possible. */
    420 int ossl_quic_channel_trigger_txku(QUIC_CHANNEL *ch);
    421 int ossl_quic_channel_has_pending(const QUIC_CHANNEL *ch);
    422 
    423 /* Force transmission of an ACK-eliciting packet. */
    424 int ossl_quic_channel_ping(QUIC_CHANNEL *ch);
    425 
    426 /*
    427  * These queries exist for diagnostic purposes only. They may roll over.
    428  * Do not rely on them for non-testing purposes.
    429  */
    430 uint16_t ossl_quic_channel_get_diag_num_rx_ack(QUIC_CHANNEL *ch);
    431 
    432 /*
    433  * Diagnostic use only. Gets the current local CID.
    434  */
    435 void ossl_quic_channel_get_diag_local_cid(QUIC_CHANNEL *ch, QUIC_CONN_ID *cid);
    436 
    437 /*
    438  * Returns 1 if stream count flow control allows us to create a new
    439  * locally-initiated stream.
    440  */
    441 int ossl_quic_channel_is_new_local_stream_admissible(QUIC_CHANNEL *ch, int is_uni);
    442 
    443 /*
    444  * Returns the number of additional streams that can currently be created based
    445  * on flow control.
    446  */
    447 uint64_t ossl_quic_channel_get_local_stream_count_avail(const QUIC_CHANNEL *ch,
    448     int is_uni);
    449 uint64_t ossl_quic_channel_get_remote_stream_count_avail(const QUIC_CHANNEL *ch,
    450     int is_uni);
    451 
    452 /*
    453  * Returns 1 if we have generated our local transport parameters yet.
    454  */
    455 int ossl_quic_channel_have_generated_transport_params(const QUIC_CHANNEL *ch);
    456 
    457 /* Configures the idle timeout to request from peer (milliseconds, 0=no timeout). */
    458 void ossl_quic_channel_set_max_idle_timeout_request(QUIC_CHANNEL *ch, uint64_t ms);
    459 /* Get the configured idle timeout to request from peer. */
    460 uint64_t ossl_quic_channel_get_max_idle_timeout_request(const QUIC_CHANNEL *ch);
    461 /* Get the idle timeout requested by the peer. */
    462 uint64_t ossl_quic_channel_get_max_idle_timeout_peer_request(const QUIC_CHANNEL *ch);
    463 /* Get the idle timeout actually negotiated. */
    464 uint64_t ossl_quic_channel_get_max_idle_timeout_actual(const QUIC_CHANNEL *ch);
    465 
    466 int ossl_quic_bind_channel(QUIC_CHANNEL *ch, const BIO_ADDR *peer,
    467     const QUIC_CONN_ID *dcid, const QUIC_CONN_ID *odcid);
    468 
    469 void ossl_ch_reset_rx_state(QUIC_CHANNEL *ch);
    470 uint64_t ossl_quic_channel_get_path_challenge_count(const QUIC_CHANNEL *ch);
    471 uint64_t ossl_quic_channel_get_path_response_count(const QUIC_CHANNEL *ch);
    472 #endif
    473 
    474 #endif
    475