Mercurial > hg > nginx
annotate src/event/ngx_event_quic.c @ 8398:8bec0ac23cf9 quic
Fixed retransmission of frames after closing connection.
Frames in sent queues are discarded, as no acknowledgment is expected
if the connection is closing.
author | Vladimir Homutov <vl@nginx.com> |
---|---|
date | Thu, 21 May 2020 15:41:01 +0300 |
parents | 1245e274b9ba |
children | ffd362e87eb2 |
rev | line source |
---|---|
8182
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
1 |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
2 /* |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
3 * Copyright (C) Nginx, Inc. |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
4 */ |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
5 |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
6 |
8171 | 7 #include <ngx_config.h> |
8 #include <ngx_core.h> | |
8208
4ae9ac69ab93
HTTP/QUIC interface reworked.
Vladimir Homutov <vl@nginx.com>
parents:
8207
diff
changeset
|
9 #include <ngx_event.h> |
8182
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
10 |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
11 |
8307
dc7ac778aafe
Introduced packet namespace in QUIC connection.
Vladimir Homutov <vl@nginx.com>
parents:
8306
diff
changeset
|
12 /* 0-RTT and 1-RTT data exist in the same packet number space, |
dc7ac778aafe
Introduced packet namespace in QUIC connection.
Vladimir Homutov <vl@nginx.com>
parents:
8306
diff
changeset
|
13 * so we have 3 packet number spaces: |
dc7ac778aafe
Introduced packet namespace in QUIC connection.
Vladimir Homutov <vl@nginx.com>
parents:
8306
diff
changeset
|
14 * |
dc7ac778aafe
Introduced packet namespace in QUIC connection.
Vladimir Homutov <vl@nginx.com>
parents:
8306
diff
changeset
|
15 * 0 - Initial |
dc7ac778aafe
Introduced packet namespace in QUIC connection.
Vladimir Homutov <vl@nginx.com>
parents:
8306
diff
changeset
|
16 * 1 - Handshake |
dc7ac778aafe
Introduced packet namespace in QUIC connection.
Vladimir Homutov <vl@nginx.com>
parents:
8306
diff
changeset
|
17 * 2 - 0-RTT and 1-RTT |
dc7ac778aafe
Introduced packet namespace in QUIC connection.
Vladimir Homutov <vl@nginx.com>
parents:
8306
diff
changeset
|
18 */ |
8331
bda817d16cc2
Rename types and variables used for packet number space.
Vladimir Homutov <vl@nginx.com>
parents:
8328
diff
changeset
|
19 #define ngx_quic_get_send_ctx(qc, level) \ |
bda817d16cc2
Rename types and variables used for packet number space.
Vladimir Homutov <vl@nginx.com>
parents:
8328
diff
changeset
|
20 ((level) == ssl_encryption_initial) ? &((qc)->send_ctx[0]) \ |
bda817d16cc2
Rename types and variables used for packet number space.
Vladimir Homutov <vl@nginx.com>
parents:
8328
diff
changeset
|
21 : (((level) == ssl_encryption_handshake) ? &((qc)->send_ctx[1]) \ |
bda817d16cc2
Rename types and variables used for packet number space.
Vladimir Homutov <vl@nginx.com>
parents:
8328
diff
changeset
|
22 : &((qc)->send_ctx[2])) |
bda817d16cc2
Rename types and variables used for packet number space.
Vladimir Homutov <vl@nginx.com>
parents:
8328
diff
changeset
|
23 |
bda817d16cc2
Rename types and variables used for packet number space.
Vladimir Homutov <vl@nginx.com>
parents:
8328
diff
changeset
|
24 #define NGX_QUIC_SEND_CTX_LAST (NGX_QUIC_ENCRYPTION_LAST - 1) |
8307
dc7ac778aafe
Introduced packet namespace in QUIC connection.
Vladimir Homutov <vl@nginx.com>
parents:
8306
diff
changeset
|
25 |
8314
de8981bf2dd5
Advertizing MAX_STREAMS (0x12) credit in advance.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8312
diff
changeset
|
26 #define NGX_QUIC_STREAMS_INC 16 |
de8981bf2dd5
Advertizing MAX_STREAMS (0x12) credit in advance.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8312
diff
changeset
|
27 #define NGX_QUIC_STREAMS_LIMIT (1ULL < 60) |
de8981bf2dd5
Advertizing MAX_STREAMS (0x12) credit in advance.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8312
diff
changeset
|
28 |
8333
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
29 /* |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
30 * 7.4. Cryptographic Message Buffering |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
31 * Implementations MUST support buffering at least 4096 bytes of data |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
32 */ |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
33 #define NGX_QUIC_MAX_BUFFERED 65535 |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
34 |
8307
dc7ac778aafe
Introduced packet namespace in QUIC connection.
Vladimir Homutov <vl@nginx.com>
parents:
8306
diff
changeset
|
35 |
8225 | 36 typedef struct { |
37 ngx_rbtree_t tree; | |
38 ngx_rbtree_node_t sentinel; | |
39 ngx_connection_handler_pt handler; | |
8229
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
40 |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
41 ngx_uint_t id_counter; |
8338
0f9e9786b90d
Added primitive flow control mechanisms.
Vladimir Homutov <vl@nginx.com>
parents:
8337
diff
changeset
|
42 |
8365
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
43 uint64_t received; |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
44 uint64_t sent; |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
45 uint64_t recv_max_data; |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
46 uint64_t send_max_data; |
8225 | 47 } ngx_quic_streams_t; |
8182
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
48 |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
49 |
8364
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
50 typedef struct { |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
51 size_t in_flight; |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
52 size_t window; |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
53 size_t ssthresh; |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
54 ngx_msec_t recovery_start; |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
55 } ngx_quic_congestion_t; |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
56 |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
57 |
8331
bda817d16cc2
Rename types and variables used for packet number space.
Vladimir Homutov <vl@nginx.com>
parents:
8328
diff
changeset
|
58 /* |
bda817d16cc2
Rename types and variables used for packet number space.
Vladimir Homutov <vl@nginx.com>
parents:
8328
diff
changeset
|
59 * 12.3. Packet Numbers |
bda817d16cc2
Rename types and variables used for packet number space.
Vladimir Homutov <vl@nginx.com>
parents:
8328
diff
changeset
|
60 * |
bda817d16cc2
Rename types and variables used for packet number space.
Vladimir Homutov <vl@nginx.com>
parents:
8328
diff
changeset
|
61 * Conceptually, a packet number space is the context in which a packet |
bda817d16cc2
Rename types and variables used for packet number space.
Vladimir Homutov <vl@nginx.com>
parents:
8328
diff
changeset
|
62 * can be processed and acknowledged. Initial packets can only be sent |
bda817d16cc2
Rename types and variables used for packet number space.
Vladimir Homutov <vl@nginx.com>
parents:
8328
diff
changeset
|
63 * with Initial packet protection keys and acknowledged in packets which |
bda817d16cc2
Rename types and variables used for packet number space.
Vladimir Homutov <vl@nginx.com>
parents:
8328
diff
changeset
|
64 * are also Initial packets. |
bda817d16cc2
Rename types and variables used for packet number space.
Vladimir Homutov <vl@nginx.com>
parents:
8328
diff
changeset
|
65 */ |
8307
dc7ac778aafe
Introduced packet namespace in QUIC connection.
Vladimir Homutov <vl@nginx.com>
parents:
8306
diff
changeset
|
66 typedef struct { |
dc7ac778aafe
Introduced packet namespace in QUIC connection.
Vladimir Homutov <vl@nginx.com>
parents:
8306
diff
changeset
|
67 ngx_quic_secret_t client_secret; |
dc7ac778aafe
Introduced packet namespace in QUIC connection.
Vladimir Homutov <vl@nginx.com>
parents:
8306
diff
changeset
|
68 ngx_quic_secret_t server_secret; |
dc7ac778aafe
Introduced packet namespace in QUIC connection.
Vladimir Homutov <vl@nginx.com>
parents:
8306
diff
changeset
|
69 |
8339
aba84d9ab256
Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8338
diff
changeset
|
70 uint64_t pnum; /* packet number to send */ |
8331
bda817d16cc2
Rename types and variables used for packet number space.
Vladimir Homutov <vl@nginx.com>
parents:
8328
diff
changeset
|
71 uint64_t largest_ack; /* number received from peer */ |
8339
aba84d9ab256
Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8338
diff
changeset
|
72 uint64_t largest_pn; /* number received from peer */ |
8308
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
73 |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
74 ngx_queue_t frames; |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
75 ngx_queue_t sent; |
8331
bda817d16cc2
Rename types and variables used for packet number space.
Vladimir Homutov <vl@nginx.com>
parents:
8328
diff
changeset
|
76 } ngx_quic_send_ctx_t; |
8307
dc7ac778aafe
Introduced packet namespace in QUIC connection.
Vladimir Homutov <vl@nginx.com>
parents:
8306
diff
changeset
|
77 |
dc7ac778aafe
Introduced packet namespace in QUIC connection.
Vladimir Homutov <vl@nginx.com>
parents:
8306
diff
changeset
|
78 |
8182
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
79 struct ngx_quic_connection_s { |
8225 | 80 ngx_str_t scid; |
81 ngx_str_t dcid; | |
8381
6e100d8c138a
Preserve original DCID and unbreak parsing 0-RTT packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8380
diff
changeset
|
82 ngx_str_t odcid; |
8225 | 83 ngx_str_t token; |
8182
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
84 |
8260
f388c0ad3477
Added processing of client transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8259
diff
changeset
|
85 ngx_uint_t client_tp_done; |
8247
e9891e8ee975
Configurable transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8246
diff
changeset
|
86 ngx_quic_tp_t tp; |
8265
d45325e90221
Limit output QUIC packets with client max_packet_size.
Roman Arutyunyan <arut@nginx.com>
parents:
8263
diff
changeset
|
87 ngx_quic_tp_t ctp; |
8247
e9891e8ee975
Configurable transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8246
diff
changeset
|
88 |
8397
1245e274b9ba
Avoided excessive definitions for connection state.
Vladimir Homutov <vl@nginx.com>
parents:
8394
diff
changeset
|
89 enum ssl_encryption_level_t state; |
8263
1295b293d09a
Connection states code cleanup.
Vladimir Homutov <vl@nginx.com>
parents:
8260
diff
changeset
|
90 |
8331
bda817d16cc2
Rename types and variables used for packet number space.
Vladimir Homutov <vl@nginx.com>
parents:
8328
diff
changeset
|
91 ngx_quic_send_ctx_t send_ctx[NGX_QUIC_SEND_CTX_LAST]; |
8306
058a5af7ddfc
Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents:
8305
diff
changeset
|
92 ngx_quic_secrets_t keys[NGX_QUIC_ENCRYPTION_LAST]; |
8319
29354c6fc5f2
TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8316
diff
changeset
|
93 ngx_quic_secrets_t next_key; |
8333
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
94 ngx_quic_frames_stream_t crypto[NGX_QUIC_ENCRYPTION_LAST]; |
8306
058a5af7ddfc
Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents:
8305
diff
changeset
|
95 |
8225 | 96 ngx_ssl_t *ssl; |
8308
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
97 |
8309 | 98 ngx_event_t push; |
8369
bddf704d62c1
Renamed retransmit event object in preparation for retry support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8368
diff
changeset
|
99 ngx_event_t retransmit; |
8355
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
100 ngx_event_t close; |
8308
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
101 ngx_queue_t free_frames; |
8355
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
102 ngx_msec_t last_cc; |
8286 | 103 |
104 #if (NGX_DEBUG) | |
105 ngx_uint_t nframes; | |
106 #endif | |
8208
4ae9ac69ab93
HTTP/QUIC interface reworked.
Vladimir Homutov <vl@nginx.com>
parents:
8207
diff
changeset
|
107 |
8225 | 108 ngx_quic_streams_t streams; |
8364
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
109 ngx_quic_congestion_t congestion; |
8281
618a65de08b3
When closing a QUIC connection, wait for all streams to finish.
Roman Arutyunyan <arut@nginx.com>
parents:
8280
diff
changeset
|
110 |
8314
de8981bf2dd5
Advertizing MAX_STREAMS (0x12) credit in advance.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8312
diff
changeset
|
111 uint64_t cur_streams; |
de8981bf2dd5
Advertizing MAX_STREAMS (0x12) credit in advance.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8312
diff
changeset
|
112 uint64_t max_streams; |
de8981bf2dd5
Advertizing MAX_STREAMS (0x12) credit in advance.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8312
diff
changeset
|
113 |
8385
fb7422074258
Added generation of CC frames with error on connection termination.
Vladimir Homutov <vl@nginx.com>
parents:
8384
diff
changeset
|
114 ngx_uint_t error; |
fb7422074258
Added generation of CC frames with error on connection termination.
Vladimir Homutov <vl@nginx.com>
parents:
8384
diff
changeset
|
115 |
8281
618a65de08b3
When closing a QUIC connection, wait for all streams to finish.
Roman Arutyunyan <arut@nginx.com>
parents:
8280
diff
changeset
|
116 unsigned send_timer_set:1; |
618a65de08b3
When closing a QUIC connection, wait for all streams to finish.
Roman Arutyunyan <arut@nginx.com>
parents:
8280
diff
changeset
|
117 unsigned closing:1; |
8355
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
118 unsigned draining:1; |
8319
29354c6fc5f2
TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8316
diff
changeset
|
119 unsigned key_phase:1; |
8383
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
120 unsigned in_retry:1; |
8397
1245e274b9ba
Avoided excessive definitions for connection state.
Vladimir Homutov <vl@nginx.com>
parents:
8394
diff
changeset
|
121 unsigned initialized:1; |
8225 | 122 }; |
8206
8d6ac639feac
Added support of multiple QUIC packets in single datagram.
Vladimir Homutov <vl@nginx.com>
parents:
8205
diff
changeset
|
123 |
8182
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
124 |
8335
76839f55bc48
Sorted functions and functions declarations.
Vladimir Homutov <vl@nginx.com>
parents:
8334
diff
changeset
|
125 typedef ngx_int_t (*ngx_quic_frame_handler_pt)(ngx_connection_t *c, |
8378
81a4f98a2556
Cleaned up reordering code.
Vladimir Homutov <vl@nginx.com>
parents:
8377
diff
changeset
|
126 ngx_quic_frame_t *frame, void *data); |
8335
76839f55bc48
Sorted functions and functions declarations.
Vladimir Homutov <vl@nginx.com>
parents:
8334
diff
changeset
|
127 |
76839f55bc48
Sorted functions and functions declarations.
Vladimir Homutov <vl@nginx.com>
parents:
8334
diff
changeset
|
128 |
8204
9e0c30e1f7fb
Compatibility with BoringSSL revised QUIC encryption secret APIs.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8203
diff
changeset
|
129 #if BORINGSSL_API_VERSION >= 10 |
9e0c30e1f7fb
Compatibility with BoringSSL revised QUIC encryption secret APIs.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8203
diff
changeset
|
130 static int ngx_quic_set_read_secret(ngx_ssl_conn_t *ssl_conn, |
9e0c30e1f7fb
Compatibility with BoringSSL revised QUIC encryption secret APIs.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8203
diff
changeset
|
131 enum ssl_encryption_level_t level, const SSL_CIPHER *cipher, |
9e0c30e1f7fb
Compatibility with BoringSSL revised QUIC encryption secret APIs.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8203
diff
changeset
|
132 const uint8_t *secret, size_t secret_len); |
9e0c30e1f7fb
Compatibility with BoringSSL revised QUIC encryption secret APIs.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8203
diff
changeset
|
133 static int ngx_quic_set_write_secret(ngx_ssl_conn_t *ssl_conn, |
9e0c30e1f7fb
Compatibility with BoringSSL revised QUIC encryption secret APIs.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8203
diff
changeset
|
134 enum ssl_encryption_level_t level, const SSL_CIPHER *cipher, |
9e0c30e1f7fb
Compatibility with BoringSSL revised QUIC encryption secret APIs.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8203
diff
changeset
|
135 const uint8_t *secret, size_t secret_len); |
9e0c30e1f7fb
Compatibility with BoringSSL revised QUIC encryption secret APIs.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8203
diff
changeset
|
136 #else |
8182
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
137 static int ngx_quic_set_encryption_secrets(ngx_ssl_conn_t *ssl_conn, |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
138 enum ssl_encryption_level_t level, const uint8_t *read_secret, |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
139 const uint8_t *write_secret, size_t secret_len); |
8204
9e0c30e1f7fb
Compatibility with BoringSSL revised QUIC encryption secret APIs.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8203
diff
changeset
|
140 #endif |
8225 | 141 |
8182
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
142 static int ngx_quic_add_handshake_data(ngx_ssl_conn_t *ssl_conn, |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
143 enum ssl_encryption_level_t level, const uint8_t *data, size_t len); |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
144 static int ngx_quic_flush_flight(ngx_ssl_conn_t *ssl_conn); |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
145 static int ngx_quic_send_alert(ngx_ssl_conn_t *ssl_conn, |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
146 enum ssl_encryption_level_t level, uint8_t alert); |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
147 |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
148 |
8225 | 149 static ngx_int_t ngx_quic_new_connection(ngx_connection_t *c, ngx_ssl_t *ssl, |
8304
90f94413177e
TLS Early Data support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8303
diff
changeset
|
150 ngx_quic_tp_t *tp, ngx_quic_header_t *pkt, |
90f94413177e
TLS Early Data support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8303
diff
changeset
|
151 ngx_connection_handler_pt handler); |
8382
b7704303a7e5
Server CID change refactored.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8381
diff
changeset
|
152 static ngx_int_t ngx_quic_new_dcid(ngx_connection_t *c, ngx_str_t *odcid); |
8383
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
153 static ngx_int_t ngx_quic_retry(ngx_connection_t *c); |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
154 static ngx_int_t ngx_quic_new_token(ngx_connection_t *c, ngx_str_t *token); |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
155 static ngx_int_t ngx_quic_validate_token(ngx_connection_t *c, |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
156 ngx_quic_header_t *pkt); |
8225 | 157 static ngx_int_t ngx_quic_init_connection(ngx_connection_t *c); |
8263
1295b293d09a
Connection states code cleanup.
Vladimir Homutov <vl@nginx.com>
parents:
8260
diff
changeset
|
158 static void ngx_quic_input_handler(ngx_event_t *rev); |
8354
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
159 |
8355
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
160 static void ngx_quic_close_connection(ngx_connection_t *c, ngx_int_t rc); |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
161 static ngx_int_t ngx_quic_close_quic(ngx_connection_t *c, ngx_int_t rc); |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
162 static void ngx_quic_close_timer_handler(ngx_event_t *ev); |
8354
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
163 static ngx_int_t ngx_quic_close_streams(ngx_connection_t *c, |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
164 ngx_quic_connection_t *qc); |
8225 | 165 |
166 static ngx_int_t ngx_quic_input(ngx_connection_t *c, ngx_buf_t *b); | |
8377
2a94aaa70b33
Cleaned up firefox workaround.
Vladimir Homutov <vl@nginx.com>
parents:
8371
diff
changeset
|
167 static ngx_inline u_char *ngx_quic_skip_zero_padding(ngx_buf_t *b); |
8383
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
168 static ngx_int_t ngx_quic_retry_input(ngx_connection_t *c, |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
169 ngx_quic_header_t *pkt); |
8225 | 170 static ngx_int_t ngx_quic_initial_input(ngx_connection_t *c, |
171 ngx_quic_header_t *pkt); | |
172 static ngx_int_t ngx_quic_handshake_input(ngx_connection_t *c, | |
173 ngx_quic_header_t *pkt); | |
8304
90f94413177e
TLS Early Data support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8303
diff
changeset
|
174 static ngx_int_t ngx_quic_early_input(ngx_connection_t *c, |
90f94413177e
TLS Early Data support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8303
diff
changeset
|
175 ngx_quic_header_t *pkt); |
8361 | 176 static ngx_int_t ngx_quic_check_peer(ngx_quic_connection_t *qc, |
177 ngx_quic_header_t *pkt); | |
8225 | 178 static ngx_int_t ngx_quic_app_input(ngx_connection_t *c, |
179 ngx_quic_header_t *pkt); | |
180 static ngx_int_t ngx_quic_payload_handler(ngx_connection_t *c, | |
181 ngx_quic_header_t *pkt); | |
8367
c10e7d48aa85
Factored out sending ACK from payload handler.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8365
diff
changeset
|
182 static ngx_int_t ngx_quic_send_ack(ngx_connection_t *c, ngx_quic_header_t *pkt); |
8355
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
183 static ngx_int_t ngx_quic_send_cc(ngx_connection_t *c, |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
184 enum ssl_encryption_level_t level, ngx_uint_t err); |
8384
52d0c4832570
Address validation using NEW_TOKEN frame.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8383
diff
changeset
|
185 static ngx_int_t ngx_quic_send_new_token(ngx_connection_t *c); |
8225 | 186 |
187 static ngx_int_t ngx_quic_handle_ack_frame(ngx_connection_t *c, | |
188 ngx_quic_header_t *pkt, ngx_quic_ack_frame_t *f); | |
8326 | 189 static ngx_int_t ngx_quic_handle_ack_frame_range(ngx_connection_t *c, |
8331
bda817d16cc2
Rename types and variables used for packet number space.
Vladimir Homutov <vl@nginx.com>
parents:
8328
diff
changeset
|
190 ngx_quic_send_ctx_t *ctx, uint64_t min, uint64_t max); |
8364
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
191 static void ngx_quic_handle_stream_ack(ngx_connection_t *c, |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
192 ngx_quic_frame_t *f); |
8335
76839f55bc48
Sorted functions and functions declarations.
Vladimir Homutov <vl@nginx.com>
parents:
8334
diff
changeset
|
193 |
76839f55bc48
Sorted functions and functions declarations.
Vladimir Homutov <vl@nginx.com>
parents:
8334
diff
changeset
|
194 static ngx_int_t ngx_quic_handle_ordered_frame(ngx_connection_t *c, |
76839f55bc48
Sorted functions and functions declarations.
Vladimir Homutov <vl@nginx.com>
parents:
8334
diff
changeset
|
195 ngx_quic_frames_stream_t *fs, ngx_quic_frame_t *frame, |
8378
81a4f98a2556
Cleaned up reordering code.
Vladimir Homutov <vl@nginx.com>
parents:
8377
diff
changeset
|
196 ngx_quic_frame_handler_pt handler, void *data); |
8333
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
197 static ngx_int_t ngx_quic_adjust_frame_offset(ngx_connection_t *c, |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
198 ngx_quic_frame_t *f, uint64_t offset_in); |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
199 static ngx_int_t ngx_quic_buffer_frame(ngx_connection_t *c, |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
200 ngx_quic_frames_stream_t *stream, ngx_quic_frame_t *f); |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
201 |
8335
76839f55bc48
Sorted functions and functions declarations.
Vladimir Homutov <vl@nginx.com>
parents:
8334
diff
changeset
|
202 static ngx_int_t ngx_quic_handle_crypto_frame(ngx_connection_t *c, |
76839f55bc48
Sorted functions and functions declarations.
Vladimir Homutov <vl@nginx.com>
parents:
8334
diff
changeset
|
203 ngx_quic_header_t *pkt, ngx_quic_frame_t *frame); |
8333
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
204 static ngx_int_t ngx_quic_crypto_input(ngx_connection_t *c, |
8378
81a4f98a2556
Cleaned up reordering code.
Vladimir Homutov <vl@nginx.com>
parents:
8377
diff
changeset
|
205 ngx_quic_frame_t *frame, void *data); |
8225 | 206 static ngx_int_t ngx_quic_handle_stream_frame(ngx_connection_t *c, |
8334
72d20158c814
Added reordering support for STREAM frames.
Vladimir Homutov <vl@nginx.com>
parents:
8333
diff
changeset
|
207 ngx_quic_header_t *pkt, ngx_quic_frame_t *frame); |
72d20158c814
Added reordering support for STREAM frames.
Vladimir Homutov <vl@nginx.com>
parents:
8333
diff
changeset
|
208 static ngx_int_t ngx_quic_stream_input(ngx_connection_t *c, |
8378
81a4f98a2556
Cleaned up reordering code.
Vladimir Homutov <vl@nginx.com>
parents:
8377
diff
changeset
|
209 ngx_quic_frame_t *frame, void *data); |
8334
72d20158c814
Added reordering support for STREAM frames.
Vladimir Homutov <vl@nginx.com>
parents:
8333
diff
changeset
|
210 |
8314
de8981bf2dd5
Advertizing MAX_STREAMS (0x12) credit in advance.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8312
diff
changeset
|
211 static ngx_int_t ngx_quic_handle_max_streams(ngx_connection_t *c); |
8365
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
212 static ngx_int_t ngx_quic_handle_max_data_frame(ngx_connection_t *c, |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
213 ngx_quic_max_data_frame_t *f); |
8245
a14afe21e692
Double MAX_STREAMS on STREAMS_BLOCKED.
Roman Arutyunyan <arut@nginx.com>
parents:
8241
diff
changeset
|
214 static ngx_int_t ngx_quic_handle_streams_blocked_frame(ngx_connection_t *c, |
a14afe21e692
Double MAX_STREAMS on STREAMS_BLOCKED.
Roman Arutyunyan <arut@nginx.com>
parents:
8241
diff
changeset
|
215 ngx_quic_header_t *pkt, ngx_quic_streams_blocked_frame_t *f); |
8266
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
216 static ngx_int_t ngx_quic_handle_stream_data_blocked_frame(ngx_connection_t *c, |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
217 ngx_quic_header_t *pkt, ngx_quic_stream_data_blocked_frame_t *f); |
8365
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
218 static ngx_int_t ngx_quic_handle_max_stream_data_frame(ngx_connection_t *c, |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
219 ngx_quic_header_t *pkt, ngx_quic_max_stream_data_frame_t *f); |
8225 | 220 |
221 static void ngx_quic_queue_frame(ngx_quic_connection_t *qc, | |
222 ngx_quic_frame_t *frame); | |
223 | |
224 static ngx_int_t ngx_quic_output(ngx_connection_t *c); | |
8331
bda817d16cc2
Rename types and variables used for packet number space.
Vladimir Homutov <vl@nginx.com>
parents:
8328
diff
changeset
|
225 static ngx_int_t ngx_quic_output_frames(ngx_connection_t *c, |
8332
6ad871b63422
Cleaned up magic numbers in ngx_quic_output_frames().
Vladimir Homutov <vl@nginx.com>
parents:
8331
diff
changeset
|
226 ngx_quic_send_ctx_t *ctx); |
8308
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
227 static void ngx_quic_free_frames(ngx_connection_t *c, ngx_queue_t *frames); |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
228 static ngx_int_t ngx_quic_send_frames(ngx_connection_t *c, ngx_queue_t *frames); |
8315
fdda518d10ba
Proper handling of packet number in header.
Vladimir Homutov <vl@nginx.com>
parents:
8314
diff
changeset
|
229 |
fdda518d10ba
Proper handling of packet number in header.
Vladimir Homutov <vl@nginx.com>
parents:
8314
diff
changeset
|
230 static void ngx_quic_set_packet_number(ngx_quic_header_t *pkt, |
8331
bda817d16cc2
Rename types and variables used for packet number space.
Vladimir Homutov <vl@nginx.com>
parents:
8328
diff
changeset
|
231 ngx_quic_send_ctx_t *ctx); |
8308
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
232 static void ngx_quic_retransmit_handler(ngx_event_t *ev); |
8331
bda817d16cc2
Rename types and variables used for packet number space.
Vladimir Homutov <vl@nginx.com>
parents:
8328
diff
changeset
|
233 static ngx_int_t ngx_quic_retransmit(ngx_connection_t *c, |
bda817d16cc2
Rename types and variables used for packet number space.
Vladimir Homutov <vl@nginx.com>
parents:
8328
diff
changeset
|
234 ngx_quic_send_ctx_t *ctx, ngx_msec_t *waitp); |
8309 | 235 static void ngx_quic_push_handler(ngx_event_t *ev); |
8225 | 236 |
237 static void ngx_quic_rbtree_insert_stream(ngx_rbtree_node_t *temp, | |
238 ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel); | |
8280
b364af7f9f3f
Removed ngx_quic_stream_node_t.
Roman Arutyunyan <arut@nginx.com>
parents:
8279
diff
changeset
|
239 static ngx_quic_stream_t *ngx_quic_find_stream(ngx_rbtree_t *rbtree, |
8284
2935a11c55b6
Fixed QUIC stream insert and find.
Roman Arutyunyan <arut@nginx.com>
parents:
8282
diff
changeset
|
240 uint64_t id); |
8280
b364af7f9f3f
Removed ngx_quic_stream_node_t.
Roman Arutyunyan <arut@nginx.com>
parents:
8279
diff
changeset
|
241 static ngx_quic_stream_t *ngx_quic_create_stream(ngx_connection_t *c, |
8282
4cf00c14f11a
Safe QUIC stream creation.
Roman Arutyunyan <arut@nginx.com>
parents:
8281
diff
changeset
|
242 uint64_t id, size_t rcvbuf_size); |
8211
6bc18966b8c1
Stream "connection" read/write methods.
Vladimir Homutov <vl@nginx.com>
parents:
8209
diff
changeset
|
243 static ssize_t ngx_quic_stream_recv(ngx_connection_t *c, u_char *buf, |
6bc18966b8c1
Stream "connection" read/write methods.
Vladimir Homutov <vl@nginx.com>
parents:
8209
diff
changeset
|
244 size_t size); |
6bc18966b8c1
Stream "connection" read/write methods.
Vladimir Homutov <vl@nginx.com>
parents:
8209
diff
changeset
|
245 static ssize_t ngx_quic_stream_send(ngx_connection_t *c, u_char *buf, |
6bc18966b8c1
Stream "connection" read/write methods.
Vladimir Homutov <vl@nginx.com>
parents:
8209
diff
changeset
|
246 size_t size); |
8239
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
247 static void ngx_quic_stream_cleanup_handler(void *data); |
8211
6bc18966b8c1
Stream "connection" read/write methods.
Vladimir Homutov <vl@nginx.com>
parents:
8209
diff
changeset
|
248 static ngx_chain_t *ngx_quic_stream_send_chain(ngx_connection_t *c, |
6bc18966b8c1
Stream "connection" read/write methods.
Vladimir Homutov <vl@nginx.com>
parents:
8209
diff
changeset
|
249 ngx_chain_t *in, off_t limit); |
8286 | 250 static ngx_quic_frame_t *ngx_quic_alloc_frame(ngx_connection_t *c, size_t size); |
251 static void ngx_quic_free_frame(ngx_connection_t *c, ngx_quic_frame_t *frame); | |
8211
6bc18966b8c1
Stream "connection" read/write methods.
Vladimir Homutov <vl@nginx.com>
parents:
8209
diff
changeset
|
252 |
8364
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
253 static void ngx_quic_congestion_ack(ngx_connection_t *c, |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
254 ngx_quic_frame_t *frame); |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
255 static void ngx_quic_congestion_lost(ngx_connection_t *c, ngx_msec_t sent); |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
256 |
8225 | 257 |
8182
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
258 static SSL_QUIC_METHOD quic_method = { |
8204
9e0c30e1f7fb
Compatibility with BoringSSL revised QUIC encryption secret APIs.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8203
diff
changeset
|
259 #if BORINGSSL_API_VERSION >= 10 |
9e0c30e1f7fb
Compatibility with BoringSSL revised QUIC encryption secret APIs.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8203
diff
changeset
|
260 ngx_quic_set_read_secret, |
9e0c30e1f7fb
Compatibility with BoringSSL revised QUIC encryption secret APIs.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8203
diff
changeset
|
261 ngx_quic_set_write_secret, |
9e0c30e1f7fb
Compatibility with BoringSSL revised QUIC encryption secret APIs.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8203
diff
changeset
|
262 #else |
8182
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
263 ngx_quic_set_encryption_secrets, |
8204
9e0c30e1f7fb
Compatibility with BoringSSL revised QUIC encryption secret APIs.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8203
diff
changeset
|
264 #endif |
8182
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
265 ngx_quic_add_handshake_data, |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
266 ngx_quic_flush_flight, |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
267 ngx_quic_send_alert, |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
268 }; |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
269 |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
270 |
8204
9e0c30e1f7fb
Compatibility with BoringSSL revised QUIC encryption secret APIs.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8203
diff
changeset
|
271 #if BORINGSSL_API_VERSION >= 10 |
9e0c30e1f7fb
Compatibility with BoringSSL revised QUIC encryption secret APIs.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8203
diff
changeset
|
272 |
9e0c30e1f7fb
Compatibility with BoringSSL revised QUIC encryption secret APIs.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8203
diff
changeset
|
273 static int |
9e0c30e1f7fb
Compatibility with BoringSSL revised QUIC encryption secret APIs.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8203
diff
changeset
|
274 ngx_quic_set_read_secret(ngx_ssl_conn_t *ssl_conn, |
9e0c30e1f7fb
Compatibility with BoringSSL revised QUIC encryption secret APIs.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8203
diff
changeset
|
275 enum ssl_encryption_level_t level, const SSL_CIPHER *cipher, |
8221
69345a26ba69
Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
8220
diff
changeset
|
276 const uint8_t *rsecret, size_t secret_len) |
8204
9e0c30e1f7fb
Compatibility with BoringSSL revised QUIC encryption secret APIs.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8203
diff
changeset
|
277 { |
8306
058a5af7ddfc
Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents:
8305
diff
changeset
|
278 ngx_connection_t *c; |
058a5af7ddfc
Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents:
8305
diff
changeset
|
279 ngx_quic_secrets_t *keys; |
8204
9e0c30e1f7fb
Compatibility with BoringSSL revised QUIC encryption secret APIs.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8203
diff
changeset
|
280 |
9e0c30e1f7fb
Compatibility with BoringSSL revised QUIC encryption secret APIs.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8203
diff
changeset
|
281 c = ngx_ssl_get_connection((ngx_ssl_conn_t *) ssl_conn); |
9e0c30e1f7fb
Compatibility with BoringSSL revised QUIC encryption secret APIs.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8203
diff
changeset
|
282 |
8359 | 283 #ifdef NGX_QUIC_DEBUG_CRYPTO |
8360
f175006124d0
Cleaned up hexdumps in debug output.
Vladimir Homutov <vl@nginx.com>
parents:
8359
diff
changeset
|
284 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, |
f175006124d0
Cleaned up hexdumps in debug output.
Vladimir Homutov <vl@nginx.com>
parents:
8359
diff
changeset
|
285 "quic ngx_quic_set_read_secret() level:%d", level); |
f175006124d0
Cleaned up hexdumps in debug output.
Vladimir Homutov <vl@nginx.com>
parents:
8359
diff
changeset
|
286 ngx_quic_hexdump(c->log, "quic read secret", rsecret, secret_len); |
8359 | 287 #endif |
8204
9e0c30e1f7fb
Compatibility with BoringSSL revised QUIC encryption secret APIs.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8203
diff
changeset
|
288 |
8306
058a5af7ddfc
Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents:
8305
diff
changeset
|
289 keys = &c->quic->keys[level]; |
058a5af7ddfc
Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents:
8305
diff
changeset
|
290 |
8304
90f94413177e
TLS Early Data support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8303
diff
changeset
|
291 if (level == ssl_encryption_early_data) { |
8397
1245e274b9ba
Avoided excessive definitions for connection state.
Vladimir Homutov <vl@nginx.com>
parents:
8394
diff
changeset
|
292 c->quic->state = ssl_encryption_early_data; |
8304
90f94413177e
TLS Early Data support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8303
diff
changeset
|
293 } |
90f94413177e
TLS Early Data support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8303
diff
changeset
|
294 |
8221
69345a26ba69
Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
8220
diff
changeset
|
295 return ngx_quic_set_encryption_secret(c->pool, ssl_conn, level, |
69345a26ba69
Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
8220
diff
changeset
|
296 rsecret, secret_len, |
8306
058a5af7ddfc
Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents:
8305
diff
changeset
|
297 &keys->client); |
8204
9e0c30e1f7fb
Compatibility with BoringSSL revised QUIC encryption secret APIs.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8203
diff
changeset
|
298 } |
9e0c30e1f7fb
Compatibility with BoringSSL revised QUIC encryption secret APIs.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8203
diff
changeset
|
299 |
9e0c30e1f7fb
Compatibility with BoringSSL revised QUIC encryption secret APIs.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8203
diff
changeset
|
300 |
9e0c30e1f7fb
Compatibility with BoringSSL revised QUIC encryption secret APIs.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8203
diff
changeset
|
301 static int |
9e0c30e1f7fb
Compatibility with BoringSSL revised QUIC encryption secret APIs.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8203
diff
changeset
|
302 ngx_quic_set_write_secret(ngx_ssl_conn_t *ssl_conn, |
9e0c30e1f7fb
Compatibility with BoringSSL revised QUIC encryption secret APIs.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8203
diff
changeset
|
303 enum ssl_encryption_level_t level, const SSL_CIPHER *cipher, |
8221
69345a26ba69
Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
8220
diff
changeset
|
304 const uint8_t *wsecret, size_t secret_len) |
8204
9e0c30e1f7fb
Compatibility with BoringSSL revised QUIC encryption secret APIs.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8203
diff
changeset
|
305 { |
8306
058a5af7ddfc
Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents:
8305
diff
changeset
|
306 ngx_connection_t *c; |
058a5af7ddfc
Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents:
8305
diff
changeset
|
307 ngx_quic_secrets_t *keys; |
8204
9e0c30e1f7fb
Compatibility with BoringSSL revised QUIC encryption secret APIs.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8203
diff
changeset
|
308 |
9e0c30e1f7fb
Compatibility with BoringSSL revised QUIC encryption secret APIs.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8203
diff
changeset
|
309 c = ngx_ssl_get_connection((ngx_ssl_conn_t *) ssl_conn); |
9e0c30e1f7fb
Compatibility with BoringSSL revised QUIC encryption secret APIs.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8203
diff
changeset
|
310 |
8359 | 311 #ifdef NGX_QUIC_DEBUG_CRYPTO |
8360
f175006124d0
Cleaned up hexdumps in debug output.
Vladimir Homutov <vl@nginx.com>
parents:
8359
diff
changeset
|
312 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, |
f175006124d0
Cleaned up hexdumps in debug output.
Vladimir Homutov <vl@nginx.com>
parents:
8359
diff
changeset
|
313 "quic ngx_quic_set_write_secret() level:%d", level); |
f175006124d0
Cleaned up hexdumps in debug output.
Vladimir Homutov <vl@nginx.com>
parents:
8359
diff
changeset
|
314 ngx_quic_hexdump(c->log, "quic write secret", wsecret, secret_len); |
8359 | 315 #endif |
8204
9e0c30e1f7fb
Compatibility with BoringSSL revised QUIC encryption secret APIs.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8203
diff
changeset
|
316 |
8306
058a5af7ddfc
Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents:
8305
diff
changeset
|
317 keys = &c->quic->keys[level]; |
058a5af7ddfc
Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents:
8305
diff
changeset
|
318 |
8221
69345a26ba69
Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
8220
diff
changeset
|
319 return ngx_quic_set_encryption_secret(c->pool, ssl_conn, level, |
69345a26ba69
Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
8220
diff
changeset
|
320 wsecret, secret_len, |
8306
058a5af7ddfc
Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents:
8305
diff
changeset
|
321 &keys->server); |
8204
9e0c30e1f7fb
Compatibility with BoringSSL revised QUIC encryption secret APIs.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8203
diff
changeset
|
322 } |
9e0c30e1f7fb
Compatibility with BoringSSL revised QUIC encryption secret APIs.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8203
diff
changeset
|
323 |
9e0c30e1f7fb
Compatibility with BoringSSL revised QUIC encryption secret APIs.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8203
diff
changeset
|
324 #else |
9e0c30e1f7fb
Compatibility with BoringSSL revised QUIC encryption secret APIs.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8203
diff
changeset
|
325 |
8182
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
326 static int |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
327 ngx_quic_set_encryption_secrets(ngx_ssl_conn_t *ssl_conn, |
8221
69345a26ba69
Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
8220
diff
changeset
|
328 enum ssl_encryption_level_t level, const uint8_t *rsecret, |
69345a26ba69
Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
8220
diff
changeset
|
329 const uint8_t *wsecret, size_t secret_len) |
8182
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
330 { |
8306
058a5af7ddfc
Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents:
8305
diff
changeset
|
331 ngx_int_t rc; |
058a5af7ddfc
Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents:
8305
diff
changeset
|
332 ngx_connection_t *c; |
058a5af7ddfc
Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents:
8305
diff
changeset
|
333 ngx_quic_secrets_t *keys; |
8182
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
334 |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
335 c = ngx_ssl_get_connection((ngx_ssl_conn_t *) ssl_conn); |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
336 |
8359 | 337 #ifdef NGX_QUIC_DEBUG_CRYPTO |
8360
f175006124d0
Cleaned up hexdumps in debug output.
Vladimir Homutov <vl@nginx.com>
parents:
8359
diff
changeset
|
338 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, |
f175006124d0
Cleaned up hexdumps in debug output.
Vladimir Homutov <vl@nginx.com>
parents:
8359
diff
changeset
|
339 "quic ngx_quic_set_encryption_secrets() level:%d", level); |
f175006124d0
Cleaned up hexdumps in debug output.
Vladimir Homutov <vl@nginx.com>
parents:
8359
diff
changeset
|
340 ngx_quic_hexdump(c->log, "quic read", rsecret, secret_len); |
8359 | 341 #endif |
8182
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
342 |
8327
0ae50d90658a
Fixed build with OpenSSL using old callbacks API.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8326
diff
changeset
|
343 keys = &c->quic->keys[level]; |
8306
058a5af7ddfc
Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents:
8305
diff
changeset
|
344 |
8221
69345a26ba69
Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
8220
diff
changeset
|
345 rc = ngx_quic_set_encryption_secret(c->pool, ssl_conn, level, |
69345a26ba69
Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
8220
diff
changeset
|
346 rsecret, secret_len, |
8306
058a5af7ddfc
Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents:
8305
diff
changeset
|
347 &keys->client); |
8221
69345a26ba69
Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
8220
diff
changeset
|
348 if (rc != 1) { |
69345a26ba69
Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
8220
diff
changeset
|
349 return rc; |
8182
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
350 } |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
351 |
8303
2ac03e80d013
TLS Early Data key derivation support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8302
diff
changeset
|
352 if (level == ssl_encryption_early_data) { |
8397
1245e274b9ba
Avoided excessive definitions for connection state.
Vladimir Homutov <vl@nginx.com>
parents:
8394
diff
changeset
|
353 c->quic->state = ssl_encryption_early_data; |
8303
2ac03e80d013
TLS Early Data key derivation support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8302
diff
changeset
|
354 return 1; |
2ac03e80d013
TLS Early Data key derivation support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8302
diff
changeset
|
355 } |
2ac03e80d013
TLS Early Data key derivation support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8302
diff
changeset
|
356 |
8359 | 357 #ifdef NGX_QUIC_DEBUG_CRYPTO |
8360
f175006124d0
Cleaned up hexdumps in debug output.
Vladimir Homutov <vl@nginx.com>
parents:
8359
diff
changeset
|
358 ngx_quic_hexdump(c->log, "quic write", wsecret, secret_len); |
8359 | 359 #endif |
8303
2ac03e80d013
TLS Early Data key derivation support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8302
diff
changeset
|
360 |
8221
69345a26ba69
Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
8220
diff
changeset
|
361 return ngx_quic_set_encryption_secret(c->pool, ssl_conn, level, |
69345a26ba69
Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
8220
diff
changeset
|
362 wsecret, secret_len, |
8306
058a5af7ddfc
Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents:
8305
diff
changeset
|
363 &keys->server); |
8182
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
364 } |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
365 |
8204
9e0c30e1f7fb
Compatibility with BoringSSL revised QUIC encryption secret APIs.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8203
diff
changeset
|
366 #endif |
9e0c30e1f7fb
Compatibility with BoringSSL revised QUIC encryption secret APIs.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8203
diff
changeset
|
367 |
8182
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
368 |
8184
ec1f84996990
Split frame and packet generation into separate steps.
Vladimir Homutov <vl@nginx.com>
parents:
8183
diff
changeset
|
369 static int |
ec1f84996990
Split frame and packet generation into separate steps.
Vladimir Homutov <vl@nginx.com>
parents:
8183
diff
changeset
|
370 ngx_quic_add_handshake_data(ngx_ssl_conn_t *ssl_conn, |
ec1f84996990
Split frame and packet generation into separate steps.
Vladimir Homutov <vl@nginx.com>
parents:
8183
diff
changeset
|
371 enum ssl_encryption_level_t level, const uint8_t *data, size_t len) |
ec1f84996990
Split frame and packet generation into separate steps.
Vladimir Homutov <vl@nginx.com>
parents:
8183
diff
changeset
|
372 { |
8333
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
373 u_char *p, *end; |
8345
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
374 size_t client_params_len, fsize, limit; |
8333
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
375 const uint8_t *client_params; |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
376 ngx_quic_frame_t *frame; |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
377 ngx_connection_t *c; |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
378 ngx_quic_connection_t *qc; |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
379 ngx_quic_frames_stream_t *fs; |
8184
ec1f84996990
Split frame and packet generation into separate steps.
Vladimir Homutov <vl@nginx.com>
parents:
8183
diff
changeset
|
380 |
ec1f84996990
Split frame and packet generation into separate steps.
Vladimir Homutov <vl@nginx.com>
parents:
8183
diff
changeset
|
381 c = ngx_ssl_get_connection((ngx_ssl_conn_t *) ssl_conn); |
ec1f84996990
Split frame and packet generation into separate steps.
Vladimir Homutov <vl@nginx.com>
parents:
8183
diff
changeset
|
382 qc = c->quic; |
ec1f84996990
Split frame and packet generation into separate steps.
Vladimir Homutov <vl@nginx.com>
parents:
8183
diff
changeset
|
383 |
8186
0a2683df5f11
Implemented improved version of quic_output().
Vladimir Homutov <vl@nginx.com>
parents:
8185
diff
changeset
|
384 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, |
8359 | 385 "quic ngx_quic_add_handshake_data"); |
8184
ec1f84996990
Split frame and packet generation into separate steps.
Vladimir Homutov <vl@nginx.com>
parents:
8183
diff
changeset
|
386 |
8260
f388c0ad3477
Added processing of client transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8259
diff
changeset
|
387 if (!qc->client_tp_done) { |
f388c0ad3477
Added processing of client transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8259
diff
changeset
|
388 |
f388c0ad3477
Added processing of client transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8259
diff
changeset
|
389 SSL_get_peer_quic_transport_params(ssl_conn, &client_params, |
f388c0ad3477
Added processing of client transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8259
diff
changeset
|
390 &client_params_len); |
f388c0ad3477
Added processing of client transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8259
diff
changeset
|
391 |
f388c0ad3477
Added processing of client transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8259
diff
changeset
|
392 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, |
8359 | 393 "quic SSL_get_peer_quic_transport_params():" |
394 " params_len %ui", client_params_len); | |
8260
f388c0ad3477
Added processing of client transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8259
diff
changeset
|
395 |
f388c0ad3477
Added processing of client transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8259
diff
changeset
|
396 if (client_params_len != 0) { |
f388c0ad3477
Added processing of client transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8259
diff
changeset
|
397 p = (u_char *) client_params; |
f388c0ad3477
Added processing of client transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8259
diff
changeset
|
398 end = p + client_params_len; |
f388c0ad3477
Added processing of client transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8259
diff
changeset
|
399 |
8265
d45325e90221
Limit output QUIC packets with client max_packet_size.
Roman Arutyunyan <arut@nginx.com>
parents:
8263
diff
changeset
|
400 if (ngx_quic_parse_transport_params(p, end, &qc->ctp, c->log) |
d45325e90221
Limit output QUIC packets with client max_packet_size.
Roman Arutyunyan <arut@nginx.com>
parents:
8263
diff
changeset
|
401 != NGX_OK) |
8260
f388c0ad3477
Added processing of client transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8259
diff
changeset
|
402 { |
8385
fb7422074258
Added generation of CC frames with error on connection termination.
Vladimir Homutov <vl@nginx.com>
parents:
8384
diff
changeset
|
403 qc->error = NGX_QUIC_ERR_TRANSPORT_PARAMETER_ERROR; |
8260
f388c0ad3477
Added processing of client transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8259
diff
changeset
|
404 return NGX_ERROR; |
f388c0ad3477
Added processing of client transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8259
diff
changeset
|
405 } |
f388c0ad3477
Added processing of client transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8259
diff
changeset
|
406 |
8271
8e54a17dabee
Respect QUIC max_idle_timeout.
Roman Arutyunyan <arut@nginx.com>
parents:
8270
diff
changeset
|
407 if (qc->ctp.max_idle_timeout > 0 |
8e54a17dabee
Respect QUIC max_idle_timeout.
Roman Arutyunyan <arut@nginx.com>
parents:
8270
diff
changeset
|
408 && qc->ctp.max_idle_timeout < qc->tp.max_idle_timeout) |
8e54a17dabee
Respect QUIC max_idle_timeout.
Roman Arutyunyan <arut@nginx.com>
parents:
8270
diff
changeset
|
409 { |
8e54a17dabee
Respect QUIC max_idle_timeout.
Roman Arutyunyan <arut@nginx.com>
parents:
8270
diff
changeset
|
410 qc->tp.max_idle_timeout = qc->ctp.max_idle_timeout; |
8e54a17dabee
Respect QUIC max_idle_timeout.
Roman Arutyunyan <arut@nginx.com>
parents:
8270
diff
changeset
|
411 } |
8e54a17dabee
Respect QUIC max_idle_timeout.
Roman Arutyunyan <arut@nginx.com>
parents:
8270
diff
changeset
|
412 |
8345
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
413 if (qc->ctp.max_packet_size < NGX_QUIC_MIN_INITIAL_SIZE |
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
414 || qc->ctp.max_packet_size > NGX_QUIC_DEFAULT_MAX_PACKET_SIZE) |
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
415 { |
8385
fb7422074258
Added generation of CC frames with error on connection termination.
Vladimir Homutov <vl@nginx.com>
parents:
8384
diff
changeset
|
416 qc->error = NGX_QUIC_ERR_TRANSPORT_PARAMETER_ERROR; |
8345
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
417 ngx_log_error(NGX_LOG_INFO, c->log, 0, |
8361 | 418 "quic maximum packet size is invalid"); |
8345
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
419 return NGX_ERROR; |
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
420 } |
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
421 |
8260
f388c0ad3477
Added processing of client transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8259
diff
changeset
|
422 qc->client_tp_done = 1; |
f388c0ad3477
Added processing of client transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8259
diff
changeset
|
423 } |
f388c0ad3477
Added processing of client transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8259
diff
changeset
|
424 } |
f388c0ad3477
Added processing of client transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8259
diff
changeset
|
425 |
8345
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
426 /* |
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
427 * we need to fit at least 1 frame into a packet, thus account head/tail; |
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
428 * 17 = 1 + 8x2 is max header for CRYPTO frame, with 1 byte for frame type |
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
429 */ |
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
430 limit = qc->ctp.max_packet_size - NGX_QUIC_MAX_LONG_HEADER - 17 |
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
431 - EVP_GCM_TLS_TAG_LEN; |
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
432 |
8333
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
433 fs = &qc->crypto[level]; |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
434 |
8345
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
435 p = (u_char *) data; |
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
436 end = (u_char *) data + len; |
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
437 |
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
438 while (p < end) { |
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
439 |
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
440 fsize = ngx_min(limit, (size_t) (end - p)); |
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
441 |
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
442 frame = ngx_quic_alloc_frame(c, fsize); |
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
443 if (frame == NULL) { |
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
444 return 0; |
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
445 } |
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
446 |
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
447 ngx_memcpy(frame->data, p, fsize); |
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
448 |
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
449 frame->level = level; |
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
450 frame->type = NGX_QUIC_FT_CRYPTO; |
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
451 frame->u.crypto.offset = fs->sent; |
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
452 frame->u.crypto.length = fsize; |
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
453 frame->u.crypto.data = frame->data; |
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
454 |
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
455 fs->sent += fsize; |
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
456 p += fsize; |
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
457 |
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
458 ngx_sprintf(frame->info, "crypto, generated by SSL len=%ui level=%d", |
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
459 fsize, level); |
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
460 |
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
461 ngx_quic_queue_frame(qc, frame); |
8186
0a2683df5f11
Implemented improved version of quic_output().
Vladimir Homutov <vl@nginx.com>
parents:
8185
diff
changeset
|
462 } |
8184
ec1f84996990
Split frame and packet generation into separate steps.
Vladimir Homutov <vl@nginx.com>
parents:
8183
diff
changeset
|
463 |
8182
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
464 return 1; |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
465 } |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
466 |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
467 |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
468 static int |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
469 ngx_quic_flush_flight(ngx_ssl_conn_t *ssl_conn) |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
470 { |
8360
f175006124d0
Cleaned up hexdumps in debug output.
Vladimir Homutov <vl@nginx.com>
parents:
8359
diff
changeset
|
471 #if (NGX_DEBUG) |
8182
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
472 ngx_connection_t *c; |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
473 |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
474 c = ngx_ssl_get_connection((ngx_ssl_conn_t *) ssl_conn); |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
475 |
8359 | 476 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, |
477 "quic ngx_quic_flush_flight()"); | |
8360
f175006124d0
Cleaned up hexdumps in debug output.
Vladimir Homutov <vl@nginx.com>
parents:
8359
diff
changeset
|
478 #endif |
8182
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
479 return 1; |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
480 } |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
481 |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
482 |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
483 static int |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
484 ngx_quic_send_alert(ngx_ssl_conn_t *ssl_conn, enum ssl_encryption_level_t level, |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
485 uint8_t alert) |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
486 { |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
487 ngx_connection_t *c; |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
488 |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
489 c = ngx_ssl_get_connection((ngx_ssl_conn_t *) ssl_conn); |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
490 |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
491 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, |
8359 | 492 "quic ngx_quic_send_alert(), lvl=%d, alert=%d", |
8182
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
493 (int) level, (int) alert); |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
494 |
8355
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
495 if (c->quic == NULL) { |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
496 return 1; |
8235
552d6868091b
Implemented send_alert callback, CONNECTION_CLOSE writer.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8234
diff
changeset
|
497 } |
552d6868091b
Implemented send_alert callback, CONNECTION_CLOSE writer.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8234
diff
changeset
|
498 |
8355
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
499 if (ngx_quic_send_cc(c, level, 0x100 + alert) != NGX_OK) { |
8235
552d6868091b
Implemented send_alert callback, CONNECTION_CLOSE writer.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8234
diff
changeset
|
500 return 0; |
552d6868091b
Implemented send_alert callback, CONNECTION_CLOSE writer.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8234
diff
changeset
|
501 } |
552d6868091b
Implemented send_alert callback, CONNECTION_CLOSE writer.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8234
diff
changeset
|
502 |
8182
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
503 return 1; |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
504 } |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
505 |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
506 |
8225 | 507 void |
8247
e9891e8ee975
Configurable transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8246
diff
changeset
|
508 ngx_quic_run(ngx_connection_t *c, ngx_ssl_t *ssl, ngx_quic_tp_t *tp, |
8271
8e54a17dabee
Respect QUIC max_idle_timeout.
Roman Arutyunyan <arut@nginx.com>
parents:
8270
diff
changeset
|
509 ngx_connection_handler_pt handler) |
8225 | 510 { |
511 ngx_buf_t *b; | |
512 ngx_quic_header_t pkt; | |
513 | |
8263
1295b293d09a
Connection states code cleanup.
Vladimir Homutov <vl@nginx.com>
parents:
8260
diff
changeset
|
514 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "quic run"); |
8225 | 515 |
8263
1295b293d09a
Connection states code cleanup.
Vladimir Homutov <vl@nginx.com>
parents:
8260
diff
changeset
|
516 c->log->action = "QUIC initialization"; |
8225 | 517 |
518 ngx_memzero(&pkt, sizeof(ngx_quic_header_t)); | |
519 | |
520 b = c->buffer; | |
521 | |
522 pkt.log = c->log; | |
523 pkt.raw = b; | |
524 pkt.data = b->start; | |
525 pkt.len = b->last - b->start; | |
526 | |
8304
90f94413177e
TLS Early Data support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8303
diff
changeset
|
527 if (ngx_quic_new_connection(c, ssl, tp, &pkt, handler) != NGX_OK) { |
8355
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
528 ngx_quic_close_connection(c, NGX_ERROR); |
8225 | 529 return; |
530 } | |
531 | |
8383
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
532 ngx_add_timer(c->read, c->quic->in_retry ? NGX_QUIC_RETRY_TIMEOUT |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
533 : c->quic->tp.max_idle_timeout); |
8225 | 534 |
8263
1295b293d09a
Connection states code cleanup.
Vladimir Homutov <vl@nginx.com>
parents:
8260
diff
changeset
|
535 c->read->handler = ngx_quic_input_handler; |
8225 | 536 |
537 return; | |
538 } | |
539 | |
8199
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
540 |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
541 static ngx_int_t |
8247
e9891e8ee975
Configurable transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8246
diff
changeset
|
542 ngx_quic_new_connection(ngx_connection_t *c, ngx_ssl_t *ssl, ngx_quic_tp_t *tp, |
8304
90f94413177e
TLS Early Data support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8303
diff
changeset
|
543 ngx_quic_header_t *pkt, ngx_connection_handler_pt handler) |
8199
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
544 { |
8384
52d0c4832570
Address validation using NEW_TOKEN frame.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8383
diff
changeset
|
545 ngx_int_t rc; |
8308
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
546 ngx_uint_t i; |
8265
d45325e90221
Limit output QUIC packets with client max_packet_size.
Roman Arutyunyan <arut@nginx.com>
parents:
8263
diff
changeset
|
547 ngx_quic_tp_t *ctp; |
8306
058a5af7ddfc
Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents:
8305
diff
changeset
|
548 ngx_quic_secrets_t *keys; |
8339
aba84d9ab256
Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8338
diff
changeset
|
549 ngx_quic_send_ctx_t *ctx; |
8225 | 550 ngx_quic_connection_t *qc; |
8288
ebd5c71b9f02
Got rid of memory allocation in decryption.
Vladimir Homutov <vl@nginx.com>
parents:
8286
diff
changeset
|
551 static u_char buf[NGX_QUIC_DEFAULT_MAX_PACKET_SIZE]; |
8199
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
552 |
8345
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
553 if (ngx_buf_size(pkt->raw) < NGX_QUIC_MIN_INITIAL_SIZE) { |
8361 | 554 ngx_log_error(NGX_LOG_INFO, c->log, 0, |
555 "quic UDP datagram is too small for initial packet"); | |
8225 | 556 return NGX_ERROR; |
557 } | |
8199
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
558 |
8386
81f85c479d7e
Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents:
8385
diff
changeset
|
559 rc = ngx_quic_parse_long_header(pkt); |
81f85c479d7e
Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents:
8385
diff
changeset
|
560 if (rc != NGX_OK) { |
81f85c479d7e
Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents:
8385
diff
changeset
|
561 return rc; |
8199
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
562 } |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
563 |
8251
c217a907ce42
Added checks for permitted frame types.
Vladimir Homutov <vl@nginx.com>
parents:
8247
diff
changeset
|
564 if (!ngx_quic_pkt_in(pkt->flags)) { |
8225 | 565 ngx_log_error(NGX_LOG_INFO, c->log, 0, |
8361 | 566 "quic invalid initial packet: 0x%xi", pkt->flags); |
8225 | 567 return NGX_ERROR; |
568 } | |
8199
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
569 |
8225 | 570 if (ngx_quic_parse_initial_header(pkt) != NGX_OK) { |
571 return NGX_ERROR; | |
572 } | |
8199
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
573 |
8387
eebdda507ec3
Added tests for connection id lengths in initial packet.
Vladimir Homutov <vl@nginx.com>
parents:
8386
diff
changeset
|
574 if (pkt->dcid.len < NGX_QUIC_CID_LEN_MIN) { |
eebdda507ec3
Added tests for connection id lengths in initial packet.
Vladimir Homutov <vl@nginx.com>
parents:
8386
diff
changeset
|
575 /* 7.2. Negotiating Connection IDs */ |
eebdda507ec3
Added tests for connection id lengths in initial packet.
Vladimir Homutov <vl@nginx.com>
parents:
8386
diff
changeset
|
576 ngx_log_error(NGX_LOG_INFO, c->log, 0, |
eebdda507ec3
Added tests for connection id lengths in initial packet.
Vladimir Homutov <vl@nginx.com>
parents:
8386
diff
changeset
|
577 "quic too short dcid in initial packet: length %i", |
eebdda507ec3
Added tests for connection id lengths in initial packet.
Vladimir Homutov <vl@nginx.com>
parents:
8386
diff
changeset
|
578 pkt->dcid.len); |
eebdda507ec3
Added tests for connection id lengths in initial packet.
Vladimir Homutov <vl@nginx.com>
parents:
8386
diff
changeset
|
579 return NGX_ERROR; |
eebdda507ec3
Added tests for connection id lengths in initial packet.
Vladimir Homutov <vl@nginx.com>
parents:
8386
diff
changeset
|
580 } |
eebdda507ec3
Added tests for connection id lengths in initial packet.
Vladimir Homutov <vl@nginx.com>
parents:
8386
diff
changeset
|
581 |
8275 | 582 c->log->action = "creating new quic connection"; |
583 | |
8225 | 584 qc = ngx_pcalloc(c->pool, sizeof(ngx_quic_connection_t)); |
585 if (qc == NULL) { | |
586 return NGX_ERROR; | |
8199
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
587 } |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
588 |
8225 | 589 ngx_rbtree_init(&qc->streams.tree, &qc->streams.sentinel, |
590 ngx_quic_rbtree_insert_stream); | |
591 | |
8333
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
592 for (i = 0; i < NGX_QUIC_SEND_CTX_LAST; i++) { |
8331
bda817d16cc2
Rename types and variables used for packet number space.
Vladimir Homutov <vl@nginx.com>
parents:
8328
diff
changeset
|
593 ngx_queue_init(&qc->send_ctx[i].frames); |
bda817d16cc2
Rename types and variables used for packet number space.
Vladimir Homutov <vl@nginx.com>
parents:
8328
diff
changeset
|
594 ngx_queue_init(&qc->send_ctx[i].sent); |
8339
aba84d9ab256
Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8338
diff
changeset
|
595 qc->send_ctx[i].largest_pn = (uint64_t) -1; |
8333
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
596 } |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
597 |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
598 for (i = 0; i < NGX_QUIC_ENCRYPTION_LAST; i++) { |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
599 ngx_queue_init(&qc->crypto[i].frames); |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
600 } |
8308
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
601 |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
602 ngx_queue_init(&qc->free_frames); |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
603 |
8369
bddf704d62c1
Renamed retransmit event object in preparation for retry support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8368
diff
changeset
|
604 qc->retransmit.log = c->log; |
bddf704d62c1
Renamed retransmit event object in preparation for retry support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8368
diff
changeset
|
605 qc->retransmit.data = c; |
bddf704d62c1
Renamed retransmit event object in preparation for retry support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8368
diff
changeset
|
606 qc->retransmit.handler = ngx_quic_retransmit_handler; |
bddf704d62c1
Renamed retransmit event object in preparation for retry support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8368
diff
changeset
|
607 qc->retransmit.cancelable = 1; |
8308
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
608 |
8309 | 609 qc->push.log = c->log; |
610 qc->push.data = c; | |
611 qc->push.handler = ngx_quic_push_handler; | |
612 qc->push.cancelable = 1; | |
613 | |
8225 | 614 c->quic = qc; |
8397
1245e274b9ba
Avoided excessive definitions for connection state.
Vladimir Homutov <vl@nginx.com>
parents:
8394
diff
changeset
|
615 qc->state = ssl_encryption_initial; |
8225 | 616 qc->ssl = ssl; |
8247
e9891e8ee975
Configurable transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8246
diff
changeset
|
617 qc->tp = *tp; |
8304
90f94413177e
TLS Early Data support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8303
diff
changeset
|
618 qc->streams.handler = handler; |
8225 | 619 |
8265
d45325e90221
Limit output QUIC packets with client max_packet_size.
Roman Arutyunyan <arut@nginx.com>
parents:
8263
diff
changeset
|
620 ctp = &qc->ctp; |
d45325e90221
Limit output QUIC packets with client max_packet_size.
Roman Arutyunyan <arut@nginx.com>
parents:
8263
diff
changeset
|
621 ctp->max_packet_size = NGX_QUIC_DEFAULT_MAX_PACKET_SIZE; |
d45325e90221
Limit output QUIC packets with client max_packet_size.
Roman Arutyunyan <arut@nginx.com>
parents:
8263
diff
changeset
|
622 ctp->ack_delay_exponent = NGX_QUIC_DEFAULT_ACK_DELAY_EXPONENT; |
d45325e90221
Limit output QUIC packets with client max_packet_size.
Roman Arutyunyan <arut@nginx.com>
parents:
8263
diff
changeset
|
623 ctp->max_ack_delay = NGX_QUIC_DEFAULT_MAX_ACK_DELAY; |
d45325e90221
Limit output QUIC packets with client max_packet_size.
Roman Arutyunyan <arut@nginx.com>
parents:
8263
diff
changeset
|
624 |
8365
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
625 qc->streams.recv_max_data = qc->tp.initial_max_data; |
8338
0f9e9786b90d
Added primitive flow control mechanisms.
Vladimir Homutov <vl@nginx.com>
parents:
8337
diff
changeset
|
626 |
8364
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
627 qc->congestion.window = ngx_min(10 * qc->tp.max_packet_size, |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
628 ngx_max(2 * qc->tp.max_packet_size, 14720)); |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
629 qc->congestion.ssthresh = NGX_MAX_SIZE_T_VALUE; |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
630 qc->congestion.recovery_start = ngx_current_msec; |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
631 |
8382
b7704303a7e5
Server CID change refactored.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8381
diff
changeset
|
632 if (ngx_quic_new_dcid(c, &pkt->dcid) != NGX_OK) { |
8225 | 633 return NGX_ERROR; |
634 } | |
8368 | 635 |
8225 | 636 qc->scid.len = pkt->scid.len; |
637 qc->scid.data = ngx_pnalloc(c->pool, qc->scid.len); | |
638 if (qc->scid.data == NULL) { | |
639 return NGX_ERROR; | |
640 } | |
641 ngx_memcpy(qc->scid.data, pkt->scid.data, qc->scid.len); | |
8199
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
642 |
8306
058a5af7ddfc
Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents:
8305
diff
changeset
|
643 keys = &c->quic->keys[ssl_encryption_initial]; |
8225 | 644 |
8306
058a5af7ddfc
Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents:
8305
diff
changeset
|
645 if (ngx_quic_set_initial_secret(c->pool, &keys->client, &keys->server, |
8381
6e100d8c138a
Preserve original DCID and unbreak parsing 0-RTT packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8380
diff
changeset
|
646 &qc->odcid) |
8225 | 647 != NGX_OK) |
648 { | |
649 return NGX_ERROR; | |
650 } | |
8199
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
651 |
8397
1245e274b9ba
Avoided excessive definitions for connection state.
Vladimir Homutov <vl@nginx.com>
parents:
8394
diff
changeset
|
652 qc->initialized = 1; |
8385
fb7422074258
Added generation of CC frames with error on connection termination.
Vladimir Homutov <vl@nginx.com>
parents:
8384
diff
changeset
|
653 |
8384
52d0c4832570
Address validation using NEW_TOKEN frame.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8383
diff
changeset
|
654 if (pkt->token.len) { |
52d0c4832570
Address validation using NEW_TOKEN frame.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8383
diff
changeset
|
655 rc = ngx_quic_validate_token(c, pkt); |
52d0c4832570
Address validation using NEW_TOKEN frame.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8383
diff
changeset
|
656 |
52d0c4832570
Address validation using NEW_TOKEN frame.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8383
diff
changeset
|
657 if (rc == NGX_ERROR) { |
52d0c4832570
Address validation using NEW_TOKEN frame.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8383
diff
changeset
|
658 ngx_log_error(NGX_LOG_INFO, c->log, 0, "quic invalid token"); |
52d0c4832570
Address validation using NEW_TOKEN frame.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8383
diff
changeset
|
659 return NGX_ERROR; |
52d0c4832570
Address validation using NEW_TOKEN frame.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8383
diff
changeset
|
660 } |
52d0c4832570
Address validation using NEW_TOKEN frame.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8383
diff
changeset
|
661 |
52d0c4832570
Address validation using NEW_TOKEN frame.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8383
diff
changeset
|
662 if (rc == NGX_DECLINED) { |
52d0c4832570
Address validation using NEW_TOKEN frame.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8383
diff
changeset
|
663 ngx_log_error(NGX_LOG_INFO, c->log, 0, "quic expired token"); |
52d0c4832570
Address validation using NEW_TOKEN frame.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8383
diff
changeset
|
664 return ngx_quic_retry(c); |
52d0c4832570
Address validation using NEW_TOKEN frame.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8383
diff
changeset
|
665 } |
52d0c4832570
Address validation using NEW_TOKEN frame.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8383
diff
changeset
|
666 |
52d0c4832570
Address validation using NEW_TOKEN frame.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8383
diff
changeset
|
667 /* NGX_OK */ |
52d0c4832570
Address validation using NEW_TOKEN frame.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8383
diff
changeset
|
668 |
52d0c4832570
Address validation using NEW_TOKEN frame.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8383
diff
changeset
|
669 } else if (tp->retry) { |
8383
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
670 return ngx_quic_retry(c); |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
671 } |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
672 |
8306
058a5af7ddfc
Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents:
8305
diff
changeset
|
673 pkt->secret = &keys->client; |
8225 | 674 pkt->level = ssl_encryption_initial; |
8288
ebd5c71b9f02
Got rid of memory allocation in decryption.
Vladimir Homutov <vl@nginx.com>
parents:
8286
diff
changeset
|
675 pkt->plaintext = buf; |
8225 | 676 |
8339
aba84d9ab256
Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8338
diff
changeset
|
677 ctx = ngx_quic_get_send_ctx(qc, pkt->level); |
aba84d9ab256
Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8338
diff
changeset
|
678 |
aba84d9ab256
Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8338
diff
changeset
|
679 if (ngx_quic_decrypt(pkt, NULL, &ctx->largest_pn) != NGX_OK) { |
8386
81f85c479d7e
Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents:
8385
diff
changeset
|
680 qc->error = pkt->error; |
8225 | 681 return NGX_ERROR; |
682 } | |
683 | |
684 if (ngx_quic_init_connection(c) != NGX_OK) { | |
685 return NGX_ERROR; | |
686 } | |
687 | |
8304
90f94413177e
TLS Early Data support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8303
diff
changeset
|
688 if (ngx_quic_payload_handler(c, pkt) != NGX_OK) { |
90f94413177e
TLS Early Data support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8303
diff
changeset
|
689 return NGX_ERROR; |
90f94413177e
TLS Early Data support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8303
diff
changeset
|
690 } |
90f94413177e
TLS Early Data support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8303
diff
changeset
|
691 |
90f94413177e
TLS Early Data support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8303
diff
changeset
|
692 /* pos is at header end, adjust by actual packet length */ |
90f94413177e
TLS Early Data support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8303
diff
changeset
|
693 pkt->raw->pos += pkt->len; |
90f94413177e
TLS Early Data support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8303
diff
changeset
|
694 |
8377
2a94aaa70b33
Cleaned up firefox workaround.
Vladimir Homutov <vl@nginx.com>
parents:
8371
diff
changeset
|
695 (void) ngx_quic_skip_zero_padding(pkt->raw); |
2a94aaa70b33
Cleaned up firefox workaround.
Vladimir Homutov <vl@nginx.com>
parents:
8371
diff
changeset
|
696 |
8304
90f94413177e
TLS Early Data support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8303
diff
changeset
|
697 return ngx_quic_input(c, pkt->raw); |
8199
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
698 } |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
699 |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
700 |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
701 static ngx_int_t |
8382
b7704303a7e5
Server CID change refactored.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8381
diff
changeset
|
702 ngx_quic_new_dcid(ngx_connection_t *c, ngx_str_t *odcid) |
8368 | 703 { |
8382
b7704303a7e5
Server CID change refactored.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8381
diff
changeset
|
704 uint8_t len; |
b7704303a7e5
Server CID change refactored.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8381
diff
changeset
|
705 ngx_quic_connection_t *qc; |
b7704303a7e5
Server CID change refactored.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8381
diff
changeset
|
706 |
b7704303a7e5
Server CID change refactored.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8381
diff
changeset
|
707 qc = c->quic; |
8368 | 708 |
709 if (RAND_bytes(&len, sizeof(len)) != 1) { | |
710 return NGX_ERROR; | |
711 } | |
712 | |
713 len = len % 10 + 10; | |
714 | |
8382
b7704303a7e5
Server CID change refactored.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8381
diff
changeset
|
715 qc->dcid.len = len; |
b7704303a7e5
Server CID change refactored.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8381
diff
changeset
|
716 qc->dcid.data = ngx_pnalloc(c->pool, len); |
b7704303a7e5
Server CID change refactored.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8381
diff
changeset
|
717 if (qc->dcid.data == NULL) { |
b7704303a7e5
Server CID change refactored.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8381
diff
changeset
|
718 return NGX_ERROR; |
b7704303a7e5
Server CID change refactored.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8381
diff
changeset
|
719 } |
b7704303a7e5
Server CID change refactored.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8381
diff
changeset
|
720 |
b7704303a7e5
Server CID change refactored.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8381
diff
changeset
|
721 if (RAND_bytes(qc->dcid.data, len) != 1) { |
8368 | 722 return NGX_ERROR; |
723 } | |
724 | |
8382
b7704303a7e5
Server CID change refactored.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8381
diff
changeset
|
725 #ifdef NGX_QUIC_DEBUG_PACKETS |
b7704303a7e5
Server CID change refactored.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8381
diff
changeset
|
726 ngx_quic_hexdump(c->log, "quic server CID", qc->dcid.data, qc->dcid.len); |
b7704303a7e5
Server CID change refactored.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8381
diff
changeset
|
727 #endif |
b7704303a7e5
Server CID change refactored.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8381
diff
changeset
|
728 |
b7704303a7e5
Server CID change refactored.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8381
diff
changeset
|
729 qc->odcid.len = odcid->len; |
b7704303a7e5
Server CID change refactored.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8381
diff
changeset
|
730 qc->odcid.data = ngx_pstrdup(c->pool, odcid); |
b7704303a7e5
Server CID change refactored.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8381
diff
changeset
|
731 if (qc->odcid.data == NULL) { |
8368 | 732 return NGX_ERROR; |
733 } | |
734 | |
735 return NGX_OK; | |
736 } | |
737 | |
738 | |
739 static ngx_int_t | |
8383
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
740 ngx_quic_retry(ngx_connection_t *c) |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
741 { |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
742 ssize_t len; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
743 ngx_str_t res, token; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
744 ngx_quic_header_t pkt; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
745 u_char buf[NGX_QUIC_RETRY_BUFFER_SIZE]; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
746 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
747 if (ngx_quic_new_token(c, &token) != NGX_OK) { |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
748 return NGX_ERROR; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
749 } |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
750 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
751 ngx_memzero(&pkt, sizeof(ngx_quic_header_t)); |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
752 pkt.flags = NGX_QUIC_PKT_FIXED_BIT | NGX_QUIC_PKT_LONG | NGX_QUIC_PKT_RETRY; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
753 pkt.log = c->log; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
754 pkt.odcid = c->quic->odcid; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
755 pkt.dcid = c->quic->scid; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
756 pkt.scid = c->quic->dcid; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
757 pkt.token = token; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
758 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
759 res.data = buf; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
760 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
761 if (ngx_quic_encrypt(&pkt, NULL, &res) != NGX_OK) { |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
762 return NGX_ERROR; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
763 } |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
764 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
765 #ifdef NGX_QUIC_DEBUG_PACKETS |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
766 ngx_quic_hexdump(c->log, "quic packet to send", res.data, res.len); |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
767 #endif |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
768 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
769 len = c->send(c, res.data, res.len); |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
770 if (len == NGX_ERROR || (size_t) len != res.len) { |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
771 return NGX_ERROR; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
772 } |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
773 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
774 c->quic->token = token; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
775 c->quic->tp.original_connection_id = c->quic->odcid; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
776 c->quic->in_retry = 1; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
777 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
778 return NGX_OK; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
779 } |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
780 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
781 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
782 static ngx_int_t |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
783 ngx_quic_new_token(ngx_connection_t *c, ngx_str_t *token) |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
784 { |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
785 int len, iv_len; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
786 u_char *data, *p, *key, *iv; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
787 ngx_msec_t now; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
788 EVP_CIPHER_CTX *ctx; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
789 const EVP_CIPHER *cipher; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
790 struct sockaddr_in *sin; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
791 #if (NGX_HAVE_INET6) |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
792 struct sockaddr_in6 *sin6; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
793 #endif |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
794 u_char in[NGX_QUIC_MAX_TOKEN_SIZE]; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
795 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
796 switch (c->sockaddr->sa_family) { |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
797 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
798 #if (NGX_HAVE_INET6) |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
799 case AF_INET6: |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
800 sin6 = (struct sockaddr_in6 *) c->sockaddr; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
801 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
802 len = sizeof(struct in6_addr); |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
803 data = sin6->sin6_addr.s6_addr; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
804 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
805 break; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
806 #endif |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
807 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
808 #if (NGX_HAVE_UNIX_DOMAIN) |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
809 case AF_UNIX: |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
810 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
811 len = ngx_min(c->addr_text.len, NGX_QUIC_MAX_TOKEN_SIZE - sizeof(now)); |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
812 data = c->addr_text.data; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
813 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
814 break; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
815 #endif |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
816 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
817 default: /* AF_INET */ |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
818 sin = (struct sockaddr_in *) c->sockaddr; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
819 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
820 len = sizeof(in_addr_t); |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
821 data = (u_char *) &sin->sin_addr; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
822 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
823 break; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
824 } |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
825 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
826 p = ngx_cpymem(in, data, len); |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
827 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
828 now = ngx_current_msec; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
829 len += sizeof(now); |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
830 ngx_memcpy(p, &now, sizeof(now)); |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
831 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
832 cipher = EVP_aes_256_cbc(); |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
833 iv_len = EVP_CIPHER_iv_length(cipher); |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
834 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
835 token->len = iv_len + len + EVP_CIPHER_block_size(cipher); |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
836 token->data = ngx_pnalloc(c->pool, token->len); |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
837 if (token->data == NULL) { |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
838 return NGX_ERROR; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
839 } |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
840 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
841 ctx = EVP_CIPHER_CTX_new(); |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
842 if (ctx == NULL) { |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
843 return NGX_ERROR; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
844 } |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
845 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
846 key = c->quic->tp.token_key; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
847 iv = token->data; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
848 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
849 if (RAND_bytes(iv, iv_len) <= 0 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
850 || !EVP_EncryptInit_ex(ctx, cipher, NULL, key, iv)) |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
851 { |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
852 EVP_CIPHER_CTX_free(ctx); |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
853 return NGX_ERROR; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
854 } |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
855 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
856 token->len = iv_len; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
857 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
858 if (EVP_EncryptUpdate(ctx, token->data + token->len, &len, in, len) != 1) { |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
859 EVP_CIPHER_CTX_free(ctx); |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
860 return NGX_ERROR; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
861 } |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
862 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
863 token->len += len; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
864 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
865 if (EVP_EncryptFinal_ex(ctx, token->data + token->len, &len) <= 0) { |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
866 EVP_CIPHER_CTX_free(ctx); |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
867 return NGX_ERROR; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
868 } |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
869 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
870 token->len += len; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
871 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
872 EVP_CIPHER_CTX_free(ctx); |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
873 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
874 #ifdef NGX_QUIC_DEBUG_PACKETS |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
875 ngx_quic_hexdump(c->log, "quic new token", token->data, token->len); |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
876 #endif |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
877 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
878 return NGX_OK; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
879 } |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
880 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
881 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
882 static ngx_int_t |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
883 ngx_quic_validate_token(ngx_connection_t *c, ngx_quic_header_t *pkt) |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
884 { |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
885 int len, tlen, iv_len; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
886 u_char *key, *iv, *p, *data; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
887 ngx_msec_t msec; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
888 EVP_CIPHER_CTX *ctx; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
889 const EVP_CIPHER *cipher; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
890 struct sockaddr_in *sin; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
891 #if (NGX_HAVE_INET6) |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
892 struct sockaddr_in6 *sin6; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
893 #endif |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
894 ngx_quic_connection_t *qc; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
895 u_char tdec[NGX_QUIC_MAX_TOKEN_SIZE]; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
896 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
897 if (pkt->token.len == 0) { |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
898 return NGX_ERROR; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
899 } |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
900 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
901 qc = c->quic; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
902 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
903 /* Retry token */ |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
904 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
905 if (qc->token.len) { |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
906 if (pkt->token.len != qc->token.len) { |
8385
fb7422074258
Added generation of CC frames with error on connection termination.
Vladimir Homutov <vl@nginx.com>
parents:
8384
diff
changeset
|
907 qc->error = NGX_QUIC_ERR_INVALID_TOKEN; |
8383
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
908 return NGX_ERROR; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
909 } |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
910 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
911 if (ngx_memcmp(pkt->token.data, qc->token.data, pkt->token.len) != 0) { |
8385
fb7422074258
Added generation of CC frames with error on connection termination.
Vladimir Homutov <vl@nginx.com>
parents:
8384
diff
changeset
|
912 qc->error = NGX_QUIC_ERR_INVALID_TOKEN; |
8383
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
913 return NGX_ERROR; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
914 } |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
915 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
916 return NGX_OK; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
917 } |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
918 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
919 /* NEW_TOKEN in a previous connection */ |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
920 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
921 cipher = EVP_aes_256_cbc(); |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
922 key = c->quic->tp.token_key; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
923 iv = pkt->token.data; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
924 iv_len = EVP_CIPHER_iv_length(cipher); |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
925 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
926 /* sanity checks */ |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
927 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
928 if (pkt->token.len < (size_t) iv_len + EVP_CIPHER_block_size(cipher)) { |
8385
fb7422074258
Added generation of CC frames with error on connection termination.
Vladimir Homutov <vl@nginx.com>
parents:
8384
diff
changeset
|
929 qc->error = NGX_QUIC_ERR_INVALID_TOKEN; |
8383
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
930 return NGX_ERROR; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
931 } |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
932 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
933 if (pkt->token.len > (size_t) iv_len + NGX_QUIC_MAX_TOKEN_SIZE) { |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
934 return NGX_ERROR; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
935 } |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
936 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
937 ctx = EVP_CIPHER_CTX_new(); |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
938 if (ctx == NULL) { |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
939 return NGX_ERROR; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
940 } |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
941 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
942 if (!EVP_DecryptInit_ex(ctx, cipher, NULL, key, iv)) { |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
943 EVP_CIPHER_CTX_free(ctx); |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
944 return NGX_ERROR; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
945 } |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
946 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
947 p = pkt->token.data + iv_len; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
948 len = pkt->token.len - iv_len; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
949 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
950 if (EVP_DecryptUpdate(ctx, tdec, &len, p, len) != 1) { |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
951 EVP_CIPHER_CTX_free(ctx); |
8385
fb7422074258
Added generation of CC frames with error on connection termination.
Vladimir Homutov <vl@nginx.com>
parents:
8384
diff
changeset
|
952 qc->error = NGX_QUIC_ERR_INVALID_TOKEN; |
8383
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
953 return NGX_ERROR; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
954 } |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
955 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
956 if (EVP_DecryptFinal_ex(ctx, tdec + len, &tlen) <= 0) { |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
957 EVP_CIPHER_CTX_free(ctx); |
8385
fb7422074258
Added generation of CC frames with error on connection termination.
Vladimir Homutov <vl@nginx.com>
parents:
8384
diff
changeset
|
958 qc->error = NGX_QUIC_ERR_INVALID_TOKEN; |
8383
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
959 return NGX_ERROR; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
960 } |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
961 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
962 EVP_CIPHER_CTX_free(ctx); |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
963 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
964 switch (c->sockaddr->sa_family) { |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
965 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
966 #if (NGX_HAVE_INET6) |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
967 case AF_INET6: |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
968 sin6 = (struct sockaddr_in6 *) c->sockaddr; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
969 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
970 len = sizeof(struct in6_addr); |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
971 data = sin6->sin6_addr.s6_addr; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
972 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
973 break; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
974 #endif |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
975 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
976 #if (NGX_HAVE_UNIX_DOMAIN) |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
977 case AF_UNIX: |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
978 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
979 len = ngx_min(c->addr_text.len, NGX_QUIC_MAX_TOKEN_SIZE - sizeof(msec)); |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
980 data = c->addr_text.data; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
981 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
982 break; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
983 #endif |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
984 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
985 default: /* AF_INET */ |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
986 sin = (struct sockaddr_in *) c->sockaddr; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
987 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
988 len = sizeof(in_addr_t); |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
989 data = (u_char *) &sin->sin_addr; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
990 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
991 break; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
992 } |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
993 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
994 if (ngx_memcmp(tdec, data, len) != 0) { |
8385
fb7422074258
Added generation of CC frames with error on connection termination.
Vladimir Homutov <vl@nginx.com>
parents:
8384
diff
changeset
|
995 qc->error = NGX_QUIC_ERR_INVALID_TOKEN; |
8383
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
996 return NGX_ERROR; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
997 } |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
998 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
999 ngx_memcpy(&msec, tdec + len, sizeof(msec)); |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1000 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1001 if (ngx_current_msec - msec > NGX_QUIC_RETRY_LIFETIME) { |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1002 return NGX_DECLINED; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1003 } |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1004 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1005 return NGX_OK; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1006 } |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1007 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1008 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1009 static ngx_int_t |
8221
69345a26ba69
Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
8220
diff
changeset
|
1010 ngx_quic_init_connection(ngx_connection_t *c) |
8199
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
1011 { |
8247
e9891e8ee975
Configurable transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8246
diff
changeset
|
1012 u_char *p; |
e9891e8ee975
Configurable transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8246
diff
changeset
|
1013 ssize_t len; |
8199
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
1014 ngx_ssl_conn_t *ssl_conn; |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
1015 ngx_quic_connection_t *qc; |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
1016 |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
1017 qc = c->quic; |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
1018 |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
1019 if (ngx_ssl_create_connection(qc->ssl, c, NGX_SSL_BUFFER) != NGX_OK) { |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
1020 return NGX_ERROR; |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
1021 } |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
1022 |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
1023 ssl_conn = c->ssl->connection; |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
1024 |
8232
253cf267f95a
Moved setting QUIC methods to runtime.
Roman Arutyunyan <arut@nginx.com>
parents:
8231
diff
changeset
|
1025 if (SSL_set_quic_method(ssl_conn, &quic_method) == 0) { |
253cf267f95a
Moved setting QUIC methods to runtime.
Roman Arutyunyan <arut@nginx.com>
parents:
8231
diff
changeset
|
1026 ngx_log_error(NGX_LOG_INFO, c->log, 0, |
8361 | 1027 "quic SSL_set_quic_method() failed"); |
8232
253cf267f95a
Moved setting QUIC methods to runtime.
Roman Arutyunyan <arut@nginx.com>
parents:
8231
diff
changeset
|
1028 return NGX_ERROR; |
253cf267f95a
Moved setting QUIC methods to runtime.
Roman Arutyunyan <arut@nginx.com>
parents:
8231
diff
changeset
|
1029 } |
253cf267f95a
Moved setting QUIC methods to runtime.
Roman Arutyunyan <arut@nginx.com>
parents:
8231
diff
changeset
|
1030 |
8304
90f94413177e
TLS Early Data support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8303
diff
changeset
|
1031 #ifdef SSL_READ_EARLY_DATA_SUCCESS |
90f94413177e
TLS Early Data support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8303
diff
changeset
|
1032 if (SSL_CTX_get_max_early_data(qc->ssl->ctx)) { |
90f94413177e
TLS Early Data support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8303
diff
changeset
|
1033 SSL_set_quic_early_data_enabled(ssl_conn, 1); |
90f94413177e
TLS Early Data support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8303
diff
changeset
|
1034 } |
90f94413177e
TLS Early Data support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8303
diff
changeset
|
1035 #endif |
90f94413177e
TLS Early Data support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8303
diff
changeset
|
1036 |
8247
e9891e8ee975
Configurable transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8246
diff
changeset
|
1037 len = ngx_quic_create_transport_params(NULL, NULL, &qc->tp); |
e9891e8ee975
Configurable transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8246
diff
changeset
|
1038 /* always succeeds */ |
e9891e8ee975
Configurable transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8246
diff
changeset
|
1039 |
e9891e8ee975
Configurable transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8246
diff
changeset
|
1040 p = ngx_pnalloc(c->pool, len); |
e9891e8ee975
Configurable transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8246
diff
changeset
|
1041 if (p == NULL) { |
e9891e8ee975
Configurable transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8246
diff
changeset
|
1042 return NGX_ERROR; |
e9891e8ee975
Configurable transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8246
diff
changeset
|
1043 } |
e9891e8ee975
Configurable transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8246
diff
changeset
|
1044 |
e9891e8ee975
Configurable transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8246
diff
changeset
|
1045 len = ngx_quic_create_transport_params(p, p + len, &qc->tp); |
e9891e8ee975
Configurable transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8246
diff
changeset
|
1046 if (len < 0) { |
e9891e8ee975
Configurable transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8246
diff
changeset
|
1047 return NGX_ERROR; |
e9891e8ee975
Configurable transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8246
diff
changeset
|
1048 } |
e9891e8ee975
Configurable transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8246
diff
changeset
|
1049 |
8359 | 1050 #ifdef NGX_QUIC_DEBUG_PACKETS |
8360
f175006124d0
Cleaned up hexdumps in debug output.
Vladimir Homutov <vl@nginx.com>
parents:
8359
diff
changeset
|
1051 ngx_quic_hexdump(c->log, "quic transport parameters", p, len); |
8359 | 1052 #endif |
1053 | |
8247
e9891e8ee975
Configurable transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8246
diff
changeset
|
1054 if (SSL_set_quic_transport_params(ssl_conn, p, len) == 0) { |
8199
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
1055 ngx_log_error(NGX_LOG_INFO, c->log, 0, |
8361 | 1056 "quic SSL_set_quic_transport_params() failed"); |
8199
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
1057 return NGX_ERROR; |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
1058 } |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
1059 |
8314
de8981bf2dd5
Advertizing MAX_STREAMS (0x12) credit in advance.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8312
diff
changeset
|
1060 qc->max_streams = qc->tp.initial_max_streams_bidi; |
8397
1245e274b9ba
Avoided excessive definitions for connection state.
Vladimir Homutov <vl@nginx.com>
parents:
8394
diff
changeset
|
1061 qc->state = ssl_encryption_handshake; |
8263
1295b293d09a
Connection states code cleanup.
Vladimir Homutov <vl@nginx.com>
parents:
8260
diff
changeset
|
1062 |
8199
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
1063 return NGX_OK; |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
1064 } |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
1065 |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
1066 |
8225 | 1067 static void |
8263
1295b293d09a
Connection states code cleanup.
Vladimir Homutov <vl@nginx.com>
parents:
8260
diff
changeset
|
1068 ngx_quic_input_handler(ngx_event_t *rev) |
8211
6bc18966b8c1
Stream "connection" read/write methods.
Vladimir Homutov <vl@nginx.com>
parents:
8209
diff
changeset
|
1069 { |
8271
8e54a17dabee
Respect QUIC max_idle_timeout.
Roman Arutyunyan <arut@nginx.com>
parents:
8270
diff
changeset
|
1070 ssize_t n; |
8e54a17dabee
Respect QUIC max_idle_timeout.
Roman Arutyunyan <arut@nginx.com>
parents:
8270
diff
changeset
|
1071 ngx_buf_t b; |
8e54a17dabee
Respect QUIC max_idle_timeout.
Roman Arutyunyan <arut@nginx.com>
parents:
8270
diff
changeset
|
1072 ngx_connection_t *c; |
8e54a17dabee
Respect QUIC max_idle_timeout.
Roman Arutyunyan <arut@nginx.com>
parents:
8270
diff
changeset
|
1073 ngx_quic_connection_t *qc; |
8288
ebd5c71b9f02
Got rid of memory allocation in decryption.
Vladimir Homutov <vl@nginx.com>
parents:
8286
diff
changeset
|
1074 static u_char buf[NGX_QUIC_DEFAULT_MAX_PACKET_SIZE]; |
8211
6bc18966b8c1
Stream "connection" read/write methods.
Vladimir Homutov <vl@nginx.com>
parents:
8209
diff
changeset
|
1075 |
8394 | 1076 ngx_memzero(&b, sizeof(ngx_buf_t)); |
8225 | 1077 b.start = buf; |
8265
d45325e90221
Limit output QUIC packets with client max_packet_size.
Roman Arutyunyan <arut@nginx.com>
parents:
8263
diff
changeset
|
1078 b.end = buf + sizeof(buf); |
8225 | 1079 b.pos = b.last = b.start; |
8383
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1080 b.memory = 1; |
8211
6bc18966b8c1
Stream "connection" read/write methods.
Vladimir Homutov <vl@nginx.com>
parents:
8209
diff
changeset
|
1081 |
8225 | 1082 c = rev->data; |
8281
618a65de08b3
When closing a QUIC connection, wait for all streams to finish.
Roman Arutyunyan <arut@nginx.com>
parents:
8280
diff
changeset
|
1083 qc = c->quic; |
8211
6bc18966b8c1
Stream "connection" read/write methods.
Vladimir Homutov <vl@nginx.com>
parents:
8209
diff
changeset
|
1084 |
8263
1295b293d09a
Connection states code cleanup.
Vladimir Homutov <vl@nginx.com>
parents:
8260
diff
changeset
|
1085 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, rev->log, 0, "quic input handler"); |
8212
e3c0b19a3a8a
Implemented ngx_quic_stream_send_chain() method.
Roman Arutyunyan <arut@nginx.com>
parents:
8211
diff
changeset
|
1086 |
8225 | 1087 if (rev->timedout) { |
8361 | 1088 ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, |
1089 "quic client timed out"); | |
8355
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1090 ngx_quic_close_connection(c, NGX_DONE); |
8225 | 1091 return; |
8212
e3c0b19a3a8a
Implemented ngx_quic_stream_send_chain() method.
Roman Arutyunyan <arut@nginx.com>
parents:
8211
diff
changeset
|
1092 } |
e3c0b19a3a8a
Implemented ngx_quic_stream_send_chain() method.
Roman Arutyunyan <arut@nginx.com>
parents:
8211
diff
changeset
|
1093 |
8225 | 1094 if (c->close) { |
8355
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1095 ngx_quic_close_connection(c, NGX_ERROR); |
8225 | 1096 return; |
1097 } | |
8220
7ada2feeac18
Added processing of CONNECTION CLOSE frames.
Vladimir Homutov <vl@nginx.com>
parents:
8218
diff
changeset
|
1098 |
8225 | 1099 n = c->recv(c, b.start, b.end - b.start); |
8215 | 1100 |
8225 | 1101 if (n == NGX_AGAIN) { |
8355
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1102 if (qc->closing) { |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1103 ngx_quic_close_connection(c, NGX_OK); |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1104 } |
8225 | 1105 return; |
8199
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
1106 } |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
1107 |
8225 | 1108 if (n == NGX_ERROR) { |
1109 c->read->eof = 1; | |
8355
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1110 ngx_quic_close_connection(c, NGX_ERROR); |
8225 | 1111 return; |
8199
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
1112 } |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
1113 |
8225 | 1114 b.last += n; |
8199
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
1115 |
8225 | 1116 if (ngx_quic_input(c, &b) != NGX_OK) { |
8355
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1117 ngx_quic_close_connection(c, NGX_ERROR); |
8225 | 1118 return; |
1119 } | |
8271
8e54a17dabee
Respect QUIC max_idle_timeout.
Roman Arutyunyan <arut@nginx.com>
parents:
8270
diff
changeset
|
1120 |
8e54a17dabee
Respect QUIC max_idle_timeout.
Roman Arutyunyan <arut@nginx.com>
parents:
8270
diff
changeset
|
1121 qc->send_timer_set = 0; |
8e54a17dabee
Respect QUIC max_idle_timeout.
Roman Arutyunyan <arut@nginx.com>
parents:
8270
diff
changeset
|
1122 ngx_add_timer(rev, qc->tp.max_idle_timeout); |
8199
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
1123 } |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
1124 |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
1125 |
8208
4ae9ac69ab93
HTTP/QUIC interface reworked.
Vladimir Homutov <vl@nginx.com>
parents:
8207
diff
changeset
|
1126 static void |
8355
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1127 ngx_quic_close_connection(ngx_connection_t *c, ngx_int_t rc) |
8208
4ae9ac69ab93
HTTP/QUIC interface reworked.
Vladimir Homutov <vl@nginx.com>
parents:
8207
diff
changeset
|
1128 { |
8354
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1129 ngx_pool_t *pool; |
8281
618a65de08b3
When closing a QUIC connection, wait for all streams to finish.
Roman Arutyunyan <arut@nginx.com>
parents:
8280
diff
changeset
|
1130 |
8355
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1131 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, |
8359 | 1132 "quic ngx_quic_close_connection, rc: %i", rc); |
8355
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1133 |
8397
1245e274b9ba
Avoided excessive definitions for connection state.
Vladimir Homutov <vl@nginx.com>
parents:
8394
diff
changeset
|
1134 if (!c->quic || !c->quic->initialized) { |
8355
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1135 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, |
8359 | 1136 "quic close connection early error"); |
8355
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1137 |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1138 } else if (ngx_quic_close_quic(c, rc) == NGX_AGAIN) { |
8354
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1139 return; |
8281
618a65de08b3
When closing a QUIC connection, wait for all streams to finish.
Roman Arutyunyan <arut@nginx.com>
parents:
8280
diff
changeset
|
1140 } |
8208
4ae9ac69ab93
HTTP/QUIC interface reworked.
Vladimir Homutov <vl@nginx.com>
parents:
8207
diff
changeset
|
1141 |
8225 | 1142 if (c->ssl) { |
1143 (void) ngx_ssl_shutdown(c); | |
8208
4ae9ac69ab93
HTTP/QUIC interface reworked.
Vladimir Homutov <vl@nginx.com>
parents:
8207
diff
changeset
|
1144 } |
4ae9ac69ab93
HTTP/QUIC interface reworked.
Vladimir Homutov <vl@nginx.com>
parents:
8207
diff
changeset
|
1145 |
8354
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1146 if (c->read->timer_set) { |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1147 ngx_del_timer(c->read); |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1148 } |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1149 |
8225 | 1150 #if (NGX_STAT_STUB) |
1151 (void) ngx_atomic_fetch_add(ngx_stat_active, -1); | |
1152 #endif | |
8208
4ae9ac69ab93
HTTP/QUIC interface reworked.
Vladimir Homutov <vl@nginx.com>
parents:
8207
diff
changeset
|
1153 |
8225 | 1154 c->destroyed = 1; |
8208
4ae9ac69ab93
HTTP/QUIC interface reworked.
Vladimir Homutov <vl@nginx.com>
parents:
8207
diff
changeset
|
1155 |
8225 | 1156 pool = c->pool; |
8208
4ae9ac69ab93
HTTP/QUIC interface reworked.
Vladimir Homutov <vl@nginx.com>
parents:
8207
diff
changeset
|
1157 |
8225 | 1158 ngx_close_connection(c); |
8208
4ae9ac69ab93
HTTP/QUIC interface reworked.
Vladimir Homutov <vl@nginx.com>
parents:
8207
diff
changeset
|
1159 |
8225 | 1160 ngx_destroy_pool(pool); |
8208
4ae9ac69ab93
HTTP/QUIC interface reworked.
Vladimir Homutov <vl@nginx.com>
parents:
8207
diff
changeset
|
1161 } |
4ae9ac69ab93
HTTP/QUIC interface reworked.
Vladimir Homutov <vl@nginx.com>
parents:
8207
diff
changeset
|
1162 |
4ae9ac69ab93
HTTP/QUIC interface reworked.
Vladimir Homutov <vl@nginx.com>
parents:
8207
diff
changeset
|
1163 |
8193
4355efde26d8
Added functions to decrypt long packets.
Vladimir Homutov <vl@nginx.com>
parents:
8192
diff
changeset
|
1164 static ngx_int_t |
8355
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1165 ngx_quic_close_quic(ngx_connection_t *c, ngx_int_t rc) |
8354
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1166 { |
8385
fb7422074258
Added generation of CC frames with error on connection termination.
Vladimir Homutov <vl@nginx.com>
parents:
8384
diff
changeset
|
1167 ngx_uint_t i, err; |
8398
8bec0ac23cf9
Fixed retransmission of frames after closing connection.
Vladimir Homutov <vl@nginx.com>
parents:
8397
diff
changeset
|
1168 ngx_quic_send_ctx_t *ctx; |
8355
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1169 ngx_quic_connection_t *qc; |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1170 enum ssl_encryption_level_t level; |
8354
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1171 |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1172 qc = c->quic; |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1173 |
8355
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1174 if (!qc->closing) { |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1175 |
8398
8bec0ac23cf9
Fixed retransmission of frames after closing connection.
Vladimir Homutov <vl@nginx.com>
parents:
8397
diff
changeset
|
1176 /* drop packets from retransmit queues, no ack is expected */ |
8bec0ac23cf9
Fixed retransmission of frames after closing connection.
Vladimir Homutov <vl@nginx.com>
parents:
8397
diff
changeset
|
1177 for (i = 0; i < NGX_QUIC_SEND_CTX_LAST; i++) { |
8bec0ac23cf9
Fixed retransmission of frames after closing connection.
Vladimir Homutov <vl@nginx.com>
parents:
8397
diff
changeset
|
1178 ctx = ngx_quic_get_send_ctx(qc, i); |
8bec0ac23cf9
Fixed retransmission of frames after closing connection.
Vladimir Homutov <vl@nginx.com>
parents:
8397
diff
changeset
|
1179 ngx_quic_free_frames(c, &ctx->sent); |
8bec0ac23cf9
Fixed retransmission of frames after closing connection.
Vladimir Homutov <vl@nginx.com>
parents:
8397
diff
changeset
|
1180 } |
8bec0ac23cf9
Fixed retransmission of frames after closing connection.
Vladimir Homutov <vl@nginx.com>
parents:
8397
diff
changeset
|
1181 |
8397
1245e274b9ba
Avoided excessive definitions for connection state.
Vladimir Homutov <vl@nginx.com>
parents:
8394
diff
changeset
|
1182 level = (qc->state == ssl_encryption_early_data) |
1245e274b9ba
Avoided excessive definitions for connection state.
Vladimir Homutov <vl@nginx.com>
parents:
8394
diff
changeset
|
1183 ? ssl_encryption_application |
1245e274b9ba
Avoided excessive definitions for connection state.
Vladimir Homutov <vl@nginx.com>
parents:
8394
diff
changeset
|
1184 : qc->state; |
8385
fb7422074258
Added generation of CC frames with error on connection termination.
Vladimir Homutov <vl@nginx.com>
parents:
8384
diff
changeset
|
1185 |
8355
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1186 if (rc == NGX_OK) { |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1187 |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1188 /* |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1189 * 10.3. Immediate Close |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1190 * |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1191 * An endpoint sends a CONNECTION_CLOSE frame (Section 19.19) to |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1192 * terminate the connection immediately. |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1193 */ |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1194 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1195 "quic immediate close, drain = %d", qc->draining); |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1196 |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1197 if (ngx_quic_send_cc(c, level, NGX_QUIC_ERR_NO_ERROR) == NGX_OK) { |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1198 |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1199 qc->close.log = c->log; |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1200 qc->close.data = c; |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1201 qc->close.handler = ngx_quic_close_timer_handler; |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1202 qc->close.cancelable = 1; |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1203 |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1204 ngx_add_timer(&qc->close, 3 * NGX_QUIC_HARDCODED_PTO); |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1205 } |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1206 |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1207 } else if (rc == NGX_DONE) { |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1208 |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1209 /* |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1210 * 10.2. Idle Timeout |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1211 * |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1212 * If the idle timeout is enabled by either peer, a connection is |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1213 * silently closed and its state is discarded when it remains idle |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1214 */ |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1215 |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1216 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1217 "quic closing %s connection", |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1218 qc->draining ? "drained" : "idle"); |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1219 |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1220 } else { |
8385
fb7422074258
Added generation of CC frames with error on connection termination.
Vladimir Homutov <vl@nginx.com>
parents:
8384
diff
changeset
|
1221 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, |
fb7422074258
Added generation of CC frames with error on connection termination.
Vladimir Homutov <vl@nginx.com>
parents:
8384
diff
changeset
|
1222 "quic immediate close due to fatal error: %ui", |
fb7422074258
Added generation of CC frames with error on connection termination.
Vladimir Homutov <vl@nginx.com>
parents:
8384
diff
changeset
|
1223 qc->error); |
fb7422074258
Added generation of CC frames with error on connection termination.
Vladimir Homutov <vl@nginx.com>
parents:
8384
diff
changeset
|
1224 |
fb7422074258
Added generation of CC frames with error on connection termination.
Vladimir Homutov <vl@nginx.com>
parents:
8384
diff
changeset
|
1225 err = qc->error ? qc->error : NGX_QUIC_ERR_INTERNAL_ERROR; |
fb7422074258
Added generation of CC frames with error on connection termination.
Vladimir Homutov <vl@nginx.com>
parents:
8384
diff
changeset
|
1226 (void) ngx_quic_send_cc(c, level, err); |
8355
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1227 } |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1228 |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1229 qc->closing = 1; |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1230 } |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1231 |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1232 if (rc == NGX_ERROR && qc->close.timer_set) { |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1233 /* do not wait for timer in case of fatal error */ |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1234 ngx_del_timer(&qc->close); |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1235 } |
8354
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1236 |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1237 if (ngx_quic_close_streams(c, qc) == NGX_AGAIN) { |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1238 return NGX_AGAIN; |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1239 } |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1240 |
8355
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1241 if (qc->close.timer_set) { |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1242 return NGX_AGAIN; |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1243 } |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1244 |
8354
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1245 for (i = 0; i < NGX_QUIC_ENCRYPTION_LAST; i++) { |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1246 ngx_quic_free_frames(c, &qc->crypto[i].frames); |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1247 } |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1248 |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1249 for (i = 0; i < NGX_QUIC_SEND_CTX_LAST; i++) { |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1250 ngx_quic_free_frames(c, &qc->send_ctx[i].frames); |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1251 ngx_quic_free_frames(c, &qc->send_ctx[i].sent); |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1252 } |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1253 |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1254 if (qc->push.timer_set) { |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1255 ngx_del_timer(&qc->push); |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1256 } |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1257 |
8369
bddf704d62c1
Renamed retransmit event object in preparation for retry support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8368
diff
changeset
|
1258 if (qc->retransmit.timer_set) { |
bddf704d62c1
Renamed retransmit event object in preparation for retry support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8368
diff
changeset
|
1259 ngx_del_timer(&qc->retransmit); |
8354
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1260 } |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1261 |
8355
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1262 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1263 "quic part of connection is terminated"); |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1264 |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1265 /* may be tested from SSL callback during SSL shutdown */ |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1266 c->quic = NULL; |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1267 |
8354
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1268 return NGX_OK; |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1269 } |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1270 |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1271 |
8355
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1272 static void |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1273 ngx_quic_close_timer_handler(ngx_event_t *ev) |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1274 { |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1275 ngx_connection_t *c; |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1276 |
8359 | 1277 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ev->log, 0, "quic close timer"); |
8355
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1278 |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1279 c = ev->data; |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1280 ngx_quic_close_connection(c, NGX_DONE); |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1281 } |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1282 |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1283 |
8354
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1284 static ngx_int_t |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1285 ngx_quic_close_streams(ngx_connection_t *c, ngx_quic_connection_t *qc) |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1286 { |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1287 ngx_event_t *rev; |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1288 ngx_rbtree_t *tree; |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1289 ngx_rbtree_node_t *node; |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1290 ngx_quic_stream_t *qs; |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1291 |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1292 #if (NGX_DEBUG) |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1293 ngx_uint_t ns; |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1294 #endif |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1295 |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1296 tree = &qc->streams.tree; |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1297 |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1298 if (tree->root == tree->sentinel) { |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1299 return NGX_OK; |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1300 } |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1301 |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1302 #if (NGX_DEBUG) |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1303 ns = 0; |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1304 #endif |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1305 |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1306 for (node = ngx_rbtree_min(tree->root, tree->sentinel); |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1307 node; |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1308 node = ngx_rbtree_next(tree, node)) |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1309 { |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1310 qs = (ngx_quic_stream_t *) node; |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1311 |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1312 rev = qs->c->read; |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1313 rev->ready = 1; |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1314 rev->pending_eof = 1; |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1315 |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1316 ngx_post_event(rev, &ngx_posted_events); |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1317 |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1318 if (rev->timer_set) { |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1319 ngx_del_timer(rev); |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1320 } |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1321 |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1322 #if (NGX_DEBUG) |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1323 ns++; |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1324 #endif |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1325 } |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1326 |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1327 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1328 "quic connection has %ui active streams", ns); |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1329 |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1330 return NGX_AGAIN; |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1331 } |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1332 |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1333 |
d11bc25fc4c3
Refactored ngx_quic_close_connection().
Vladimir Homutov <vl@nginx.com>
parents:
8350
diff
changeset
|
1334 static ngx_int_t |
8225 | 1335 ngx_quic_input(ngx_connection_t *c, ngx_buf_t *b) |
8193
4355efde26d8
Added functions to decrypt long packets.
Vladimir Homutov <vl@nginx.com>
parents:
8192
diff
changeset
|
1336 { |
8225 | 1337 u_char *p; |
1338 ngx_int_t rc; | |
1339 ngx_quic_header_t pkt; | |
8193
4355efde26d8
Added functions to decrypt long packets.
Vladimir Homutov <vl@nginx.com>
parents:
8192
diff
changeset
|
1340 |
8304
90f94413177e
TLS Early Data support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8303
diff
changeset
|
1341 p = b->pos; |
8208
4ae9ac69ab93
HTTP/QUIC interface reworked.
Vladimir Homutov <vl@nginx.com>
parents:
8207
diff
changeset
|
1342 |
8304
90f94413177e
TLS Early Data support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8303
diff
changeset
|
1343 while (p < b->last) { |
8263
1295b293d09a
Connection states code cleanup.
Vladimir Homutov <vl@nginx.com>
parents:
8260
diff
changeset
|
1344 c->log->action = "processing quic packet"; |
1295b293d09a
Connection states code cleanup.
Vladimir Homutov <vl@nginx.com>
parents:
8260
diff
changeset
|
1345 |
8225 | 1346 ngx_memzero(&pkt, sizeof(ngx_quic_header_t)); |
1347 pkt.raw = b; | |
1348 pkt.data = p; | |
1349 pkt.len = b->last - p; | |
1350 pkt.log = c->log; | |
8251
c217a907ce42
Added checks for permitted frame types.
Vladimir Homutov <vl@nginx.com>
parents:
8247
diff
changeset
|
1351 pkt.flags = p[0]; |
8193
4355efde26d8
Added functions to decrypt long packets.
Vladimir Homutov <vl@nginx.com>
parents:
8192
diff
changeset
|
1352 |
8383
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1353 if (c->quic->in_retry) { |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1354 return ngx_quic_retry_input(c, &pkt); |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1355 } |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1356 |
8371
9d9531431c8c
Removed outdated/incorrect comments and fixed style.
Vladimir Homutov <vl@nginx.com>
parents:
8370
diff
changeset
|
1357 /* TODO: check current state */ |
8251
c217a907ce42
Added checks for permitted frame types.
Vladimir Homutov <vl@nginx.com>
parents:
8247
diff
changeset
|
1358 if (ngx_quic_long_pkt(pkt.flags)) { |
8225 | 1359 |
8251
c217a907ce42
Added checks for permitted frame types.
Vladimir Homutov <vl@nginx.com>
parents:
8247
diff
changeset
|
1360 if (ngx_quic_pkt_in(pkt.flags)) { |
8225 | 1361 rc = ngx_quic_initial_input(c, &pkt); |
8206
8d6ac639feac
Added support of multiple QUIC packets in single datagram.
Vladimir Homutov <vl@nginx.com>
parents:
8205
diff
changeset
|
1362 |
8251
c217a907ce42
Added checks for permitted frame types.
Vladimir Homutov <vl@nginx.com>
parents:
8247
diff
changeset
|
1363 } else if (ngx_quic_pkt_hs(pkt.flags)) { |
8225 | 1364 rc = ngx_quic_handshake_input(c, &pkt); |
8193
4355efde26d8
Added functions to decrypt long packets.
Vladimir Homutov <vl@nginx.com>
parents:
8192
diff
changeset
|
1365 |
8304
90f94413177e
TLS Early Data support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8303
diff
changeset
|
1366 } else if (ngx_quic_pkt_zrtt(pkt.flags)) { |
90f94413177e
TLS Early Data support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8303
diff
changeset
|
1367 rc = ngx_quic_early_input(c, &pkt); |
90f94413177e
TLS Early Data support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8303
diff
changeset
|
1368 |
8225 | 1369 } else { |
1370 ngx_log_error(NGX_LOG_INFO, c->log, 0, | |
8361 | 1371 "quic unknown long packet type"); |
8225 | 1372 return NGX_ERROR; |
1373 } | |
8193
4355efde26d8
Added functions to decrypt long packets.
Vladimir Homutov <vl@nginx.com>
parents:
8192
diff
changeset
|
1374 |
8225 | 1375 } else { |
1376 rc = ngx_quic_app_input(c, &pkt); | |
1377 } | |
8193
4355efde26d8
Added functions to decrypt long packets.
Vladimir Homutov <vl@nginx.com>
parents:
8192
diff
changeset
|
1378 |
8333
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
1379 if (rc == NGX_ERROR) { |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
1380 return NGX_ERROR; |
8225 | 1381 } |
8206
8d6ac639feac
Added support of multiple QUIC packets in single datagram.
Vladimir Homutov <vl@nginx.com>
parents:
8205
diff
changeset
|
1382 |
8333
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
1383 /* NGX_OK || NGX_DECLINED */ |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
1384 |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
1385 /* |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
1386 * we get NGX_DECLINED when there are no keys [yet] available |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
1387 * to decrypt packet. |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
1388 * Instead of queueing it, we ignore it and rely on the sender's |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
1389 * retransmission: |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
1390 * |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
1391 * 12.2. Coalescing Packets: |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
1392 * |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
1393 * For example, if decryption fails (because the keys are |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
1394 * not available or any other reason), the receiver MAY either |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
1395 * discard or buffer the packet for later processing and MUST |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
1396 * attempt to process the remaining packets. |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
1397 */ |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
1398 |
8225 | 1399 /* b->pos is at header end, adjust by actual packet length */ |
8377
2a94aaa70b33
Cleaned up firefox workaround.
Vladimir Homutov <vl@nginx.com>
parents:
8371
diff
changeset
|
1400 b->pos += pkt.len; |
2a94aaa70b33
Cleaned up firefox workaround.
Vladimir Homutov <vl@nginx.com>
parents:
8371
diff
changeset
|
1401 p = ngx_quic_skip_zero_padding(b); |
8304
90f94413177e
TLS Early Data support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8303
diff
changeset
|
1402 } |
8182
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
1403 |
8225 | 1404 return NGX_OK; |
8182
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
1405 } |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
1406 |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
1407 |
8377
2a94aaa70b33
Cleaned up firefox workaround.
Vladimir Homutov <vl@nginx.com>
parents:
8371
diff
changeset
|
1408 /* firefox workaround: skip zero padding at the end of quic packet */ |
2a94aaa70b33
Cleaned up firefox workaround.
Vladimir Homutov <vl@nginx.com>
parents:
8371
diff
changeset
|
1409 static ngx_inline u_char * |
2a94aaa70b33
Cleaned up firefox workaround.
Vladimir Homutov <vl@nginx.com>
parents:
8371
diff
changeset
|
1410 ngx_quic_skip_zero_padding(ngx_buf_t *b) |
2a94aaa70b33
Cleaned up firefox workaround.
Vladimir Homutov <vl@nginx.com>
parents:
8371
diff
changeset
|
1411 { |
2a94aaa70b33
Cleaned up firefox workaround.
Vladimir Homutov <vl@nginx.com>
parents:
8371
diff
changeset
|
1412 while (b->pos < b->last && *(b->pos) == 0) { |
2a94aaa70b33
Cleaned up firefox workaround.
Vladimir Homutov <vl@nginx.com>
parents:
8371
diff
changeset
|
1413 b->pos++; |
2a94aaa70b33
Cleaned up firefox workaround.
Vladimir Homutov <vl@nginx.com>
parents:
8371
diff
changeset
|
1414 } |
2a94aaa70b33
Cleaned up firefox workaround.
Vladimir Homutov <vl@nginx.com>
parents:
8371
diff
changeset
|
1415 |
2a94aaa70b33
Cleaned up firefox workaround.
Vladimir Homutov <vl@nginx.com>
parents:
8371
diff
changeset
|
1416 return b->pos; |
2a94aaa70b33
Cleaned up firefox workaround.
Vladimir Homutov <vl@nginx.com>
parents:
8371
diff
changeset
|
1417 } |
2a94aaa70b33
Cleaned up firefox workaround.
Vladimir Homutov <vl@nginx.com>
parents:
8371
diff
changeset
|
1418 |
2a94aaa70b33
Cleaned up firefox workaround.
Vladimir Homutov <vl@nginx.com>
parents:
8371
diff
changeset
|
1419 |
8182
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
1420 static ngx_int_t |
8383
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1421 ngx_quic_retry_input(ngx_connection_t *c, ngx_quic_header_t *pkt) |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1422 { |
8386
81f85c479d7e
Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents:
8385
diff
changeset
|
1423 ngx_int_t rc; |
8383
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1424 ngx_quic_secrets_t *keys; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1425 ngx_quic_send_ctx_t *ctx; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1426 ngx_quic_connection_t *qc; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1427 static u_char buf[NGX_QUIC_DEFAULT_MAX_PACKET_SIZE]; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1428 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1429 c->log->action = "retrying quic connection"; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1430 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1431 if (ngx_buf_size(pkt->raw) < NGX_QUIC_MIN_INITIAL_SIZE) { |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1432 ngx_log_error(NGX_LOG_INFO, c->log, 0, |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1433 "quic UDP datagram is too small for initial packet"); |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1434 return NGX_OK; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1435 } |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1436 |
8386
81f85c479d7e
Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents:
8385
diff
changeset
|
1437 rc = ngx_quic_parse_long_header(pkt); |
81f85c479d7e
Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents:
8385
diff
changeset
|
1438 if (rc != NGX_OK) { |
81f85c479d7e
Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents:
8385
diff
changeset
|
1439 return rc; |
8383
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1440 } |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1441 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1442 if (ngx_quic_pkt_zrtt(pkt->flags)) { |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1443 ngx_log_error(NGX_LOG_INFO, c->log, 0, |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1444 "quic discard inflight 0-RTT packet"); |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1445 return NGX_OK; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1446 } |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1447 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1448 if (!ngx_quic_pkt_in(pkt->flags)) { |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1449 ngx_log_error(NGX_LOG_INFO, c->log, 0, |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1450 "quic invalid initial packet: 0x%xi", pkt->flags); |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1451 return NGX_ERROR; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1452 } |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1453 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1454 if (ngx_quic_parse_initial_header(pkt) != NGX_OK) { |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1455 return NGX_ERROR; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1456 } |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1457 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1458 if (ngx_quic_new_dcid(c, &pkt->dcid) != NGX_OK) { |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1459 return NGX_ERROR; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1460 } |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1461 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1462 qc = c->quic; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1463 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1464 keys = &c->quic->keys[ssl_encryption_initial]; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1465 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1466 if (ngx_quic_set_initial_secret(c->pool, &keys->client, &keys->server, |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1467 &qc->odcid) |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1468 != NGX_OK) |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1469 { |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1470 return NGX_ERROR; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1471 } |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1472 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1473 c->quic->in_retry = 0; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1474 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1475 if (ngx_quic_validate_token(c, pkt) != NGX_OK) { |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1476 ngx_log_error(NGX_LOG_INFO, c->log, 0, "quic invalid token"); |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1477 return NGX_ERROR; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1478 } |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1479 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1480 pkt->secret = &keys->client; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1481 pkt->level = ssl_encryption_initial; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1482 pkt->plaintext = buf; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1483 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1484 ctx = ngx_quic_get_send_ctx(qc, pkt->level); |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1485 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1486 if (ngx_quic_decrypt(pkt, NULL, &ctx->largest_pn) != NGX_OK) { |
8386
81f85c479d7e
Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents:
8385
diff
changeset
|
1487 qc->error = pkt->error; |
8383
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1488 return NGX_ERROR; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1489 } |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1490 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1491 if (ngx_quic_init_connection(c) != NGX_OK) { |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1492 return NGX_ERROR; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1493 } |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1494 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1495 if (ngx_quic_payload_handler(c, pkt) != NGX_OK) { |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1496 return NGX_ERROR; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1497 } |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1498 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1499 /* pos is at header end, adjust by actual packet length */ |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1500 pkt->raw->pos += pkt->len; |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1501 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1502 (void) ngx_quic_skip_zero_padding(pkt->raw); |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1503 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1504 return ngx_quic_input(c, pkt->raw); |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1505 } |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1506 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1507 |
7ea34e13937f
Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8382
diff
changeset
|
1508 static ngx_int_t |
8223 | 1509 ngx_quic_initial_input(ngx_connection_t *c, ngx_quic_header_t *pkt) |
1510 { | |
8386
81f85c479d7e
Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents:
8385
diff
changeset
|
1511 ngx_int_t rc; |
8339
aba84d9ab256
Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8338
diff
changeset
|
1512 ngx_ssl_conn_t *ssl_conn; |
aba84d9ab256
Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8338
diff
changeset
|
1513 ngx_quic_secrets_t *keys; |
aba84d9ab256
Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8338
diff
changeset
|
1514 ngx_quic_send_ctx_t *ctx; |
aba84d9ab256
Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8338
diff
changeset
|
1515 static u_char buf[NGX_QUIC_DEFAULT_MAX_PACKET_SIZE]; |
8223 | 1516 |
8263
1295b293d09a
Connection states code cleanup.
Vladimir Homutov <vl@nginx.com>
parents:
8260
diff
changeset
|
1517 c->log->action = "processing initial quic packet"; |
1295b293d09a
Connection states code cleanup.
Vladimir Homutov <vl@nginx.com>
parents:
8260
diff
changeset
|
1518 |
8223 | 1519 ssl_conn = c->ssl->connection; |
1520 | |
8386
81f85c479d7e
Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents:
8385
diff
changeset
|
1521 rc = ngx_quic_parse_long_header(pkt); |
81f85c479d7e
Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents:
8385
diff
changeset
|
1522 if (rc != NGX_OK) { |
81f85c479d7e
Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents:
8385
diff
changeset
|
1523 return rc; |
8223 | 1524 } |
1525 | |
8224
ae35ccba7aa6
Extracted transport part of the code into separate file.
Vladimir Homutov <vl@nginx.com>
parents:
8223
diff
changeset
|
1526 if (ngx_quic_parse_initial_header(pkt) != NGX_OK) { |
8223 | 1527 return NGX_ERROR; |
1528 } | |
1529 | |
8306
058a5af7ddfc
Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents:
8305
diff
changeset
|
1530 keys = &c->quic->keys[ssl_encryption_initial]; |
058a5af7ddfc
Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents:
8305
diff
changeset
|
1531 |
058a5af7ddfc
Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents:
8305
diff
changeset
|
1532 pkt->secret = &keys->client; |
8223 | 1533 pkt->level = ssl_encryption_initial; |
8288
ebd5c71b9f02
Got rid of memory allocation in decryption.
Vladimir Homutov <vl@nginx.com>
parents:
8286
diff
changeset
|
1534 pkt->plaintext = buf; |
8223 | 1535 |
8339
aba84d9ab256
Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8338
diff
changeset
|
1536 ctx = ngx_quic_get_send_ctx(c->quic, pkt->level); |
aba84d9ab256
Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8338
diff
changeset
|
1537 |
aba84d9ab256
Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8338
diff
changeset
|
1538 if (ngx_quic_decrypt(pkt, ssl_conn, &ctx->largest_pn) != NGX_OK) { |
8386
81f85c479d7e
Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents:
8385
diff
changeset
|
1539 c->quic->error = pkt->error; |
8223 | 1540 return NGX_ERROR; |
1541 } | |
1542 | |
1543 return ngx_quic_payload_handler(c, pkt); | |
1544 } | |
1545 | |
1546 | |
1547 static ngx_int_t | |
8206
8d6ac639feac
Added support of multiple QUIC packets in single datagram.
Vladimir Homutov <vl@nginx.com>
parents:
8205
diff
changeset
|
1548 ngx_quic_handshake_input(ngx_connection_t *c, ngx_quic_header_t *pkt) |
8182
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
1549 { |
8386
81f85c479d7e
Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents:
8385
diff
changeset
|
1550 ngx_int_t rc; |
8306
058a5af7ddfc
Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents:
8305
diff
changeset
|
1551 ngx_quic_secrets_t *keys; |
8339
aba84d9ab256
Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8338
diff
changeset
|
1552 ngx_quic_send_ctx_t *ctx; |
8182
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
1553 ngx_quic_connection_t *qc; |
8288
ebd5c71b9f02
Got rid of memory allocation in decryption.
Vladimir Homutov <vl@nginx.com>
parents:
8286
diff
changeset
|
1554 static u_char buf[NGX_QUIC_DEFAULT_MAX_PACKET_SIZE]; |
8182
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
1555 |
8263
1295b293d09a
Connection states code cleanup.
Vladimir Homutov <vl@nginx.com>
parents:
8260
diff
changeset
|
1556 c->log->action = "processing handshake quic packet"; |
1295b293d09a
Connection states code cleanup.
Vladimir Homutov <vl@nginx.com>
parents:
8260
diff
changeset
|
1557 |
8182
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
1558 qc = c->quic; |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
1559 |
8321
e45719a9b148
Discarding Handshake packets if no Handshake keys yet.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8320
diff
changeset
|
1560 keys = &c->quic->keys[ssl_encryption_handshake]; |
e45719a9b148
Discarding Handshake packets if no Handshake keys yet.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8320
diff
changeset
|
1561 |
e45719a9b148
Discarding Handshake packets if no Handshake keys yet.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8320
diff
changeset
|
1562 if (keys->client.key.len == 0) { |
e45719a9b148
Discarding Handshake packets if no Handshake keys yet.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8320
diff
changeset
|
1563 ngx_log_error(NGX_LOG_INFO, c->log, 0, |
8361 | 1564 "quic no read keys yet, packet ignored"); |
8321
e45719a9b148
Discarding Handshake packets if no Handshake keys yet.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8320
diff
changeset
|
1565 return NGX_DECLINED; |
e45719a9b148
Discarding Handshake packets if no Handshake keys yet.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8320
diff
changeset
|
1566 } |
e45719a9b148
Discarding Handshake packets if no Handshake keys yet.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8320
diff
changeset
|
1567 |
8193
4355efde26d8
Added functions to decrypt long packets.
Vladimir Homutov <vl@nginx.com>
parents:
8192
diff
changeset
|
1568 /* extract cleartext data into pkt */ |
8386
81f85c479d7e
Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents:
8385
diff
changeset
|
1569 rc = ngx_quic_parse_long_header(pkt); |
81f85c479d7e
Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents:
8385
diff
changeset
|
1570 if (rc != NGX_OK) { |
81f85c479d7e
Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents:
8385
diff
changeset
|
1571 return rc; |
8182
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
1572 } |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
1573 |
8361 | 1574 if (ngx_quic_check_peer(qc, pkt) != NGX_OK) { |
8182
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
1575 return NGX_ERROR; |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
1576 } |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
1577 |
8224
ae35ccba7aa6
Extracted transport part of the code into separate file.
Vladimir Homutov <vl@nginx.com>
parents:
8223
diff
changeset
|
1578 if (ngx_quic_parse_handshake_header(pkt) != NGX_OK) { |
8182
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
1579 return NGX_ERROR; |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
1580 } |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
1581 |
8306
058a5af7ddfc
Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents:
8305
diff
changeset
|
1582 pkt->secret = &keys->client; |
8206
8d6ac639feac
Added support of multiple QUIC packets in single datagram.
Vladimir Homutov <vl@nginx.com>
parents:
8205
diff
changeset
|
1583 pkt->level = ssl_encryption_handshake; |
8288
ebd5c71b9f02
Got rid of memory allocation in decryption.
Vladimir Homutov <vl@nginx.com>
parents:
8286
diff
changeset
|
1584 pkt->plaintext = buf; |
8206
8d6ac639feac
Added support of multiple QUIC packets in single datagram.
Vladimir Homutov <vl@nginx.com>
parents:
8205
diff
changeset
|
1585 |
8339
aba84d9ab256
Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8338
diff
changeset
|
1586 ctx = ngx_quic_get_send_ctx(qc, pkt->level); |
aba84d9ab256
Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8338
diff
changeset
|
1587 |
aba84d9ab256
Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8338
diff
changeset
|
1588 if (ngx_quic_decrypt(pkt, c->ssl->connection, &ctx->largest_pn) != NGX_OK) { |
8386
81f85c479d7e
Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents:
8385
diff
changeset
|
1589 qc->error = pkt->error; |
8182
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
1590 return NGX_ERROR; |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
1591 } |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
1592 |
8393
e169cce912c7
Avoid retransmitting of packets with discarded keys.
Vladimir Homutov <vl@nginx.com>
parents:
8392
diff
changeset
|
1593 /* |
e169cce912c7
Avoid retransmitting of packets with discarded keys.
Vladimir Homutov <vl@nginx.com>
parents:
8392
diff
changeset
|
1594 * 4.10.1. The successful use of Handshake packets indicates |
e169cce912c7
Avoid retransmitting of packets with discarded keys.
Vladimir Homutov <vl@nginx.com>
parents:
8392
diff
changeset
|
1595 * that no more Initial packets need to be exchanged |
e169cce912c7
Avoid retransmitting of packets with discarded keys.
Vladimir Homutov <vl@nginx.com>
parents:
8392
diff
changeset
|
1596 */ |
e169cce912c7
Avoid retransmitting of packets with discarded keys.
Vladimir Homutov <vl@nginx.com>
parents:
8392
diff
changeset
|
1597 ctx = ngx_quic_get_send_ctx(c->quic, ssl_encryption_initial); |
e169cce912c7
Avoid retransmitting of packets with discarded keys.
Vladimir Homutov <vl@nginx.com>
parents:
8392
diff
changeset
|
1598 ngx_quic_free_frames(c, &ctx->sent); |
e169cce912c7
Avoid retransmitting of packets with discarded keys.
Vladimir Homutov <vl@nginx.com>
parents:
8392
diff
changeset
|
1599 |
8206
8d6ac639feac
Added support of multiple QUIC packets in single datagram.
Vladimir Homutov <vl@nginx.com>
parents:
8205
diff
changeset
|
1600 return ngx_quic_payload_handler(c, pkt); |
8199
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
1601 } |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
1602 |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
1603 |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
1604 static ngx_int_t |
8304
90f94413177e
TLS Early Data support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8303
diff
changeset
|
1605 ngx_quic_early_input(ngx_connection_t *c, ngx_quic_header_t *pkt) |
90f94413177e
TLS Early Data support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8303
diff
changeset
|
1606 { |
8386
81f85c479d7e
Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents:
8385
diff
changeset
|
1607 ngx_int_t rc; |
8306
058a5af7ddfc
Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents:
8305
diff
changeset
|
1608 ngx_quic_secrets_t *keys; |
8339
aba84d9ab256
Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8338
diff
changeset
|
1609 ngx_quic_send_ctx_t *ctx; |
8304
90f94413177e
TLS Early Data support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8303
diff
changeset
|
1610 ngx_quic_connection_t *qc; |
90f94413177e
TLS Early Data support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8303
diff
changeset
|
1611 static u_char buf[NGX_QUIC_DEFAULT_MAX_PACKET_SIZE]; |
90f94413177e
TLS Early Data support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8303
diff
changeset
|
1612 |
90f94413177e
TLS Early Data support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8303
diff
changeset
|
1613 c->log->action = "processing early data quic packet"; |
90f94413177e
TLS Early Data support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8303
diff
changeset
|
1614 |
90f94413177e
TLS Early Data support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8303
diff
changeset
|
1615 qc = c->quic; |
90f94413177e
TLS Early Data support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8303
diff
changeset
|
1616 |
90f94413177e
TLS Early Data support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8303
diff
changeset
|
1617 /* extract cleartext data into pkt */ |
8386
81f85c479d7e
Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents:
8385
diff
changeset
|
1618 rc = ngx_quic_parse_long_header(pkt); |
81f85c479d7e
Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents:
8385
diff
changeset
|
1619 if (rc != NGX_OK) { |
81f85c479d7e
Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents:
8385
diff
changeset
|
1620 return rc; |
8304
90f94413177e
TLS Early Data support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8303
diff
changeset
|
1621 } |
90f94413177e
TLS Early Data support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8303
diff
changeset
|
1622 |
8361 | 1623 if (ngx_quic_check_peer(qc, pkt) != NGX_OK) { |
8304
90f94413177e
TLS Early Data support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8303
diff
changeset
|
1624 return NGX_ERROR; |
90f94413177e
TLS Early Data support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8303
diff
changeset
|
1625 } |
90f94413177e
TLS Early Data support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8303
diff
changeset
|
1626 |
90f94413177e
TLS Early Data support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8303
diff
changeset
|
1627 if (ngx_quic_parse_handshake_header(pkt) != NGX_OK) { |
90f94413177e
TLS Early Data support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8303
diff
changeset
|
1628 return NGX_ERROR; |
90f94413177e
TLS Early Data support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8303
diff
changeset
|
1629 } |
90f94413177e
TLS Early Data support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8303
diff
changeset
|
1630 |
8397
1245e274b9ba
Avoided excessive definitions for connection state.
Vladimir Homutov <vl@nginx.com>
parents:
8394
diff
changeset
|
1631 if (c->quic->state != ssl_encryption_early_data) { |
8361 | 1632 ngx_log_error(NGX_LOG_INFO, c->log, 0, "quic unexpected 0-RTT packet"); |
8304
90f94413177e
TLS Early Data support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8303
diff
changeset
|
1633 return NGX_OK; |
90f94413177e
TLS Early Data support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8303
diff
changeset
|
1634 } |
90f94413177e
TLS Early Data support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8303
diff
changeset
|
1635 |
8306
058a5af7ddfc
Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents:
8305
diff
changeset
|
1636 keys = &c->quic->keys[ssl_encryption_early_data]; |
058a5af7ddfc
Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents:
8305
diff
changeset
|
1637 |
058a5af7ddfc
Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents:
8305
diff
changeset
|
1638 pkt->secret = &keys->client; |
8304
90f94413177e
TLS Early Data support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8303
diff
changeset
|
1639 pkt->level = ssl_encryption_early_data; |
90f94413177e
TLS Early Data support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8303
diff
changeset
|
1640 pkt->plaintext = buf; |
90f94413177e
TLS Early Data support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8303
diff
changeset
|
1641 |
8339
aba84d9ab256
Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8338
diff
changeset
|
1642 ctx = ngx_quic_get_send_ctx(qc, pkt->level); |
aba84d9ab256
Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8338
diff
changeset
|
1643 |
aba84d9ab256
Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8338
diff
changeset
|
1644 if (ngx_quic_decrypt(pkt, c->ssl->connection, &ctx->largest_pn) != NGX_OK) { |
8386
81f85c479d7e
Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents:
8385
diff
changeset
|
1645 qc->error = pkt->error; |
8304
90f94413177e
TLS Early Data support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8303
diff
changeset
|
1646 return NGX_ERROR; |
90f94413177e
TLS Early Data support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8303
diff
changeset
|
1647 } |
90f94413177e
TLS Early Data support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8303
diff
changeset
|
1648 |
90f94413177e
TLS Early Data support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8303
diff
changeset
|
1649 return ngx_quic_payload_handler(c, pkt); |
90f94413177e
TLS Early Data support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8303
diff
changeset
|
1650 } |
90f94413177e
TLS Early Data support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8303
diff
changeset
|
1651 |
90f94413177e
TLS Early Data support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8303
diff
changeset
|
1652 |
90f94413177e
TLS Early Data support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8303
diff
changeset
|
1653 static ngx_int_t |
8361 | 1654 ngx_quic_check_peer(ngx_quic_connection_t *qc, ngx_quic_header_t *pkt) |
1655 { | |
8381
6e100d8c138a
Preserve original DCID and unbreak parsing 0-RTT packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8380
diff
changeset
|
1656 ngx_str_t *dcid; |
6e100d8c138a
Preserve original DCID and unbreak parsing 0-RTT packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8380
diff
changeset
|
1657 |
6e100d8c138a
Preserve original DCID and unbreak parsing 0-RTT packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8380
diff
changeset
|
1658 dcid = ngx_quic_pkt_zrtt(pkt->flags) ? &qc->odcid : &qc->dcid; |
6e100d8c138a
Preserve original DCID and unbreak parsing 0-RTT packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8380
diff
changeset
|
1659 |
6e100d8c138a
Preserve original DCID and unbreak parsing 0-RTT packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8380
diff
changeset
|
1660 if (pkt->dcid.len != dcid->len) { |
8361 | 1661 ngx_log_error(NGX_LOG_INFO, pkt->log, 0, "quic unexpected quic dcidl"); |
1662 return NGX_ERROR; | |
1663 } | |
1664 | |
8381
6e100d8c138a
Preserve original DCID and unbreak parsing 0-RTT packets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8380
diff
changeset
|
1665 if (ngx_memcmp(pkt->dcid.data, dcid->data, dcid->len) != 0) { |
8361 | 1666 ngx_log_error(NGX_LOG_INFO, pkt->log, 0, "quic unexpected quic dcid"); |
1667 return NGX_ERROR; | |
1668 } | |
1669 | |
1670 if (pkt->scid.len != qc->scid.len) { | |
1671 ngx_log_error(NGX_LOG_INFO, pkt->log, 0, "quic unexpected quic scidl"); | |
1672 return NGX_ERROR; | |
1673 } | |
1674 | |
1675 if (ngx_memcmp(pkt->scid.data, qc->scid.data, qc->scid.len) != 0) { | |
1676 ngx_log_error(NGX_LOG_INFO, pkt->log, 0, "quic unexpected quic scid"); | |
1677 return NGX_ERROR; | |
1678 } | |
1679 | |
1680 return NGX_OK; | |
1681 } | |
1682 | |
1683 | |
1684 static ngx_int_t | |
8206
8d6ac639feac
Added support of multiple QUIC packets in single datagram.
Vladimir Homutov <vl@nginx.com>
parents:
8205
diff
changeset
|
1685 ngx_quic_app_input(ngx_connection_t *c, ngx_quic_header_t *pkt) |
8199
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
1686 { |
8319
29354c6fc5f2
TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8316
diff
changeset
|
1687 ngx_int_t rc; |
29354c6fc5f2
TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8316
diff
changeset
|
1688 ngx_quic_secrets_t *keys, *next, tmp; |
8339
aba84d9ab256
Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8338
diff
changeset
|
1689 ngx_quic_send_ctx_t *ctx; |
8199
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
1690 ngx_quic_connection_t *qc; |
8288
ebd5c71b9f02
Got rid of memory allocation in decryption.
Vladimir Homutov <vl@nginx.com>
parents:
8286
diff
changeset
|
1691 static u_char buf[NGX_QUIC_DEFAULT_MAX_PACKET_SIZE]; |
8199
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
1692 |
8263
1295b293d09a
Connection states code cleanup.
Vladimir Homutov <vl@nginx.com>
parents:
8260
diff
changeset
|
1693 c->log->action = "processing application data quic packet"; |
1295b293d09a
Connection states code cleanup.
Vladimir Homutov <vl@nginx.com>
parents:
8260
diff
changeset
|
1694 |
8199
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
1695 qc = c->quic; |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
1696 |
8306
058a5af7ddfc
Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents:
8305
diff
changeset
|
1697 keys = &c->quic->keys[ssl_encryption_application]; |
8319
29354c6fc5f2
TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8316
diff
changeset
|
1698 next = &c->quic->next_key; |
8306
058a5af7ddfc
Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents:
8305
diff
changeset
|
1699 |
058a5af7ddfc
Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents:
8305
diff
changeset
|
1700 if (keys->client.key.len == 0) { |
8223 | 1701 ngx_log_error(NGX_LOG_INFO, c->log, 0, |
8361 | 1702 "quic no read keys yet, packet ignored"); |
8223 | 1703 return NGX_DECLINED; |
1704 } | |
8199
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
1705 |
8386
81f85c479d7e
Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents:
8385
diff
changeset
|
1706 rc = ngx_quic_parse_short_header(pkt, &qc->dcid); |
81f85c479d7e
Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents:
8385
diff
changeset
|
1707 if (rc != NGX_OK) { |
81f85c479d7e
Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents:
8385
diff
changeset
|
1708 return rc; |
8185
6a76d9657772
QUIC handshake final bits.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8184
diff
changeset
|
1709 } |
6a76d9657772
QUIC handshake final bits.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8184
diff
changeset
|
1710 |
8306
058a5af7ddfc
Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents:
8305
diff
changeset
|
1711 pkt->secret = &keys->client; |
8319
29354c6fc5f2
TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8316
diff
changeset
|
1712 pkt->next = &next->client; |
29354c6fc5f2
TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8316
diff
changeset
|
1713 pkt->key_phase = c->quic->key_phase; |
8206
8d6ac639feac
Added support of multiple QUIC packets in single datagram.
Vladimir Homutov <vl@nginx.com>
parents:
8205
diff
changeset
|
1714 pkt->level = ssl_encryption_application; |
8288
ebd5c71b9f02
Got rid of memory allocation in decryption.
Vladimir Homutov <vl@nginx.com>
parents:
8286
diff
changeset
|
1715 pkt->plaintext = buf; |
8206
8d6ac639feac
Added support of multiple QUIC packets in single datagram.
Vladimir Homutov <vl@nginx.com>
parents:
8205
diff
changeset
|
1716 |
8339
aba84d9ab256
Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8338
diff
changeset
|
1717 ctx = ngx_quic_get_send_ctx(qc, pkt->level); |
aba84d9ab256
Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8338
diff
changeset
|
1718 |
aba84d9ab256
Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8338
diff
changeset
|
1719 if (ngx_quic_decrypt(pkt, c->ssl->connection, &ctx->largest_pn) != NGX_OK) { |
8386
81f85c479d7e
Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents:
8385
diff
changeset
|
1720 qc->error = pkt->error; |
8199
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
1721 return NGX_ERROR; |
8185
6a76d9657772
QUIC handshake final bits.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8184
diff
changeset
|
1722 } |
6a76d9657772
QUIC handshake final bits.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8184
diff
changeset
|
1723 |
8319
29354c6fc5f2
TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8316
diff
changeset
|
1724 /* switch keys on Key Phase change */ |
29354c6fc5f2
TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8316
diff
changeset
|
1725 |
29354c6fc5f2
TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8316
diff
changeset
|
1726 if (pkt->key_update) { |
29354c6fc5f2
TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8316
diff
changeset
|
1727 c->quic->key_phase ^= 1; |
29354c6fc5f2
TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8316
diff
changeset
|
1728 |
29354c6fc5f2
TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8316
diff
changeset
|
1729 tmp = *keys; |
29354c6fc5f2
TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8316
diff
changeset
|
1730 *keys = *next; |
29354c6fc5f2
TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8316
diff
changeset
|
1731 *next = tmp; |
29354c6fc5f2
TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8316
diff
changeset
|
1732 } |
29354c6fc5f2
TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8316
diff
changeset
|
1733 |
29354c6fc5f2
TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8316
diff
changeset
|
1734 rc = ngx_quic_payload_handler(c, pkt); |
29354c6fc5f2
TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8316
diff
changeset
|
1735 |
29354c6fc5f2
TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8316
diff
changeset
|
1736 if (rc == NGX_ERROR) { |
29354c6fc5f2
TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8316
diff
changeset
|
1737 return NGX_ERROR; |
29354c6fc5f2
TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8316
diff
changeset
|
1738 } |
29354c6fc5f2
TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8316
diff
changeset
|
1739 |
29354c6fc5f2
TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8316
diff
changeset
|
1740 /* generate next keys */ |
29354c6fc5f2
TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8316
diff
changeset
|
1741 |
29354c6fc5f2
TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8316
diff
changeset
|
1742 if (pkt->key_update) { |
29354c6fc5f2
TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8316
diff
changeset
|
1743 if (ngx_quic_key_update(c, keys, next) != NGX_OK) { |
29354c6fc5f2
TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8316
diff
changeset
|
1744 return NGX_ERROR; |
29354c6fc5f2
TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8316
diff
changeset
|
1745 } |
29354c6fc5f2
TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8316
diff
changeset
|
1746 } |
29354c6fc5f2
TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8316
diff
changeset
|
1747 |
29354c6fc5f2
TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8316
diff
changeset
|
1748 return rc; |
8182
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
1749 } |
8171 | 1750 |
1751 | |
8225 | 1752 static ngx_int_t |
1753 ngx_quic_payload_handler(ngx_connection_t *c, ngx_quic_header_t *pkt) | |
1754 { | |
1755 u_char *end, *p; | |
1756 ssize_t len; | |
8367
c10e7d48aa85
Factored out sending ACK from payload handler.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8365
diff
changeset
|
1757 ngx_uint_t ack_sent, do_close; |
c10e7d48aa85
Factored out sending ACK from payload handler.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8365
diff
changeset
|
1758 ngx_quic_frame_t frame; |
8225 | 1759 ngx_quic_connection_t *qc; |
1760 | |
1761 qc = c->quic; | |
1762 | |
8355
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1763 if (qc->closing) { |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1764 /* |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1765 * 10.1 Closing and Draining Connection States |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1766 * ... delayed or reordered packets are properly discarded. |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1767 * |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1768 * An endpoint retains only enough information to generate |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1769 * a packet containing a CONNECTION_CLOSE frame and to identify |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1770 * packets as belonging to the connection. |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1771 */ |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1772 return ngx_quic_send_cc(c, pkt->level, NGX_QUIC_ERR_NO_ERROR); |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1773 } |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1774 |
8225 | 1775 p = pkt->payload.data; |
1776 end = p + pkt->payload.len; | |
1777 | |
8367
c10e7d48aa85
Factored out sending ACK from payload handler.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8365
diff
changeset
|
1778 ack_sent = 0; |
8225 | 1779 do_close = 0; |
1780 | |
1781 while (p < end) { | |
1782 | |
8275 | 1783 c->log->action = "parsing frames"; |
1784 | |
8240
1f002206a59b
Added boundaries checks into frame parser.
Vladimir Homutov <vl@nginx.com>
parents:
8239
diff
changeset
|
1785 len = ngx_quic_parse_frame(pkt, p, end, &frame); |
8251
c217a907ce42
Added checks for permitted frame types.
Vladimir Homutov <vl@nginx.com>
parents:
8247
diff
changeset
|
1786 |
8225 | 1787 if (len < 0) { |
8385
fb7422074258
Added generation of CC frames with error on connection termination.
Vladimir Homutov <vl@nginx.com>
parents:
8384
diff
changeset
|
1788 qc->error = pkt->error; |
8225 | 1789 return NGX_ERROR; |
1790 } | |
1791 | |
8275 | 1792 c->log->action = "handling frames"; |
1793 | |
8225 | 1794 p += len; |
1795 | |
1796 switch (frame.type) { | |
1797 | |
1798 case NGX_QUIC_FT_ACK: | |
1799 if (ngx_quic_handle_ack_frame(c, pkt, &frame.u.ack) != NGX_OK) { | |
1800 return NGX_ERROR; | |
1801 } | |
1802 | |
8367
c10e7d48aa85
Factored out sending ACK from payload handler.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8365
diff
changeset
|
1803 continue; |
c10e7d48aa85
Factored out sending ACK from payload handler.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8365
diff
changeset
|
1804 |
c10e7d48aa85
Factored out sending ACK from payload handler.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8365
diff
changeset
|
1805 case NGX_QUIC_FT_PADDING: |
c10e7d48aa85
Factored out sending ACK from payload handler.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8365
diff
changeset
|
1806 /* no action required */ |
c10e7d48aa85
Factored out sending ACK from payload handler.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8365
diff
changeset
|
1807 continue; |
c10e7d48aa85
Factored out sending ACK from payload handler.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8365
diff
changeset
|
1808 |
c10e7d48aa85
Factored out sending ACK from payload handler.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8365
diff
changeset
|
1809 case NGX_QUIC_FT_CONNECTION_CLOSE: |
c10e7d48aa85
Factored out sending ACK from payload handler.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8365
diff
changeset
|
1810 case NGX_QUIC_FT_CONNECTION_CLOSE2: |
c10e7d48aa85
Factored out sending ACK from payload handler.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8365
diff
changeset
|
1811 do_close = 1; |
c10e7d48aa85
Factored out sending ACK from payload handler.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8365
diff
changeset
|
1812 continue; |
c10e7d48aa85
Factored out sending ACK from payload handler.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8365
diff
changeset
|
1813 } |
c10e7d48aa85
Factored out sending ACK from payload handler.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8365
diff
changeset
|
1814 |
c10e7d48aa85
Factored out sending ACK from payload handler.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8365
diff
changeset
|
1815 /* got there with ack-eliciting packet */ |
c10e7d48aa85
Factored out sending ACK from payload handler.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8365
diff
changeset
|
1816 |
c10e7d48aa85
Factored out sending ACK from payload handler.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8365
diff
changeset
|
1817 if (!ack_sent) { |
c10e7d48aa85
Factored out sending ACK from payload handler.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8365
diff
changeset
|
1818 if (ngx_quic_send_ack(c, pkt) != NGX_OK) { |
c10e7d48aa85
Factored out sending ACK from payload handler.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8365
diff
changeset
|
1819 return NGX_ERROR; |
c10e7d48aa85
Factored out sending ACK from payload handler.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8365
diff
changeset
|
1820 } |
c10e7d48aa85
Factored out sending ACK from payload handler.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8365
diff
changeset
|
1821 |
c10e7d48aa85
Factored out sending ACK from payload handler.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8365
diff
changeset
|
1822 ack_sent = 1; |
c10e7d48aa85
Factored out sending ACK from payload handler.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8365
diff
changeset
|
1823 } |
c10e7d48aa85
Factored out sending ACK from payload handler.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8365
diff
changeset
|
1824 |
c10e7d48aa85
Factored out sending ACK from payload handler.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8365
diff
changeset
|
1825 switch (frame.type) { |
8225 | 1826 |
1827 case NGX_QUIC_FT_CRYPTO: | |
1828 | |
8333
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
1829 if (ngx_quic_handle_crypto_frame(c, pkt, &frame) != NGX_OK) { |
8225 | 1830 return NGX_ERROR; |
1831 } | |
1832 | |
1833 break; | |
1834 | |
1835 case NGX_QUIC_FT_PING: | |
1836 break; | |
1837 | |
1838 case NGX_QUIC_FT_STREAM0: | |
1839 case NGX_QUIC_FT_STREAM1: | |
1840 case NGX_QUIC_FT_STREAM2: | |
1841 case NGX_QUIC_FT_STREAM3: | |
1842 case NGX_QUIC_FT_STREAM4: | |
1843 case NGX_QUIC_FT_STREAM5: | |
1844 case NGX_QUIC_FT_STREAM6: | |
1845 case NGX_QUIC_FT_STREAM7: | |
1846 | |
8334
72d20158c814
Added reordering support for STREAM frames.
Vladimir Homutov <vl@nginx.com>
parents:
8333
diff
changeset
|
1847 if (ngx_quic_handle_stream_frame(c, pkt, &frame) != NGX_OK) { |
8225 | 1848 return NGX_ERROR; |
1849 } | |
1850 | |
1851 break; | |
1852 | |
8237
ff540f13d95d
MAX_DATA frame parser/handler.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8236
diff
changeset
|
1853 case NGX_QUIC_FT_MAX_DATA: |
8365
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
1854 |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
1855 if (ngx_quic_handle_max_data_frame(c, &frame.u.max_data) != NGX_OK) |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
1856 { |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
1857 return NGX_ERROR; |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
1858 } |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
1859 |
8237
ff540f13d95d
MAX_DATA frame parser/handler.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8236
diff
changeset
|
1860 break; |
ff540f13d95d
MAX_DATA frame parser/handler.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8236
diff
changeset
|
1861 |
8236
d3b26c3bea22
Added parsing of STREAMS BLOCKED frames.
Vladimir Homutov <vl@nginx.com>
parents:
8235
diff
changeset
|
1862 case NGX_QUIC_FT_STREAMS_BLOCKED: |
d3b26c3bea22
Added parsing of STREAMS BLOCKED frames.
Vladimir Homutov <vl@nginx.com>
parents:
8235
diff
changeset
|
1863 case NGX_QUIC_FT_STREAMS_BLOCKED2: |
8245
a14afe21e692
Double MAX_STREAMS on STREAMS_BLOCKED.
Roman Arutyunyan <arut@nginx.com>
parents:
8241
diff
changeset
|
1864 |
a14afe21e692
Double MAX_STREAMS on STREAMS_BLOCKED.
Roman Arutyunyan <arut@nginx.com>
parents:
8241
diff
changeset
|
1865 if (ngx_quic_handle_streams_blocked_frame(c, pkt, |
a14afe21e692
Double MAX_STREAMS on STREAMS_BLOCKED.
Roman Arutyunyan <arut@nginx.com>
parents:
8241
diff
changeset
|
1866 &frame.u.streams_blocked) |
a14afe21e692
Double MAX_STREAMS on STREAMS_BLOCKED.
Roman Arutyunyan <arut@nginx.com>
parents:
8241
diff
changeset
|
1867 != NGX_OK) |
a14afe21e692
Double MAX_STREAMS on STREAMS_BLOCKED.
Roman Arutyunyan <arut@nginx.com>
parents:
8241
diff
changeset
|
1868 { |
a14afe21e692
Double MAX_STREAMS on STREAMS_BLOCKED.
Roman Arutyunyan <arut@nginx.com>
parents:
8241
diff
changeset
|
1869 return NGX_ERROR; |
a14afe21e692
Double MAX_STREAMS on STREAMS_BLOCKED.
Roman Arutyunyan <arut@nginx.com>
parents:
8241
diff
changeset
|
1870 } |
a14afe21e692
Double MAX_STREAMS on STREAMS_BLOCKED.
Roman Arutyunyan <arut@nginx.com>
parents:
8241
diff
changeset
|
1871 |
8236
d3b26c3bea22
Added parsing of STREAMS BLOCKED frames.
Vladimir Homutov <vl@nginx.com>
parents:
8235
diff
changeset
|
1872 break; |
d3b26c3bea22
Added parsing of STREAMS BLOCKED frames.
Vladimir Homutov <vl@nginx.com>
parents:
8235
diff
changeset
|
1873 |
8266
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
1874 case NGX_QUIC_FT_STREAM_DATA_BLOCKED: |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
1875 |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
1876 if (ngx_quic_handle_stream_data_blocked_frame(c, pkt, |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
1877 &frame.u.stream_data_blocked) |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
1878 != NGX_OK) |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
1879 { |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
1880 return NGX_ERROR; |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
1881 } |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
1882 |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
1883 break; |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
1884 |
8365
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
1885 case NGX_QUIC_FT_MAX_STREAM_DATA: |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
1886 |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
1887 if (ngx_quic_handle_max_stream_data_frame(c, pkt, |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
1888 &frame.u.max_stream_data) |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
1889 != NGX_OK) |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
1890 { |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
1891 return NGX_ERROR; |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
1892 } |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
1893 |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
1894 break; |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
1895 |
8325
9b9d592c0da3
Ignore non-yet-implemented frames.
Vladimir Homutov <vl@nginx.com>
parents:
8322
diff
changeset
|
1896 case NGX_QUIC_FT_NEW_CONNECTION_ID: |
9b9d592c0da3
Ignore non-yet-implemented frames.
Vladimir Homutov <vl@nginx.com>
parents:
8322
diff
changeset
|
1897 case NGX_QUIC_FT_RETIRE_CONNECTION_ID: |
9b9d592c0da3
Ignore non-yet-implemented frames.
Vladimir Homutov <vl@nginx.com>
parents:
8322
diff
changeset
|
1898 case NGX_QUIC_FT_NEW_TOKEN: |
9b9d592c0da3
Ignore non-yet-implemented frames.
Vladimir Homutov <vl@nginx.com>
parents:
8322
diff
changeset
|
1899 case NGX_QUIC_FT_RESET_STREAM: |
9b9d592c0da3
Ignore non-yet-implemented frames.
Vladimir Homutov <vl@nginx.com>
parents:
8322
diff
changeset
|
1900 case NGX_QUIC_FT_STOP_SENDING: |
9b9d592c0da3
Ignore non-yet-implemented frames.
Vladimir Homutov <vl@nginx.com>
parents:
8322
diff
changeset
|
1901 case NGX_QUIC_FT_PATH_CHALLENGE: |
9b9d592c0da3
Ignore non-yet-implemented frames.
Vladimir Homutov <vl@nginx.com>
parents:
8322
diff
changeset
|
1902 case NGX_QUIC_FT_PATH_RESPONSE: |
9b9d592c0da3
Ignore non-yet-implemented frames.
Vladimir Homutov <vl@nginx.com>
parents:
8322
diff
changeset
|
1903 |
9b9d592c0da3
Ignore non-yet-implemented frames.
Vladimir Homutov <vl@nginx.com>
parents:
8322
diff
changeset
|
1904 /* TODO: handle */ |
9b9d592c0da3
Ignore non-yet-implemented frames.
Vladimir Homutov <vl@nginx.com>
parents:
8322
diff
changeset
|
1905 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, |
8359 | 1906 "quic frame handler not implemented"); |
8325
9b9d592c0da3
Ignore non-yet-implemented frames.
Vladimir Homutov <vl@nginx.com>
parents:
8322
diff
changeset
|
1907 break; |
9b9d592c0da3
Ignore non-yet-implemented frames.
Vladimir Homutov <vl@nginx.com>
parents:
8322
diff
changeset
|
1908 |
8225 | 1909 default: |
8346
4e4485793418
Added MAX_STREAM_DATA stub handler.
Vladimir Homutov <vl@nginx.com>
parents:
8345
diff
changeset
|
1910 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, |
8359 | 1911 "quic missing frame handler"); |
8225 | 1912 return NGX_ERROR; |
1913 } | |
1914 } | |
1915 | |
1916 if (p != end) { | |
1917 ngx_log_error(NGX_LOG_INFO, c->log, 0, | |
8361 | 1918 "quic trailing garbage in payload: %ui bytes", end - p); |
8385
fb7422074258
Added generation of CC frames with error on connection termination.
Vladimir Homutov <vl@nginx.com>
parents:
8384
diff
changeset
|
1919 |
fb7422074258
Added generation of CC frames with error on connection termination.
Vladimir Homutov <vl@nginx.com>
parents:
8384
diff
changeset
|
1920 qc->error = NGX_QUIC_ERR_FRAME_ENCODING_ERROR; |
8225 | 1921 return NGX_ERROR; |
1922 } | |
1923 | |
1924 if (do_close) { | |
8355
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1925 qc->draining = 1; |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1926 ngx_quic_close_connection(c, NGX_OK); |
8225 | 1927 } |
1928 | |
8367
c10e7d48aa85
Factored out sending ACK from payload handler.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8365
diff
changeset
|
1929 return NGX_OK; |
c10e7d48aa85
Factored out sending ACK from payload handler.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8365
diff
changeset
|
1930 } |
c10e7d48aa85
Factored out sending ACK from payload handler.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8365
diff
changeset
|
1931 |
c10e7d48aa85
Factored out sending ACK from payload handler.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8365
diff
changeset
|
1932 |
c10e7d48aa85
Factored out sending ACK from payload handler.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8365
diff
changeset
|
1933 static ngx_int_t |
c10e7d48aa85
Factored out sending ACK from payload handler.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8365
diff
changeset
|
1934 ngx_quic_send_ack(ngx_connection_t *c, ngx_quic_header_t *pkt) |
c10e7d48aa85
Factored out sending ACK from payload handler.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8365
diff
changeset
|
1935 { |
c10e7d48aa85
Factored out sending ACK from payload handler.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8365
diff
changeset
|
1936 ngx_quic_frame_t *frame; |
8225 | 1937 |
8275 | 1938 c->log->action = "generating acknowledgment"; |
1939 | |
8367
c10e7d48aa85
Factored out sending ACK from payload handler.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8365
diff
changeset
|
1940 /* every ACK-eliciting packet is acknowledged, TODO ACK Ranges */ |
c10e7d48aa85
Factored out sending ACK from payload handler.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8365
diff
changeset
|
1941 |
c10e7d48aa85
Factored out sending ACK from payload handler.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8365
diff
changeset
|
1942 frame = ngx_quic_alloc_frame(c, 0); |
c10e7d48aa85
Factored out sending ACK from payload handler.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8365
diff
changeset
|
1943 if (frame == NULL) { |
8225 | 1944 return NGX_ERROR; |
1945 } | |
1946 | |
8367
c10e7d48aa85
Factored out sending ACK from payload handler.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8365
diff
changeset
|
1947 frame->level = (pkt->level == ssl_encryption_early_data) |
c10e7d48aa85
Factored out sending ACK from payload handler.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8365
diff
changeset
|
1948 ? ssl_encryption_application |
c10e7d48aa85
Factored out sending ACK from payload handler.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8365
diff
changeset
|
1949 : pkt->level; |
c10e7d48aa85
Factored out sending ACK from payload handler.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8365
diff
changeset
|
1950 |
c10e7d48aa85
Factored out sending ACK from payload handler.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8365
diff
changeset
|
1951 frame->type = NGX_QUIC_FT_ACK; |
c10e7d48aa85
Factored out sending ACK from payload handler.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8365
diff
changeset
|
1952 frame->u.ack.largest = pkt->pn; |
c10e7d48aa85
Factored out sending ACK from payload handler.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8365
diff
changeset
|
1953 |
c10e7d48aa85
Factored out sending ACK from payload handler.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8365
diff
changeset
|
1954 ngx_sprintf(frame->info, "ACK for PN=%d from frame handler level=%d", |
c10e7d48aa85
Factored out sending ACK from payload handler.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8365
diff
changeset
|
1955 pkt->pn, frame->level); |
c10e7d48aa85
Factored out sending ACK from payload handler.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8365
diff
changeset
|
1956 ngx_quic_queue_frame(c->quic, frame); |
8225 | 1957 |
8309 | 1958 return NGX_OK; |
8225 | 1959 } |
1960 | |
1961 | |
1962 static ngx_int_t | |
8355
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1963 ngx_quic_send_cc(ngx_connection_t *c, enum ssl_encryption_level_t level, |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1964 ngx_uint_t err) |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1965 { |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1966 ngx_quic_frame_t *frame; |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1967 ngx_quic_connection_t *qc; |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1968 |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1969 qc = c->quic; |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1970 |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1971 if (qc->draining) { |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1972 return NGX_OK; |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1973 } |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1974 |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1975 if (qc->closing |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1976 && ngx_current_msec - qc->last_cc < NGX_QUIC_CC_MIN_INTERVAL) |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1977 { |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1978 /* dot not send CC too often */ |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1979 return NGX_OK; |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1980 } |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1981 |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1982 frame = ngx_quic_alloc_frame(c, 0); |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1983 if (frame == NULL) { |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1984 return NGX_ERROR; |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1985 } |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1986 |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1987 frame->level = level; |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1988 frame->type = NGX_QUIC_FT_CONNECTION_CLOSE; |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1989 frame->u.close.error_code = err; |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1990 ngx_sprintf(frame->info, "cc from send_cc err=%ui level=%d", err, |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1991 frame->level); |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1992 |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1993 ngx_quic_queue_frame(c->quic, frame); |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1994 |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1995 qc->last_cc = ngx_current_msec; |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1996 |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1997 return ngx_quic_output(c); |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1998 } |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
1999 |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
2000 |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
2001 static ngx_int_t |
8384
52d0c4832570
Address validation using NEW_TOKEN frame.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8383
diff
changeset
|
2002 ngx_quic_send_new_token(ngx_connection_t *c) |
52d0c4832570
Address validation using NEW_TOKEN frame.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8383
diff
changeset
|
2003 { |
52d0c4832570
Address validation using NEW_TOKEN frame.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8383
diff
changeset
|
2004 ngx_str_t token; |
52d0c4832570
Address validation using NEW_TOKEN frame.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8383
diff
changeset
|
2005 ngx_quic_frame_t *frame; |
52d0c4832570
Address validation using NEW_TOKEN frame.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8383
diff
changeset
|
2006 |
52d0c4832570
Address validation using NEW_TOKEN frame.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8383
diff
changeset
|
2007 if (!c->quic->tp.retry) { |
52d0c4832570
Address validation using NEW_TOKEN frame.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8383
diff
changeset
|
2008 return NGX_OK; |
52d0c4832570
Address validation using NEW_TOKEN frame.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8383
diff
changeset
|
2009 } |
52d0c4832570
Address validation using NEW_TOKEN frame.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8383
diff
changeset
|
2010 |
52d0c4832570
Address validation using NEW_TOKEN frame.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8383
diff
changeset
|
2011 if (ngx_quic_new_token(c, &token) != NGX_OK) { |
52d0c4832570
Address validation using NEW_TOKEN frame.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8383
diff
changeset
|
2012 return NGX_ERROR; |
52d0c4832570
Address validation using NEW_TOKEN frame.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8383
diff
changeset
|
2013 } |
52d0c4832570
Address validation using NEW_TOKEN frame.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8383
diff
changeset
|
2014 |
52d0c4832570
Address validation using NEW_TOKEN frame.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8383
diff
changeset
|
2015 frame = ngx_quic_alloc_frame(c, 0); |
52d0c4832570
Address validation using NEW_TOKEN frame.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8383
diff
changeset
|
2016 if (frame == NULL) { |
52d0c4832570
Address validation using NEW_TOKEN frame.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8383
diff
changeset
|
2017 return NGX_ERROR; |
52d0c4832570
Address validation using NEW_TOKEN frame.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8383
diff
changeset
|
2018 } |
52d0c4832570
Address validation using NEW_TOKEN frame.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8383
diff
changeset
|
2019 |
52d0c4832570
Address validation using NEW_TOKEN frame.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8383
diff
changeset
|
2020 frame->level = ssl_encryption_application; |
52d0c4832570
Address validation using NEW_TOKEN frame.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8383
diff
changeset
|
2021 frame->type = NGX_QUIC_FT_NEW_TOKEN; |
52d0c4832570
Address validation using NEW_TOKEN frame.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8383
diff
changeset
|
2022 frame->u.token.length = token.len; |
52d0c4832570
Address validation using NEW_TOKEN frame.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8383
diff
changeset
|
2023 frame->u.token.data = token.data; |
52d0c4832570
Address validation using NEW_TOKEN frame.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8383
diff
changeset
|
2024 ngx_sprintf(frame->info, "NEW_TOKEN"); |
52d0c4832570
Address validation using NEW_TOKEN frame.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8383
diff
changeset
|
2025 ngx_quic_queue_frame(c->quic, frame); |
52d0c4832570
Address validation using NEW_TOKEN frame.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8383
diff
changeset
|
2026 |
52d0c4832570
Address validation using NEW_TOKEN frame.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8383
diff
changeset
|
2027 return NGX_OK; |
52d0c4832570
Address validation using NEW_TOKEN frame.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8383
diff
changeset
|
2028 } |
52d0c4832570
Address validation using NEW_TOKEN frame.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8383
diff
changeset
|
2029 |
52d0c4832570
Address validation using NEW_TOKEN frame.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8383
diff
changeset
|
2030 static ngx_int_t |
8225 | 2031 ngx_quic_handle_ack_frame(ngx_connection_t *c, ngx_quic_header_t *pkt, |
8308
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2032 ngx_quic_ack_frame_t *ack) |
8225 | 2033 { |
8331
bda817d16cc2
Rename types and variables used for packet number space.
Vladimir Homutov <vl@nginx.com>
parents:
8328
diff
changeset
|
2034 ssize_t n; |
bda817d16cc2
Rename types and variables used for packet number space.
Vladimir Homutov <vl@nginx.com>
parents:
8328
diff
changeset
|
2035 u_char *pos, *end; |
bda817d16cc2
Rename types and variables used for packet number space.
Vladimir Homutov <vl@nginx.com>
parents:
8328
diff
changeset
|
2036 uint64_t gap, range; |
bda817d16cc2
Rename types and variables used for packet number space.
Vladimir Homutov <vl@nginx.com>
parents:
8328
diff
changeset
|
2037 ngx_uint_t i, min, max; |
bda817d16cc2
Rename types and variables used for packet number space.
Vladimir Homutov <vl@nginx.com>
parents:
8328
diff
changeset
|
2038 ngx_quic_send_ctx_t *ctx; |
bda817d16cc2
Rename types and variables used for packet number space.
Vladimir Homutov <vl@nginx.com>
parents:
8328
diff
changeset
|
2039 |
bda817d16cc2
Rename types and variables used for packet number space.
Vladimir Homutov <vl@nginx.com>
parents:
8328
diff
changeset
|
2040 ctx = ngx_quic_get_send_ctx(c->quic, pkt->level); |
8308
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2041 |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2042 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, |
8359 | 2043 "quic ngx_quic_handle_ack_frame level %d", pkt->level); |
8308
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2044 |
8326 | 2045 /* |
8385
fb7422074258
Added generation of CC frames with error on connection termination.
Vladimir Homutov <vl@nginx.com>
parents:
8384
diff
changeset
|
2046 * If any computed packet number is negative, an endpoint MUST |
fb7422074258
Added generation of CC frames with error on connection termination.
Vladimir Homutov <vl@nginx.com>
parents:
8384
diff
changeset
|
2047 * generate a connection error of type FRAME_ENCODING_ERROR. |
fb7422074258
Added generation of CC frames with error on connection termination.
Vladimir Homutov <vl@nginx.com>
parents:
8384
diff
changeset
|
2048 * (19.3.1) |
8326 | 2049 */ |
2050 | |
8308
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2051 if (ack->first_range > ack->largest) { |
8385
fb7422074258
Added generation of CC frames with error on connection termination.
Vladimir Homutov <vl@nginx.com>
parents:
8384
diff
changeset
|
2052 c->quic->error = NGX_QUIC_ERR_FRAME_ENCODING_ERROR; |
8308
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2053 ngx_log_error(NGX_LOG_INFO, c->log, 0, |
8361 | 2054 "quic invalid first range in ack frame"); |
8308
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2055 return NGX_ERROR; |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2056 } |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2057 |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2058 min = ack->largest - ack->first_range; |
8326 | 2059 max = ack->largest; |
2060 | |
8331
bda817d16cc2
Rename types and variables used for packet number space.
Vladimir Homutov <vl@nginx.com>
parents:
8328
diff
changeset
|
2061 if (ngx_quic_handle_ack_frame_range(c, ctx, min, max) != NGX_OK) { |
8326 | 2062 return NGX_ERROR; |
2063 } | |
2064 | |
2065 /* 13.2.3. Receiver Tracking of ACK Frames */ | |
8331
bda817d16cc2
Rename types and variables used for packet number space.
Vladimir Homutov <vl@nginx.com>
parents:
8328
diff
changeset
|
2066 if (ctx->largest_ack < max) { |
bda817d16cc2
Rename types and variables used for packet number space.
Vladimir Homutov <vl@nginx.com>
parents:
8328
diff
changeset
|
2067 ctx->largest_ack = max; |
8326 | 2068 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, |
8359 | 2069 "quic updated largest received ack: %ui", max); |
8326 | 2070 } |
2071 | |
2072 pos = ack->ranges_start; | |
2073 end = ack->ranges_end; | |
2074 | |
2075 for (i = 0; i < ack->range_count; i++) { | |
2076 | |
2077 n = ngx_quic_parse_ack_range(pkt, pos, end, &gap, &range); | |
2078 if (n == NGX_ERROR) { | |
2079 return NGX_ERROR; | |
2080 } | |
2081 pos += n; | |
2082 | |
2083 if (gap >= min) { | |
8385
fb7422074258
Added generation of CC frames with error on connection termination.
Vladimir Homutov <vl@nginx.com>
parents:
8384
diff
changeset
|
2084 c->quic->error = NGX_QUIC_ERR_FRAME_ENCODING_ERROR; |
8326 | 2085 ngx_log_error(NGX_LOG_INFO, c->log, 0, |
8361 | 2086 "quic invalid range %ui in ack frame", i); |
8326 | 2087 return NGX_ERROR; |
2088 } | |
2089 | |
2090 max = min - 1 - gap; | |
2091 | |
2092 if (range > max + 1) { | |
8385
fb7422074258
Added generation of CC frames with error on connection termination.
Vladimir Homutov <vl@nginx.com>
parents:
8384
diff
changeset
|
2093 c->quic->error = NGX_QUIC_ERR_FRAME_ENCODING_ERROR; |
8326 | 2094 ngx_log_error(NGX_LOG_INFO, c->log, 0, |
8361 | 2095 "quic invalid range %ui in ack frame", i); |
8326 | 2096 return NGX_ERROR; |
2097 } | |
2098 | |
2099 min = max - range + 1; | |
2100 | |
8331
bda817d16cc2
Rename types and variables used for packet number space.
Vladimir Homutov <vl@nginx.com>
parents:
8328
diff
changeset
|
2101 if (ngx_quic_handle_ack_frame_range(c, ctx, min, max) != NGX_OK) { |
8326 | 2102 return NGX_ERROR; |
2103 } | |
2104 } | |
2105 | |
2106 return NGX_OK; | |
2107 } | |
2108 | |
2109 | |
2110 static ngx_int_t | |
8331
bda817d16cc2
Rename types and variables used for packet number space.
Vladimir Homutov <vl@nginx.com>
parents:
8328
diff
changeset
|
2111 ngx_quic_handle_ack_frame_range(ngx_connection_t *c, ngx_quic_send_ctx_t *ctx, |
8326 | 2112 uint64_t min, uint64_t max) |
2113 { | |
8364
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
2114 ngx_uint_t found; |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
2115 ngx_queue_t *q; |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
2116 ngx_quic_frame_t *f; |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
2117 ngx_quic_connection_t *qc; |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
2118 |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
2119 qc = c->quic; |
8308
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2120 |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2121 found = 0; |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2122 |
8331
bda817d16cc2
Rename types and variables used for packet number space.
Vladimir Homutov <vl@nginx.com>
parents:
8328
diff
changeset
|
2123 q = ngx_queue_head(&ctx->sent); |
bda817d16cc2
Rename types and variables used for packet number space.
Vladimir Homutov <vl@nginx.com>
parents:
8328
diff
changeset
|
2124 |
bda817d16cc2
Rename types and variables used for packet number space.
Vladimir Homutov <vl@nginx.com>
parents:
8328
diff
changeset
|
2125 while (q != ngx_queue_sentinel(&ctx->sent)) { |
8308
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2126 |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2127 f = ngx_queue_data(q, ngx_quic_frame_t, queue); |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2128 |
8326 | 2129 if (f->pnum >= min && f->pnum <= max) { |
8364
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
2130 ngx_quic_congestion_ack(c, f); |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
2131 |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
2132 ngx_quic_handle_stream_ack(c, f); |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
2133 |
8308
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2134 q = ngx_queue_next(q); |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2135 ngx_queue_remove(&f->queue); |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2136 ngx_quic_free_frame(c, f); |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2137 found = 1; |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2138 |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2139 } else { |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2140 q = ngx_queue_next(q); |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2141 } |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2142 } |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2143 |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2144 if (!found) { |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2145 |
8331
bda817d16cc2
Rename types and variables used for packet number space.
Vladimir Homutov <vl@nginx.com>
parents:
8328
diff
changeset
|
2146 if (max <= ctx->pnum) { |
8308
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2147 /* duplicate ACK or ACK for non-ack-eliciting frame */ |
8326 | 2148 return NGX_OK; |
8308
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2149 } |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2150 |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2151 ngx_log_error(NGX_LOG_INFO, c->log, 0, |
8361 | 2152 "quic ACK for the packet not in sent queue "); |
8385
fb7422074258
Added generation of CC frames with error on connection termination.
Vladimir Homutov <vl@nginx.com>
parents:
8384
diff
changeset
|
2153 |
fb7422074258
Added generation of CC frames with error on connection termination.
Vladimir Homutov <vl@nginx.com>
parents:
8384
diff
changeset
|
2154 qc->error = NGX_QUIC_ERR_PROTOCOL_VIOLATION; |
fb7422074258
Added generation of CC frames with error on connection termination.
Vladimir Homutov <vl@nginx.com>
parents:
8384
diff
changeset
|
2155 |
8308
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2156 return NGX_ERROR; |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2157 } |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2158 |
8364
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
2159 if (!qc->push.timer_set) { |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
2160 ngx_post_event(&qc->push, &ngx_posted_events); |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
2161 } |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
2162 |
8225 | 2163 return NGX_OK; |
2164 } | |
2165 | |
2166 | |
8364
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
2167 static void |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
2168 ngx_quic_handle_stream_ack(ngx_connection_t *c, ngx_quic_frame_t *f) |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
2169 { |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
2170 uint64_t sent, unacked; |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
2171 ngx_event_t *wev; |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
2172 ngx_quic_stream_t *sn; |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
2173 ngx_quic_connection_t *qc; |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
2174 |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
2175 if (f->type < NGX_QUIC_FT_STREAM0 || f->type > NGX_QUIC_FT_STREAM7) { |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
2176 return; |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
2177 } |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
2178 |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
2179 qc = c->quic; |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
2180 |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
2181 sn = ngx_quic_find_stream(&qc->streams.tree, f->u.stream.stream_id); |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
2182 if (sn == NULL) { |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
2183 return; |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
2184 } |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
2185 |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
2186 wev = sn->c->write; |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
2187 sent = sn->c->sent; |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
2188 unacked = sent - sn->acked; |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
2189 |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
2190 if (unacked >= NGX_QUIC_STREAM_BUFSIZE && wev->active) { |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
2191 wev->ready = 1; |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
2192 ngx_post_event(wev, &ngx_posted_events); |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
2193 } |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
2194 |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
2195 sn->acked += f->u.stream.length; |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
2196 |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
2197 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, sn->c->log, 0, |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
2198 "quic stream ack %uL acked:%uL, unacked:%uL", |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
2199 f->u.stream.length, sn->acked, sent - sn->acked); |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
2200 } |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
2201 |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
2202 |
8225 | 2203 static ngx_int_t |
8333
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2204 ngx_quic_handle_ordered_frame(ngx_connection_t *c, ngx_quic_frames_stream_t *fs, |
8378
81a4f98a2556
Cleaned up reordering code.
Vladimir Homutov <vl@nginx.com>
parents:
8377
diff
changeset
|
2205 ngx_quic_frame_t *frame, ngx_quic_frame_handler_pt handler, void *data) |
8333
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2206 { |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2207 size_t full_len; |
8334
72d20158c814
Added reordering support for STREAM frames.
Vladimir Homutov <vl@nginx.com>
parents:
8333
diff
changeset
|
2208 ngx_int_t rc; |
8333
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2209 ngx_queue_t *q; |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2210 ngx_quic_ordered_frame_t *f; |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2211 |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2212 f = &frame->u.ord; |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2213 |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2214 if (f->offset > fs->received) { |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2215 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, |
8359 | 2216 "quic out-of-order frame: expecting %ui got %ui", |
8333
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2217 fs->received, f->offset); |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2218 |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2219 return ngx_quic_buffer_frame(c, fs, frame); |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2220 } |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2221 |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2222 if (f->offset < fs->received) { |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2223 |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2224 if (ngx_quic_adjust_frame_offset(c, frame, fs->received) |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2225 == NGX_DONE) |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2226 { |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2227 /* old/duplicate data range */ |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2228 return NGX_OK; |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2229 } |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2230 |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2231 /* intersecting data range, frame modified */ |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2232 } |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2233 |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2234 /* f->offset == fs->received */ |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2235 |
8378
81a4f98a2556
Cleaned up reordering code.
Vladimir Homutov <vl@nginx.com>
parents:
8377
diff
changeset
|
2236 rc = handler(c, frame, data); |
8334
72d20158c814
Added reordering support for STREAM frames.
Vladimir Homutov <vl@nginx.com>
parents:
8333
diff
changeset
|
2237 if (rc == NGX_ERROR) { |
8225 | 2238 return NGX_ERROR; |
8334
72d20158c814
Added reordering support for STREAM frames.
Vladimir Homutov <vl@nginx.com>
parents:
8333
diff
changeset
|
2239 |
72d20158c814
Added reordering support for STREAM frames.
Vladimir Homutov <vl@nginx.com>
parents:
8333
diff
changeset
|
2240 } else if (rc == NGX_DONE) { |
72d20158c814
Added reordering support for STREAM frames.
Vladimir Homutov <vl@nginx.com>
parents:
8333
diff
changeset
|
2241 /* handler destroyed stream, queue no longer exists */ |
72d20158c814
Added reordering support for STREAM frames.
Vladimir Homutov <vl@nginx.com>
parents:
8333
diff
changeset
|
2242 return NGX_OK; |
8225 | 2243 } |
2244 | |
8334
72d20158c814
Added reordering support for STREAM frames.
Vladimir Homutov <vl@nginx.com>
parents:
8333
diff
changeset
|
2245 /* rc == NGX_OK */ |
72d20158c814
Added reordering support for STREAM frames.
Vladimir Homutov <vl@nginx.com>
parents:
8333
diff
changeset
|
2246 |
8333
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2247 fs->received += f->length; |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2248 |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2249 /* now check the queue if we can continue with buffered frames */ |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2250 |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2251 do { |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2252 q = ngx_queue_head(&fs->frames); |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2253 if (q == ngx_queue_sentinel(&fs->frames)) { |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2254 break; |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2255 } |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2256 |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2257 frame = ngx_queue_data(q, ngx_quic_frame_t, queue); |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2258 f = &frame->u.ord; |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2259 |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2260 if (f->offset > fs->received) { |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2261 /* gap found, nothing more to do */ |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2262 break; |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2263 } |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2264 |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2265 full_len = f->length; |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2266 |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2267 if (f->offset < fs->received) { |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2268 |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2269 if (ngx_quic_adjust_frame_offset(c, frame, fs->received) |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2270 == NGX_DONE) |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2271 { |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2272 /* old/duplicate data range */ |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2273 ngx_queue_remove(q); |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2274 fs->total -= f->length; |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2275 |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2276 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, |
8359 | 2277 "quic skipped buffered frame, total %ui", |
2278 fs->total); | |
8333
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2279 ngx_quic_free_frame(c, frame); |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2280 continue; |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2281 } |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2282 |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2283 /* frame was adjusted, proceed to input */ |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2284 } |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2285 |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2286 /* f->offset == fs->received */ |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2287 |
8378
81a4f98a2556
Cleaned up reordering code.
Vladimir Homutov <vl@nginx.com>
parents:
8377
diff
changeset
|
2288 rc = handler(c, frame, data); |
8334
72d20158c814
Added reordering support for STREAM frames.
Vladimir Homutov <vl@nginx.com>
parents:
8333
diff
changeset
|
2289 |
72d20158c814
Added reordering support for STREAM frames.
Vladimir Homutov <vl@nginx.com>
parents:
8333
diff
changeset
|
2290 if (rc == NGX_ERROR) { |
8333
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2291 return NGX_ERROR; |
8334
72d20158c814
Added reordering support for STREAM frames.
Vladimir Homutov <vl@nginx.com>
parents:
8333
diff
changeset
|
2292 |
72d20158c814
Added reordering support for STREAM frames.
Vladimir Homutov <vl@nginx.com>
parents:
8333
diff
changeset
|
2293 } else if (rc == NGX_DONE) { |
72d20158c814
Added reordering support for STREAM frames.
Vladimir Homutov <vl@nginx.com>
parents:
8333
diff
changeset
|
2294 /* handler destroyed stream, queue no longer exists */ |
72d20158c814
Added reordering support for STREAM frames.
Vladimir Homutov <vl@nginx.com>
parents:
8333
diff
changeset
|
2295 return NGX_OK; |
8333
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2296 } |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2297 |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2298 fs->received += f->length; |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2299 fs->total -= full_len; |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2300 |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2301 ngx_queue_remove(q); |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2302 |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2303 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, |
8359 | 2304 "quic consumed buffered frame, total %ui", fs->total); |
8333
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2305 |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2306 ngx_quic_free_frame(c, frame); |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2307 |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2308 } while (1); |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2309 |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2310 return NGX_OK; |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2311 } |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2312 |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2313 |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2314 static ngx_int_t |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2315 ngx_quic_adjust_frame_offset(ngx_connection_t *c, ngx_quic_frame_t *frame, |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2316 uint64_t offset_in) |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2317 { |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2318 size_t tail; |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2319 ngx_quic_ordered_frame_t *f; |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2320 |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2321 f = &frame->u.ord; |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2322 |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2323 tail = offset_in - f->offset; |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2324 |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2325 if (tail >= f->length) { |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2326 /* range preceeding already received data or duplicate, ignore */ |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2327 |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2328 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, |
8359 | 2329 "quic old or duplicate data in ordered frame, ignored"); |
8333
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2330 return NGX_DONE; |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2331 } |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2332 |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2333 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, |
8359 | 2334 "quic adjusted ordered frame data start to expected offset"); |
8333
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2335 |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2336 /* intersecting range: adjust data size */ |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2337 |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2338 f->offset += tail; |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2339 f->data += tail; |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2340 f->length -= tail; |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2341 |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2342 return NGX_OK; |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2343 } |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2344 |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2345 |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2346 static ngx_int_t |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2347 ngx_quic_buffer_frame(ngx_connection_t *c, ngx_quic_frames_stream_t *fs, |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2348 ngx_quic_frame_t *frame) |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2349 { |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2350 u_char *data; |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2351 ngx_queue_t *q; |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2352 ngx_quic_frame_t *dst, *item; |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2353 ngx_quic_ordered_frame_t *f, *df; |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2354 |
8359 | 2355 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, |
2356 "quic ngx_quic_buffer_frame"); | |
8333
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2357 |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2358 f = &frame->u.ord; |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2359 |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2360 /* frame start offset is in the future, buffer it */ |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2361 |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2362 /* check limit on total size used by all buffered frames, not actual data */ |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2363 if (NGX_QUIC_MAX_BUFFERED - fs->total < f->length) { |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2364 ngx_log_error(NGX_LOG_INFO, c->log, 0, |
8361 | 2365 "quic ordered input buffer limit exceeded"); |
8333
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2366 return NGX_ERROR; |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2367 } |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2368 |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2369 dst = ngx_quic_alloc_frame(c, f->length); |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2370 if (dst == NULL) { |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2371 return NGX_ERROR; |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2372 } |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2373 |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2374 data = dst->data; |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2375 ngx_memcpy(dst, frame, sizeof(ngx_quic_frame_t)); |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2376 dst->data = data; |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2377 |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2378 ngx_memcpy(dst->data, f->data, f->length); |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2379 |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2380 df = &dst->u.ord; |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2381 df->data = dst->data; |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2382 |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2383 fs->total += f->length; |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2384 |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2385 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, |
8359 | 2386 "quic ordered frame with unexpected offset:" |
2387 " buffered, total %ui", fs->total); | |
8333
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2388 |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2389 /* TODO: do we need some timeout for this queue ? */ |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2390 |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2391 if (ngx_queue_empty(&fs->frames)) { |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2392 ngx_queue_insert_after(&fs->frames, &dst->queue); |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2393 return NGX_OK; |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2394 } |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2395 |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2396 for (q = ngx_queue_last(&fs->frames); |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2397 q != ngx_queue_sentinel(&fs->frames); |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2398 q = ngx_queue_prev(q)) |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2399 { |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2400 item = ngx_queue_data(q, ngx_quic_frame_t, queue); |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2401 f = &item->u.ord; |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2402 |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2403 if (f->offset < df->offset) { |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2404 ngx_queue_insert_after(q, &dst->queue); |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2405 return NGX_OK; |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2406 } |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2407 } |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2408 |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2409 ngx_queue_insert_after(&fs->frames, &dst->queue); |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2410 |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2411 return NGX_OK; |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2412 } |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2413 |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2414 |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2415 static ngx_int_t |
8335
76839f55bc48
Sorted functions and functions declarations.
Vladimir Homutov <vl@nginx.com>
parents:
8334
diff
changeset
|
2416 ngx_quic_handle_crypto_frame(ngx_connection_t *c, ngx_quic_header_t *pkt, |
76839f55bc48
Sorted functions and functions declarations.
Vladimir Homutov <vl@nginx.com>
parents:
8334
diff
changeset
|
2417 ngx_quic_frame_t *frame) |
76839f55bc48
Sorted functions and functions declarations.
Vladimir Homutov <vl@nginx.com>
parents:
8334
diff
changeset
|
2418 { |
76839f55bc48
Sorted functions and functions declarations.
Vladimir Homutov <vl@nginx.com>
parents:
8334
diff
changeset
|
2419 ngx_quic_connection_t *qc; |
76839f55bc48
Sorted functions and functions declarations.
Vladimir Homutov <vl@nginx.com>
parents:
8334
diff
changeset
|
2420 ngx_quic_frames_stream_t *fs; |
76839f55bc48
Sorted functions and functions declarations.
Vladimir Homutov <vl@nginx.com>
parents:
8334
diff
changeset
|
2421 |
76839f55bc48
Sorted functions and functions declarations.
Vladimir Homutov <vl@nginx.com>
parents:
8334
diff
changeset
|
2422 qc = c->quic; |
76839f55bc48
Sorted functions and functions declarations.
Vladimir Homutov <vl@nginx.com>
parents:
8334
diff
changeset
|
2423 fs = &qc->crypto[pkt->level]; |
76839f55bc48
Sorted functions and functions declarations.
Vladimir Homutov <vl@nginx.com>
parents:
8334
diff
changeset
|
2424 |
8378
81a4f98a2556
Cleaned up reordering code.
Vladimir Homutov <vl@nginx.com>
parents:
8377
diff
changeset
|
2425 return ngx_quic_handle_ordered_frame(c, fs, frame, ngx_quic_crypto_input, |
81a4f98a2556
Cleaned up reordering code.
Vladimir Homutov <vl@nginx.com>
parents:
8377
diff
changeset
|
2426 NULL); |
8335
76839f55bc48
Sorted functions and functions declarations.
Vladimir Homutov <vl@nginx.com>
parents:
8334
diff
changeset
|
2427 } |
76839f55bc48
Sorted functions and functions declarations.
Vladimir Homutov <vl@nginx.com>
parents:
8334
diff
changeset
|
2428 |
76839f55bc48
Sorted functions and functions declarations.
Vladimir Homutov <vl@nginx.com>
parents:
8334
diff
changeset
|
2429 |
76839f55bc48
Sorted functions and functions declarations.
Vladimir Homutov <vl@nginx.com>
parents:
8334
diff
changeset
|
2430 static ngx_int_t |
8378
81a4f98a2556
Cleaned up reordering code.
Vladimir Homutov <vl@nginx.com>
parents:
8377
diff
changeset
|
2431 ngx_quic_crypto_input(ngx_connection_t *c, ngx_quic_frame_t *frame, void *data) |
8333
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2432 { |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2433 int sslerr; |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2434 ssize_t n; |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2435 ngx_ssl_conn_t *ssl_conn; |
8393
e169cce912c7
Avoid retransmitting of packets with discarded keys.
Vladimir Homutov <vl@nginx.com>
parents:
8392
diff
changeset
|
2436 ngx_quic_send_ctx_t *ctx; |
8333
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2437 ngx_quic_crypto_frame_t *f; |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2438 |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2439 f = &frame->u.crypto; |
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2440 |
8225 | 2441 ssl_conn = c->ssl->connection; |
2442 | |
2443 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
8359 | 2444 "quic SSL_quic_read_level: %d, SSL_quic_write_level: %d", |
8225 | 2445 (int) SSL_quic_read_level(ssl_conn), |
2446 (int) SSL_quic_write_level(ssl_conn)); | |
2447 | |
2448 if (!SSL_provide_quic_data(ssl_conn, SSL_quic_read_level(ssl_conn), | |
8333
167d32476737
Crypto buffer frames reordering.
Vladimir Homutov <vl@nginx.com>
parents:
8332
diff
changeset
|
2449 f->data, f->length)) |
8225 | 2450 { |
2451 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, | |
2452 "SSL_provide_quic_data() failed"); | |
2453 return NGX_ERROR; | |
2454 } | |
2455 | |
2456 n = SSL_do_handshake(ssl_conn); | |
2457 | |
2458 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_do_handshake: %d", n); | |
2459 | |
2460 if (n == -1) { | |
2461 sslerr = SSL_get_error(ssl_conn, n); | |
2462 | |
2463 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_get_error: %d", | |
2464 sslerr); | |
2465 | |
8300
23a2b5e7acc8
Improved SSL_do_handshake() error handling in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8299
diff
changeset
|
2466 if (sslerr != SSL_ERROR_WANT_READ) { |
8225 | 2467 ngx_ssl_error(NGX_LOG_ERR, c->log, 0, "SSL_do_handshake() failed"); |
8300
23a2b5e7acc8
Improved SSL_do_handshake() error handling in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8299
diff
changeset
|
2468 return NGX_ERROR; |
8225 | 2469 } |
8263
1295b293d09a
Connection states code cleanup.
Vladimir Homutov <vl@nginx.com>
parents:
8260
diff
changeset
|
2470 |
8302
76818c9cdd6f
Sending HANDSHAKE_DONE just once with BoringSSL.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8301
diff
changeset
|
2471 } else if (n == 1 && !SSL_in_init(ssl_conn)) { |
8397
1245e274b9ba
Avoided excessive definitions for connection state.
Vladimir Homutov <vl@nginx.com>
parents:
8394
diff
changeset
|
2472 c->quic->state = ssl_encryption_application; |
8225 | 2473 |
8263
1295b293d09a
Connection states code cleanup.
Vladimir Homutov <vl@nginx.com>
parents:
8260
diff
changeset
|
2474 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, |
8299 | 2475 "quic ssl cipher: %s", SSL_get_cipher(ssl_conn)); |
8225 | 2476 |
8263
1295b293d09a
Connection states code cleanup.
Vladimir Homutov <vl@nginx.com>
parents:
8260
diff
changeset
|
2477 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, |
8359 | 2478 "quic handshake completed successfully"); |
8273
cb75f194f1f0
Implemented sending HANDSHAKE_DONE frame after handshake.
Vladimir Homutov <vl@nginx.com>
parents:
8272
diff
changeset
|
2479 |
8286 | 2480 frame = ngx_quic_alloc_frame(c, 0); |
8273
cb75f194f1f0
Implemented sending HANDSHAKE_DONE frame after handshake.
Vladimir Homutov <vl@nginx.com>
parents:
8272
diff
changeset
|
2481 if (frame == NULL) { |
cb75f194f1f0
Implemented sending HANDSHAKE_DONE frame after handshake.
Vladimir Homutov <vl@nginx.com>
parents:
8272
diff
changeset
|
2482 return NGX_ERROR; |
cb75f194f1f0
Implemented sending HANDSHAKE_DONE frame after handshake.
Vladimir Homutov <vl@nginx.com>
parents:
8272
diff
changeset
|
2483 } |
cb75f194f1f0
Implemented sending HANDSHAKE_DONE frame after handshake.
Vladimir Homutov <vl@nginx.com>
parents:
8272
diff
changeset
|
2484 |
cb75f194f1f0
Implemented sending HANDSHAKE_DONE frame after handshake.
Vladimir Homutov <vl@nginx.com>
parents:
8272
diff
changeset
|
2485 /* 12.4 Frames and frame types, figure 8 */ |
cb75f194f1f0
Implemented sending HANDSHAKE_DONE frame after handshake.
Vladimir Homutov <vl@nginx.com>
parents:
8272
diff
changeset
|
2486 frame->level = ssl_encryption_application; |
cb75f194f1f0
Implemented sending HANDSHAKE_DONE frame after handshake.
Vladimir Homutov <vl@nginx.com>
parents:
8272
diff
changeset
|
2487 frame->type = NGX_QUIC_FT_HANDSHAKE_DONE; |
cb75f194f1f0
Implemented sending HANDSHAKE_DONE frame after handshake.
Vladimir Homutov <vl@nginx.com>
parents:
8272
diff
changeset
|
2488 ngx_sprintf(frame->info, "HANDSHAKE DONE on handshake completed"); |
cb75f194f1f0
Implemented sending HANDSHAKE_DONE frame after handshake.
Vladimir Homutov <vl@nginx.com>
parents:
8272
diff
changeset
|
2489 ngx_quic_queue_frame(c->quic, frame); |
8319
29354c6fc5f2
TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8316
diff
changeset
|
2490 |
8384
52d0c4832570
Address validation using NEW_TOKEN frame.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8383
diff
changeset
|
2491 if (ngx_quic_send_new_token(c) != NGX_OK) { |
52d0c4832570
Address validation using NEW_TOKEN frame.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8383
diff
changeset
|
2492 return NGX_ERROR; |
52d0c4832570
Address validation using NEW_TOKEN frame.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8383
diff
changeset
|
2493 } |
52d0c4832570
Address validation using NEW_TOKEN frame.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8383
diff
changeset
|
2494 |
8319
29354c6fc5f2
TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8316
diff
changeset
|
2495 /* |
29354c6fc5f2
TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8316
diff
changeset
|
2496 * Generating next keys before a key update is received. |
29354c6fc5f2
TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8316
diff
changeset
|
2497 * See quic-tls 9.4 Header Protection Timing Side-Channels. |
29354c6fc5f2
TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8316
diff
changeset
|
2498 */ |
29354c6fc5f2
TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8316
diff
changeset
|
2499 |
29354c6fc5f2
TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8316
diff
changeset
|
2500 if (ngx_quic_key_update(c, &c->quic->keys[ssl_encryption_application], |
29354c6fc5f2
TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8316
diff
changeset
|
2501 &c->quic->next_key) |
29354c6fc5f2
TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8316
diff
changeset
|
2502 != NGX_OK) |
29354c6fc5f2
TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8316
diff
changeset
|
2503 { |
29354c6fc5f2
TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8316
diff
changeset
|
2504 return NGX_ERROR; |
29354c6fc5f2
TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8316
diff
changeset
|
2505 } |
8393
e169cce912c7
Avoid retransmitting of packets with discarded keys.
Vladimir Homutov <vl@nginx.com>
parents:
8392
diff
changeset
|
2506 |
e169cce912c7
Avoid retransmitting of packets with discarded keys.
Vladimir Homutov <vl@nginx.com>
parents:
8392
diff
changeset
|
2507 /* |
e169cce912c7
Avoid retransmitting of packets with discarded keys.
Vladimir Homutov <vl@nginx.com>
parents:
8392
diff
changeset
|
2508 * 4.10.2 An endpoint MUST discard its handshake keys |
e169cce912c7
Avoid retransmitting of packets with discarded keys.
Vladimir Homutov <vl@nginx.com>
parents:
8392
diff
changeset
|
2509 * when the TLS handshake is confirmed |
e169cce912c7
Avoid retransmitting of packets with discarded keys.
Vladimir Homutov <vl@nginx.com>
parents:
8392
diff
changeset
|
2510 */ |
e169cce912c7
Avoid retransmitting of packets with discarded keys.
Vladimir Homutov <vl@nginx.com>
parents:
8392
diff
changeset
|
2511 ctx = ngx_quic_get_send_ctx(c->quic, ssl_encryption_handshake); |
e169cce912c7
Avoid retransmitting of packets with discarded keys.
Vladimir Homutov <vl@nginx.com>
parents:
8392
diff
changeset
|
2512 ngx_quic_free_frames(c, &ctx->sent); |
8263
1295b293d09a
Connection states code cleanup.
Vladimir Homutov <vl@nginx.com>
parents:
8260
diff
changeset
|
2513 } |
1295b293d09a
Connection states code cleanup.
Vladimir Homutov <vl@nginx.com>
parents:
8260
diff
changeset
|
2514 |
8225 | 2515 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, |
8359 | 2516 "quic SSL_quic_read_level: %d, SSL_quic_write_level: %d", |
8225 | 2517 (int) SSL_quic_read_level(ssl_conn), |
2518 (int) SSL_quic_write_level(ssl_conn)); | |
2519 | |
2520 return NGX_OK; | |
2521 } | |
2522 | |
2523 | |
2524 static ngx_int_t | |
8334
72d20158c814
Added reordering support for STREAM frames.
Vladimir Homutov <vl@nginx.com>
parents:
8333
diff
changeset
|
2525 ngx_quic_handle_stream_frame(ngx_connection_t *c, ngx_quic_header_t *pkt, |
72d20158c814
Added reordering support for STREAM frames.
Vladimir Homutov <vl@nginx.com>
parents:
8333
diff
changeset
|
2526 ngx_quic_frame_t *frame) |
8225 | 2527 { |
8337
ab443e80d9e4
Create new stream immediately on receiving new stream id.
Vladimir Homutov <vl@nginx.com>
parents:
8336
diff
changeset
|
2528 size_t n; |
8378
81a4f98a2556
Cleaned up reordering code.
Vladimir Homutov <vl@nginx.com>
parents:
8377
diff
changeset
|
2529 ngx_buf_t *b; |
81a4f98a2556
Cleaned up reordering code.
Vladimir Homutov <vl@nginx.com>
parents:
8377
diff
changeset
|
2530 ngx_event_t *rev; |
8334
72d20158c814
Added reordering support for STREAM frames.
Vladimir Homutov <vl@nginx.com>
parents:
8333
diff
changeset
|
2531 ngx_quic_stream_t *sn; |
72d20158c814
Added reordering support for STREAM frames.
Vladimir Homutov <vl@nginx.com>
parents:
8333
diff
changeset
|
2532 ngx_quic_connection_t *qc; |
72d20158c814
Added reordering support for STREAM frames.
Vladimir Homutov <vl@nginx.com>
parents:
8333
diff
changeset
|
2533 ngx_quic_stream_frame_t *f; |
72d20158c814
Added reordering support for STREAM frames.
Vladimir Homutov <vl@nginx.com>
parents:
8333
diff
changeset
|
2534 ngx_quic_frames_stream_t *fs; |
8225 | 2535 |
2536 qc = c->quic; | |
8334
72d20158c814
Added reordering support for STREAM frames.
Vladimir Homutov <vl@nginx.com>
parents:
8333
diff
changeset
|
2537 f = &frame->u.stream; |
8225 | 2538 |
2539 sn = ngx_quic_find_stream(&qc->streams.tree, f->stream_id); | |
2540 | |
8334
72d20158c814
Added reordering support for STREAM frames.
Vladimir Homutov <vl@nginx.com>
parents:
8333
diff
changeset
|
2541 if (sn == NULL) { |
8359 | 2542 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, |
2543 "quic stream id 0x%xi is new", f->stream_id); | |
8337
ab443e80d9e4
Create new stream immediately on receiving new stream id.
Vladimir Homutov <vl@nginx.com>
parents:
8336
diff
changeset
|
2544 |
ab443e80d9e4
Create new stream immediately on receiving new stream id.
Vladimir Homutov <vl@nginx.com>
parents:
8336
diff
changeset
|
2545 n = (f->stream_id & NGX_QUIC_STREAM_UNIDIRECTIONAL) |
ab443e80d9e4
Create new stream immediately on receiving new stream id.
Vladimir Homutov <vl@nginx.com>
parents:
8336
diff
changeset
|
2546 ? qc->tp.initial_max_stream_data_uni |
ab443e80d9e4
Create new stream immediately on receiving new stream id.
Vladimir Homutov <vl@nginx.com>
parents:
8336
diff
changeset
|
2547 : qc->tp.initial_max_stream_data_bidi_remote; |
ab443e80d9e4
Create new stream immediately on receiving new stream id.
Vladimir Homutov <vl@nginx.com>
parents:
8336
diff
changeset
|
2548 |
ab443e80d9e4
Create new stream immediately on receiving new stream id.
Vladimir Homutov <vl@nginx.com>
parents:
8336
diff
changeset
|
2549 if (n < NGX_QUIC_STREAM_BUFSIZE) { |
ab443e80d9e4
Create new stream immediately on receiving new stream id.
Vladimir Homutov <vl@nginx.com>
parents:
8336
diff
changeset
|
2550 n = NGX_QUIC_STREAM_BUFSIZE; |
ab443e80d9e4
Create new stream immediately on receiving new stream id.
Vladimir Homutov <vl@nginx.com>
parents:
8336
diff
changeset
|
2551 } |
ab443e80d9e4
Create new stream immediately on receiving new stream id.
Vladimir Homutov <vl@nginx.com>
parents:
8336
diff
changeset
|
2552 |
ab443e80d9e4
Create new stream immediately on receiving new stream id.
Vladimir Homutov <vl@nginx.com>
parents:
8336
diff
changeset
|
2553 if (n < f->length) { |
8361 | 2554 ngx_log_error(NGX_LOG_INFO, c->log, 0, |
2555 "quic no space in stream buffer"); | |
8337
ab443e80d9e4
Create new stream immediately on receiving new stream id.
Vladimir Homutov <vl@nginx.com>
parents:
8336
diff
changeset
|
2556 return NGX_ERROR; |
ab443e80d9e4
Create new stream immediately on receiving new stream id.
Vladimir Homutov <vl@nginx.com>
parents:
8336
diff
changeset
|
2557 } |
ab443e80d9e4
Create new stream immediately on receiving new stream id.
Vladimir Homutov <vl@nginx.com>
parents:
8336
diff
changeset
|
2558 |
ab443e80d9e4
Create new stream immediately on receiving new stream id.
Vladimir Homutov <vl@nginx.com>
parents:
8336
diff
changeset
|
2559 /* |
ab443e80d9e4
Create new stream immediately on receiving new stream id.
Vladimir Homutov <vl@nginx.com>
parents:
8336
diff
changeset
|
2560 * TODO: check IDs are increasing ? create all lower-numbered? |
ab443e80d9e4
Create new stream immediately on receiving new stream id.
Vladimir Homutov <vl@nginx.com>
parents:
8336
diff
changeset
|
2561 * |
ab443e80d9e4
Create new stream immediately on receiving new stream id.
Vladimir Homutov <vl@nginx.com>
parents:
8336
diff
changeset
|
2562 * 2.1. Stream Types and Identifiers |
ab443e80d9e4
Create new stream immediately on receiving new stream id.
Vladimir Homutov <vl@nginx.com>
parents:
8336
diff
changeset
|
2563 * |
ab443e80d9e4
Create new stream immediately on receiving new stream id.
Vladimir Homutov <vl@nginx.com>
parents:
8336
diff
changeset
|
2564 * Within each type, streams are created with numerically increasing |
ab443e80d9e4
Create new stream immediately on receiving new stream id.
Vladimir Homutov <vl@nginx.com>
parents:
8336
diff
changeset
|
2565 * stream IDs. A stream ID that is used out of order results in all |
ab443e80d9e4
Create new stream immediately on receiving new stream id.
Vladimir Homutov <vl@nginx.com>
parents:
8336
diff
changeset
|
2566 * streams of that type with lower-numbered stream IDs also being |
ab443e80d9e4
Create new stream immediately on receiving new stream id.
Vladimir Homutov <vl@nginx.com>
parents:
8336
diff
changeset
|
2567 * opened. |
ab443e80d9e4
Create new stream immediately on receiving new stream id.
Vladimir Homutov <vl@nginx.com>
parents:
8336
diff
changeset
|
2568 */ |
ab443e80d9e4
Create new stream immediately on receiving new stream id.
Vladimir Homutov <vl@nginx.com>
parents:
8336
diff
changeset
|
2569 sn = ngx_quic_create_stream(c, f->stream_id, n); |
8334
72d20158c814
Added reordering support for STREAM frames.
Vladimir Homutov <vl@nginx.com>
parents:
8333
diff
changeset
|
2570 if (sn == NULL) { |
72d20158c814
Added reordering support for STREAM frames.
Vladimir Homutov <vl@nginx.com>
parents:
8333
diff
changeset
|
2571 return NGX_ERROR; |
72d20158c814
Added reordering support for STREAM frames.
Vladimir Homutov <vl@nginx.com>
parents:
8333
diff
changeset
|
2572 } |
8337
ab443e80d9e4
Create new stream immediately on receiving new stream id.
Vladimir Homutov <vl@nginx.com>
parents:
8336
diff
changeset
|
2573 |
ab443e80d9e4
Create new stream immediately on receiving new stream id.
Vladimir Homutov <vl@nginx.com>
parents:
8336
diff
changeset
|
2574 rev = sn->c->read; |
ab443e80d9e4
Create new stream immediately on receiving new stream id.
Vladimir Homutov <vl@nginx.com>
parents:
8336
diff
changeset
|
2575 |
ab443e80d9e4
Create new stream immediately on receiving new stream id.
Vladimir Homutov <vl@nginx.com>
parents:
8336
diff
changeset
|
2576 if (f->offset == 0) { |
ab443e80d9e4
Create new stream immediately on receiving new stream id.
Vladimir Homutov <vl@nginx.com>
parents:
8336
diff
changeset
|
2577 |
ab443e80d9e4
Create new stream immediately on receiving new stream id.
Vladimir Homutov <vl@nginx.com>
parents:
8336
diff
changeset
|
2578 b = sn->b; |
ab443e80d9e4
Create new stream immediately on receiving new stream id.
Vladimir Homutov <vl@nginx.com>
parents:
8336
diff
changeset
|
2579 b->last = ngx_cpymem(b->last, f->data, f->length); |
ab443e80d9e4
Create new stream immediately on receiving new stream id.
Vladimir Homutov <vl@nginx.com>
parents:
8336
diff
changeset
|
2580 |
ab443e80d9e4
Create new stream immediately on receiving new stream id.
Vladimir Homutov <vl@nginx.com>
parents:
8336
diff
changeset
|
2581 sn->fs.received += f->length; |
ab443e80d9e4
Create new stream immediately on receiving new stream id.
Vladimir Homutov <vl@nginx.com>
parents:
8336
diff
changeset
|
2582 |
ab443e80d9e4
Create new stream immediately on receiving new stream id.
Vladimir Homutov <vl@nginx.com>
parents:
8336
diff
changeset
|
2583 rev->ready = 1; |
ab443e80d9e4
Create new stream immediately on receiving new stream id.
Vladimir Homutov <vl@nginx.com>
parents:
8336
diff
changeset
|
2584 |
ab443e80d9e4
Create new stream immediately on receiving new stream id.
Vladimir Homutov <vl@nginx.com>
parents:
8336
diff
changeset
|
2585 if (f->fin) { |
ab443e80d9e4
Create new stream immediately on receiving new stream id.
Vladimir Homutov <vl@nginx.com>
parents:
8336
diff
changeset
|
2586 rev->pending_eof = 1; |
ab443e80d9e4
Create new stream immediately on receiving new stream id.
Vladimir Homutov <vl@nginx.com>
parents:
8336
diff
changeset
|
2587 } |
ab443e80d9e4
Create new stream immediately on receiving new stream id.
Vladimir Homutov <vl@nginx.com>
parents:
8336
diff
changeset
|
2588 |
ab443e80d9e4
Create new stream immediately on receiving new stream id.
Vladimir Homutov <vl@nginx.com>
parents:
8336
diff
changeset
|
2589 } else { |
ab443e80d9e4
Create new stream immediately on receiving new stream id.
Vladimir Homutov <vl@nginx.com>
parents:
8336
diff
changeset
|
2590 rev->ready = 0; |
ab443e80d9e4
Create new stream immediately on receiving new stream id.
Vladimir Homutov <vl@nginx.com>
parents:
8336
diff
changeset
|
2591 } |
ab443e80d9e4
Create new stream immediately on receiving new stream id.
Vladimir Homutov <vl@nginx.com>
parents:
8336
diff
changeset
|
2592 |
ab443e80d9e4
Create new stream immediately on receiving new stream id.
Vladimir Homutov <vl@nginx.com>
parents:
8336
diff
changeset
|
2593 if ((f->stream_id & NGX_QUIC_STREAM_UNIDIRECTIONAL) == 0) { |
ab443e80d9e4
Create new stream immediately on receiving new stream id.
Vladimir Homutov <vl@nginx.com>
parents:
8336
diff
changeset
|
2594 ngx_quic_handle_max_streams(c); |
ab443e80d9e4
Create new stream immediately on receiving new stream id.
Vladimir Homutov <vl@nginx.com>
parents:
8336
diff
changeset
|
2595 } |
ab443e80d9e4
Create new stream immediately on receiving new stream id.
Vladimir Homutov <vl@nginx.com>
parents:
8336
diff
changeset
|
2596 |
ab443e80d9e4
Create new stream immediately on receiving new stream id.
Vladimir Homutov <vl@nginx.com>
parents:
8336
diff
changeset
|
2597 qc->streams.handler(sn->c); |
ab443e80d9e4
Create new stream immediately on receiving new stream id.
Vladimir Homutov <vl@nginx.com>
parents:
8336
diff
changeset
|
2598 |
ab443e80d9e4
Create new stream immediately on receiving new stream id.
Vladimir Homutov <vl@nginx.com>
parents:
8336
diff
changeset
|
2599 if (f->offset == 0) { |
ab443e80d9e4
Create new stream immediately on receiving new stream id.
Vladimir Homutov <vl@nginx.com>
parents:
8336
diff
changeset
|
2600 return NGX_OK; |
ab443e80d9e4
Create new stream immediately on receiving new stream id.
Vladimir Homutov <vl@nginx.com>
parents:
8336
diff
changeset
|
2601 } |
ab443e80d9e4
Create new stream immediately on receiving new stream id.
Vladimir Homutov <vl@nginx.com>
parents:
8336
diff
changeset
|
2602 |
ab443e80d9e4
Create new stream immediately on receiving new stream id.
Vladimir Homutov <vl@nginx.com>
parents:
8336
diff
changeset
|
2603 /* out-of-order stream: proceed to buffering */ |
8334
72d20158c814
Added reordering support for STREAM frames.
Vladimir Homutov <vl@nginx.com>
parents:
8333
diff
changeset
|
2604 } |
72d20158c814
Added reordering support for STREAM frames.
Vladimir Homutov <vl@nginx.com>
parents:
8333
diff
changeset
|
2605 |
72d20158c814
Added reordering support for STREAM frames.
Vladimir Homutov <vl@nginx.com>
parents:
8333
diff
changeset
|
2606 fs = &sn->fs; |
72d20158c814
Added reordering support for STREAM frames.
Vladimir Homutov <vl@nginx.com>
parents:
8333
diff
changeset
|
2607 |
8378
81a4f98a2556
Cleaned up reordering code.
Vladimir Homutov <vl@nginx.com>
parents:
8377
diff
changeset
|
2608 return ngx_quic_handle_ordered_frame(c, fs, frame, ngx_quic_stream_input, |
81a4f98a2556
Cleaned up reordering code.
Vladimir Homutov <vl@nginx.com>
parents:
8377
diff
changeset
|
2609 sn); |
8334
72d20158c814
Added reordering support for STREAM frames.
Vladimir Homutov <vl@nginx.com>
parents:
8333
diff
changeset
|
2610 } |
72d20158c814
Added reordering support for STREAM frames.
Vladimir Homutov <vl@nginx.com>
parents:
8333
diff
changeset
|
2611 |
72d20158c814
Added reordering support for STREAM frames.
Vladimir Homutov <vl@nginx.com>
parents:
8333
diff
changeset
|
2612 |
72d20158c814
Added reordering support for STREAM frames.
Vladimir Homutov <vl@nginx.com>
parents:
8333
diff
changeset
|
2613 static ngx_int_t |
8378
81a4f98a2556
Cleaned up reordering code.
Vladimir Homutov <vl@nginx.com>
parents:
8377
diff
changeset
|
2614 ngx_quic_stream_input(ngx_connection_t *c, ngx_quic_frame_t *frame, void *data) |
8334
72d20158c814
Added reordering support for STREAM frames.
Vladimir Homutov <vl@nginx.com>
parents:
8333
diff
changeset
|
2615 { |
72d20158c814
Added reordering support for STREAM frames.
Vladimir Homutov <vl@nginx.com>
parents:
8333
diff
changeset
|
2616 ngx_buf_t *b; |
72d20158c814
Added reordering support for STREAM frames.
Vladimir Homutov <vl@nginx.com>
parents:
8333
diff
changeset
|
2617 ngx_event_t *rev; |
72d20158c814
Added reordering support for STREAM frames.
Vladimir Homutov <vl@nginx.com>
parents:
8333
diff
changeset
|
2618 ngx_quic_stream_t *sn; |
72d20158c814
Added reordering support for STREAM frames.
Vladimir Homutov <vl@nginx.com>
parents:
8333
diff
changeset
|
2619 ngx_quic_connection_t *qc; |
72d20158c814
Added reordering support for STREAM frames.
Vladimir Homutov <vl@nginx.com>
parents:
8333
diff
changeset
|
2620 ngx_quic_stream_frame_t *f; |
72d20158c814
Added reordering support for STREAM frames.
Vladimir Homutov <vl@nginx.com>
parents:
8333
diff
changeset
|
2621 |
72d20158c814
Added reordering support for STREAM frames.
Vladimir Homutov <vl@nginx.com>
parents:
8333
diff
changeset
|
2622 qc = c->quic; |
8378
81a4f98a2556
Cleaned up reordering code.
Vladimir Homutov <vl@nginx.com>
parents:
8377
diff
changeset
|
2623 sn = data; |
8334
72d20158c814
Added reordering support for STREAM frames.
Vladimir Homutov <vl@nginx.com>
parents:
8333
diff
changeset
|
2624 |
72d20158c814
Added reordering support for STREAM frames.
Vladimir Homutov <vl@nginx.com>
parents:
8333
diff
changeset
|
2625 f = &frame->u.stream; |
72d20158c814
Added reordering support for STREAM frames.
Vladimir Homutov <vl@nginx.com>
parents:
8333
diff
changeset
|
2626 |
8359 | 2627 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "quic existing stream"); |
8225 | 2628 |
2629 b = sn->b; | |
8337
ab443e80d9e4
Create new stream immediately on receiving new stream id.
Vladimir Homutov <vl@nginx.com>
parents:
8336
diff
changeset
|
2630 |
ab443e80d9e4
Create new stream immediately on receiving new stream id.
Vladimir Homutov <vl@nginx.com>
parents:
8336
diff
changeset
|
2631 if ((size_t) ((b->pos - b->start) + (b->end - b->last)) < f->length) { |
8361 | 2632 ngx_log_error(NGX_LOG_INFO, c->log, 0, |
2633 "quic no space in stream buffer"); | |
8337
ab443e80d9e4
Create new stream immediately on receiving new stream id.
Vladimir Homutov <vl@nginx.com>
parents:
8336
diff
changeset
|
2634 return NGX_ERROR; |
ab443e80d9e4
Create new stream immediately on receiving new stream id.
Vladimir Homutov <vl@nginx.com>
parents:
8336
diff
changeset
|
2635 } |
ab443e80d9e4
Create new stream immediately on receiving new stream id.
Vladimir Homutov <vl@nginx.com>
parents:
8336
diff
changeset
|
2636 |
ab443e80d9e4
Create new stream immediately on receiving new stream id.
Vladimir Homutov <vl@nginx.com>
parents:
8336
diff
changeset
|
2637 if ((size_t) (b->end - b->last) < f->length) { |
ab443e80d9e4
Create new stream immediately on receiving new stream id.
Vladimir Homutov <vl@nginx.com>
parents:
8336
diff
changeset
|
2638 b->last = ngx_movemem(b->start, b->pos, b->last - b->pos); |
ab443e80d9e4
Create new stream immediately on receiving new stream id.
Vladimir Homutov <vl@nginx.com>
parents:
8336
diff
changeset
|
2639 b->pos = b->start; |
ab443e80d9e4
Create new stream immediately on receiving new stream id.
Vladimir Homutov <vl@nginx.com>
parents:
8336
diff
changeset
|
2640 } |
ab443e80d9e4
Create new stream immediately on receiving new stream id.
Vladimir Homutov <vl@nginx.com>
parents:
8336
diff
changeset
|
2641 |
8282
4cf00c14f11a
Safe QUIC stream creation.
Roman Arutyunyan <arut@nginx.com>
parents:
8281
diff
changeset
|
2642 b->last = ngx_cpymem(b->last, f->data, f->length); |
8225 | 2643 |
8294
32db41d603cd
Fixed handling QUIC stream eof.
Roman Arutyunyan <arut@nginx.com>
parents:
8293
diff
changeset
|
2644 rev = sn->c->read; |
32db41d603cd
Fixed handling QUIC stream eof.
Roman Arutyunyan <arut@nginx.com>
parents:
8293
diff
changeset
|
2645 rev->ready = 1; |
32db41d603cd
Fixed handling QUIC stream eof.
Roman Arutyunyan <arut@nginx.com>
parents:
8293
diff
changeset
|
2646 |
32db41d603cd
Fixed handling QUIC stream eof.
Roman Arutyunyan <arut@nginx.com>
parents:
8293
diff
changeset
|
2647 if (f->fin) { |
32db41d603cd
Fixed handling QUIC stream eof.
Roman Arutyunyan <arut@nginx.com>
parents:
8293
diff
changeset
|
2648 rev->pending_eof = 1; |
32db41d603cd
Fixed handling QUIC stream eof.
Roman Arutyunyan <arut@nginx.com>
parents:
8293
diff
changeset
|
2649 } |
8225 | 2650 |
8337
ab443e80d9e4
Create new stream immediately on receiving new stream id.
Vladimir Homutov <vl@nginx.com>
parents:
8336
diff
changeset
|
2651 if (rev->active) { |
ab443e80d9e4
Create new stream immediately on receiving new stream id.
Vladimir Homutov <vl@nginx.com>
parents:
8336
diff
changeset
|
2652 rev->handler(rev); |
8314
de8981bf2dd5
Advertizing MAX_STREAMS (0x12) credit in advance.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8312
diff
changeset
|
2653 } |
de8981bf2dd5
Advertizing MAX_STREAMS (0x12) credit in advance.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8312
diff
changeset
|
2654 |
8337
ab443e80d9e4
Create new stream immediately on receiving new stream id.
Vladimir Homutov <vl@nginx.com>
parents:
8336
diff
changeset
|
2655 /* check if stream was destroyed by handler */ |
8334
72d20158c814
Added reordering support for STREAM frames.
Vladimir Homutov <vl@nginx.com>
parents:
8333
diff
changeset
|
2656 if (ngx_quic_find_stream(&qc->streams.tree, f->stream_id) == NULL) { |
72d20158c814
Added reordering support for STREAM frames.
Vladimir Homutov <vl@nginx.com>
parents:
8333
diff
changeset
|
2657 return NGX_DONE; |
72d20158c814
Added reordering support for STREAM frames.
Vladimir Homutov <vl@nginx.com>
parents:
8333
diff
changeset
|
2658 } |
72d20158c814
Added reordering support for STREAM frames.
Vladimir Homutov <vl@nginx.com>
parents:
8333
diff
changeset
|
2659 |
8225 | 2660 return NGX_OK; |
2661 } | |
2662 | |
2663 | |
8245
a14afe21e692
Double MAX_STREAMS on STREAMS_BLOCKED.
Roman Arutyunyan <arut@nginx.com>
parents:
8241
diff
changeset
|
2664 static ngx_int_t |
8314
de8981bf2dd5
Advertizing MAX_STREAMS (0x12) credit in advance.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8312
diff
changeset
|
2665 ngx_quic_handle_max_streams(ngx_connection_t *c) |
de8981bf2dd5
Advertizing MAX_STREAMS (0x12) credit in advance.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8312
diff
changeset
|
2666 { |
de8981bf2dd5
Advertizing MAX_STREAMS (0x12) credit in advance.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8312
diff
changeset
|
2667 ngx_quic_frame_t *frame; |
de8981bf2dd5
Advertizing MAX_STREAMS (0x12) credit in advance.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8312
diff
changeset
|
2668 ngx_quic_connection_t *qc; |
de8981bf2dd5
Advertizing MAX_STREAMS (0x12) credit in advance.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8312
diff
changeset
|
2669 |
de8981bf2dd5
Advertizing MAX_STREAMS (0x12) credit in advance.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8312
diff
changeset
|
2670 qc = c->quic; |
de8981bf2dd5
Advertizing MAX_STREAMS (0x12) credit in advance.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8312
diff
changeset
|
2671 qc->cur_streams++; |
de8981bf2dd5
Advertizing MAX_STREAMS (0x12) credit in advance.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8312
diff
changeset
|
2672 |
de8981bf2dd5
Advertizing MAX_STREAMS (0x12) credit in advance.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8312
diff
changeset
|
2673 if (qc->cur_streams + NGX_QUIC_STREAMS_INC / 2 < qc->max_streams) { |
de8981bf2dd5
Advertizing MAX_STREAMS (0x12) credit in advance.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8312
diff
changeset
|
2674 return NGX_OK; |
de8981bf2dd5
Advertizing MAX_STREAMS (0x12) credit in advance.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8312
diff
changeset
|
2675 } |
de8981bf2dd5
Advertizing MAX_STREAMS (0x12) credit in advance.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8312
diff
changeset
|
2676 |
de8981bf2dd5
Advertizing MAX_STREAMS (0x12) credit in advance.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8312
diff
changeset
|
2677 frame = ngx_quic_alloc_frame(c, 0); |
de8981bf2dd5
Advertizing MAX_STREAMS (0x12) credit in advance.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8312
diff
changeset
|
2678 if (frame == NULL) { |
de8981bf2dd5
Advertizing MAX_STREAMS (0x12) credit in advance.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8312
diff
changeset
|
2679 return NGX_ERROR; |
de8981bf2dd5
Advertizing MAX_STREAMS (0x12) credit in advance.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8312
diff
changeset
|
2680 } |
de8981bf2dd5
Advertizing MAX_STREAMS (0x12) credit in advance.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8312
diff
changeset
|
2681 |
de8981bf2dd5
Advertizing MAX_STREAMS (0x12) credit in advance.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8312
diff
changeset
|
2682 qc->max_streams = ngx_max(qc->max_streams + NGX_QUIC_STREAMS_INC, |
de8981bf2dd5
Advertizing MAX_STREAMS (0x12) credit in advance.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8312
diff
changeset
|
2683 NGX_QUIC_STREAMS_LIMIT); |
de8981bf2dd5
Advertizing MAX_STREAMS (0x12) credit in advance.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8312
diff
changeset
|
2684 |
de8981bf2dd5
Advertizing MAX_STREAMS (0x12) credit in advance.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8312
diff
changeset
|
2685 frame->level = ssl_encryption_application; |
de8981bf2dd5
Advertizing MAX_STREAMS (0x12) credit in advance.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8312
diff
changeset
|
2686 frame->type = NGX_QUIC_FT_MAX_STREAMS; |
de8981bf2dd5
Advertizing MAX_STREAMS (0x12) credit in advance.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8312
diff
changeset
|
2687 frame->u.max_streams.limit = qc->max_streams; |
de8981bf2dd5
Advertizing MAX_STREAMS (0x12) credit in advance.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8312
diff
changeset
|
2688 frame->u.max_streams.bidi = 1; |
de8981bf2dd5
Advertizing MAX_STREAMS (0x12) credit in advance.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8312
diff
changeset
|
2689 |
de8981bf2dd5
Advertizing MAX_STREAMS (0x12) credit in advance.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8312
diff
changeset
|
2690 ngx_sprintf(frame->info, "MAX_STREAMS limit:%d bidi:%d level=%d", |
de8981bf2dd5
Advertizing MAX_STREAMS (0x12) credit in advance.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8312
diff
changeset
|
2691 (int) frame->u.max_streams.limit, |
de8981bf2dd5
Advertizing MAX_STREAMS (0x12) credit in advance.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8312
diff
changeset
|
2692 (int) frame->u.max_streams.bidi, |
de8981bf2dd5
Advertizing MAX_STREAMS (0x12) credit in advance.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8312
diff
changeset
|
2693 frame->level); |
de8981bf2dd5
Advertizing MAX_STREAMS (0x12) credit in advance.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8312
diff
changeset
|
2694 |
de8981bf2dd5
Advertizing MAX_STREAMS (0x12) credit in advance.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8312
diff
changeset
|
2695 ngx_quic_queue_frame(qc, frame); |
de8981bf2dd5
Advertizing MAX_STREAMS (0x12) credit in advance.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8312
diff
changeset
|
2696 |
de8981bf2dd5
Advertizing MAX_STREAMS (0x12) credit in advance.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8312
diff
changeset
|
2697 return NGX_OK; |
de8981bf2dd5
Advertizing MAX_STREAMS (0x12) credit in advance.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8312
diff
changeset
|
2698 } |
de8981bf2dd5
Advertizing MAX_STREAMS (0x12) credit in advance.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8312
diff
changeset
|
2699 |
de8981bf2dd5
Advertizing MAX_STREAMS (0x12) credit in advance.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8312
diff
changeset
|
2700 |
de8981bf2dd5
Advertizing MAX_STREAMS (0x12) credit in advance.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8312
diff
changeset
|
2701 static ngx_int_t |
8365
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2702 ngx_quic_handle_max_data_frame(ngx_connection_t *c, |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2703 ngx_quic_max_data_frame_t *f) |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2704 { |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2705 ngx_event_t *wev; |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2706 ngx_rbtree_t *tree; |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2707 ngx_rbtree_node_t *node; |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2708 ngx_quic_stream_t *qs; |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2709 ngx_quic_connection_t *qc; |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2710 |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2711 qc = c->quic; |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2712 tree = &qc->streams.tree; |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2713 |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2714 if (f->max_data <= qc->streams.send_max_data) { |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2715 return NGX_OK; |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2716 } |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2717 |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2718 if (qc->streams.sent >= qc->streams.send_max_data) { |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2719 |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2720 for (node = ngx_rbtree_min(tree->root, tree->sentinel); |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2721 node; |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2722 node = ngx_rbtree_next(tree, node)) |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2723 { |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2724 qs = (ngx_quic_stream_t *) node; |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2725 wev = qs->c->write; |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2726 |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2727 if (wev->active) { |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2728 wev->ready = 1; |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2729 ngx_post_event(wev, &ngx_posted_events); |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2730 } |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2731 } |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2732 } |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2733 |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2734 qc->streams.send_max_data = f->max_data; |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2735 |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2736 return NGX_OK; |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2737 } |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2738 |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2739 |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2740 static ngx_int_t |
8245
a14afe21e692
Double MAX_STREAMS on STREAMS_BLOCKED.
Roman Arutyunyan <arut@nginx.com>
parents:
8241
diff
changeset
|
2741 ngx_quic_handle_streams_blocked_frame(ngx_connection_t *c, |
a14afe21e692
Double MAX_STREAMS on STREAMS_BLOCKED.
Roman Arutyunyan <arut@nginx.com>
parents:
8241
diff
changeset
|
2742 ngx_quic_header_t *pkt, ngx_quic_streams_blocked_frame_t *f) |
a14afe21e692
Double MAX_STREAMS on STREAMS_BLOCKED.
Roman Arutyunyan <arut@nginx.com>
parents:
8241
diff
changeset
|
2743 { |
a14afe21e692
Double MAX_STREAMS on STREAMS_BLOCKED.
Roman Arutyunyan <arut@nginx.com>
parents:
8241
diff
changeset
|
2744 ngx_quic_frame_t *frame; |
a14afe21e692
Double MAX_STREAMS on STREAMS_BLOCKED.
Roman Arutyunyan <arut@nginx.com>
parents:
8241
diff
changeset
|
2745 |
8286 | 2746 frame = ngx_quic_alloc_frame(c, 0); |
8245
a14afe21e692
Double MAX_STREAMS on STREAMS_BLOCKED.
Roman Arutyunyan <arut@nginx.com>
parents:
8241
diff
changeset
|
2747 if (frame == NULL) { |
a14afe21e692
Double MAX_STREAMS on STREAMS_BLOCKED.
Roman Arutyunyan <arut@nginx.com>
parents:
8241
diff
changeset
|
2748 return NGX_ERROR; |
a14afe21e692
Double MAX_STREAMS on STREAMS_BLOCKED.
Roman Arutyunyan <arut@nginx.com>
parents:
8241
diff
changeset
|
2749 } |
a14afe21e692
Double MAX_STREAMS on STREAMS_BLOCKED.
Roman Arutyunyan <arut@nginx.com>
parents:
8241
diff
changeset
|
2750 |
a14afe21e692
Double MAX_STREAMS on STREAMS_BLOCKED.
Roman Arutyunyan <arut@nginx.com>
parents:
8241
diff
changeset
|
2751 frame->level = pkt->level; |
a14afe21e692
Double MAX_STREAMS on STREAMS_BLOCKED.
Roman Arutyunyan <arut@nginx.com>
parents:
8241
diff
changeset
|
2752 frame->type = NGX_QUIC_FT_MAX_STREAMS; |
8314
de8981bf2dd5
Advertizing MAX_STREAMS (0x12) credit in advance.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8312
diff
changeset
|
2753 frame->u.max_streams.limit = ngx_max(f->limit * 2, NGX_QUIC_STREAMS_LIMIT); |
8245
a14afe21e692
Double MAX_STREAMS on STREAMS_BLOCKED.
Roman Arutyunyan <arut@nginx.com>
parents:
8241
diff
changeset
|
2754 frame->u.max_streams.bidi = f->bidi; |
a14afe21e692
Double MAX_STREAMS on STREAMS_BLOCKED.
Roman Arutyunyan <arut@nginx.com>
parents:
8241
diff
changeset
|
2755 |
8314
de8981bf2dd5
Advertizing MAX_STREAMS (0x12) credit in advance.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8312
diff
changeset
|
2756 c->quic->max_streams = frame->u.max_streams.limit; |
de8981bf2dd5
Advertizing MAX_STREAMS (0x12) credit in advance.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8312
diff
changeset
|
2757 |
8245
a14afe21e692
Double MAX_STREAMS on STREAMS_BLOCKED.
Roman Arutyunyan <arut@nginx.com>
parents:
8241
diff
changeset
|
2758 ngx_sprintf(frame->info, "MAX_STREAMS limit:%d bidi:%d level=%d", |
a14afe21e692
Double MAX_STREAMS on STREAMS_BLOCKED.
Roman Arutyunyan <arut@nginx.com>
parents:
8241
diff
changeset
|
2759 (int) frame->u.max_streams.limit, |
a14afe21e692
Double MAX_STREAMS on STREAMS_BLOCKED.
Roman Arutyunyan <arut@nginx.com>
parents:
8241
diff
changeset
|
2760 (int) frame->u.max_streams.bidi, |
a14afe21e692
Double MAX_STREAMS on STREAMS_BLOCKED.
Roman Arutyunyan <arut@nginx.com>
parents:
8241
diff
changeset
|
2761 frame->level); |
a14afe21e692
Double MAX_STREAMS on STREAMS_BLOCKED.
Roman Arutyunyan <arut@nginx.com>
parents:
8241
diff
changeset
|
2762 |
a14afe21e692
Double MAX_STREAMS on STREAMS_BLOCKED.
Roman Arutyunyan <arut@nginx.com>
parents:
8241
diff
changeset
|
2763 ngx_quic_queue_frame(c->quic, frame); |
a14afe21e692
Double MAX_STREAMS on STREAMS_BLOCKED.
Roman Arutyunyan <arut@nginx.com>
parents:
8241
diff
changeset
|
2764 |
a14afe21e692
Double MAX_STREAMS on STREAMS_BLOCKED.
Roman Arutyunyan <arut@nginx.com>
parents:
8241
diff
changeset
|
2765 return NGX_OK; |
a14afe21e692
Double MAX_STREAMS on STREAMS_BLOCKED.
Roman Arutyunyan <arut@nginx.com>
parents:
8241
diff
changeset
|
2766 } |
a14afe21e692
Double MAX_STREAMS on STREAMS_BLOCKED.
Roman Arutyunyan <arut@nginx.com>
parents:
8241
diff
changeset
|
2767 |
a14afe21e692
Double MAX_STREAMS on STREAMS_BLOCKED.
Roman Arutyunyan <arut@nginx.com>
parents:
8241
diff
changeset
|
2768 |
8266
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
2769 static ngx_int_t |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
2770 ngx_quic_handle_stream_data_blocked_frame(ngx_connection_t *c, |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
2771 ngx_quic_header_t *pkt, ngx_quic_stream_data_blocked_frame_t *f) |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
2772 { |
8280
b364af7f9f3f
Removed ngx_quic_stream_node_t.
Roman Arutyunyan <arut@nginx.com>
parents:
8279
diff
changeset
|
2773 size_t n; |
b364af7f9f3f
Removed ngx_quic_stream_node_t.
Roman Arutyunyan <arut@nginx.com>
parents:
8279
diff
changeset
|
2774 ngx_buf_t *b; |
b364af7f9f3f
Removed ngx_quic_stream_node_t.
Roman Arutyunyan <arut@nginx.com>
parents:
8279
diff
changeset
|
2775 ngx_quic_frame_t *frame; |
b364af7f9f3f
Removed ngx_quic_stream_node_t.
Roman Arutyunyan <arut@nginx.com>
parents:
8279
diff
changeset
|
2776 ngx_quic_stream_t *sn; |
b364af7f9f3f
Removed ngx_quic_stream_node_t.
Roman Arutyunyan <arut@nginx.com>
parents:
8279
diff
changeset
|
2777 ngx_quic_connection_t *qc; |
8266
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
2778 |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
2779 qc = c->quic; |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
2780 sn = ngx_quic_find_stream(&qc->streams.tree, f->id); |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
2781 |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
2782 if (sn == NULL) { |
8361 | 2783 ngx_log_error(NGX_LOG_INFO, c->log, 0, |
2784 "quic unknown stream id:%uL", f->id); | |
8266
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
2785 return NGX_ERROR; |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
2786 } |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
2787 |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
2788 b = sn->b; |
8338
0f9e9786b90d
Added primitive flow control mechanisms.
Vladimir Homutov <vl@nginx.com>
parents:
8337
diff
changeset
|
2789 n = sn->fs.received + (b->pos - b->start) + (b->end - b->last); |
8266
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
2790 |
8286 | 2791 frame = ngx_quic_alloc_frame(c, 0); |
8266
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
2792 if (frame == NULL) { |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
2793 return NGX_ERROR; |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
2794 } |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
2795 |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
2796 frame->level = pkt->level; |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
2797 frame->type = NGX_QUIC_FT_MAX_STREAM_DATA; |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
2798 frame->u.max_stream_data.id = f->id; |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
2799 frame->u.max_stream_data.limit = n; |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
2800 |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
2801 ngx_sprintf(frame->info, "MAX_STREAM_DATA id:%d limit:%d level=%d", |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
2802 (int) frame->u.max_stream_data.id, |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
2803 (int) frame->u.max_stream_data.limit, |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
2804 frame->level); |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
2805 |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
2806 ngx_quic_queue_frame(c->quic, frame); |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
2807 |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
2808 return NGX_OK; |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
2809 } |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
2810 |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
2811 |
8365
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2812 static ngx_int_t |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2813 ngx_quic_handle_max_stream_data_frame(ngx_connection_t *c, |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2814 ngx_quic_header_t *pkt, ngx_quic_max_stream_data_frame_t *f) |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2815 { |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2816 uint64_t sent; |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2817 ngx_event_t *wev; |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2818 ngx_quic_stream_t *sn; |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2819 ngx_quic_connection_t *qc; |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2820 |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2821 qc = c->quic; |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2822 sn = ngx_quic_find_stream(&qc->streams.tree, f->id); |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2823 |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2824 if (sn == NULL) { |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2825 ngx_log_error(NGX_LOG_INFO, c->log, 0, "unknown stream id:%uL", f->id); |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2826 return NGX_ERROR; |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2827 } |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2828 |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2829 if (f->limit <= sn->send_max_data) { |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2830 return NGX_OK; |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2831 } |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2832 |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2833 sent = sn->c->sent; |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2834 |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2835 if (sent >= sn->send_max_data) { |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2836 wev = sn->c->write; |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2837 |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2838 if (wev->active) { |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2839 wev->ready = 1; |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2840 ngx_post_event(wev, &ngx_posted_events); |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2841 } |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2842 } |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2843 |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2844 sn->send_max_data = f->limit; |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2845 |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2846 return NGX_OK; |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2847 } |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2848 |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
2849 |
8225 | 2850 static void |
2851 ngx_quic_queue_frame(ngx_quic_connection_t *qc, ngx_quic_frame_t *frame) | |
2852 { | |
8331
bda817d16cc2
Rename types and variables used for packet number space.
Vladimir Homutov <vl@nginx.com>
parents:
8328
diff
changeset
|
2853 ngx_quic_send_ctx_t *ctx; |
bda817d16cc2
Rename types and variables used for packet number space.
Vladimir Homutov <vl@nginx.com>
parents:
8328
diff
changeset
|
2854 |
bda817d16cc2
Rename types and variables used for packet number space.
Vladimir Homutov <vl@nginx.com>
parents:
8328
diff
changeset
|
2855 ctx = ngx_quic_get_send_ctx(qc, frame->level); |
bda817d16cc2
Rename types and variables used for packet number space.
Vladimir Homutov <vl@nginx.com>
parents:
8328
diff
changeset
|
2856 |
bda817d16cc2
Rename types and variables used for packet number space.
Vladimir Homutov <vl@nginx.com>
parents:
8328
diff
changeset
|
2857 ngx_queue_insert_tail(&ctx->frames, &frame->queue); |
8309 | 2858 |
2859 /* TODO: check PUSH flag on stream and call output */ | |
2860 | |
2861 if (!qc->push.timer_set && !qc->closing) { | |
2862 ngx_add_timer(&qc->push, qc->tp.max_ack_delay); | |
2863 } | |
8225 | 2864 } |
2865 | |
2866 | |
2867 static ngx_int_t | |
2868 ngx_quic_output(ngx_connection_t *c) | |
2869 { | |
8308
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2870 ngx_uint_t i; |
8225 | 2871 ngx_quic_connection_t *qc; |
2872 | |
8275 | 2873 c->log->action = "sending frames"; |
2874 | |
8308
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2875 qc = c->quic; |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2876 |
8331
bda817d16cc2
Rename types and variables used for packet number space.
Vladimir Homutov <vl@nginx.com>
parents:
8328
diff
changeset
|
2877 for (i = 0; i < NGX_QUIC_SEND_CTX_LAST; i++) { |
8332
6ad871b63422
Cleaned up magic numbers in ngx_quic_output_frames().
Vladimir Homutov <vl@nginx.com>
parents:
8331
diff
changeset
|
2878 if (ngx_quic_output_frames(c, &qc->send_ctx[i]) != NGX_OK) { |
8225 | 2879 return NGX_ERROR; |
2880 } | |
8308
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2881 } |
8225 | 2882 |
8322
d9bc33166361
Do not set timers after the connection is closed.
Vladimir Homutov <vl@nginx.com>
parents:
8321
diff
changeset
|
2883 if (!qc->send_timer_set && !qc->closing) { |
8271
8e54a17dabee
Respect QUIC max_idle_timeout.
Roman Arutyunyan <arut@nginx.com>
parents:
8270
diff
changeset
|
2884 qc->send_timer_set = 1; |
8e54a17dabee
Respect QUIC max_idle_timeout.
Roman Arutyunyan <arut@nginx.com>
parents:
8270
diff
changeset
|
2885 ngx_add_timer(c->read, qc->tp.max_idle_timeout); |
8e54a17dabee
Respect QUIC max_idle_timeout.
Roman Arutyunyan <arut@nginx.com>
parents:
8270
diff
changeset
|
2886 } |
8e54a17dabee
Respect QUIC max_idle_timeout.
Roman Arutyunyan <arut@nginx.com>
parents:
8270
diff
changeset
|
2887 |
8369
bddf704d62c1
Renamed retransmit event object in preparation for retry support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8368
diff
changeset
|
2888 if (!qc->retransmit.timer_set && !qc->closing) { |
bddf704d62c1
Renamed retransmit event object in preparation for retry support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8368
diff
changeset
|
2889 ngx_add_timer(&qc->retransmit, qc->tp.max_ack_delay); |
8308
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2890 } |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2891 |
8225 | 2892 return NGX_OK; |
2893 } | |
2894 | |
2895 | |
8308
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2896 static ngx_int_t |
8332
6ad871b63422
Cleaned up magic numbers in ngx_quic_output_frames().
Vladimir Homutov <vl@nginx.com>
parents:
8331
diff
changeset
|
2897 ngx_quic_output_frames(ngx_connection_t *c, ngx_quic_send_ctx_t *ctx) |
8308
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2898 { |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2899 size_t len, hlen, n; |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2900 ngx_int_t rc; |
8364
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
2901 ngx_uint_t need_ack; |
8308
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2902 ngx_queue_t *q, range; |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2903 ngx_quic_frame_t *f; |
8364
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
2904 ngx_quic_congestion_t *cg; |
8308
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2905 ngx_quic_connection_t *qc; |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2906 |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2907 qc = c->quic; |
8364
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
2908 cg = &qc->congestion; |
8308
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2909 |
8331
bda817d16cc2
Rename types and variables used for packet number space.
Vladimir Homutov <vl@nginx.com>
parents:
8328
diff
changeset
|
2910 if (ngx_queue_empty(&ctx->frames)) { |
8308
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2911 return NGX_OK; |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2912 } |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2913 |
8332
6ad871b63422
Cleaned up magic numbers in ngx_quic_output_frames().
Vladimir Homutov <vl@nginx.com>
parents:
8331
diff
changeset
|
2914 q = ngx_queue_head(&ctx->frames); |
6ad871b63422
Cleaned up magic numbers in ngx_quic_output_frames().
Vladimir Homutov <vl@nginx.com>
parents:
8331
diff
changeset
|
2915 f = ngx_queue_data(q, ngx_quic_frame_t, queue); |
6ad871b63422
Cleaned up magic numbers in ngx_quic_output_frames().
Vladimir Homutov <vl@nginx.com>
parents:
8331
diff
changeset
|
2916 |
6ad871b63422
Cleaned up magic numbers in ngx_quic_output_frames().
Vladimir Homutov <vl@nginx.com>
parents:
8331
diff
changeset
|
2917 /* all frames in same send_ctx share same level */ |
6ad871b63422
Cleaned up magic numbers in ngx_quic_output_frames().
Vladimir Homutov <vl@nginx.com>
parents:
8331
diff
changeset
|
2918 hlen = (f->level == ssl_encryption_application) ? NGX_QUIC_MAX_SHORT_HEADER |
6ad871b63422
Cleaned up magic numbers in ngx_quic_output_frames().
Vladimir Homutov <vl@nginx.com>
parents:
8331
diff
changeset
|
2919 : NGX_QUIC_MAX_LONG_HEADER; |
8308
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2920 hlen += EVP_GCM_TLS_TAG_LEN; |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2921 |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2922 do { |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2923 len = 0; |
8364
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
2924 need_ack = 0; |
8308
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2925 ngx_queue_init(&range); |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2926 |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2927 do { |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2928 /* process group of frames that fits into packet */ |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2929 f = ngx_queue_data(q, ngx_quic_frame_t, queue); |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2930 |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2931 n = ngx_quic_create_frame(NULL, f); |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2932 |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2933 if (len && hlen + len + n > qc->ctp.max_packet_size) { |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2934 break; |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2935 } |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2936 |
8364
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
2937 if (f->need_ack) { |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
2938 need_ack = 1; |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
2939 } |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
2940 |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
2941 if (need_ack && cg->in_flight + len + n > cg->window) { |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
2942 break; |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
2943 } |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
2944 |
8308
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2945 q = ngx_queue_next(q); |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2946 |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2947 f->first = ngx_current_msec; |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2948 |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2949 ngx_queue_remove(&f->queue); |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2950 ngx_queue_insert_tail(&range, &f->queue); |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2951 |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2952 len += n; |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2953 |
8331
bda817d16cc2
Rename types and variables used for packet number space.
Vladimir Homutov <vl@nginx.com>
parents:
8328
diff
changeset
|
2954 } while (q != ngx_queue_sentinel(&ctx->frames)); |
8308
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2955 |
8364
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
2956 if (ngx_queue_empty(&range)) { |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
2957 break; |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
2958 } |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
2959 |
8308
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2960 rc = ngx_quic_send_frames(c, &range); |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2961 |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2962 if (rc == NGX_OK) { |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2963 /* |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2964 * frames are moved into the sent queue |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2965 * to wait for ack/be retransmitted |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2966 */ |
8355
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
2967 if (qc->closing) { |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
2968 /* if we are closing, any ack will be discarded */ |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
2969 ngx_quic_free_frames(c, &range); |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
2970 |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
2971 } else { |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
2972 ngx_queue_add(&ctx->sent, &range); |
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
2973 } |
8308
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2974 |
8364
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
2975 cg->in_flight += len; |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
2976 |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
2977 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
2978 "quic congestion send if:%uz", cg->in_flight); |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
2979 |
8308
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2980 } else if (rc == NGX_DONE) { |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2981 |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2982 /* no ack is expected for this frames, can free them */ |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2983 ngx_quic_free_frames(c, &range); |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2984 |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2985 } else { |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2986 return NGX_ERROR; |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2987 } |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2988 |
8331
bda817d16cc2
Rename types and variables used for packet number space.
Vladimir Homutov <vl@nginx.com>
parents:
8328
diff
changeset
|
2989 } while (q != ngx_queue_sentinel(&ctx->frames)); |
8308
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2990 |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2991 return NGX_OK; |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2992 } |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2993 |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2994 |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2995 static void |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2996 ngx_quic_free_frames(ngx_connection_t *c, ngx_queue_t *frames) |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2997 { |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2998 ngx_queue_t *q; |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
2999 ngx_quic_frame_t *f; |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3000 |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3001 do { |
8334
72d20158c814
Added reordering support for STREAM frames.
Vladimir Homutov <vl@nginx.com>
parents:
8333
diff
changeset
|
3002 q = ngx_queue_head(frames); |
72d20158c814
Added reordering support for STREAM frames.
Vladimir Homutov <vl@nginx.com>
parents:
8333
diff
changeset
|
3003 |
72d20158c814
Added reordering support for STREAM frames.
Vladimir Homutov <vl@nginx.com>
parents:
8333
diff
changeset
|
3004 if (q == ngx_queue_sentinel(frames)) { |
72d20158c814
Added reordering support for STREAM frames.
Vladimir Homutov <vl@nginx.com>
parents:
8333
diff
changeset
|
3005 break; |
72d20158c814
Added reordering support for STREAM frames.
Vladimir Homutov <vl@nginx.com>
parents:
8333
diff
changeset
|
3006 } |
72d20158c814
Added reordering support for STREAM frames.
Vladimir Homutov <vl@nginx.com>
parents:
8333
diff
changeset
|
3007 |
72d20158c814
Added reordering support for STREAM frames.
Vladimir Homutov <vl@nginx.com>
parents:
8333
diff
changeset
|
3008 ngx_queue_remove(q); |
72d20158c814
Added reordering support for STREAM frames.
Vladimir Homutov <vl@nginx.com>
parents:
8333
diff
changeset
|
3009 |
8308
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3010 f = ngx_queue_data(q, ngx_quic_frame_t, queue); |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3011 |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3012 ngx_quic_free_frame(c, f); |
8334
72d20158c814
Added reordering support for STREAM frames.
Vladimir Homutov <vl@nginx.com>
parents:
8333
diff
changeset
|
3013 } while (1); |
8308
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3014 } |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3015 |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3016 |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3017 static ngx_int_t |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3018 ngx_quic_send_frames(ngx_connection_t *c, ngx_queue_t *frames) |
8225 | 3019 { |
8289
949b95e4d504
Merged ngx_quic_send_packet() into ngx_quic_send_frames().
Vladimir Homutov <vl@nginx.com>
parents:
8288
diff
changeset
|
3020 ssize_t len; |
949b95e4d504
Merged ngx_quic_send_packet() into ngx_quic_send_frames().
Vladimir Homutov <vl@nginx.com>
parents:
8288
diff
changeset
|
3021 u_char *p; |
8308
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3022 ngx_msec_t now; |
8289
949b95e4d504
Merged ngx_quic_send_packet() into ngx_quic_send_frames().
Vladimir Homutov <vl@nginx.com>
parents:
8288
diff
changeset
|
3023 ngx_str_t out, res; |
8308
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3024 ngx_queue_t *q; |
8385
fb7422074258
Added generation of CC frames with error on connection termination.
Vladimir Homutov <vl@nginx.com>
parents:
8384
diff
changeset
|
3025 ngx_ssl_conn_t *ssl_conn; |
8308
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3026 ngx_quic_frame_t *f, *start; |
8289
949b95e4d504
Merged ngx_quic_send_packet() into ngx_quic_send_frames().
Vladimir Homutov <vl@nginx.com>
parents:
8288
diff
changeset
|
3027 ngx_quic_header_t pkt; |
8306
058a5af7ddfc
Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents:
8305
diff
changeset
|
3028 ngx_quic_secrets_t *keys; |
8331
bda817d16cc2
Rename types and variables used for packet number space.
Vladimir Homutov <vl@nginx.com>
parents:
8328
diff
changeset
|
3029 ngx_quic_send_ctx_t *ctx; |
8289
949b95e4d504
Merged ngx_quic_send_packet() into ngx_quic_send_frames().
Vladimir Homutov <vl@nginx.com>
parents:
8288
diff
changeset
|
3030 ngx_quic_connection_t *qc; |
949b95e4d504
Merged ngx_quic_send_packet() into ngx_quic_send_frames().
Vladimir Homutov <vl@nginx.com>
parents:
8288
diff
changeset
|
3031 static ngx_str_t initial_token = ngx_null_string; |
949b95e4d504
Merged ngx_quic_send_packet() into ngx_quic_send_frames().
Vladimir Homutov <vl@nginx.com>
parents:
8288
diff
changeset
|
3032 static u_char src[NGX_QUIC_DEFAULT_MAX_PACKET_SIZE]; |
949b95e4d504
Merged ngx_quic_send_packet() into ngx_quic_send_frames().
Vladimir Homutov <vl@nginx.com>
parents:
8288
diff
changeset
|
3033 static u_char dst[NGX_QUIC_DEFAULT_MAX_PACKET_SIZE]; |
8225 | 3034 |
8359 | 3035 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, |
3036 "quic ngx_quic_send_frames"); | |
8308
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3037 |
8385
fb7422074258
Added generation of CC frames with error on connection termination.
Vladimir Homutov <vl@nginx.com>
parents:
8384
diff
changeset
|
3038 ssl_conn = c->ssl ? c->ssl->connection : NULL; |
fb7422074258
Added generation of CC frames with error on connection termination.
Vladimir Homutov <vl@nginx.com>
parents:
8384
diff
changeset
|
3039 |
8308
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3040 q = ngx_queue_head(frames); |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3041 start = ngx_queue_data(q, ngx_quic_frame_t, queue); |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3042 |
8331
bda817d16cc2
Rename types and variables used for packet number space.
Vladimir Homutov <vl@nginx.com>
parents:
8328
diff
changeset
|
3043 ctx = ngx_quic_get_send_ctx(c->quic, start->level); |
8225 | 3044 |
8289
949b95e4d504
Merged ngx_quic_send_packet() into ngx_quic_send_frames().
Vladimir Homutov <vl@nginx.com>
parents:
8288
diff
changeset
|
3045 ngx_memzero(&pkt, sizeof(ngx_quic_header_t)); |
8225 | 3046 |
8364
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3047 now = ngx_current_msec; |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3048 |
8289
949b95e4d504
Merged ngx_quic_send_packet() into ngx_quic_send_frames().
Vladimir Homutov <vl@nginx.com>
parents:
8288
diff
changeset
|
3049 p = src; |
949b95e4d504
Merged ngx_quic_send_packet() into ngx_quic_send_frames().
Vladimir Homutov <vl@nginx.com>
parents:
8288
diff
changeset
|
3050 out.data = src; |
8225 | 3051 |
8308
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3052 for (q = ngx_queue_head(frames); |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3053 q != ngx_queue_sentinel(frames); |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3054 q = ngx_queue_next(q)) |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3055 { |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3056 f = ngx_queue_data(q, ngx_quic_frame_t, queue); |
8225 | 3057 |
8359 | 3058 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, |
3059 "quic frame out: %s", f->info); | |
8225 | 3060 |
8308
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3061 len = ngx_quic_create_frame(p, f); |
8225 | 3062 if (len == -1) { |
3063 return NGX_ERROR; | |
3064 } | |
3065 | |
8312
053fa468b044
Fixed missing propagation of need_ack flag from frames to packet.
Vladimir Homutov <vl@nginx.com>
parents:
8311
diff
changeset
|
3066 if (f->need_ack) { |
053fa468b044
Fixed missing propagation of need_ack flag from frames to packet.
Vladimir Homutov <vl@nginx.com>
parents:
8311
diff
changeset
|
3067 pkt.need_ack = 1; |
053fa468b044
Fixed missing propagation of need_ack flag from frames to packet.
Vladimir Homutov <vl@nginx.com>
parents:
8311
diff
changeset
|
3068 } |
053fa468b044
Fixed missing propagation of need_ack flag from frames to packet.
Vladimir Homutov <vl@nginx.com>
parents:
8311
diff
changeset
|
3069 |
8225 | 3070 p += len; |
8331
bda817d16cc2
Rename types and variables used for packet number space.
Vladimir Homutov <vl@nginx.com>
parents:
8328
diff
changeset
|
3071 f->pnum = ctx->pnum; |
8364
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3072 f->last = now; |
8308
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3073 } |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3074 |
8225 | 3075 out.len = p - out.data; |
3076 | |
8301
c9fbe9508e1f
QUIC packet padding to fulfil header protection sample demands.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8300
diff
changeset
|
3077 while (out.len < 4) { |
c9fbe9508e1f
QUIC packet padding to fulfil header protection sample demands.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8300
diff
changeset
|
3078 *p++ = NGX_QUIC_FT_PADDING; |
c9fbe9508e1f
QUIC packet padding to fulfil header protection sample demands.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8300
diff
changeset
|
3079 out.len++; |
c9fbe9508e1f
QUIC packet padding to fulfil header protection sample demands.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8300
diff
changeset
|
3080 } |
c9fbe9508e1f
QUIC packet padding to fulfil header protection sample demands.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8300
diff
changeset
|
3081 |
8289
949b95e4d504
Merged ngx_quic_send_packet() into ngx_quic_send_frames().
Vladimir Homutov <vl@nginx.com>
parents:
8288
diff
changeset
|
3082 qc = c->quic; |
8225 | 3083 |
8306
058a5af7ddfc
Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents:
8305
diff
changeset
|
3084 keys = &c->quic->keys[start->level]; |
058a5af7ddfc
Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents:
8305
diff
changeset
|
3085 |
058a5af7ddfc
Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents:
8305
diff
changeset
|
3086 pkt.secret = &keys->server; |
058a5af7ddfc
Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents:
8305
diff
changeset
|
3087 |
8370
262396242352
Reworked macros for parsing/assembling packet types.
Vladimir Homutov <vl@nginx.com>
parents:
8369
diff
changeset
|
3088 pkt.flags = NGX_QUIC_PKT_FIXED_BIT; |
262396242352
Reworked macros for parsing/assembling packet types.
Vladimir Homutov <vl@nginx.com>
parents:
8369
diff
changeset
|
3089 |
8289
949b95e4d504
Merged ngx_quic_send_packet() into ngx_quic_send_frames().
Vladimir Homutov <vl@nginx.com>
parents:
8288
diff
changeset
|
3090 if (start->level == ssl_encryption_initial) { |
8370
262396242352
Reworked macros for parsing/assembling packet types.
Vladimir Homutov <vl@nginx.com>
parents:
8369
diff
changeset
|
3091 pkt.flags |= NGX_QUIC_PKT_LONG | NGX_QUIC_PKT_INITIAL; |
8225 | 3092 pkt.token = initial_token; |
3093 | |
8289
949b95e4d504
Merged ngx_quic_send_packet() into ngx_quic_send_frames().
Vladimir Homutov <vl@nginx.com>
parents:
8288
diff
changeset
|
3094 } else if (start->level == ssl_encryption_handshake) { |
8370
262396242352
Reworked macros for parsing/assembling packet types.
Vladimir Homutov <vl@nginx.com>
parents:
8369
diff
changeset
|
3095 pkt.flags |= NGX_QUIC_PKT_LONG | NGX_QUIC_PKT_HANDSHAKE; |
8315
fdda518d10ba
Proper handling of packet number in header.
Vladimir Homutov <vl@nginx.com>
parents:
8314
diff
changeset
|
3096 |
fdda518d10ba
Proper handling of packet number in header.
Vladimir Homutov <vl@nginx.com>
parents:
8314
diff
changeset
|
3097 } else { |
8370
262396242352
Reworked macros for parsing/assembling packet types.
Vladimir Homutov <vl@nginx.com>
parents:
8369
diff
changeset
|
3098 if (c->quic->key_phase) { |
262396242352
Reworked macros for parsing/assembling packet types.
Vladimir Homutov <vl@nginx.com>
parents:
8369
diff
changeset
|
3099 pkt.flags |= NGX_QUIC_PKT_KPHASE; |
262396242352
Reworked macros for parsing/assembling packet types.
Vladimir Homutov <vl@nginx.com>
parents:
8369
diff
changeset
|
3100 } |
8225 | 3101 } |
3102 | |
8331
bda817d16cc2
Rename types and variables used for packet number space.
Vladimir Homutov <vl@nginx.com>
parents:
8328
diff
changeset
|
3103 ngx_quic_set_packet_number(&pkt, ctx); |
8315
fdda518d10ba
Proper handling of packet number in header.
Vladimir Homutov <vl@nginx.com>
parents:
8314
diff
changeset
|
3104 |
8289
949b95e4d504
Merged ngx_quic_send_packet() into ngx_quic_send_frames().
Vladimir Homutov <vl@nginx.com>
parents:
8288
diff
changeset
|
3105 pkt.log = c->log; |
949b95e4d504
Merged ngx_quic_send_packet() into ngx_quic_send_frames().
Vladimir Homutov <vl@nginx.com>
parents:
8288
diff
changeset
|
3106 pkt.level = start->level; |
8344
e0abe17a2878
Removed source/destination swap from the function creating header.
Vladimir Homutov <vl@nginx.com>
parents:
8343
diff
changeset
|
3107 pkt.dcid = qc->scid; |
e0abe17a2878
Removed source/destination swap from the function creating header.
Vladimir Homutov <vl@nginx.com>
parents:
8343
diff
changeset
|
3108 pkt.scid = qc->dcid; |
8289
949b95e4d504
Merged ngx_quic_send_packet() into ngx_quic_send_frames().
Vladimir Homutov <vl@nginx.com>
parents:
8288
diff
changeset
|
3109 pkt.payload = out; |
8285
f85749b60e58
Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents:
8284
diff
changeset
|
3110 |
8289
949b95e4d504
Merged ngx_quic_send_packet() into ngx_quic_send_frames().
Vladimir Homutov <vl@nginx.com>
parents:
8288
diff
changeset
|
3111 res.data = dst; |
8285
f85749b60e58
Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents:
8284
diff
changeset
|
3112 |
8359 | 3113 ngx_log_debug6(NGX_LOG_DEBUG_EVENT, c->log, 0, |
3114 "quic packet ready: %ui bytes at level %d" | |
3115 " need_ack: %d number: %L encoded %d:0x%xD", | |
3116 out.len, start->level, pkt.need_ack, pkt.number, | |
3117 pkt.num_len, pkt.trunc); | |
3118 | |
8385
fb7422074258
Added generation of CC frames with error on connection termination.
Vladimir Homutov <vl@nginx.com>
parents:
8384
diff
changeset
|
3119 if (ngx_quic_encrypt(&pkt, ssl_conn, &res) != NGX_OK) { |
8225 | 3120 return NGX_ERROR; |
3121 } | |
3122 | |
8359 | 3123 #ifdef NGX_QUIC_DEBUG_PACKETS |
8360
f175006124d0
Cleaned up hexdumps in debug output.
Vladimir Homutov <vl@nginx.com>
parents:
8359
diff
changeset
|
3124 ngx_quic_hexdump(c->log, "quic packet to send", res.data, res.len); |
8359 | 3125 #endif |
8225 | 3126 |
8308
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3127 len = c->send(c, res.data, res.len); |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3128 if (len == NGX_ERROR || (size_t) len != res.len) { |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3129 return NGX_ERROR; |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3130 } |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3131 |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3132 /* len == NGX_OK || NGX_AGAIN */ |
8331
bda817d16cc2
Rename types and variables used for packet number space.
Vladimir Homutov <vl@nginx.com>
parents:
8328
diff
changeset
|
3133 ctx->pnum++; |
8225 | 3134 |
8308
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3135 return pkt.need_ack ? NGX_OK : NGX_DONE; |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3136 } |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3137 |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3138 |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3139 static void |
8331
bda817d16cc2
Rename types and variables used for packet number space.
Vladimir Homutov <vl@nginx.com>
parents:
8328
diff
changeset
|
3140 ngx_quic_set_packet_number(ngx_quic_header_t *pkt, ngx_quic_send_ctx_t *ctx) |
8315
fdda518d10ba
Proper handling of packet number in header.
Vladimir Homutov <vl@nginx.com>
parents:
8314
diff
changeset
|
3141 { |
fdda518d10ba
Proper handling of packet number in header.
Vladimir Homutov <vl@nginx.com>
parents:
8314
diff
changeset
|
3142 uint64_t delta; |
fdda518d10ba
Proper handling of packet number in header.
Vladimir Homutov <vl@nginx.com>
parents:
8314
diff
changeset
|
3143 |
8331
bda817d16cc2
Rename types and variables used for packet number space.
Vladimir Homutov <vl@nginx.com>
parents:
8328
diff
changeset
|
3144 delta = ctx->pnum - ctx->largest_ack; |
bda817d16cc2
Rename types and variables used for packet number space.
Vladimir Homutov <vl@nginx.com>
parents:
8328
diff
changeset
|
3145 pkt->number = ctx->pnum; |
8315
fdda518d10ba
Proper handling of packet number in header.
Vladimir Homutov <vl@nginx.com>
parents:
8314
diff
changeset
|
3146 |
fdda518d10ba
Proper handling of packet number in header.
Vladimir Homutov <vl@nginx.com>
parents:
8314
diff
changeset
|
3147 if (delta <= 0x7F) { |
fdda518d10ba
Proper handling of packet number in header.
Vladimir Homutov <vl@nginx.com>
parents:
8314
diff
changeset
|
3148 pkt->num_len = 1; |
8331
bda817d16cc2
Rename types and variables used for packet number space.
Vladimir Homutov <vl@nginx.com>
parents:
8328
diff
changeset
|
3149 pkt->trunc = ctx->pnum & 0xff; |
8315
fdda518d10ba
Proper handling of packet number in header.
Vladimir Homutov <vl@nginx.com>
parents:
8314
diff
changeset
|
3150 |
fdda518d10ba
Proper handling of packet number in header.
Vladimir Homutov <vl@nginx.com>
parents:
8314
diff
changeset
|
3151 } else if (delta <= 0x7FFF) { |
fdda518d10ba
Proper handling of packet number in header.
Vladimir Homutov <vl@nginx.com>
parents:
8314
diff
changeset
|
3152 pkt->num_len = 2; |
fdda518d10ba
Proper handling of packet number in header.
Vladimir Homutov <vl@nginx.com>
parents:
8314
diff
changeset
|
3153 pkt->flags |= 0x1; |
8331
bda817d16cc2
Rename types and variables used for packet number space.
Vladimir Homutov <vl@nginx.com>
parents:
8328
diff
changeset
|
3154 pkt->trunc = ctx->pnum & 0xffff; |
8315
fdda518d10ba
Proper handling of packet number in header.
Vladimir Homutov <vl@nginx.com>
parents:
8314
diff
changeset
|
3155 |
fdda518d10ba
Proper handling of packet number in header.
Vladimir Homutov <vl@nginx.com>
parents:
8314
diff
changeset
|
3156 } else if (delta <= 0x7FFFFF) { |
fdda518d10ba
Proper handling of packet number in header.
Vladimir Homutov <vl@nginx.com>
parents:
8314
diff
changeset
|
3157 pkt->num_len = 3; |
fdda518d10ba
Proper handling of packet number in header.
Vladimir Homutov <vl@nginx.com>
parents:
8314
diff
changeset
|
3158 pkt->flags |= 0x2; |
8331
bda817d16cc2
Rename types and variables used for packet number space.
Vladimir Homutov <vl@nginx.com>
parents:
8328
diff
changeset
|
3159 pkt->trunc = ctx->pnum & 0xffffff; |
8315
fdda518d10ba
Proper handling of packet number in header.
Vladimir Homutov <vl@nginx.com>
parents:
8314
diff
changeset
|
3160 |
fdda518d10ba
Proper handling of packet number in header.
Vladimir Homutov <vl@nginx.com>
parents:
8314
diff
changeset
|
3161 } else { |
fdda518d10ba
Proper handling of packet number in header.
Vladimir Homutov <vl@nginx.com>
parents:
8314
diff
changeset
|
3162 pkt->num_len = 4; |
fdda518d10ba
Proper handling of packet number in header.
Vladimir Homutov <vl@nginx.com>
parents:
8314
diff
changeset
|
3163 pkt->flags |= 0x3; |
8331
bda817d16cc2
Rename types and variables used for packet number space.
Vladimir Homutov <vl@nginx.com>
parents:
8328
diff
changeset
|
3164 pkt->trunc = ctx->pnum & 0xffffffff; |
8315
fdda518d10ba
Proper handling of packet number in header.
Vladimir Homutov <vl@nginx.com>
parents:
8314
diff
changeset
|
3165 } |
fdda518d10ba
Proper handling of packet number in header.
Vladimir Homutov <vl@nginx.com>
parents:
8314
diff
changeset
|
3166 } |
fdda518d10ba
Proper handling of packet number in header.
Vladimir Homutov <vl@nginx.com>
parents:
8314
diff
changeset
|
3167 |
fdda518d10ba
Proper handling of packet number in header.
Vladimir Homutov <vl@nginx.com>
parents:
8314
diff
changeset
|
3168 |
fdda518d10ba
Proper handling of packet number in header.
Vladimir Homutov <vl@nginx.com>
parents:
8314
diff
changeset
|
3169 static void |
8308
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3170 ngx_quic_retransmit_handler(ngx_event_t *ev) |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3171 { |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3172 ngx_uint_t i; |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3173 ngx_msec_t wait, nswait; |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3174 ngx_connection_t *c; |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3175 ngx_quic_connection_t *qc; |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3176 |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3177 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ev->log, 0, |
8359 | 3178 "quic retransmit timer"); |
8308
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3179 |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3180 c = ev->data; |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3181 qc = c->quic; |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3182 |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3183 wait = 0; |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3184 |
8331
bda817d16cc2
Rename types and variables used for packet number space.
Vladimir Homutov <vl@nginx.com>
parents:
8328
diff
changeset
|
3185 for (i = 0; i < NGX_QUIC_SEND_CTX_LAST; i++) { |
bda817d16cc2
Rename types and variables used for packet number space.
Vladimir Homutov <vl@nginx.com>
parents:
8328
diff
changeset
|
3186 if (ngx_quic_retransmit(c, &qc->send_ctx[i], &nswait) != NGX_OK) { |
8355
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
3187 ngx_quic_close_connection(c, NGX_ERROR); |
8308
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3188 return; |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3189 } |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3190 |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3191 if (i == 0) { |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3192 wait = nswait; |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3193 |
8392
5ffb21c5c93d
Fixed frame retransmissions.
Vladimir Homutov <vl@nginx.com>
parents:
8388
diff
changeset
|
3194 } else if (nswait > 0 && (wait == 0 || wait > nswait)) { |
8308
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3195 wait = nswait; |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3196 } |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3197 } |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3198 |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3199 if (wait > 0) { |
8369
bddf704d62c1
Renamed retransmit event object in preparation for retry support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8368
diff
changeset
|
3200 ngx_add_timer(&qc->retransmit, wait); |
8308
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3201 } |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3202 } |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3203 |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3204 |
8309 | 3205 static void |
3206 ngx_quic_push_handler(ngx_event_t *ev) | |
3207 { | |
8334
72d20158c814
Added reordering support for STREAM frames.
Vladimir Homutov <vl@nginx.com>
parents:
8333
diff
changeset
|
3208 ngx_connection_t *c; |
8309 | 3209 |
8359 | 3210 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ev->log, 0, "quic push timer"); |
8309 | 3211 |
3212 c = ev->data; | |
3213 | |
3214 if (ngx_quic_output(c) != NGX_OK) { | |
8355
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
3215 ngx_quic_close_connection(c, NGX_ERROR); |
8309 | 3216 return; |
3217 } | |
3218 } | |
3219 | |
3220 | |
8308
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3221 static ngx_int_t |
8331
bda817d16cc2
Rename types and variables used for packet number space.
Vladimir Homutov <vl@nginx.com>
parents:
8328
diff
changeset
|
3222 ngx_quic_retransmit(ngx_connection_t *c, ngx_quic_send_ctx_t *ctx, |
8308
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3223 ngx_msec_t *waitp) |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3224 { |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3225 uint64_t pn; |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3226 ngx_msec_t now, wait; |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3227 ngx_queue_t *q, range; |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3228 ngx_quic_frame_t *f, *start; |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3229 ngx_quic_connection_t *qc; |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3230 |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3231 qc = c->quic; |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3232 |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3233 now = ngx_current_msec; |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3234 |
8331
bda817d16cc2
Rename types and variables used for packet number space.
Vladimir Homutov <vl@nginx.com>
parents:
8328
diff
changeset
|
3235 if (ngx_queue_empty(&ctx->sent)) { |
8308
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3236 *waitp = 0; |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3237 return NGX_OK; |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3238 } |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3239 |
8331
bda817d16cc2
Rename types and variables used for packet number space.
Vladimir Homutov <vl@nginx.com>
parents:
8328
diff
changeset
|
3240 q = ngx_queue_head(&ctx->sent); |
8308
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3241 |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3242 do { |
8363
d3395396ce51
Fixed packet retransmission.
Roman Arutyunyan <arut@nginx.com>
parents:
8362
diff
changeset
|
3243 start = ngx_queue_data(q, ngx_quic_frame_t, queue); |
d3395396ce51
Fixed packet retransmission.
Roman Arutyunyan <arut@nginx.com>
parents:
8362
diff
changeset
|
3244 |
d3395396ce51
Fixed packet retransmission.
Roman Arutyunyan <arut@nginx.com>
parents:
8362
diff
changeset
|
3245 wait = start->last + qc->tp.max_ack_delay - now; |
d3395396ce51
Fixed packet retransmission.
Roman Arutyunyan <arut@nginx.com>
parents:
8362
diff
changeset
|
3246 |
d3395396ce51
Fixed packet retransmission.
Roman Arutyunyan <arut@nginx.com>
parents:
8362
diff
changeset
|
3247 if ((ngx_msec_int_t) wait > 0) { |
d3395396ce51
Fixed packet retransmission.
Roman Arutyunyan <arut@nginx.com>
parents:
8362
diff
changeset
|
3248 break; |
d3395396ce51
Fixed packet retransmission.
Roman Arutyunyan <arut@nginx.com>
parents:
8362
diff
changeset
|
3249 } |
d3395396ce51
Fixed packet retransmission.
Roman Arutyunyan <arut@nginx.com>
parents:
8362
diff
changeset
|
3250 |
d3395396ce51
Fixed packet retransmission.
Roman Arutyunyan <arut@nginx.com>
parents:
8362
diff
changeset
|
3251 pn = start->pnum; |
d3395396ce51
Fixed packet retransmission.
Roman Arutyunyan <arut@nginx.com>
parents:
8362
diff
changeset
|
3252 |
8308
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3253 ngx_queue_init(&range); |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3254 |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3255 /* send frames with same packet number to the wire */ |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3256 do { |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3257 f = ngx_queue_data(q, ngx_quic_frame_t, queue); |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3258 |
8388 | 3259 if (now - start->first > qc->tp.max_idle_timeout) { |
8308
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3260 ngx_log_error(NGX_LOG_ERR, c->log, 0, |
8361 | 3261 "quic retransmission timeout"); |
8308
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3262 return NGX_DECLINED; |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3263 } |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3264 |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3265 if (f->pnum != pn) { |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3266 break; |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3267 } |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3268 |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3269 q = ngx_queue_next(q); |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3270 |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3271 ngx_queue_remove(&f->queue); |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3272 ngx_queue_insert_tail(&range, &f->queue); |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3273 |
8331
bda817d16cc2
Rename types and variables used for packet number space.
Vladimir Homutov <vl@nginx.com>
parents:
8328
diff
changeset
|
3274 } while (q != ngx_queue_sentinel(&ctx->sent)); |
8308
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3275 |
8364
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3276 ngx_quic_congestion_lost(c, start->last); |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3277 |
8308
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3278 /* NGX_DONE is impossible here, such frames don't get into this queue */ |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3279 if (ngx_quic_send_frames(c, &range) != NGX_OK) { |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3280 return NGX_ERROR; |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3281 } |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3282 |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3283 /* move frames group to the end of queue */ |
8331
bda817d16cc2
Rename types and variables used for packet number space.
Vladimir Homutov <vl@nginx.com>
parents:
8328
diff
changeset
|
3284 ngx_queue_add(&ctx->sent, &range); |
bda817d16cc2
Rename types and variables used for packet number space.
Vladimir Homutov <vl@nginx.com>
parents:
8328
diff
changeset
|
3285 |
8392
5ffb21c5c93d
Fixed frame retransmissions.
Vladimir Homutov <vl@nginx.com>
parents:
8388
diff
changeset
|
3286 wait = qc->tp.max_ack_delay; |
5ffb21c5c93d
Fixed frame retransmissions.
Vladimir Homutov <vl@nginx.com>
parents:
8388
diff
changeset
|
3287 |
8331
bda817d16cc2
Rename types and variables used for packet number space.
Vladimir Homutov <vl@nginx.com>
parents:
8328
diff
changeset
|
3288 } while (q != ngx_queue_sentinel(&ctx->sent)); |
8308
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3289 |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3290 *waitp = wait; |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3291 |
8225 | 3292 return NGX_OK; |
3293 } | |
3294 | |
3295 | |
3296 ngx_connection_t * | |
3297 ngx_quic_create_uni_stream(ngx_connection_t *c) | |
3298 { | |
8280
b364af7f9f3f
Removed ngx_quic_stream_node_t.
Roman Arutyunyan <arut@nginx.com>
parents:
8279
diff
changeset
|
3299 ngx_uint_t id; |
b364af7f9f3f
Removed ngx_quic_stream_node_t.
Roman Arutyunyan <arut@nginx.com>
parents:
8279
diff
changeset
|
3300 ngx_quic_stream_t *qs, *sn; |
b364af7f9f3f
Removed ngx_quic_stream_node_t.
Roman Arutyunyan <arut@nginx.com>
parents:
8279
diff
changeset
|
3301 ngx_quic_connection_t *qc; |
8229
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
3302 |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
3303 qs = c->qs; |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
3304 qc = qs->parent->quic; |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
3305 |
8280
b364af7f9f3f
Removed ngx_quic_stream_node_t.
Roman Arutyunyan <arut@nginx.com>
parents:
8279
diff
changeset
|
3306 id = (qc->streams.id_counter << 2) |
b364af7f9f3f
Removed ngx_quic_stream_node_t.
Roman Arutyunyan <arut@nginx.com>
parents:
8279
diff
changeset
|
3307 | NGX_QUIC_STREAM_SERVER_INITIATED |
b364af7f9f3f
Removed ngx_quic_stream_node_t.
Roman Arutyunyan <arut@nginx.com>
parents:
8279
diff
changeset
|
3308 | NGX_QUIC_STREAM_UNIDIRECTIONAL; |
8229
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
3309 |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
3310 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, |
8359 | 3311 "quic creating server uni stream #%ui id %ui", |
8229
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
3312 qc->streams.id_counter, id); |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
3313 |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
3314 qc->streams.id_counter++; |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
3315 |
8282
4cf00c14f11a
Safe QUIC stream creation.
Roman Arutyunyan <arut@nginx.com>
parents:
8281
diff
changeset
|
3316 sn = ngx_quic_create_stream(qs->parent, id, 0); |
8229
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
3317 if (sn == NULL) { |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
3318 return NULL; |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
3319 } |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
3320 |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
3321 return sn->c; |
8225 | 3322 } |
3323 | |
3324 | |
3325 static void | |
3326 ngx_quic_rbtree_insert_stream(ngx_rbtree_node_t *temp, | |
3327 ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel) | |
3328 { | |
8280
b364af7f9f3f
Removed ngx_quic_stream_node_t.
Roman Arutyunyan <arut@nginx.com>
parents:
8279
diff
changeset
|
3329 ngx_rbtree_node_t **p; |
b364af7f9f3f
Removed ngx_quic_stream_node_t.
Roman Arutyunyan <arut@nginx.com>
parents:
8279
diff
changeset
|
3330 ngx_quic_stream_t *qn, *qnt; |
8225 | 3331 |
3332 for ( ;; ) { | |
8284
2935a11c55b6
Fixed QUIC stream insert and find.
Roman Arutyunyan <arut@nginx.com>
parents:
8282
diff
changeset
|
3333 qn = (ngx_quic_stream_t *) node; |
2935a11c55b6
Fixed QUIC stream insert and find.
Roman Arutyunyan <arut@nginx.com>
parents:
8282
diff
changeset
|
3334 qnt = (ngx_quic_stream_t *) temp; |
8225 | 3335 |
8284
2935a11c55b6
Fixed QUIC stream insert and find.
Roman Arutyunyan <arut@nginx.com>
parents:
8282
diff
changeset
|
3336 p = (qn->id < qnt->id) ? &temp->left : &temp->right; |
8225 | 3337 |
3338 if (*p == sentinel) { | |
3339 break; | |
3340 } | |
3341 | |
3342 temp = *p; | |
3343 } | |
3344 | |
3345 *p = node; | |
3346 node->parent = temp; | |
3347 node->left = sentinel; | |
3348 node->right = sentinel; | |
3349 ngx_rbt_red(node); | |
3350 } | |
3351 | |
3352 | |
8280
b364af7f9f3f
Removed ngx_quic_stream_node_t.
Roman Arutyunyan <arut@nginx.com>
parents:
8279
diff
changeset
|
3353 static ngx_quic_stream_t * |
8284
2935a11c55b6
Fixed QUIC stream insert and find.
Roman Arutyunyan <arut@nginx.com>
parents:
8282
diff
changeset
|
3354 ngx_quic_find_stream(ngx_rbtree_t *rbtree, uint64_t id) |
8225 | 3355 { |
3356 ngx_rbtree_node_t *node, *sentinel; | |
8284
2935a11c55b6
Fixed QUIC stream insert and find.
Roman Arutyunyan <arut@nginx.com>
parents:
8282
diff
changeset
|
3357 ngx_quic_stream_t *qn; |
8225 | 3358 |
3359 node = rbtree->root; | |
3360 sentinel = rbtree->sentinel; | |
3361 | |
3362 while (node != sentinel) { | |
8284
2935a11c55b6
Fixed QUIC stream insert and find.
Roman Arutyunyan <arut@nginx.com>
parents:
8282
diff
changeset
|
3363 qn = (ngx_quic_stream_t *) node; |
8225 | 3364 |
8284
2935a11c55b6
Fixed QUIC stream insert and find.
Roman Arutyunyan <arut@nginx.com>
parents:
8282
diff
changeset
|
3365 if (id == qn->id) { |
2935a11c55b6
Fixed QUIC stream insert and find.
Roman Arutyunyan <arut@nginx.com>
parents:
8282
diff
changeset
|
3366 return qn; |
8225 | 3367 } |
3368 | |
8284
2935a11c55b6
Fixed QUIC stream insert and find.
Roman Arutyunyan <arut@nginx.com>
parents:
8282
diff
changeset
|
3369 node = (id < qn->id) ? node->left : node->right; |
8225 | 3370 } |
3371 | |
3372 return NULL; | |
3373 } | |
3374 | |
3375 | |
8280
b364af7f9f3f
Removed ngx_quic_stream_node_t.
Roman Arutyunyan <arut@nginx.com>
parents:
8279
diff
changeset
|
3376 static ngx_quic_stream_t * |
8282
4cf00c14f11a
Safe QUIC stream creation.
Roman Arutyunyan <arut@nginx.com>
parents:
8281
diff
changeset
|
3377 ngx_quic_create_stream(ngx_connection_t *c, uint64_t id, size_t rcvbuf_size) |
8229
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
3378 { |
8365
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
3379 ngx_log_t *log; |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
3380 ngx_pool_t *pool; |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
3381 ngx_quic_stream_t *sn; |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
3382 ngx_pool_cleanup_t *cln; |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
3383 ngx_quic_connection_t *qc; |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
3384 |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
3385 qc = c->quic; |
8229
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
3386 |
8282
4cf00c14f11a
Safe QUIC stream creation.
Roman Arutyunyan <arut@nginx.com>
parents:
8281
diff
changeset
|
3387 pool = ngx_create_pool(NGX_DEFAULT_POOL_SIZE, c->log); |
4cf00c14f11a
Safe QUIC stream creation.
Roman Arutyunyan <arut@nginx.com>
parents:
8281
diff
changeset
|
3388 if (pool == NULL) { |
8229
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
3389 return NULL; |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
3390 } |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
3391 |
8282
4cf00c14f11a
Safe QUIC stream creation.
Roman Arutyunyan <arut@nginx.com>
parents:
8281
diff
changeset
|
3392 sn = ngx_pcalloc(pool, sizeof(ngx_quic_stream_t)); |
4cf00c14f11a
Safe QUIC stream creation.
Roman Arutyunyan <arut@nginx.com>
parents:
8281
diff
changeset
|
3393 if (sn == NULL) { |
4cf00c14f11a
Safe QUIC stream creation.
Roman Arutyunyan <arut@nginx.com>
parents:
8281
diff
changeset
|
3394 ngx_destroy_pool(pool); |
8229
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
3395 return NULL; |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
3396 } |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
3397 |
8282
4cf00c14f11a
Safe QUIC stream creation.
Roman Arutyunyan <arut@nginx.com>
parents:
8281
diff
changeset
|
3398 sn->node.key = id; |
4cf00c14f11a
Safe QUIC stream creation.
Roman Arutyunyan <arut@nginx.com>
parents:
8281
diff
changeset
|
3399 sn->parent = c; |
4cf00c14f11a
Safe QUIC stream creation.
Roman Arutyunyan <arut@nginx.com>
parents:
8281
diff
changeset
|
3400 sn->id = id; |
4cf00c14f11a
Safe QUIC stream creation.
Roman Arutyunyan <arut@nginx.com>
parents:
8281
diff
changeset
|
3401 |
4cf00c14f11a
Safe QUIC stream creation.
Roman Arutyunyan <arut@nginx.com>
parents:
8281
diff
changeset
|
3402 sn->b = ngx_create_temp_buf(pool, rcvbuf_size); |
4cf00c14f11a
Safe QUIC stream creation.
Roman Arutyunyan <arut@nginx.com>
parents:
8281
diff
changeset
|
3403 if (sn->b == NULL) { |
4cf00c14f11a
Safe QUIC stream creation.
Roman Arutyunyan <arut@nginx.com>
parents:
8281
diff
changeset
|
3404 ngx_destroy_pool(pool); |
8229
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
3405 return NULL; |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
3406 } |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
3407 |
8334
72d20158c814
Added reordering support for STREAM frames.
Vladimir Homutov <vl@nginx.com>
parents:
8333
diff
changeset
|
3408 ngx_queue_init(&sn->fs.frames); |
72d20158c814
Added reordering support for STREAM frames.
Vladimir Homutov <vl@nginx.com>
parents:
8333
diff
changeset
|
3409 |
8229
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
3410 log = ngx_palloc(pool, sizeof(ngx_log_t)); |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
3411 if (log == NULL) { |
8282
4cf00c14f11a
Safe QUIC stream creation.
Roman Arutyunyan <arut@nginx.com>
parents:
8281
diff
changeset
|
3412 ngx_destroy_pool(pool); |
8229
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
3413 return NULL; |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
3414 } |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
3415 |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
3416 *log = *c->log; |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
3417 pool->log = log; |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
3418 |
8282
4cf00c14f11a
Safe QUIC stream creation.
Roman Arutyunyan <arut@nginx.com>
parents:
8281
diff
changeset
|
3419 sn->c = ngx_get_connection(-1, log); |
4cf00c14f11a
Safe QUIC stream creation.
Roman Arutyunyan <arut@nginx.com>
parents:
8281
diff
changeset
|
3420 if (sn->c == NULL) { |
4cf00c14f11a
Safe QUIC stream creation.
Roman Arutyunyan <arut@nginx.com>
parents:
8281
diff
changeset
|
3421 ngx_destroy_pool(pool); |
8229
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
3422 return NULL; |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
3423 } |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
3424 |
8280
b364af7f9f3f
Removed ngx_quic_stream_node_t.
Roman Arutyunyan <arut@nginx.com>
parents:
8279
diff
changeset
|
3425 sn->c->qs = sn; |
8282
4cf00c14f11a
Safe QUIC stream creation.
Roman Arutyunyan <arut@nginx.com>
parents:
8281
diff
changeset
|
3426 sn->c->pool = pool; |
4cf00c14f11a
Safe QUIC stream creation.
Roman Arutyunyan <arut@nginx.com>
parents:
8281
diff
changeset
|
3427 sn->c->ssl = c->ssl; |
4cf00c14f11a
Safe QUIC stream creation.
Roman Arutyunyan <arut@nginx.com>
parents:
8281
diff
changeset
|
3428 sn->c->sockaddr = c->sockaddr; |
4cf00c14f11a
Safe QUIC stream creation.
Roman Arutyunyan <arut@nginx.com>
parents:
8281
diff
changeset
|
3429 sn->c->listening = c->listening; |
4cf00c14f11a
Safe QUIC stream creation.
Roman Arutyunyan <arut@nginx.com>
parents:
8281
diff
changeset
|
3430 sn->c->addr_text = c->addr_text; |
4cf00c14f11a
Safe QUIC stream creation.
Roman Arutyunyan <arut@nginx.com>
parents:
8281
diff
changeset
|
3431 sn->c->local_sockaddr = c->local_sockaddr; |
4cf00c14f11a
Safe QUIC stream creation.
Roman Arutyunyan <arut@nginx.com>
parents:
8281
diff
changeset
|
3432 sn->c->number = ngx_atomic_fetch_add(ngx_connection_counter, 1); |
8229
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
3433 |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
3434 sn->c->recv = ngx_quic_stream_recv; |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
3435 sn->c->send = ngx_quic_stream_send; |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
3436 sn->c->send_chain = ngx_quic_stream_send_chain; |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
3437 |
8282
4cf00c14f11a
Safe QUIC stream creation.
Roman Arutyunyan <arut@nginx.com>
parents:
8281
diff
changeset
|
3438 sn->c->read->log = c->log; |
4cf00c14f11a
Safe QUIC stream creation.
Roman Arutyunyan <arut@nginx.com>
parents:
8281
diff
changeset
|
3439 sn->c->write->log = c->log; |
4cf00c14f11a
Safe QUIC stream creation.
Roman Arutyunyan <arut@nginx.com>
parents:
8281
diff
changeset
|
3440 |
8362
44cac24aaa44
Assign connection number to every QUIC stream log.
Roman Arutyunyan <arut@nginx.com>
parents:
8361
diff
changeset
|
3441 log->connection = sn->c->number; |
44cac24aaa44
Assign connection number to every QUIC stream log.
Roman Arutyunyan <arut@nginx.com>
parents:
8361
diff
changeset
|
3442 |
8364
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3443 if ((id & NGX_QUIC_STREAM_UNIDIRECTIONAL) == 0 |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3444 || (id & NGX_QUIC_STREAM_SERVER_INITIATED)) |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3445 { |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3446 sn->c->write->ready = 1; |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3447 } |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3448 |
8365
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
3449 if (id & NGX_QUIC_STREAM_UNIDIRECTIONAL) { |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
3450 if (id & NGX_QUIC_STREAM_SERVER_INITIATED) { |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
3451 sn->send_max_data = qc->ctp.initial_max_stream_data_uni; |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
3452 } |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
3453 |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
3454 } else { |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
3455 if (id & NGX_QUIC_STREAM_SERVER_INITIATED) { |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
3456 sn->send_max_data = qc->ctp.initial_max_stream_data_bidi_remote; |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
3457 } else { |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
3458 sn->send_max_data = qc->ctp.initial_max_stream_data_bidi_local; |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
3459 } |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
3460 } |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
3461 |
8239
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
3462 cln = ngx_pool_cleanup_add(pool, 0); |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
3463 if (cln == NULL) { |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
3464 ngx_close_connection(sn->c); |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
3465 ngx_destroy_pool(pool); |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
3466 return NULL; |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
3467 } |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
3468 |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
3469 cln->handler = ngx_quic_stream_cleanup_handler; |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
3470 cln->data = sn->c; |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
3471 |
8282
4cf00c14f11a
Safe QUIC stream creation.
Roman Arutyunyan <arut@nginx.com>
parents:
8281
diff
changeset
|
3472 ngx_rbtree_insert(&c->quic->streams.tree, &sn->node); |
4cf00c14f11a
Safe QUIC stream creation.
Roman Arutyunyan <arut@nginx.com>
parents:
8281
diff
changeset
|
3473 |
8229
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
3474 return sn; |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
3475 } |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
3476 |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
3477 |
8225 | 3478 static ssize_t |
3479 ngx_quic_stream_recv(ngx_connection_t *c, u_char *buf, size_t size) | |
3480 { | |
8338
0f9e9786b90d
Added primitive flow control mechanisms.
Vladimir Homutov <vl@nginx.com>
parents:
8337
diff
changeset
|
3481 ssize_t len; |
0f9e9786b90d
Added primitive flow control mechanisms.
Vladimir Homutov <vl@nginx.com>
parents:
8337
diff
changeset
|
3482 ngx_buf_t *b; |
0f9e9786b90d
Added primitive flow control mechanisms.
Vladimir Homutov <vl@nginx.com>
parents:
8337
diff
changeset
|
3483 ngx_event_t *rev; |
0f9e9786b90d
Added primitive flow control mechanisms.
Vladimir Homutov <vl@nginx.com>
parents:
8337
diff
changeset
|
3484 ngx_connection_t *pc; |
0f9e9786b90d
Added primitive flow control mechanisms.
Vladimir Homutov <vl@nginx.com>
parents:
8337
diff
changeset
|
3485 ngx_quic_frame_t *frame; |
0f9e9786b90d
Added primitive flow control mechanisms.
Vladimir Homutov <vl@nginx.com>
parents:
8337
diff
changeset
|
3486 ngx_quic_stream_t *qs; |
0f9e9786b90d
Added primitive flow control mechanisms.
Vladimir Homutov <vl@nginx.com>
parents:
8337
diff
changeset
|
3487 ngx_quic_connection_t *qc; |
8225 | 3488 |
3489 qs = c->qs; | |
8280
b364af7f9f3f
Removed ngx_quic_stream_node_t.
Roman Arutyunyan <arut@nginx.com>
parents:
8279
diff
changeset
|
3490 b = qs->b; |
8338
0f9e9786b90d
Added primitive flow control mechanisms.
Vladimir Homutov <vl@nginx.com>
parents:
8337
diff
changeset
|
3491 pc = qs->parent; |
0f9e9786b90d
Added primitive flow control mechanisms.
Vladimir Homutov <vl@nginx.com>
parents:
8337
diff
changeset
|
3492 qc = pc->quic; |
8279
5f223cdad40e
Implemented eof in QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8278
diff
changeset
|
3493 rev = c->read; |
8225 | 3494 |
8359 | 3495 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, |
3496 "quic stream id 0x%xi recv: eof:%d, avail:%z", | |
3497 qs->id, rev->pending_eof, b->last - b->pos); | |
8279
5f223cdad40e
Implemented eof in QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8278
diff
changeset
|
3498 |
8266
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
3499 if (b->pos == b->last) { |
8279
5f223cdad40e
Implemented eof in QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8278
diff
changeset
|
3500 rev->ready = 0; |
5f223cdad40e
Implemented eof in QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8278
diff
changeset
|
3501 |
5f223cdad40e
Implemented eof in QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8278
diff
changeset
|
3502 if (rev->pending_eof) { |
5f223cdad40e
Implemented eof in QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8278
diff
changeset
|
3503 rev->eof = 1; |
5f223cdad40e
Implemented eof in QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8278
diff
changeset
|
3504 return 0; |
5f223cdad40e
Implemented eof in QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8278
diff
changeset
|
3505 } |
5f223cdad40e
Implemented eof in QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8278
diff
changeset
|
3506 |
8359 | 3507 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, |
3508 "quic stream id 0x%xi recv() not ready", qs->id); | |
8266
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
3509 return NGX_AGAIN; |
8225 | 3510 } |
3511 | |
3512 len = ngx_min(b->last - b->pos, (ssize_t) size); | |
3513 | |
3514 ngx_memcpy(buf, b->pos, len); | |
3515 | |
3516 b->pos += len; | |
8365
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
3517 qc->streams.received += len; |
8225 | 3518 |
8266
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
3519 if (b->pos == b->last) { |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
3520 b->pos = b->start; |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
3521 b->last = b->start; |
8294
32db41d603cd
Fixed handling QUIC stream eof.
Roman Arutyunyan <arut@nginx.com>
parents:
8293
diff
changeset
|
3522 rev->ready = rev->pending_eof; |
8266
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
3523 } |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
3524 |
8359 | 3525 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, |
3526 "quic stream id 0x%xi recv: %z of %uz", qs->id, len, size); | |
8225 | 3527 |
8338
0f9e9786b90d
Added primitive flow control mechanisms.
Vladimir Homutov <vl@nginx.com>
parents:
8337
diff
changeset
|
3528 if (!rev->pending_eof) { |
0f9e9786b90d
Added primitive flow control mechanisms.
Vladimir Homutov <vl@nginx.com>
parents:
8337
diff
changeset
|
3529 frame = ngx_quic_alloc_frame(pc, 0); |
0f9e9786b90d
Added primitive flow control mechanisms.
Vladimir Homutov <vl@nginx.com>
parents:
8337
diff
changeset
|
3530 if (frame == NULL) { |
0f9e9786b90d
Added primitive flow control mechanisms.
Vladimir Homutov <vl@nginx.com>
parents:
8337
diff
changeset
|
3531 return NGX_ERROR; |
0f9e9786b90d
Added primitive flow control mechanisms.
Vladimir Homutov <vl@nginx.com>
parents:
8337
diff
changeset
|
3532 } |
0f9e9786b90d
Added primitive flow control mechanisms.
Vladimir Homutov <vl@nginx.com>
parents:
8337
diff
changeset
|
3533 |
0f9e9786b90d
Added primitive flow control mechanisms.
Vladimir Homutov <vl@nginx.com>
parents:
8337
diff
changeset
|
3534 frame->level = ssl_encryption_application; |
0f9e9786b90d
Added primitive flow control mechanisms.
Vladimir Homutov <vl@nginx.com>
parents:
8337
diff
changeset
|
3535 frame->type = NGX_QUIC_FT_MAX_STREAM_DATA; |
0f9e9786b90d
Added primitive flow control mechanisms.
Vladimir Homutov <vl@nginx.com>
parents:
8337
diff
changeset
|
3536 frame->u.max_stream_data.id = qs->id; |
0f9e9786b90d
Added primitive flow control mechanisms.
Vladimir Homutov <vl@nginx.com>
parents:
8337
diff
changeset
|
3537 frame->u.max_stream_data.limit = qs->fs.received + (b->pos - b->start) |
0f9e9786b90d
Added primitive flow control mechanisms.
Vladimir Homutov <vl@nginx.com>
parents:
8337
diff
changeset
|
3538 + (b->end - b->last); |
0f9e9786b90d
Added primitive flow control mechanisms.
Vladimir Homutov <vl@nginx.com>
parents:
8337
diff
changeset
|
3539 |
0f9e9786b90d
Added primitive flow control mechanisms.
Vladimir Homutov <vl@nginx.com>
parents:
8337
diff
changeset
|
3540 ngx_sprintf(frame->info, "MAX_STREAM_DATA id:%d limit:%d l=%d on recv", |
0f9e9786b90d
Added primitive flow control mechanisms.
Vladimir Homutov <vl@nginx.com>
parents:
8337
diff
changeset
|
3541 (int) frame->u.max_stream_data.id, |
0f9e9786b90d
Added primitive flow control mechanisms.
Vladimir Homutov <vl@nginx.com>
parents:
8337
diff
changeset
|
3542 (int) frame->u.max_stream_data.limit, |
0f9e9786b90d
Added primitive flow control mechanisms.
Vladimir Homutov <vl@nginx.com>
parents:
8337
diff
changeset
|
3543 frame->level); |
0f9e9786b90d
Added primitive flow control mechanisms.
Vladimir Homutov <vl@nginx.com>
parents:
8337
diff
changeset
|
3544 |
0f9e9786b90d
Added primitive flow control mechanisms.
Vladimir Homutov <vl@nginx.com>
parents:
8337
diff
changeset
|
3545 ngx_quic_queue_frame(pc->quic, frame); |
0f9e9786b90d
Added primitive flow control mechanisms.
Vladimir Homutov <vl@nginx.com>
parents:
8337
diff
changeset
|
3546 } |
0f9e9786b90d
Added primitive flow control mechanisms.
Vladimir Homutov <vl@nginx.com>
parents:
8337
diff
changeset
|
3547 |
8365
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
3548 if ((qc->streams.recv_max_data / 2) < qc->streams.received) { |
8338
0f9e9786b90d
Added primitive flow control mechanisms.
Vladimir Homutov <vl@nginx.com>
parents:
8337
diff
changeset
|
3549 |
0f9e9786b90d
Added primitive flow control mechanisms.
Vladimir Homutov <vl@nginx.com>
parents:
8337
diff
changeset
|
3550 frame = ngx_quic_alloc_frame(pc, 0); |
0f9e9786b90d
Added primitive flow control mechanisms.
Vladimir Homutov <vl@nginx.com>
parents:
8337
diff
changeset
|
3551 |
0f9e9786b90d
Added primitive flow control mechanisms.
Vladimir Homutov <vl@nginx.com>
parents:
8337
diff
changeset
|
3552 if (frame == NULL) { |
0f9e9786b90d
Added primitive flow control mechanisms.
Vladimir Homutov <vl@nginx.com>
parents:
8337
diff
changeset
|
3553 return NGX_ERROR; |
0f9e9786b90d
Added primitive flow control mechanisms.
Vladimir Homutov <vl@nginx.com>
parents:
8337
diff
changeset
|
3554 } |
0f9e9786b90d
Added primitive flow control mechanisms.
Vladimir Homutov <vl@nginx.com>
parents:
8337
diff
changeset
|
3555 |
8365
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
3556 qc->streams.recv_max_data *= 2; |
8338
0f9e9786b90d
Added primitive flow control mechanisms.
Vladimir Homutov <vl@nginx.com>
parents:
8337
diff
changeset
|
3557 |
0f9e9786b90d
Added primitive flow control mechanisms.
Vladimir Homutov <vl@nginx.com>
parents:
8337
diff
changeset
|
3558 frame->level = ssl_encryption_application; |
0f9e9786b90d
Added primitive flow control mechanisms.
Vladimir Homutov <vl@nginx.com>
parents:
8337
diff
changeset
|
3559 frame->type = NGX_QUIC_FT_MAX_DATA; |
8365
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
3560 frame->u.max_data.max_data = qc->streams.recv_max_data; |
8338
0f9e9786b90d
Added primitive flow control mechanisms.
Vladimir Homutov <vl@nginx.com>
parents:
8337
diff
changeset
|
3561 |
0f9e9786b90d
Added primitive flow control mechanisms.
Vladimir Homutov <vl@nginx.com>
parents:
8337
diff
changeset
|
3562 ngx_sprintf(frame->info, "MAX_DATA max_data:%d level=%d on recv", |
0f9e9786b90d
Added primitive flow control mechanisms.
Vladimir Homutov <vl@nginx.com>
parents:
8337
diff
changeset
|
3563 (int) frame->u.max_data.max_data, frame->level); |
0f9e9786b90d
Added primitive flow control mechanisms.
Vladimir Homutov <vl@nginx.com>
parents:
8337
diff
changeset
|
3564 |
0f9e9786b90d
Added primitive flow control mechanisms.
Vladimir Homutov <vl@nginx.com>
parents:
8337
diff
changeset
|
3565 ngx_quic_queue_frame(pc->quic, frame); |
0f9e9786b90d
Added primitive flow control mechanisms.
Vladimir Homutov <vl@nginx.com>
parents:
8337
diff
changeset
|
3566 |
8359 | 3567 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, |
3568 "quic stream id 0x%xi recv: increased max data: %ui", | |
8365
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
3569 qs->id, qc->streams.recv_max_data); |
8338
0f9e9786b90d
Added primitive flow control mechanisms.
Vladimir Homutov <vl@nginx.com>
parents:
8337
diff
changeset
|
3570 } |
0f9e9786b90d
Added primitive flow control mechanisms.
Vladimir Homutov <vl@nginx.com>
parents:
8337
diff
changeset
|
3571 |
8225 | 3572 return len; |
3573 } | |
3574 | |
3575 | |
3576 static ssize_t | |
3577 ngx_quic_stream_send(ngx_connection_t *c, u_char *buf, size_t size) | |
3578 { | |
8345
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
3579 u_char *p, *end; |
8364
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3580 size_t fsize, limit, n, len; |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3581 uint64_t sent, unacked; |
8280
b364af7f9f3f
Removed ngx_quic_stream_node_t.
Roman Arutyunyan <arut@nginx.com>
parents:
8279
diff
changeset
|
3582 ngx_connection_t *pc; |
b364af7f9f3f
Removed ngx_quic_stream_node_t.
Roman Arutyunyan <arut@nginx.com>
parents:
8279
diff
changeset
|
3583 ngx_quic_frame_t *frame; |
b364af7f9f3f
Removed ngx_quic_stream_node_t.
Roman Arutyunyan <arut@nginx.com>
parents:
8279
diff
changeset
|
3584 ngx_quic_stream_t *qs; |
b364af7f9f3f
Removed ngx_quic_stream_node_t.
Roman Arutyunyan <arut@nginx.com>
parents:
8279
diff
changeset
|
3585 ngx_quic_connection_t *qc; |
8225 | 3586 |
3587 qs = c->qs; | |
3588 pc = qs->parent; | |
3589 qc = pc->quic; | |
3590 | |
8281
618a65de08b3
When closing a QUIC connection, wait for all streams to finish.
Roman Arutyunyan <arut@nginx.com>
parents:
8280
diff
changeset
|
3591 if (qc->closing) { |
618a65de08b3
When closing a QUIC connection, wait for all streams to finish.
Roman Arutyunyan <arut@nginx.com>
parents:
8280
diff
changeset
|
3592 return NGX_ERROR; |
618a65de08b3
When closing a QUIC connection, wait for all streams to finish.
Roman Arutyunyan <arut@nginx.com>
parents:
8280
diff
changeset
|
3593 } |
618a65de08b3
When closing a QUIC connection, wait for all streams to finish.
Roman Arutyunyan <arut@nginx.com>
parents:
8280
diff
changeset
|
3594 |
8359 | 3595 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, |
3596 "quic stream id 0x%xi send: %uz", qs->id, size); | |
8281
618a65de08b3
When closing a QUIC connection, wait for all streams to finish.
Roman Arutyunyan <arut@nginx.com>
parents:
8280
diff
changeset
|
3597 |
8345
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
3598 /* |
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
3599 * we need to fit at least 1 frame into a packet, thus account head/tail; |
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
3600 * 25 = 1 + 8x3 is max header for STREAM frame, with 1 byte for frame type |
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
3601 */ |
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
3602 limit = qc->ctp.max_packet_size - NGX_QUIC_MAX_SHORT_HEADER - 25 |
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
3603 - EVP_GCM_TLS_TAG_LEN; |
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
3604 |
8364
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3605 len = size; |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3606 sent = c->sent; |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3607 unacked = sent - qs->acked; |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3608 |
8365
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
3609 if (qc->streams.send_max_data == 0) { |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
3610 qc->streams.send_max_data = qc->ctp.initial_max_data; |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
3611 } |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
3612 |
8364
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3613 if (unacked >= NGX_QUIC_STREAM_BUFSIZE) { |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3614 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3615 "quic send hit buffer size"); |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3616 len = 0; |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3617 |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3618 } else if (unacked + len > NGX_QUIC_STREAM_BUFSIZE) { |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3619 len = NGX_QUIC_STREAM_BUFSIZE - unacked; |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3620 } |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3621 |
8365
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
3622 if (qc->streams.sent >= qc->streams.send_max_data) { |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
3623 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
3624 "quic send hit MAX_DATA"); |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
3625 len = 0; |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
3626 |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
3627 } else if (qc->streams.sent + len > qc->streams.send_max_data) { |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
3628 len = qc->streams.send_max_data - qc->streams.sent; |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
3629 } |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
3630 |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
3631 if (sent >= qs->send_max_data) { |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
3632 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
3633 "quic send hit MAX_STREAM_DATA"); |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
3634 len = 0; |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
3635 |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
3636 } else if (sent + len > qs->send_max_data) { |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
3637 len = qs->send_max_data - sent; |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
3638 } |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
3639 |
8345
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
3640 p = (u_char *) buf; |
8364
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3641 end = (u_char *) buf + len; |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3642 n = 0; |
8345
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
3643 |
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
3644 while (p < end) { |
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
3645 |
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
3646 fsize = ngx_min(limit, (size_t) (end - p)); |
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
3647 |
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
3648 frame = ngx_quic_alloc_frame(pc, fsize); |
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
3649 if (frame == NULL) { |
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
3650 return 0; |
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
3651 } |
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
3652 |
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
3653 ngx_memcpy(frame->data, p, fsize); |
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
3654 |
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
3655 frame->level = ssl_encryption_application; |
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
3656 frame->type = NGX_QUIC_FT_STREAM6; /* OFF=1 LEN=1 FIN=0 */ |
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
3657 frame->u.stream.off = 1; |
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
3658 frame->u.stream.len = 1; |
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
3659 frame->u.stream.fin = 0; |
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
3660 |
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
3661 frame->u.stream.type = frame->type; |
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
3662 frame->u.stream.stream_id = qs->id; |
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
3663 frame->u.stream.offset = c->sent; |
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
3664 frame->u.stream.length = fsize; |
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
3665 frame->u.stream.data = frame->data; |
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
3666 |
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
3667 c->sent += fsize; |
8365
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
3668 qc->streams.sent += fsize; |
8345
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
3669 p += fsize; |
8364
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3670 n += fsize; |
8345
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
3671 |
8359 | 3672 ngx_sprintf(frame->info, "stream 0x%xi len=%ui level=%d", |
8345
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
3673 qs->id, fsize, frame->level); |
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
3674 |
6481427ca3fc
Respecting maximum packet size.
Vladimir Homutov <vl@nginx.com>
parents:
8344
diff
changeset
|
3675 ngx_quic_queue_frame(qc, frame); |
8225 | 3676 } |
3677 | |
8365
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
3678 ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0, |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
3679 "quic send %uz of %uz, sent:%O, unacked:%uL", |
fab75acb1f72
Respect MAX_DATA and MAX_STREAM_DATA from QUIC client.
Roman Arutyunyan <arut@nginx.com>
parents:
8364
diff
changeset
|
3680 n, size, c->sent, (uint64_t) c->sent - qs->acked); |
8364
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3681 |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3682 if (n != size) { |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3683 c->write->ready = 0; |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3684 } |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3685 |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3686 if (n == 0) { |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3687 return NGX_AGAIN; |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3688 } |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3689 |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3690 return n; |
8225 | 3691 } |
3692 | |
3693 | |
8239
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
3694 static void |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
3695 ngx_quic_stream_cleanup_handler(void *data) |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
3696 { |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
3697 ngx_connection_t *c = data; |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
3698 |
8280
b364af7f9f3f
Removed ngx_quic_stream_node_t.
Roman Arutyunyan <arut@nginx.com>
parents:
8279
diff
changeset
|
3699 ngx_connection_t *pc; |
b364af7f9f3f
Removed ngx_quic_stream_node_t.
Roman Arutyunyan <arut@nginx.com>
parents:
8279
diff
changeset
|
3700 ngx_quic_frame_t *frame; |
b364af7f9f3f
Removed ngx_quic_stream_node_t.
Roman Arutyunyan <arut@nginx.com>
parents:
8279
diff
changeset
|
3701 ngx_quic_stream_t *qs; |
b364af7f9f3f
Removed ngx_quic_stream_node_t.
Roman Arutyunyan <arut@nginx.com>
parents:
8279
diff
changeset
|
3702 ngx_quic_connection_t *qc; |
8239
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
3703 |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
3704 qs = c->qs; |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
3705 pc = qs->parent; |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
3706 qc = pc->quic; |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
3707 |
8359 | 3708 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, |
3709 "quic stream id 0x%xi cleanup", qs->id); | |
8281
618a65de08b3
When closing a QUIC connection, wait for all streams to finish.
Roman Arutyunyan <arut@nginx.com>
parents:
8280
diff
changeset
|
3710 |
618a65de08b3
When closing a QUIC connection, wait for all streams to finish.
Roman Arutyunyan <arut@nginx.com>
parents:
8280
diff
changeset
|
3711 ngx_rbtree_delete(&qc->streams.tree, &qs->node); |
8348
d42b50d239f4
Fixed memory leak with reordered stream frames.
Vladimir Homutov <vl@nginx.com>
parents:
8346
diff
changeset
|
3712 ngx_quic_free_frames(pc, &qs->fs.frames); |
8281
618a65de08b3
When closing a QUIC connection, wait for all streams to finish.
Roman Arutyunyan <arut@nginx.com>
parents:
8280
diff
changeset
|
3713 |
618a65de08b3
When closing a QUIC connection, wait for all streams to finish.
Roman Arutyunyan <arut@nginx.com>
parents:
8280
diff
changeset
|
3714 if (qc->closing) { |
8355
ad3a6f069498
Added proper handling of connection close phases.
Vladimir Homutov <vl@nginx.com>
parents:
8354
diff
changeset
|
3715 /* schedule handler call to continue ngx_quic_close_connection() */ |
8281
618a65de08b3
When closing a QUIC connection, wait for all streams to finish.
Roman Arutyunyan <arut@nginx.com>
parents:
8280
diff
changeset
|
3716 ngx_post_event(pc->read, &ngx_posted_events); |
618a65de08b3
When closing a QUIC connection, wait for all streams to finish.
Roman Arutyunyan <arut@nginx.com>
parents:
8280
diff
changeset
|
3717 return; |
618a65de08b3
When closing a QUIC connection, wait for all streams to finish.
Roman Arutyunyan <arut@nginx.com>
parents:
8280
diff
changeset
|
3718 } |
618a65de08b3
When closing a QUIC connection, wait for all streams to finish.
Roman Arutyunyan <arut@nginx.com>
parents:
8280
diff
changeset
|
3719 |
8280
b364af7f9f3f
Removed ngx_quic_stream_node_t.
Roman Arutyunyan <arut@nginx.com>
parents:
8279
diff
changeset
|
3720 if ((qs->id & 0x03) == NGX_QUIC_STREAM_UNIDIRECTIONAL) { |
8239
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
3721 /* do not send fin for client unidirectional streams */ |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
3722 return; |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
3723 } |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
3724 |
8359 | 3725 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, |
3726 "quic stream id 0x%xi send fin", qs->id); | |
8239
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
3727 |
8286 | 3728 frame = ngx_quic_alloc_frame(pc, 0); |
8239
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
3729 if (frame == NULL) { |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
3730 return; |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
3731 } |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
3732 |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
3733 frame->level = ssl_encryption_application; |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
3734 frame->type = NGX_QUIC_FT_STREAM7; /* OFF=1 LEN=1 FIN=1 */ |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
3735 frame->u.stream.off = 1; |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
3736 frame->u.stream.len = 1; |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
3737 frame->u.stream.fin = 1; |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
3738 |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
3739 frame->u.stream.type = frame->type; |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
3740 frame->u.stream.stream_id = qs->id; |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
3741 frame->u.stream.offset = c->sent; |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
3742 frame->u.stream.length = 0; |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
3743 frame->u.stream.data = NULL; |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
3744 |
8359 | 3745 ngx_sprintf(frame->info, "stream 0x%xi fin=1 level=%d", |
3746 qs->id, frame->level); | |
8239
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
3747 |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
3748 ngx_quic_queue_frame(qc, frame); |
8293
1ec905f4d851
Push QUIC stream frames in send() and cleanup handler.
Roman Arutyunyan <arut@nginx.com>
parents:
8290
diff
changeset
|
3749 |
1ec905f4d851
Push QUIC stream frames in send() and cleanup handler.
Roman Arutyunyan <arut@nginx.com>
parents:
8290
diff
changeset
|
3750 (void) ngx_quic_output(pc); |
8239
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
3751 } |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
3752 |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
3753 |
8225 | 3754 static ngx_chain_t * |
3755 ngx_quic_stream_send_chain(ngx_connection_t *c, ngx_chain_t *in, | |
3756 off_t limit) | |
3757 { | |
3758 size_t len; | |
3759 ssize_t n; | |
3760 ngx_buf_t *b; | |
3761 | |
3762 for ( /* void */; in; in = in->next) { | |
3763 b = in->buf; | |
3764 | |
3765 if (!ngx_buf_in_memory(b)) { | |
3766 continue; | |
3767 } | |
3768 | |
3769 if (ngx_buf_size(b) == 0) { | |
3770 continue; | |
3771 } | |
3772 | |
3773 len = b->last - b->pos; | |
3774 | |
3775 n = ngx_quic_stream_send(c, b->pos, len); | |
3776 | |
3777 if (n == NGX_ERROR) { | |
3778 return NGX_CHAIN_ERROR; | |
3779 } | |
3780 | |
3781 if (n == NGX_AGAIN) { | |
3782 return in; | |
3783 } | |
3784 | |
8350
47dac6e0521a
Fixed QUIC buffer consumption in send_chain().
Roman Arutyunyan <arut@nginx.com>
parents:
8348
diff
changeset
|
3785 b->pos += n; |
47dac6e0521a
Fixed QUIC buffer consumption in send_chain().
Roman Arutyunyan <arut@nginx.com>
parents:
8348
diff
changeset
|
3786 |
8225 | 3787 if (n != (ssize_t) len) { |
3788 return in; | |
3789 } | |
3790 } | |
3791 | |
3792 return NULL; | |
3793 } | |
8286 | 3794 |
3795 | |
3796 static ngx_quic_frame_t * | |
3797 ngx_quic_alloc_frame(ngx_connection_t *c, size_t size) | |
3798 { | |
3799 u_char *p; | |
8308
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3800 ngx_queue_t *q; |
8286 | 3801 ngx_quic_frame_t *frame; |
3802 ngx_quic_connection_t *qc; | |
3803 | |
3804 if (size) { | |
3805 p = ngx_alloc(size, c->log); | |
3806 if (p == NULL) { | |
3807 return NULL; | |
3808 } | |
3809 | |
3810 } else { | |
3811 p = NULL; | |
3812 } | |
3813 | |
3814 qc = c->quic; | |
8308
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3815 |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3816 if (!ngx_queue_empty(&qc->free_frames)) { |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3817 |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3818 q = ngx_queue_head(&qc->free_frames); |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3819 frame = ngx_queue_data(q, ngx_quic_frame_t, queue); |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3820 |
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3821 ngx_queue_remove(&frame->queue); |
8286 | 3822 |
8359 | 3823 #ifdef NGX_QUIC_DEBUG_FRAMES_ALLOC |
8286 | 3824 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, |
8359 | 3825 "quic reuse frame n:%ui", qc->nframes); |
3826 #endif | |
8286 | 3827 |
3828 } else { | |
3829 frame = ngx_pcalloc(c->pool, sizeof(ngx_quic_frame_t)); | |
3830 if (frame == NULL) { | |
3831 ngx_free(p); | |
3832 return NULL; | |
3833 } | |
3834 | |
3835 #if (NGX_DEBUG) | |
3836 ++qc->nframes; | |
3837 #endif | |
3838 | |
8359 | 3839 #ifdef NGX_QUIC_DEBUG_FRAMES_ALLOC |
8286 | 3840 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, |
8359 | 3841 "quic alloc frame n:%ui", qc->nframes); |
3842 #endif | |
8286 | 3843 } |
3844 | |
3845 ngx_memzero(frame, sizeof(ngx_quic_frame_t)); | |
3846 | |
3847 frame->data = p; | |
3848 | |
3849 return frame; | |
3850 } | |
3851 | |
3852 | |
3853 static void | |
8364
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3854 ngx_quic_congestion_ack(ngx_connection_t *c, ngx_quic_frame_t *f) |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3855 { |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3856 ssize_t n; |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3857 ngx_msec_t timer; |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3858 ngx_quic_congestion_t *cg; |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3859 ngx_quic_connection_t *qc; |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3860 |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3861 qc = c->quic; |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3862 cg = &qc->congestion; |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3863 |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3864 n = ngx_quic_create_frame(NULL, f); |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3865 |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3866 cg->in_flight -= n; |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3867 |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3868 timer = f->last - cg->recovery_start; |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3869 |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3870 if ((ngx_msec_int_t) timer <= 0) { |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3871 return; |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3872 } |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3873 |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3874 if (cg->window < cg->ssthresh) { |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3875 cg->window += n; |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3876 |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3877 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3878 "quic congestion slow start win:%uz, ss:%uz, if:%uz", |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3879 cg->window, cg->ssthresh, cg->in_flight); |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3880 |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3881 } else { |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3882 cg->window += qc->tp.max_packet_size * n / cg->window; |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3883 |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3884 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3885 "quic congestion avoidance win:%uz, ss:%uz, if:%uz", |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3886 cg->window, cg->ssthresh, cg->in_flight); |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3887 } |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3888 |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3889 /* prevent recovery_start from wrapping */ |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3890 |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3891 timer = cg->recovery_start - ngx_current_msec + qc->tp.max_idle_timeout * 2; |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3892 |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3893 if ((ngx_msec_int_t) timer < 0) { |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3894 cg->recovery_start = ngx_current_msec - qc->tp.max_idle_timeout * 2; |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3895 } |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3896 } |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3897 |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3898 |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3899 static void |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3900 ngx_quic_congestion_lost(ngx_connection_t *c, ngx_msec_t sent) |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3901 { |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3902 ngx_msec_t timer; |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3903 ngx_quic_congestion_t *cg; |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3904 ngx_quic_connection_t *qc; |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3905 |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3906 qc = c->quic; |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3907 cg = &qc->congestion; |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3908 |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3909 timer = sent - cg->recovery_start; |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3910 |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3911 if ((ngx_msec_int_t) timer <= 0) { |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3912 return; |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3913 } |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3914 |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3915 cg->recovery_start = ngx_current_msec; |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3916 cg->window /= 2; |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3917 |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3918 if (cg->window < qc->tp.max_packet_size * 2) { |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3919 cg->window = qc->tp.max_packet_size * 2; |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3920 } |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3921 |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3922 cg->ssthresh = cg->window; |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3923 |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3924 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3925 "quic congestion lost win:%uz, ss:%uz, if:%uz", |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3926 cg->window, cg->ssthresh, cg->in_flight); |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3927 } |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3928 |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3929 |
eee307399229
QUIC basic congestion control.
Roman Arutyunyan <arut@nginx.com>
parents:
8363
diff
changeset
|
3930 static void |
8286 | 3931 ngx_quic_free_frame(ngx_connection_t *c, ngx_quic_frame_t *frame) |
3932 { | |
3933 ngx_quic_connection_t *qc; | |
3934 | |
3935 qc = c->quic; | |
3936 | |
3937 if (frame->data) { | |
3938 ngx_free(frame->data); | |
8394 | 3939 frame->data = NULL; |
8286 | 3940 } |
3941 | |
8308
e10b4c61420f
Implemented retransmission and retransmit queue.
Vladimir Homutov <vl@nginx.com>
parents:
8307
diff
changeset
|
3942 ngx_queue_insert_head(&qc->free_frames, &frame->queue); |
8286 | 3943 |
8359 | 3944 #ifdef NGX_QUIC_DEBUG_FRAMES_ALLOC |
8286 | 3945 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, |
8359 | 3946 "quic free frame n:%ui", qc->nframes); |
3947 #endif | |
8286 | 3948 } |