Line data Source code
1 : // QUIC encoders
2 : #include "../../../util/log/fd_log.h"
3 :
4 : /* TODO replace FD_QUIC_PARSE_FAIL with FD_QUIC_ENCODE_FAIL */
5 :
6 : /* TODO add platform optimized versions of these
7 : e.g. 32 bit unaligned fetch w/ byte swap on intel */
8 23411717 : #define FD_TEMPL_ENCODE_IMPL_uchar(p,val) ( \
9 23411717 : ( (p)[0] = (uchar)( (val) ) ) )
10 12 : #define FD_TEMPL_ENCODE_IMPL_ushort(p,val) ( \
11 12 : ( (p)[0] = (uchar)( (ushort)(val) >> (ushort)0x08 ) ), \
12 12 : ( (p)[1] = (uchar)( (ushort)(val) >> (ushort)0x00 ) ) )
13 3024252 : #define FD_TEMPL_ENCODE_IMPL_uint(p,val) ( \
14 3024252 : ( (p)[0] = (uchar)( (uint)(val) >> (uint)0x18 ) ), \
15 3024252 : ( (p)[1] = (uchar)( (uint)(val) >> (uint)0x10 ) ), \
16 3024252 : ( (p)[2] = (uchar)( (uint)(val) >> (uint)0x08 ) ), \
17 3024252 : ( (p)[3] = (uchar)( (uint)(val) >> (uint)0x00 ) ) )
18 3 : #define FD_TEMPL_ENCODE_IMPL_ulong(p,val) ( \
19 3 : ( (p)[0] = (uchar)( (ulong)(val) >> (ulong)0x38 ) ), \
20 3 : ( (p)[1] = (uchar)( (ulong)(val) >> (ulong)0x30 ) ), \
21 3 : ( (p)[2] = (uchar)( (ulong)(val) >> (ulong)0x28 ) ), \
22 3 : ( (p)[3] = (uchar)( (ulong)(val) >> (ulong)0x20 ) ), \
23 3 : ( (p)[4] = (uchar)( (ulong)(val) >> (ulong)0x18 ) ), \
24 3 : ( (p)[5] = (uchar)( (ulong)(val) >> (ulong)0x10 ) ), \
25 3 : ( (p)[6] = (uchar)( (ulong)(val) >> (ulong)0x08 ) ), \
26 3 : ( (p)[7] = (uchar)( (ulong)(val) >> (ulong)0x00 ) ) )
27 :
28 : /* encodes the given type, "returns" the number of bytes encoded */
29 26435984 : #define FD_TEMPL_ENCODE(TYPE,VAR,p) ( ( FD_TEMPL_ENCODE_IMPL_##TYPE((p),(VAR)) ), sizeof(fd_quic_##TYPE) )
30 :
31 : /* returns bytes encoded
32 :
33 : frame is not const, as it may be mutated, for example to store offsets
34 : to particular bytes in the encoded data */
35 : #define FD_TEMPL_DEF_STRUCT_BEGIN(NAME) \
36 : static inline \
37 : ulong \
38 : fd_quic_encode_##NAME( uchar * buf, \
39 : ulong sz, \
40 18981194 : fd_quic_##NAME##_t * frame ) { \
41 18981194 : (void)frame; \
42 18981194 : uchar * orig_buf = buf; \
43 18981194 : uchar * buf_end = buf + sz; \
44 18981194 : ulong tmp_len = 0; (void)tmp_len; \
45 18981194 : uchar * type_ptr = NULL; (void)type_ptr;
46 :
47 : /* encodes TYPE into output */
48 : #define FD_TEMPL_MBR_FRAME_TYPE(NAME,ID_LO,ID_HI) \
49 1617912 : if( buf >= buf_end ) return FD_QUIC_PARSE_FAIL; \
50 1617912 : buf[0] = ID_LO; \
51 1617909 : type_ptr = buf++;
52 :
53 :
54 : /* encodes aligned bytes into output */
55 : #define FD_TEMPL_MBR_ELEM(NAME,TYPE) \
56 26435984 : if( FD_UNLIKELY( buf+sizeof(fd_quic_##TYPE) > buf_end ) ) \
57 26435984 : return FD_QUIC_PARSE_FAIL; \
58 26435984 : buf += FD_TEMPL_ENCODE(TYPE,frame->NAME,buf);
59 :
60 :
61 : /* encodes a packet number. Assumes pkt_number_len == 3 (4 bytes)
62 : keeps the pointer to the start of the packet number field */
63 : #define FD_TEMPL_MBR_ELEM_PKTNUM(NAME,TYPE) \
64 14363099 : if( FD_UNLIKELY( buf+4 > buf_end ) ) return FD_QUIC_ENCODE_FAIL; \
65 14363099 : frame->NAME##_pnoff = (unsigned)( buf - orig_buf ); \
66 14363099 : FD_STORE( uint, buf, fd_uint_bswap( (uint)frame->NAME ) ); \
67 14363099 : buf += 4;
68 :
69 :
70 : /* encodes a VARINT
71 : always aligned
72 : most significant two bits represent the width of the int
73 : remaining bits are all data bits
74 : checks for capacity before writing */
75 : #define FD_TEMPL_MBR_ELEM_VARINT(NAME,TYPE) \
76 6489780 : if( FD_UNLIKELY( buf+8 > buf_end ) ) return FD_QUIC_ENCODE_FAIL; \
77 6489780 : buf += fd_quic_varint_encode( buf, frame->NAME );
78 :
79 :
80 : // VAR currently assumed to be aligned bytes
81 : #define FD_TEMPL_MBR_ELEM_VAR(NAME,MIN,MAX,LEN_NAME) \
82 20399579 : tmp_len = frame->LEN_NAME; \
83 20399579 : if( FD_UNLIKELY( tmp_len<(MIN) || tmp_len>(MAX) ) ) { \
84 0 : FD_LOG_DEBUG(( "buffer overflow encoding variable length field." \
85 0 : " field: " #NAME \
86 0 : " MIN: %lu" \
87 0 : " MAX: %lu" \
88 0 : " " #LEN_NAME ": %lu" \
89 0 : " tmp_len: %lu\n", \
90 0 : (ulong)MIN, \
91 0 : (ulong)MAX, \
92 0 : (ulong)frame->LEN_NAME, \
93 0 : (ulong)tmp_len )); \
94 0 : return FD_QUIC_PARSE_FAIL; \
95 0 : } \
96 20399579 : if( FD_UNLIKELY( (ulong)buf + tmp_len > (ulong)buf_end ) ) { \
97 0 : return FD_QUIC_PARSE_FAIL; \
98 0 : } \
99 20399579 : fd_memcpy( buf, frame->NAME, tmp_len ); \
100 20399579 : buf += tmp_len;
101 :
102 :
103 : #define FD_TEMPL_MBR_ELEM_VAR_RAW(NAME,MIN,MAX,LEN_NAME) \
104 12114 : FD_TEMPL_MBR_ELEM_VAR(NAME,MIN,MAX,LEN_NAME)
105 :
106 : #define FD_TEMPL_MBR_ELEM_RAW(NAME,BYTES) \
107 18 : if( FD_UNLIKELY( buf+(BYTES) > buf_end ) ) \
108 18 : return FD_QUIC_PARSE_FAIL; \
109 18 : memcpy( buf, frame->NAME, (BYTES) ); \
110 18 : buf += (BYTES);
111 :
112 : /* at end, return the number of bytes consumed */
113 : #define FD_TEMPL_DEF_STRUCT_END(NAME) \
114 18981152 : return (ulong)( buf-orig_buf ); \
115 18981179 : }
116 :
117 : #include "fd_quic_dft.h"
118 :
|