Mercurial > hg > nginx-quic
comparison src/event/quic/ngx_event_quic_frames.c @ 8760:6ccf3867959a quic
QUIC: refactored ngx_quic_order_bufs() and ngx_quic_split_bufs().
They are replaced with ngx_quic_write_chain() and ngx_quic_read_chain().
These functions represent the API to data buffering.
The first function adds data of given size at given offset to the buffer.
Now it returns the unwritten part of the chain similar to c->send_chain().
The second function returns data of given size from the beginning of the buffer.
Its second argument and return value are swapped compared to
ngx_quic_split_bufs() to better match ngx_quic_write_chain().
Added, returned and stored data are regular ngx_chain_t/ngx_buf_t chains.
Missing data is marked with b->sync flag.
The functions are now used in both send and recv data chains in QUIC streams.
author | Roman Arutyunyan <arut@nginx.com> |
---|---|
date | Fri, 24 Dec 2021 18:17:23 +0300 |
parents | 56dec0d4e5b1 |
children | 19e063e955bf |
comparison
equal
deleted
inserted
replaced
8759:56dec0d4e5b1 | 8760:6ccf3867959a |
---|---|
9 #include <ngx_event.h> | 9 #include <ngx_event.h> |
10 #include <ngx_event_quic_connection.h> | 10 #include <ngx_event_quic_connection.h> |
11 | 11 |
12 | 12 |
13 #define NGX_QUIC_BUFFER_SIZE 4096 | 13 #define NGX_QUIC_BUFFER_SIZE 4096 |
14 | |
15 | |
16 static ngx_chain_t *ngx_quic_split_bufs(ngx_connection_t *c, ngx_chain_t *in, | |
17 size_t len); | |
18 | 14 |
19 | 15 |
20 ngx_quic_frame_t * | 16 ngx_quic_frame_t * |
21 ngx_quic_alloc_frame(ngx_connection_t *c) | 17 ngx_quic_alloc_frame(ngx_connection_t *c) |
22 { | 18 { |
241 onf = &nf->u.ord; | 237 onf = &nf->u.ord; |
242 onf->offset += of->length; | 238 onf->offset += of->length; |
243 onf->length = shrink; | 239 onf->length = shrink; |
244 nf->len = ngx_quic_create_frame(NULL, nf); | 240 nf->len = ngx_quic_create_frame(NULL, nf); |
245 | 241 |
246 nf->data = ngx_quic_split_bufs(c, f->data, of->length); | 242 f->data = ngx_quic_read_chain(c, &nf->data, of->length); |
247 if (nf->data == NGX_CHAIN_ERROR) { | 243 if (f->data == NGX_CHAIN_ERROR) { |
248 return NGX_ERROR; | 244 return NGX_ERROR; |
249 } | 245 } |
250 | 246 |
251 ngx_queue_insert_after(&f->queue, &nf->queue); | 247 ngx_queue_insert_after(&f->queue, &nf->queue); |
252 | 248 |
253 return NGX_OK; | 249 return NGX_OK; |
254 } | 250 } |
255 | 251 |
256 | 252 |
257 static ngx_chain_t * | 253 ngx_chain_t * |
258 ngx_quic_split_bufs(ngx_connection_t *c, ngx_chain_t *in, size_t len) | 254 ngx_quic_read_chain(ngx_connection_t *c, ngx_chain_t **chain, off_t limit) |
259 { | 255 { |
260 size_t n; | 256 off_t n; |
261 ngx_buf_t *b; | 257 ngx_buf_t *b; |
262 ngx_chain_t *out; | 258 ngx_chain_t *out, *in, *cl, **ll; |
263 ngx_quic_connection_t *qc; | 259 ngx_quic_connection_t *qc; |
264 | 260 |
265 qc = ngx_quic_get_connection(c); | 261 qc = ngx_quic_get_connection(c); |
266 | 262 |
267 while (in) { | 263 out = *chain; |
268 n = ngx_buf_size(in->buf); | 264 |
269 | 265 for (ll = &out; *ll; ll = &(*ll)->next) { |
270 if (n == len) { | 266 b = (*ll)->buf; |
271 out = in->next; | 267 |
272 in->next = NULL; | 268 if (b->sync) { |
273 return out; | 269 /* hole */ |
274 } | |
275 | |
276 if (n > len) { | |
277 break; | 270 break; |
278 } | 271 } |
279 | 272 |
280 len -= n; | 273 if (limit == 0) { |
281 in = in->next; | 274 break; |
282 } | 275 } |
283 | 276 |
284 if (in == NULL) { | 277 n = b->last - b->pos; |
285 return NULL; | 278 |
286 } | 279 if (n > limit) { |
280 goto split; | |
281 } | |
282 | |
283 limit -= n; | |
284 } | |
285 | |
286 *chain = *ll; | |
287 *ll = NULL; | |
288 | |
289 return out; | |
290 | |
291 split: | |
292 | |
293 in = *ll; | |
287 | 294 |
288 /* split in->buf by creating shadow bufs which reference it */ | 295 /* split in->buf by creating shadow bufs which reference it */ |
289 | 296 |
290 if (in->buf->shadow == NULL) { | 297 if (in->buf->shadow == NULL) { |
291 if (qc->free_shadow_bufs) { | 298 if (qc->free_shadow_bufs) { |
303 b->shadow = in->buf; | 310 b->shadow = in->buf; |
304 b->last_shadow = 1; | 311 b->last_shadow = 1; |
305 in->buf = b; | 312 in->buf = b; |
306 } | 313 } |
307 | 314 |
308 out = ngx_alloc_chain_link(c->pool); | 315 cl = ngx_alloc_chain_link(c->pool); |
309 if (out == NULL) { | 316 if (cl == NULL) { |
310 return NGX_CHAIN_ERROR; | 317 return NGX_CHAIN_ERROR; |
311 } | 318 } |
312 | 319 |
313 if (qc->free_shadow_bufs) { | 320 if (qc->free_shadow_bufs) { |
314 b = qc->free_shadow_bufs; | 321 b = qc->free_shadow_bufs; |
315 qc->free_shadow_bufs = b->shadow; | 322 qc->free_shadow_bufs = b->shadow; |
316 | 323 |
317 } else { | 324 } else { |
318 b = ngx_alloc_buf(c->pool); | 325 b = ngx_alloc_buf(c->pool); |
319 if (b == NULL) { | 326 if (b == NULL) { |
320 ngx_free_chain(c->pool, out); | 327 ngx_free_chain(c->pool, cl); |
321 return NGX_CHAIN_ERROR; | 328 return NGX_CHAIN_ERROR; |
322 } | 329 } |
323 } | 330 } |
324 | 331 |
325 out->buf = b; | 332 cl->buf = b; |
326 out->next = in->next; | 333 cl->next = in->next; |
327 in->next = NULL; | 334 in->next = NULL; |
335 *chain = cl; | |
328 | 336 |
329 *b = *in->buf; | 337 *b = *in->buf; |
330 b->last_shadow = 0; | 338 b->last_shadow = 0; |
331 b->pos = b->pos + len; | 339 b->pos += limit; |
332 | 340 |
333 in->buf->shadow = b; | 341 in->buf->shadow = b; |
334 in->buf->last = in->buf->pos + len; | 342 in->buf->last = b->pos; |
343 in->buf->last_buf = 0; | |
335 | 344 |
336 return out; | 345 return out; |
337 } | 346 } |
338 | 347 |
339 | 348 |
478 | 487 |
479 return out; | 488 return out; |
480 } | 489 } |
481 | 490 |
482 | 491 |
483 ngx_int_t | 492 ngx_chain_t * |
484 ngx_quic_order_bufs(ngx_connection_t *c, ngx_chain_t **out, ngx_chain_t *in, | 493 ngx_quic_write_chain(ngx_connection_t *c, ngx_chain_t **chain, ngx_chain_t *in, |
485 off_t limit, off_t offset) | 494 off_t limit, off_t offset) |
486 { | 495 { |
487 off_t n; | 496 off_t n; |
488 u_char *p; | 497 u_char *p; |
489 ngx_buf_t *b; | 498 ngx_buf_t *b; |
490 ngx_chain_t *cl, *sl; | 499 ngx_chain_t *cl, *sl; |
491 | 500 |
492 while (in && limit) { | 501 while (in && limit) { |
493 cl = *out; | 502 cl = *chain; |
494 | 503 |
495 if (cl == NULL) { | 504 if (cl == NULL) { |
496 cl = ngx_quic_alloc_buf(c); | 505 cl = ngx_quic_alloc_buf(c); |
497 if (cl == NULL) { | 506 if (cl == NULL) { |
498 return NGX_ERROR; | 507 return NGX_CHAIN_ERROR; |
499 } | 508 } |
500 | 509 |
501 cl->buf->last = cl->buf->end; | 510 cl->buf->last = cl->buf->end; |
502 cl->buf->sync = 1; /* hole */ | 511 cl->buf->sync = 1; /* hole */ |
503 cl->next = NULL; | 512 cl->next = NULL; |
504 *out = cl; | 513 *chain = cl; |
505 } | 514 } |
506 | 515 |
507 b = cl->buf; | 516 b = cl->buf; |
508 n = b->last - b->pos; | 517 n = b->last - b->pos; |
509 | 518 |
510 if (n <= offset) { | 519 if (n <= offset) { |
511 offset -= n; | 520 offset -= n; |
512 out = &cl->next; | 521 chain = &cl->next; |
513 continue; | 522 continue; |
514 } | 523 } |
515 | 524 |
516 if (b->sync && offset > 0) { | 525 if (b->sync && offset > 0) { |
517 sl = ngx_quic_split_bufs(c, cl, offset); | 526 /* split hole at offset */ |
518 if (sl == NGX_CHAIN_ERROR) { | 527 |
519 return NGX_ERROR; | 528 b->sync = 0; |
520 } | 529 |
521 | 530 sl = ngx_quic_read_chain(c, &cl, offset); |
522 cl->next = sl; | 531 if (cl == NGX_CHAIN_ERROR) { |
532 return NGX_CHAIN_ERROR; | |
533 } | |
534 | |
535 sl->buf->sync = 1; | |
536 cl->buf->sync = 1; | |
537 | |
538 *chain = sl; | |
539 sl->next = cl; | |
523 continue; | 540 continue; |
524 } | 541 } |
525 | 542 |
526 for (p = b->pos + offset; p != b->last && in && limit; /* void */ ) { | 543 for (p = b->pos + offset; p != b->last && in && limit; /* void */ ) { |
527 n = ngx_min(b->last - p, in->buf->last - in->buf->pos); | 544 n = ngx_min(b->last - p, in->buf->last - in->buf->pos); |
539 if (in->buf->pos == in->buf->last) { | 556 if (in->buf->pos == in->buf->last) { |
540 in = in->next; | 557 in = in->next; |
541 } | 558 } |
542 } | 559 } |
543 | 560 |
561 if (b->sync && p == b->last) { | |
562 b->sync = 0; | |
563 continue; | |
564 } | |
565 | |
544 if (b->sync && p != b->pos) { | 566 if (b->sync && p != b->pos) { |
545 sl = ngx_quic_split_bufs(c, cl, p - b->pos); | 567 /* split hole at p - b->pos */ |
568 | |
569 b->sync = 0; | |
570 | |
571 sl = ngx_quic_read_chain(c, &cl, p - b->pos); | |
546 if (sl == NGX_CHAIN_ERROR) { | 572 if (sl == NGX_CHAIN_ERROR) { |
547 return NGX_ERROR; | 573 return NGX_CHAIN_ERROR; |
548 } | 574 } |
549 | 575 |
550 cl->next = sl; | 576 cl->buf->sync = 1; |
551 cl->buf->sync = 0; | 577 |
552 } | 578 *chain = sl; |
553 } | 579 sl->next = cl; |
554 | 580 } |
555 return NGX_OK; | 581 } |
582 | |
583 return in; | |
556 } | 584 } |
557 | 585 |
558 | 586 |
559 #if (NGX_DEBUG) | 587 #if (NGX_DEBUG) |
560 | 588 |