Mercurial > hg > nginx
comparison src/event/ngx_event_quic.c @ 8220:7ada2feeac18 quic
Added processing of CONNECTION CLOSE frames.
Contents is parsed and debug is output. No actions are taken.
author | Vladimir Homutov <vl@nginx.com> |
---|---|
date | Mon, 16 Mar 2020 13:06:43 +0300 |
parents | 33feac1e57ac |
children | 69345a26ba69 |
comparison
equal
deleted
inserted
replaced
8219:1307308c3cf1 | 8220:7ada2feeac18 |
---|---|
127 #define NGX_QUIC_FT_PATH_RESPONSE 0x1b | 127 #define NGX_QUIC_FT_PATH_RESPONSE 0x1b |
128 #define NGX_QUIC_FT_CONNECTION_CLOSE 0x1c | 128 #define NGX_QUIC_FT_CONNECTION_CLOSE 0x1c |
129 #define NGX_QUIC_FT_CONNECTION_CLOSE2 0x1d // XXX | 129 #define NGX_QUIC_FT_CONNECTION_CLOSE2 0x1d // XXX |
130 #define NGX_QUIC_FT_HANDSHAKE_DONE 0x1e | 130 #define NGX_QUIC_FT_HANDSHAKE_DONE 0x1e |
131 | 131 |
132 | |
133 #define ngx_quic_stream_bit_off(val) (((val) & 0x04) ? 1 : 0) | 132 #define ngx_quic_stream_bit_off(val) (((val) & 0x04) ? 1 : 0) |
134 #define ngx_quic_stream_bit_len(val) (((val) & 0x02) ? 1 : 0) | 133 #define ngx_quic_stream_bit_len(val) (((val) & 0x02) ? 1 : 0) |
135 #define ngx_quic_stream_bit_fin(val) (((val) & 0x01) ? 1 : 0) | 134 #define ngx_quic_stream_bit_fin(val) (((val) & 0x01) ? 1 : 0) |
136 | 135 |
136 | |
137 #define NGX_QUIC_ERR_NO_ERROR 0x0 | |
138 #define NGX_QUIC_ERR_INTERNAL_ERROR 0x1 | |
139 #define NGX_QUIC_ERR_SERVER_BUSY 0x2 | |
140 #define NGX_QUIC_ERR_FLOW_CONTROL_ERROR 0x3 | |
141 #define NGX_QUIC_ERR_STREAM_LIMIT_ERROR 0x4 | |
142 #define NGX_QUIC_ERR_STREAM_STATE_ERROR 0x5 | |
143 #define NGX_QUIC_ERR_FINAL_SIZE_ERROR 0x6 | |
144 #define NGX_QUIC_ERR_FRAME_ENCODING_ERROR 0x7 | |
145 #define NGX_QUIC_ERR_TRANSPORT_PARAMETER_ERROR 0x8 | |
146 #define NGX_QUIC_ERR_CONNECTION_ID_LIMIT_ERROR 0x9 | |
147 #define NGX_QUIC_ERR_PROTOCOL_VIOLATION 0xA | |
148 #define NGX_QUIC_ERR_INVALID_TOKEN 0xB | |
149 /* 0xC is not defined */ | |
150 #define NGX_QUIC_ERR_CRYPTO_BUFFER_EXCEEDED 0xD | |
151 #define NGX_QUIC_ERR_CRYPTO_ERROR 0x10 | |
152 | |
153 #define NGX_QUIC_ERR_LAST NGX_QUIC_ERR_CRYPTO_ERROR | |
154 | |
155 /* literal errors indexed by corresponding value */ | |
156 static char *ngx_quic_errors[] = { | |
157 "NO_ERROR", | |
158 "INTERNAL_ERROR", | |
159 "SERVER_BUSY", | |
160 "FLOW_CONTROL_ERROR", | |
161 "STREAM_LIMIT_ERROR", | |
162 "STREAM_STATE_ERROR", | |
163 "FINAL_SIZE_ERROR", | |
164 "FRAME_ENCODING_ERROR", | |
165 "TRANSPORT_PARAMETER_ERROR", | |
166 "CONNECTION_ID_LIMIT_ERROR", | |
167 "PROTOCOL_VIOLATION", | |
168 "INVALID_TOKEN", | |
169 "", | |
170 "CRYPTO_BUFFER_EXCEEDED", | |
171 "CRYPTO_ERROR", | |
172 }; | |
137 | 173 |
138 | 174 |
139 /* TODO: real states, these are stubs */ | 175 /* TODO: real states, these are stubs */ |
140 typedef enum { | 176 typedef enum { |
141 NGX_QUIC_ST_INITIAL, | 177 NGX_QUIC_ST_INITIAL, |
194 uint64_t stream_id; | 230 uint64_t stream_id; |
195 uint64_t offset; | 231 uint64_t offset; |
196 uint64_t length; | 232 uint64_t length; |
197 u_char *data; | 233 u_char *data; |
198 } ngx_quic_stream_frame_t; | 234 } ngx_quic_stream_frame_t; |
235 | |
236 | |
237 typedef struct { | |
238 uint64_t error_code; | |
239 uint64_t frame_type; | |
240 ngx_str_t reason; | |
241 } ngx_quic_close_frame_t; | |
199 | 242 |
200 | 243 |
201 struct ngx_quic_frame_s { | 244 struct ngx_quic_frame_s { |
202 ngx_uint_t type; | 245 ngx_uint_t type; |
203 ngx_quic_level_t level; | 246 ngx_quic_level_t level; |
205 union { | 248 union { |
206 ngx_quic_crypto_frame_t crypto; | 249 ngx_quic_crypto_frame_t crypto; |
207 ngx_quic_ack_frame_t ack; | 250 ngx_quic_ack_frame_t ack; |
208 ngx_quic_ncid_t ncid; | 251 ngx_quic_ncid_t ncid; |
209 ngx_quic_stream_frame_t stream; | 252 ngx_quic_stream_frame_t stream; |
253 ngx_quic_close_frame_t close; | |
210 // more frames | 254 // more frames |
211 } u; | 255 } u; |
212 | 256 |
213 u_char info[128]; // for debug purposes | 257 u_char info[128]; // for debug purposes |
214 }; | 258 }; |
1736 p += 16; | 1780 p += 16; |
1737 | 1781 |
1738 break; | 1782 break; |
1739 | 1783 |
1740 case NGX_QUIC_FT_CONNECTION_CLOSE: | 1784 case NGX_QUIC_FT_CONNECTION_CLOSE: |
1741 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "connection close frame => NGX_ERROR"); | 1785 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "connection close frame"); |
1742 | 1786 |
1743 // TODO: parse connection close here | 1787 frame->u.close.error_code = ngx_quic_parse_int(&p); |
1744 return NGX_ERROR; | 1788 frame->u.close.frame_type = ngx_quic_parse_int(&p); // not in 0x1d CC |
1789 frame->u.close.reason.len = ngx_quic_parse_int(&p); | |
1790 frame->u.close.reason.data = p; | |
1791 p += frame->u.close.reason.len; | |
1792 | |
1793 if (frame->u.close.error_code > NGX_QUIC_ERR_LAST) { | |
1794 frame->u.close.error_code = NGX_QUIC_ERR_LAST; | |
1795 } | |
1745 break; | 1796 break; |
1746 | 1797 |
1747 case NGX_QUIC_FT_STREAM0: | 1798 case NGX_QUIC_FT_STREAM0: |
1748 case NGX_QUIC_FT_STREAM1: | 1799 case NGX_QUIC_FT_STREAM1: |
1749 case NGX_QUIC_FT_STREAM2: | 1800 case NGX_QUIC_FT_STREAM2: |
2035 { | 2086 { |
2036 u_char *end, *p; | 2087 u_char *end, *p; |
2037 ssize_t len; | 2088 ssize_t len; |
2038 ngx_buf_t *b; | 2089 ngx_buf_t *b; |
2039 ngx_log_t *log; | 2090 ngx_log_t *log; |
2040 ngx_uint_t ack_this; | 2091 ngx_uint_t ack_this, do_close; |
2041 ngx_pool_t *pool; | 2092 ngx_pool_t *pool; |
2042 ngx_event_t *rev, *wev; | 2093 ngx_event_t *rev, *wev; |
2043 ngx_quic_frame_t frame, *ack_frame; | 2094 ngx_quic_frame_t frame, *ack_frame; |
2044 ngx_quic_connection_t *qc; | 2095 ngx_quic_connection_t *qc; |
2045 ngx_quic_stream_node_t *sn; | 2096 ngx_quic_stream_node_t *sn; |
2048 | 2099 |
2049 p = pkt->payload.data; | 2100 p = pkt->payload.data; |
2050 end = p + pkt->payload.len; | 2101 end = p + pkt->payload.len; |
2051 | 2102 |
2052 ack_this = 0; | 2103 ack_this = 0; |
2104 do_close = 0; | |
2053 | 2105 |
2054 while (p < end) { | 2106 while (p < end) { |
2055 | 2107 |
2056 len = ngx_quic_read_frame(c, p, end, &frame); | 2108 len = ngx_quic_read_frame(c, p, end, &frame); |
2057 if (len < 0) { | 2109 if (len < 0) { |
2105 "NCID: { seq=%ui retire=%ui len=%ui}", | 2157 "NCID: { seq=%ui retire=%ui len=%ui}", |
2106 frame.u.ncid.seqnum, | 2158 frame.u.ncid.seqnum, |
2107 frame.u.ncid.retire, | 2159 frame.u.ncid.retire, |
2108 frame.u.ncid.len); | 2160 frame.u.ncid.len); |
2109 continue; | 2161 continue; |
2162 | |
2163 case NGX_QUIC_FT_CONNECTION_CLOSE: | |
2164 ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
2165 "CONN.CLOSE: { %s (0x%xi) type=0x%xi reason='%V'}", | |
2166 ngx_quic_errors[frame.u.close.error_code], | |
2167 frame.u.close.error_code, | |
2168 frame.u.close.frame_type, | |
2169 &frame.u.close.reason); | |
2170 | |
2171 do_close = 1; | |
2172 break; | |
2110 | 2173 |
2111 case NGX_QUIC_FT_STREAM0: | 2174 case NGX_QUIC_FT_STREAM0: |
2112 case NGX_QUIC_FT_STREAM1: | 2175 case NGX_QUIC_FT_STREAM1: |
2113 case NGX_QUIC_FT_STREAM2: | 2176 case NGX_QUIC_FT_STREAM2: |
2114 case NGX_QUIC_FT_STREAM3: | 2177 case NGX_QUIC_FT_STREAM3: |
2228 ngx_log_error(NGX_LOG_INFO, c->log, 0, | 2291 ngx_log_error(NGX_LOG_INFO, c->log, 0, |
2229 "trailing garbage in payload: %ui bytes", end - p); | 2292 "trailing garbage in payload: %ui bytes", end - p); |
2230 return NGX_ERROR; | 2293 return NGX_ERROR; |
2231 } | 2294 } |
2232 | 2295 |
2296 if (do_close) { | |
2297 // TODO: handle stream close | |
2298 } | |
2233 | 2299 |
2234 if (ack_this == 0) { | 2300 if (ack_this == 0) { |
2235 /* do not ack packets with ACKs and PADDING */ | 2301 /* do not ack packets with ACKs and PADDING */ |
2236 return NGX_OK; | 2302 return NGX_OK; |
2237 } | 2303 } |