LCOV - code coverage report
Current view: top level - waltz/quic - fd_quic_conn.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 69 98 70.4 %
Date: 2025-01-08 12:08:44 Functions: 6 7 85.7 %

          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             : 
       6             : /* define a map for stream_id -> stream* */
       7             : #define MAP_NAME              fd_quic_stream_map
       8       18528 : #define MAP_KEY               stream_id
       9         390 : #define MAP_T                 fd_quic_stream_map_t
      10       18528 : #define MAP_KEY_NULL          FD_QUIC_STREAM_ID_UNUSED
      11             : #define MAP_KEY_INVAL(key)    ((key)==MAP_KEY_NULL)
      12             : #define MAP_QUERY_OPT         1
      13             : 
      14             : #include "../../util/tmpl/fd_map_dynamic.c"
      15             : 
      16             : struct fd_quic_conn_layout {
      17             :   int   stream_map_lg;
      18             :   ulong stream_map_off;
      19             :   ulong pkt_meta_off;
      20             : };
      21             : typedef struct fd_quic_conn_layout fd_quic_conn_layout_t;
      22             : 
      23             : /* TODO maybe introduce a separate parameter for size of pkt_meta
      24             :    pool? */
      25             : ulong
      26       10935 : fd_quic_conn_align( void ) {
      27       10935 :   ulong align = fd_ulong_max( alignof( fd_quic_conn_t ), alignof( fd_quic_stream_t ) );
      28       10935 :   align = fd_ulong_max( align, alignof( fd_quic_pkt_meta_t ) );
      29       10935 :   align = fd_ulong_max( align, fd_quic_stream_map_align() );
      30       10935 :   return align;
      31       10935 : }
      32             : 
      33             : static ulong
      34             : fd_quic_conn_footprint_ext( fd_quic_limits_t const * limits,
      35      327321 :                             fd_quic_conn_layout_t *  layout ) {
      36             : 
      37      327321 :   ulong inflight_pkt_cnt = limits->inflight_pkt_cnt;
      38      327321 :   if( FD_UNLIKELY( inflight_pkt_cnt==0UL ) ) return 0UL;
      39             : 
      40      327321 :   ulong stream_id_cnt = limits->stream_id_cnt;
      41             : 
      42      327321 :   ulong off  = 0;
      43             : 
      44      327321 :   off += sizeof( fd_quic_conn_t );
      45             : 
      46      327321 :   if( stream_id_cnt ) {
      47             :     /* allocate space for stream hash map */
      48             :     /* about a million seems like a decent bound, with expected values up to 20,000 */
      49         312 :     ulong lg = 0;
      50        1980 :     while( lg < 20 && (1ul<<lg) < (ulong)((double)stream_id_cnt*FD_QUIC_DEFAULT_SPARSITY) ) {
      51        1668 :       lg++;
      52        1668 :     }
      53         312 :     layout->stream_map_lg = (int)lg;
      54             : 
      55         312 :     off                     = fd_ulong_align_up( off, fd_quic_stream_align() );
      56         312 :     layout->stream_map_off  = off;
      57         312 :     off                    += fd_quic_stream_map_footprint( (int)lg );
      58      327009 :   } else {
      59      327009 :     layout->stream_map_lg  = 0;
      60      327009 :     layout->stream_map_off = 0UL;
      61      327009 :   }
      62             : 
      63             :   /* allocate space for packet metadata */
      64      327321 :   off                   = fd_ulong_align_up( off, alignof(fd_quic_pkt_meta_t) );
      65      327321 :   layout->pkt_meta_off  = off;
      66      327321 :   off                  += inflight_pkt_cnt * sizeof(fd_quic_pkt_meta_t);
      67             : 
      68             :   /* align total footprint */
      69             : 
      70      327321 :   return off;
      71      327321 : }
      72             : 
      73             : FD_FN_PURE ulong
      74       10935 : fd_quic_conn_footprint( fd_quic_limits_t const * limits ) {
      75       10935 :   fd_quic_conn_layout_t layout;
      76       10935 :   return fd_quic_conn_footprint_ext( limits, &layout );
      77       10935 : }
      78             : 
      79             : fd_quic_conn_t *
      80             : fd_quic_conn_new( void *                   mem,
      81             :                   fd_quic_t *              quic,
      82      316386 :                   fd_quic_limits_t const * limits ) {
      83             : 
      84             :   /* Argument checks */
      85             : 
      86      316386 :   if( FD_UNLIKELY( !mem ) ) {
      87           0 :     FD_LOG_WARNING(( "NULL mem" ));
      88           0 :     return NULL;
      89           0 :   }
      90             : 
      91      316386 :   ulong align = fd_quic_conn_align();
      92      316386 :   if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)mem, align ) ) ) {
      93           0 :     FD_LOG_WARNING(( "misaligned mem" ));
      94           0 :     return NULL;
      95           0 :   }
      96             : 
      97      316386 :   if( FD_UNLIKELY( !quic ) ) {
      98           0 :     FD_LOG_WARNING(( "NULL quic" ));
      99           0 :     return NULL;
     100           0 :   }
     101             : 
     102      316386 :   if( FD_UNLIKELY( !limits ) ) {
     103           0 :     FD_LOG_WARNING(( "NULL limits" ));
     104           0 :     return NULL;
     105           0 :   }
     106             : 
     107      316386 :   fd_quic_conn_layout_t layout = {0};
     108      316386 :   ulong footprint = fd_quic_conn_footprint_ext( limits, &layout );
     109      316386 :   if( FD_UNLIKELY( !footprint ) ) {
     110           0 :     FD_LOG_WARNING(( "invalid footprint for limits" ));
     111           0 :     return NULL;
     112           0 :   }
     113             : 
     114             :   /* Initialize conn */
     115             : 
     116      316386 :   fd_quic_conn_t * conn = (fd_quic_conn_t *)mem;
     117      316386 :   fd_memset( conn, 0, sizeof(fd_quic_conn_t) );
     118             : 
     119      316386 :   conn->quic  = quic;
     120      316386 :   conn->state = FD_QUIC_CONN_STATE_INVALID;
     121             : 
     122             :   /* Initialize streams */
     123             : 
     124      316386 :   FD_QUIC_STREAM_LIST_SENTINEL( conn->send_streams );
     125      316386 :   FD_QUIC_STREAM_LIST_SENTINEL( conn->used_streams );
     126             : 
     127             :   /* Initialize stream hash map */
     128             : 
     129      316386 :   if( layout.stream_map_off ) {
     130         195 :     ulong stream_map_laddr = (ulong)mem + layout.stream_map_off;
     131         195 :     conn->stream_map = fd_quic_stream_map_join( fd_quic_stream_map_new( (void *)stream_map_laddr, layout.stream_map_lg ) );
     132         195 :     if( FD_UNLIKELY( !conn->stream_map ) ) return NULL;
     133         195 :   }
     134             : 
     135             :   /* Initialize packet meta pool */
     136             : 
     137      316386 :   ulong                pkt_meta_cnt = limits->inflight_pkt_cnt;
     138      316386 :   fd_quic_pkt_meta_t * pkt_meta     = (fd_quic_pkt_meta_t *)( (ulong)mem + layout.pkt_meta_off );
     139      316386 :   fd_memset( pkt_meta, 0, pkt_meta_cnt*sizeof(fd_quic_pkt_meta_t) );
     140             : 
     141             :   /* store pointer to storage and size */
     142      316386 :   conn->pkt_meta_mem = pkt_meta;
     143             : 
     144      316386 :   return conn;
     145      316386 : }
     146             : 
     147             : /* set the user-defined context value on the connection */
     148             : void
     149       18003 : fd_quic_conn_set_context( fd_quic_conn_t * conn, void * context ) {
     150       18003 :   conn->context = context;
     151       18003 : }
     152             : 
     153             : 
     154             : /* get the user-defined context value from a connection */
     155             : void *
     156       12000 : fd_quic_conn_get_context( fd_quic_conn_t * conn ) {
     157       12000 :   return conn->context;
     158       12000 : }
     159             : 
     160             : char const *
     161           0 : fd_quic_conn_reason_name( uint reason ) {
     162             :   /* define mapping from reason code to name as a c-string */
     163           0 :   static char const * fd_quic_conn_reason_names[] = {
     164           0 : #   define COMMA ,
     165           0 : #   define _(NAME,CODE,DESC) \
     166           0 :     [CODE] = #NAME
     167           0 :     FD_QUIC_REASON_CODES(_,COMMA)
     168           0 : #   undef _
     169           0 : #   undef COMMA
     170           0 :   };
     171             : 
     172           0 : # define ELEMENTS ( sizeof(fd_quic_conn_reason_names) / sizeof(fd_quic_conn_reason_names[0]) )
     173             : 
     174           0 :   if( FD_UNLIKELY( reason >= ELEMENTS ) ) return "N/A";
     175             : 
     176           0 :   char const * name = fd_quic_conn_reason_names[reason];
     177             : 
     178           0 :   return name ? name : "N/A";
     179           0 : }

Generated by: LCOV version 1.14