Skip to content

Internal structures and states

Christian Huitema edited this page Apr 7, 2020 · 3 revisions

Contexts and connections

Picoquic code uses 2 main objects types to represent the Quic context (type picoquic_quic_t) and the Quic connection (type picoquic_cnx_t). There is normally just one Quic context per process, and one Quic connection per connection.

The Quic context gathers the information common to all connections, such as for example the length of connection identifiers or the value of the reset secret. The Quic context keeps track of all connections created through the call to picoquic_create_cnx. These lists of connections are used in context level calls, such as:

  • Arrival of a packet on a socket shared by all connections: picoquic_incoming_packet
  • Preparing the next packet from one of the connections: picoquic_prepare_next_packet

The Quic connection context tracks all the state of a connection, either directly or through a set of other objects such as paths or packet contexts.

Connection context and dependencies

The connection context includes variables describing the state of the connection, as well as pointers or tables of the following types:

  • TLS context for the connection, represented by a void *, because the structure depends on the specific TLS stack used in the implementation. Of course, we only use picotls today. See documentation of TLS usage (TBD).

  • List of connections: the management of connections requires listing the connection pointer in several lists managed by the Quic context, including a double linked list of connections ordered by wake time.

  • Queue of miscellaneous frames: frames that are produced outside the regular polling process, either because they are one-off or because they are inserted by test programs. Each frame is represented by a picoquic_misc_frame_header_t object.

  • tls_stream and crypto context: two tables indexed by epoch picoquic_epoch_enum, listing the data received from the peer in the TLS Stream for the epoch (during handshake) and the current crypto context used for encrypting or decrypting packets for that epoch. (Note that encryption keys are opaquely stored in the crypto contexts.) In addition, the "new" and "old" crypto contexts are used to manage rotation of the 1-RTT key.

  • Table of packet contexts, indexed by context number picoquic_packet_context_enum. This is almost the same concept as epoch, except that 0-RTT and 1-RTT share a single context. (TODO: unify in a future code reorg.) The packet context maintains the transmission data for a class of packets, such as sequence number, list of unacknowledged packets, or sack dashboard. Note that the packet structures are allocated once and reused, and that the list of empty packets in maintained in the Quic context.

  • Management of streams: lists of the picoquic_stream_head_t objects describing the Quic streams in progress on the connection. There are two lists: a splay of all open frames, and a chained list of the frames currently ready to send data.

  • Queue of datagram frames: datagram frames that are ready to be sent. Each frame is represented by a picoquic_misc_frame_header_t object. These structures will probably be revisited as we understand datagram usage better.

  • Table of paths: a variable size array of path pointers allocated to match the number of active paths. Each path is defined by the four-tuple of local and remote IP addresses and UDP ports. There is a picoquic_path_t object for each path.

  • List of connection ID sent to the peer and not yet retired. Each ID is documented in an object of type picoquic_local_cnxid_t. Each of the local connection ID is registered with the Quic Context. They can be used by the peer at any time as destination connection ID. The Quic context will use its table to assign the incoming packet to the proper connection.

Path context

Each path context maintains data used to manage transmission or tests on that path, including a pointer to the local connection ID last used by the peer for sending data on the path, and a copy of the connection ID used for sending to that peer.

The path context includes a pointer to the congestion context for the path, allocated when the path is created by the selected congestion control algorithm.

Picoquic is "almost ready" to support multi-path operation, but the current code only send data to the path number 0. In case of migration, the newly selected path is moved to index 0, and the old path is marked "deprecated".

Clone this wiki locally