Line data Source code
1 : #include "fd_quic_trace.h"
2 : #include "../../../waltz/quic/fd_quic_proto.c"
3 : #include "../../../waltz/quic/templ/fd_quic_frame.h"
4 :
5 : #define FRAME_STUB(name) \
6 : static ulong \
7 : fd_quic_trace_##name##_frame( \
8 : void * context FD_PARAM_UNUSED, \
9 : fd_quic_##name##_frame_t * frame FD_PARAM_UNUSED, \
10 : uchar const * p FD_PARAM_UNUSED, \
11 0 : ulong p_sz FD_PARAM_UNUSED ) { \
12 0 : return 0UL; \
13 0 : }
14 :
15 : static ulong
16 : fd_quic_trace_padding_frame(
17 : void * context FD_PARAM_UNUSED,
18 : fd_quic_padding_frame_t * frame FD_PARAM_UNUSED,
19 : uchar const * p,
20 0 : ulong p_sz ) {
21 0 : ulong pad_sz;
22 0 : for( pad_sz=0UL; pad_sz<p_sz && p[0]==0; p++, pad_sz++ ) {}
23 0 : return pad_sz;
24 0 : }
25 :
26 : FRAME_STUB( ping )
27 :
28 : static ulong
29 : fd_quic_trace_ack_frame(
30 : void * context FD_PARAM_UNUSED,
31 : fd_quic_ack_frame_t * frame,
32 : uchar const * p,
33 0 : ulong p_sz ) {
34 0 : uchar const * p_begin = p;
35 0 : uchar const * p_end = p + p_sz;
36 :
37 0 : for( ulong j=0UL; j < frame->ack_range_count; j++ ) {
38 0 : if( FD_UNLIKELY( p_end <= p ) ) return FD_QUIC_PARSE_FAIL;
39 :
40 0 : fd_quic_ack_range_frag_t ack_range[1];
41 0 : ulong rc = fd_quic_decode_ack_range_frag( ack_range, p, (ulong)( p_end - p ) );
42 0 : if( FD_UNLIKELY( rc == FD_QUIC_PARSE_FAIL ) ) return FD_QUIC_PARSE_FAIL;
43 0 : p += rc;
44 0 : }
45 :
46 0 : if( frame->type & 1U ) {
47 0 : fd_quic_ecn_counts_frag_t ecn_counts[1];
48 0 : ulong rc = fd_quic_decode_ecn_counts_frag( ecn_counts, p, (ulong)( p_end - p ) );
49 0 : if( rc == FD_QUIC_PARSE_FAIL ) return FD_QUIC_PARSE_FAIL;
50 0 : p += rc;
51 0 : }
52 :
53 0 : return (ulong)( p - p_begin );
54 0 : }
55 :
56 : FRAME_STUB( reset_stream )
57 : FRAME_STUB( stop_sending )
58 :
59 : static ulong
60 : fd_quic_trace_crypto_frame(
61 : void * context FD_PARAM_UNUSED,
62 : fd_quic_crypto_frame_t * frame,
63 : uchar const * p FD_PARAM_UNUSED,
64 0 : ulong p_sz ) {
65 0 : if( FD_UNLIKELY( frame->length > p_sz ) ) return FD_QUIC_PARSE_FAIL;
66 0 : return frame->length;
67 0 : }
68 :
69 : FRAME_STUB( new_token )
70 :
71 : static ulong
72 : fd_quic_trace_stream_8_frame(
73 : fd_quic_trace_frame_ctx_t * context,
74 : fd_quic_stream_8_frame_t * data,
75 : uchar const * p FD_PARAM_UNUSED,
76 0 : ulong p_sz ) {
77 0 : printf( "ts=%20ld conn_id=%016lx src_ip=%08x src_port=%5hu pktnum=%8lu sid=%8lu off= 0 (i) len=%4lu (i) fin=%i\n",
78 0 : fd_log_wallclock(),
79 0 : context->conn_id,
80 0 : fd_uint_bswap( context->src_ip ),
81 0 : context->src_port,
82 0 : context->pkt_num,
83 0 : data->stream_id,
84 0 : p_sz,
85 0 : data->type&1 );
86 0 : return p_sz;
87 0 : }
88 :
89 : static ulong
90 : fd_quic_trace_stream_a_frame(
91 : fd_quic_trace_frame_ctx_t * context,
92 : fd_quic_stream_a_frame_t * data,
93 : uchar const * p FD_PARAM_UNUSED,
94 0 : ulong p_sz ) {
95 0 : if( data->length > p_sz ) return FD_QUIC_PARSE_FAIL;
96 0 : printf( "ts=%20ld conn_id=%016lx src_ip=%08x src_port=%5hu pktnum=%8lu sid=%8lu off= 0 (i) len=%4lu (e) fin=%i\n",
97 0 : fd_log_wallclock(),
98 0 : context->conn_id,
99 0 : fd_uint_bswap( context->src_ip ),
100 0 : context->src_port,
101 0 : context->pkt_num,
102 0 : data->stream_id,
103 0 : data->length,
104 0 : data->type&1 );
105 0 : return data->length;
106 0 : }
107 :
108 : static ulong
109 : fd_quic_trace_stream_c_frame(
110 : fd_quic_trace_frame_ctx_t * context,
111 : fd_quic_stream_c_frame_t * data,
112 : uchar const * p FD_PARAM_UNUSED,
113 0 : ulong p_sz ) {
114 0 : printf( "ts=%20ld conn_id=%016lx src_ip=%08x src_port=%5hu pktnum=%8lu sid=%8lu off=%4lu (e) len=%4lu (i) fin=%i\n",
115 0 : fd_log_wallclock(),
116 0 : context->conn_id,
117 0 : fd_uint_bswap( context->src_ip ),
118 0 : context->src_port,
119 0 : context->pkt_num,
120 0 : data->stream_id,
121 0 : data->offset,
122 0 : p_sz,
123 0 : data->type&1 );
124 0 : return p_sz;
125 0 : }
126 :
127 : static ulong
128 : fd_quic_trace_stream_e_frame(
129 : fd_quic_trace_frame_ctx_t * context,
130 : fd_quic_stream_e_frame_t * data,
131 : uchar const * p FD_PARAM_UNUSED,
132 0 : ulong p_sz FD_PARAM_UNUSED ) {
133 0 : if( data->length > p_sz ) return FD_QUIC_PARSE_FAIL;
134 0 : printf( "ts=%20ld conn_id=%016lx src_ip=%08x src_port=%5hu pktnum=%8lu sid=%8lu off=%4lu (e) len=%4lu (e) fin=%i\n",
135 0 : fd_log_wallclock(),
136 0 : context->conn_id,
137 0 : fd_uint_bswap( context->src_ip ),
138 0 : context->src_port,
139 0 : context->pkt_num,
140 0 : data->stream_id,
141 0 : data->offset,
142 0 : data->length,
143 0 : data->type&1 );
144 0 : return data->length;
145 0 : }
146 :
147 : FRAME_STUB( max_data )
148 : FRAME_STUB( max_stream_data )
149 : FRAME_STUB( max_streams )
150 : FRAME_STUB( data_blocked )
151 : FRAME_STUB( stream_data_blocked )
152 : FRAME_STUB( streams_blocked )
153 : FRAME_STUB( new_conn_id )
154 : FRAME_STUB( retire_conn_id )
155 : FRAME_STUB( path_challenge )
156 : FRAME_STUB( path_response )
157 :
158 : static ulong
159 : fd_quic_trace_conn_close_0_frame(
160 : void * context FD_PARAM_UNUSED,
161 : fd_quic_conn_close_0_frame_t * frame,
162 : uchar const * p FD_PARAM_UNUSED,
163 0 : ulong p_sz ) {
164 0 : if( FD_UNLIKELY( frame->reason_phrase_length > p_sz ) ) return FD_QUIC_PARSE_FAIL;
165 0 : return frame->reason_phrase_length;
166 0 : }
167 :
168 : static ulong
169 : fd_quic_trace_conn_close_1_frame(
170 : void * context FD_PARAM_UNUSED,
171 : fd_quic_conn_close_1_frame_t * frame,
172 : uchar const * p FD_PARAM_UNUSED,
173 0 : ulong p_sz ) {
174 0 : if( FD_UNLIKELY( frame->reason_phrase_length > p_sz ) ) return FD_QUIC_PARSE_FAIL;
175 0 : return frame->reason_phrase_length;
176 0 : }
177 :
178 : FRAME_STUB( handshake_done )
179 :
180 : #define FD_TEMPL_DEF_STRUCT_BEGIN(NAME) \
181 : static ulong fd_quic_trace1_##NAME( \
182 : void * const ctx, \
183 : uchar const * const buf, \
184 : ulong const buf_sz \
185 0 : ) { \
186 0 : fd_quic_##NAME##_t frame[1] = {0}; \
187 0 : uchar const * p0 = buf; \
188 0 : uchar const * const p1 = buf+buf_sz; \
189 0 : ulong rc; \
190 0 : \
191 0 : rc = fd_quic_decode_##NAME( frame, p0, (ulong)(p1-p0) ); \
192 0 : if( FD_UNLIKELY( rc==FD_QUIC_PARSE_FAIL ) ) return FD_QUIC_PARSE_FAIL;\
193 0 : p0 += rc; \
194 0 : \
195 0 : rc = fd_quic_trace_##NAME( ctx, frame, p0, (ulong)(p1-p0) ); \
196 0 : if( FD_UNLIKELY( rc==FD_QUIC_PARSE_FAIL ) ) return FD_QUIC_PARSE_FAIL;\
197 0 : p0 += rc; \
198 0 : \
199 0 : return (ulong)(p0-buf); \
200 0 : }
201 : #include "../../../waltz/quic/templ/fd_quic_dft.h"
202 : #include "../../../waltz/quic/templ/fd_quic_frames_templ.h"
203 : #include "../../../waltz/quic/templ/fd_quic_undefs.h"
204 :
205 : static ulong
206 : fd_quic_trace_frame( fd_quic_trace_frame_ctx_t * context,
207 : uchar const * data,
208 0 : ulong data_sz ) {
209 0 : if( FD_UNLIKELY( data_sz<1UL ) ) return FD_QUIC_PARSE_FAIL;
210 :
211 : /* Frame ID is technically a varint but it's sufficient to look at the
212 : first byte. */
213 0 : uint id = data[0];
214 0 : if( !fd_quic_frame_type_allowed( context->pkt_type, id ) ) {
215 0 : FD_LOG_HEXDUMP_NOTICE(( "Frame not allowed", data, data_sz ));
216 0 : return FD_QUIC_PARSE_FAIL;
217 0 : }
218 :
219 0 : switch( id ) {
220 0 : # define F(T,MID,NAME,...) \
221 0 : case T: return fd_quic_trace1_##NAME##_frame( context, data, data_sz );
222 0 : FD_QUIC_FRAME_TYPES(F)
223 0 : # undef F
224 0 : default:
225 0 : FD_LOG_HEXDUMP_NOTICE(( "Failed to parse frame", data, data_sz ));
226 0 : return FD_QUIC_PARSE_FAIL;
227 0 : }
228 0 : }
229 :
230 : void
231 : fd_quic_trace_frames( fd_quic_trace_frame_ctx_t * context,
232 : uchar const * data,
233 0 : ulong data_sz ) {
234 0 : while( data_sz ) {
235 0 : ulong ret = fd_quic_trace_frame( context, data, data_sz );
236 0 : if( ret==FD_QUIC_PARSE_FAIL ) return;
237 0 : if( FD_UNLIKELY( ret>data_sz ) ) return;
238 0 : data += ret;
239 0 : data_sz -= ret;
240 0 : }
241 0 : }
|