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