quic 0.0.3 → 0.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/ext/quic/endpoint.c CHANGED
@@ -58,35 +58,29 @@ struct quic_endpoint {
58
58
  collide. */
59
59
  static st_index_t quic_cid_hash_seed;
60
60
 
61
- static int
62
- quic_cid_cmp(st_data_t a, st_data_t b)
63
- {
61
+ static int quic_cid_cmp(st_data_t a, st_data_t b) {
64
62
  return !ngtcp2_cid_eq((const ngtcp2_cid *)a, (const ngtcp2_cid *)b);
65
63
  }
66
64
 
67
- static st_index_t
68
- quic_cid_hash(st_data_t a)
69
- {
65
+ static st_index_t quic_cid_hash(st_data_t a) {
70
66
  const ngtcp2_cid *cid = (const ngtcp2_cid *)a;
71
67
  return st_hash(cid->data, cid->datalen, quic_cid_hash_seed);
72
68
  }
73
69
 
74
- static const struct st_hash_type quic_cid_hash_type = {quic_cid_cmp, quic_cid_hash};
70
+ static const struct st_hash_type quic_cid_hash_type = {quic_cid_cmp,
71
+ quic_cid_hash};
75
72
 
76
- static int
77
- quic_endpoint_mark_i(st_data_t key, st_data_t value, st_data_t arg)
78
- {
73
+ static int quic_endpoint_mark_i(st_data_t key, st_data_t value, st_data_t arg) {
79
74
  (void)key;
80
75
  (void)arg;
81
76
  rb_gc_mark_movable((VALUE)value);
82
77
  return ST_CONTINUE;
83
78
  }
84
79
 
85
- static void
86
- quic_endpoint_mark(void *ptr)
87
- {
80
+ static void quic_endpoint_mark(void *ptr) {
88
81
  quic_endpoint_t *ep = (quic_endpoint_t *)ptr;
89
- if (ep->cids != NULL) st_foreach(ep->cids, quic_endpoint_mark_i, 0);
82
+ if (ep->cids != NULL)
83
+ st_foreach(ep->cids, quic_endpoint_mark_i, 0);
90
84
  rb_gc_mark_movable(ep->conns);
91
85
  rb_gc_mark_movable(ep->responses);
92
86
  rb_gc_mark_movable(ep->closed);
@@ -96,9 +90,8 @@ quic_endpoint_mark(void *ptr)
96
90
  rb_gc_mark_movable(ep->settings);
97
91
  }
98
92
 
99
- static int
100
- quic_endpoint_compact_check_i(st_data_t key, st_data_t value, st_data_t arg, int error)
101
- {
93
+ static int quic_endpoint_compact_check_i(st_data_t key, st_data_t value,
94
+ st_data_t arg, int error) {
102
95
  (void)key;
103
96
  (void)value;
104
97
  (void)arg;
@@ -106,9 +99,8 @@ quic_endpoint_compact_check_i(st_data_t key, st_data_t value, st_data_t arg, int
106
99
  return ST_REPLACE;
107
100
  }
108
101
 
109
- static int
110
- quic_endpoint_compact_replace_i(st_data_t *key, st_data_t *value, st_data_t arg, int existing)
111
- {
102
+ static int quic_endpoint_compact_replace_i(st_data_t *key, st_data_t *value,
103
+ st_data_t arg, int existing) {
112
104
  (void)key;
113
105
  (void)arg;
114
106
  (void)existing;
@@ -116,9 +108,7 @@ quic_endpoint_compact_replace_i(st_data_t *key, st_data_t *value, st_data_t arg,
116
108
  return ST_CONTINUE;
117
109
  }
118
110
 
119
- static void
120
- quic_endpoint_compact(void *ptr)
121
- {
111
+ static void quic_endpoint_compact(void *ptr) {
122
112
  quic_endpoint_t *ep = (quic_endpoint_t *)ptr;
123
113
  if (ep->cids != NULL) {
124
114
  st_foreach_with_replace(ep->cids, quic_endpoint_compact_check_i,
@@ -133,9 +123,8 @@ quic_endpoint_compact(void *ptr)
133
123
  ep->settings = rb_gc_location(ep->settings);
134
124
  }
135
125
 
136
- static int
137
- quic_endpoint_free_key_i(st_data_t key, st_data_t value, st_data_t arg)
138
- {
126
+ static int quic_endpoint_free_key_i(st_data_t key, st_data_t value,
127
+ st_data_t arg) {
139
128
  (void)value;
140
129
  (void)arg;
141
130
  xfree((void *)key);
@@ -144,9 +133,7 @@ quic_endpoint_free_key_i(st_data_t key, st_data_t value, st_data_t arg)
144
133
 
145
134
  /* Connections still in the table are unreachable too (each marks the
146
135
  Endpoint), and quic_conn_free never reaches back here. */
147
- static void
148
- quic_endpoint_free(void *ptr)
149
- {
136
+ static void quic_endpoint_free(void *ptr) {
150
137
  quic_endpoint_t *ep = (quic_endpoint_t *)ptr;
151
138
  if (ep->cids != NULL) {
152
139
  st_foreach(ep->cids, quic_endpoint_free_key_i, 0);
@@ -156,31 +143,32 @@ quic_endpoint_free(void *ptr)
156
143
  xfree(ep);
157
144
  }
158
145
 
159
- static size_t
160
- quic_endpoint_size(const void *ptr)
161
- {
146
+ static size_t quic_endpoint_size(const void *ptr) {
162
147
  const quic_endpoint_t *ep = (const quic_endpoint_t *)ptr;
163
148
  return sizeof(*ep) + (ep->cids != NULL ? st_memsize(ep->cids) : 0);
164
149
  }
165
150
 
166
151
  static const rb_data_type_t quic_endpoint_data_type = {
167
- "QUIC::Endpoint",
168
- {quic_endpoint_mark, quic_endpoint_free, quic_endpoint_size, quic_endpoint_compact,},
169
- NULL, NULL,
170
- RUBY_TYPED_FREE_IMMEDIATELY,
152
+ "QUIC::Endpoint",
153
+ {
154
+ quic_endpoint_mark,
155
+ quic_endpoint_free,
156
+ quic_endpoint_size,
157
+ quic_endpoint_compact,
158
+ },
159
+ NULL,
160
+ NULL,
161
+ RUBY_TYPED_FREE_IMMEDIATELY,
171
162
  };
172
163
 
173
- static quic_endpoint_t *
174
- quic_endpoint_get(VALUE self)
175
- {
164
+ static quic_endpoint_t *quic_endpoint_get(VALUE self) {
176
165
  quic_endpoint_t *ep;
177
166
  TypedData_Get_Struct(self, quic_endpoint_t, &quic_endpoint_data_type, ep);
178
167
  return ep;
179
168
  }
180
169
 
181
- void
182
- quic_endpoint_associate_cid(quic_endpoint_t *ep, const ngtcp2_cid *cid, VALUE conn)
183
- {
170
+ void quic_endpoint_associate_cid(quic_endpoint_t *ep, const ngtcp2_cid *cid,
171
+ VALUE conn) {
184
172
  /* For a key already there, st_insert replaces the value and keeps the
185
173
  key it has, so a copy is made only for a new key. */
186
174
  if (st_lookup(ep->cids, (st_data_t)cid, NULL)) {
@@ -192,68 +180,65 @@ quic_endpoint_associate_cid(quic_endpoint_t *ep, const ngtcp2_cid *cid, VALUE co
192
180
  st_insert(ep->cids, (st_data_t)key, (st_data_t)conn);
193
181
  }
194
182
 
195
- void
196
- quic_endpoint_dissociate_cid(quic_endpoint_t *ep, const ngtcp2_cid *cid, VALUE conn)
197
- {
183
+ void quic_endpoint_dissociate_cid(quic_endpoint_t *ep, const ngtcp2_cid *cid,
184
+ VALUE conn) {
198
185
  st_data_t key = (st_data_t)cid;
199
186
  st_data_t value;
200
- if (!st_lookup(ep->cids, key, &value) || (VALUE)value != conn) return;
187
+ if (!st_lookup(ep->cids, key, &value) || (VALUE)value != conn)
188
+ return;
201
189
  /* st_delete hands back the stored key. */
202
- if (st_delete(ep->cids, &key, &value)) xfree((void *)key);
190
+ if (st_delete(ep->cids, &key, &value))
191
+ xfree((void *)key);
203
192
  }
204
193
 
205
- int
206
- quic_endpoint_generate_reset_token(const quic_endpoint_t *ep, uint8_t *token,
207
- const ngtcp2_cid *cid)
208
- {
209
- return ngtcp2_crypto_generate_stateless_reset_token(token, ep->reset_secret,
210
- sizeof(ep->reset_secret), cid) == 0
211
- ? 0 : -1;
194
+ int quic_endpoint_generate_reset_token(const quic_endpoint_t *ep,
195
+ uint8_t *token, const ngtcp2_cid *cid) {
196
+ return ngtcp2_crypto_generate_stateless_reset_token(
197
+ token, ep->reset_secret, sizeof(ep->reset_secret), cid) == 0
198
+ ? 0
199
+ : -1;
212
200
  }
213
201
 
214
- static VALUE
215
- quic_addr_str(const ngtcp2_addr *addr)
216
- {
202
+ static VALUE quic_addr_str(const ngtcp2_addr *addr) {
217
203
  return rb_str_new((const char *)addr->addr, (long)addr->addrlen);
218
204
  }
219
205
 
220
206
  /* Queue an answer for #write_pkt. Returns false when the queue is full and
221
207
  the answer was dropped. */
222
- static bool
223
- quic_endpoint_push_response(quic_endpoint_t *ep, VALUE pkt, VALUE to)
224
- {
225
- if (RARRAY_LEN(ep->responses) >= QUIC_ENDPOINT_MAX_RESPONSES) return false;
208
+ static bool quic_endpoint_push_response(quic_endpoint_t *ep, VALUE pkt,
209
+ VALUE to) {
210
+ if (RARRAY_LEN(ep->responses) >= QUIC_ENDPOINT_MAX_RESPONSES)
211
+ return false;
226
212
  rb_ary_push(ep->responses, rb_assoc_new(pkt, to));
227
213
  return true;
228
214
  }
229
215
 
230
- static void
231
- quic_conn_set_error(quic_conn_t *c, VALUE exc)
232
- {
216
+ static void quic_conn_set_error(quic_conn_t *c, VALUE exc) {
233
217
  /* The first failure is the reason; what follows is its consequence. */
234
- if (NIL_P(c->error)) c->error = exc;
218
+ if (NIL_P(c->error))
219
+ c->error = exc;
235
220
  }
236
221
 
237
222
  /* Take the Stateless Resets that came back since the last call, one per
238
223
  whole second. Computed on read_pkt rather than with a timer. */
239
- static void
240
- quic_endpoint_refill_reset_bucket(quic_endpoint_t *ep, ngtcp2_tstamp now)
241
- {
224
+ static void quic_endpoint_refill_reset_bucket(quic_endpoint_t *ep,
225
+ ngtcp2_tstamp now) {
242
226
  if (ep->reset_bucket >= QUIC_STATELESS_RESET_BURST) {
243
227
  ep->reset_refill_ts = now;
244
228
  return;
245
229
  }
246
230
  uint64_t n = (now - ep->reset_refill_ts) / NGTCP2_SECONDS;
247
- if (n == 0) return;
231
+ if (n == 0)
232
+ return;
248
233
  ep->reset_bucket = n >= QUIC_STATELESS_RESET_BURST - ep->reset_bucket
249
- ? QUIC_STATELESS_RESET_BURST : ep->reset_bucket + (size_t)n;
234
+ ? QUIC_STATELESS_RESET_BURST
235
+ : ep->reset_bucket + (size_t)n;
250
236
  ep->reset_refill_ts += n * NGTCP2_SECONDS;
251
237
  }
252
238
 
253
- static void
254
- quic_endpoint_send_version_negotiation(quic_endpoint_t *ep, const ngtcp2_version_cid *vc,
255
- VALUE remote)
256
- {
239
+ static void quic_endpoint_send_version_negotiation(quic_endpoint_t *ep,
240
+ const ngtcp2_version_cid *vc,
241
+ VALUE remote) {
257
242
  uint8_t unused_bits;
258
243
  uint32_t grease;
259
244
  if (RAND_bytes(&unused_bits, 1) != 1 ||
@@ -263,77 +248,87 @@ quic_endpoint_send_version_negotiation(quic_endpoint_t *ep, const ngtcp2_version
263
248
  /* A reserved version (0x?a?a?a?a) ahead of the one supported, so that
264
249
  clients keep handling versions they do not know (RFC 9000 section
265
250
  6.3). */
266
- uint32_t versions[] = {(grease & 0xf0f0f0f0U) | 0x0a0a0a0aU, NGTCP2_PROTO_VER_V1};
251
+ uint32_t versions[] = {(grease & 0xf0f0f0f0U) | 0x0a0a0a0aU,
252
+ NGTCP2_PROTO_VER_V1};
267
253
 
268
254
  VALUE pkt = rb_str_buf_new(NGTCP2_MAX_UDP_PAYLOAD_SIZE);
269
255
  ngtcp2_ssize n = ngtcp2_pkt_write_version_negotiation(
270
- (uint8_t *)RSTRING_PTR(pkt), NGTCP2_MAX_UDP_PAYLOAD_SIZE, unused_bits, vc->scid, vc->scidlen,
271
- vc->dcid, vc->dcidlen, versions, sizeof(versions) / sizeof(versions[0]));
272
- if (n <= 0) return;
256
+ (uint8_t *)RSTRING_PTR(pkt), NGTCP2_MAX_UDP_PAYLOAD_SIZE, unused_bits,
257
+ vc->scid, vc->scidlen, vc->dcid, vc->dcidlen, versions,
258
+ sizeof(versions) / sizeof(versions[0]));
259
+ if (n <= 0)
260
+ return;
273
261
  rb_str_set_len(pkt, n);
274
262
  quic_endpoint_push_response(ep, pkt, rb_str_dup(remote));
275
263
  }
276
264
 
277
265
  /* Tell the peer that this Endpoint has no state for dcid, as
278
266
  examples/server.cc's send_stateless_reset does. */
279
- static void
280
- quic_endpoint_send_stateless_reset(quic_endpoint_t *ep, const ngtcp2_cid *dcid, size_t pktlen,
281
- VALUE remote)
282
- {
283
- if (ep->reset_bucket == 0) return;
267
+ static void quic_endpoint_send_stateless_reset(quic_endpoint_t *ep,
268
+ const ngtcp2_cid *dcid,
269
+ size_t pktlen, VALUE remote) {
270
+ if (ep->reset_bucket == 0)
271
+ return;
284
272
  ep->reset_bucket--;
285
273
 
286
274
  ngtcp2_stateless_reset_token token;
287
- if (quic_endpoint_generate_reset_token(ep, token.data, dcid) != 0) return;
275
+ if (quic_endpoint_generate_reset_token(ep, token.data, dcid) != 0)
276
+ return;
288
277
 
289
278
  /* Shorter than the packet that prompted it, so that two endpoints cannot
290
279
  keep answering each other's resets (RFC 9000 section 10.3.3): one byte
291
280
  shorter up to 43 bytes, 42 bytes beyond. */
292
- enum { MAX_RANDLEN = NGTCP2_MAX_CIDLEN + 22 - NGTCP2_STATELESS_RESET_TOKENLEN };
281
+ enum {
282
+ MAX_RANDLEN = NGTCP2_MAX_CIDLEN + 22 - NGTCP2_STATELESS_RESET_TOKENLEN
283
+ };
293
284
  uint8_t rand_bytes[MAX_RANDLEN];
294
- size_t randlen = pktlen <= 43 ? pktlen - NGTCP2_STATELESS_RESET_TOKENLEN - 1 : MAX_RANDLEN;
295
- if (RAND_bytes(rand_bytes, (int)randlen) != 1) return;
285
+ size_t randlen =
286
+ pktlen <= 43 ? pktlen - NGTCP2_STATELESS_RESET_TOKENLEN - 1 : MAX_RANDLEN;
287
+ if (RAND_bytes(rand_bytes, (int)randlen) != 1)
288
+ return;
296
289
 
297
290
  VALUE pkt = rb_str_buf_new(NGTCP2_MAX_UDP_PAYLOAD_SIZE);
298
291
  ngtcp2_ssize n = ngtcp2_pkt_write_stateless_reset2(
299
- (uint8_t *)RSTRING_PTR(pkt), NGTCP2_MAX_UDP_PAYLOAD_SIZE, &token, rand_bytes, randlen);
300
- if (n <= 0) return;
292
+ (uint8_t *)RSTRING_PTR(pkt), NGTCP2_MAX_UDP_PAYLOAD_SIZE, &token,
293
+ rand_bytes, randlen);
294
+ if (n <= 0)
295
+ return;
301
296
  rb_str_set_len(pkt, n);
302
297
  quic_endpoint_push_response(ep, pkt, rb_str_dup(remote));
303
298
  }
304
299
 
305
300
  /* Turn a new connection away with CONNECTION_REFUSED in an Initial packet,
306
301
  without making any state for it. */
307
- static void
308
- quic_endpoint_refuse(quic_endpoint_t *ep, const ngtcp2_pkt_hd *hd, VALUE remote)
309
- {
302
+ static void quic_endpoint_refuse(quic_endpoint_t *ep, const ngtcp2_pkt_hd *hd,
303
+ VALUE remote) {
310
304
  VALUE pkt = rb_str_buf_new(NGTCP2_MAX_UDP_PAYLOAD_SIZE);
311
305
  /* Despite its documentation, this returns the packet's length. */
312
306
  ngtcp2_ssize n = ngtcp2_crypto_write_connection_close(
313
- (uint8_t *)RSTRING_PTR(pkt), NGTCP2_MAX_UDP_PAYLOAD_SIZE, hd->version, &hd->scid, &hd->dcid,
314
- NGTCP2_CONNECTION_REFUSED, NULL, 0);
315
- if (n <= 0) return;
307
+ (uint8_t *)RSTRING_PTR(pkt), NGTCP2_MAX_UDP_PAYLOAD_SIZE, hd->version,
308
+ &hd->scid, &hd->dcid, NGTCP2_CONNECTION_REFUSED, NULL, 0);
309
+ if (n <= 0)
310
+ return;
316
311
  rb_str_set_len(pkt, n);
317
312
  quic_endpoint_push_response(ep, pkt, rb_str_dup(remote));
318
313
  }
319
314
 
320
315
  /* The closing and draining periods last three PTOs (RFC 9000 section
321
316
  10.2). */
322
- static ngtcp2_tstamp
323
- quic_close_deadline(const quic_conn_t *c, ngtcp2_tstamp now)
324
- {
317
+ static ngtcp2_tstamp quic_close_deadline(const quic_conn_t *c,
318
+ ngtcp2_tstamp now) {
325
319
  return now + 3 * ngtcp2_conn_get_pto2(c->conn);
326
320
  }
327
321
 
328
322
  /* Enter the closing period with a CONNECTION_CLOSE carrying ccerr, and
329
323
  queue that packet. Returns false when ngtcp2 cannot build it; the
330
324
  connection then has to leave the table at once. */
331
- static bool
332
- quic_endpoint_start_closing(quic_endpoint_t *ep, quic_conn_t *c, const ngtcp2_ccerr *ccerr)
333
- {
325
+ static bool quic_endpoint_start_closing(quic_endpoint_t *ep, quic_conn_t *c,
326
+ const ngtcp2_ccerr *ccerr) {
334
327
  ngtcp2_tstamp now = quic_now();
335
- if (ngtcp2_conn_in_closing_period2(c->conn) || ngtcp2_conn_in_draining_period2(c->conn)) {
336
- if (c->close_deadline == 0) c->close_deadline = quic_close_deadline(c, now);
328
+ if (ngtcp2_conn_in_closing_period2(c->conn) ||
329
+ ngtcp2_conn_in_draining_period2(c->conn)) {
330
+ if (c->close_deadline == 0)
331
+ c->close_deadline = quic_close_deadline(c, now);
337
332
  return true;
338
333
  }
339
334
 
@@ -342,15 +337,19 @@ quic_endpoint_start_closing(quic_endpoint_t *ep, quic_conn_t *c, const ngtcp2_cc
342
337
  ngtcp2_pkt_info pi;
343
338
  VALUE pkt = rb_str_buf_new(QUIC_WRITE_PKT_BUFLEN);
344
339
  ngtcp2_ssize n = ngtcp2_conn_write_connection_close(
345
- c->conn, &ps.path, &pi, (uint8_t *)RSTRING_PTR(pkt), QUIC_WRITE_PKT_BUFLEN, ccerr, now);
346
- if (n < 0) return false;
340
+ c->conn, &ps.path, &pi, (uint8_t *)RSTRING_PTR(pkt),
341
+ QUIC_WRITE_PKT_BUFLEN, ccerr, now);
342
+ if (n < 0)
343
+ return false;
347
344
 
348
345
  c->close_deadline = quic_close_deadline(c, now);
349
346
  c->close_next_pkts_recv = 1;
350
- if (n == 0) return true;
347
+ if (n == 0)
348
+ return true;
351
349
  rb_str_set_len(pkt, n);
352
350
  c->closebuf = pkt;
353
- quic_endpoint_push_response(ep, rb_str_dup(pkt), quic_addr_str(&ps.path.remote));
351
+ quic_endpoint_push_response(ep, rb_str_dup(pkt),
352
+ quic_addr_str(&ps.path.remote));
354
353
  return true;
355
354
  }
356
355
 
@@ -358,10 +357,10 @@ quic_endpoint_start_closing(quic_endpoint_t *ep, quic_conn_t *c, const ngtcp2_cc
358
357
  CONNECTION_CLOSE again, but no more than three times what the peer sent
359
358
  and to every 1st, 2nd, 4th, 8th, ... packet only (examples/server.cc's
360
359
  Handler::send_conn_close). */
361
- static void
362
- quic_endpoint_resend_close(quic_endpoint_t *ep, quic_conn_t *c, size_t pktlen, VALUE remote)
363
- {
364
- if (NIL_P(c->closebuf)) return;
360
+ static void quic_endpoint_resend_close(quic_endpoint_t *ep, quic_conn_t *c,
361
+ size_t pktlen, VALUE remote) {
362
+ if (NIL_P(c->closebuf))
363
+ return;
365
364
 
366
365
  c->close_bytes_recv += pktlen;
367
366
  c->close_pkts_recv++;
@@ -370,7 +369,9 @@ quic_endpoint_resend_close(quic_endpoint_t *ep, quic_conn_t *c, size_t pktlen, V
370
369
  c->close_bytes_recv * 3 < c->close_bytes_sent + len) {
371
370
  return;
372
371
  }
373
- if (!quic_endpoint_push_response(ep, rb_str_dup(c->closebuf), rb_str_dup(remote))) return;
372
+ if (!quic_endpoint_push_response(ep, rb_str_dup(c->closebuf),
373
+ rb_str_dup(remote)))
374
+ return;
374
375
  c->close_bytes_sent += len;
375
376
  c->close_next_pkts_recv *= 2;
376
377
  }
@@ -380,12 +381,12 @@ quic_endpoint_resend_close(quic_endpoint_t *ep, quic_conn_t *c, size_t pktlen, V
380
381
  for it; the reason goes to c->error. Returns true when the connection has
381
382
  to leave the table now, false when it stays for its closing or draining
382
383
  period. */
383
- static bool
384
- quic_endpoint_handle_error(quic_endpoint_t *ep, quic_conn_t *c, int rv)
385
- {
384
+ static bool quic_endpoint_handle_error(quic_endpoint_t *ep, quic_conn_t *c,
385
+ int rv) {
386
386
  VALUE exc = c->pending_exc;
387
387
  c->pending_exc = Qnil;
388
- if (!NIL_P(exc)) rv = NGTCP2_ERR_CALLBACK_FAILURE;
388
+ if (!NIL_P(exc))
389
+ rv = NGTCP2_ERR_CALLBACK_FAILURE;
389
390
 
390
391
  ngtcp2_ccerr ccerr;
391
392
  switch (rv) {
@@ -412,7 +413,8 @@ quic_endpoint_handle_error(quic_endpoint_t *ep, quic_conn_t *c, int rv)
412
413
  /* Send the TLS alert itself, as examples/server.cc does; set_liberr
413
414
  would only know that the handshake failed. */
414
415
  quic_conn_set_error(c, quic_conn_error_new(c, rv));
415
- ngtcp2_ccerr_set_tls_alert(&ccerr, ngtcp2_conn_get_tls_alert2(c->conn), NULL, 0);
416
+ ngtcp2_ccerr_set_tls_alert(&ccerr, ngtcp2_conn_get_tls_alert2(c->conn),
417
+ NULL, 0);
416
418
  break;
417
419
  default:
418
420
  quic_conn_set_error(c, quic_conn_error_new(c, rv));
@@ -423,52 +425,55 @@ quic_endpoint_handle_error(quic_endpoint_t *ep, quic_conn_t *c, int rv)
423
425
  }
424
426
 
425
427
  /* Drop every table entry of conn and cut it loose from the Endpoint. */
426
- static void
427
- quic_endpoint_detach(quic_endpoint_t *ep, VALUE conn, quic_conn_t *c)
428
- {
429
- quic_endpoint_dissociate_cid(ep, ngtcp2_conn_get_client_initial_dcid2(c->conn), conn);
428
+ static void quic_endpoint_detach(quic_endpoint_t *ep, VALUE conn,
429
+ quic_conn_t *c) {
430
+ quic_endpoint_dissociate_cid(
431
+ ep, ngtcp2_conn_get_client_initial_dcid2(c->conn), conn);
430
432
 
431
433
  size_t n = ngtcp2_conn_get_scid2(c->conn, NULL);
432
434
  VALUE tmp;
433
435
  ngtcp2_cid *scids = ALLOCV_N(ngtcp2_cid, tmp, n);
434
436
  ngtcp2_conn_get_scid2(c->conn, scids);
435
- for (size_t i = 0; i < n; i++) quic_endpoint_dissociate_cid(ep, &scids[i], conn);
437
+ for (size_t i = 0; i < n; i++)
438
+ quic_endpoint_dissociate_cid(ep, &scids[i], conn);
436
439
  ALLOCV_END(tmp);
437
440
 
438
441
  c->endpoint = NULL;
439
442
  c->endpoint_owner = Qnil;
443
+ /* The Endpoint never drives the connection again. */
444
+ quic_conn_close_qlog(c);
440
445
  }
441
446
 
442
447
  /* Take conn out of the table and hand it to #take_closed. */
443
- static void
444
- quic_endpoint_remove(quic_endpoint_t *ep, VALUE conn, quic_conn_t *c)
445
- {
448
+ static void quic_endpoint_remove(quic_endpoint_t *ep, VALUE conn,
449
+ quic_conn_t *c) {
446
450
  quic_endpoint_detach(ep, conn, c);
447
451
  long len = RARRAY_LEN(ep->conns);
448
452
  for (long i = 0; i < len; i++) {
449
- if (RARRAY_AREF(ep->conns, i) != conn) continue;
453
+ if (RARRAY_AREF(ep->conns, i) != conn)
454
+ continue;
450
455
  rb_ary_delete_at(ep->conns, i);
451
- if (i < ep->write_cursor) ep->write_cursor--;
456
+ if (i < ep->write_cursor)
457
+ ep->write_cursor--;
452
458
  break;
453
459
  }
454
460
  rb_ary_push(ep->closed, conn);
455
461
  }
456
462
 
457
- void
458
- quic_endpoint_close_conn(quic_endpoint_t *ep, quic_conn_t *c, const ngtcp2_ccerr *ccerr)
459
- {
460
- if (!quic_endpoint_start_closing(ep, c, ccerr)) quic_endpoint_remove(ep, c->owner, c);
463
+ void quic_endpoint_close_conn(quic_endpoint_t *ep, quic_conn_t *c,
464
+ const ngtcp2_ccerr *ccerr) {
465
+ if (!quic_endpoint_start_closing(ep, c, ccerr))
466
+ quic_endpoint_remove(ep, c->owner, c);
461
467
  }
462
468
 
463
469
  /* QUIC::Endpoint._new(local_sockaddr:, tls_context:, transport_params:,
464
470
  settings:, max_connections:), every keyword required. Endpoint.new
465
471
  (lib/quic/endpoint.rb) fills in the defaults. */
466
- static VALUE
467
- quic_endpoint_s_new(int argc, VALUE *argv, VALUE klass)
468
- {
472
+ static VALUE quic_endpoint_s_new(int argc, VALUE *argv, VALUE klass) {
469
473
  VALUE opts = Qnil;
470
474
  rb_scan_args(argc, argv, "0:", &opts);
471
- if (NIL_P(opts)) opts = rb_hash_new();
475
+ if (NIL_P(opts))
476
+ opts = rb_hash_new();
472
477
 
473
478
  ID keywords[5];
474
479
  VALUE values[5];
@@ -489,11 +494,13 @@ quic_endpoint_s_new(int argc, VALUE *argv, VALUE klass)
489
494
  quic_fill_settings(&settings, values[3]);
490
495
  long max_connections = NUM2LONG(values[4]);
491
496
  if (max_connections <= 0) {
492
- rb_raise(rb_eArgError, "max_connections must be positive (got %ld)", max_connections);
497
+ rb_raise(rb_eArgError, "max_connections must be positive (got %ld)",
498
+ max_connections);
493
499
  }
494
500
 
495
501
  quic_endpoint_t *ep;
496
- VALUE self = TypedData_Make_Struct(klass, quic_endpoint_t, &quic_endpoint_data_type, ep);
502
+ VALUE self = TypedData_Make_Struct(klass, quic_endpoint_t,
503
+ &quic_endpoint_data_type, ep);
497
504
  ep->conns = Qnil;
498
505
  ep->responses = Qnil;
499
506
  ep->closed = Qnil;
@@ -524,9 +531,8 @@ struct quic_endpoint_read_args {
524
531
  };
525
532
 
526
533
  /* A packet for a connection in the table. */
527
- static VALUE
528
- quic_endpoint_dispatch(struct quic_endpoint_read_args *a, VALUE conn)
529
- {
534
+ static VALUE quic_endpoint_dispatch(struct quic_endpoint_read_args *a,
535
+ VALUE conn) {
530
536
  quic_conn_t *c = quic_conn_get(conn);
531
537
  const uint8_t *data = (const uint8_t *)RSTRING_PTR(a->packet);
532
538
  size_t datalen = (size_t)RSTRING_LEN(a->packet);
@@ -535,10 +541,12 @@ quic_endpoint_dispatch(struct quic_endpoint_read_args *a, VALUE conn)
535
541
  quic_endpoint_resend_close(a->ep, c, datalen, a->remote);
536
542
  return Qnil;
537
543
  }
538
- if (c->close_deadline != 0) return Qnil;
544
+ if (c->close_deadline != 0)
545
+ return Qnil;
539
546
 
540
547
  int rv = quic_conn_read_pkt_raw(c, &a->path, data, datalen);
541
- if ((rv != 0 || !NIL_P(c->pending_exc)) && quic_endpoint_handle_error(a->ep, c, rv)) {
548
+ if ((rv != 0 || !NIL_P(c->pending_exc)) &&
549
+ quic_endpoint_handle_error(a->ep, c, rv)) {
542
550
  quic_endpoint_remove(a->ep, conn, c);
543
551
  return Qnil;
544
552
  }
@@ -547,9 +555,8 @@ quic_endpoint_dispatch(struct quic_endpoint_read_args *a, VALUE conn)
547
555
 
548
556
  /* A packet for no connection in the table: a new connection, or one this
549
557
  Endpoint has forgotten. */
550
- static VALUE
551
- quic_endpoint_accept(struct quic_endpoint_read_args *a, const ngtcp2_cid *dcid)
552
- {
558
+ static VALUE quic_endpoint_accept(struct quic_endpoint_read_args *a,
559
+ const ngtcp2_cid *dcid) {
553
560
  quic_endpoint_t *ep = a->ep;
554
561
  const uint8_t *data = (const uint8_t *)RSTRING_PTR(a->packet);
555
562
  size_t datalen = (size_t)RSTRING_LEN(a->packet);
@@ -570,8 +577,9 @@ quic_endpoint_accept(struct quic_endpoint_read_args *a, const ngtcp2_cid *dcid)
570
577
  }
571
578
 
572
579
  /* As in Server._accept, a token is accepted without checking it. */
573
- VALUE conn = quic_server_conn_new(rb_cQUICConnectionServer, &hd, &a->path, ep->tls_context,
574
- ep->transport_params, ep->settings, ep, a->self);
580
+ VALUE conn = quic_server_conn_new(rb_cQUICConnectionServer, &hd, &a->path,
581
+ ep->tls_context, ep->transport_params,
582
+ ep->settings, ep, a->self);
575
583
  quic_conn_t *c = quic_conn_get(conn);
576
584
  int rv = quic_conn_read_pkt_raw(c, &a->path, data, datalen);
577
585
  if (rv != 0 || !NIL_P(c->pending_exc)) {
@@ -582,20 +590,20 @@ quic_endpoint_accept(struct quic_endpoint_read_args *a, const ngtcp2_cid *dcid)
582
590
  return Qnil;
583
591
  }
584
592
 
585
- quic_endpoint_associate_cid(ep, ngtcp2_conn_get_client_initial_dcid2(c->conn), conn);
593
+ quic_endpoint_associate_cid(ep, ngtcp2_conn_get_client_initial_dcid2(c->conn),
594
+ conn);
586
595
  size_t n = ngtcp2_conn_get_scid2(c->conn, NULL);
587
596
  VALUE tmp;
588
597
  ngtcp2_cid *scids = ALLOCV_N(ngtcp2_cid, tmp, n);
589
598
  ngtcp2_conn_get_scid2(c->conn, scids);
590
- for (size_t i = 0; i < n; i++) quic_endpoint_associate_cid(ep, &scids[i], conn);
599
+ for (size_t i = 0; i < n; i++)
600
+ quic_endpoint_associate_cid(ep, &scids[i], conn);
591
601
  ALLOCV_END(tmp);
592
602
  rb_ary_push(ep->conns, conn);
593
603
  return conn;
594
604
  }
595
605
 
596
- static VALUE
597
- quic_endpoint_read_pkt_body(VALUE arg)
598
- {
606
+ static VALUE quic_endpoint_read_pkt_body(VALUE arg) {
599
607
  struct quic_endpoint_read_args *a = (struct quic_endpoint_read_args *)arg;
600
608
  const uint8_t *data = (const uint8_t *)RSTRING_PTR(a->packet);
601
609
  size_t datalen = (size_t)RSTRING_LEN(a->packet);
@@ -603,7 +611,8 @@ quic_endpoint_read_pkt_body(VALUE arg)
603
611
  quic_endpoint_refill_reset_bucket(a->ep, quic_now());
604
612
 
605
613
  /* ngtcp2_pkt_decode_version_cid asserts datalen > 0. */
606
- if (datalen == 0) return Qnil;
614
+ if (datalen == 0)
615
+ return Qnil;
607
616
 
608
617
  ngtcp2_version_cid vc;
609
618
  int rv = ngtcp2_pkt_decode_version_cid(&vc, data, datalen, QUIC_SCID_LEN);
@@ -612,7 +621,8 @@ quic_endpoint_read_pkt_body(VALUE arg)
612
621
  return Qnil;
613
622
  }
614
623
  /* A supported version never carries a DCID longer than this. */
615
- if (rv != 0 || vc.dcidlen > NGTCP2_MAX_CIDLEN) return Qnil;
624
+ if (rv != 0 || vc.dcidlen > NGTCP2_MAX_CIDLEN)
625
+ return Qnil;
616
626
 
617
627
  ngtcp2_cid dcid;
618
628
  ngtcp2_cid_init(&dcid, vc.dcid, vc.dcidlen);
@@ -623,9 +633,7 @@ quic_endpoint_read_pkt_body(VALUE arg)
623
633
  return quic_endpoint_accept(a, &dcid);
624
634
  }
625
635
 
626
- static VALUE
627
- quic_endpoint_read_pkt_unlock(VALUE arg)
628
- {
636
+ static VALUE quic_endpoint_read_pkt_unlock(VALUE arg) {
629
637
  rb_str_unlocktmp(((struct quic_endpoint_read_args *)arg)->packet);
630
638
  return Qnil;
631
639
  }
@@ -634,13 +642,12 @@ quic_endpoint_read_pkt_unlock(VALUE arg)
634
642
  Connection::Server it went to, which may be a new one, or nil when the
635
643
  Endpoint answered or dropped it. A connection's own failure is never
636
644
  raised; it closes that connection (see quic_endpoint_handle_error). */
637
- static VALUE
638
- quic_endpoint_read_pkt(int argc, VALUE *argv, VALUE self)
639
- {
645
+ static VALUE quic_endpoint_read_pkt(int argc, VALUE *argv, VALUE self) {
640
646
  VALUE packet = Qnil;
641
647
  VALUE opts = Qnil;
642
648
  rb_scan_args(argc, argv, "1:", &packet, &opts);
643
- if (NIL_P(opts)) opts = rb_hash_new();
649
+ if (NIL_P(opts))
650
+ opts = rb_hash_new();
644
651
 
645
652
  ID keywords[2];
646
653
  VALUE values[2];
@@ -650,7 +657,8 @@ quic_endpoint_read_pkt(int argc, VALUE *argv, VALUE self)
650
657
 
651
658
  quic_endpoint_t *ep = quic_endpoint_get(self);
652
659
  VALUE remote = values[0];
653
- VALUE local = values[1] == Qundef || NIL_P(values[1]) ? ep->local_sockaddr : values[1];
660
+ VALUE local =
661
+ values[1] == Qundef || NIL_P(values[1]) ? ep->local_sockaddr : values[1];
654
662
  quic_require_binary(packet, "packet");
655
663
  quic_require_sockaddr(remote, "remote");
656
664
  quic_require_sockaddr(local, "local");
@@ -679,12 +687,11 @@ quic_endpoint_read_pkt(int argc, VALUE *argv, VALUE self)
679
687
  nil when there is none left. The Endpoint's own answers go first, then
680
688
  each connection's packets until it has none, resuming where the last
681
689
  call stopped. After nil, the next call starts over. */
682
- static VALUE
683
- quic_endpoint_write_pkt(VALUE self)
684
- {
690
+ static VALUE quic_endpoint_write_pkt(VALUE self) {
685
691
  quic_endpoint_t *ep = quic_endpoint_get(self);
686
692
  for (;;) {
687
- if (RARRAY_LEN(ep->responses) > 0) return rb_ary_shift(ep->responses);
693
+ if (RARRAY_LEN(ep->responses) > 0)
694
+ return rb_ary_shift(ep->responses);
688
695
  if (ep->write_cursor >= RARRAY_LEN(ep->conns)) {
689
696
  ep->write_cursor = 0;
690
697
  return Qnil;
@@ -701,7 +708,8 @@ quic_endpoint_write_pkt(VALUE self)
701
708
  VALUE pkt = rb_str_buf_new(QUIC_WRITE_PKT_BUFLEN);
702
709
  ngtcp2_path_storage ps;
703
710
  ngtcp2_path_storage_zero(&ps);
704
- ngtcp2_ssize n = quic_conn_write_pkt_raw(conn, c, &ps.path, (uint8_t *)RSTRING_PTR(pkt));
711
+ ngtcp2_ssize n =
712
+ quic_conn_write_pkt_raw(conn, c, &ps.path, (uint8_t *)RSTRING_PTR(pkt));
705
713
  if (n < 0 || !NIL_P(c->pending_exc)) {
706
714
  if (quic_endpoint_handle_error(ep, c, n < 0 ? (int)n : 0)) {
707
715
  quic_endpoint_remove(ep, conn, c);
@@ -720,15 +728,15 @@ quic_endpoint_write_pkt(VALUE self)
720
728
  /* #expiry: the earliest time (CLOCK_MONOTONIC ns) any connection in the
721
729
  table needs #handle_expiry, the end of a closing or draining period
722
730
  included. nil when no connection waits for one. */
723
- static VALUE
724
- quic_endpoint_expiry(VALUE self)
725
- {
731
+ static VALUE quic_endpoint_expiry(VALUE self) {
726
732
  quic_endpoint_t *ep = quic_endpoint_get(self);
727
733
  ngtcp2_tstamp earliest = UINT64_MAX;
728
734
  for (long i = 0; i < RARRAY_LEN(ep->conns); i++) {
729
735
  quic_conn_t *c = quic_conn_get(RARRAY_AREF(ep->conns, i));
730
- ngtcp2_tstamp t = c->close_deadline != 0 ? c->close_deadline : ngtcp2_conn_get_expiry2(c->conn);
731
- if (t < earliest) earliest = t;
736
+ ngtcp2_tstamp t = c->close_deadline != 0 ? c->close_deadline
737
+ : ngtcp2_conn_get_expiry2(c->conn);
738
+ if (t < earliest)
739
+ earliest = t;
732
740
  }
733
741
  return earliest == UINT64_MAX ? Qnil : ULL2NUM((unsigned long long)earliest);
734
742
  }
@@ -736,9 +744,7 @@ quic_endpoint_expiry(VALUE self)
736
744
  /* #handle_expiry: run the timers of every connection due, and take out of
737
745
  the table those whose closing or draining period is over or that timed
738
746
  out. */
739
- static VALUE
740
- quic_endpoint_handle_expiry(VALUE self)
741
- {
747
+ static VALUE quic_endpoint_handle_expiry(VALUE self) {
742
748
  quic_endpoint_t *ep = quic_endpoint_get(self);
743
749
  ngtcp2_tstamp now = quic_now();
744
750
  /* A copy, since connections leave ep->conns along the way. */
@@ -746,16 +752,20 @@ quic_endpoint_handle_expiry(VALUE self)
746
752
  for (long i = 0; i < RARRAY_LEN(conns); i++) {
747
753
  VALUE conn = RARRAY_AREF(conns, i);
748
754
  quic_conn_t *c = quic_conn_get(conn);
749
- if (c->endpoint == NULL) continue;
755
+ if (c->endpoint == NULL)
756
+ continue;
750
757
  if (c->close_deadline != 0) {
751
- if (c->close_deadline <= now) quic_endpoint_remove(ep, conn, c);
758
+ if (c->close_deadline <= now)
759
+ quic_endpoint_remove(ep, conn, c);
752
760
  continue;
753
761
  }
754
- if (ngtcp2_conn_get_expiry2(c->conn) > now) continue;
762
+ if (ngtcp2_conn_get_expiry2(c->conn) > now)
763
+ continue;
755
764
 
756
765
  c->now = now;
757
766
  int rv = ngtcp2_conn_handle_expiry(c->conn, now);
758
- if ((rv != 0 || !NIL_P(c->pending_exc)) && quic_endpoint_handle_error(ep, c, rv)) {
767
+ if ((rv != 0 || !NIL_P(c->pending_exc)) &&
768
+ quic_endpoint_handle_error(ep, c, rv)) {
759
769
  quic_endpoint_remove(ep, conn, c);
760
770
  }
761
771
  }
@@ -765,9 +775,7 @@ quic_endpoint_handle_expiry(VALUE self)
765
775
 
766
776
  /* #take_closed: the connections that left the table since the last call,
767
777
  in the order they left. */
768
- static VALUE
769
- quic_endpoint_take_closed(VALUE self)
770
- {
778
+ static VALUE quic_endpoint_take_closed(VALUE self) {
771
779
  quic_endpoint_t *ep = quic_endpoint_get(self);
772
780
  VALUE closed = ep->closed;
773
781
  ep->closed = rb_ary_new();
@@ -776,36 +784,29 @@ quic_endpoint_take_closed(VALUE self)
776
784
 
777
785
  /* #connections: the connections in the table, closing and draining ones
778
786
  included. */
779
- static VALUE
780
- quic_endpoint_connections(VALUE self)
781
- {
787
+ static VALUE quic_endpoint_connections(VALUE self) {
782
788
  return rb_ary_dup(quic_endpoint_get(self)->conns);
783
789
  }
784
790
 
785
791
  /* #stop_accepting: refuse every new connection from now on with
786
792
  CONNECTION_REFUSED. There is no way back. */
787
- static VALUE
788
- quic_endpoint_stop_accepting(VALUE self)
789
- {
793
+ static VALUE quic_endpoint_stop_accepting(VALUE self) {
790
794
  quic_endpoint_get(self)->accepting = false;
791
795
  return Qnil;
792
796
  }
793
797
 
794
798
  /* #tls_context=: the context new connections are made with. Connections
795
799
  already made keep theirs. */
796
- static VALUE
797
- quic_endpoint_set_tls_context(VALUE self, VALUE tls_context)
798
- {
800
+ static VALUE quic_endpoint_set_tls_context(VALUE self, VALUE tls_context) {
799
801
  quic_endpoint_t *ep = quic_endpoint_get(self);
800
802
  quic_tls_context_get(tls_context);
801
803
  ep->tls_context = tls_context;
802
804
  return tls_context;
803
805
  }
804
806
 
805
- void
806
- Init_quic_endpoint(VALUE rb_mQUICArg)
807
- {
808
- if (RAND_bytes((uint8_t *)&quic_cid_hash_seed, sizeof(quic_cid_hash_seed)) != 1) {
807
+ void Init_quic_endpoint(VALUE rb_mQUICArg) {
808
+ if (RAND_bytes((uint8_t *)&quic_cid_hash_seed, sizeof(quic_cid_hash_seed)) !=
809
+ 1) {
809
810
  rb_raise(rb_eRuntimeError, "RAND_bytes(CID hash seed) failed");
810
811
  }
811
812
 
@@ -815,9 +816,14 @@ Init_quic_endpoint(VALUE rb_mQUICArg)
815
816
  rb_define_method(rb_cQUICEndpoint, "read_pkt", quic_endpoint_read_pkt, -1);
816
817
  rb_define_method(rb_cQUICEndpoint, "write_pkt", quic_endpoint_write_pkt, 0);
817
818
  rb_define_method(rb_cQUICEndpoint, "expiry", quic_endpoint_expiry, 0);
818
- rb_define_method(rb_cQUICEndpoint, "handle_expiry", quic_endpoint_handle_expiry, 0);
819
- rb_define_method(rb_cQUICEndpoint, "take_closed", quic_endpoint_take_closed, 0);
820
- rb_define_method(rb_cQUICEndpoint, "connections", quic_endpoint_connections, 0);
821
- rb_define_method(rb_cQUICEndpoint, "stop_accepting", quic_endpoint_stop_accepting, 0);
822
- rb_define_method(rb_cQUICEndpoint, "tls_context=", quic_endpoint_set_tls_context, 1);
819
+ rb_define_method(rb_cQUICEndpoint, "handle_expiry",
820
+ quic_endpoint_handle_expiry, 0);
821
+ rb_define_method(rb_cQUICEndpoint, "take_closed", quic_endpoint_take_closed,
822
+ 0);
823
+ rb_define_method(rb_cQUICEndpoint, "connections", quic_endpoint_connections,
824
+ 0);
825
+ rb_define_method(rb_cQUICEndpoint, "stop_accepting",
826
+ quic_endpoint_stop_accepting, 0);
827
+ rb_define_method(rb_cQUICEndpoint,
828
+ "tls_context=", quic_endpoint_set_tls_context, 1);
823
829
  }