Line data Source code
1 : #ifndef HEADER_fd_src_waltz_quic_fd_quic_conn_id_h 2 : #define HEADER_fd_src_waltz_quic_fd_quic_conn_id_h 3 : 4 : #include "../../util/fd_util_base.h" 5 : #include "../../util/rng/fd_rng.h" 6 : #include <string.h> 7 : 8 : /* TODO move this into more reasonable place */ 9 27039558 : #define FD_QUIC_MAX_CONN_ID_SZ 20 10 : 11 : /* Firedancer connection ids will sized thus */ 12 375120 : #define FD_QUIC_CONN_ID_SZ 8 13 : 14 : /* pad fd_quic_conn_id struct */ 15 : #define FD_QUIC_CONN_ID_PAD (24 - 1 - FD_QUIC_MAX_CONN_ID_SZ) 16 : 17 : /* fd_quic_conn_id_t contains a QUIC connection ID with size in [0,20] 18 : bytes. The unused conn_id high bytes MUST be zeroed. */ 19 : 20 : struct fd_quic_conn_id { 21 : uchar sz; 22 : uchar conn_id[FD_QUIC_MAX_CONN_ID_SZ]; 23 : 24 : /* explicitly pad for alignment */ 25 : uchar pad[FD_QUIC_CONN_ID_PAD]; 26 : }; 27 : typedef struct fd_quic_conn_id fd_quic_conn_id_t; 28 : 29 : FD_PROTOTYPES_BEGIN 30 : 31 : static inline fd_quic_conn_id_t 32 : fd_quic_conn_id_new( void const * conn_id, 33 649905 : ulong sz /* in [0,20] */ ) { 34 : /* TODO debug assertion verifying sz */ 35 649905 : fd_quic_conn_id_t id = { .sz = (uchar)sz }; 36 649905 : fd_memcpy( id.conn_id, conn_id, sz ); 37 649905 : return id; 38 649905 : } 39 : 40 : /* fd_quic_conn_id_rand creates a new random 8 byte conn ID. Returns 41 : conn ID. Cannot fail. */ 42 : 43 : static inline fd_quic_conn_id_t * 44 : fd_quic_conn_id_rand( fd_quic_conn_id_t * conn_id, 45 6012 : fd_rng_t * rng ) { 46 : 47 : /* from rfc9000: 48 : Each endpoint selects connection IDs using an implementation-specific (and 49 : perhaps deployment-specific) method that will allow packets with that 50 : connection ID to be routed back to the endpoint and to be identified by 51 : the endpoint upon receipt. */ 52 : /* this means we can generate a connection id with the property that it can 53 : be delivered to the same endpoint by flow control */ 54 : /* TODO load balancing / flow steering */ 55 : 56 : /* padding must be set to zero also */ 57 6012 : *conn_id = (fd_quic_conn_id_t){ .sz = 8u, .conn_id = {0u}, .pad = {0u} }; 58 6012 : FD_STORE( ulong, conn_id->conn_id, fd_rng_ulong( rng ) ); 59 6012 : return conn_id; 60 6012 : } 61 : 62 : FD_PROTOTYPES_END 63 : 64 : /* Defines a NULL connection id 65 : Used as a NULL key in hash maps 66 : Note that the QUIC protocol supports zero-length connection ids. 67 : Hence, an all-zero fd_quic_conn_id_t wouldn't work as a NULL key */ 68 : #define FD_QUIC_CONN_ID_NULL ((fd_quic_conn_id_t){ .sz = 0xff }) 69 : 70 : /* define some functions for using fd_quic_conn_id as a key */ 71 : 72 : /* is this an invalid connection id */ 73 : #define FD_QUIC_CONN_ID_INVAL(CONN_ID) ((CONN_ID).sz > FD_QUIC_MAX_CONN_ID_SZ) 74 : 75 : /* are these connection ids the same connection id 76 : for this to work properly, all unused bytes are set to zero */ 77 : #define FD_QUIC_CONN_ID_EQUAL(LHS,RHS) \ 78 : (memcmp(&(LHS),&(RHS),sizeof(fd_quic_conn_id_t))==0) 79 : 80 : /* fd_quic_net_endpoint_t identifies a UDP/IP network endpoint. 81 : Stored in host endian. May change during the lifetime of the conn. */ 82 : 83 : struct fd_quic_net_endpoint { 84 : uint ip_addr; 85 : ushort udp_port; 86 : }; 87 : typedef struct fd_quic_net_endpoint fd_quic_net_endpoint_t; 88 : 89 : #endif /* HEADER_fd_src_waltz_quic_fd_quic_conn_id_h */ 90 :