LCOV - code coverage report
Current view: top level - waltz/quic/templ - fd_quic_transport_params.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 123 0.0 %
Date: 2026-03-19 18:19:27 Functions: 0 6 0.0 %

          Line data    Source code
       1             : #include "../fd_quic_common.h"
       2             : 
       3             : #include "fd_quic_transport_params.h"
       4             : #include "fd_quic_parse_util.h"
       5             : 
       6             : #include <stdio.h>
       7             : 
       8             : void
       9           0 : fd_quic_dump_transport_param_desc( FILE * out ) {
      10           0 :   fprintf( out, "Transport parameter descriptions:\n" );
      11             : 
      12           0 : #define __( NAME, ID, TYPE, DFT, DESC, ... ) \
      13           0 :   fprintf( out, #ID " " #TYPE " " #NAME "\n" DESC "\n\n" );
      14             : 
      15           0 :   FD_QUIC_TRANSPORT_PARAMS( __, _ )
      16           0 : #undef __
      17           0 : }
      18             : 
      19             : /* Helper for bounds checking that avoids -Wtype-limits warnings, sigh */
      20             : static inline int
      21           0 : fd_quic_varint_bounds_check( ulong value, ulong min, ulong max ) {
      22             :   // compiler should optimize out checks against min/max == VARINT_MIN/MAX
      23           0 :   if( min != FD_QUIC_VARINT_MIN && value < min ) return -1; /* out of bounds */
      24           0 :   if( max != FD_QUIC_VARINT_MAX && value > max ) return -1; /* out of bounds */
      25           0 :   return 0; /* in bounds */
      26           0 : }
      27             : 
      28             : #define FD_QUIC_PARSE_TP_VARINT( NAME, MIN, MAX )                                  \
      29           0 :   do {                                                                             \
      30           0 :     if( FD_UNLIKELY( sz==0    ) ) return -2;                                       \
      31           0 :     uint width = 1u << ( (unsigned)buf[0] >> 6u );                                 \
      32           0 :     if( FD_UNLIKELY( sz<width ) ) return -3;                                       \
      33           0 :     ulong value = (ulong)( buf[0] & 0x3f );                                        \
      34           0 :     for( ulong j=1; j<width; ++j ) {                                               \
      35           0 :       value= ( value<<8u ) + (ulong)buf[j];                                        \
      36           0 :     }                                                                              \
      37           0 :     if( FD_UNLIKELY( fd_quic_varint_bounds_check( value, MIN, MAX ) ) ) return -4; \
      38           0 :     params->NAME = value;                                                          \
      39           0 :     params->NAME##_present = 1;                                                    \
      40           0 :   } while(0)
      41             : 
      42             : #define FD_QUIC_PARSE_TP_CONN_ID( NAME, ... )               \
      43           0 :   do {                                                      \
      44           0 :     if( FD_UNLIKELY( sz>sizeof(params->NAME) ) ) return -1; \
      45           0 :     fd_memcpy( params->NAME, buf, sz );                     \
      46           0 :     params->NAME##_len = (uchar)sz;                         \
      47           0 :     params->NAME##_present = 1;                             \
      48           0 :   } while(0)
      49             : 
      50             : #define FD_QUIC_PARSE_TP_ZERO_LENGTH( NAME, ... ) \
      51           0 :   params->NAME##_present = 1;
      52             : 
      53             : #define FD_QUIC_PARSE_TP_TOKEN( NAME, ... )                 \
      54           0 :   do {                                                      \
      55           0 :     if( FD_UNLIKELY( sz>sizeof(params->NAME) ) ) return -1; \
      56           0 :     fd_memcpy( params->NAME, buf, sz );                     \
      57           0 :     params->NAME##_len = (uchar)sz;                         \
      58           0 :     params->NAME##_present = 1;                             \
      59           0 :   } while(0)
      60             : 
      61             : #define FD_QUIC_PARSE_TP_PREFERRED_ADDRESS( NAME, ... )     \
      62           0 :   do {                                                      \
      63           0 :     if( FD_UNLIKELY( sz>sizeof(params->NAME) ) ) return -1; \
      64           0 :     fd_memcpy( params->NAME, buf, sz );                     \
      65           0 :     params->NAME##_len = (uchar)sz;                         \
      66           0 :     params->NAME##_present = 1;                             \
      67           0 :   } while(0)
      68             : 
      69             : 
      70             : static int
      71             : fd_quic_decode_transport_param( fd_quic_transport_params_t * params,
      72             :                                 ulong                        id,
      73             :                                 uchar const *                buf,
      74           0 :                                 ulong                        sz ) {
      75             :   // This compiles into a jump table, which is reasonably fast
      76           0 :   switch( id ) {
      77           0 : #define __( NAME, ID, TYPE, DFT, DESC, MIN, MAX, ... ) \
      78           0 :   case ID: { \
      79           0 :       FD_QUIC_PARSE_TP_##TYPE( NAME, MIN, MAX ); \
      80           0 :       return 0; \
      81           0 :     } \
      82           0 : 
      83           0 :   FD_QUIC_TRANSPORT_PARAMS( __, _ )
      84           0 : #undef __
      85             : 
      86           0 :   }
      87             : 
      88           0 :   return 0; /* ignore unknown IDs */
      89           0 : }
      90             : 
      91             : int
      92             : fd_quic_decode_transport_params( fd_quic_transport_params_t * params,
      93             :                                  uchar const *                buf,
      94           0 :                                  ulong                        buf_sz ) {
      95           0 :   while( buf_sz > 0 ) {
      96             :     /* upon success, this function adjusts buf and sz by bytes consumed */
      97           0 :     ulong param_id = fd_quic_tp_parse_varint( &buf, &buf_sz );
      98           0 :     ulong param_sz = fd_quic_tp_parse_varint( &buf, &buf_sz );
      99           0 :     if( FD_UNLIKELY( param_sz > buf_sz ) ) return -1; /* length OOB */
     100             : 
     101           0 :     int param_err = fd_quic_decode_transport_param( params, param_id, buf, param_sz );
     102           0 :     if( FD_UNLIKELY( param_err ) ) return -1; /* parse failure */
     103             : 
     104             :     /* update buf and buf_sz */
     105           0 :     buf    += param_sz;
     106           0 :     buf_sz -= param_sz;
     107           0 :   }
     108             : 
     109           0 :   return 0; /* success */
     110           0 : }
     111             : 
     112             : #define FD_QUIC_DUMP_TP_VARINT(NAME) \
     113           0 :   fprintf( out, "%lu", (ulong)params->NAME )
     114             : #define FD_QUIC_DUMP_TP_CONN_ID(NAME) \
     115           0 :   do { \
     116           0 :     ulong sz = params->NAME##_len; \
     117           0 :     fprintf( out, "len(%d) ", (int)sz ); \
     118           0 :     for( ulong j = 0; j < sz; ++j ) { \
     119           0 :       fprintf( out, "%2.2x ", (unsigned)params->NAME[j] ); \
     120           0 :     } \
     121           0 :   } while(0)
     122             : #define FD_QUIC_DUMP_TP_ZERO_LENGTH(NAME) \
     123           0 :   fprintf( out, "%u", (unsigned)params->NAME##_present )
     124           0 : #define FD_QUIC_DUMP_TP_TOKEN(NAME) FD_QUIC_DUMP_TP_CONN_ID(NAME)
     125           0 : #define FD_QUIC_DUMP_TP_PREFERRED_ADDRESS(NAME) FD_QUIC_DUMP_TP_CONN_ID(NAME)
     126             : 
     127             : void
     128           0 : fd_quic_dump_transport_params( fd_quic_transport_params_t const * params, FILE * out ) {
     129           0 :   fprintf( out, "Transport params:\n" );
     130           0 : #define __( NAME, ID, TYPE, DFT, DESC, ... ) \
     131           0 :   fprintf( out, "  %-50s: %s ", #NAME " (" #ID ")", params->NAME##_present ? "*" : " " ); \
     132           0 :   FD_QUIC_DUMP_TP_##TYPE(NAME); \
     133           0 :   fprintf( out, "\n" );
     134           0 :   FD_QUIC_TRANSPORT_PARAMS( __, _ )
     135           0 : #undef __
     136           0 : }
     137             : 
     138             : 
     139             : #define FD_QUIC_ENCODE_TP_VARINT(NAME,ID)                              \
     140           0 :   do {                                                                 \
     141           0 :     ulong val_len = fd_quic_varint_min_sz( params->NAME );             \
     142           0 :     if( val_len == FD_QUIC_ENCODE_FAIL ) return FD_QUIC_ENCODE_FAIL;   \
     143           0 :     FD_QUIC_ENCODE_VARINT( buf, buf_sz, ID );                          \
     144           0 :     FD_QUIC_ENCODE_VARINT( buf, buf_sz, val_len );                     \
     145           0 :     FD_QUIC_ENCODE_VARINT(buf,buf_sz,params->NAME);                    \
     146           0 :   } while(0)
     147             : 
     148             : #define FD_QUIC_ENCODE_TP_CONN_ID(NAME,ID)                             \
     149           0 :   do {                                                                 \
     150           0 :     ulong val_len = params->NAME##_len;                                \
     151           0 :     FD_QUIC_ENCODE_VARINT( buf, buf_sz, ID );                          \
     152           0 :     FD_QUIC_ENCODE_VARINT( buf, buf_sz, val_len );                     \
     153           0 :     if( val_len + 1 > buf_sz ) return FD_QUIC_ENCODE_FAIL;             \
     154           0 :     for( ulong j = 0; j < val_len; ++j ) {                             \
     155           0 :       buf[j] = params->NAME[j];                                        \
     156           0 :     }                                                                  \
     157           0 :     buf += val_len; buf_sz -= val_len;                                 \
     158           0 :   } while(0);
     159             : 
     160             : #define FD_QUIC_ENCODE_TP_ZERO_LENGTH(NAME,ID)                         \
     161           0 :   do {                                                                 \
     162           0 :     if( params->NAME##_present ) {                                               \
     163           0 :       FD_QUIC_ENCODE_VARINT( buf, buf_sz, ID );                        \
     164           0 :       FD_QUIC_ENCODE_VARINT( buf, buf_sz, 0 );                         \
     165           0 :     }                                                                  \
     166           0 :   } while(0)
     167             : 
     168             : #define FD_QUIC_ENCODE_TP_TOKEN(NAME,ID) \
     169           0 :   FD_QUIC_ENCODE_TP_CONN_ID(NAME,ID)
     170             : 
     171             : #define FD_QUIC_ENCODE_TP_PREFERRED_ADDRESS(NAME,ID) \
     172           0 :   FD_QUIC_ENCODE_TP_CONN_ID(NAME,ID)
     173             : 
     174             : 
     175             : /* determine footprint of each type */
     176             : 
     177             : #define FD_QUIC_FOOTPRINT_FAIL ((ulong)1 << (ulong)62)
     178             : 
     179             : /* we need the length of the ID + the length of the length of the parameter value
     180             :    plus the length of the parameter value */
     181             : #define FD_QUIC_FOOTPRINT_TP_VARINT(NAME,ID)                           \
     182             :   (                                                                    \
     183             :     fd_quic_varint_min_sz( ID ) +                                      \
     184             :     fd_quic_varint_min_sz( fd_quic_varint_min_sz( params->NAME ) ) +   \
     185             :     fd_quic_varint_min_sz( params->NAME )                              \
     186             :   )
     187             : 
     188             : /* the length of a connection id is specified by *_len */
     189             : #define FD_QUIC_FOOTPRINT_TP_CONN_ID(NAME,ID)                          \
     190             :   (                                                                    \
     191             :     fd_quic_varint_min_sz( ID ) +                                      \
     192             :     fd_quic_varint_min_sz( params->NAME##_len ) +                      \
     193             :     params->NAME##_len                                                 \
     194             :   )
     195             : 
     196             : #define FD_QUIC_FOOTPRINT_TP_ZERO_LENGTH(NAME,ID)                      \
     197             :   (                                                                    \
     198             :     fd_quic_varint_min_sz( ID ) +                                      \
     199             :     fd_quic_varint_min_sz( 0 )                                         \
     200             :   )
     201             : 
     202             : #define FD_QUIC_FOOTPRINT_TP_TOKEN(NAME,ID) \
     203             :   FD_QUIC_FOOTPRINT_TP_CONN_ID(NAME,ID)
     204             : 
     205             : #define FD_QUIC_FOOTPRINT_TP_PREFERRED_ADDRESS(NAME,ID) \
     206             :   FD_QUIC_FOOTPRINT_TP_CONN_ID(NAME,ID)
     207             : 
     208             : 
     209             : #define FD_QUIC_VALIDATE_TP_TOKEN(NAME,ID) \
     210             :   FD_QUIC_VALIDATE_TP_CONN_ID(NAME,ID)
     211             : 
     212             : #define FD_QUIC_VALIDATE_TP_PREFERRED_ADDRESS(NAME,ID) \
     213             :   FD_QUIC_VALIDATE_TP_CONN_ID(NAME,ID)
     214             : 
     215             : 
     216             : // encode transport parameters into a buffer
     217             : // returns the number of bytes written
     218             : ulong
     219             : fd_quic_encode_transport_params( uchar *                            buf,
     220             :                                  ulong                              buf_sz,
     221           0 :                                  fd_quic_transport_params_t const * params ) {
     222           0 :   ulong orig_buf_sz = buf_sz;
     223           0 : #define __( NAME, ID, TYPE, DFT, DESC, ... )                           \
     224           0 :   if( params->NAME##_present ) {                                       \
     225           0 :     FD_QUIC_ENCODE_TP_##TYPE(NAME,ID);                                 \
     226           0 :   }
     227           0 :   FD_QUIC_TRANSPORT_PARAMS( __, _ )
     228           0 : #undef __
     229             : 
     230           0 :   return orig_buf_sz - buf_sz;
     231           0 : }

Generated by: LCOV version 1.14