Line data Source code
1 : #include "fd_quic_conn.h" 2 : #include "fd_quic_common.h" 3 : #include "fd_quic_enum.h" 4 : #include "fd_quic_pkt_meta.h" 5 : #include "fd_quic_private.h" 6 : 7 : /* define a map for stream_id -> stream* */ 8 : #define MAP_NAME fd_quic_stream_map 9 28032 : #define MAP_KEY stream_id 10 942 : #define MAP_T fd_quic_stream_map_t 11 28032 : #define MAP_KEY_NULL FD_QUIC_STREAM_ID_UNUSED 12 : #define MAP_KEY_INVAL(key) ((key)==MAP_KEY_NULL) 13 : #define MAP_QUERY_OPT 1 14 : 15 : #include "../../util/tmpl/fd_map_dynamic.c" 16 : 17 : struct fd_quic_conn_layout { 18 : int stream_map_lg; 19 : ulong stream_map_off; 20 : }; 21 : typedef struct fd_quic_conn_layout fd_quic_conn_layout_t; 22 : 23 : ulong 24 655362 : fd_quic_conn_align( void ) { 25 655362 : ulong align = fd_ulong_max( alignof( fd_quic_conn_t ), alignof( fd_quic_stream_t ) ); 26 655362 : align = fd_ulong_max( align, fd_quic_stream_map_align() ); 27 655362 : return align; 28 655362 : } 29 : 30 : static ulong 31 : fd_quic_conn_footprint_ext( fd_quic_limits_t const * limits, 32 327681 : fd_quic_conn_layout_t * layout ) { 33 : 34 327681 : ulong stream_id_cnt = limits->stream_id_cnt; 35 : 36 327681 : ulong off = 0; 37 : 38 327681 : off += sizeof( fd_quic_conn_t ); 39 : 40 327681 : if( stream_id_cnt ) { 41 : /* allocate space for stream hash map */ 42 : /* about a million seems like a decent bound, with expected values up to 20,000 */ 43 675 : ulong lg = 0; 44 4212 : while( lg < 20 && (1ul<<lg) < (ulong)((double)stream_id_cnt*FD_QUIC_DEFAULT_SPARSITY) ) { 45 3537 : lg++; 46 3537 : } 47 675 : layout->stream_map_lg = (int)lg; 48 : 49 675 : off = fd_ulong_align_up( off, fd_quic_stream_align() ); 50 675 : layout->stream_map_off = off; 51 675 : off += fd_quic_stream_map_footprint( (int)lg ); 52 327006 : } else { 53 327006 : layout->stream_map_lg = 0; 54 327006 : layout->stream_map_off = 0UL; 55 327006 : } 56 : 57 327681 : return fd_ulong_align_up( off, fd_quic_conn_align() ); 58 327681 : } 59 : 60 : ulong 61 11019 : fd_quic_conn_footprint( fd_quic_limits_t const * limits ) { 62 11019 : fd_quic_conn_layout_t layout; 63 11019 : return fd_quic_conn_footprint_ext( limits, &layout ); 64 11019 : } 65 : 66 : fd_quic_conn_t * 67 : fd_quic_conn_new( void * mem, 68 : fd_quic_t * quic, 69 316662 : fd_quic_limits_t const * limits ) { 70 : 71 : /* Argument checks */ 72 : 73 316662 : if( FD_UNLIKELY( !mem ) ) { 74 0 : FD_LOG_WARNING(( "NULL mem" )); 75 0 : return NULL; 76 0 : } 77 : 78 316662 : ulong align = fd_quic_conn_align(); 79 316662 : if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)mem, align ) ) ) { 80 0 : FD_LOG_WARNING(( "misaligned mem" )); 81 0 : return NULL; 82 0 : } 83 : 84 316662 : if( FD_UNLIKELY( !quic ) ) { 85 0 : FD_LOG_WARNING(( "NULL quic" )); 86 0 : return NULL; 87 0 : } 88 : 89 316662 : if( FD_UNLIKELY( !limits ) ) { 90 0 : FD_LOG_WARNING(( "NULL limits" )); 91 0 : return NULL; 92 0 : } 93 : 94 316662 : fd_quic_conn_layout_t layout = {0}; 95 316662 : ulong footprint = fd_quic_conn_footprint_ext( limits, &layout ); 96 316662 : if( FD_UNLIKELY( !footprint ) ) { 97 0 : FD_LOG_WARNING(( "invalid footprint for limits" )); 98 0 : return NULL; 99 0 : } 100 : 101 : /* Initialize conn */ 102 : 103 316662 : fd_quic_conn_t * conn = (fd_quic_conn_t *)mem; 104 316662 : fd_memset( conn, 0, sizeof(fd_quic_conn_t) ); 105 : 106 316662 : conn->quic = quic; 107 316662 : fd_quic_set_conn_state( conn, FD_QUIC_CONN_STATE_INVALID ); 108 : 109 : /* Initialize streams */ 110 : 111 316662 : FD_QUIC_STREAM_LIST_SENTINEL( conn->send_streams ); 112 316662 : FD_QUIC_STREAM_LIST_SENTINEL( conn->used_streams ); 113 : 114 : /* Initialize stream hash map */ 115 : 116 316662 : if( layout.stream_map_off ) { 117 471 : ulong stream_map_laddr = (ulong)mem + layout.stream_map_off; 118 471 : conn->stream_map = fd_quic_stream_map_join( fd_quic_stream_map_new( (void *)stream_map_laddr, layout.stream_map_lg ) ); 119 471 : if( FD_UNLIKELY( !conn->stream_map ) ) return NULL; 120 471 : } 121 : 122 : /* Initialize packet meta tracker */ 123 316662 : fd_quic_state_t * state = fd_quic_get_state( quic ); 124 316662 : fd_quic_pkt_meta_tracker_init( &conn->pkt_meta_tracker, 125 316662 : quic->limits.inflight_frame_cnt, 126 316662 : state->pkt_meta_pool ); 127 : 128 : 129 316662 : return conn; 130 316662 : } 131 : 132 : /* set the user-defined context value on the connection */ 133 : void 134 18003 : fd_quic_conn_set_context( fd_quic_conn_t * conn, void * context ) { 135 18003 : conn->context = context; 136 18003 : } 137 : 138 : 139 : /* get the user-defined context value from a connection */ 140 : void * 141 3 : fd_quic_conn_get_context( fd_quic_conn_t * conn ) { 142 3 : return conn->context; 143 3 : } 144 : 145 : char const * 146 0 : fd_quic_conn_reason_name( uint reason ) { 147 : /* define mapping from reason code to name as a c-string */ 148 0 : static char const * fd_quic_conn_reason_names[] = { 149 0 : # define COMMA , 150 0 : # define _(NAME,CODE,DESC) \ 151 0 : [CODE] = #NAME 152 0 : FD_QUIC_REASON_CODES(_,COMMA) 153 0 : # undef _ 154 0 : # undef COMMA 155 0 : }; 156 : 157 0 : # define ELEMENTS ( sizeof(fd_quic_conn_reason_names) / sizeof(fd_quic_conn_reason_names[0]) ) 158 : 159 0 : if( FD_UNLIKELY( reason >= ELEMENTS ) ) return "N/A"; 160 : 161 0 : char const * name = fd_quic_conn_reason_names[reason]; 162 : 163 0 : return name ? name : "N/A"; 164 0 : }