comparison src/event/ngx_event_quic.c @ 7686: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
7685:1307308c3cf1 7686: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 }