Mercurial > hg > nginx
annotate src/event/ngx_event_quic.c @ 8274:ee53bfd8f9ed quic
Added QUIC version check for sending HANDSHAKE_DONE frame.
author | Vladimir Homutov <vl@nginx.com> |
---|---|
date | Tue, 24 Mar 2020 12:15:39 +0300 |
parents | cb75f194f1f0 |
children | 19660929e8ff |
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 |
8263
1295b293d09a
Connection states code cleanup.
Vladimir Homutov <vl@nginx.com>
parents:
8260
diff
changeset
|
12 typedef enum { |
1295b293d09a
Connection states code cleanup.
Vladimir Homutov <vl@nginx.com>
parents:
8260
diff
changeset
|
13 NGX_QUIC_ST_INITIAL, /* connection just created */ |
1295b293d09a
Connection states code cleanup.
Vladimir Homutov <vl@nginx.com>
parents:
8260
diff
changeset
|
14 NGX_QUIC_ST_HANDSHAKE, /* handshake started */ |
1295b293d09a
Connection states code cleanup.
Vladimir Homutov <vl@nginx.com>
parents:
8260
diff
changeset
|
15 NGX_QUIC_ST_APPLICATION /* handshake complete */ |
1295b293d09a
Connection states code cleanup.
Vladimir Homutov <vl@nginx.com>
parents:
8260
diff
changeset
|
16 } ngx_quic_state_t; |
1295b293d09a
Connection states code cleanup.
Vladimir Homutov <vl@nginx.com>
parents:
8260
diff
changeset
|
17 |
1295b293d09a
Connection states code cleanup.
Vladimir Homutov <vl@nginx.com>
parents:
8260
diff
changeset
|
18 |
8266
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
19 #define NGX_QUIC_STREAM_BUFSIZE 16384 |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
20 |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
21 |
8225 | 22 typedef struct { |
23 ngx_rbtree_node_t node; | |
24 ngx_buf_t *b; | |
25 ngx_connection_t *c; | |
26 ngx_quic_stream_t s; | |
27 } ngx_quic_stream_node_t; | |
28 | |
29 | |
30 typedef struct { | |
31 ngx_rbtree_t tree; | |
32 ngx_rbtree_node_t sentinel; | |
33 ngx_connection_handler_pt handler; | |
8229
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
34 |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
35 ngx_uint_t id_counter; |
8225 | 36 } ngx_quic_streams_t; |
8182
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
37 |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
38 |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
39 struct ngx_quic_connection_s { |
8225 | 40 ngx_str_t scid; |
41 ngx_str_t dcid; | |
42 ngx_str_t token; | |
8182
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
43 |
8260
f388c0ad3477
Added processing of client transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8259
diff
changeset
|
44 ngx_uint_t client_tp_done; |
8247
e9891e8ee975
Configurable transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8246
diff
changeset
|
45 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
|
46 ngx_quic_tp_t ctp; |
8247
e9891e8ee975
Configurable transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8246
diff
changeset
|
47 |
8263
1295b293d09a
Connection states code cleanup.
Vladimir Homutov <vl@nginx.com>
parents:
8260
diff
changeset
|
48 ngx_quic_state_t state; |
1295b293d09a
Connection states code cleanup.
Vladimir Homutov <vl@nginx.com>
parents:
8260
diff
changeset
|
49 |
8225 | 50 /* current packet numbers for each namespace */ |
51 ngx_uint_t initial_pn; | |
52 ngx_uint_t handshake_pn; | |
53 ngx_uint_t appdata_pn; | |
8184
ec1f84996990
Split frame and packet generation into separate steps.
Vladimir Homutov <vl@nginx.com>
parents:
8183
diff
changeset
|
54 |
8225 | 55 ngx_quic_secrets_t secrets; |
56 ngx_ssl_t *ssl; | |
57 ngx_quic_frame_t *frames; | |
8208
4ae9ac69ab93
HTTP/QUIC interface reworked.
Vladimir Homutov <vl@nginx.com>
parents:
8207
diff
changeset
|
58 |
8225 | 59 ngx_quic_streams_t streams; |
8237
ff540f13d95d
MAX_DATA frame parser/handler.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8236
diff
changeset
|
60 ngx_uint_t max_data; |
8271
8e54a17dabee
Respect QUIC max_idle_timeout.
Roman Arutyunyan <arut@nginx.com>
parents:
8270
diff
changeset
|
61 ngx_uint_t send_timer_set; |
8e54a17dabee
Respect QUIC max_idle_timeout.
Roman Arutyunyan <arut@nginx.com>
parents:
8270
diff
changeset
|
62 /* unsigned send_timer_set:1 */ |
8259
9e9eab876964
Fixed CRYPTO offset generation.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8258
diff
changeset
|
63 |
9e9eab876964
Fixed CRYPTO offset generation.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8258
diff
changeset
|
64 #define SSL_ECRYPTION_LAST ((ssl_encryption_application) + 1) |
9e9eab876964
Fixed CRYPTO offset generation.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8258
diff
changeset
|
65 uint64_t crypto_offset[SSL_ECRYPTION_LAST]; |
8225 | 66 }; |
8206
8d6ac639feac
Added support of multiple QUIC packets in single datagram.
Vladimir Homutov <vl@nginx.com>
parents:
8205
diff
changeset
|
67 |
8182
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
68 |
8204
9e0c30e1f7fb
Compatibility with BoringSSL revised QUIC encryption secret APIs.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8203
diff
changeset
|
69 #if BORINGSSL_API_VERSION >= 10 |
9e0c30e1f7fb
Compatibility with BoringSSL revised QUIC encryption secret APIs.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8203
diff
changeset
|
70 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
|
71 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
|
72 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
|
73 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
|
74 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
|
75 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
|
76 #else |
8182
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
77 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
|
78 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
|
79 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
|
80 #endif |
8225 | 81 |
8182
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
82 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
|
83 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
|
84 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
|
85 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
|
86 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
|
87 |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
88 |
8225 | 89 static ngx_int_t ngx_quic_new_connection(ngx_connection_t *c, ngx_ssl_t *ssl, |
8247
e9891e8ee975
Configurable transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8246
diff
changeset
|
90 ngx_quic_tp_t *tp, ngx_quic_header_t *pkt); |
8225 | 91 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
|
92 static void ngx_quic_input_handler(ngx_event_t *rev); |
8225 | 93 static void ngx_quic_close_connection(ngx_connection_t *c); |
94 | |
95 static ngx_int_t ngx_quic_input(ngx_connection_t *c, ngx_buf_t *b); | |
96 static ngx_int_t ngx_quic_initial_input(ngx_connection_t *c, | |
97 ngx_quic_header_t *pkt); | |
98 static ngx_int_t ngx_quic_handshake_input(ngx_connection_t *c, | |
99 ngx_quic_header_t *pkt); | |
100 static ngx_int_t ngx_quic_app_input(ngx_connection_t *c, | |
101 ngx_quic_header_t *pkt); | |
102 static ngx_int_t ngx_quic_payload_handler(ngx_connection_t *c, | |
103 ngx_quic_header_t *pkt); | |
104 | |
105 static ngx_int_t ngx_quic_handle_ack_frame(ngx_connection_t *c, | |
106 ngx_quic_header_t *pkt, ngx_quic_ack_frame_t *f); | |
107 static ngx_int_t ngx_quic_handle_crypto_frame(ngx_connection_t *c, | |
108 ngx_quic_header_t *pkt, ngx_quic_crypto_frame_t *frame); | |
109 static ngx_int_t ngx_quic_handle_stream_frame(ngx_connection_t *c, | |
110 ngx_quic_header_t *pkt, ngx_quic_stream_frame_t *frame); | |
8245
a14afe21e692
Double MAX_STREAMS on STREAMS_BLOCKED.
Roman Arutyunyan <arut@nginx.com>
parents:
8241
diff
changeset
|
111 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
|
112 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
|
113 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
|
114 ngx_quic_header_t *pkt, ngx_quic_stream_data_blocked_frame_t *f); |
8225 | 115 |
116 static void ngx_quic_queue_frame(ngx_quic_connection_t *qc, | |
117 ngx_quic_frame_t *frame); | |
118 | |
119 static ngx_int_t ngx_quic_output(ngx_connection_t *c); | |
120 ngx_int_t ngx_quic_frames_send(ngx_connection_t *c, ngx_quic_frame_t *start, | |
121 ngx_quic_frame_t *end, size_t total); | |
122 static ngx_int_t ngx_quic_send_packet(ngx_connection_t *c, | |
123 ngx_quic_connection_t *qc, enum ssl_encryption_level_t level, | |
124 ngx_str_t *payload); | |
125 | |
126 | |
127 static void ngx_quic_rbtree_insert_stream(ngx_rbtree_node_t *temp, | |
128 ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel); | |
129 static ngx_quic_stream_node_t *ngx_quic_find_stream(ngx_rbtree_t *rbtree, | |
130 ngx_uint_t key); | |
8229
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
131 static ngx_quic_stream_node_t *ngx_quic_create_stream(ngx_connection_t *c, |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
132 ngx_uint_t id); |
8211
6bc18966b8c1
Stream "connection" read/write methods.
Vladimir Homutov <vl@nginx.com>
parents:
8209
diff
changeset
|
133 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
|
134 size_t size); |
6bc18966b8c1
Stream "connection" read/write methods.
Vladimir Homutov <vl@nginx.com>
parents:
8209
diff
changeset
|
135 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
|
136 size_t size); |
8239
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
137 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
|
138 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
|
139 ngx_chain_t *in, off_t limit); |
6bc18966b8c1
Stream "connection" read/write methods.
Vladimir Homutov <vl@nginx.com>
parents:
8209
diff
changeset
|
140 |
8225 | 141 |
8182
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
142 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
|
143 #if BORINGSSL_API_VERSION >= 10 |
9e0c30e1f7fb
Compatibility with BoringSSL revised QUIC encryption secret APIs.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8203
diff
changeset
|
144 ngx_quic_set_read_secret, |
9e0c30e1f7fb
Compatibility with BoringSSL revised QUIC encryption secret APIs.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8203
diff
changeset
|
145 ngx_quic_set_write_secret, |
9e0c30e1f7fb
Compatibility with BoringSSL revised QUIC encryption secret APIs.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8203
diff
changeset
|
146 #else |
8182
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
147 ngx_quic_set_encryption_secrets, |
8204
9e0c30e1f7fb
Compatibility with BoringSSL revised QUIC encryption secret APIs.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8203
diff
changeset
|
148 #endif |
8182
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
149 ngx_quic_add_handshake_data, |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
150 ngx_quic_flush_flight, |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
151 ngx_quic_send_alert, |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
152 }; |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
153 |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
154 |
8204
9e0c30e1f7fb
Compatibility with BoringSSL revised QUIC encryption secret APIs.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8203
diff
changeset
|
155 #if BORINGSSL_API_VERSION >= 10 |
9e0c30e1f7fb
Compatibility with BoringSSL revised QUIC encryption secret APIs.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8203
diff
changeset
|
156 |
9e0c30e1f7fb
Compatibility with BoringSSL revised QUIC encryption secret APIs.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8203
diff
changeset
|
157 static int |
9e0c30e1f7fb
Compatibility with BoringSSL revised QUIC encryption secret APIs.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8203
diff
changeset
|
158 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
|
159 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
|
160 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
|
161 { |
8221
69345a26ba69
Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
8220
diff
changeset
|
162 ngx_connection_t *c; |
8204
9e0c30e1f7fb
Compatibility with BoringSSL revised QUIC encryption secret APIs.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8203
diff
changeset
|
163 |
9e0c30e1f7fb
Compatibility with BoringSSL revised QUIC encryption secret APIs.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8203
diff
changeset
|
164 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
|
165 |
8221
69345a26ba69
Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
8220
diff
changeset
|
166 ngx_quic_hexdump(c->log, "level:%d read secret", |
69345a26ba69
Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
8220
diff
changeset
|
167 rsecret, secret_len, level); |
8204
9e0c30e1f7fb
Compatibility with BoringSSL revised QUIC encryption secret APIs.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8203
diff
changeset
|
168 |
8221
69345a26ba69
Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
8220
diff
changeset
|
169 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
|
170 rsecret, secret_len, |
69345a26ba69
Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
8220
diff
changeset
|
171 &c->quic->secrets.client); |
8204
9e0c30e1f7fb
Compatibility with BoringSSL revised QUIC encryption secret APIs.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8203
diff
changeset
|
172 } |
9e0c30e1f7fb
Compatibility with BoringSSL revised QUIC encryption secret APIs.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8203
diff
changeset
|
173 |
9e0c30e1f7fb
Compatibility with BoringSSL revised QUIC encryption secret APIs.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8203
diff
changeset
|
174 |
9e0c30e1f7fb
Compatibility with BoringSSL revised QUIC encryption secret APIs.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8203
diff
changeset
|
175 static int |
9e0c30e1f7fb
Compatibility with BoringSSL revised QUIC encryption secret APIs.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8203
diff
changeset
|
176 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
|
177 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
|
178 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
|
179 { |
8221
69345a26ba69
Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
8220
diff
changeset
|
180 ngx_connection_t *c; |
8204
9e0c30e1f7fb
Compatibility with BoringSSL revised QUIC encryption secret APIs.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8203
diff
changeset
|
181 |
9e0c30e1f7fb
Compatibility with BoringSSL revised QUIC encryption secret APIs.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8203
diff
changeset
|
182 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
|
183 |
8221
69345a26ba69
Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
8220
diff
changeset
|
184 ngx_quic_hexdump(c->log, "level:%d write secret", |
69345a26ba69
Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
8220
diff
changeset
|
185 wsecret, secret_len, level); |
8204
9e0c30e1f7fb
Compatibility with BoringSSL revised QUIC encryption secret APIs.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8203
diff
changeset
|
186 |
8221
69345a26ba69
Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
8220
diff
changeset
|
187 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
|
188 wsecret, secret_len, |
69345a26ba69
Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
8220
diff
changeset
|
189 &c->quic->secrets.server); |
8204
9e0c30e1f7fb
Compatibility with BoringSSL revised QUIC encryption secret APIs.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8203
diff
changeset
|
190 } |
9e0c30e1f7fb
Compatibility with BoringSSL revised QUIC encryption secret APIs.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8203
diff
changeset
|
191 |
9e0c30e1f7fb
Compatibility with BoringSSL revised QUIC encryption secret APIs.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8203
diff
changeset
|
192 #else |
9e0c30e1f7fb
Compatibility with BoringSSL revised QUIC encryption secret APIs.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8203
diff
changeset
|
193 |
8182
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
194 static int |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
195 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
|
196 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
|
197 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
|
198 { |
8221
69345a26ba69
Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
8220
diff
changeset
|
199 ngx_int_t rc; |
69345a26ba69
Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
8220
diff
changeset
|
200 ngx_connection_t *c; |
8182
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
201 |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
202 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
|
203 |
8222
bec4cd55361e
Fixed a typo with OpenSSL.
Vladimir Homutov <vl@nginx.com>
parents:
8221
diff
changeset
|
204 ngx_quic_hexdump(c->log, "level:%d read", rsecret, secret_len, level); |
8221
69345a26ba69
Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
8220
diff
changeset
|
205 ngx_quic_hexdump(c->log, "level:%d write", wsecret, secret_len, level); |
8182
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
206 |
8221
69345a26ba69
Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
8220
diff
changeset
|
207 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
|
208 rsecret, secret_len, |
69345a26ba69
Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
8220
diff
changeset
|
209 &c->quic->secrets.client); |
69345a26ba69
Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
8220
diff
changeset
|
210 if (rc != 1) { |
69345a26ba69
Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
8220
diff
changeset
|
211 return rc; |
8182
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
212 } |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
213 |
8221
69345a26ba69
Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
8220
diff
changeset
|
214 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
|
215 wsecret, secret_len, |
69345a26ba69
Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
8220
diff
changeset
|
216 &c->quic->secrets.server); |
8182
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
217 } |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
218 |
8204
9e0c30e1f7fb
Compatibility with BoringSSL revised QUIC encryption secret APIs.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8203
diff
changeset
|
219 #endif |
9e0c30e1f7fb
Compatibility with BoringSSL revised QUIC encryption secret APIs.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8203
diff
changeset
|
220 |
8182
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
221 |
8184
ec1f84996990
Split frame and packet generation into separate steps.
Vladimir Homutov <vl@nginx.com>
parents:
8183
diff
changeset
|
222 static int |
ec1f84996990
Split frame and packet generation into separate steps.
Vladimir Homutov <vl@nginx.com>
parents:
8183
diff
changeset
|
223 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
|
224 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
|
225 { |
8260
f388c0ad3477
Added processing of client transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8259
diff
changeset
|
226 u_char *p, *end; |
f388c0ad3477
Added processing of client transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8259
diff
changeset
|
227 size_t client_params_len; |
f388c0ad3477
Added processing of client transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8259
diff
changeset
|
228 const uint8_t *client_params; |
8225 | 229 ngx_quic_frame_t *frame; |
230 ngx_connection_t *c; | |
231 ngx_quic_connection_t *qc; | |
8184
ec1f84996990
Split frame and packet generation into separate steps.
Vladimir Homutov <vl@nginx.com>
parents:
8183
diff
changeset
|
232 |
ec1f84996990
Split frame and packet generation into separate steps.
Vladimir Homutov <vl@nginx.com>
parents:
8183
diff
changeset
|
233 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
|
234 qc = c->quic; |
ec1f84996990
Split frame and packet generation into separate steps.
Vladimir Homutov <vl@nginx.com>
parents:
8183
diff
changeset
|
235 |
8186
0a2683df5f11
Implemented improved version of quic_output().
Vladimir Homutov <vl@nginx.com>
parents:
8185
diff
changeset
|
236 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, |
0a2683df5f11
Implemented improved version of quic_output().
Vladimir Homutov <vl@nginx.com>
parents:
8185
diff
changeset
|
237 "ngx_quic_add_handshake_data"); |
8184
ec1f84996990
Split frame and packet generation into separate steps.
Vladimir Homutov <vl@nginx.com>
parents:
8183
diff
changeset
|
238 |
8260
f388c0ad3477
Added processing of client transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8259
diff
changeset
|
239 /* XXX: obtain client parameters after the handshake? */ |
f388c0ad3477
Added processing of client transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8259
diff
changeset
|
240 if (!qc->client_tp_done) { |
f388c0ad3477
Added processing of client transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8259
diff
changeset
|
241 |
f388c0ad3477
Added processing of client transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8259
diff
changeset
|
242 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
|
243 &client_params_len); |
f388c0ad3477
Added processing of client transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8259
diff
changeset
|
244 |
f388c0ad3477
Added processing of client transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8259
diff
changeset
|
245 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, |
f388c0ad3477
Added processing of client transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8259
diff
changeset
|
246 "SSL_get_peer_quic_transport_params(): params_len %ui", |
f388c0ad3477
Added processing of client transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8259
diff
changeset
|
247 client_params_len); |
f388c0ad3477
Added processing of client transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8259
diff
changeset
|
248 |
f388c0ad3477
Added processing of client transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8259
diff
changeset
|
249 if (client_params_len != 0) { |
f388c0ad3477
Added processing of client transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8259
diff
changeset
|
250 p = (u_char *) client_params; |
f388c0ad3477
Added processing of client transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8259
diff
changeset
|
251 end = p + client_params_len; |
f388c0ad3477
Added processing of client transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8259
diff
changeset
|
252 |
8265
d45325e90221
Limit output QUIC packets with client max_packet_size.
Roman Arutyunyan <arut@nginx.com>
parents:
8263
diff
changeset
|
253 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
|
254 != NGX_OK) |
8260
f388c0ad3477
Added processing of client transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8259
diff
changeset
|
255 { |
f388c0ad3477
Added processing of client transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8259
diff
changeset
|
256 return NGX_ERROR; |
f388c0ad3477
Added processing of client transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8259
diff
changeset
|
257 } |
f388c0ad3477
Added processing of client transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8259
diff
changeset
|
258 |
8271
8e54a17dabee
Respect QUIC max_idle_timeout.
Roman Arutyunyan <arut@nginx.com>
parents:
8270
diff
changeset
|
259 if (qc->ctp.max_idle_timeout > 0 |
8e54a17dabee
Respect QUIC max_idle_timeout.
Roman Arutyunyan <arut@nginx.com>
parents:
8270
diff
changeset
|
260 && 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
|
261 { |
8e54a17dabee
Respect QUIC max_idle_timeout.
Roman Arutyunyan <arut@nginx.com>
parents:
8270
diff
changeset
|
262 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
|
263 } |
8e54a17dabee
Respect QUIC max_idle_timeout.
Roman Arutyunyan <arut@nginx.com>
parents:
8270
diff
changeset
|
264 |
8260
f388c0ad3477
Added processing of client transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8259
diff
changeset
|
265 qc->client_tp_done = 1; |
f388c0ad3477
Added processing of client transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8259
diff
changeset
|
266 } |
f388c0ad3477
Added processing of client transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8259
diff
changeset
|
267 } |
f388c0ad3477
Added processing of client transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8259
diff
changeset
|
268 |
8186
0a2683df5f11
Implemented improved version of quic_output().
Vladimir Homutov <vl@nginx.com>
parents:
8185
diff
changeset
|
269 frame = ngx_pcalloc(c->pool, sizeof(ngx_quic_frame_t)); |
0a2683df5f11
Implemented improved version of quic_output().
Vladimir Homutov <vl@nginx.com>
parents:
8185
diff
changeset
|
270 if (frame == NULL) { |
0a2683df5f11
Implemented improved version of quic_output().
Vladimir Homutov <vl@nginx.com>
parents:
8185
diff
changeset
|
271 return 0; |
0a2683df5f11
Implemented improved version of quic_output().
Vladimir Homutov <vl@nginx.com>
parents:
8185
diff
changeset
|
272 } |
8184
ec1f84996990
Split frame and packet generation into separate steps.
Vladimir Homutov <vl@nginx.com>
parents:
8183
diff
changeset
|
273 |
8186
0a2683df5f11
Implemented improved version of quic_output().
Vladimir Homutov <vl@nginx.com>
parents:
8185
diff
changeset
|
274 p = ngx_pnalloc(c->pool, len); |
0a2683df5f11
Implemented improved version of quic_output().
Vladimir Homutov <vl@nginx.com>
parents:
8185
diff
changeset
|
275 if (p == NULL) { |
8184
ec1f84996990
Split frame and packet generation into separate steps.
Vladimir Homutov <vl@nginx.com>
parents:
8183
diff
changeset
|
276 return 0; |
ec1f84996990
Split frame and packet generation into separate steps.
Vladimir Homutov <vl@nginx.com>
parents:
8183
diff
changeset
|
277 } |
8186
0a2683df5f11
Implemented improved version of quic_output().
Vladimir Homutov <vl@nginx.com>
parents:
8185
diff
changeset
|
278 |
0a2683df5f11
Implemented improved version of quic_output().
Vladimir Homutov <vl@nginx.com>
parents:
8185
diff
changeset
|
279 ngx_memcpy(p, data, len); |
8184
ec1f84996990
Split frame and packet generation into separate steps.
Vladimir Homutov <vl@nginx.com>
parents:
8183
diff
changeset
|
280 |
8186
0a2683df5f11
Implemented improved version of quic_output().
Vladimir Homutov <vl@nginx.com>
parents:
8185
diff
changeset
|
281 frame->level = level; |
0a2683df5f11
Implemented improved version of quic_output().
Vladimir Homutov <vl@nginx.com>
parents:
8185
diff
changeset
|
282 frame->type = NGX_QUIC_FT_CRYPTO; |
8259
9e9eab876964
Fixed CRYPTO offset generation.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8258
diff
changeset
|
283 frame->u.crypto.offset += qc->crypto_offset[level]; |
8186
0a2683df5f11
Implemented improved version of quic_output().
Vladimir Homutov <vl@nginx.com>
parents:
8185
diff
changeset
|
284 frame->u.crypto.len = len; |
0a2683df5f11
Implemented improved version of quic_output().
Vladimir Homutov <vl@nginx.com>
parents:
8185
diff
changeset
|
285 frame->u.crypto.data = p; |
0a2683df5f11
Implemented improved version of quic_output().
Vladimir Homutov <vl@nginx.com>
parents:
8185
diff
changeset
|
286 |
8259
9e9eab876964
Fixed CRYPTO offset generation.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8258
diff
changeset
|
287 qc->crypto_offset[level] += len; |
9e9eab876964
Fixed CRYPTO offset generation.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8258
diff
changeset
|
288 |
8186
0a2683df5f11
Implemented improved version of quic_output().
Vladimir Homutov <vl@nginx.com>
parents:
8185
diff
changeset
|
289 ngx_sprintf(frame->info, "crypto, generated by SSL len=%ui level=%d", len, level); |
0a2683df5f11
Implemented improved version of quic_output().
Vladimir Homutov <vl@nginx.com>
parents:
8185
diff
changeset
|
290 |
0a2683df5f11
Implemented improved version of quic_output().
Vladimir Homutov <vl@nginx.com>
parents:
8185
diff
changeset
|
291 ngx_quic_queue_frame(qc, frame); |
8184
ec1f84996990
Split frame and packet generation into separate steps.
Vladimir Homutov <vl@nginx.com>
parents:
8183
diff
changeset
|
292 |
8182
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
293 return 1; |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
294 } |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
295 |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
296 |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
297 static int |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
298 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
|
299 { |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
300 ngx_connection_t *c; |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
301 |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
302 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
|
303 |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
304 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "ngx_quic_flush_flight()"); |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
305 |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
306 return 1; |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
307 } |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
308 |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
309 |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
310 static int |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
311 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
|
312 uint8_t alert) |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
313 { |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
314 ngx_connection_t *c; |
8235
552d6868091b
Implemented send_alert callback, CONNECTION_CLOSE writer.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8234
diff
changeset
|
315 ngx_quic_frame_t *frame; |
8182
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
316 |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
317 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
|
318 |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
319 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
320 "ngx_quic_send_alert(), lvl=%d, alert=%d", |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
321 (int) level, (int) alert); |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
322 |
8235
552d6868091b
Implemented send_alert callback, CONNECTION_CLOSE writer.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8234
diff
changeset
|
323 frame = ngx_pcalloc(c->pool, sizeof(ngx_quic_frame_t)); |
552d6868091b
Implemented send_alert callback, CONNECTION_CLOSE writer.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8234
diff
changeset
|
324 if (frame == NULL) { |
552d6868091b
Implemented send_alert callback, CONNECTION_CLOSE writer.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8234
diff
changeset
|
325 return 0; |
552d6868091b
Implemented send_alert callback, CONNECTION_CLOSE writer.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8234
diff
changeset
|
326 } |
552d6868091b
Implemented send_alert callback, CONNECTION_CLOSE writer.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8234
diff
changeset
|
327 |
552d6868091b
Implemented send_alert callback, CONNECTION_CLOSE writer.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8234
diff
changeset
|
328 frame->level = level; |
552d6868091b
Implemented send_alert callback, CONNECTION_CLOSE writer.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8234
diff
changeset
|
329 frame->type = NGX_QUIC_FT_CONNECTION_CLOSE; |
552d6868091b
Implemented send_alert callback, CONNECTION_CLOSE writer.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8234
diff
changeset
|
330 frame->u.close.error_code = 0x100 + alert; |
552d6868091b
Implemented send_alert callback, CONNECTION_CLOSE writer.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8234
diff
changeset
|
331 |
552d6868091b
Implemented send_alert callback, CONNECTION_CLOSE writer.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8234
diff
changeset
|
332 ngx_quic_queue_frame(c->quic, frame); |
552d6868091b
Implemented send_alert callback, CONNECTION_CLOSE writer.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8234
diff
changeset
|
333 |
552d6868091b
Implemented send_alert callback, CONNECTION_CLOSE writer.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8234
diff
changeset
|
334 if (ngx_quic_output(c) != NGX_OK) { |
552d6868091b
Implemented send_alert callback, CONNECTION_CLOSE writer.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8234
diff
changeset
|
335 return 0; |
552d6868091b
Implemented send_alert callback, CONNECTION_CLOSE writer.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8234
diff
changeset
|
336 } |
552d6868091b
Implemented send_alert callback, CONNECTION_CLOSE writer.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8234
diff
changeset
|
337 |
8182
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
338 return 1; |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
339 } |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
340 |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
341 |
8225 | 342 void |
8247
e9891e8ee975
Configurable transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8246
diff
changeset
|
343 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
|
344 ngx_connection_handler_pt handler) |
8225 | 345 { |
346 ngx_buf_t *b; | |
347 ngx_quic_header_t pkt; | |
348 | |
8263
1295b293d09a
Connection states code cleanup.
Vladimir Homutov <vl@nginx.com>
parents:
8260
diff
changeset
|
349 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "quic run"); |
8225 | 350 |
8263
1295b293d09a
Connection states code cleanup.
Vladimir Homutov <vl@nginx.com>
parents:
8260
diff
changeset
|
351 c->log->action = "QUIC initialization"; |
8225 | 352 |
353 ngx_memzero(&pkt, sizeof(ngx_quic_header_t)); | |
354 | |
355 b = c->buffer; | |
356 | |
357 pkt.log = c->log; | |
358 pkt.raw = b; | |
359 pkt.data = b->start; | |
360 pkt.len = b->last - b->start; | |
361 | |
8247
e9891e8ee975
Configurable transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8246
diff
changeset
|
362 if (ngx_quic_new_connection(c, ssl, tp, &pkt) != NGX_OK) { |
8225 | 363 ngx_quic_close_connection(c); |
364 return; | |
365 } | |
366 | |
367 // we don't need stream handler for initial packet processing | |
368 c->quic->streams.handler = handler; | |
369 | |
8271
8e54a17dabee
Respect QUIC max_idle_timeout.
Roman Arutyunyan <arut@nginx.com>
parents:
8270
diff
changeset
|
370 ngx_add_timer(c->read, c->quic->tp.max_idle_timeout); |
8225 | 371 |
8263
1295b293d09a
Connection states code cleanup.
Vladimir Homutov <vl@nginx.com>
parents:
8260
diff
changeset
|
372 c->read->handler = ngx_quic_input_handler; |
8225 | 373 |
374 return; | |
375 } | |
376 | |
8199
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
377 |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
378 static ngx_int_t |
8247
e9891e8ee975
Configurable transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8246
diff
changeset
|
379 ngx_quic_new_connection(ngx_connection_t *c, ngx_ssl_t *ssl, ngx_quic_tp_t *tp, |
8225 | 380 ngx_quic_header_t *pkt) |
8199
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
381 { |
8265
d45325e90221
Limit output QUIC packets with client max_packet_size.
Roman Arutyunyan <arut@nginx.com>
parents:
8263
diff
changeset
|
382 ngx_quic_tp_t *ctp; |
8225 | 383 ngx_quic_connection_t *qc; |
8199
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
384 |
8225 | 385 if (ngx_buf_size(pkt->raw) < 1200) { |
386 ngx_log_error(NGX_LOG_INFO, c->log, 0, "too small UDP datagram"); | |
387 return NGX_ERROR; | |
388 } | |
8199
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
389 |
8225 | 390 if (ngx_quic_parse_long_header(pkt) != NGX_OK) { |
8199
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
391 return NGX_ERROR; |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
392 } |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
393 |
8251
c217a907ce42
Added checks for permitted frame types.
Vladimir Homutov <vl@nginx.com>
parents:
8247
diff
changeset
|
394 if (!ngx_quic_pkt_in(pkt->flags)) { |
8225 | 395 ngx_log_error(NGX_LOG_INFO, c->log, 0, |
396 "invalid initial packet: 0x%xi", pkt->flags); | |
397 return NGX_ERROR; | |
398 } | |
8199
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
399 |
8225 | 400 if (ngx_quic_parse_initial_header(pkt) != NGX_OK) { |
401 return NGX_ERROR; | |
402 } | |
8199
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
403 |
8225 | 404 qc = ngx_pcalloc(c->pool, sizeof(ngx_quic_connection_t)); |
405 if (qc == NULL) { | |
406 return NGX_ERROR; | |
8199
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
407 } |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
408 |
8263
1295b293d09a
Connection states code cleanup.
Vladimir Homutov <vl@nginx.com>
parents:
8260
diff
changeset
|
409 qc->state = NGX_QUIC_ST_INITIAL; |
1295b293d09a
Connection states code cleanup.
Vladimir Homutov <vl@nginx.com>
parents:
8260
diff
changeset
|
410 |
8225 | 411 ngx_rbtree_init(&qc->streams.tree, &qc->streams.sentinel, |
412 ngx_quic_rbtree_insert_stream); | |
413 | |
414 c->quic = qc; | |
415 qc->ssl = ssl; | |
8247
e9891e8ee975
Configurable transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8246
diff
changeset
|
416 qc->tp = *tp; |
8225 | 417 |
8265
d45325e90221
Limit output QUIC packets with client max_packet_size.
Roman Arutyunyan <arut@nginx.com>
parents:
8263
diff
changeset
|
418 ctp = &qc->ctp; |
d45325e90221
Limit output QUIC packets with client max_packet_size.
Roman Arutyunyan <arut@nginx.com>
parents:
8263
diff
changeset
|
419 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
|
420 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
|
421 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
|
422 |
8225 | 423 qc->dcid.len = pkt->dcid.len; |
424 qc->dcid.data = ngx_pnalloc(c->pool, pkt->dcid.len); | |
425 if (qc->dcid.data == NULL) { | |
426 return NGX_ERROR; | |
427 } | |
428 ngx_memcpy(qc->dcid.data, pkt->dcid.data, qc->dcid.len); | |
429 | |
430 qc->scid.len = pkt->scid.len; | |
431 qc->scid.data = ngx_pnalloc(c->pool, qc->scid.len); | |
432 if (qc->scid.data == NULL) { | |
433 return NGX_ERROR; | |
434 } | |
435 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
|
436 |
8225 | 437 qc->token.len = pkt->token.len; |
438 qc->token.data = ngx_pnalloc(c->pool, qc->token.len); | |
439 if (qc->token.data == NULL) { | |
440 return NGX_ERROR; | |
441 } | |
442 ngx_memcpy(qc->token.data, pkt->token.data, qc->token.len); | |
443 | |
444 | |
445 if (ngx_quic_set_initial_secret(c->pool, &qc->secrets, &qc->dcid) | |
446 != NGX_OK) | |
447 { | |
448 return NGX_ERROR; | |
449 } | |
8199
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
450 |
8225 | 451 pkt->secret = &qc->secrets.client.in; |
452 pkt->level = ssl_encryption_initial; | |
453 | |
454 if (ngx_quic_decrypt(c->pool, NULL, pkt) != NGX_OK) { | |
455 return NGX_ERROR; | |
456 } | |
457 | |
458 if (ngx_quic_init_connection(c) != NGX_OK) { | |
459 return NGX_ERROR; | |
460 } | |
461 | |
462 return ngx_quic_payload_handler(c, pkt); | |
8199
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
463 } |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
464 |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
465 |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
466 static ngx_int_t |
8221
69345a26ba69
Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
8220
diff
changeset
|
467 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
|
468 { |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
469 int n, sslerr; |
8247
e9891e8ee975
Configurable transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8246
diff
changeset
|
470 u_char *p; |
e9891e8ee975
Configurable transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8246
diff
changeset
|
471 ssize_t len; |
8199
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
472 ngx_ssl_conn_t *ssl_conn; |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
473 ngx_quic_connection_t *qc; |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
474 |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
475 qc = c->quic; |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
476 |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
477 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
|
478 return NGX_ERROR; |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
479 } |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
480 |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
481 ssl_conn = c->ssl->connection; |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
482 |
8232
253cf267f95a
Moved setting QUIC methods to runtime.
Roman Arutyunyan <arut@nginx.com>
parents:
8231
diff
changeset
|
483 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
|
484 ngx_log_error(NGX_LOG_INFO, c->log, 0, |
253cf267f95a
Moved setting QUIC methods to runtime.
Roman Arutyunyan <arut@nginx.com>
parents:
8231
diff
changeset
|
485 "SSL_set_quic_method() failed"); |
253cf267f95a
Moved setting QUIC methods to runtime.
Roman Arutyunyan <arut@nginx.com>
parents:
8231
diff
changeset
|
486 return NGX_ERROR; |
253cf267f95a
Moved setting QUIC methods to runtime.
Roman Arutyunyan <arut@nginx.com>
parents:
8231
diff
changeset
|
487 } |
253cf267f95a
Moved setting QUIC methods to runtime.
Roman Arutyunyan <arut@nginx.com>
parents:
8231
diff
changeset
|
488 |
8247
e9891e8ee975
Configurable transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8246
diff
changeset
|
489 len = ngx_quic_create_transport_params(NULL, NULL, &qc->tp); |
e9891e8ee975
Configurable transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8246
diff
changeset
|
490 /* always succeeds */ |
e9891e8ee975
Configurable transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8246
diff
changeset
|
491 |
e9891e8ee975
Configurable transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8246
diff
changeset
|
492 p = ngx_pnalloc(c->pool, len); |
e9891e8ee975
Configurable transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8246
diff
changeset
|
493 if (p == NULL) { |
e9891e8ee975
Configurable transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8246
diff
changeset
|
494 return NGX_ERROR; |
e9891e8ee975
Configurable transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8246
diff
changeset
|
495 } |
e9891e8ee975
Configurable transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8246
diff
changeset
|
496 |
e9891e8ee975
Configurable transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8246
diff
changeset
|
497 len = ngx_quic_create_transport_params(p, p + len, &qc->tp); |
e9891e8ee975
Configurable transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8246
diff
changeset
|
498 if (len < 0) { |
e9891e8ee975
Configurable transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8246
diff
changeset
|
499 return NGX_ERROR; |
e9891e8ee975
Configurable transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8246
diff
changeset
|
500 } |
e9891e8ee975
Configurable transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8246
diff
changeset
|
501 |
e9891e8ee975
Configurable transport parameters.
Vladimir Homutov <vl@nginx.com>
parents:
8246
diff
changeset
|
502 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
|
503 ngx_log_error(NGX_LOG_INFO, c->log, 0, |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
504 "SSL_set_quic_transport_params() failed"); |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
505 return NGX_ERROR; |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
506 } |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
507 |
8263
1295b293d09a
Connection states code cleanup.
Vladimir Homutov <vl@nginx.com>
parents:
8260
diff
changeset
|
508 qc->state = NGX_QUIC_ST_HANDSHAKE; |
1295b293d09a
Connection states code cleanup.
Vladimir Homutov <vl@nginx.com>
parents:
8260
diff
changeset
|
509 |
8199
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
510 n = SSL_do_handshake(ssl_conn); |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
511 |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
512 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_do_handshake: %d", n); |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
513 |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
514 if (n == -1) { |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
515 sslerr = SSL_get_error(ssl_conn, n); |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
516 |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
517 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_get_error: %d", |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
518 sslerr); |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
519 } |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
520 |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
521 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
522 "SSL_quic_read_level: %d, SSL_quic_write_level: %d", |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
523 (int) SSL_quic_read_level(ssl_conn), |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
524 (int) SSL_quic_write_level(ssl_conn)); |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
525 |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
526 return NGX_OK; |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
527 } |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
528 |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
529 |
8225 | 530 static void |
8263
1295b293d09a
Connection states code cleanup.
Vladimir Homutov <vl@nginx.com>
parents:
8260
diff
changeset
|
531 ngx_quic_input_handler(ngx_event_t *rev) |
8211
6bc18966b8c1
Stream "connection" read/write methods.
Vladimir Homutov <vl@nginx.com>
parents:
8209
diff
changeset
|
532 { |
8271
8e54a17dabee
Respect QUIC max_idle_timeout.
Roman Arutyunyan <arut@nginx.com>
parents:
8270
diff
changeset
|
533 ssize_t n; |
8e54a17dabee
Respect QUIC max_idle_timeout.
Roman Arutyunyan <arut@nginx.com>
parents:
8270
diff
changeset
|
534 ngx_buf_t b; |
8e54a17dabee
Respect QUIC max_idle_timeout.
Roman Arutyunyan <arut@nginx.com>
parents:
8270
diff
changeset
|
535 ngx_connection_t *c; |
8e54a17dabee
Respect QUIC max_idle_timeout.
Roman Arutyunyan <arut@nginx.com>
parents:
8270
diff
changeset
|
536 ngx_quic_connection_t *qc; |
8211
6bc18966b8c1
Stream "connection" read/write methods.
Vladimir Homutov <vl@nginx.com>
parents:
8209
diff
changeset
|
537 |
8265
d45325e90221
Limit output QUIC packets with client max_packet_size.
Roman Arutyunyan <arut@nginx.com>
parents:
8263
diff
changeset
|
538 static u_char buf[65535]; |
8211
6bc18966b8c1
Stream "connection" read/write methods.
Vladimir Homutov <vl@nginx.com>
parents:
8209
diff
changeset
|
539 |
8225 | 540 b.start = buf; |
8265
d45325e90221
Limit output QUIC packets with client max_packet_size.
Roman Arutyunyan <arut@nginx.com>
parents:
8263
diff
changeset
|
541 b.end = buf + sizeof(buf); |
8225 | 542 b.pos = b.last = b.start; |
8211
6bc18966b8c1
Stream "connection" read/write methods.
Vladimir Homutov <vl@nginx.com>
parents:
8209
diff
changeset
|
543 |
8225 | 544 c = rev->data; |
8211
6bc18966b8c1
Stream "connection" read/write methods.
Vladimir Homutov <vl@nginx.com>
parents:
8209
diff
changeset
|
545 |
8263
1295b293d09a
Connection states code cleanup.
Vladimir Homutov <vl@nginx.com>
parents:
8260
diff
changeset
|
546 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
|
547 |
8225 | 548 if (rev->timedout) { |
549 ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out"); | |
550 ngx_quic_close_connection(c); | |
551 return; | |
8212
e3c0b19a3a8a
Implemented ngx_quic_stream_send_chain() method.
Roman Arutyunyan <arut@nginx.com>
parents:
8211
diff
changeset
|
552 } |
e3c0b19a3a8a
Implemented ngx_quic_stream_send_chain() method.
Roman Arutyunyan <arut@nginx.com>
parents:
8211
diff
changeset
|
553 |
8225 | 554 if (c->close) { |
555 ngx_quic_close_connection(c); | |
556 return; | |
557 } | |
8220
7ada2feeac18
Added processing of CONNECTION CLOSE frames.
Vladimir Homutov <vl@nginx.com>
parents:
8218
diff
changeset
|
558 |
8225 | 559 n = c->recv(c, b.start, b.end - b.start); |
8215 | 560 |
8225 | 561 if (n == NGX_AGAIN) { |
562 return; | |
8199
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
563 } |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
564 |
8225 | 565 if (n == NGX_ERROR) { |
566 c->read->eof = 1; | |
567 ngx_quic_close_connection(c); | |
568 return; | |
8199
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
569 } |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
570 |
8225 | 571 b.last += n; |
8199
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
572 |
8225 | 573 if (ngx_quic_input(c, &b) != NGX_OK) { |
574 ngx_quic_close_connection(c); | |
575 return; | |
576 } | |
8271
8e54a17dabee
Respect QUIC max_idle_timeout.
Roman Arutyunyan <arut@nginx.com>
parents:
8270
diff
changeset
|
577 |
8e54a17dabee
Respect QUIC max_idle_timeout.
Roman Arutyunyan <arut@nginx.com>
parents:
8270
diff
changeset
|
578 qc = c->quic; |
8e54a17dabee
Respect QUIC max_idle_timeout.
Roman Arutyunyan <arut@nginx.com>
parents:
8270
diff
changeset
|
579 |
8e54a17dabee
Respect QUIC max_idle_timeout.
Roman Arutyunyan <arut@nginx.com>
parents:
8270
diff
changeset
|
580 qc->send_timer_set = 0; |
8e54a17dabee
Respect QUIC max_idle_timeout.
Roman Arutyunyan <arut@nginx.com>
parents:
8270
diff
changeset
|
581 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
|
582 } |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
583 |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
584 |
8208
4ae9ac69ab93
HTTP/QUIC interface reworked.
Vladimir Homutov <vl@nginx.com>
parents:
8207
diff
changeset
|
585 static void |
8225 | 586 ngx_quic_close_connection(ngx_connection_t *c) |
8208
4ae9ac69ab93
HTTP/QUIC interface reworked.
Vladimir Homutov <vl@nginx.com>
parents:
8207
diff
changeset
|
587 { |
8225 | 588 ngx_pool_t *pool; |
8208
4ae9ac69ab93
HTTP/QUIC interface reworked.
Vladimir Homutov <vl@nginx.com>
parents:
8207
diff
changeset
|
589 |
8225 | 590 /* XXX wait for all streams to close */ |
8208
4ae9ac69ab93
HTTP/QUIC interface reworked.
Vladimir Homutov <vl@nginx.com>
parents:
8207
diff
changeset
|
591 |
8225 | 592 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, |
593 "close quic connection: %d", c->fd); | |
8208
4ae9ac69ab93
HTTP/QUIC interface reworked.
Vladimir Homutov <vl@nginx.com>
parents:
8207
diff
changeset
|
594 |
8225 | 595 if (c->ssl) { |
596 (void) ngx_ssl_shutdown(c); | |
8208
4ae9ac69ab93
HTTP/QUIC interface reworked.
Vladimir Homutov <vl@nginx.com>
parents:
8207
diff
changeset
|
597 } |
4ae9ac69ab93
HTTP/QUIC interface reworked.
Vladimir Homutov <vl@nginx.com>
parents:
8207
diff
changeset
|
598 |
8225 | 599 #if (NGX_STAT_STUB) |
600 (void) ngx_atomic_fetch_add(ngx_stat_active, -1); | |
601 #endif | |
8208
4ae9ac69ab93
HTTP/QUIC interface reworked.
Vladimir Homutov <vl@nginx.com>
parents:
8207
diff
changeset
|
602 |
8225 | 603 c->destroyed = 1; |
8208
4ae9ac69ab93
HTTP/QUIC interface reworked.
Vladimir Homutov <vl@nginx.com>
parents:
8207
diff
changeset
|
604 |
8225 | 605 pool = c->pool; |
8208
4ae9ac69ab93
HTTP/QUIC interface reworked.
Vladimir Homutov <vl@nginx.com>
parents:
8207
diff
changeset
|
606 |
8225 | 607 ngx_close_connection(c); |
8208
4ae9ac69ab93
HTTP/QUIC interface reworked.
Vladimir Homutov <vl@nginx.com>
parents:
8207
diff
changeset
|
608 |
8225 | 609 ngx_destroy_pool(pool); |
8208
4ae9ac69ab93
HTTP/QUIC interface reworked.
Vladimir Homutov <vl@nginx.com>
parents:
8207
diff
changeset
|
610 } |
4ae9ac69ab93
HTTP/QUIC interface reworked.
Vladimir Homutov <vl@nginx.com>
parents:
8207
diff
changeset
|
611 |
4ae9ac69ab93
HTTP/QUIC interface reworked.
Vladimir Homutov <vl@nginx.com>
parents:
8207
diff
changeset
|
612 |
8193
4355efde26d8
Added functions to decrypt long packets.
Vladimir Homutov <vl@nginx.com>
parents:
8192
diff
changeset
|
613 static ngx_int_t |
8225 | 614 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
|
615 { |
8225 | 616 u_char *p; |
617 ngx_int_t rc; | |
618 ngx_quic_header_t pkt; | |
8193
4355efde26d8
Added functions to decrypt long packets.
Vladimir Homutov <vl@nginx.com>
parents:
8192
diff
changeset
|
619 |
8225 | 620 p = b->start; |
8208
4ae9ac69ab93
HTTP/QUIC interface reworked.
Vladimir Homutov <vl@nginx.com>
parents:
8207
diff
changeset
|
621 |
8225 | 622 do { |
8263
1295b293d09a
Connection states code cleanup.
Vladimir Homutov <vl@nginx.com>
parents:
8260
diff
changeset
|
623 c->log->action = "processing quic packet"; |
1295b293d09a
Connection states code cleanup.
Vladimir Homutov <vl@nginx.com>
parents:
8260
diff
changeset
|
624 |
8225 | 625 ngx_memzero(&pkt, sizeof(ngx_quic_header_t)); |
626 pkt.raw = b; | |
627 pkt.data = p; | |
628 pkt.len = b->last - p; | |
629 pkt.log = c->log; | |
8251
c217a907ce42
Added checks for permitted frame types.
Vladimir Homutov <vl@nginx.com>
parents:
8247
diff
changeset
|
630 pkt.flags = p[0]; |
8193
4355efde26d8
Added functions to decrypt long packets.
Vladimir Homutov <vl@nginx.com>
parents:
8192
diff
changeset
|
631 |
8251
c217a907ce42
Added checks for permitted frame types.
Vladimir Homutov <vl@nginx.com>
parents:
8247
diff
changeset
|
632 if (pkt.flags == 0) { |
8225 | 633 /* XXX: no idea WTF is this, just ignore */ |
634 ngx_log_error(NGX_LOG_ALERT, c->log, 0, "FIREFOX: ZEROES"); | |
635 break; | |
636 } | |
8206
8d6ac639feac
Added support of multiple QUIC packets in single datagram.
Vladimir Homutov <vl@nginx.com>
parents:
8205
diff
changeset
|
637 |
8225 | 638 // TODO: check current state |
8251
c217a907ce42
Added checks for permitted frame types.
Vladimir Homutov <vl@nginx.com>
parents:
8247
diff
changeset
|
639 if (ngx_quic_long_pkt(pkt.flags)) { |
8225 | 640 |
8251
c217a907ce42
Added checks for permitted frame types.
Vladimir Homutov <vl@nginx.com>
parents:
8247
diff
changeset
|
641 if (ngx_quic_pkt_in(pkt.flags)) { |
8225 | 642 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
|
643 |
8251
c217a907ce42
Added checks for permitted frame types.
Vladimir Homutov <vl@nginx.com>
parents:
8247
diff
changeset
|
644 } else if (ngx_quic_pkt_hs(pkt.flags)) { |
8225 | 645 rc = ngx_quic_handshake_input(c, &pkt); |
8193
4355efde26d8
Added functions to decrypt long packets.
Vladimir Homutov <vl@nginx.com>
parents:
8192
diff
changeset
|
646 |
8225 | 647 } else { |
648 ngx_log_error(NGX_LOG_INFO, c->log, 0, | |
649 "BUG: unknown quic state"); | |
650 return NGX_ERROR; | |
651 } | |
8193
4355efde26d8
Added functions to decrypt long packets.
Vladimir Homutov <vl@nginx.com>
parents:
8192
diff
changeset
|
652 |
8225 | 653 } else { |
654 rc = ngx_quic_app_input(c, &pkt); | |
655 } | |
8193
4355efde26d8
Added functions to decrypt long packets.
Vladimir Homutov <vl@nginx.com>
parents:
8192
diff
changeset
|
656 |
8267
a8349cc72c64
Avoid using QUIC connection after CONNECTION_CLOSE.
Roman Arutyunyan <arut@nginx.com>
parents:
8266
diff
changeset
|
657 if (rc != NGX_OK) { |
a8349cc72c64
Avoid using QUIC connection after CONNECTION_CLOSE.
Roman Arutyunyan <arut@nginx.com>
parents:
8266
diff
changeset
|
658 return rc; |
8225 | 659 } |
8206
8d6ac639feac
Added support of multiple QUIC packets in single datagram.
Vladimir Homutov <vl@nginx.com>
parents:
8205
diff
changeset
|
660 |
8225 | 661 /* b->pos is at header end, adjust by actual packet length */ |
662 p = b->pos + pkt.len; | |
663 b->pos = p; /* reset b->pos to the next packet start */ | |
8193
4355efde26d8
Added functions to decrypt long packets.
Vladimir Homutov <vl@nginx.com>
parents:
8192
diff
changeset
|
664 |
8225 | 665 } while (p < b->last); |
8182
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
666 |
8225 | 667 return NGX_OK; |
8182
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
668 } |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
669 |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
670 |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
671 static ngx_int_t |
8223 | 672 ngx_quic_initial_input(ngx_connection_t *c, ngx_quic_header_t *pkt) |
673 { | |
674 ngx_ssl_conn_t *ssl_conn; | |
675 ngx_quic_connection_t *qc; | |
676 | |
8263
1295b293d09a
Connection states code cleanup.
Vladimir Homutov <vl@nginx.com>
parents:
8260
diff
changeset
|
677 c->log->action = "processing initial quic packet"; |
1295b293d09a
Connection states code cleanup.
Vladimir Homutov <vl@nginx.com>
parents:
8260
diff
changeset
|
678 |
8223 | 679 qc = c->quic; |
680 ssl_conn = c->ssl->connection; | |
681 | |
8224
ae35ccba7aa6
Extracted transport part of the code into separate file.
Vladimir Homutov <vl@nginx.com>
parents:
8223
diff
changeset
|
682 if (ngx_quic_parse_long_header(pkt) != NGX_OK) { |
8223 | 683 return NGX_ERROR; |
684 } | |
685 | |
8224
ae35ccba7aa6
Extracted transport part of the code into separate file.
Vladimir Homutov <vl@nginx.com>
parents:
8223
diff
changeset
|
686 if (ngx_quic_parse_initial_header(pkt) != NGX_OK) { |
8223 | 687 return NGX_ERROR; |
688 } | |
689 | |
690 pkt->secret = &qc->secrets.client.in; | |
691 pkt->level = ssl_encryption_initial; | |
692 | |
693 if (ngx_quic_decrypt(c->pool, ssl_conn, pkt) != NGX_OK) { | |
694 return NGX_ERROR; | |
695 } | |
696 | |
697 return ngx_quic_payload_handler(c, pkt); | |
698 } | |
699 | |
700 | |
701 static ngx_int_t | |
8206
8d6ac639feac
Added support of multiple QUIC packets in single datagram.
Vladimir Homutov <vl@nginx.com>
parents:
8205
diff
changeset
|
702 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
|
703 { |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
704 ngx_quic_connection_t *qc; |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
705 |
8263
1295b293d09a
Connection states code cleanup.
Vladimir Homutov <vl@nginx.com>
parents:
8260
diff
changeset
|
706 c->log->action = "processing handshake quic packet"; |
1295b293d09a
Connection states code cleanup.
Vladimir Homutov <vl@nginx.com>
parents:
8260
diff
changeset
|
707 |
8182
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
708 qc = c->quic; |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
709 |
8193
4355efde26d8
Added functions to decrypt long packets.
Vladimir Homutov <vl@nginx.com>
parents:
8192
diff
changeset
|
710 /* extract cleartext data into pkt */ |
8224
ae35ccba7aa6
Extracted transport part of the code into separate file.
Vladimir Homutov <vl@nginx.com>
parents:
8223
diff
changeset
|
711 if (ngx_quic_parse_long_header(pkt) != NGX_OK) { |
8182
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
712 return NGX_ERROR; |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
713 } |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
714 |
8206
8d6ac639feac
Added support of multiple QUIC packets in single datagram.
Vladimir Homutov <vl@nginx.com>
parents:
8205
diff
changeset
|
715 if (pkt->dcid.len != qc->dcid.len) { |
8182
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
716 ngx_log_error(NGX_LOG_INFO, c->log, 0, "unexpected quic dcidl"); |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
717 return NGX_ERROR; |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
718 } |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
719 |
8206
8d6ac639feac
Added support of multiple QUIC packets in single datagram.
Vladimir Homutov <vl@nginx.com>
parents:
8205
diff
changeset
|
720 if (ngx_memcmp(pkt->dcid.data, qc->dcid.data, qc->dcid.len) != 0) { |
8182
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
721 ngx_log_error(NGX_LOG_INFO, c->log, 0, "unexpected quic dcid"); |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
722 return NGX_ERROR; |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
723 } |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
724 |
8206
8d6ac639feac
Added support of multiple QUIC packets in single datagram.
Vladimir Homutov <vl@nginx.com>
parents:
8205
diff
changeset
|
725 if (pkt->scid.len != qc->scid.len) { |
8182
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
726 ngx_log_error(NGX_LOG_INFO, c->log, 0, "unexpected quic scidl"); |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
727 return NGX_ERROR; |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
728 } |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
729 |
8206
8d6ac639feac
Added support of multiple QUIC packets in single datagram.
Vladimir Homutov <vl@nginx.com>
parents:
8205
diff
changeset
|
730 if (ngx_memcmp(pkt->scid.data, qc->scid.data, qc->scid.len) != 0) { |
8182
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
731 ngx_log_error(NGX_LOG_INFO, c->log, 0, "unexpected quic scid"); |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
732 return NGX_ERROR; |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
733 } |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
734 |
8251
c217a907ce42
Added checks for permitted frame types.
Vladimir Homutov <vl@nginx.com>
parents:
8247
diff
changeset
|
735 if (!ngx_quic_pkt_hs(pkt->flags)) { |
8193
4355efde26d8
Added functions to decrypt long packets.
Vladimir Homutov <vl@nginx.com>
parents:
8192
diff
changeset
|
736 ngx_log_error(NGX_LOG_INFO, c->log, 0, |
8206
8d6ac639feac
Added support of multiple QUIC packets in single datagram.
Vladimir Homutov <vl@nginx.com>
parents:
8205
diff
changeset
|
737 "invalid packet type: 0x%xi", pkt->flags); |
8182
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
738 return NGX_ERROR; |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
739 } |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
740 |
8224
ae35ccba7aa6
Extracted transport part of the code into separate file.
Vladimir Homutov <vl@nginx.com>
parents:
8223
diff
changeset
|
741 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
|
742 return NGX_ERROR; |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
743 } |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
744 |
8221
69345a26ba69
Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
8220
diff
changeset
|
745 pkt->secret = &qc->secrets.client.hs; |
8206
8d6ac639feac
Added support of multiple QUIC packets in single datagram.
Vladimir Homutov <vl@nginx.com>
parents:
8205
diff
changeset
|
746 pkt->level = ssl_encryption_handshake; |
8d6ac639feac
Added support of multiple QUIC packets in single datagram.
Vladimir Homutov <vl@nginx.com>
parents:
8205
diff
changeset
|
747 |
8221
69345a26ba69
Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
8220
diff
changeset
|
748 if (ngx_quic_decrypt(c->pool, c->ssl->connection, pkt) != NGX_OK) { |
8182
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
749 return NGX_ERROR; |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
750 } |
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
751 |
8206
8d6ac639feac
Added support of multiple QUIC packets in single datagram.
Vladimir Homutov <vl@nginx.com>
parents:
8205
diff
changeset
|
752 return ngx_quic_payload_handler(c, pkt); |
8199
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
753 } |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
754 |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
755 |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
756 static ngx_int_t |
8206
8d6ac639feac
Added support of multiple QUIC packets in single datagram.
Vladimir Homutov <vl@nginx.com>
parents:
8205
diff
changeset
|
757 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
|
758 { |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
759 ngx_quic_connection_t *qc; |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
760 |
8263
1295b293d09a
Connection states code cleanup.
Vladimir Homutov <vl@nginx.com>
parents:
8260
diff
changeset
|
761 c->log->action = "processing application data quic packet"; |
1295b293d09a
Connection states code cleanup.
Vladimir Homutov <vl@nginx.com>
parents:
8260
diff
changeset
|
762 |
8199
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
763 qc = c->quic; |
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
764 |
8223 | 765 if (qc->secrets.client.ad.key.len == 0) { |
766 ngx_log_error(NGX_LOG_INFO, c->log, 0, | |
767 "no read keys yet, packet ignored"); | |
768 return NGX_DECLINED; | |
769 } | |
8199
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
770 |
8224
ae35ccba7aa6
Extracted transport part of the code into separate file.
Vladimir Homutov <vl@nginx.com>
parents:
8223
diff
changeset
|
771 if (ngx_quic_parse_short_header(pkt, &qc->dcid) != NGX_OK) { |
8185
6a76d9657772
QUIC handshake final bits.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8184
diff
changeset
|
772 return NGX_ERROR; |
6a76d9657772
QUIC handshake final bits.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8184
diff
changeset
|
773 } |
6a76d9657772
QUIC handshake final bits.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8184
diff
changeset
|
774 |
8221
69345a26ba69
Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
8220
diff
changeset
|
775 pkt->secret = &qc->secrets.client.ad; |
8206
8d6ac639feac
Added support of multiple QUIC packets in single datagram.
Vladimir Homutov <vl@nginx.com>
parents:
8205
diff
changeset
|
776 pkt->level = ssl_encryption_application; |
8d6ac639feac
Added support of multiple QUIC packets in single datagram.
Vladimir Homutov <vl@nginx.com>
parents:
8205
diff
changeset
|
777 |
8221
69345a26ba69
Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
8220
diff
changeset
|
778 if (ngx_quic_decrypt(c->pool, c->ssl->connection, pkt) != NGX_OK) { |
8199
1297dc83a6b9
Generic payload handler for quic packets.
Vladimir Homutov <vl@nginx.com>
parents:
8198
diff
changeset
|
779 return NGX_ERROR; |
8185
6a76d9657772
QUIC handshake final bits.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8184
diff
changeset
|
780 } |
6a76d9657772
QUIC handshake final bits.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8184
diff
changeset
|
781 |
8206
8d6ac639feac
Added support of multiple QUIC packets in single datagram.
Vladimir Homutov <vl@nginx.com>
parents:
8205
diff
changeset
|
782 return ngx_quic_payload_handler(c, pkt); |
8182
b28ea685a56e
Moved all QUIC code into ngx_event_quic.c
Vladimir Homutov <vl@nginx.com>
parents:
8180
diff
changeset
|
783 } |
8171 | 784 |
785 | |
8225 | 786 static ngx_int_t |
787 ngx_quic_payload_handler(ngx_connection_t *c, ngx_quic_header_t *pkt) | |
788 { | |
789 u_char *end, *p; | |
790 ssize_t len; | |
791 ngx_uint_t ack_this, do_close; | |
792 ngx_quic_frame_t frame, *ack_frame; | |
793 ngx_quic_connection_t *qc; | |
794 | |
8263
1295b293d09a
Connection states code cleanup.
Vladimir Homutov <vl@nginx.com>
parents:
8260
diff
changeset
|
795 c->log->action = "processing quic payload"; |
1295b293d09a
Connection states code cleanup.
Vladimir Homutov <vl@nginx.com>
parents:
8260
diff
changeset
|
796 |
8225 | 797 qc = c->quic; |
798 | |
799 p = pkt->payload.data; | |
800 end = p + pkt->payload.len; | |
801 | |
802 ack_this = 0; | |
803 do_close = 0; | |
804 | |
805 while (p < end) { | |
806 | |
8240
1f002206a59b
Added boundaries checks into frame parser.
Vladimir Homutov <vl@nginx.com>
parents:
8239
diff
changeset
|
807 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
|
808 |
c217a907ce42
Added checks for permitted frame types.
Vladimir Homutov <vl@nginx.com>
parents:
8247
diff
changeset
|
809 if (len == NGX_DECLINED) { |
c217a907ce42
Added checks for permitted frame types.
Vladimir Homutov <vl@nginx.com>
parents:
8247
diff
changeset
|
810 /* TODO: handle protocol violation: |
c217a907ce42
Added checks for permitted frame types.
Vladimir Homutov <vl@nginx.com>
parents:
8247
diff
changeset
|
811 * such frame not allowed in this packet |
c217a907ce42
Added checks for permitted frame types.
Vladimir Homutov <vl@nginx.com>
parents:
8247
diff
changeset
|
812 */ |
c217a907ce42
Added checks for permitted frame types.
Vladimir Homutov <vl@nginx.com>
parents:
8247
diff
changeset
|
813 return NGX_ERROR; |
c217a907ce42
Added checks for permitted frame types.
Vladimir Homutov <vl@nginx.com>
parents:
8247
diff
changeset
|
814 } |
c217a907ce42
Added checks for permitted frame types.
Vladimir Homutov <vl@nginx.com>
parents:
8247
diff
changeset
|
815 |
8225 | 816 if (len < 0) { |
817 return NGX_ERROR; | |
818 } | |
819 | |
820 p += len; | |
821 | |
822 switch (frame.type) { | |
823 | |
824 case NGX_QUIC_FT_ACK: | |
825 if (ngx_quic_handle_ack_frame(c, pkt, &frame.u.ack) != NGX_OK) { | |
826 return NGX_ERROR; | |
827 } | |
828 | |
829 break; | |
830 | |
831 case NGX_QUIC_FT_CRYPTO: | |
832 | |
833 if (ngx_quic_handle_crypto_frame(c, pkt, &frame.u.crypto) | |
834 != NGX_OK) | |
835 { | |
836 return NGX_ERROR; | |
837 } | |
838 | |
839 ack_this = 1; | |
840 break; | |
841 | |
842 case NGX_QUIC_FT_PADDING: | |
843 break; | |
844 | |
845 case NGX_QUIC_FT_PING: | |
846 ack_this = 1; | |
847 break; | |
848 | |
849 case NGX_QUIC_FT_NEW_CONNECTION_ID: | |
850 ack_this = 1; | |
851 break; | |
852 | |
853 case NGX_QUIC_FT_CONNECTION_CLOSE: | |
8258
80d7144b1c38
Closing connection on NGX_QUIC_FT_CONNECTION_CLOSE.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8252
diff
changeset
|
854 case NGX_QUIC_FT_CONNECTION_CLOSE2: |
8225 | 855 |
856 do_close = 1; | |
857 break; | |
858 | |
859 case NGX_QUIC_FT_STREAM0: | |
860 case NGX_QUIC_FT_STREAM1: | |
861 case NGX_QUIC_FT_STREAM2: | |
862 case NGX_QUIC_FT_STREAM3: | |
863 case NGX_QUIC_FT_STREAM4: | |
864 case NGX_QUIC_FT_STREAM5: | |
865 case NGX_QUIC_FT_STREAM6: | |
866 case NGX_QUIC_FT_STREAM7: | |
867 | |
868 if (ngx_quic_handle_stream_frame(c, pkt, &frame.u.stream) | |
869 != NGX_OK) | |
870 { | |
871 return NGX_ERROR; | |
872 } | |
873 | |
874 ack_this = 1; | |
875 break; | |
876 | |
8237
ff540f13d95d
MAX_DATA frame parser/handler.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8236
diff
changeset
|
877 case NGX_QUIC_FT_MAX_DATA: |
ff540f13d95d
MAX_DATA frame parser/handler.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8236
diff
changeset
|
878 c->quic->max_data = frame.u.max_data.max_data; |
ff540f13d95d
MAX_DATA frame parser/handler.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8236
diff
changeset
|
879 ack_this = 1; |
ff540f13d95d
MAX_DATA frame parser/handler.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8236
diff
changeset
|
880 break; |
ff540f13d95d
MAX_DATA frame parser/handler.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8236
diff
changeset
|
881 |
8231
78540e2160d0
Added parsing of RESET_STREAM and STOP_SENDING frames
Vladimir Homutov <vl@nginx.com>
parents:
8229
diff
changeset
|
882 case NGX_QUIC_FT_RESET_STREAM: |
8240
1f002206a59b
Added boundaries checks into frame parser.
Vladimir Homutov <vl@nginx.com>
parents:
8239
diff
changeset
|
883 /* TODO: handle */ |
8231
78540e2160d0
Added parsing of RESET_STREAM and STOP_SENDING frames
Vladimir Homutov <vl@nginx.com>
parents:
8229
diff
changeset
|
884 break; |
78540e2160d0
Added parsing of RESET_STREAM and STOP_SENDING frames
Vladimir Homutov <vl@nginx.com>
parents:
8229
diff
changeset
|
885 |
78540e2160d0
Added parsing of RESET_STREAM and STOP_SENDING frames
Vladimir Homutov <vl@nginx.com>
parents:
8229
diff
changeset
|
886 case NGX_QUIC_FT_STOP_SENDING: |
8240
1f002206a59b
Added boundaries checks into frame parser.
Vladimir Homutov <vl@nginx.com>
parents:
8239
diff
changeset
|
887 /* TODO: handle; need ack ? */ |
8231
78540e2160d0
Added parsing of RESET_STREAM and STOP_SENDING frames
Vladimir Homutov <vl@nginx.com>
parents:
8229
diff
changeset
|
888 break; |
78540e2160d0
Added parsing of RESET_STREAM and STOP_SENDING frames
Vladimir Homutov <vl@nginx.com>
parents:
8229
diff
changeset
|
889 |
8236
d3b26c3bea22
Added parsing of STREAMS BLOCKED frames.
Vladimir Homutov <vl@nginx.com>
parents:
8235
diff
changeset
|
890 case NGX_QUIC_FT_STREAMS_BLOCKED: |
d3b26c3bea22
Added parsing of STREAMS BLOCKED frames.
Vladimir Homutov <vl@nginx.com>
parents:
8235
diff
changeset
|
891 case NGX_QUIC_FT_STREAMS_BLOCKED2: |
8245
a14afe21e692
Double MAX_STREAMS on STREAMS_BLOCKED.
Roman Arutyunyan <arut@nginx.com>
parents:
8241
diff
changeset
|
892 |
a14afe21e692
Double MAX_STREAMS on STREAMS_BLOCKED.
Roman Arutyunyan <arut@nginx.com>
parents:
8241
diff
changeset
|
893 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
|
894 &frame.u.streams_blocked) |
a14afe21e692
Double MAX_STREAMS on STREAMS_BLOCKED.
Roman Arutyunyan <arut@nginx.com>
parents:
8241
diff
changeset
|
895 != NGX_OK) |
a14afe21e692
Double MAX_STREAMS on STREAMS_BLOCKED.
Roman Arutyunyan <arut@nginx.com>
parents:
8241
diff
changeset
|
896 { |
a14afe21e692
Double MAX_STREAMS on STREAMS_BLOCKED.
Roman Arutyunyan <arut@nginx.com>
parents:
8241
diff
changeset
|
897 return NGX_ERROR; |
a14afe21e692
Double MAX_STREAMS on STREAMS_BLOCKED.
Roman Arutyunyan <arut@nginx.com>
parents:
8241
diff
changeset
|
898 } |
a14afe21e692
Double MAX_STREAMS on STREAMS_BLOCKED.
Roman Arutyunyan <arut@nginx.com>
parents:
8241
diff
changeset
|
899 |
a14afe21e692
Double MAX_STREAMS on STREAMS_BLOCKED.
Roman Arutyunyan <arut@nginx.com>
parents:
8241
diff
changeset
|
900 ack_this = 1; |
8236
d3b26c3bea22
Added parsing of STREAMS BLOCKED frames.
Vladimir Homutov <vl@nginx.com>
parents:
8235
diff
changeset
|
901 break; |
d3b26c3bea22
Added parsing of STREAMS BLOCKED frames.
Vladimir Homutov <vl@nginx.com>
parents:
8235
diff
changeset
|
902 |
8266
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
903 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
|
904 |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
905 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
|
906 &frame.u.stream_data_blocked) |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
907 != NGX_OK) |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
908 { |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
909 return NGX_ERROR; |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
910 } |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
911 |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
912 ack_this = 1; |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
913 break; |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
914 |
8225 | 915 default: |
916 return NGX_ERROR; | |
917 } | |
918 } | |
919 | |
920 if (p != end) { | |
921 ngx_log_error(NGX_LOG_INFO, c->log, 0, | |
922 "trailing garbage in payload: %ui bytes", end - p); | |
923 return NGX_ERROR; | |
924 } | |
925 | |
926 if (do_close) { | |
8267
a8349cc72c64
Avoid using QUIC connection after CONNECTION_CLOSE.
Roman Arutyunyan <arut@nginx.com>
parents:
8266
diff
changeset
|
927 return NGX_DONE; |
8225 | 928 } |
929 | |
930 if (ack_this == 0) { | |
931 /* do not ack packets with ACKs and PADDING */ | |
932 return NGX_OK; | |
933 } | |
934 | |
935 // packet processed, ACK it now if required | |
936 // TODO: if (ack_required) ... - currently just ack each packet | |
937 | |
938 ack_frame = ngx_pcalloc(c->pool, sizeof(ngx_quic_frame_t)); | |
939 if (ack_frame == NULL) { | |
940 return NGX_ERROR; | |
941 } | |
942 | |
943 ack_frame->level = pkt->level; | |
944 ack_frame->type = NGX_QUIC_FT_ACK; | |
945 ack_frame->u.ack.pn = pkt->pn; | |
946 | |
947 ngx_sprintf(ack_frame->info, "ACK for PN=%d from frame handler level=%d", pkt->pn, pkt->level); | |
948 ngx_quic_queue_frame(qc, ack_frame); | |
949 | |
950 return ngx_quic_output(c); | |
951 } | |
952 | |
953 | |
954 static ngx_int_t | |
955 ngx_quic_handle_ack_frame(ngx_connection_t *c, ngx_quic_header_t *pkt, | |
956 ngx_quic_ack_frame_t *f) | |
957 { | |
958 /* TODO: handle ACK here */ | |
959 return NGX_OK; | |
960 } | |
961 | |
962 | |
963 static ngx_int_t | |
964 ngx_quic_handle_crypto_frame(ngx_connection_t *c, ngx_quic_header_t *pkt, | |
965 ngx_quic_crypto_frame_t *f) | |
966 { | |
8273
cb75f194f1f0
Implemented sending HANDSHAKE_DONE frame after handshake.
Vladimir Homutov <vl@nginx.com>
parents:
8272
diff
changeset
|
967 int sslerr; |
cb75f194f1f0
Implemented sending HANDSHAKE_DONE frame after handshake.
Vladimir Homutov <vl@nginx.com>
parents:
8272
diff
changeset
|
968 ssize_t n; |
cb75f194f1f0
Implemented sending HANDSHAKE_DONE frame after handshake.
Vladimir Homutov <vl@nginx.com>
parents:
8272
diff
changeset
|
969 ngx_ssl_conn_t *ssl_conn; |
8225 | 970 |
971 if (f->offset != 0x0) { | |
972 ngx_log_error(NGX_LOG_INFO, c->log, 0, | |
973 "crypto frame with non-zero offset"); | |
974 // TODO: add support for crypto frames spanning packets | |
975 return NGX_ERROR; | |
976 } | |
977 | |
978 ssl_conn = c->ssl->connection; | |
979 | |
980 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
981 "SSL_quic_read_level: %d, SSL_quic_write_level: %d", | |
982 (int) SSL_quic_read_level(ssl_conn), | |
983 (int) SSL_quic_write_level(ssl_conn)); | |
984 | |
985 if (!SSL_provide_quic_data(ssl_conn, SSL_quic_read_level(ssl_conn), | |
986 f->data, f->len)) | |
987 { | |
988 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, | |
989 "SSL_provide_quic_data() failed"); | |
990 return NGX_ERROR; | |
991 } | |
992 | |
993 n = SSL_do_handshake(ssl_conn); | |
994 | |
995 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_do_handshake: %d", n); | |
996 | |
997 if (n == -1) { | |
998 sslerr = SSL_get_error(ssl_conn, n); | |
999 | |
1000 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_get_error: %d", | |
1001 sslerr); | |
1002 | |
1003 if (sslerr == SSL_ERROR_SSL) { | |
1004 ngx_ssl_error(NGX_LOG_ERR, c->log, 0, "SSL_do_handshake() failed"); | |
1005 } | |
8263
1295b293d09a
Connection states code cleanup.
Vladimir Homutov <vl@nginx.com>
parents:
8260
diff
changeset
|
1006 |
1295b293d09a
Connection states code cleanup.
Vladimir Homutov <vl@nginx.com>
parents:
8260
diff
changeset
|
1007 } else if (n == 1) { |
1295b293d09a
Connection states code cleanup.
Vladimir Homutov <vl@nginx.com>
parents:
8260
diff
changeset
|
1008 c->quic->state = NGX_QUIC_ST_APPLICATION; |
8225 | 1009 |
8263
1295b293d09a
Connection states code cleanup.
Vladimir Homutov <vl@nginx.com>
parents:
8260
diff
changeset
|
1010 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, |
8225 | 1011 "quic ssl cipher: %s", SSL_get_cipher(ssl_conn)); |
1012 | |
8263
1295b293d09a
Connection states code cleanup.
Vladimir Homutov <vl@nginx.com>
parents:
8260
diff
changeset
|
1013 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, |
1295b293d09a
Connection states code cleanup.
Vladimir Homutov <vl@nginx.com>
parents:
8260
diff
changeset
|
1014 "handshake completed successfully"); |
8273
cb75f194f1f0
Implemented sending HANDSHAKE_DONE frame after handshake.
Vladimir Homutov <vl@nginx.com>
parents:
8272
diff
changeset
|
1015 |
8274
ee53bfd8f9ed
Added QUIC version check for sending HANDSHAKE_DONE frame.
Vladimir Homutov <vl@nginx.com>
parents:
8273
diff
changeset
|
1016 #if (NGX_QUIC_DRAFT_VERSION >= 27) |
ee53bfd8f9ed
Added QUIC version check for sending HANDSHAKE_DONE frame.
Vladimir Homutov <vl@nginx.com>
parents:
8273
diff
changeset
|
1017 { |
ee53bfd8f9ed
Added QUIC version check for sending HANDSHAKE_DONE frame.
Vladimir Homutov <vl@nginx.com>
parents:
8273
diff
changeset
|
1018 ngx_quic_frame_t *frame; |
ee53bfd8f9ed
Added QUIC version check for sending HANDSHAKE_DONE frame.
Vladimir Homutov <vl@nginx.com>
parents:
8273
diff
changeset
|
1019 |
8273
cb75f194f1f0
Implemented sending HANDSHAKE_DONE frame after handshake.
Vladimir Homutov <vl@nginx.com>
parents:
8272
diff
changeset
|
1020 frame = ngx_pcalloc(c->pool, sizeof(ngx_quic_frame_t)); |
cb75f194f1f0
Implemented sending HANDSHAKE_DONE frame after handshake.
Vladimir Homutov <vl@nginx.com>
parents:
8272
diff
changeset
|
1021 if (frame == NULL) { |
cb75f194f1f0
Implemented sending HANDSHAKE_DONE frame after handshake.
Vladimir Homutov <vl@nginx.com>
parents:
8272
diff
changeset
|
1022 return NGX_ERROR; |
cb75f194f1f0
Implemented sending HANDSHAKE_DONE frame after handshake.
Vladimir Homutov <vl@nginx.com>
parents:
8272
diff
changeset
|
1023 } |
cb75f194f1f0
Implemented sending HANDSHAKE_DONE frame after handshake.
Vladimir Homutov <vl@nginx.com>
parents:
8272
diff
changeset
|
1024 |
cb75f194f1f0
Implemented sending HANDSHAKE_DONE frame after handshake.
Vladimir Homutov <vl@nginx.com>
parents:
8272
diff
changeset
|
1025 /* 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
|
1026 frame->level = ssl_encryption_application; |
cb75f194f1f0
Implemented sending HANDSHAKE_DONE frame after handshake.
Vladimir Homutov <vl@nginx.com>
parents:
8272
diff
changeset
|
1027 frame->type = NGX_QUIC_FT_HANDSHAKE_DONE; |
cb75f194f1f0
Implemented sending HANDSHAKE_DONE frame after handshake.
Vladimir Homutov <vl@nginx.com>
parents:
8272
diff
changeset
|
1028 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
|
1029 ngx_quic_queue_frame(c->quic, frame); |
8274
ee53bfd8f9ed
Added QUIC version check for sending HANDSHAKE_DONE frame.
Vladimir Homutov <vl@nginx.com>
parents:
8273
diff
changeset
|
1030 } |
ee53bfd8f9ed
Added QUIC version check for sending HANDSHAKE_DONE frame.
Vladimir Homutov <vl@nginx.com>
parents:
8273
diff
changeset
|
1031 #endif |
8263
1295b293d09a
Connection states code cleanup.
Vladimir Homutov <vl@nginx.com>
parents:
8260
diff
changeset
|
1032 } |
1295b293d09a
Connection states code cleanup.
Vladimir Homutov <vl@nginx.com>
parents:
8260
diff
changeset
|
1033 |
8225 | 1034 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, |
1035 "SSL_quic_read_level: %d, SSL_quic_write_level: %d", | |
1036 (int) SSL_quic_read_level(ssl_conn), | |
1037 (int) SSL_quic_write_level(ssl_conn)); | |
1038 | |
1039 return NGX_OK; | |
1040 } | |
1041 | |
1042 | |
1043 static ngx_int_t | |
1044 ngx_quic_handle_stream_frame(ngx_connection_t *c, | |
1045 ngx_quic_header_t *pkt, ngx_quic_stream_frame_t *f) | |
1046 { | |
1047 ngx_buf_t *b; | |
8266
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
1048 ngx_event_t *rev; |
8225 | 1049 ngx_quic_connection_t *qc; |
1050 ngx_quic_stream_node_t *sn; | |
1051 | |
1052 qc = c->quic; | |
1053 | |
1054 sn = ngx_quic_find_stream(&qc->streams.tree, f->stream_id); | |
1055 | |
1056 if (sn) { | |
1057 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "existing stream"); | |
1058 b = sn->b; | |
1059 | |
8266
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
1060 if ((size_t) ((b->pos - b->start) + (b->end - b->last)) < f->length) { |
8225 | 1061 ngx_log_error(NGX_LOG_INFO, c->log, 0, "no space in stream buffer"); |
1062 return NGX_ERROR; | |
1063 } | |
1064 | |
8266
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
1065 if ((size_t) (b->end - b->last) < f->length) { |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
1066 b->last = ngx_movemem(b->start, b->pos, b->last - b->pos); |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
1067 b->pos = b->start; |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
1068 } |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
1069 |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
1070 b->last = ngx_cpymem(b->last, f->data, f->length); |
8225 | 1071 |
8266
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
1072 rev = sn->c->read; |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
1073 rev->ready = 1; |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
1074 |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
1075 if (rev->active) { |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
1076 rev->handler(rev); |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
1077 } |
8225 | 1078 |
1079 return NGX_OK; | |
1080 } | |
1081 | |
1082 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "stream is new"); | |
1083 | |
8229
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1084 sn = ngx_quic_create_stream(c, f->stream_id); |
8225 | 1085 if (sn == NULL) { |
1086 return NGX_ERROR; | |
1087 } | |
1088 | |
1089 b = sn->b; | |
1090 | |
1091 ngx_memcpy(b->start, f->data, f->length); | |
1092 b->last = b->start + f->length; | |
1093 | |
1094 qc->streams.handler(sn->c); | |
1095 | |
1096 return NGX_OK; | |
1097 } | |
1098 | |
1099 | |
8245
a14afe21e692
Double MAX_STREAMS on STREAMS_BLOCKED.
Roman Arutyunyan <arut@nginx.com>
parents:
8241
diff
changeset
|
1100 static ngx_int_t |
a14afe21e692
Double MAX_STREAMS on STREAMS_BLOCKED.
Roman Arutyunyan <arut@nginx.com>
parents:
8241
diff
changeset
|
1101 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
|
1102 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
|
1103 { |
a14afe21e692
Double MAX_STREAMS on STREAMS_BLOCKED.
Roman Arutyunyan <arut@nginx.com>
parents:
8241
diff
changeset
|
1104 ngx_quic_frame_t *frame; |
a14afe21e692
Double MAX_STREAMS on STREAMS_BLOCKED.
Roman Arutyunyan <arut@nginx.com>
parents:
8241
diff
changeset
|
1105 |
a14afe21e692
Double MAX_STREAMS on STREAMS_BLOCKED.
Roman Arutyunyan <arut@nginx.com>
parents:
8241
diff
changeset
|
1106 frame = ngx_pcalloc(c->pool, sizeof(ngx_quic_frame_t)); |
a14afe21e692
Double MAX_STREAMS on STREAMS_BLOCKED.
Roman Arutyunyan <arut@nginx.com>
parents:
8241
diff
changeset
|
1107 if (frame == NULL) { |
a14afe21e692
Double MAX_STREAMS on STREAMS_BLOCKED.
Roman Arutyunyan <arut@nginx.com>
parents:
8241
diff
changeset
|
1108 return NGX_ERROR; |
a14afe21e692
Double MAX_STREAMS on STREAMS_BLOCKED.
Roman Arutyunyan <arut@nginx.com>
parents:
8241
diff
changeset
|
1109 } |
a14afe21e692
Double MAX_STREAMS on STREAMS_BLOCKED.
Roman Arutyunyan <arut@nginx.com>
parents:
8241
diff
changeset
|
1110 |
a14afe21e692
Double MAX_STREAMS on STREAMS_BLOCKED.
Roman Arutyunyan <arut@nginx.com>
parents:
8241
diff
changeset
|
1111 frame->level = pkt->level; |
a14afe21e692
Double MAX_STREAMS on STREAMS_BLOCKED.
Roman Arutyunyan <arut@nginx.com>
parents:
8241
diff
changeset
|
1112 frame->type = NGX_QUIC_FT_MAX_STREAMS; |
a14afe21e692
Double MAX_STREAMS on STREAMS_BLOCKED.
Roman Arutyunyan <arut@nginx.com>
parents:
8241
diff
changeset
|
1113 frame->u.max_streams.limit = f->limit * 2; |
a14afe21e692
Double MAX_STREAMS on STREAMS_BLOCKED.
Roman Arutyunyan <arut@nginx.com>
parents:
8241
diff
changeset
|
1114 frame->u.max_streams.bidi = f->bidi; |
a14afe21e692
Double MAX_STREAMS on STREAMS_BLOCKED.
Roman Arutyunyan <arut@nginx.com>
parents:
8241
diff
changeset
|
1115 |
a14afe21e692
Double MAX_STREAMS on STREAMS_BLOCKED.
Roman Arutyunyan <arut@nginx.com>
parents:
8241
diff
changeset
|
1116 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
|
1117 (int) frame->u.max_streams.limit, |
a14afe21e692
Double MAX_STREAMS on STREAMS_BLOCKED.
Roman Arutyunyan <arut@nginx.com>
parents:
8241
diff
changeset
|
1118 (int) frame->u.max_streams.bidi, |
a14afe21e692
Double MAX_STREAMS on STREAMS_BLOCKED.
Roman Arutyunyan <arut@nginx.com>
parents:
8241
diff
changeset
|
1119 frame->level); |
a14afe21e692
Double MAX_STREAMS on STREAMS_BLOCKED.
Roman Arutyunyan <arut@nginx.com>
parents:
8241
diff
changeset
|
1120 |
a14afe21e692
Double MAX_STREAMS on STREAMS_BLOCKED.
Roman Arutyunyan <arut@nginx.com>
parents:
8241
diff
changeset
|
1121 ngx_quic_queue_frame(c->quic, frame); |
a14afe21e692
Double MAX_STREAMS on STREAMS_BLOCKED.
Roman Arutyunyan <arut@nginx.com>
parents:
8241
diff
changeset
|
1122 |
a14afe21e692
Double MAX_STREAMS on STREAMS_BLOCKED.
Roman Arutyunyan <arut@nginx.com>
parents:
8241
diff
changeset
|
1123 return NGX_OK; |
a14afe21e692
Double MAX_STREAMS on STREAMS_BLOCKED.
Roman Arutyunyan <arut@nginx.com>
parents:
8241
diff
changeset
|
1124 } |
a14afe21e692
Double MAX_STREAMS on STREAMS_BLOCKED.
Roman Arutyunyan <arut@nginx.com>
parents:
8241
diff
changeset
|
1125 |
a14afe21e692
Double MAX_STREAMS on STREAMS_BLOCKED.
Roman Arutyunyan <arut@nginx.com>
parents:
8241
diff
changeset
|
1126 |
8266
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
1127 static ngx_int_t |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
1128 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
|
1129 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
|
1130 { |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
1131 size_t n; |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
1132 ngx_buf_t *b; |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
1133 ngx_quic_frame_t *frame; |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
1134 ngx_quic_connection_t *qc; |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
1135 ngx_quic_stream_node_t *sn; |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
1136 |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
1137 qc = c->quic; |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
1138 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
|
1139 |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
1140 if (sn == NULL) { |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
1141 ngx_log_error(NGX_LOG_INFO, c->log, 0, "unknown stream id:%uL", f->id); |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
1142 return NGX_ERROR; |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
1143 } |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
1144 |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
1145 b = sn->b; |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
1146 n = (b->pos - b->start) + (b->end - b->last); |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
1147 |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
1148 frame = ngx_pcalloc(c->pool, sizeof(ngx_quic_frame_t)); |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
1149 if (frame == NULL) { |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
1150 return NGX_ERROR; |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
1151 } |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
1152 |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
1153 frame->level = pkt->level; |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
1154 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
|
1155 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
|
1156 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
|
1157 |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
1158 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
|
1159 (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
|
1160 (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
|
1161 frame->level); |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
1162 |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
1163 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
|
1164 |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
1165 return NGX_OK; |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
1166 } |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
1167 |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
1168 |
8225 | 1169 static void |
1170 ngx_quic_queue_frame(ngx_quic_connection_t *qc, ngx_quic_frame_t *frame) | |
1171 { | |
8270
c87a13514abc
Allow ngx_queue_frame() to insert frame in the front.
Roman Arutyunyan <arut@nginx.com>
parents:
8267
diff
changeset
|
1172 ngx_quic_frame_t **f; |
8225 | 1173 |
8270
c87a13514abc
Allow ngx_queue_frame() to insert frame in the front.
Roman Arutyunyan <arut@nginx.com>
parents:
8267
diff
changeset
|
1174 for (f = &qc->frames; *f; f = &(*f)->next) { |
c87a13514abc
Allow ngx_queue_frame() to insert frame in the front.
Roman Arutyunyan <arut@nginx.com>
parents:
8267
diff
changeset
|
1175 if ((*f)->level > frame->level) { |
8225 | 1176 break; |
1177 } | |
1178 } | |
1179 | |
8270
c87a13514abc
Allow ngx_queue_frame() to insert frame in the front.
Roman Arutyunyan <arut@nginx.com>
parents:
8267
diff
changeset
|
1180 frame->next = *f; |
c87a13514abc
Allow ngx_queue_frame() to insert frame in the front.
Roman Arutyunyan <arut@nginx.com>
parents:
8267
diff
changeset
|
1181 *f = frame; |
8225 | 1182 } |
1183 | |
1184 | |
1185 static ngx_int_t | |
1186 ngx_quic_output(ngx_connection_t *c) | |
1187 { | |
8265
d45325e90221
Limit output QUIC packets with client max_packet_size.
Roman Arutyunyan <arut@nginx.com>
parents:
8263
diff
changeset
|
1188 size_t len, hlen, n; |
8225 | 1189 ngx_uint_t lvl; |
1190 ngx_quic_frame_t *f, *start; | |
1191 ngx_quic_connection_t *qc; | |
1192 | |
1193 qc = c->quic; | |
1194 | |
1195 if (qc->frames == NULL) { | |
1196 return NGX_OK; | |
1197 } | |
1198 | |
1199 lvl = qc->frames->level; | |
1200 start = qc->frames; | |
1201 f = start; | |
1202 | |
1203 do { | |
1204 len = 0; | |
1205 | |
8265
d45325e90221
Limit output QUIC packets with client max_packet_size.
Roman Arutyunyan <arut@nginx.com>
parents:
8263
diff
changeset
|
1206 hlen = (lvl == ssl_encryption_application) ? NGX_QUIC_MAX_SHORT_HEADER |
d45325e90221
Limit output QUIC packets with client max_packet_size.
Roman Arutyunyan <arut@nginx.com>
parents:
8263
diff
changeset
|
1207 : NGX_QUIC_MAX_LONG_HEADER; |
d45325e90221
Limit output QUIC packets with client max_packet_size.
Roman Arutyunyan <arut@nginx.com>
parents:
8263
diff
changeset
|
1208 |
8225 | 1209 do { |
1210 /* process same-level group of frames */ | |
1211 | |
8265
d45325e90221
Limit output QUIC packets with client max_packet_size.
Roman Arutyunyan <arut@nginx.com>
parents:
8263
diff
changeset
|
1212 n = ngx_quic_create_frame(NULL, NULL, f); |
d45325e90221
Limit output QUIC packets with client max_packet_size.
Roman Arutyunyan <arut@nginx.com>
parents:
8263
diff
changeset
|
1213 |
d45325e90221
Limit output QUIC packets with client max_packet_size.
Roman Arutyunyan <arut@nginx.com>
parents:
8263
diff
changeset
|
1214 if (len && hlen + len + n > qc->ctp.max_packet_size) { |
d45325e90221
Limit output QUIC packets with client max_packet_size.
Roman Arutyunyan <arut@nginx.com>
parents:
8263
diff
changeset
|
1215 break; |
d45325e90221
Limit output QUIC packets with client max_packet_size.
Roman Arutyunyan <arut@nginx.com>
parents:
8263
diff
changeset
|
1216 } |
d45325e90221
Limit output QUIC packets with client max_packet_size.
Roman Arutyunyan <arut@nginx.com>
parents:
8263
diff
changeset
|
1217 |
d45325e90221
Limit output QUIC packets with client max_packet_size.
Roman Arutyunyan <arut@nginx.com>
parents:
8263
diff
changeset
|
1218 len += n; |
8225 | 1219 |
1220 f = f->next; | |
1221 } while (f && f->level == lvl); | |
1222 | |
1223 | |
1224 if (ngx_quic_frames_send(c, start, f, len) != NGX_OK) { | |
1225 return NGX_ERROR; | |
1226 } | |
1227 | |
1228 if (f == NULL) { | |
1229 break; | |
1230 } | |
1231 | |
1232 lvl = f->level; // TODO: must not decrease (ever, also between calls) | |
1233 start = f; | |
1234 | |
1235 } while (1); | |
1236 | |
1237 qc->frames = NULL; | |
1238 | |
8271
8e54a17dabee
Respect QUIC max_idle_timeout.
Roman Arutyunyan <arut@nginx.com>
parents:
8270
diff
changeset
|
1239 if (!qc->send_timer_set) { |
8e54a17dabee
Respect QUIC max_idle_timeout.
Roman Arutyunyan <arut@nginx.com>
parents:
8270
diff
changeset
|
1240 qc->send_timer_set = 1; |
8e54a17dabee
Respect QUIC max_idle_timeout.
Roman Arutyunyan <arut@nginx.com>
parents:
8270
diff
changeset
|
1241 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
|
1242 } |
8e54a17dabee
Respect QUIC max_idle_timeout.
Roman Arutyunyan <arut@nginx.com>
parents:
8270
diff
changeset
|
1243 |
8225 | 1244 return NGX_OK; |
1245 } | |
1246 | |
1247 | |
1248 /* pack a group of frames [start; end) into memory p and send as single packet */ | |
1249 ngx_int_t | |
1250 ngx_quic_frames_send(ngx_connection_t *c, ngx_quic_frame_t *start, | |
1251 ngx_quic_frame_t *end, size_t total) | |
1252 { | |
1253 ssize_t len; | |
1254 u_char *p; | |
1255 ngx_str_t out; | |
1256 ngx_quic_frame_t *f; | |
1257 | |
1258 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
1259 "sending frames %p...%p", start, end); | |
1260 | |
1261 p = ngx_pnalloc(c->pool, total); | |
1262 if (p == NULL) { | |
1263 return NGX_ERROR; | |
1264 } | |
1265 | |
1266 out.data = p; | |
1267 | |
1268 for (f = start; f != end; f = f->next) { | |
1269 | |
1270 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "frame: %s", f->info); | |
1271 | |
1272 len = ngx_quic_create_frame(p, p + total, f); | |
1273 if (len == -1) { | |
1274 return NGX_ERROR; | |
1275 } | |
1276 | |
1277 p += len; | |
1278 } | |
1279 | |
1280 out.len = p - out.data; | |
1281 | |
1282 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
1283 "packet ready: %ui bytes at level %d", | |
1284 out.len, start->level); | |
1285 | |
1286 // IOVEC/sendmsg_chain ? | |
1287 if (ngx_quic_send_packet(c, c->quic, start->level, &out) != NGX_OK) { | |
1288 return NGX_ERROR; | |
1289 } | |
1290 | |
1291 return NGX_OK; | |
1292 } | |
1293 | |
1294 | |
1295 static ngx_int_t | |
1296 ngx_quic_send_packet(ngx_connection_t *c, ngx_quic_connection_t *qc, | |
1297 enum ssl_encryption_level_t level, ngx_str_t *payload) | |
1298 { | |
1299 ngx_str_t res; | |
1300 ngx_quic_header_t pkt; | |
1301 | |
1302 pkt.log = c->log; | |
1303 | |
1304 static ngx_str_t initial_token = ngx_null_string; | |
1305 | |
1306 ngx_memzero(&pkt, sizeof(ngx_quic_header_t)); | |
1307 ngx_quic_hexdump0(c->log, "payload", payload->data, payload->len); | |
1308 | |
1309 pkt.level = level; | |
1310 pkt.dcid = qc->dcid; | |
1311 pkt.scid = qc->scid; | |
1312 | |
1313 if (level == ssl_encryption_initial) { | |
1314 pkt.number = &qc->initial_pn; | |
1315 pkt.flags = NGX_QUIC_PKT_INITIAL; | |
1316 pkt.secret = &qc->secrets.server.in; | |
1317 pkt.token = initial_token; | |
1318 | |
1319 } else if (level == ssl_encryption_handshake) { | |
1320 pkt.number = &qc->handshake_pn; | |
1321 pkt.flags = NGX_QUIC_PKT_HANDSHAKE; | |
1322 pkt.secret = &qc->secrets.server.hs; | |
1323 | |
1324 } else { | |
1325 pkt.number = &qc->appdata_pn; | |
1326 pkt.secret = &qc->secrets.server.ad; | |
1327 } | |
1328 | |
1329 if (ngx_quic_encrypt(c->pool, c->ssl->connection, &pkt, payload, &res) | |
1330 != NGX_OK) | |
1331 { | |
1332 return NGX_ERROR; | |
1333 } | |
1334 | |
1335 ngx_quic_hexdump0(c->log, "packet to send", res.data, res.len); | |
1336 | |
1337 c->send(c, res.data, res.len); // TODO: err handling | |
1338 | |
1339 (*pkt.number)++; | |
1340 | |
1341 return NGX_OK; | |
1342 } | |
1343 | |
1344 | |
1345 ngx_connection_t * | |
1346 ngx_quic_create_uni_stream(ngx_connection_t *c) | |
1347 { | |
8229
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1348 ngx_uint_t id; |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1349 ngx_quic_stream_t *qs; |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1350 ngx_quic_connection_t *qc; |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1351 ngx_quic_stream_node_t *sn; |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1352 |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1353 qs = c->qs; |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1354 qc = qs->parent->quic; |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1355 |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1356 /* |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1357 * A stream ID is a 62-bit integer that is unique for all streams |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1358 * on a connection. |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1359 * |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1360 * 0x3 | Server-Initiated, Unidirectional |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1361 */ |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1362 id = (qc->streams.id_counter << 2) | 0x3; |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1363 |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1364 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1365 "creating server uni stream #%ui id %ui", |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1366 qc->streams.id_counter, id); |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1367 |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1368 qc->streams.id_counter++; |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1369 |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1370 sn = ngx_quic_create_stream(qs->parent, id); |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1371 if (sn == NULL) { |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1372 return NULL; |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1373 } |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1374 |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1375 return sn->c; |
8225 | 1376 } |
1377 | |
1378 | |
1379 static void | |
1380 ngx_quic_rbtree_insert_stream(ngx_rbtree_node_t *temp, | |
1381 ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel) | |
1382 { | |
1383 ngx_rbtree_node_t **p; | |
1384 ngx_quic_stream_node_t *qn, *qnt; | |
1385 | |
1386 for ( ;; ) { | |
1387 | |
1388 if (node->key < temp->key) { | |
1389 | |
1390 p = &temp->left; | |
1391 | |
1392 } else if (node->key > temp->key) { | |
1393 | |
1394 p = &temp->right; | |
1395 | |
1396 } else { /* node->key == temp->key */ | |
1397 | |
1398 qn = (ngx_quic_stream_node_t *) &node->color; | |
1399 qnt = (ngx_quic_stream_node_t *) &temp->color; | |
1400 | |
1401 if (qn->c < qnt->c) { | |
1402 p = &temp->left; | |
1403 } else { | |
1404 p = &temp->right; | |
1405 } | |
1406 } | |
1407 | |
1408 if (*p == sentinel) { | |
1409 break; | |
1410 } | |
1411 | |
1412 temp = *p; | |
1413 } | |
1414 | |
1415 *p = node; | |
1416 node->parent = temp; | |
1417 node->left = sentinel; | |
1418 node->right = sentinel; | |
1419 ngx_rbt_red(node); | |
1420 } | |
1421 | |
1422 | |
1423 static ngx_quic_stream_node_t * | |
1424 ngx_quic_find_stream(ngx_rbtree_t *rbtree, ngx_uint_t key) | |
1425 { | |
1426 ngx_rbtree_node_t *node, *sentinel; | |
1427 | |
1428 node = rbtree->root; | |
1429 sentinel = rbtree->sentinel; | |
1430 | |
1431 while (node != sentinel) { | |
1432 | |
1433 if (key == node->key) { | |
1434 return (ngx_quic_stream_node_t *) node; | |
1435 } | |
1436 | |
1437 node = (key < node->key) ? node->left : node->right; | |
1438 } | |
1439 | |
1440 return NULL; | |
1441 } | |
1442 | |
1443 | |
8229
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1444 static ngx_quic_stream_node_t * |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1445 ngx_quic_create_stream(ngx_connection_t *c, ngx_uint_t id) |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1446 { |
8266
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
1447 size_t n; |
8229
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1448 ngx_log_t *log; |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1449 ngx_pool_t *pool; |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1450 ngx_event_t *rev, *wev; |
8239
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
1451 ngx_pool_cleanup_t *cln; |
8229
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1452 ngx_quic_connection_t *qc; |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1453 ngx_quic_stream_node_t *sn; |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1454 |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1455 qc = c->quic; |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1456 |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1457 sn = ngx_pcalloc(c->pool, sizeof(ngx_quic_stream_node_t)); |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1458 if (sn == NULL) { |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1459 return NULL; |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1460 } |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1461 |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1462 sn->c = ngx_get_connection(-1, c->log); // TODO: free on connection termination |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1463 if (sn->c == NULL) { |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1464 return NULL; |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1465 } |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1466 |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1467 pool = ngx_create_pool(NGX_DEFAULT_POOL_SIZE, c->log); |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1468 if (pool == NULL) { |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1469 /* XXX free connection */ |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1470 // TODO: add pool cleanup handdler |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1471 return NULL; |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1472 } |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1473 |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1474 log = ngx_palloc(pool, sizeof(ngx_log_t)); |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1475 if (log == NULL) { |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1476 /* XXX free pool and connection */ |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1477 return NULL; |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1478 } |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1479 |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1480 *log = *c->log; |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1481 pool->log = log; |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1482 |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1483 sn->c->log = log; |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1484 sn->c->pool = pool; |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1485 |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1486 sn->c->listening = c->listening; |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1487 sn->c->sockaddr = c->sockaddr; |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1488 sn->c->local_sockaddr = c->local_sockaddr; |
8234
19bb9edcd8bd
Added copying addr_text to QUIC stream connections.
Roman Arutyunyan <arut@nginx.com>
parents:
8232
diff
changeset
|
1489 sn->c->addr_text = c->addr_text; |
8272
7f0981be07c4
Fixed client certificate verification.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8271
diff
changeset
|
1490 sn->c->ssl = c->ssl; |
8229
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1491 |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1492 rev = sn->c->read; |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1493 wev = sn->c->write; |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1494 |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1495 rev->ready = 1; |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1496 |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1497 rev->log = c->log; |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1498 wev->log = c->log; |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1499 |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1500 sn->c->number = ngx_atomic_fetch_add(ngx_connection_counter, 1); |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1501 |
8266
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
1502 n = ngx_max(NGX_QUIC_STREAM_BUFSIZE, |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
1503 qc->tp.initial_max_stream_data_bidi_remote); |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
1504 |
8229
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1505 sn->node.key =id; |
8266
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
1506 sn->b = ngx_create_temp_buf(pool, n); |
8229
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1507 if (sn->b == NULL) { |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1508 return NULL; |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1509 } |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1510 |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1511 ngx_rbtree_insert(&qc->streams.tree, &sn->node); |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1512 |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1513 sn->s.id = id; |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1514 sn->s.unidirectional = (sn->s.id & 0x02) ? 1 : 0; |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1515 sn->s.parent = c; |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1516 sn->c->qs = &sn->s; |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1517 |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1518 sn->c->recv = ngx_quic_stream_recv; |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1519 sn->c->send = ngx_quic_stream_send; |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1520 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
|
1521 |
8239
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
1522 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
|
1523 if (cln == NULL) { |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
1524 ngx_close_connection(sn->c); |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
1525 ngx_destroy_pool(pool); |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
1526 return NULL; |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
1527 } |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
1528 |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
1529 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
|
1530 cln->data = sn->c; |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
1531 |
8229
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1532 return sn; |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1533 } |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1534 |
cfc429911c0d
Implemented creation of server unidirectional streams.
Vladimir Homutov <vl@nginx.com>
parents:
8225
diff
changeset
|
1535 |
8225 | 1536 static ssize_t |
1537 ngx_quic_stream_recv(ngx_connection_t *c, u_char *buf, size_t size) | |
1538 { | |
1539 ssize_t len; | |
1540 ngx_buf_t *b; | |
1541 ngx_quic_stream_t *qs; | |
1542 ngx_quic_connection_t *qc; | |
1543 ngx_quic_stream_node_t *sn; | |
1544 | |
1545 qs = c->qs; | |
1546 qc = qs->parent->quic; | |
1547 | |
1548 // XXX: get direct pointer from stream structure? | |
1549 sn = ngx_quic_find_stream(&qc->streams.tree, qs->id); | |
1550 | |
1551 if (sn == NULL) { | |
1552 return NGX_ERROR; | |
1553 } | |
1554 | |
1555 // XXX: how to return EOF? | |
1556 | |
1557 b = sn->b; | |
1558 | |
8266
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
1559 if (b->pos == b->last) { |
8225 | 1560 c->read->ready = 0; |
8266
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
1561 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "quic recv() not ready"); |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
1562 return NGX_AGAIN; |
8225 | 1563 } |
1564 | |
1565 len = ngx_min(b->last - b->pos, (ssize_t) size); | |
1566 | |
1567 ngx_memcpy(buf, b->pos, len); | |
1568 | |
1569 b->pos += len; | |
1570 | |
8266
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
1571 if (b->pos == b->last) { |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
1572 b->pos = b->start; |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
1573 b->last = b->start; |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
1574 } |
f92e583fc256
Better flow control and buffering for QUIC streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8265
diff
changeset
|
1575 |
8225 | 1576 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, |
1577 "quic recv: %z of %uz", len, size); | |
1578 | |
1579 return len; | |
1580 } | |
1581 | |
1582 | |
1583 static ssize_t | |
1584 ngx_quic_stream_send(ngx_connection_t *c, u_char *buf, size_t size) | |
1585 { | |
1586 u_char *p; | |
1587 ngx_connection_t *pc; | |
1588 ngx_quic_frame_t *frame; | |
1589 ngx_quic_stream_t *qs; | |
1590 ngx_quic_connection_t *qc; | |
1591 ngx_quic_stream_node_t *sn; | |
1592 | |
1593 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "quic send: %uz", size); | |
1594 | |
1595 qs = c->qs; | |
1596 pc = qs->parent; | |
1597 qc = pc->quic; | |
1598 | |
1599 // XXX: get direct pointer from stream structure? | |
1600 sn = ngx_quic_find_stream(&qc->streams.tree, qs->id); | |
1601 | |
1602 if (sn == NULL) { | |
1603 return NGX_ERROR; | |
1604 } | |
1605 | |
1606 frame = ngx_pcalloc(pc->pool, sizeof(ngx_quic_frame_t)); | |
1607 if (frame == NULL) { | |
1608 return 0; | |
1609 } | |
1610 | |
1611 p = ngx_pnalloc(pc->pool, size); | |
1612 if (p == NULL) { | |
1613 return 0; | |
1614 } | |
1615 | |
1616 ngx_memcpy(p, buf, size); | |
1617 | |
1618 frame->level = ssl_encryption_application; | |
1619 frame->type = NGX_QUIC_FT_STREAM6; /* OFF=1 LEN=1 FIN=0 */ | |
1620 frame->u.stream.off = 1; | |
1621 frame->u.stream.len = 1; | |
1622 frame->u.stream.fin = 0; | |
1623 | |
1624 frame->u.stream.type = frame->type; | |
1625 frame->u.stream.stream_id = qs->id; | |
1626 frame->u.stream.offset = c->sent; | |
1627 frame->u.stream.length = size; | |
1628 frame->u.stream.data = p; | |
1629 | |
1630 c->sent += size; | |
1631 | |
1632 ngx_sprintf(frame->info, "stream %xi len=%ui level=%d", | |
1633 qs->id, size, frame->level); | |
1634 | |
1635 ngx_quic_queue_frame(qc, frame); | |
1636 | |
1637 return size; | |
1638 } | |
1639 | |
1640 | |
8239
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
1641 static void |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
1642 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
|
1643 { |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
1644 ngx_connection_t *c = data; |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
1645 |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
1646 ngx_connection_t *pc; |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
1647 ngx_quic_frame_t *frame; |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
1648 ngx_quic_stream_t *qs; |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
1649 ngx_quic_connection_t *qc; |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
1650 ngx_quic_stream_node_t *sn; |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
1651 |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
1652 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "quic send fin"); |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
1653 |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
1654 qs = c->qs; |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
1655 pc = qs->parent; |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
1656 qc = pc->quic; |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
1657 |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
1658 if ((qs->id & 0x03) == 0x02) { |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
1659 /* 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
|
1660 return; |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
1661 } |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
1662 |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
1663 // XXX: get direct pointer from stream structure? |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
1664 sn = ngx_quic_find_stream(&qc->streams.tree, qs->id); |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
1665 |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
1666 if (sn == NULL) { |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
1667 return; |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
1668 } |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
1669 |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
1670 frame = ngx_pcalloc(pc->pool, sizeof(ngx_quic_frame_t)); |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
1671 if (frame == NULL) { |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
1672 return; |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
1673 } |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
1674 |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
1675 frame->level = ssl_encryption_application; |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
1676 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
|
1677 frame->u.stream.off = 1; |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
1678 frame->u.stream.len = 1; |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
1679 frame->u.stream.fin = 1; |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
1680 |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
1681 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
|
1682 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
|
1683 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
|
1684 frame->u.stream.length = 0; |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
1685 frame->u.stream.data = NULL; |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
1686 |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
1687 ngx_sprintf(frame->info, "stream %xi fin=1 level=%d", qs->id, frame->level); |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
1688 |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
1689 ngx_quic_queue_frame(qc, frame); |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
1690 } |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
1691 |
5ad7bffd3850
Send a FIN frame when QUIC stream is closed.
Roman Arutyunyan <arut@nginx.com>
parents:
8237
diff
changeset
|
1692 |
8225 | 1693 static ngx_chain_t * |
1694 ngx_quic_stream_send_chain(ngx_connection_t *c, ngx_chain_t *in, | |
1695 off_t limit) | |
1696 { | |
1697 size_t len; | |
1698 ssize_t n; | |
1699 ngx_buf_t *b; | |
1700 | |
1701 for ( /* void */; in; in = in->next) { | |
1702 b = in->buf; | |
1703 | |
1704 if (!ngx_buf_in_memory(b)) { | |
1705 continue; | |
1706 } | |
1707 | |
1708 if (ngx_buf_size(b) == 0) { | |
1709 continue; | |
1710 } | |
1711 | |
1712 len = b->last - b->pos; | |
1713 | |
1714 n = ngx_quic_stream_send(c, b->pos, len); | |
1715 | |
1716 if (n == NGX_ERROR) { | |
1717 return NGX_CHAIN_ERROR; | |
1718 } | |
1719 | |
1720 if (n == NGX_AGAIN) { | |
1721 return in; | |
1722 } | |
1723 | |
1724 if (n != (ssize_t) len) { | |
1725 b->pos += n; | |
1726 return in; | |
1727 } | |
1728 } | |
1729 | |
1730 return NULL; | |
1731 } |