5
5
#include "fd_tpu.h"
6
6
#include "../../waltz/quic/fd_quic_private.h"
7
7
#include "generated/quic_seccomp.h"
8
+ #include "../../util/io/fd_io.h"
8
9
#include "../../util/net/fd_eth.h"
9
10
10
11
#include <errno.h>
12
+ #include <fcntl.h>
11
13
#include <linux/unistd.h>
12
14
#include <sys/random.h>
13
15
14
16
#define OUT_IDX_VERIFY 0
15
17
#define OUT_IDX_NET 1
16
18
19
+ #define FD_QUIC_KEYLOG_FLUSH_INTERVAL_NS ((long)100e6)
20
+
17
21
/* fd_quic_tile provides a TPU server tile.
18
22
19
23
This tile handles incoming transactions that clients request to be
@@ -413,10 +417,66 @@ quic_tx_aio_send( void * _ctx,
413
417
return FD_AIO_SUCCESS ;
414
418
}
415
419
420
+ static void
421
+ quic_tls_keylog ( void * _ctx ,
422
+ char const * line ) {
423
+ fd_quic_ctx_t * ctx = _ctx ;
424
+ fd_io_buffered_ostream_t * os = & ctx -> keylog_stream ;
425
+
426
+ /* Lazily flush ostream */
427
+ ulong line_sz = strlen ( line )+ 1 ;
428
+ ulong peek_sz = fd_io_buffered_ostream_peek_sz ( os );
429
+ if ( FD_UNLIKELY ( peek_sz < line_sz ) ) {
430
+ int err = fd_io_buffered_ostream_flush ( os );
431
+ if ( FD_UNLIKELY ( err ) ) {
432
+ FD_LOG_ERR (( "fd_io_buffered_ostream_flush(keylog) failed (%i-%s)" , errno , fd_io_strerror ( errno ) ));
433
+ }
434
+ peek_sz = fd_io_buffered_ostream_peek_sz ( os );
435
+ }
436
+ if ( FD_UNLIKELY ( peek_sz < line_sz ) ) {
437
+ FD_LOG_ERR (( "keylog buffer too small (buf_sz=%lu, line_sz=%lu)" , peek_sz , line_sz ));
438
+ }
439
+
440
+ /* Append line */
441
+ char * cur = fd_io_buffered_ostream_peek ( os );
442
+ cur = fd_cstr_append_text ( cur , line , strlen ( line ) );
443
+ cur = fd_cstr_append_char ( cur , '\n' );
444
+ fd_io_buffered_ostream_seek ( os , line_sz );
445
+ }
446
+
447
+ static void
448
+ during_housekeeping ( fd_quic_ctx_t * ctx ) {
449
+ if ( FD_UNLIKELY ( ctx -> keylog_stream .wbuf ) ) {
450
+ long now = fd_log_wallclock ();
451
+ if ( FD_UNLIKELY ( now > ctx -> keylog_next_flush ) ) {
452
+ int err = fd_io_buffered_ostream_flush ( & ctx -> keylog_stream );
453
+ if ( FD_UNLIKELY ( err ) ) {
454
+ FD_LOG_ERR (( "fd_io_buffered_ostream_flush(keylog) failed (%i-%s)" , errno , fd_io_strerror ( errno ) ));
455
+ }
456
+ ctx -> keylog_next_flush = now + FD_QUIC_KEYLOG_FLUSH_INTERVAL_NS ;
457
+ }
458
+ }
459
+ }
460
+
416
461
static void
417
462
privileged_init ( fd_topo_t * topo ,
418
463
fd_topo_tile_t * tile ) {
419
- (void )topo ; (void )tile ;
464
+ fd_quic_ctx_t * ctx = fd_topo_obj_laddr ( topo , tile -> tile_obj_id );
465
+ if ( FD_UNLIKELY ( topo -> objs [ tile -> tile_obj_id ].footprint < scratch_footprint ( tile ) ) ) {
466
+ FD_LOG_ERR (( "insufficient tile scratch space" ));
467
+ }
468
+ fd_memset ( ctx , 0 , sizeof (fd_quic_ctx_t ) );
469
+ ctx -> keylog_fd = -1 ;
470
+
471
+ if ( 0 != strcmp ( tile -> quic .key_log_path , "" ) ) {
472
+ ctx -> keylog_fd = open ( tile -> quic .key_log_path , O_WRONLY |O_CREAT |O_APPEND , 0644 );
473
+ if ( FD_UNLIKELY ( ctx -> keylog_fd < 0 ) ) {
474
+ FD_LOG_ERR (( "open(%s, O_WRONLY|O_CREAT|O_APPEND, 0644) failed (%i-%s)" ,
475
+ tile -> quic .key_log_path , errno , fd_io_strerror ( errno ) ));
476
+ }
477
+ fd_io_buffered_ostream_init ( & ctx -> keylog_stream , ctx -> keylog_fd , ctx -> keylog_buf , sizeof (ctx -> keylog_buf ) );
478
+ FD_LOG_WARNING (( "Logging QUIC encryption keys to %s" , tile -> quic .key_log_path ));
479
+ }
420
480
421
481
/* The fd_quic implementation calls fd_log_wallclock() internally
422
482
which itself calls clock_gettime() which on most kernels is not a
@@ -444,9 +504,6 @@ static void
444
504
unprivileged_init ( fd_topo_t * topo ,
445
505
fd_topo_tile_t * tile ) {
446
506
void * scratch = fd_topo_obj_laddr ( topo , tile -> tile_obj_id );
447
- if ( FD_UNLIKELY ( topo -> objs [ tile -> tile_obj_id ].footprint < scratch_footprint ( tile ) ) ) {
448
- FD_LOG_ERR (( "insufficient tile scratch space" ));
449
- }
450
507
451
508
if ( FD_UNLIKELY ( tile -> in_cnt == 0 ) ) {
452
509
FD_LOG_ERR (( "quic tile has no input links" ));
@@ -472,7 +529,7 @@ unprivileged_init( fd_topo_t * topo,
472
529
473
530
FD_SCRATCH_ALLOC_INIT ( l , scratch );
474
531
fd_quic_ctx_t * ctx = FD_SCRATCH_ALLOC_APPEND ( l , alignof( fd_quic_ctx_t ), sizeof ( fd_quic_ctx_t ) );
475
- fd_memset ( ctx , 0 , sizeof ( fd_quic_ctx_t ) );
532
+ FD_TEST ( ( ulong ) ctx == ( ulong ) scratch );
476
533
477
534
for ( ulong i = 0 ; i < tile -> in_cnt ; i ++ ) {
478
535
fd_topo_link_t * link = & topo -> links [ tile -> in_link_id [ i ] ];
@@ -524,6 +581,10 @@ unprivileged_init( fd_topo_t * topo,
524
581
quic -> cb .now = quic_now ;
525
582
quic -> cb .now_ctx = ctx ;
526
583
quic -> cb .quic_ctx = ctx ;
584
+ if ( ctx -> keylog_fd >=0 ) {
585
+ quic -> cb .tls_keylog = quic_tls_keylog ;
586
+ ctx -> keylog_next_flush = fd_log_wallclock () + FD_QUIC_KEYLOG_FLUSH_INTERVAL_NS ;
587
+ }
527
588
528
589
fd_quic_set_aio_net_tx ( quic , quic_tx_aio );
529
590
fd_quic_set_clock_tickcount ( quic );
@@ -564,10 +625,8 @@ populate_allowed_seccomp( fd_topo_t const * topo,
564
625
fd_topo_tile_t const * tile ,
565
626
ulong out_cnt ,
566
627
struct sock_filter * out ) {
567
- (void )topo ;
568
- (void )tile ;
569
-
570
- populate_sock_filter_policy_quic ( out_cnt , out , (uint )fd_log_private_logfile_fd () );
628
+ fd_quic_ctx_t const * ctx = fd_topo_obj_laddr ( topo , tile -> tile_obj_id );
629
+ populate_sock_filter_policy_quic ( out_cnt , out , (uint )fd_log_private_logfile_fd (), (uint )ctx -> keylog_fd );
571
630
return sock_filter_policy_quic_instr_cnt ;
572
631
}
573
632
@@ -576,15 +635,16 @@ populate_allowed_fds( fd_topo_t const * topo,
576
635
fd_topo_tile_t const * tile ,
577
636
ulong out_fds_cnt ,
578
637
int * out_fds ) {
579
- (void )topo ;
580
- (void )tile ;
638
+ fd_quic_ctx_t * ctx = fd_topo_obj_laddr ( topo , tile -> tile_obj_id );
581
639
582
- if ( FD_UNLIKELY ( out_fds_cnt < 2UL ) ) FD_LOG_ERR (( "out_fds_cnt %lu" , out_fds_cnt ));
640
+ if ( FD_UNLIKELY ( out_fds_cnt < 3UL ) ) FD_LOG_ERR (( "out_fds_cnt %lu" , out_fds_cnt ));
583
641
584
642
ulong out_cnt = 0UL ;
585
643
out_fds [ out_cnt ++ ] = 2 ; /* stderr */
586
644
if ( FD_LIKELY ( -1 != fd_log_private_logfile_fd () ) )
587
645
out_fds [ out_cnt ++ ] = fd_log_private_logfile_fd (); /* logfile */
646
+ if ( ctx -> keylog_fd != -1 )
647
+ out_fds [ out_cnt ++ ] = ctx -> keylog_fd ;
588
648
return out_cnt ;
589
649
}
590
650
@@ -594,11 +654,12 @@ populate_allowed_fds( fd_topo_t const * topo,
594
654
#define STEM_CALLBACK_CONTEXT_TYPE fd_quic_ctx_t
595
655
#define STEM_CALLBACK_CONTEXT_ALIGN alignof(fd_quic_ctx_t)
596
656
597
- #define STEM_CALLBACK_METRICS_WRITE metrics_write
598
- #define STEM_CALLBACK_BEFORE_CREDIT before_credit
599
- #define STEM_CALLBACK_BEFORE_FRAG before_frag
600
- #define STEM_CALLBACK_DURING_FRAG during_frag
601
- #define STEM_CALLBACK_AFTER_FRAG after_frag
657
+ #define STEM_CALLBACK_METRICS_WRITE metrics_write
658
+ #define STEM_CALLBACK_BEFORE_CREDIT before_credit
659
+ #define STEM_CALLBACK_BEFORE_FRAG before_frag
660
+ #define STEM_CALLBACK_DURING_FRAG during_frag
661
+ #define STEM_CALLBACK_AFTER_FRAG after_frag
662
+ #define STEM_CALLBACK_DURING_HOUSEKEEPING during_housekeeping
602
663
603
664
#include "../stem/fd_stem.c"
604
665
0 commit comments