# HG changeset patch # User Vladimir Homutov # Date 1584812995 -10800 # Node ID 085fd6e68367733c70739f6c32780acbfde80a9f # Parent 0a18893299fe55163c088e993dafd3756a2dc9aa Implemented parsing of remaining frame types. diff --git a/src/event/ngx_event_quic_transport.c b/src/event/ngx_event_quic_transport.c --- a/src/event/ngx_event_quic_transport.c +++ b/src/event/ngx_event_quic_transport.c @@ -856,7 +856,7 @@ ngx_quic_parse_frame(ngx_quic_header_t * (f->type == NGX_QUIC_FT_STREAMS_BLOCKED) ? 1 : 0; ngx_log_debug2(NGX_LOG_DEBUG_EVENT, pkt->log, 0, - "STREAMS BLOCKED frame { limit %i bidi: %d }", + "STREAMS BLOCKED frame { limit %ui bidi: %d }", f->u.streams_blocked.limit, f->u.streams_blocked.bidi); @@ -877,19 +877,141 @@ ngx_quic_parse_frame(ngx_quic_header_t * case NGX_QUIC_FT_MAX_STREAMS: case NGX_QUIC_FT_MAX_STREAMS2: + + if (!(ngx_quic_short_pkt(flags) || ngx_quic_pkt_zrtt(flags))) { + goto not_allowed; + } + + p = ngx_quic_parse_int(p, end, &f->u.max_streams.limit); + if (p == NULL) { + ngx_log_error(NGX_LOG_ERR, pkt->log, 0, + "failed to parse max streams frame limit"); + return NGX_ERROR; + } + + f->u.max_streams.bidi = (f->type == NGX_QUIC_FT_MAX_STREAMS) ? 1 : 0; + + ngx_log_debug2(NGX_LOG_DEBUG_EVENT, pkt->log, 0, + "MAX STREAMS frame { limit %ui bidi: %d }", + f->u.max_streams.limit, + f->u.max_streams.bidi); + break; + case NGX_QUIC_FT_MAX_STREAM_DATA: + + if (!(ngx_quic_short_pkt(flags) || ngx_quic_pkt_zrtt(flags))) { + goto not_allowed; + } + + p = ngx_quic_parse_int_multi(p, end, &f->u.max_stream_data.id, + &f->u.max_stream_data.limit, NULL); + if (p == NULL) { + ngx_log_error(NGX_LOG_ERR, pkt->log, 0, + "failed to parse max stream data frame"); + return NGX_ERROR; + } + + ngx_log_debug2(NGX_LOG_DEBUG_EVENT, pkt->log, 0, + "MAX STREAM DATA frame { id: %ui limit: %ui }", + f->u.max_stream_data.id, + f->u.max_stream_data.limit); + break; + case NGX_QUIC_FT_DATA_BLOCKED: + + if (!(ngx_quic_short_pkt(flags) || ngx_quic_pkt_zrtt(flags))) { + goto not_allowed; + } + + p = ngx_quic_parse_int(p, end, &f->u.data_blocked.limit); + if (p == NULL) { + ngx_log_error(NGX_LOG_ERR, pkt->log, 0, + "failed to parse data blocked frame limit"); + return NGX_ERROR; + } + + ngx_log_debug1(NGX_LOG_DEBUG_EVENT, pkt->log, 0, + "DATA BLOCKED frame { limit %ui }", + f->u.data_blocked.limit); + break; + case NGX_QUIC_FT_STREAM_DATA_BLOCKED: + + if (!(ngx_quic_short_pkt(flags) || ngx_quic_pkt_zrtt(flags))) { + goto not_allowed; + } + + p = ngx_quic_parse_int_multi(p, end, &f->u.stream_data_blocked.id, + &f->u.stream_data_blocked.limit, NULL); + if (p == NULL) { + ngx_log_error(NGX_LOG_ERR, pkt->log, 0, + "failed to parse tream data blocked frame"); + return NGX_ERROR; + } + + ngx_log_debug2(NGX_LOG_DEBUG_EVENT, pkt->log, 0, + "STREAM DATA BLOCKED frame { id: %ui limit: %ui }", + f->u.stream_data_blocked.id, + f->u.stream_data_blocked.limit); + break; + case NGX_QUIC_FT_RETIRE_CONNECTION_ID: + + if (!(ngx_quic_short_pkt(flags) || ngx_quic_pkt_zrtt(flags))) { + goto not_allowed; + } + + p = ngx_quic_parse_int(p, end, &f->u.retire_cid.sequence_number); + if (p == NULL) { + ngx_log_error(NGX_LOG_ERR, pkt->log, 0, + "failed to parse retire connection id" + " frame sequence number"); + return NGX_ERROR; + } + + ngx_log_debug1(NGX_LOG_DEBUG_EVENT, pkt->log, 0, + "RETIRE CONNECTION ID frame { sequence_number %ui }", + f->u.retire_cid.sequence_number); + break; + case NGX_QUIC_FT_PATH_CHALLENGE: + + if (!(ngx_quic_short_pkt(flags) || ngx_quic_pkt_zrtt(flags))) { + goto not_allowed; + } + + p = ngx_quic_copy_bytes(p, end, 8, f->u.path_challenge.data); + if (p == NULL) { + ngx_log_error(NGX_LOG_ERR, pkt->log, 0, + "failed to get path challenge frame data"); + return NGX_ERROR; + } + + ngx_log_debug0(NGX_LOG_DEBUG_EVENT, pkt->log, 0, + "PATH CHALLENGE frame"); + + ngx_quic_hexdump0(pkt->log, "path challenge data", + f->u.path_challenge.data, 8); + break; + case NGX_QUIC_FT_PATH_RESPONSE: if (!(ngx_quic_short_pkt(flags) || ngx_quic_pkt_zrtt(flags))) { goto not_allowed; } - ngx_log_error(NGX_LOG_ERR, pkt->log, 0, - "unimplemented frame type 0x%xi in packet", f->type); + p = ngx_quic_copy_bytes(p, end, 8, f->u.path_response.data); + if (p == NULL) { + ngx_log_error(NGX_LOG_ERR, pkt->log, 0, + "failed to get path response frame data"); + return NGX_ERROR; + } + + ngx_log_debug0(NGX_LOG_DEBUG_EVENT, pkt->log, 0, + "PATH RESPONSE frame"); + + ngx_quic_hexdump0(pkt->log, "path response data", + f->u.path_response.data, 8); break; default: diff --git a/src/event/ngx_event_quic_transport.h b/src/event/ngx_event_quic_transport.h --- a/src/event/ngx_event_quic_transport.h +++ b/src/event/ngx_event_quic_transport.h @@ -172,6 +172,33 @@ typedef struct { } ngx_quic_max_streams_frame_t; +typedef struct { + uint64_t id; + uint64_t limit; +} ngx_quic_max_stream_data_frame_t; + + +typedef struct { + uint64_t limit; +} ngx_quic_data_blocked_frame_t; + + +typedef struct { + uint64_t id; + uint64_t limit; +} ngx_quic_stream_data_blocked_frame_t; + + +typedef struct { + uint64_t sequence_number; +} ngx_quic_retire_cid_frame_t; + + +typedef struct { + u_char data[8]; +} ngx_quic_path_challenge_frame_t; + + typedef struct ngx_quic_frame_s ngx_quic_frame_t; struct ngx_quic_frame_s { @@ -189,6 +216,12 @@ struct ngx_quic_frame_s { ngx_quic_stop_sending_frame_t stop_sending; ngx_quic_streams_blocked_frame_t streams_blocked; ngx_quic_max_streams_frame_t max_streams; + ngx_quic_max_stream_data_frame_t max_stream_data; + ngx_quic_data_blocked_frame_t data_blocked; + ngx_quic_stream_data_blocked_frame_t stream_data_blocked; + ngx_quic_retire_cid_frame_t retire_cid; + ngx_quic_path_challenge_frame_t path_challenge; + ngx_quic_path_challenge_frame_t path_response; } u; u_char info[128]; // for debug };