Mercurial > hg > nginx
annotate src/event/quic/ngx_event_quic_socket.c @ 9017:c2f5d79cde64 quic
QUIC: separate UDP framework for QUIC.
Previously, QUIC used the existing UDP framework, which was created for UDP in
Stream. However the way QUIC connections are created and looked up is different
from the way UDP connections in Stream are created and looked up. Now these
two implementations are decoupled.
author | Roman Arutyunyan <arut@nginx.com> |
---|---|
date | Wed, 20 Apr 2022 16:01:17 +0400 |
parents | a2fbae359828 |
children | adcc6d8acfd4 |
rev | line source |
---|---|
8763 | 1 |
2 /* | |
3 * Copyright (C) Nginx, Inc. | |
4 */ | |
5 | |
6 | |
7 #include <ngx_config.h> | |
8 #include <ngx_core.h> | |
9 #include <ngx_event.h> | |
10 #include <ngx_event_quic_connection.h> | |
11 | |
12 | |
13 ngx_int_t | |
14 ngx_quic_open_sockets(ngx_connection_t *c, ngx_quic_connection_t *qc, | |
15 ngx_quic_header_t *pkt) | |
16 { | |
8955
32daba3aabb2
QUIC: got rid of ngx_quic_create_temp_socket().
Vladimir Homutov <vl@nginx.com>
parents:
8940
diff
changeset
|
17 ngx_quic_socket_t *qsock, *tmp; |
8763 | 18 ngx_quic_client_id_t *cid; |
19 | |
20 /* | |
8971
1e2f4e9c8195
QUIC: reworked migration handling.
Vladimir Homutov <vl@nginx.com>
parents:
8955
diff
changeset
|
21 * qc->path = NULL |
1e2f4e9c8195
QUIC: reworked migration handling.
Vladimir Homutov <vl@nginx.com>
parents:
8955
diff
changeset
|
22 * |
8763 | 23 * qc->nclient_ids = 0 |
24 * qc->nsockets = 0 | |
25 * qc->max_retired_seqnum = 0 | |
26 * qc->client_seqnum = 0 | |
27 */ | |
28 | |
29 ngx_queue_init(&qc->sockets); | |
30 ngx_queue_init(&qc->free_sockets); | |
31 | |
32 ngx_queue_init(&qc->paths); | |
33 ngx_queue_init(&qc->free_paths); | |
34 | |
35 ngx_queue_init(&qc->client_ids); | |
36 ngx_queue_init(&qc->free_client_ids); | |
37 | |
38 qc->tp.original_dcid.len = pkt->odcid.len; | |
39 qc->tp.original_dcid.data = ngx_pstrdup(c->pool, &pkt->odcid); | |
40 if (qc->tp.original_dcid.data == NULL) { | |
9015
a2fbae359828
QUIC: fixed indentation.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8997
diff
changeset
|
41 return NGX_ERROR; |
8763 | 42 } |
43 | |
8955
32daba3aabb2
QUIC: got rid of ngx_quic_create_temp_socket().
Vladimir Homutov <vl@nginx.com>
parents:
8940
diff
changeset
|
44 /* socket to use for further processing (id auto-generated) */ |
32daba3aabb2
QUIC: got rid of ngx_quic_create_temp_socket().
Vladimir Homutov <vl@nginx.com>
parents:
8940
diff
changeset
|
45 qsock = ngx_quic_create_socket(c, qc); |
8763 | 46 if (qsock == NULL) { |
47 return NGX_ERROR; | |
48 } | |
49 | |
8955
32daba3aabb2
QUIC: got rid of ngx_quic_create_temp_socket().
Vladimir Homutov <vl@nginx.com>
parents:
8940
diff
changeset
|
50 /* socket is listening at new server id */ |
8763 | 51 if (ngx_quic_listen(c, qc, qsock) != NGX_OK) { |
52 return NGX_ERROR; | |
53 } | |
54 | |
8971
1e2f4e9c8195
QUIC: reworked migration handling.
Vladimir Homutov <vl@nginx.com>
parents:
8955
diff
changeset
|
55 qsock->used = 1; |
1e2f4e9c8195
QUIC: reworked migration handling.
Vladimir Homutov <vl@nginx.com>
parents:
8955
diff
changeset
|
56 |
8763 | 57 qc->tp.initial_scid.len = qsock->sid.len; |
58 qc->tp.initial_scid.data = ngx_pnalloc(c->pool, qsock->sid.len); | |
59 if (qc->tp.initial_scid.data == NULL) { | |
60 goto failed; | |
61 } | |
62 ngx_memcpy(qc->tp.initial_scid.data, qsock->sid.id, qsock->sid.len); | |
63 | |
64 /* for all packets except first, this is set at udp layer */ | |
65 c->udp = &qsock->udp; | |
66 | |
67 /* ngx_quic_get_connection(c) macro is now usable */ | |
68 | |
69 /* we have a client identified by scid */ | |
70 cid = ngx_quic_create_client_id(c, &pkt->scid, 0, NULL); | |
71 if (cid == NULL) { | |
72 goto failed; | |
73 } | |
74 | |
8971
1e2f4e9c8195
QUIC: reworked migration handling.
Vladimir Homutov <vl@nginx.com>
parents:
8955
diff
changeset
|
75 /* path of the first packet is our initial active path */ |
1e2f4e9c8195
QUIC: reworked migration handling.
Vladimir Homutov <vl@nginx.com>
parents:
8955
diff
changeset
|
76 qc->path = ngx_quic_new_path(c, c->sockaddr, c->socklen, cid); |
1e2f4e9c8195
QUIC: reworked migration handling.
Vladimir Homutov <vl@nginx.com>
parents:
8955
diff
changeset
|
77 if (qc->path == NULL) { |
8763 | 78 goto failed; |
79 } | |
80 | |
8971
1e2f4e9c8195
QUIC: reworked migration handling.
Vladimir Homutov <vl@nginx.com>
parents:
8955
diff
changeset
|
81 qc->path->tag = NGX_QUIC_PATH_ACTIVE; |
1e2f4e9c8195
QUIC: reworked migration handling.
Vladimir Homutov <vl@nginx.com>
parents:
8955
diff
changeset
|
82 |
8763 | 83 if (pkt->validated) { |
8971
1e2f4e9c8195
QUIC: reworked migration handling.
Vladimir Homutov <vl@nginx.com>
parents:
8955
diff
changeset
|
84 qc->path->validated = 1; |
1e2f4e9c8195
QUIC: reworked migration handling.
Vladimir Homutov <vl@nginx.com>
parents:
8955
diff
changeset
|
85 qc->path->limited = 0; |
8763 | 86 } |
87 | |
8971
1e2f4e9c8195
QUIC: reworked migration handling.
Vladimir Homutov <vl@nginx.com>
parents:
8955
diff
changeset
|
88 ngx_quic_path_dbg(c, "set active", qc->path); |
8763 | 89 |
8955
32daba3aabb2
QUIC: got rid of ngx_quic_create_temp_socket().
Vladimir Homutov <vl@nginx.com>
parents:
8940
diff
changeset
|
90 tmp = ngx_pcalloc(c->pool, sizeof(ngx_quic_socket_t)); |
32daba3aabb2
QUIC: got rid of ngx_quic_create_temp_socket().
Vladimir Homutov <vl@nginx.com>
parents:
8940
diff
changeset
|
91 if (tmp == NULL) { |
8763 | 92 goto failed; |
93 } | |
94 | |
8955
32daba3aabb2
QUIC: got rid of ngx_quic_create_temp_socket().
Vladimir Homutov <vl@nginx.com>
parents:
8940
diff
changeset
|
95 tmp->sid.seqnum = NGX_QUIC_UNSET_PN; /* temporary socket */ |
32daba3aabb2
QUIC: got rid of ngx_quic_create_temp_socket().
Vladimir Homutov <vl@nginx.com>
parents:
8940
diff
changeset
|
96 |
32daba3aabb2
QUIC: got rid of ngx_quic_create_temp_socket().
Vladimir Homutov <vl@nginx.com>
parents:
8940
diff
changeset
|
97 ngx_memcpy(tmp->sid.id, pkt->odcid.data, pkt->odcid.len); |
32daba3aabb2
QUIC: got rid of ngx_quic_create_temp_socket().
Vladimir Homutov <vl@nginx.com>
parents:
8940
diff
changeset
|
98 tmp->sid.len = pkt->odcid.len; |
32daba3aabb2
QUIC: got rid of ngx_quic_create_temp_socket().
Vladimir Homutov <vl@nginx.com>
parents:
8940
diff
changeset
|
99 |
32daba3aabb2
QUIC: got rid of ngx_quic_create_temp_socket().
Vladimir Homutov <vl@nginx.com>
parents:
8940
diff
changeset
|
100 if (ngx_quic_listen(c, qc, tmp) != NGX_OK) { |
32daba3aabb2
QUIC: got rid of ngx_quic_create_temp_socket().
Vladimir Homutov <vl@nginx.com>
parents:
8940
diff
changeset
|
101 goto failed; |
32daba3aabb2
QUIC: got rid of ngx_quic_create_temp_socket().
Vladimir Homutov <vl@nginx.com>
parents:
8940
diff
changeset
|
102 } |
32daba3aabb2
QUIC: got rid of ngx_quic_create_temp_socket().
Vladimir Homutov <vl@nginx.com>
parents:
8940
diff
changeset
|
103 |
8763 | 104 return NGX_OK; |
105 | |
106 failed: | |
107 | |
108 ngx_rbtree_delete(&c->listening->rbtree, &qsock->udp.node); | |
109 c->udp = NULL; | |
110 | |
111 return NGX_ERROR; | |
112 } | |
113 | |
114 | |
115 ngx_quic_socket_t * | |
8955
32daba3aabb2
QUIC: got rid of ngx_quic_create_temp_socket().
Vladimir Homutov <vl@nginx.com>
parents:
8940
diff
changeset
|
116 ngx_quic_create_socket(ngx_connection_t *c, ngx_quic_connection_t *qc) |
8763 | 117 { |
118 ngx_queue_t *q; | |
119 ngx_quic_socket_t *sock; | |
120 | |
121 if (!ngx_queue_empty(&qc->free_sockets)) { | |
122 | |
123 q = ngx_queue_head(&qc->free_sockets); | |
124 sock = ngx_queue_data(q, ngx_quic_socket_t, queue); | |
125 | |
126 ngx_queue_remove(&sock->queue); | |
127 | |
128 ngx_memzero(sock, sizeof(ngx_quic_socket_t)); | |
129 | |
130 } else { | |
131 | |
132 sock = ngx_pcalloc(c->pool, sizeof(ngx_quic_socket_t)); | |
133 if (sock == NULL) { | |
134 return NULL; | |
135 } | |
136 } | |
137 | |
8955
32daba3aabb2
QUIC: got rid of ngx_quic_create_temp_socket().
Vladimir Homutov <vl@nginx.com>
parents:
8940
diff
changeset
|
138 sock->sid.len = NGX_QUIC_SERVER_CID_LEN; |
32daba3aabb2
QUIC: got rid of ngx_quic_create_temp_socket().
Vladimir Homutov <vl@nginx.com>
parents:
8940
diff
changeset
|
139 if (ngx_quic_create_server_id(c, sock->sid.id) != NGX_OK) { |
32daba3aabb2
QUIC: got rid of ngx_quic_create_temp_socket().
Vladimir Homutov <vl@nginx.com>
parents:
8940
diff
changeset
|
140 return NULL; |
32daba3aabb2
QUIC: got rid of ngx_quic_create_temp_socket().
Vladimir Homutov <vl@nginx.com>
parents:
8940
diff
changeset
|
141 } |
32daba3aabb2
QUIC: got rid of ngx_quic_create_temp_socket().
Vladimir Homutov <vl@nginx.com>
parents:
8940
diff
changeset
|
142 |
32daba3aabb2
QUIC: got rid of ngx_quic_create_temp_socket().
Vladimir Homutov <vl@nginx.com>
parents:
8940
diff
changeset
|
143 sock->sid.seqnum = qc->server_seqnum++; |
32daba3aabb2
QUIC: got rid of ngx_quic_create_temp_socket().
Vladimir Homutov <vl@nginx.com>
parents:
8940
diff
changeset
|
144 |
8763 | 145 return sock; |
146 } | |
147 | |
148 | |
149 void | |
150 ngx_quic_close_socket(ngx_connection_t *c, ngx_quic_socket_t *qsock) | |
151 { | |
152 ngx_quic_connection_t *qc; | |
153 | |
154 qc = ngx_quic_get_connection(c); | |
155 | |
156 ngx_queue_remove(&qsock->queue); | |
157 ngx_queue_insert_head(&qc->free_sockets, &qsock->queue); | |
158 | |
159 ngx_rbtree_delete(&c->listening->rbtree, &qsock->udp.node); | |
160 qc->nsockets--; | |
161 | |
162 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
8997
fab36e4abf83
QUIC: got rid of hash symbol in backup and logging.
Vladimir Homutov <vl@nginx.com>
parents:
8971
diff
changeset
|
163 "quic socket seq:%L closed nsock:%ui", |
8763 | 164 (int64_t) qsock->sid.seqnum, qc->nsockets); |
165 } | |
166 | |
167 | |
168 ngx_int_t | |
169 ngx_quic_listen(ngx_connection_t *c, ngx_quic_connection_t *qc, | |
170 ngx_quic_socket_t *qsock) | |
171 { | |
172 ngx_str_t id; | |
173 ngx_quic_server_id_t *sid; | |
174 | |
175 sid = &qsock->sid; | |
176 | |
177 id.data = sid->id; | |
178 id.len = sid->len; | |
179 | |
9017
c2f5d79cde64
QUIC: separate UDP framework for QUIC.
Roman Arutyunyan <arut@nginx.com>
parents:
9015
diff
changeset
|
180 qsock->udp.connection = c; |
c2f5d79cde64
QUIC: separate UDP framework for QUIC.
Roman Arutyunyan <arut@nginx.com>
parents:
9015
diff
changeset
|
181 qsock->udp.node.key = ngx_crc32_long(id.data, id.len); |
c2f5d79cde64
QUIC: separate UDP framework for QUIC.
Roman Arutyunyan <arut@nginx.com>
parents:
9015
diff
changeset
|
182 |
c2f5d79cde64
QUIC: separate UDP framework for QUIC.
Roman Arutyunyan <arut@nginx.com>
parents:
9015
diff
changeset
|
183 ngx_rbtree_insert(&c->listening->rbtree, &qsock->udp.node); |
8763 | 184 |
185 ngx_queue_insert_tail(&qc->sockets, &qsock->queue); | |
186 | |
187 qc->nsockets++; | |
188 qsock->quic = qc; | |
189 | |
190 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
8997
fab36e4abf83
QUIC: got rid of hash symbol in backup and logging.
Vladimir Homutov <vl@nginx.com>
parents:
8971
diff
changeset
|
191 "quic socket seq:%L listening at sid:%xV nsock:%ui", |
8955
32daba3aabb2
QUIC: got rid of ngx_quic_create_temp_socket().
Vladimir Homutov <vl@nginx.com>
parents:
8940
diff
changeset
|
192 (int64_t) sid->seqnum, &id, qc->nsockets); |
8763 | 193 |
194 return NGX_OK; | |
195 } | |
196 | |
197 | |
198 void | |
199 ngx_quic_close_sockets(ngx_connection_t *c) | |
200 { | |
201 ngx_queue_t *q; | |
202 ngx_quic_socket_t *qsock; | |
203 ngx_quic_connection_t *qc; | |
204 | |
205 qc = ngx_quic_get_connection(c); | |
206 | |
207 while (!ngx_queue_empty(&qc->sockets)) { | |
208 q = ngx_queue_head(&qc->sockets); | |
209 qsock = ngx_queue_data(q, ngx_quic_socket_t, queue); | |
210 | |
211 ngx_quic_close_socket(c, qsock); | |
212 } | |
213 } | |
214 | |
215 | |
216 ngx_quic_socket_t * | |
217 ngx_quic_find_socket(ngx_connection_t *c, uint64_t seqnum) | |
218 { | |
219 ngx_queue_t *q; | |
220 ngx_quic_socket_t *qsock; | |
221 ngx_quic_connection_t *qc; | |
222 | |
223 qc = ngx_quic_get_connection(c); | |
224 | |
225 for (q = ngx_queue_head(&qc->sockets); | |
226 q != ngx_queue_sentinel(&qc->sockets); | |
227 q = ngx_queue_next(q)) | |
228 { | |
229 qsock = ngx_queue_data(q, ngx_quic_socket_t, queue); | |
230 | |
231 if (qsock->sid.seqnum == seqnum) { | |
232 return qsock; | |
233 } | |
234 } | |
235 | |
236 return NULL; | |
237 } |