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