Line data Source code
1 : #include "fd_h2_hdr_match.h"
2 : #include "fd_hpack_private.h"
3 :
4 : FD_TL ulong fd_h2_hdr_match_seed;
5 :
6 : fd_h2_hdr_match_entry_t const fd_h2_hdr_match_entry_null = {0};
7 :
8 : static fd_h2_hdr_match_entry_t *
9 : fd_h2_hdr_matcher_insert1( fd_h2_hdr_match_entry_t * map,
10 : int id,
11 : char const * name, /* static lifetime */
12 1251 : ulong name_len ) {
13 1251 : fd_h2_hdr_match_key_t key = { .hdr=name, .hdr_len=(ushort)name_len };
14 1251 : fd_h2_hdr_match_entry_t * entry = fd_h2_hdr_map_insert( map, key );
15 1251 : if( FD_UNLIKELY( !entry ) ) return NULL;
16 1248 : entry->id = (short)id;
17 1248 : return entry;
18 1251 : }
19 :
20 : fd_h2_hdr_matcher_t *
21 : fd_h2_hdr_matcher_init( void * mem,
22 12 : ulong seed ) {
23 :
24 12 : if( FD_UNLIKELY( !mem ) ) {
25 3 : FD_LOG_WARNING(( "NULL mem" ));
26 3 : return NULL;
27 3 : }
28 9 : if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)mem, alignof(fd_h2_hdr_matcher_t) ) ) ) {
29 3 : FD_LOG_WARNING(( "misaligned mem" ));
30 3 : return NULL;
31 3 : }
32 :
33 6 : fd_h2_hdr_matcher_t * matcher = mem;
34 6 : if( FD_UNLIKELY( !fd_h2_hdr_map_join( fd_h2_hdr_map_new( matcher->entry ) ) ) ) {
35 0 : return NULL;
36 0 : }
37 6 : fd_h2_hdr_match_entry_t * map = matcher->entry;
38 6 : matcher->seed = seed;
39 6 : matcher->entry_cnt = 0UL;
40 :
41 6 : fd_h2_hdr_match_seed = seed;
42 :
43 6 : int last_header_id = 0;
44 372 : for( ulong i=1UL; i<=61; i++ ) {
45 366 : int header_id = (int)fd_h2_hpack_matcher[ i ];
46 366 : if( last_header_id==header_id ) continue;
47 312 : char const * name = fd_hpack_static_table[ i ].entry;
48 312 : ulong name_len = fd_hpack_static_table[ i ].name_len;
49 312 : fd_h2_hdr_matcher_insert1( map, header_id, name, name_len );
50 312 : last_header_id = header_id;
51 312 : }
52 6 : fd_h2_hdr_matcher_insert1( map, FD_H2_SEC_WEBSOCKET_KEY, "sec-websocket-key", 17UL );
53 6 : fd_h2_hdr_matcher_insert1( map, FD_H2_SEC_WEBSOCKET_EXTENSIONS, "sec-websocket-extensions", 24UL );
54 6 : fd_h2_hdr_matcher_insert1( map, FD_H2_SEC_WEBSOCKET_PROTOCOL, "sec-websocket-protocol", 22UL );
55 6 : fd_h2_hdr_matcher_insert1( map, FD_H2_SEC_WEBSOCKET_ACCEPT, "sec-websocket-accept", 20UL );
56 6 : fd_h2_hdr_matcher_insert1( map, FD_H2_SEC_WEBSOCKET_VERSION, "sec-websocket-version", 21UL );
57 :
58 : /* matcher->entry_cnt still 0, which is deliberate */
59 6 : return matcher;
60 6 : }
61 :
62 : void *
63 3 : fd_h2_hdr_matcher_fini( fd_h2_hdr_matcher_t * matcher ) {
64 3 : return matcher;
65 3 : }
66 :
67 : void
68 : fd_h2_hdr_matcher_insert( fd_h2_hdr_matcher_t * matcher,
69 : int id,
70 : char const * name, /* static lifetime */
71 909 : ulong name_len ) {
72 909 : if( FD_UNLIKELY( id<1 || id>SHORT_MAX ) ) {
73 0 : FD_LOG_ERR(( "id %d out of bounds", id ));
74 0 : }
75 909 : if( FD_UNLIKELY( matcher->entry_cnt>=FD_H2_HDR_MATCH_MAX ) ) {
76 0 : FD_LOG_ERR(( "too many header entries (%lu)", matcher->entry_cnt ));
77 0 : }
78 909 : if( FD_UNLIKELY( name_len==0 || name_len>USHORT_MAX ) ) {
79 0 : FD_LOG_ERR(( "invalid name_len: %lu", name_len ));
80 0 : }
81 909 : fd_h2_hdr_match_seed = matcher->seed;
82 909 : if( FD_UNLIKELY( !fd_h2_hdr_matcher_insert1( matcher->entry, id, name, name_len ) ) ) return;
83 906 : matcher->entry_cnt++;
84 906 : }
85 :
86 : schar const __attribute__((aligned(16)))
87 : fd_h2_hpack_matcher[ 62 ] = {
88 : [ 1 ] = FD_H2_HDR_AUTHORITY,
89 : [ 2 ] = FD_H2_HDR_METHOD,
90 : [ 3 ] = FD_H2_HDR_METHOD,
91 : [ 4 ] = FD_H2_HDR_PATH,
92 : [ 5 ] = FD_H2_HDR_PATH,
93 : [ 6 ] = FD_H2_HDR_SCHEME,
94 : [ 7 ] = FD_H2_HDR_SCHEME,
95 : [ 8 ] = FD_H2_HDR_STATUS,
96 : [ 9 ] = FD_H2_HDR_STATUS,
97 : [ 10 ] = FD_H2_HDR_STATUS,
98 : [ 11 ] = FD_H2_HDR_STATUS,
99 : [ 12 ] = FD_H2_HDR_STATUS,
100 : [ 13 ] = FD_H2_HDR_STATUS,
101 : [ 14 ] = FD_H2_HDR_STATUS,
102 : [ 15 ] = FD_H2_HDR_ACCEPT_CHARSET,
103 : [ 16 ] = FD_H2_HDR_ACCEPT_ENCODING,
104 : [ 17 ] = FD_H2_HDR_ACCEPT_LANGUAGE,
105 : [ 18 ] = FD_H2_HDR_ACCEPT_RANGES,
106 : [ 19 ] = FD_H2_HDR_ACCEPT,
107 : [ 20 ] = FD_H2_HDR_ACCESS_CONTROL_ALLOW_ORIGIN,
108 : [ 21 ] = FD_H2_HDR_AGE,
109 : [ 22 ] = FD_H2_HDR_ALLOW,
110 : [ 23 ] = FD_H2_HDR_AUTHORIZATION,
111 : [ 24 ] = FD_H2_HDR_CACHE_CONTROL,
112 : [ 25 ] = FD_H2_HDR_CONTENT_DISPOSITION,
113 : [ 26 ] = FD_H2_HDR_CONTENT_ENCODING,
114 : [ 27 ] = FD_H2_HDR_CONTENT_LANGUAGE,
115 : [ 28 ] = FD_H2_HDR_CONTENT_LENGTH,
116 : [ 29 ] = FD_H2_HDR_CONTENT_LOCATION,
117 : [ 30 ] = FD_H2_HDR_CONTENT_RANGE,
118 : [ 31 ] = FD_H2_HDR_CONTENT_TYPE,
119 : [ 32 ] = FD_H2_HDR_COOKIE,
120 : [ 33 ] = FD_H2_HDR_DATE,
121 : [ 34 ] = FD_H2_HDR_ETAG,
122 : [ 35 ] = FD_H2_HDR_EXPECT,
123 : [ 36 ] = FD_H2_HDR_EXPIRES,
124 : [ 37 ] = FD_H2_HDR_FROM,
125 : [ 38 ] = FD_H2_HDR_HOST,
126 : [ 39 ] = FD_H2_HDR_IF_MATCH,
127 : [ 40 ] = FD_H2_HDR_IF_MODIFIED_SINCE,
128 : [ 41 ] = FD_H2_HDR_IF_NONE_MATCH,
129 : [ 42 ] = FD_H2_HDR_IF_RANGE,
130 : [ 43 ] = FD_H2_HDR_IF_UNMODIFIED_SINCE,
131 : [ 44 ] = FD_H2_HDR_LAST_MODIFIED,
132 : [ 45 ] = FD_H2_HDR_LINK,
133 : [ 46 ] = FD_H2_HDR_LOCATION,
134 : [ 47 ] = FD_H2_HDR_MAX_FORWARDS,
135 : [ 48 ] = FD_H2_HDR_PROXY_AUTHENTICATE,
136 : [ 49 ] = FD_H2_HDR_PROXY_AUTHORIZATION,
137 : [ 50 ] = FD_H2_HDR_RANGE,
138 : [ 51 ] = FD_H2_HDR_REFERER,
139 : [ 52 ] = FD_H2_HDR_REFRESH,
140 : [ 53 ] = FD_H2_HDR_RETRY_AFTER,
141 : [ 54 ] = FD_H2_HDR_SERVER,
142 : [ 55 ] = FD_H2_HDR_SET_COOKIE,
143 : [ 56 ] = FD_H2_HDR_STRICT_TRANSPORT_SECURITY,
144 : [ 57 ] = FD_H2_HDR_TRANSFER_ENCODING,
145 : [ 58 ] = FD_H2_HDR_USER_AGENT,
146 : [ 59 ] = FD_H2_HDR_VARY,
147 : [ 60 ] = FD_H2_HDR_VIA,
148 : [ 61 ] = FD_H2_HDR_WWW_AUTHENTICATE
149 : };
|