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

Generated by: LCOV version 1.14