comparison src/event/ngx_event_quic_transport.c @ 8333:167d32476737 quic

Crypto buffer frames reordering. If offset in CRYPTO frame doesn't match expected, following actions are taken: a) Duplicate frames or frames within [0...current offset] are ignored b) New data from intersecting ranges (starts before current_offset, ends after) is consumed c) "Future" frames are stored in a sorted queue (min offset .. max offset) Once a frame is consumed, current offset is updated and the queue is inspected: we iterate the queue until the gap is found and act as described above for each frame. The amount of data in buffered frames is limited by corresponding macro. The CRYPTO and STREAM frame structures are now compatible: they share the same set of initial fields. This allows to have code that deals with both of this frames. The ordering layer now processes the frame with offset and invokes the handler when it can organise an ordered stream of data.
author Vladimir Homutov <vl@nginx.com>
date Tue, 14 Apr 2020 12:16:25 +0300
parents 1cdd53532309
children 0f9e9786b90d
comparison
equal deleted inserted replaced
8332:6ad871b63422 8333:167d32476737
591 ngx_log_error(NGX_LOG_INFO, pkt->log, 0, 591 ngx_log_error(NGX_LOG_INFO, pkt->log, 0,
592 "failed to parse crypto frame offset"); 592 "failed to parse crypto frame offset");
593 return NGX_ERROR; 593 return NGX_ERROR;
594 } 594 }
595 595
596 p = ngx_quic_parse_int(p, end, &f->u.crypto.len); 596 p = ngx_quic_parse_int(p, end, &f->u.crypto.length);
597 if (p == NULL) { 597 if (p == NULL) {
598 ngx_log_error(NGX_LOG_INFO, pkt->log, 0, 598 ngx_log_error(NGX_LOG_INFO, pkt->log, 0,
599 "failed to parse crypto frame len"); 599 "failed to parse crypto frame len");
600 return NGX_ERROR; 600 return NGX_ERROR;
601 } 601 }
602 602
603 p = ngx_quic_read_bytes(p, end, f->u.crypto.len, &f->u.crypto.data); 603 p = ngx_quic_read_bytes(p, end, f->u.crypto.length, &f->u.crypto.data);
604 if (p == NULL) { 604 if (p == NULL) {
605 ngx_log_error(NGX_LOG_INFO, pkt->log, 0, 605 ngx_log_error(NGX_LOG_INFO, pkt->log, 0,
606 "failed to parse crypto frame data"); 606 "failed to parse crypto frame data");
607 return NGX_ERROR; 607 return NGX_ERROR;
608 } 608 }
609 609
610 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, pkt->log, 0, 610 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, pkt->log, 0,
611 "quic CRYPTO frame length: %uL off:%uL pp:%p", 611 "quic CRYPTO frame length: %uL off:%uL pp:%p",
612 f->u.crypto.len, f->u.crypto.offset, 612 f->u.crypto.length, f->u.crypto.offset,
613 f->u.crypto.data); 613 f->u.crypto.data);
614 614
615 ngx_quic_hexdump0(pkt->log, "CRYPTO frame contents", 615 ngx_quic_hexdump0(pkt->log, "CRYPTO frame contents",
616 f->u.crypto.data, f->u.crypto.len); 616 f->u.crypto.data, f->u.crypto.length);
617 break; 617 break;
618 618
619 case NGX_QUIC_FT_PADDING: 619 case NGX_QUIC_FT_PADDING:
620 620
621 /* allowed in any packet type */ 621 /* allowed in any packet type */
1240 u_char *start; 1240 u_char *start;
1241 1241
1242 if (p == NULL) { 1242 if (p == NULL) {
1243 len = ngx_quic_varint_len(NGX_QUIC_FT_CRYPTO); 1243 len = ngx_quic_varint_len(NGX_QUIC_FT_CRYPTO);
1244 len += ngx_quic_varint_len(crypto->offset); 1244 len += ngx_quic_varint_len(crypto->offset);
1245 len += ngx_quic_varint_len(crypto->len); 1245 len += ngx_quic_varint_len(crypto->length);
1246 len += crypto->len; 1246 len += crypto->length;
1247 1247
1248 return len; 1248 return len;
1249 } 1249 }
1250 1250
1251 start = p; 1251 start = p;
1252 1252
1253 ngx_quic_build_int(&p, NGX_QUIC_FT_CRYPTO); 1253 ngx_quic_build_int(&p, NGX_QUIC_FT_CRYPTO);
1254 ngx_quic_build_int(&p, crypto->offset); 1254 ngx_quic_build_int(&p, crypto->offset);
1255 ngx_quic_build_int(&p, crypto->len); 1255 ngx_quic_build_int(&p, crypto->length);
1256 p = ngx_cpymem(p, crypto->data, crypto->len); 1256 p = ngx_cpymem(p, crypto->data, crypto->length);
1257 1257
1258 return p - start; 1258 return p - start;
1259 } 1259 }
1260 1260
1261 1261