litespeed-quic/src/liblsquic/lsquic_engine_public.h

123 lines
4.7 KiB
C
Raw Normal View History

2022-05-06 16:49:46 +00:00
/* Copyright (c) 2017 - 2022 LiteSpeed Technologies Inc. See LICENSE. */
2017-09-22 21:00:03 +00:00
/*
* lsquic_engine_public.h -- Engine's "public interface"
*
* This structure is used to bundle things in engine that connections
* need. This way, the space per mini connection is one pointer instead
* of several.
2017-09-22 21:00:03 +00:00
*/
#ifndef LSQUIC_ENGINE_PUBLIC_H
#define LSQUIC_ENGINE_PUBLIC_H 1
struct lsquic_cid;
2017-09-22 21:00:03 +00:00
struct lsquic_conn;
struct lsquic_engine;
struct stack_st_X509;
struct lsquic_hash;
struct lsquic_stream_if;
struct ssl_ctx_st;
struct crand;
struct evp_aead_ctx_st;
struct lsquic_server_config;
struct sockaddr;
enum warning_type
{
WT_ACKPARSE_MINI,
WT_ACKPARSE_FULL,
WT_NO_POISON,
N_WARNING_TYPES,
};
#define WARNING_INTERVAL (24ULL * 3600ULL * 1000000ULL)
2017-09-22 21:00:03 +00:00
struct lsquic_engine_public {
struct lsquic_mm enp_mm;
struct lsquic_engine_settings enp_settings;
struct token_generator *enp_tokgen;
lsquic_lookup_cert_f enp_lookup_cert;
void *enp_cert_lu_ctx;
struct ssl_ctx_st * (*enp_get_ssl_ctx)(void *peer_ctx,
const struct sockaddr *);
const struct lsquic_shared_hash_if
*enp_shi;
void *enp_shi_ctx;
lsquic_time_t enp_last_warning[N_WARNING_TYPES];
const struct lsquic_stream_if *enp_stream_if;
void *enp_stream_if_ctx;
const struct lsquic_hset_if *enp_hsi_if;
void *enp_hsi_ctx;
void (*enp_generate_scid)(void *,
struct lsquic_conn *, struct lsquic_cid *, unsigned);
void *enp_gen_scid_ctx;
int (*enp_verify_cert)(void *verify_ctx,
struct stack_st_X509 *chain);
void *enp_verify_ctx;
2017-09-22 21:00:03 +00:00
const struct lsquic_packout_mem_if
*enp_pmi;
void *enp_pmi_ctx;
struct lsquic_engine *enp_engine;
struct lsquic_hash *enp_srst_hash;
2017-09-22 21:00:03 +00:00
enum {
ENPUB_PROC = (1 << 0), /* Being processed by one of the user-facing
* functions.
*/
ENPUB_CAN_SEND = (1 << 1),
ENPUB_HTTP = (1 << 2), /* Engine in HTTP mode */
2017-09-22 21:00:03 +00:00
} enp_flags;
unsigned char enp_ver_tags_buf[ sizeof(lsquic_ver_tag_t) * N_LSQVER ];
unsigned enp_ver_tags_len;
struct crand *enp_crand;
struct evp_aead_ctx_st *enp_retry_aead_ctx;
unsigned char *enp_alpn; /* May be set if not HTTP */
/* es_noprogress_timeout converted to microseconds for speed */
lsquic_time_t enp_noprog_timeout;
lsquic_time_t enp_mtu_probe_timer;
/* Certs used by gQUIC server: */
struct lsquic_hash *enp_compressed_server_certs;
struct lsquic_hash *enp_server_certs;
/* gQUIC server configuration: */
struct lsquic_server_config *enp_server_config;
/* Serialized subset of server engine transport parameters that is used
* as SSL QUIC context. 0 is for version <= LSQVER_ID27, 1 is for others.
*/
unsigned char enp_quic_ctx_buf[2][200];
unsigned enp_quic_ctx_sz[2];
#if LSQUIC_CONN_STATS
struct batch_size_stats {
unsigned min, max, /* Minimum and maximum batch sizes */
count; /* Number of batches sent */
float avg; /* Average batch size */
} enp_batch_size_stats;
#endif
2017-09-22 21:00:03 +00:00
};
[API Change, OPTIMIZATION] Only process conns that need to be processed The API is simplified: do not expose the user code to several queues. A "connection queue" is now an internal concept. The user processes connections using the single function lsquic_engine_process_conns(). When this function is called, only those connections are processed that need to be processed. A connection needs to be processed when: 1. New incoming packets have been fed to the connection. 2. User wants to read from a stream that is readable. 3. User wants to write to a stream that is writeable. 4. There are buffered packets that can be sent out. (This means that the user wrote to a stream outside of the lsquic library callback.) 5. A control frame (such as BLOCKED) needs to be sent out. 6. A stream needs to be serviced or delayed stream needs to be created. 7. An alarm rings. 8. Pacer timer expires. To achieve this, the library places the connections into two priority queues (min heaps): 1. Tickable Queue; and 2. Advisory Tick Time queue (ATTQ). Each time lsquic_engine_process_conns() is called, the Tickable Queue is emptied. After the connections have been ticked, they are queried again: if a connection is not being closed, it is placed either in the Tickable Queue if it is ready to be ticked again or it is placed in the Advisory Tick Time Queue. It is assumed that a connection always has at least one timer set (the idle alarm). The connections in the Tickable Queue are arranged in the least recently ticked order. This lets connections that have been quiet longer to get their packets scheduled first. This change means that the library no longer needs to be ticked periodically. The user code can query the library when is the next tick event and schedule it exactly. When connections are processed, only the tickable connections are processed, not *all* the connections. When there are no tick events, it means that no timer event is necessary -- only the file descriptor READ event is active. The following are improvements and simplifications that have been triggered: - Queue of connections with incoming packets is gone. - "Pending Read/Write Events" Queue is gone (along with its history and progress checks). This queue has become the Tickable Queue. - The connection hash no longer needs to track the connection insertion order.
2018-04-09 13:39:38 +00:00
/* Put connection onto the Tickable Queue if it is not already on it. If
2017-09-22 21:00:03 +00:00
* connection is being destroyed, this is a no-op.
*/
void
[API Change, OPTIMIZATION] Only process conns that need to be processed The API is simplified: do not expose the user code to several queues. A "connection queue" is now an internal concept. The user processes connections using the single function lsquic_engine_process_conns(). When this function is called, only those connections are processed that need to be processed. A connection needs to be processed when: 1. New incoming packets have been fed to the connection. 2. User wants to read from a stream that is readable. 3. User wants to write to a stream that is writeable. 4. There are buffered packets that can be sent out. (This means that the user wrote to a stream outside of the lsquic library callback.) 5. A control frame (such as BLOCKED) needs to be sent out. 6. A stream needs to be serviced or delayed stream needs to be created. 7. An alarm rings. 8. Pacer timer expires. To achieve this, the library places the connections into two priority queues (min heaps): 1. Tickable Queue; and 2. Advisory Tick Time queue (ATTQ). Each time lsquic_engine_process_conns() is called, the Tickable Queue is emptied. After the connections have been ticked, they are queried again: if a connection is not being closed, it is placed either in the Tickable Queue if it is ready to be ticked again or it is placed in the Advisory Tick Time Queue. It is assumed that a connection always has at least one timer set (the idle alarm). The connections in the Tickable Queue are arranged in the least recently ticked order. This lets connections that have been quiet longer to get their packets scheduled first. This change means that the library no longer needs to be ticked periodically. The user code can query the library when is the next tick event and schedule it exactly. When connections are processed, only the tickable connections are processed, not *all* the connections. When there are no tick events, it means that no timer event is necessary -- only the file descriptor READ event is active. The following are improvements and simplifications that have been triggered: - Queue of connections with incoming packets is gone. - "Pending Read/Write Events" Queue is gone (along with its history and progress checks). This queue has become the Tickable Queue. - The connection hash no longer needs to track the connection insertion order.
2018-04-09 13:39:38 +00:00
lsquic_engine_add_conn_to_tickable (struct lsquic_engine_public *,
lsquic_conn_t *);
2017-09-22 21:00:03 +00:00
/* Put connection onto Advisory Tick Time Queue if it is not already on it.
*/
void
lsquic_engine_add_conn_to_attq (struct lsquic_engine_public *enpub,
lsquic_conn_t *, lsquic_time_t, unsigned why);
2017-09-22 21:00:03 +00:00
void
lsquic_engine_retire_cid (struct lsquic_engine_public *,
struct lsquic_conn *, unsigned cce_idx, lsquic_time_t now,
lsquic_time_t drain_time);
int
lsquic_engine_add_cid (struct lsquic_engine_public *,
struct lsquic_conn *, unsigned cce_idx);
struct lsquic_conn *
lsquic_engine_find_conn (const struct lsquic_engine_public *pub,
const lsquic_cid_t *cid);
2017-09-22 21:00:03 +00:00
#endif