From b7a5224bd8b2976c2978b0be2569a44de730c000 Mon Sep 17 00:00:00 2001 From: Roman Arutyunyan Date: Wed, 28 Jul 2021 13:21:47 +0300 Subject: [PATCH] QUIC: eliminated stream type from ngx_quic_stream_frame_t. The information about the type is contained in off/len/fin bits. Also, where possible, only the first stream type (0x08) is used for simplicity. --- src/event/quic/ngx_event_quic.c | 9 +-- src/event/quic/ngx_event_quic_ack.c | 18 +----- src/event/quic/ngx_event_quic_frames.c | 19 +----- src/event/quic/ngx_event_quic_streams.c | 6 +- src/event/quic/ngx_event_quic_transport.c | 72 +++++++++++++---------- src/event/quic/ngx_event_quic_transport.h | 3 +- 6 files changed, 50 insertions(+), 77 deletions(-) diff --git a/src/event/quic/ngx_event_quic.c b/src/event/quic/ngx_event_quic.c index 8f57b9f5d..302101cf4 100644 --- a/src/event/quic/ngx_event_quic.c +++ b/src/event/quic/ngx_event_quic.c @@ -1191,14 +1191,7 @@ ngx_quic_handle_frames(ngx_connection_t *c, ngx_quic_header_t *pkt) case NGX_QUIC_FT_PING: break; - case NGX_QUIC_FT_STREAM0: - case NGX_QUIC_FT_STREAM1: - case NGX_QUIC_FT_STREAM2: - case NGX_QUIC_FT_STREAM3: - case NGX_QUIC_FT_STREAM4: - case NGX_QUIC_FT_STREAM5: - case NGX_QUIC_FT_STREAM6: - case NGX_QUIC_FT_STREAM7: + case NGX_QUIC_FT_STREAM: if (ngx_quic_handle_stream_frame(c, pkt, &frame) != NGX_OK) { return NGX_ERROR; diff --git a/src/event/quic/ngx_event_quic_ack.c b/src/event/quic/ngx_event_quic_ack.c index c4e924c8e..06205c1ba 100644 --- a/src/event/quic/ngx_event_quic_ack.c +++ b/src/event/quic/ngx_event_quic_ack.c @@ -239,14 +239,7 @@ ngx_quic_handle_ack_frame_range(ngx_connection_t *c, ngx_quic_send_ctx_t *ctx, ngx_quic_drop_ack_ranges(c, ctx, f->u.ack.largest); break; - case NGX_QUIC_FT_STREAM0: - case NGX_QUIC_FT_STREAM1: - case NGX_QUIC_FT_STREAM2: - case NGX_QUIC_FT_STREAM3: - case NGX_QUIC_FT_STREAM4: - case NGX_QUIC_FT_STREAM5: - case NGX_QUIC_FT_STREAM6: - case NGX_QUIC_FT_STREAM7: + case NGX_QUIC_FT_STREAM: ngx_quic_handle_stream_ack(c, f); break; } @@ -599,14 +592,7 @@ ngx_quic_resend_frames(ngx_connection_t *c, ngx_quic_send_ctx_t *ctx) ngx_quic_queue_frame(qc, f); break; - case NGX_QUIC_FT_STREAM0: - case NGX_QUIC_FT_STREAM1: - case NGX_QUIC_FT_STREAM2: - case NGX_QUIC_FT_STREAM3: - case NGX_QUIC_FT_STREAM4: - case NGX_QUIC_FT_STREAM5: - case NGX_QUIC_FT_STREAM6: - case NGX_QUIC_FT_STREAM7: + case NGX_QUIC_FT_STREAM: qs = ngx_quic_find_stream(&qc->streams.tree, f->u.stream.stream_id); if (qs && qs->connection->write->error) { diff --git a/src/event/quic/ngx_event_quic_frames.c b/src/event/quic/ngx_event_quic_frames.c index 52b5c624e..438565858 100644 --- a/src/event/quic/ngx_event_quic_frames.c +++ b/src/event/quic/ngx_event_quic_frames.c @@ -197,14 +197,7 @@ ngx_quic_split_frame(ngx_connection_t *c, ngx_quic_frame_t *f, size_t len) switch (f->type) { case NGX_QUIC_FT_CRYPTO: - case NGX_QUIC_FT_STREAM0: - case NGX_QUIC_FT_STREAM1: - case NGX_QUIC_FT_STREAM2: - case NGX_QUIC_FT_STREAM3: - case NGX_QUIC_FT_STREAM4: - case NGX_QUIC_FT_STREAM5: - case NGX_QUIC_FT_STREAM6: - case NGX_QUIC_FT_STREAM7: + case NGX_QUIC_FT_STREAM: break; default: @@ -663,15 +656,7 @@ ngx_quic_log_frame(ngx_log_t *log, ngx_quic_frame_t *f, ngx_uint_t tx) break; - case NGX_QUIC_FT_STREAM0: - case NGX_QUIC_FT_STREAM1: - case NGX_QUIC_FT_STREAM2: - case NGX_QUIC_FT_STREAM3: - case NGX_QUIC_FT_STREAM4: - case NGX_QUIC_FT_STREAM5: - case NGX_QUIC_FT_STREAM6: - case NGX_QUIC_FT_STREAM7: - + case NGX_QUIC_FT_STREAM: p = ngx_slprintf(p, last, "STREAM id:0x%xL", f->u.stream.stream_id); if (f->u.stream.off) { diff --git a/src/event/quic/ngx_event_quic_streams.c b/src/event/quic/ngx_event_quic_streams.c index 24ccdea03..58639a6f9 100644 --- a/src/event/quic/ngx_event_quic_streams.c +++ b/src/event/quic/ngx_event_quic_streams.c @@ -584,12 +584,11 @@ ngx_quic_stream_send_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit) } frame->level = ssl_encryption_application; - frame->type = NGX_QUIC_FT_STREAM6; /* OFF=1 LEN=1 FIN=0 */ + frame->type = NGX_QUIC_FT_STREAM; frame->u.stream.off = 1; frame->u.stream.len = 1; frame->u.stream.fin = 0; - frame->u.stream.type = frame->type; frame->u.stream.stream_id = qs->id; frame->u.stream.offset = c->sent; frame->u.stream.length = n; @@ -755,12 +754,11 @@ ngx_quic_stream_cleanup_handler(void *data) } frame->level = ssl_encryption_application; - frame->type = NGX_QUIC_FT_STREAM7; /* OFF=1 LEN=1 FIN=1 */ + frame->type = NGX_QUIC_FT_STREAM; frame->u.stream.off = 1; frame->u.stream.len = 1; frame->u.stream.fin = 1; - frame->u.stream.type = frame->type; frame->u.stream.stream_id = qs->id; frame->u.stream.offset = c->sent; frame->u.stream.length = 0; diff --git a/src/event/quic/ngx_event_quic_transport.c b/src/event/quic/ngx_event_quic_transport.c index 894595fbc..94d516fc7 100644 --- a/src/event/quic/ngx_event_quic_transport.c +++ b/src/event/quic/ngx_event_quic_transport.c @@ -14,6 +14,10 @@ #define NGX_QUIC_LONG_DCID_OFFSET 6 #define NGX_QUIC_SHORT_DCID_OFFSET 1 +#define NGX_QUIC_STREAM_FRAME_FIN 0x01 +#define NGX_QUIC_STREAM_FRAME_LEN 0x02 +#define NGX_QUIC_STREAM_FRAME_OFF 0x04 + #if (NGX_HAVE_NONALIGNED) @@ -736,10 +740,6 @@ ngx_quic_create_retry_itag(ngx_quic_header_t *pkt, u_char *out, } -#define ngx_quic_stream_bit_off(val) (((val) & 0x04) ? 1 : 0) -#define ngx_quic_stream_bit_len(val) (((val) & 0x02) ? 1 : 0) -#define ngx_quic_stream_bit_fin(val) (((val) & 0x01) ? 1 : 0) - ssize_t ngx_quic_parse_frame(ngx_quic_header_t *pkt, u_char *start, u_char *end, ngx_quic_frame_t *f) @@ -931,7 +931,7 @@ ngx_quic_parse_frame(ngx_quic_header_t *pkt, u_char *start, u_char *end, break; - case NGX_QUIC_FT_STREAM0: + case NGX_QUIC_FT_STREAM: case NGX_QUIC_FT_STREAM1: case NGX_QUIC_FT_STREAM2: case NGX_QUIC_FT_STREAM3: @@ -940,34 +940,36 @@ ngx_quic_parse_frame(ngx_quic_header_t *pkt, u_char *start, u_char *end, case NGX_QUIC_FT_STREAM6: case NGX_QUIC_FT_STREAM7: - f->u.stream.type = f->type; - - f->u.stream.off = ngx_quic_stream_bit_off(f->type); - f->u.stream.len = ngx_quic_stream_bit_len(f->type); - f->u.stream.fin = ngx_quic_stream_bit_fin(f->type); + f->u.stream.fin = (f->type & NGX_QUIC_STREAM_FRAME_FIN) ? 1 : 0; p = ngx_quic_parse_int(p, end, &f->u.stream.stream_id); if (p == NULL) { goto error; } - if (f->type & 0x04) { + if (f->type & NGX_QUIC_STREAM_FRAME_OFF) { + f->u.stream.off = 1; + p = ngx_quic_parse_int(p, end, &f->u.stream.offset); if (p == NULL) { goto error; } } else { + f->u.stream.off = 0; f->u.stream.offset = 0; } - if (f->type & 0x02) { + if (f->type & NGX_QUIC_STREAM_FRAME_LEN) { + f->u.stream.len = 1; + p = ngx_quic_parse_int(p, end, &f->u.stream.length); if (p == NULL) { goto error; } } else { + f->u.stream.len = 0; f->u.stream.length = end - p; /* up to packet end */ } @@ -977,6 +979,8 @@ ngx_quic_parse_frame(ngx_quic_header_t *pkt, u_char *start, u_char *end, } b->last = p; + + f->type = NGX_QUIC_FT_STREAM; break; case NGX_QUIC_FT_MAX_DATA: @@ -1141,7 +1145,7 @@ ngx_quic_frame_allowed(ngx_quic_header_t *pkt, ngx_uint_t frame_type) /* STOP_SENDING */ 0x3, /* CRYPTO */ 0xD, /* NEW_TOKEN */ 0x0, /* only sent by server */ - /* STREAM0 */ 0x3, + /* STREAM */ 0x3, /* STREAM1 */ 0x3, /* STREAM2 */ 0x3, /* STREAM3 */ 0x3, @@ -1276,14 +1280,7 @@ ngx_quic_create_frame(u_char *p, ngx_quic_frame_t *f) case NGX_QUIC_FT_NEW_TOKEN: return ngx_quic_create_new_token(p, &f->u.token); - case NGX_QUIC_FT_STREAM0: - case NGX_QUIC_FT_STREAM1: - case NGX_QUIC_FT_STREAM2: - case NGX_QUIC_FT_STREAM3: - case NGX_QUIC_FT_STREAM4: - case NGX_QUIC_FT_STREAM5: - case NGX_QUIC_FT_STREAM6: - case NGX_QUIC_FT_STREAM7: + case NGX_QUIC_FT_STREAM: return ngx_quic_create_stream(p, &f->u.stream, f->data); case NGX_QUIC_FT_CONNECTION_CLOSE: @@ -1499,20 +1496,34 @@ ngx_quic_create_stream(u_char *p, ngx_quic_stream_frame_t *sf, ngx_chain_t *data) { size_t len; - u_char *start; + u_char *start, type; ngx_buf_t *b; + type = NGX_QUIC_FT_STREAM; + + if (sf->off) { + type |= NGX_QUIC_STREAM_FRAME_OFF; + } + + if (sf->len) { + type |= NGX_QUIC_STREAM_FRAME_LEN; + } + + if (sf->fin) { + type |= NGX_QUIC_STREAM_FRAME_FIN; + } + if (p == NULL) { - len = ngx_quic_varint_len(sf->type); + len = ngx_quic_varint_len(type); + len += ngx_quic_varint_len(sf->stream_id); if (sf->off) { len += ngx_quic_varint_len(sf->offset); } - len += ngx_quic_varint_len(sf->stream_id); - - /* length is always present in generated frames */ - len += ngx_quic_varint_len(sf->length); + if (sf->len) { + len += ngx_quic_varint_len(sf->length); + } len += sf->length; @@ -1521,15 +1532,16 @@ ngx_quic_create_stream(u_char *p, ngx_quic_stream_frame_t *sf, start = p; - ngx_quic_build_int(&p, sf->type); + ngx_quic_build_int(&p, type); ngx_quic_build_int(&p, sf->stream_id); if (sf->off) { ngx_quic_build_int(&p, sf->offset); } - /* length is always present in generated frames */ - ngx_quic_build_int(&p, sf->length); + if (sf->len) { + ngx_quic_build_int(&p, sf->length); + } while (data) { b = data->buf; diff --git a/src/event/quic/ngx_event_quic_transport.h b/src/event/quic/ngx_event_quic_transport.h index b35ba1839..81a41b1ea 100644 --- a/src/event/quic/ngx_event_quic_transport.h +++ b/src/event/quic/ngx_event_quic_transport.h @@ -63,7 +63,7 @@ #define NGX_QUIC_FT_STOP_SENDING 0x05 #define NGX_QUIC_FT_CRYPTO 0x06 #define NGX_QUIC_FT_NEW_TOKEN 0x07 -#define NGX_QUIC_FT_STREAM0 0x08 +#define NGX_QUIC_FT_STREAM 0x08 #define NGX_QUIC_FT_STREAM1 0x09 #define NGX_QUIC_FT_STREAM2 0x0A #define NGX_QUIC_FT_STREAM3 0x0B @@ -190,7 +190,6 @@ typedef struct { uint64_t offset; uint64_t length; - uint8_t type; uint64_t stream_id; unsigned off:1; unsigned len:1;