284 lines
10 KiB
C
284 lines
10 KiB
C
/*
|
|
* Copyright (C) Nginx, Inc.
|
|
*/
|
|
|
|
|
|
#ifndef _NGX_EVENT_QUIC_CONNECTION_H_INCLUDED_
|
|
#define _NGX_EVENT_QUIC_CONNECTION_H_INCLUDED_
|
|
|
|
|
|
#include <ngx_config.h>
|
|
#include <ngx_core.h>
|
|
#include <ngx_event.h>
|
|
|
|
|
|
/* #define NGX_QUIC_DEBUG_PACKETS */ /* dump packet contents */
|
|
/* #define NGX_QUIC_DEBUG_FRAMES */ /* dump frames contents */
|
|
/* #define NGX_QUIC_DEBUG_ALLOC */ /* log frames and bufs alloc */
|
|
/* #define NGX_QUIC_DEBUG_CRYPTO */
|
|
|
|
typedef struct ngx_quic_connection_s ngx_quic_connection_t;
|
|
typedef struct ngx_quic_server_id_s ngx_quic_server_id_t;
|
|
typedef struct ngx_quic_client_id_s ngx_quic_client_id_t;
|
|
typedef struct ngx_quic_send_ctx_s ngx_quic_send_ctx_t;
|
|
typedef struct ngx_quic_socket_s ngx_quic_socket_t;
|
|
typedef struct ngx_quic_path_s ngx_quic_path_t;
|
|
typedef struct ngx_quic_keys_s ngx_quic_keys_t;
|
|
|
|
#if (NGX_QUIC_OPENSSL_COMPAT)
|
|
#include <ngx_event_quic_openssl_compat.h>
|
|
#endif
|
|
#include <ngx_event_quic_transport.h>
|
|
#include <ngx_event_quic_protection.h>
|
|
#include <ngx_event_quic_frames.h>
|
|
#include <ngx_event_quic_migration.h>
|
|
#include <ngx_event_quic_connid.h>
|
|
#include <ngx_event_quic_streams.h>
|
|
#include <ngx_event_quic_ssl.h>
|
|
#include <ngx_event_quic_tokens.h>
|
|
#include <ngx_event_quic_ack.h>
|
|
#include <ngx_event_quic_output.h>
|
|
#include <ngx_event_quic_socket.h>
|
|
|
|
|
|
/* RFC 9002, 6.2.2. Handshakes and New Paths: kInitialRtt */
|
|
#define NGX_QUIC_INITIAL_RTT 333 /* ms */
|
|
|
|
#define NGX_QUIC_UNSET_PN (uint64_t) -1
|
|
|
|
#define NGX_QUIC_SEND_CTX_LAST (NGX_QUIC_ENCRYPTION_LAST - 1)
|
|
|
|
/* 0-RTT and 1-RTT data exist in the same packet number space,
|
|
* so we have 3 packet number spaces:
|
|
*
|
|
* 0 - Initial
|
|
* 1 - Handshake
|
|
* 2 - 0-RTT and 1-RTT
|
|
*/
|
|
#define ngx_quic_get_send_ctx(qc, level) \
|
|
((level) == ssl_encryption_initial) ? &((qc)->send_ctx[0]) \
|
|
: (((level) == ssl_encryption_handshake) ? &((qc)->send_ctx[1]) \
|
|
: &((qc)->send_ctx[2]))
|
|
|
|
#define ngx_quic_get_connection(c) \
|
|
(((c)->udp) ? (((ngx_quic_socket_t *)((c)->udp))->quic) : NULL)
|
|
|
|
#define ngx_quic_get_socket(c) ((ngx_quic_socket_t *)((c)->udp))
|
|
|
|
|
|
struct ngx_quic_client_id_s {
|
|
ngx_queue_t queue;
|
|
uint64_t seqnum;
|
|
size_t len;
|
|
u_char id[NGX_QUIC_CID_LEN_MAX];
|
|
u_char sr_token[NGX_QUIC_SR_TOKEN_LEN];
|
|
ngx_uint_t used; /* unsigned used:1; */
|
|
};
|
|
|
|
|
|
struct ngx_quic_server_id_s {
|
|
uint64_t seqnum;
|
|
size_t len;
|
|
u_char id[NGX_QUIC_CID_LEN_MAX];
|
|
};
|
|
|
|
|
|
struct ngx_quic_path_s {
|
|
ngx_queue_t queue;
|
|
struct sockaddr *sockaddr;
|
|
ngx_sockaddr_t sa;
|
|
socklen_t socklen;
|
|
ngx_quic_client_id_t *cid;
|
|
ngx_msec_t expires;
|
|
ngx_uint_t tries;
|
|
ngx_uint_t tag;
|
|
off_t sent;
|
|
off_t received;
|
|
u_char challenge1[8];
|
|
u_char challenge2[8];
|
|
uint64_t seqnum;
|
|
ngx_str_t addr_text;
|
|
u_char text[NGX_SOCKADDR_STRLEN];
|
|
unsigned validated:1;
|
|
unsigned validating:1;
|
|
unsigned limited:1;
|
|
};
|
|
|
|
|
|
struct ngx_quic_socket_s {
|
|
ngx_udp_connection_t udp;
|
|
ngx_quic_connection_t *quic;
|
|
ngx_queue_t queue;
|
|
ngx_quic_server_id_t sid;
|
|
ngx_sockaddr_t sockaddr;
|
|
socklen_t socklen;
|
|
ngx_uint_t used; /* unsigned used:1; */
|
|
};
|
|
|
|
|
|
typedef struct {
|
|
ngx_rbtree_t tree;
|
|
ngx_rbtree_node_t sentinel;
|
|
|
|
ngx_queue_t uninitialized;
|
|
ngx_queue_t free;
|
|
|
|
uint64_t sent;
|
|
uint64_t recv_offset;
|
|
uint64_t recv_window;
|
|
uint64_t recv_last;
|
|
uint64_t recv_max_data;
|
|
uint64_t send_offset;
|
|
uint64_t send_max_data;
|
|
|
|
uint64_t server_max_streams_uni;
|
|
uint64_t server_max_streams_bidi;
|
|
uint64_t server_streams_uni;
|
|
uint64_t server_streams_bidi;
|
|
|
|
uint64_t client_max_streams_uni;
|
|
uint64_t client_max_streams_bidi;
|
|
uint64_t client_streams_uni;
|
|
uint64_t client_streams_bidi;
|
|
|
|
ngx_uint_t initialized;
|
|
/* unsigned initialized:1; */
|
|
} ngx_quic_streams_t;
|
|
|
|
|
|
typedef struct {
|
|
size_t in_flight;
|
|
size_t window;
|
|
size_t ssthresh;
|
|
ngx_msec_t recovery_start;
|
|
} ngx_quic_congestion_t;
|
|
|
|
|
|
/*
|
|
* RFC 9000, 12.3. Packet Numbers
|
|
*
|
|
* Conceptually, a packet number space is the context in which a packet
|
|
* can be processed and acknowledged. Initial packets can only be sent
|
|
* with Initial packet protection keys and acknowledged in packets that
|
|
* are also Initial packets.
|
|
*/
|
|
struct ngx_quic_send_ctx_s {
|
|
enum ssl_encryption_level_t level;
|
|
|
|
ngx_quic_buffer_t crypto;
|
|
uint64_t crypto_sent;
|
|
|
|
uint64_t pnum; /* to be sent */
|
|
uint64_t largest_ack; /* received from peer */
|
|
uint64_t largest_pn; /* received from peer */
|
|
|
|
ngx_queue_t frames; /* generated frames */
|
|
ngx_queue_t sending; /* frames assigned to pkt */
|
|
ngx_queue_t sent; /* frames waiting ACK */
|
|
|
|
uint64_t pending_ack; /* non sent ack-eliciting */
|
|
uint64_t largest_range;
|
|
uint64_t first_range;
|
|
ngx_msec_t largest_received;
|
|
ngx_msec_t ack_delay_start;
|
|
ngx_uint_t nranges;
|
|
ngx_quic_ack_range_t ranges[NGX_QUIC_MAX_RANGES];
|
|
ngx_uint_t send_ack;
|
|
};
|
|
|
|
|
|
struct ngx_quic_connection_s {
|
|
uint32_t version;
|
|
|
|
ngx_quic_path_t *path;
|
|
|
|
ngx_queue_t sockets;
|
|
ngx_queue_t paths;
|
|
ngx_queue_t client_ids;
|
|
ngx_queue_t free_sockets;
|
|
ngx_queue_t free_paths;
|
|
ngx_queue_t free_client_ids;
|
|
|
|
ngx_uint_t nsockets;
|
|
ngx_uint_t nclient_ids;
|
|
uint64_t max_retired_seqnum;
|
|
uint64_t client_seqnum;
|
|
uint64_t server_seqnum;
|
|
uint64_t path_seqnum;
|
|
|
|
ngx_quic_tp_t tp;
|
|
ngx_quic_tp_t ctp;
|
|
|
|
ngx_quic_send_ctx_t send_ctx[NGX_QUIC_SEND_CTX_LAST];
|
|
|
|
ngx_quic_keys_t *keys;
|
|
|
|
ngx_quic_conf_t *conf;
|
|
|
|
ngx_event_t push;
|
|
ngx_event_t pto;
|
|
ngx_event_t close;
|
|
ngx_event_t path_validation;
|
|
ngx_msec_t last_cc;
|
|
|
|
ngx_msec_t first_rtt;
|
|
ngx_msec_t latest_rtt;
|
|
ngx_msec_t avg_rtt;
|
|
ngx_msec_t min_rtt;
|
|
ngx_msec_t rttvar;
|
|
|
|
ngx_uint_t pto_count;
|
|
|
|
ngx_queue_t free_frames;
|
|
ngx_buf_t *free_bufs;
|
|
ngx_buf_t *free_shadow_bufs;
|
|
|
|
ngx_uint_t nframes;
|
|
#ifdef NGX_QUIC_DEBUG_ALLOC
|
|
ngx_uint_t nbufs;
|
|
ngx_uint_t nshadowbufs;
|
|
#endif
|
|
|
|
#if (NGX_QUIC_OPENSSL_COMPAT)
|
|
ngx_quic_compat_t *compat;
|
|
#endif
|
|
|
|
ngx_quic_streams_t streams;
|
|
ngx_quic_congestion_t congestion;
|
|
|
|
off_t received;
|
|
|
|
ngx_uint_t error;
|
|
enum ssl_encryption_level_t error_level;
|
|
ngx_uint_t error_ftype;
|
|
const char *error_reason;
|
|
|
|
ngx_uint_t shutdown_code;
|
|
const char *shutdown_reason;
|
|
|
|
unsigned error_app:1;
|
|
unsigned send_timer_set:1;
|
|
unsigned closing:1;
|
|
unsigned shutdown:1;
|
|
unsigned draining:1;
|
|
unsigned key_phase:1;
|
|
unsigned validated:1;
|
|
unsigned client_tp_done:1;
|
|
};
|
|
|
|
|
|
ngx_int_t ngx_quic_apply_transport_params(ngx_connection_t *c,
|
|
ngx_quic_tp_t *ctp);
|
|
void ngx_quic_discard_ctx(ngx_connection_t *c,
|
|
enum ssl_encryption_level_t level);
|
|
void ngx_quic_close_connection(ngx_connection_t *c, ngx_int_t rc);
|
|
void ngx_quic_shutdown_quic(ngx_connection_t *c);
|
|
|
|
#if (NGX_DEBUG)
|
|
void ngx_quic_connstate_dbg(ngx_connection_t *c);
|
|
#else
|
|
#define ngx_quic_connstate_dbg(c)
|
|
#endif
|
|
|
|
#endif /* _NGX_EVENT_QUIC_CONNECTION_H_INCLUDED_ */
|