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 : #define FD_TEMPL_DEF_STRUCT_BEGIN(NAME) \
184 : static ulong fd_quic_trace1_##NAME( \
185 : void * const ctx, \
186 : uchar const * const buf, \
187 : ulong const buf_sz \
188 0 : ) { \
189 0 : fd_quic_##NAME##_t frame[1] = {0}; \
190 0 : uchar const * p0 = buf; \
191 0 : uchar const * const p1 = buf+buf_sz; \
192 0 : ulong rc; \
193 0 : \
194 0 : rc = fd_quic_decode_##NAME( frame, p0, (ulong)(p1-p0) ); \
195 0 : if( FD_UNLIKELY( rc==FD_QUIC_PARSE_FAIL ) ) return FD_QUIC_PARSE_FAIL;\
196 0 : p0 += rc; \
197 0 : \
198 0 : rc = fd_quic_trace_##NAME( ctx, frame, p0, (ulong)(p1-p0) ); \
199 0 : if( FD_UNLIKELY( rc==FD_QUIC_PARSE_FAIL ) ) return FD_QUIC_PARSE_FAIL;\
200 0 : p0 += rc; \
201 0 : \
202 0 : return (ulong)(p0-buf); \
203 0 : }
204 : #include "../../../../waltz/quic/templ/fd_quic_dft.h"
205 : #include "../../../../waltz/quic/templ/fd_quic_frames_templ.h"
206 : #include "../../../../waltz/quic/templ/fd_quic_undefs.h"
207 :
208 : static ulong
209 : fd_quic_trace_frame( fd_quic_trace_frame_ctx_t * context,
210 : uchar const * data,
211 0 : ulong data_sz ) {
212 0 : if( FD_UNLIKELY( data_sz<1UL ) ) return FD_QUIC_PARSE_FAIL;
213 :
214 : /* Frame ID is technically a varint but it's sufficient to look at the
215 : first byte. */
216 0 : uint id = data[0];
217 0 : if( !fd_quic_frame_type_allowed( context->pkt_type, id ) ) {
218 0 : FD_LOG_HEXDUMP_NOTICE(( "Frame not allowed", data, data_sz ));
219 0 : return FD_QUIC_PARSE_FAIL;
220 0 : }
221 :
222 0 : switch( id ) {
223 0 : # define F(T,MID,NAME,...) \
224 0 : case T: return fd_quic_trace1_##NAME##_frame( context, data, data_sz );
225 0 : FD_QUIC_FRAME_TYPES(F)
226 0 : # undef F
227 0 : default:
228 0 : FD_LOG_HEXDUMP_NOTICE(( "Failed to parse frame", data, data_sz ));
229 0 : return FD_QUIC_PARSE_FAIL;
230 0 : }
231 0 : }
232 :
233 : void
234 : fd_quic_trace_frames( fd_quic_trace_frame_ctx_t * context,
235 : uchar const * data,
236 0 : ulong data_sz ) {
237 0 : while( data_sz ) {
238 0 : ulong ret = fd_quic_trace_frame( context, data, data_sz );
239 0 : if( ret==FD_QUIC_PARSE_FAIL ) return;
240 0 : if( FD_UNLIKELY( ret>data_sz ) ) return;
241 0 : data += ret;
242 0 : data_sz -= ret;
243 0 : }
244 0 : }
|