litespeed-quic/include/lsquic.h

902 lines
26 KiB
C
Raw Normal View History

/* Copyright (c) 2017 - 2018 LiteSpeed Technologies Inc. See LICENSE. */
2017-09-22 21:00:03 +00:00
#ifndef __LSQUIC_H__
#define __LSQUIC_H__
/**
* @file
* public API for using liblsquic is defined in this file.
*
*/
#include <stdarg.h>
#include <lsquic_types.h>
#ifndef WIN32
2017-09-22 21:00:03 +00:00
#include <sys/uio.h>
#include <sys/types.h>
#include <time.h>
2018-03-30 14:57:17 +00:00
#include <sys/queue.h>
#else
#include <vc_compat.h>
#endif
2017-09-22 21:00:03 +00:00
struct iovec;
struct sockaddr;
#ifdef __cplusplus
extern "C" {
#endif
/**
* Engine flags:
*/
/** Server mode */
#define LSENG_SERVER (1 << 0)
/** Treat stream 3 as headers stream and, in general, behave like the
* regular QUIC.
*/
#define LSENG_HTTP (1 << 1)
#define LSENG_HTTP_SERVER (LSENG_SERVER|LSENG_HTTP)
/**
* This is a list of QUIC versions that we know of. List of supported
* versions is in LSQUIC_SUPPORTED_VERSIONS.
*/
enum lsquic_version
{
/** Q035. This is the first version to be supported by LSQUIC. */
LSQVER_035,
/*
2017-09-22 21:00:03 +00:00
* Q037. This version is like Q035, except the way packet hashes are
* generated is different for clients and servers. In addition, new
* option NSTP (no STOP_WAITING frames) is rumored to be supported at
* some point in the future.
*/
/* Support for this version has been removed. The comment remains to
* document the changes.
*/
2017-09-22 21:00:03 +00:00
/*
2017-09-22 21:00:03 +00:00
* Q038. Based on Q037, supports PADDING frames in the middle of packet
* and NSTP (no STOP_WAITING frames) option.
*/
/* Support for this version has been removed. The comment remains to
* document the changes.
*/
2017-09-22 21:00:03 +00:00
/**
* Q039. Switch to big endian. Do not ack acks. Send connection level
* WINDOW_UPDATE frame every 20 sent packets which do not contain
* retransmittable frames.
*/
LSQVER_039,
2018-05-09 18:43:22 +00:00
/*
* Q041. RST_STREAM, ACK and STREAM frames match IETF format.
2017-09-22 21:00:03 +00:00
*/
2018-05-09 18:43:22 +00:00
/* Support for this version has been removed. The comment remains to
* document the changes.
*/
2017-09-22 21:00:03 +00:00
/*
2018-05-04 18:00:34 +00:00
* Q042. Receiving overlapping stream data is allowed.
*/
/* Support for this version has been removed. The comment remains to
* document the changes.
*/
2018-05-04 18:00:34 +00:00
2018-05-09 12:57:43 +00:00
/**
* Q043. Support for processing PRIORITY frames. Since this library
* has supported PRIORITY frames from the beginning, this version is
* exactly the same as LSQVER_042.
*/
LSQVER_043,
2017-09-22 21:00:03 +00:00
N_LSQVER
};
/**
2018-05-09 18:43:22 +00:00
* We currently support versions 35, 39, and 43.
2017-09-22 21:00:03 +00:00
* @see lsquic_version
*/
2018-05-09 12:57:43 +00:00
#define LSQUIC_SUPPORTED_VERSIONS ((1 << N_LSQVER) - 1)
2017-09-22 21:00:03 +00:00
#define LSQUIC_EXPERIMENTAL_VERSIONS 0
2017-09-22 21:00:03 +00:00
2018-05-09 18:43:22 +00:00
#define LSQUIC_DEPRECATED_VERSIONS 0
2017-09-22 21:00:03 +00:00
/**
* @struct lsquic_stream_if
* @brief The definition of callback functions call by lsquic_stream to
* process events.
*
*/
struct lsquic_stream_if {
/**
* Use @ref lsquic_conn_get_ctx to get back the context. It is
* OK for this function to return NULL.
*/
lsquic_conn_ctx_t *(*on_new_conn)(void *stream_if_ctx,
lsquic_conn_t *c);
/** This is called when our side received GOAWAY frame. After this,
* new streams should not be created. The callback is optional.
*/
void (*on_goaway_received)(lsquic_conn_t *c);
void (*on_conn_closed)(lsquic_conn_t *c);
/** If you need to initiate a connection, call lsquic_conn_make_stream().
* This will cause `on_new_stream' callback to be called when appropriate
* (this operation is delayed when maximum number of outgoing streams is
* reached).
*
* After `on_close' is called, the stream is no longer accessible.
*/
lsquic_stream_ctx_t *
(*on_new_stream)(void *stream_if_ctx, lsquic_stream_t *s);
void (*on_read) (lsquic_stream_t *s, lsquic_stream_ctx_t *h);
void (*on_write) (lsquic_stream_t *s, lsquic_stream_ctx_t *h);
void (*on_close) (lsquic_stream_t *s, lsquic_stream_ctx_t *h);
};
/**
* Minimum flow control window is set to 16 KB for both client and server.
* This means we can send up to this amount of data before handshake gets
* completed.
*/
#define LSQUIC_MIN_FCW (16 * 1024)
/* Each LSQUIC_DF_* value corresponds to es_* entry in
* lsquic_engine_settings below.
*/
/**
* By default, deprecated and experimental versions are not included.
2017-09-22 21:00:03 +00:00
*/
#define LSQUIC_DF_VERSIONS (LSQUIC_SUPPORTED_VERSIONS & \
~LSQUIC_DEPRECATED_VERSIONS & \
2017-09-22 21:00:03 +00:00
~LSQUIC_EXPERIMENTAL_VERSIONS)
#define LSQUIC_DF_CFCW_SERVER (3 * 1024 * 1024 / 2)
#define LSQUIC_DF_CFCW_CLIENT (15 * 1024 * 1024)
#define LSQUIC_DF_SFCW_SERVER (1 * 1024 * 1024)
#define LSQUIC_DF_SFCW_CLIENT (6 * 1024 * 1024)
#define LSQUIC_DF_MAX_STREAMS_IN 100
/**
* Default handshake timeout in microseconds.
*/
#define LSQUIC_DF_HANDSHAKE_TO (10 * 1000 * 1000)
#define LSQUIC_DF_IDLE_CONN_TO (30 * 1000 * 1000)
#define LSQUIC_DF_SILENT_CLOSE 1
/** Default value of maximum header list size. If set to non-zero value,
* SETTINGS_MAX_HEADER_LIST_SIZE will be sent to peer after handshake is
* completed (assuming the peer supports this setting frame type).
*/
#define LSQUIC_DF_MAX_HEADER_LIST_SIZE 0
/** Default value of UAID (user-agent ID). */
#define LSQUIC_DF_UA "LSQUIC"
#define LSQUIC_DF_STTL 86400
#define LSQUIC_DF_MAX_INCHOATE (1 * 1000 * 1000)
#define LSQUIC_DF_SUPPORT_SREJ_SERVER 1
#define LSQUIC_DF_SUPPORT_SREJ_CLIENT 0 /* TODO: client support */
/** Do not use NSTP by default */
#define LSQUIC_DF_SUPPORT_NSTP 0
#define LSQUIC_DF_SUPPORT_PUSH 1
#define LSQUIC_DF_SUPPORT_TCID0 1
/** By default, LSQUIC ignores Public Reset packets. */
#define LSQUIC_DF_HONOR_PRST 0
/** By default, infinite loop checks are turned on */
#define LSQUIC_DF_PROGRESS_CHECK 1000
/** By default, read/write events are dispatched in a loop */
#define LSQUIC_DF_RW_ONCE 0
/** By default, the threshold is not enabled */
#define LSQUIC_DF_PROC_TIME_THRESH 0
/** By default, packets are paced */
#define LSQUIC_DF_PACE_PACKETS 1
struct lsquic_engine_settings {
/**
* This is a bit mask wherein each bit corresponds to a value in
* enum lsquic_version. Client starts negotiating with the highest
* version and goes down. Server supports either of the versions
* specified here.
*
* @see lsquic_version
*/
unsigned es_versions;
/**
* Initial default CFCW.
*
* In server mode, per-connection values may be set lower than
* this if resources are scarce.
*
* Do not set es_cfcw and es_sfcw lower than @ref LSQUIC_MIN_FCW.
*
* @see es_max_cfcw
*/
unsigned es_cfcw;
/**
* Initial default SFCW.
*
* In server mode, per-connection values may be set lower than
* this if resources are scarce.
*
* Do not set es_cfcw and es_sfcw lower than @ref LSQUIC_MIN_FCW.
*
* @see es_max_sfcw
*/
unsigned es_sfcw;
/**
* This value is used to specify maximum allowed value CFCW is allowed
* to reach due to window auto-tuning. By default, this value is zero,
* which means that CFCW is not allowed to increase from its initial
* value.
*
* @see es_cfcw
*/
unsigned es_max_cfcw;
unsigned es_max_sfcw;
/** MIDS */
unsigned es_max_streams_in;
/**
* Handshake timeout in microseconds.
*
* For client, this can be set to an arbitrary value (zero turns the
* timeout off).
*
*/
unsigned long es_handshake_to;
/** ICSL in microseconds */
unsigned long es_idle_conn_to;
/** SCLS (silent close) */
int es_silent_close;
/**
* This corresponds to SETTINGS_MAX_HEADER_LIST_SIZE
* (RFC 7540, Section 6.5.2). 0 means no limit. Defaults
* to @ref LSQUIC_DF_MAX_HEADER_LIST_SIZE.
*/
unsigned es_max_header_list_size;
/** UAID -- User-Agent ID. Defaults to @ref LSQUIC_DF_UA. */
const char *es_ua;
uint32_t es_pdmd; /* One fixed value X509 */
uint32_t es_aead; /* One fixed value AESG */
uint32_t es_kexs; /* One fixed value C255 */
/**
* Support SREJ: for client side, this means supporting server's SREJ
* responses (this does not work yet) and for server side, this means
* generating SREJ instead of REJ when appropriate.
*/
int es_support_srej;
/**
* Setting this value to 0 means that
*
* For client:
* a) we send a SETTINGS frame to indicate that we do not support server
* push; and
* b) All incoming pushed streams get reset immediately.
* (For maximum effect, set es_max_streams_in to 0.)
*
*/
int es_support_push;
/**
* If set to true value, the server will not include connection ID in
* outgoing packets if client's CHLO specifies TCID=0.
*
* For client, this means including TCID=0 into CHLO message. TODO:
* this does not work yet.
*/
int es_support_tcid0;
/**
* Q037 and higher support "No STOP_WAITING frame" mode. When set, the
* client will send NSTP option in its Client Hello message and will not
* sent STOP_WAITING frames, while ignoring incoming STOP_WAITING frames,
* if any. Note that if the version negotiation happens to downgrade the
* client below Q037, this mode will *not* be used.
*
* This option does not affect the server, as it must support NSTP mode
* if it was specified by the client.
*/
int es_support_nstp;
/**
* If set to true value, the library will drop connections when it
* receives corresponding Public Reset packet. The default is to
* ignore these packets.
*/
int es_honor_prst;
/**
* A non-zero value enables internal checks that identify suspected
* infinite loops in user @ref on_read and @ref on_write callbacks
* and break them. An infinite loop may occur if user code keeps
* on performing the same operation without checking status, e.g.
* reading from a closed stream etc.
*
* The value of this parameter is as follows: should a callback return
* this number of times in a row without making progress (that is,
* reading, writing, or changing stream state), loop break will occur.
*
* The defaut value is @ref LSQUIC_DF_PROGRESS_CHECK.
*/
unsigned es_progress_check;
/**
* A non-zero value make stream dispatch its read-write events once
* per call.
*
* When zero, read and write events are dispatched until the stream
* is no longer readable or writeable, respectively, or until the
* user signals unwillingness to read or write using
* @ref lsquic_stream_wantread() or @ref lsquic_stream_wantwrite()
* or shuts down the stream.
*
* The default value is @ref LSQUIC_DF_RW_ONCE.
*/
int es_rw_once;
/**
* If set, this value specifies that number of microseconds that
* @ref lsquic_engine_process_conns() and
* @ref lsquic_engine_send_unsent_packets() are allowed to spend
* before returning.
2017-09-22 21:00:03 +00:00
*
* This is not an exact science and the connections must make
* progress, so the deadline is checked after all connections get
* a chance to tick (in the case of @ref lsquic_engine_process_conns())
* and at least one batch of packets is sent out.
2017-09-22 21:00:03 +00:00
*
* When processing function runs out of its time slice, immediate
[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
* calls to @ref lsquic_engine_has_unsent_packets() return false.
2017-09-22 21:00:03 +00:00
*
* The default value is @ref LSQUIC_DF_PROC_TIME_THRESH.
*/
unsigned es_proc_time_thresh;
/**
* If set to true, packet pacing is implemented per connection.
*
* The default value is @ref LSQUIC_DF_PACE_PACKETS.
*/
int es_pace_packets;
};
/* Initialize `settings' to default values */
void
lsquic_engine_init_settings (struct lsquic_engine_settings *,
unsigned lsquic_engine_flags);
/**
* Check settings for errors.
*
* @param settings Settings struct.
*
* @param flags Engine flags.
*
* @param err_buf Optional pointer to buffer into which error string
* is written.
* @param err_buf_sz Size of err_buf. No more than this number of bytes
* will be written to err_buf, including the NUL byte.
*
* @retval 0 Settings have no errors.
* @retval -1 There are errors in settings.
*/
int
lsquic_engine_check_settings (const struct lsquic_engine_settings *settings,
unsigned lsquic_engine_flags,
char *err_buf, size_t err_buf_sz);
struct lsquic_out_spec
{
const unsigned char *buf;
size_t sz;
const struct sockaddr *local_sa;
const struct sockaddr *dest_sa;
void *peer_ctx;
};
/**
* Returns number of packets successfully sent out or -1 on error. -1 should
* only be returned if no packets were sent out.
*/
typedef int (*lsquic_packets_out_f)(
void *packets_out_ctx,
const struct lsquic_out_spec *out_spec,
unsigned n_packets_out
);
/**
* The packet out memory interface is used by LSQUIC to get buffers to
* which outgoing packets will be written before they are passed to
* ea_packets_out callback. pmi_release() is called at some point,
* usually after the packet is sent successfully, to return the buffer
* to the pool.
*
* If not specified, malloc() and free() are used.
*/
struct lsquic_packout_mem_if
{
void * (*pmi_allocate) (void *pmi_ctx, size_t sz);
void (*pmi_release) (void *pmi_ctx, void *obj);
};
/* TODO: describe this important data structure */
typedef struct lsquic_engine_api
{
const struct lsquic_engine_settings *ea_settings; /* Optional */
const struct lsquic_stream_if *ea_stream_if;
void *ea_stream_if_ctx;
lsquic_packets_out_f ea_packets_out;
void *ea_packets_out_ctx;
/**
* Memory interface is optional.
*/
const struct lsquic_packout_mem_if *ea_pmi;
void *ea_pmi_ctx;
} lsquic_engine_api_t;
/**
* Create new engine.
*
* @param lsquic_engine_flags A bitmask of @ref LSENG_SERVER and
* @ref LSENG_HTTP
*/
lsquic_engine_t *
lsquic_engine_new (unsigned lsquic_engine_flags,
const struct lsquic_engine_api *);
/**
* Create a client connection to peer identified by `peer_ctx'.
* If `max_packet_size' is set to zero, it is inferred based on `peer_sa':
* 1350 for IPv6 and 1370 for IPv4.
*/
Latest changes - [API Change] lsquic_engine_connect() returns pointer to the connection object. - [API Change] Add lsquic_conn_get_engine() to get engine object from connection object. - [API Change] Add lsquic_conn_status() to query connection status. - [API Change] Add add lsquic_conn_set_ctx(). - [API Change] Add new timestamp format, e.g. 2017-03-21 13:43:46.671345 - [OPTIMIZATION] Process handshake STREAM frames as soon as packet arrives. - [OPTIMIZATION] Do not compile expensive send controller sanity check by default. - [OPTIMIZATION] Add fast path to gquic_be_gen_reg_pkt_header. - [OPTIMIZATION] Only make squeeze function call if necessary. - [OPTIMIZATION] Speed up Q039 ACK frame parsing. - [OPTIMIZATION] Fit most used elements of packet_out into first 64 bytes. - [OPTIMIZATION] Keep track of scheduled bytes instead of calculating. - [OPTIMIZATION] Prefetch next unacked packet when processing ACK. - [OPTIMIZATION] Leverage fact that ACK ranges and unacked list are. ordered. - [OPTIMIZATION] Reduce function pointer use for STREAM frame generation - Fix: reset incoming streams that arrive after we send GOAWAY. - Fix: delay client on_new_conn() call until connection is fully set up. - Fixes to buffered packets logic: splitting, STREAM frame elision. - Fix: do not dispatch on_write callback if no packets are available. - Fix WINDOW_UPDATE send and resend logic. - Fix STREAM frame extension code. - Fix: Drop unflushed data when stream is reset. - Switch to tracking CWND using bytes rather than packets. - Fix TCP friendly adjustment in cubic. - Fix: do not generate invalid STOP_WAITING frames during high packet loss. - Pacer fixes.
2018-02-26 21:01:16 +00:00
lsquic_conn_t *
2017-09-22 21:00:03 +00:00
lsquic_engine_connect (lsquic_engine_t *, const struct sockaddr *peer_sa,
Latest changes - [API Change] lsquic_engine_connect() returns pointer to the connection object. - [API Change] Add lsquic_conn_get_engine() to get engine object from connection object. - [API Change] Add lsquic_conn_status() to query connection status. - [API Change] Add add lsquic_conn_set_ctx(). - [API Change] Add new timestamp format, e.g. 2017-03-21 13:43:46.671345 - [OPTIMIZATION] Process handshake STREAM frames as soon as packet arrives. - [OPTIMIZATION] Do not compile expensive send controller sanity check by default. - [OPTIMIZATION] Add fast path to gquic_be_gen_reg_pkt_header. - [OPTIMIZATION] Only make squeeze function call if necessary. - [OPTIMIZATION] Speed up Q039 ACK frame parsing. - [OPTIMIZATION] Fit most used elements of packet_out into first 64 bytes. - [OPTIMIZATION] Keep track of scheduled bytes instead of calculating. - [OPTIMIZATION] Prefetch next unacked packet when processing ACK. - [OPTIMIZATION] Leverage fact that ACK ranges and unacked list are. ordered. - [OPTIMIZATION] Reduce function pointer use for STREAM frame generation - Fix: reset incoming streams that arrive after we send GOAWAY. - Fix: delay client on_new_conn() call until connection is fully set up. - Fixes to buffered packets logic: splitting, STREAM frame elision. - Fix: do not dispatch on_write callback if no packets are available. - Fix WINDOW_UPDATE send and resend logic. - Fix STREAM frame extension code. - Fix: Drop unflushed data when stream is reset. - Switch to tracking CWND using bytes rather than packets. - Fix TCP friendly adjustment in cubic. - Fix: do not generate invalid STOP_WAITING frames during high packet loss. - Pacer fixes.
2018-02-26 21:01:16 +00:00
void *peer_ctx, lsquic_conn_ctx_t *conn_ctx,
const char *hostname, unsigned short max_packet_size);
2017-09-22 21:00:03 +00:00
/**
* Pass incoming packet to the QUIC engine. This function can be called
* more than once in a row. After you add one or more packets, call
* lsquic_engine_process_conns_with_incoming() to schedule output, if any.
*
* @retval 0 Packet was processed by a real connection.
*
* @retval -1 Some error occurred. Possible reasons are invalid packet
* size or failure to allocate memory.
*/
int
lsquic_engine_packet_in (lsquic_engine_t *,
const unsigned char *packet_in_data, size_t packet_in_size,
const struct sockaddr *sa_local, const struct sockaddr *sa_peer,
void *peer_ctx);
/**
[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
* Process tickable connections. This function must be called often enough so
2017-09-22 21:00:03 +00:00
* that packets and connections do not expire.
*/
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_process_conns (lsquic_engine_t *engine);
2017-09-22 21:00:03 +00:00
/**
* Returns true if engine has some unsent packets. This happens if
* @ref ea_packets_out() could not send everything out.
*/
int
lsquic_engine_has_unsent_packets (lsquic_engine_t *engine);
/**
* Send out as many unsent packets as possibe: until we are out of unsent
* packets or until @ref ea_packets_out() fails.
*/
void
lsquic_engine_send_unsent_packets (lsquic_engine_t *engine);
void
lsquic_engine_destroy (lsquic_engine_t *);
void lsquic_conn_make_stream(lsquic_conn_t *);
/** Return number of delayed streams currently pending */
unsigned
lsquic_conn_n_pending_streams (const lsquic_conn_t *);
/** Cancel `n' pending streams. Returns new number of pending streams. */
unsigned
lsquic_conn_cancel_pending_streams (lsquic_conn_t *, unsigned n);
/**
* Mark connection as going away: send GOAWAY frame and do not accept
* any more incoming streams, nor generate streams of our own.
*/
void
lsquic_conn_going_away(lsquic_conn_t *conn);
/**
* This forces connection close. on_conn_closed and on_close callbacks
* will be called.
*/
void lsquic_conn_close(lsquic_conn_t *conn);
int lsquic_stream_wantread(lsquic_stream_t *s, int is_want);
ssize_t lsquic_stream_read(lsquic_stream_t *s, void *buf, size_t len);
ssize_t lsquic_stream_readv(lsquic_stream_t *s, const struct iovec *,
int iovcnt);
int lsquic_stream_wantwrite(lsquic_stream_t *s, int is_want);
/**
* Write `len' bytes to the stream. Returns number of bytes written, which
Latest changes - [API Change] Sendfile-like functionality is gone. The stream no longer opens files and deals with file descriptors. (Among other things, this makes the code more portable.) Three writing functions are provided: lsquic_stream_write lsquic_stream_writev lsquic_stream_writef (NEW) lsquic_stream_writef() is given an abstract reader that has function pointers for size() and read() functions which the user can implement. This is the most flexible way. lsquic_stream_write() and lsquic_stream_writev() are now both implemented as wrappers around lsquic_stream_writef(). - [OPTIMIZATION] When writing to stream, be it within or without the on_write() callback, place data directly into packet buffer, bypassing auxiliary data structures. This reduces amount of memory required, for the amount of data that can be written is limited by the congestion window. To support writes outside the on_write() callback, we keep N outgoing packet buffers per connection which can be written to by any stream. One half of these are reserved for the highest priority stream(s), the other half for all other streams. This way, low-priority streams cannot write instead of high-priority streams and, on the other hand, low-priority streams get a chance to send their packets out. The algorithm is as follows: - When user writes to stream outside of the callback: - If this is the highest priority stream, place it onto the reserved N/2 queue or fail. (The actual size of this queue is dynamic -- MAX(N/2, CWND) -- rather than N/2, allowing high-priority streams to write as much as can be sent.) - If the stream is not the highest priority, try to place the data onto the reserved N/2 queue or fail. - When tick occurs *and* more packets can be scheduled: - Transfer packets from the high N/2 queue to the scheduled queue. - If more scheduling is allowed: - Call on_write callbacks for highest-priority streams, placing resulting packets directly onto the scheduled queue. - If more scheduling is allowed: - Transfer packets from the low N/2 queue to the scheduled queue. - If more scheduling is allowed: - Call on_write callbacks for non-highest-priority streams, placing resulting packets directly onto the scheduled queue The number N is currently 20, but it could be varied based on resource usage. - If stream is created due to incoming headers, make headers readable from on_new. - Outgoing packets are no longer marked non-writeable to prevent placing more than one STREAM frame from the same stream into a single packet. This property is maintained via code flow and an explicit check. Packets for stream data are allocated using a special function. - STREAM frame elision is cheaper, as we only perform it if a reset stream has outgoing packets referencing it. - lsquic_packet_out_t is smaller, as stream_rec elements are now inside a union.
2017-10-31 13:35:58 +00:00
* may be smaller that `len'.
2017-09-22 21:00:03 +00:00
*/
ssize_t lsquic_stream_write(lsquic_stream_t *s, const void *buf, size_t len);
Latest changes - [API Change] Sendfile-like functionality is gone. The stream no longer opens files and deals with file descriptors. (Among other things, this makes the code more portable.) Three writing functions are provided: lsquic_stream_write lsquic_stream_writev lsquic_stream_writef (NEW) lsquic_stream_writef() is given an abstract reader that has function pointers for size() and read() functions which the user can implement. This is the most flexible way. lsquic_stream_write() and lsquic_stream_writev() are now both implemented as wrappers around lsquic_stream_writef(). - [OPTIMIZATION] When writing to stream, be it within or without the on_write() callback, place data directly into packet buffer, bypassing auxiliary data structures. This reduces amount of memory required, for the amount of data that can be written is limited by the congestion window. To support writes outside the on_write() callback, we keep N outgoing packet buffers per connection which can be written to by any stream. One half of these are reserved for the highest priority stream(s), the other half for all other streams. This way, low-priority streams cannot write instead of high-priority streams and, on the other hand, low-priority streams get a chance to send their packets out. The algorithm is as follows: - When user writes to stream outside of the callback: - If this is the highest priority stream, place it onto the reserved N/2 queue or fail. (The actual size of this queue is dynamic -- MAX(N/2, CWND) -- rather than N/2, allowing high-priority streams to write as much as can be sent.) - If the stream is not the highest priority, try to place the data onto the reserved N/2 queue or fail. - When tick occurs *and* more packets can be scheduled: - Transfer packets from the high N/2 queue to the scheduled queue. - If more scheduling is allowed: - Call on_write callbacks for highest-priority streams, placing resulting packets directly onto the scheduled queue. - If more scheduling is allowed: - Transfer packets from the low N/2 queue to the scheduled queue. - If more scheduling is allowed: - Call on_write callbacks for non-highest-priority streams, placing resulting packets directly onto the scheduled queue The number N is currently 20, but it could be varied based on resource usage. - If stream is created due to incoming headers, make headers readable from on_new. - Outgoing packets are no longer marked non-writeable to prevent placing more than one STREAM frame from the same stream into a single packet. This property is maintained via code flow and an explicit check. Packets for stream data are allocated using a special function. - STREAM frame elision is cheaper, as we only perform it if a reset stream has outgoing packets referencing it. - lsquic_packet_out_t is smaller, as stream_rec elements are now inside a union.
2017-10-31 13:35:58 +00:00
ssize_t lsquic_stream_writev(lsquic_stream_t *s, const struct iovec *vec, int count);
2017-09-22 21:00:03 +00:00
/**
Latest changes - [API Change] Sendfile-like functionality is gone. The stream no longer opens files and deals with file descriptors. (Among other things, this makes the code more portable.) Three writing functions are provided: lsquic_stream_write lsquic_stream_writev lsquic_stream_writef (NEW) lsquic_stream_writef() is given an abstract reader that has function pointers for size() and read() functions which the user can implement. This is the most flexible way. lsquic_stream_write() and lsquic_stream_writev() are now both implemented as wrappers around lsquic_stream_writef(). - [OPTIMIZATION] When writing to stream, be it within or without the on_write() callback, place data directly into packet buffer, bypassing auxiliary data structures. This reduces amount of memory required, for the amount of data that can be written is limited by the congestion window. To support writes outside the on_write() callback, we keep N outgoing packet buffers per connection which can be written to by any stream. One half of these are reserved for the highest priority stream(s), the other half for all other streams. This way, low-priority streams cannot write instead of high-priority streams and, on the other hand, low-priority streams get a chance to send their packets out. The algorithm is as follows: - When user writes to stream outside of the callback: - If this is the highest priority stream, place it onto the reserved N/2 queue or fail. (The actual size of this queue is dynamic -- MAX(N/2, CWND) -- rather than N/2, allowing high-priority streams to write as much as can be sent.) - If the stream is not the highest priority, try to place the data onto the reserved N/2 queue or fail. - When tick occurs *and* more packets can be scheduled: - Transfer packets from the high N/2 queue to the scheduled queue. - If more scheduling is allowed: - Call on_write callbacks for highest-priority streams, placing resulting packets directly onto the scheduled queue. - If more scheduling is allowed: - Transfer packets from the low N/2 queue to the scheduled queue. - If more scheduling is allowed: - Call on_write callbacks for non-highest-priority streams, placing resulting packets directly onto the scheduled queue The number N is currently 20, but it could be varied based on resource usage. - If stream is created due to incoming headers, make headers readable from on_new. - Outgoing packets are no longer marked non-writeable to prevent placing more than one STREAM frame from the same stream into a single packet. This property is maintained via code flow and an explicit check. Packets for stream data are allocated using a special function. - STREAM frame elision is cheaper, as we only perform it if a reset stream has outgoing packets referencing it. - lsquic_packet_out_t is smaller, as stream_rec elements are now inside a union.
2017-10-31 13:35:58 +00:00
* Used as argument to @ref lsquic_stream_writef()
2017-09-22 21:00:03 +00:00
*/
Latest changes - [API Change] Sendfile-like functionality is gone. The stream no longer opens files and deals with file descriptors. (Among other things, this makes the code more portable.) Three writing functions are provided: lsquic_stream_write lsquic_stream_writev lsquic_stream_writef (NEW) lsquic_stream_writef() is given an abstract reader that has function pointers for size() and read() functions which the user can implement. This is the most flexible way. lsquic_stream_write() and lsquic_stream_writev() are now both implemented as wrappers around lsquic_stream_writef(). - [OPTIMIZATION] When writing to stream, be it within or without the on_write() callback, place data directly into packet buffer, bypassing auxiliary data structures. This reduces amount of memory required, for the amount of data that can be written is limited by the congestion window. To support writes outside the on_write() callback, we keep N outgoing packet buffers per connection which can be written to by any stream. One half of these are reserved for the highest priority stream(s), the other half for all other streams. This way, low-priority streams cannot write instead of high-priority streams and, on the other hand, low-priority streams get a chance to send their packets out. The algorithm is as follows: - When user writes to stream outside of the callback: - If this is the highest priority stream, place it onto the reserved N/2 queue or fail. (The actual size of this queue is dynamic -- MAX(N/2, CWND) -- rather than N/2, allowing high-priority streams to write as much as can be sent.) - If the stream is not the highest priority, try to place the data onto the reserved N/2 queue or fail. - When tick occurs *and* more packets can be scheduled: - Transfer packets from the high N/2 queue to the scheduled queue. - If more scheduling is allowed: - Call on_write callbacks for highest-priority streams, placing resulting packets directly onto the scheduled queue. - If more scheduling is allowed: - Transfer packets from the low N/2 queue to the scheduled queue. - If more scheduling is allowed: - Call on_write callbacks for non-highest-priority streams, placing resulting packets directly onto the scheduled queue The number N is currently 20, but it could be varied based on resource usage. - If stream is created due to incoming headers, make headers readable from on_new. - Outgoing packets are no longer marked non-writeable to prevent placing more than one STREAM frame from the same stream into a single packet. This property is maintained via code flow and an explicit check. Packets for stream data are allocated using a special function. - STREAM frame elision is cheaper, as we only perform it if a reset stream has outgoing packets referencing it. - lsquic_packet_out_t is smaller, as stream_rec elements are now inside a union.
2017-10-31 13:35:58 +00:00
struct lsquic_reader
{
/**
* Not a ssize_t because the read function is not supposed to return
* an error. If an error occurs in the read function (for example, when
* reading from a file fails), it is supposed to deal with the error
* itself.
*/
size_t (*lsqr_read) (void *lsqr_ctx, void *buf, size_t count);
/**
* Return number of bytes remaining in the reader.
*/
size_t (*lsqr_size) (void *lsqr_ctx);
void *lsqr_ctx;
};
2017-09-22 21:00:03 +00:00
/**
Latest changes - [API Change] Sendfile-like functionality is gone. The stream no longer opens files and deals with file descriptors. (Among other things, this makes the code more portable.) Three writing functions are provided: lsquic_stream_write lsquic_stream_writev lsquic_stream_writef (NEW) lsquic_stream_writef() is given an abstract reader that has function pointers for size() and read() functions which the user can implement. This is the most flexible way. lsquic_stream_write() and lsquic_stream_writev() are now both implemented as wrappers around lsquic_stream_writef(). - [OPTIMIZATION] When writing to stream, be it within or without the on_write() callback, place data directly into packet buffer, bypassing auxiliary data structures. This reduces amount of memory required, for the amount of data that can be written is limited by the congestion window. To support writes outside the on_write() callback, we keep N outgoing packet buffers per connection which can be written to by any stream. One half of these are reserved for the highest priority stream(s), the other half for all other streams. This way, low-priority streams cannot write instead of high-priority streams and, on the other hand, low-priority streams get a chance to send their packets out. The algorithm is as follows: - When user writes to stream outside of the callback: - If this is the highest priority stream, place it onto the reserved N/2 queue or fail. (The actual size of this queue is dynamic -- MAX(N/2, CWND) -- rather than N/2, allowing high-priority streams to write as much as can be sent.) - If the stream is not the highest priority, try to place the data onto the reserved N/2 queue or fail. - When tick occurs *and* more packets can be scheduled: - Transfer packets from the high N/2 queue to the scheduled queue. - If more scheduling is allowed: - Call on_write callbacks for highest-priority streams, placing resulting packets directly onto the scheduled queue. - If more scheduling is allowed: - Transfer packets from the low N/2 queue to the scheduled queue. - If more scheduling is allowed: - Call on_write callbacks for non-highest-priority streams, placing resulting packets directly onto the scheduled queue The number N is currently 20, but it could be varied based on resource usage. - If stream is created due to incoming headers, make headers readable from on_new. - Outgoing packets are no longer marked non-writeable to prevent placing more than one STREAM frame from the same stream into a single packet. This property is maintained via code flow and an explicit check. Packets for stream data are allocated using a special function. - STREAM frame elision is cheaper, as we only perform it if a reset stream has outgoing packets referencing it. - lsquic_packet_out_t is smaller, as stream_rec elements are now inside a union.
2017-10-31 13:35:58 +00:00
* Write to stream using @ref lsquic_reader. This is the most generic of
* the write functions -- @ref lsquic_stream_write() and
* @ref lsquic_stream_writev() utilize the same mechanism.
*
* @retval Number of bytes written or -1 on error.
2017-09-22 21:00:03 +00:00
*/
Latest changes - [API Change] Sendfile-like functionality is gone. The stream no longer opens files and deals with file descriptors. (Among other things, this makes the code more portable.) Three writing functions are provided: lsquic_stream_write lsquic_stream_writev lsquic_stream_writef (NEW) lsquic_stream_writef() is given an abstract reader that has function pointers for size() and read() functions which the user can implement. This is the most flexible way. lsquic_stream_write() and lsquic_stream_writev() are now both implemented as wrappers around lsquic_stream_writef(). - [OPTIMIZATION] When writing to stream, be it within or without the on_write() callback, place data directly into packet buffer, bypassing auxiliary data structures. This reduces amount of memory required, for the amount of data that can be written is limited by the congestion window. To support writes outside the on_write() callback, we keep N outgoing packet buffers per connection which can be written to by any stream. One half of these are reserved for the highest priority stream(s), the other half for all other streams. This way, low-priority streams cannot write instead of high-priority streams and, on the other hand, low-priority streams get a chance to send their packets out. The algorithm is as follows: - When user writes to stream outside of the callback: - If this is the highest priority stream, place it onto the reserved N/2 queue or fail. (The actual size of this queue is dynamic -- MAX(N/2, CWND) -- rather than N/2, allowing high-priority streams to write as much as can be sent.) - If the stream is not the highest priority, try to place the data onto the reserved N/2 queue or fail. - When tick occurs *and* more packets can be scheduled: - Transfer packets from the high N/2 queue to the scheduled queue. - If more scheduling is allowed: - Call on_write callbacks for highest-priority streams, placing resulting packets directly onto the scheduled queue. - If more scheduling is allowed: - Transfer packets from the low N/2 queue to the scheduled queue. - If more scheduling is allowed: - Call on_write callbacks for non-highest-priority streams, placing resulting packets directly onto the scheduled queue The number N is currently 20, but it could be varied based on resource usage. - If stream is created due to incoming headers, make headers readable from on_new. - Outgoing packets are no longer marked non-writeable to prevent placing more than one STREAM frame from the same stream into a single packet. This property is maintained via code flow and an explicit check. Packets for stream data are allocated using a special function. - STREAM frame elision is cheaper, as we only perform it if a reset stream has outgoing packets referencing it. - lsquic_packet_out_t is smaller, as stream_rec elements are now inside a union.
2017-10-31 13:35:58 +00:00
ssize_t
lsquic_stream_writef (lsquic_stream_t *, struct lsquic_reader *);
2017-09-22 21:00:03 +00:00
Latest changes - [API Change] Sendfile-like functionality is gone. The stream no longer opens files and deals with file descriptors. (Among other things, this makes the code more portable.) Three writing functions are provided: lsquic_stream_write lsquic_stream_writev lsquic_stream_writef (NEW) lsquic_stream_writef() is given an abstract reader that has function pointers for size() and read() functions which the user can implement. This is the most flexible way. lsquic_stream_write() and lsquic_stream_writev() are now both implemented as wrappers around lsquic_stream_writef(). - [OPTIMIZATION] When writing to stream, be it within or without the on_write() callback, place data directly into packet buffer, bypassing auxiliary data structures. This reduces amount of memory required, for the amount of data that can be written is limited by the congestion window. To support writes outside the on_write() callback, we keep N outgoing packet buffers per connection which can be written to by any stream. One half of these are reserved for the highest priority stream(s), the other half for all other streams. This way, low-priority streams cannot write instead of high-priority streams and, on the other hand, low-priority streams get a chance to send their packets out. The algorithm is as follows: - When user writes to stream outside of the callback: - If this is the highest priority stream, place it onto the reserved N/2 queue or fail. (The actual size of this queue is dynamic -- MAX(N/2, CWND) -- rather than N/2, allowing high-priority streams to write as much as can be sent.) - If the stream is not the highest priority, try to place the data onto the reserved N/2 queue or fail. - When tick occurs *and* more packets can be scheduled: - Transfer packets from the high N/2 queue to the scheduled queue. - If more scheduling is allowed: - Call on_write callbacks for highest-priority streams, placing resulting packets directly onto the scheduled queue. - If more scheduling is allowed: - Transfer packets from the low N/2 queue to the scheduled queue. - If more scheduling is allowed: - Call on_write callbacks for non-highest-priority streams, placing resulting packets directly onto the scheduled queue The number N is currently 20, but it could be varied based on resource usage. - If stream is created due to incoming headers, make headers readable from on_new. - Outgoing packets are no longer marked non-writeable to prevent placing more than one STREAM frame from the same stream into a single packet. This property is maintained via code flow and an explicit check. Packets for stream data are allocated using a special function. - STREAM frame elision is cheaper, as we only perform it if a reset stream has outgoing packets referencing it. - lsquic_packet_out_t is smaller, as stream_rec elements are now inside a union.
2017-10-31 13:35:58 +00:00
/**
* Flush any buffered data. This triggers packetizing even a single byte
* into a separate frame. Flushing a closed stream is an error.
*
* @retval 0 Success
* @retval -1 Failure
*/
int
lsquic_stream_flush (lsquic_stream_t *s);
2017-09-22 21:00:03 +00:00
/**
* @typedef lsquic_http_header_t
* @brief HTTP header structure. Contains header name and value.
*
*/
typedef struct lsquic_http_header
{
struct iovec name;
struct iovec value;
} lsquic_http_header_t;
/**
* @typedef lsquic_http_headers_t
* @brief HTTP header list structure. Contains a list of HTTP headers in key/value pairs.
* used in API functions to pass headers.
*/
struct lsquic_http_headers
{
int count;
lsquic_http_header_t *headers;
};
int lsquic_stream_send_headers(lsquic_stream_t *s,
const lsquic_http_headers_t *h, int eos);
int lsquic_conn_is_push_enabled(lsquic_conn_t *c);
/** Possible values for how are 0, 1, and 2. See shutdown(2). */
int lsquic_stream_shutdown(lsquic_stream_t *s, int how);
int lsquic_stream_close(lsquic_stream_t *s);
/** Returns ID of the stream */
uint32_t
lsquic_stream_id (const lsquic_stream_t *s);
/**
* Returns stream ctx associated with the stream. (The context is what
* is returned by @ref on_new_stream callback).
*/
lsquic_stream_ctx_t *
lsquic_stream_get_ctx (const lsquic_stream_t *s);
/** Returns true if this is a pushed stream */
int
lsquic_stream_is_pushed (const lsquic_stream_t *s);
/**
* Refuse pushed stream. Call it from @ref on_new_stream.
*
* No need to call lsquic_stream_close() after this. on_close will be called.
*
* @see lsquic_stream_is_pushed
*/
int
lsquic_stream_refuse_push (lsquic_stream_t *s);
/**
* Get information associated with pushed stream:
*
* @param ref_stream_id Stream ID in response to which push promise was
* sent.
* @param headers Uncompressed request headers.
* @param headers_sz Size of uncompressed request headers, not counting
* the NUL byte.
*
* @retval 0 Success.
* @retval -1 This is not a pushed stream.
*/
int
lsquic_stream_push_info (const lsquic_stream_t *, uint32_t *ref_stream_id,
const char **headers, size_t *headers_sz);
/** Return current priority of the stream */
unsigned lsquic_stream_priority (const lsquic_stream_t *s);
/**
* Set stream priority. Valid priority values are 1 through 256, inclusive.
*
* @retval 0 Success.
* @retval -1 Priority value is invalid.
*/
int lsquic_stream_set_priority (lsquic_stream_t *s, unsigned priority);
/**
* Get a pointer to the connection object. Use it with lsquic_conn_*
* functions.
*/
lsquic_conn_t * lsquic_stream_conn(const lsquic_stream_t *s);
lsquic_stream_t *
lsquic_conn_get_stream_by_id (lsquic_conn_t *c, uint32_t stream_id);
/** Get connection ID */
lsquic_cid_t
lsquic_conn_id (const lsquic_conn_t *c);
Latest changes - [API Change] lsquic_engine_connect() returns pointer to the connection object. - [API Change] Add lsquic_conn_get_engine() to get engine object from connection object. - [API Change] Add lsquic_conn_status() to query connection status. - [API Change] Add add lsquic_conn_set_ctx(). - [API Change] Add new timestamp format, e.g. 2017-03-21 13:43:46.671345 - [OPTIMIZATION] Process handshake STREAM frames as soon as packet arrives. - [OPTIMIZATION] Do not compile expensive send controller sanity check by default. - [OPTIMIZATION] Add fast path to gquic_be_gen_reg_pkt_header. - [OPTIMIZATION] Only make squeeze function call if necessary. - [OPTIMIZATION] Speed up Q039 ACK frame parsing. - [OPTIMIZATION] Fit most used elements of packet_out into first 64 bytes. - [OPTIMIZATION] Keep track of scheduled bytes instead of calculating. - [OPTIMIZATION] Prefetch next unacked packet when processing ACK. - [OPTIMIZATION] Leverage fact that ACK ranges and unacked list are. ordered. - [OPTIMIZATION] Reduce function pointer use for STREAM frame generation - Fix: reset incoming streams that arrive after we send GOAWAY. - Fix: delay client on_new_conn() call until connection is fully set up. - Fixes to buffered packets logic: splitting, STREAM frame elision. - Fix: do not dispatch on_write callback if no packets are available. - Fix WINDOW_UPDATE send and resend logic. - Fix STREAM frame extension code. - Fix: Drop unflushed data when stream is reset. - Switch to tracking CWND using bytes rather than packets. - Fix TCP friendly adjustment in cubic. - Fix: do not generate invalid STOP_WAITING frames during high packet loss. - Pacer fixes.
2018-02-26 21:01:16 +00:00
/** Get pointer to the engine */
lsquic_engine_t *
lsquic_conn_get_engine (lsquic_conn_t *c);
2017-09-22 21:00:03 +00:00
int lsquic_conn_get_sockaddr(const lsquic_conn_t *c,
const struct sockaddr **local, const struct sockaddr **peer);
struct lsquic_logger_if {
int (*vprintf)(void *logger_ctx, const char *fmt, va_list args);
};
/**
* Enumerate timestamp styles supported by LSQUIC logger mechanism.
*/
enum lsquic_logger_timestamp_style {
/**
* No timestamp is generated.
*/
LLTS_NONE,
/**
* The timestamp consists of 24 hours, minutes, seconds, and
* milliseconds. Example: 13:43:46.671
*/
LLTS_HHMMSSMS,
/**
* Like above, plus date, e.g: 2017-03-21 13:43:46.671
*/
LLTS_YYYYMMDD_HHMMSSMS,
/**
* This is Chrome-like timestamp used by proto-quic. The timestamp
* includes month, date, hours, minutes, seconds, and microseconds.
*
* Example: 1223/104613.946956 (instead of 12/23 10:46:13.946956).
*
* This is to facilitate reading two logs side-by-side.
*/
LLTS_CHROMELIKE,
/**
* The timestamp consists of 24 hours, minutes, seconds, and
* microseconds. Example: 13:43:46.671123
*/
LLTS_HHMMSSUS,
Latest changes - [API Change] lsquic_engine_connect() returns pointer to the connection object. - [API Change] Add lsquic_conn_get_engine() to get engine object from connection object. - [API Change] Add lsquic_conn_status() to query connection status. - [API Change] Add add lsquic_conn_set_ctx(). - [API Change] Add new timestamp format, e.g. 2017-03-21 13:43:46.671345 - [OPTIMIZATION] Process handshake STREAM frames as soon as packet arrives. - [OPTIMIZATION] Do not compile expensive send controller sanity check by default. - [OPTIMIZATION] Add fast path to gquic_be_gen_reg_pkt_header. - [OPTIMIZATION] Only make squeeze function call if necessary. - [OPTIMIZATION] Speed up Q039 ACK frame parsing. - [OPTIMIZATION] Fit most used elements of packet_out into first 64 bytes. - [OPTIMIZATION] Keep track of scheduled bytes instead of calculating. - [OPTIMIZATION] Prefetch next unacked packet when processing ACK. - [OPTIMIZATION] Leverage fact that ACK ranges and unacked list are. ordered. - [OPTIMIZATION] Reduce function pointer use for STREAM frame generation - Fix: reset incoming streams that arrive after we send GOAWAY. - Fix: delay client on_new_conn() call until connection is fully set up. - Fixes to buffered packets logic: splitting, STREAM frame elision. - Fix: do not dispatch on_write callback if no packets are available. - Fix WINDOW_UPDATE send and resend logic. - Fix STREAM frame extension code. - Fix: Drop unflushed data when stream is reset. - Switch to tracking CWND using bytes rather than packets. - Fix TCP friendly adjustment in cubic. - Fix: do not generate invalid STOP_WAITING frames during high packet loss. - Pacer fixes.
2018-02-26 21:01:16 +00:00
/**
* Date and time using microsecond resolution,
* e.g: 2017-03-21 13:43:46.671123
*/
LLTS_YYYYMMDD_HHMMSSUS,
2017-09-22 21:00:03 +00:00
N_LLTS
};
/**
* Call this if you want to do something with LSQUIC log messages, as they
* are thrown out by default.
*/
void lsquic_logger_init(const struct lsquic_logger_if *, void *logger_ctx,
enum lsquic_logger_timestamp_style);
/**
* Set log level for all LSQUIC modules. Acceptable values are debug, info,
* notice, warning, error, alert, emerg, crit (case-insensitive).
*
* @retval 0 Success.
* @retval -1 Failure: log_level is not valid.
*/
int
lsquic_set_log_level (const char *log_level);
/**
* E.g. "event=debug"
*/
int
lsquic_logger_lopt (const char *optarg);
/**
* Return the list of QUIC versions (as bitmask) this engine instance
* supports.
*/
unsigned lsquic_engine_quic_versions (const lsquic_engine_t *);
/**
* This is one of the flags that can be passed to @ref lsquic_global_init.
* Use it to initialize LSQUIC for use in client mode.
*/
#define LSQUIC_GLOBAL_CLIENT (1 << 0)
/**
* This is one of the flags that can be passed to @ref lsquic_global_init.
* Use it to initialize LSQUIC for use in server mode.
*/
#define LSQUIC_GLOBAL_SERVER (1 << 1)
/**
* Initialize LSQUIC. This must be called before any other LSQUIC function
* is called. Returns 0 on success and -1 on failure.
*
* @param flags This a bitmask of @ref LSQUIC_GLOBAL_CLIENT and
* @ref LSQUIC_GLOBAL_SERVER. At least one of these
* flags should be specified.
*
* @retval 0 Success.
* @retval -1 Initialization failed.
*
* @see LSQUIC_GLOBAL_CLIENT
* @see LSQUIC_GLOBAL_SERVER
*/
int
lsquic_global_init (int flags);
/**
* Clean up global state created by @ref lsquic_global_init. Should be
* called after all LSQUIC engine instances are gone.
*/
void
lsquic_global_cleanup (void);
/**
* Get QUIC version used by the connection.
*
* @see lsquic_version
*/
enum lsquic_version
lsquic_conn_quic_version (const lsquic_conn_t *c);
/** Translate string QUIC version to LSQUIC QUIC version representation */
enum lsquic_version
lsquic_str2ver (const char *str, size_t len);
/**
* Get user-supplied context associated with the connection.
*/
lsquic_conn_ctx_t *
lsquic_conn_get_ctx (const lsquic_conn_t *c);
Latest changes - [API Change] lsquic_engine_connect() returns pointer to the connection object. - [API Change] Add lsquic_conn_get_engine() to get engine object from connection object. - [API Change] Add lsquic_conn_status() to query connection status. - [API Change] Add add lsquic_conn_set_ctx(). - [API Change] Add new timestamp format, e.g. 2017-03-21 13:43:46.671345 - [OPTIMIZATION] Process handshake STREAM frames as soon as packet arrives. - [OPTIMIZATION] Do not compile expensive send controller sanity check by default. - [OPTIMIZATION] Add fast path to gquic_be_gen_reg_pkt_header. - [OPTIMIZATION] Only make squeeze function call if necessary. - [OPTIMIZATION] Speed up Q039 ACK frame parsing. - [OPTIMIZATION] Fit most used elements of packet_out into first 64 bytes. - [OPTIMIZATION] Keep track of scheduled bytes instead of calculating. - [OPTIMIZATION] Prefetch next unacked packet when processing ACK. - [OPTIMIZATION] Leverage fact that ACK ranges and unacked list are. ordered. - [OPTIMIZATION] Reduce function pointer use for STREAM frame generation - Fix: reset incoming streams that arrive after we send GOAWAY. - Fix: delay client on_new_conn() call until connection is fully set up. - Fixes to buffered packets logic: splitting, STREAM frame elision. - Fix: do not dispatch on_write callback if no packets are available. - Fix WINDOW_UPDATE send and resend logic. - Fix STREAM frame extension code. - Fix: Drop unflushed data when stream is reset. - Switch to tracking CWND using bytes rather than packets. - Fix TCP friendly adjustment in cubic. - Fix: do not generate invalid STOP_WAITING frames during high packet loss. - Pacer fixes.
2018-02-26 21:01:16 +00:00
/**
* Set user-supplied context associated with the connection.
*/
void lsquic_conn_set_ctx (lsquic_conn_t *c, lsquic_conn_ctx_t *h);
2017-09-22 21:00:03 +00:00
/**
* Get peer context associated with the connection.
2017-09-22 21:00:03 +00:00
*/
void *lsquic_conn_get_peer_ctx( const lsquic_conn_t *lconn);
/**
* Abort connection.
*/
void
lsquic_conn_abort (lsquic_conn_t *c);
/**
[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
* Returns true if there are connections to be processed, false otherwise.
* If true, `diff' is set to the difference between the earliest advisory
* tick time and now. If the former is in the past, the value of `diff'
* is negative.
2017-09-22 21:00:03 +00:00
*/
int
lsquic_engine_earliest_adv_tick (lsquic_engine_t *engine, int *diff);
/**
* Return number of connections whose advisory tick time is before current
* time plus `from_now' microseconds from now. `from_now' can be negative.
2017-09-22 21:00:03 +00:00
*/
unsigned
lsquic_engine_count_attq (lsquic_engine_t *engine, int from_now);
Latest changes - [API Change] lsquic_engine_connect() returns pointer to the connection object. - [API Change] Add lsquic_conn_get_engine() to get engine object from connection object. - [API Change] Add lsquic_conn_status() to query connection status. - [API Change] Add add lsquic_conn_set_ctx(). - [API Change] Add new timestamp format, e.g. 2017-03-21 13:43:46.671345 - [OPTIMIZATION] Process handshake STREAM frames as soon as packet arrives. - [OPTIMIZATION] Do not compile expensive send controller sanity check by default. - [OPTIMIZATION] Add fast path to gquic_be_gen_reg_pkt_header. - [OPTIMIZATION] Only make squeeze function call if necessary. - [OPTIMIZATION] Speed up Q039 ACK frame parsing. - [OPTIMIZATION] Fit most used elements of packet_out into first 64 bytes. - [OPTIMIZATION] Keep track of scheduled bytes instead of calculating. - [OPTIMIZATION] Prefetch next unacked packet when processing ACK. - [OPTIMIZATION] Leverage fact that ACK ranges and unacked list are. ordered. - [OPTIMIZATION] Reduce function pointer use for STREAM frame generation - Fix: reset incoming streams that arrive after we send GOAWAY. - Fix: delay client on_new_conn() call until connection is fully set up. - Fixes to buffered packets logic: splitting, STREAM frame elision. - Fix: do not dispatch on_write callback if no packets are available. - Fix WINDOW_UPDATE send and resend logic. - Fix STREAM frame extension code. - Fix: Drop unflushed data when stream is reset. - Switch to tracking CWND using bytes rather than packets. - Fix TCP friendly adjustment in cubic. - Fix: do not generate invalid STOP_WAITING frames during high packet loss. - Pacer fixes.
2018-02-26 21:01:16 +00:00
enum LSQUIC_CONN_STATUS
{
LSCONN_ST_HSK_IN_PROGRESS,
LSCONN_ST_CONNECTED,
LSCONN_ST_HSK_FAILURE,
LSCONN_ST_GOING_AWAY,
LSCONN_ST_TIMED_OUT,
/* If es_honor_prst is not set, the connection will never get public
* reset packets and this flag will not be set.
*/
LSCONN_ST_RESET,
LSCONN_ST_USER_ABORTED,
LSCONN_ST_ERROR,
LSCONN_ST_CLOSED,
};
enum LSQUIC_CONN_STATUS
lsquic_conn_status (lsquic_conn_t *, char *errbuf, size_t bufsz);
extern const char *const
lsquic_ver2str[N_LSQVER];
2017-09-22 21:00:03 +00:00
#ifdef __cplusplus
}
#endif
#endif //__LSQUIC_H__