LCOV - code coverage report
Current view: top level - app/fddev/quic_trace - fd_quic_trace_main.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 74 0.0 %
Date: 2025-01-08 12:08:44 Functions: 0 2 0.0 %

          Line data    Source code
       1             : /* This directory provides the 'fddev quic-trace' subcommand.
       2             : 
       3             :    The goal of quic-trace is to tap QUIC traffic on a live system, which
       4             :    requires encryption keys and other annoying connection state.
       5             : 
       6             :    quic-trace does this by tapping into the shared memory segments of an
       7             :    fd_quic_tile running on the same host.  It does so strictly read-only
       8             :    to minimize impact to a production system.
       9             : 
      10             :    This file (fd_quic_trace_main.c) provides the glue code required to
      11             :    join remote fd_quic_tile objects.
      12             : 
      13             :    fd_quic_trace_rx_tile.c provides a fd_tango consumer for incoming
      14             :    QUIC packets. */
      15             : 
      16             : #include "fd_quic_trace.h"
      17             : #include "../fddev.h"
      18             : #include "../../../disco/quic/fd_quic_tile.h"
      19             : #include "../../../waltz/quic/log/fd_quic_log_user.h"
      20             : 
      21             : /* Define global variables */
      22             : 
      23             : fd_quic_ctx_t         fd_quic_trace_ctx;
      24             : fd_quic_ctx_t const * fd_quic_trace_ctx_remote;
      25             : ulong                 fd_quic_trace_ctx_raddr;
      26             : ulong **              fd_quic_trace_target_fseq;
      27             : ulong volatile *      fd_quic_trace_link_metrics;
      28             : void const *          fd_quic_trace_log_base;
      29             : 
      30           0 : #define EVENT_STREAM 0
      31           0 : #define EVENT_ERROR  1
      32             : 
      33             : void
      34             : quic_trace_cmd_args( int *    pargc,
      35             :                      char *** pargv,
      36           0 :                      args_t * args ) {
      37           0 :   char const * event = fd_env_strip_cmdline_cstr( pargc, pargv, "--event", NULL, "stream" );
      38           0 :   if( 0==strcmp( event, "stream" ) ) {
      39           0 :     args->quic_trace.event = EVENT_STREAM;
      40           0 :   } else if( 0==strcmp( event, "error" ) ) {
      41           0 :     args->quic_trace.event = EVENT_ERROR;
      42           0 :   } else {
      43           0 :     FD_LOG_ERR(( "Unsupported QUIC event type \"%s\"", event ));
      44           0 :   }
      45             : 
      46           0 :   args->quic_trace.dump = fd_env_strip_cmdline_contains( pargc, pargv, "--dump" );
      47           0 : }
      48             : 
      49             : void
      50             : quic_trace_cmd_fn( args_t *         args,
      51           0 :                    config_t * const config ) {
      52           0 :   (void)args;
      53             : 
      54           0 :   fd_topo_t * topo = &config->topo;
      55           0 :   fd_topo_join_workspaces( topo, FD_SHMEM_JOIN_MODE_READ_ONLY );
      56           0 :   fd_topo_fill( topo );
      57             : 
      58           0 :   fd_topo_tile_t * quic_tile = NULL;
      59           0 :   for( ulong tile_idx=0UL; tile_idx < topo->tile_cnt; tile_idx++ ) {
      60           0 :     if( 0==strcmp( topo->tiles[ tile_idx ].name, "quic" ) ) {
      61           0 :       quic_tile = &topo->tiles[ tile_idx ];
      62           0 :       break;
      63           0 :     }
      64           0 :   }
      65           0 :   if( !quic_tile ) FD_LOG_ERR(( "QUIC tile not found in topology" ));
      66             : 
      67             :   /* Ugly: fd_quic_ctx_t uses non-relocatable object addressing.
      68             :      We need to rebase pointers.  foreign_{...} refer to the original
      69             :      objects in shared memory, local_{...} refer to translated copies. */
      70             : 
      71           0 :   void *                quic_tile_base   = fd_topo_obj_laddr( topo, quic_tile->tile_obj_id );
      72           0 :   fd_quic_ctx_t const * foreign_quic_ctx = quic_tile_base;
      73           0 :   fd_quic_ctx_t * quic_ctx = &fd_quic_trace_ctx;
      74           0 :   *quic_ctx                = *foreign_quic_ctx;
      75           0 :   fd_quic_trace_ctx_remote =  foreign_quic_ctx;
      76             : 
      77           0 :   ulong quic_raddr = (ulong)foreign_quic_ctx->quic;
      78           0 :   ulong ctx_raddr  = quic_raddr - fd_ulong_align_up( sizeof(fd_quic_ctx_t), fd_ulong_max( alignof(fd_quic_ctx_t), fd_quic_align() ) );
      79           0 :   fd_quic_trace_ctx_raddr = ctx_raddr;
      80             : 
      81           0 :   FD_LOG_INFO(( "fd_quic_tile state at %p in tile address space", (void *)ctx_raddr ));
      82           0 :   FD_LOG_INFO(( "fd_quic_tile state at %p in local address space", quic_tile_base ));
      83             : 
      84           0 :   quic_ctx->reasm = (void *)( (ulong)quic_tile_base + (ulong)quic_ctx->reasm - ctx_raddr );
      85           0 :   quic_ctx->stem  = (void *)( (ulong)quic_tile_base + (ulong)quic_ctx->stem  - ctx_raddr );
      86           0 :   quic_ctx->quic  = (void *)( (ulong)quic_tile_base + (ulong)quic_ctx->quic  - ctx_raddr );
      87             : 
      88           0 :   fd_topo_link_t * net_quic = &topo->links[ quic_tile->in_link_id[ 0 ] ];
      89           0 :   quic_ctx->in_mem = topo->workspaces[ topo->objs[ net_quic->dcache_obj_id ].wksp_id ].wksp;
      90           0 :   FD_LOG_INFO(( "net->quic link at %p", (void *)quic_ctx->in_mem ));
      91             : 
      92             :   /* Join shared memory objects
      93             :      Mostly nops but verifies object magic numbers to ensure that
      94             :      derived pointers are correct. */
      95             : 
      96           0 :   FD_LOG_INFO(( "Joining fd_quic" ));
      97           0 :   fd_quic_t * quic = fd_quic_join( quic_ctx->quic );
      98           0 :   if( !quic ) FD_LOG_ERR(( "Failed to join fd_quic" ));
      99             : 
     100             :   /* Locate original fseq objects
     101             :      These are monitored to ensure the trace RX tile doesn't skip ahead
     102             :      of the quic tile. */
     103           0 :   fd_quic_trace_target_fseq = malloc( quic_tile->in_cnt * sizeof(ulong) );
     104           0 :   for( ulong i=0UL; i<quic_tile->in_cnt; i++ ) {
     105           0 :     fd_quic_trace_target_fseq[ i ] = quic_tile->in_link_fseq[ i ];
     106           0 :   }
     107             : 
     108             :   /* Locate log buffer */
     109             : 
     110           0 :   void * log = (void *)( (ulong)quic + quic->layout.log_off );
     111           0 :   fd_quic_log_rx_t log_rx[1];
     112           0 :   FD_LOG_DEBUG(( "Joining quic_log" ));
     113           0 :   if( FD_UNLIKELY( !fd_quic_log_rx_join( log_rx, log ) ) ) {
     114           0 :     FD_LOG_ERR(( "fd_quic_log_rx_join failed" ));
     115           0 :   }
     116           0 :   fd_quic_trace_log_base = log_rx->base;
     117             : 
     118             :   /* Redirect metadata writes to dummy buffers.
     119             :      Without this hack, stem_run would attempt to write metadata updates
     120             :      into the target topology which is read-only. */
     121             : 
     122             :   /* ... redirect metric updates */
     123           0 :   ulong * metrics = aligned_alloc( FD_METRICS_ALIGN, FD_METRICS_FOOTPRINT( quic_tile->in_cnt, quic_tile->out_cnt ) );
     124           0 :   if( !metrics ) FD_LOG_ERR(( "out of memory" ));
     125           0 :   fd_memset( metrics, 0, FD_METRICS_FOOTPRINT( quic_tile->in_cnt, quic_tile->out_cnt ) );
     126           0 :   fd_metrics_register( metrics );
     127             : 
     128           0 :   fd_quic_trace_link_metrics = fd_metrics_link_in( fd_metrics_base_tl, 0 );
     129             : 
     130             :   /* Join net->quic link consumer */
     131             : 
     132           0 :   FD_LOG_NOTICE(( "quic-trace starting ..." ));
     133           0 :   switch( args->quic_trace.event ) {
     134           0 :   case EVENT_STREAM:
     135           0 :     fd_quic_trace_rx_tile( net_quic->mcache, args->quic_trace.dump );
     136           0 :     break;
     137           0 :   case EVENT_ERROR:
     138           0 :     fd_quic_trace_log_tile( log_rx->mcache );
     139           0 :     break;
     140           0 :   default:
     141           0 :     __builtin_unreachable();
     142           0 :   }
     143             : 
     144           0 :   fd_quic_log_rx_leave( log_rx );
     145           0 : }

Generated by: LCOV version 1.14