# HG changeset patch # User Vladimir Homutov # Date 1585040354 -10800 # Node ID cb75f194f1f004f7ec655fc0adf88517ad1717fc # Parent 7f0981be07c456a5a1108da2ea71bf184d0c0845 Implemented sending HANDSHAKE_DONE frame after handshake. This makes it possible to switch to draft 27 by default. diff --git a/src/event/ngx_event_quic.c b/src/event/ngx_event_quic.c --- a/src/event/ngx_event_quic.c +++ b/src/event/ngx_event_quic.c @@ -964,9 +964,10 @@ static ngx_int_t ngx_quic_handle_crypto_frame(ngx_connection_t *c, ngx_quic_header_t *pkt, ngx_quic_crypto_frame_t *f) { - int sslerr; - ssize_t n; - ngx_ssl_conn_t *ssl_conn; + int sslerr; + ssize_t n; + ngx_ssl_conn_t *ssl_conn; + ngx_quic_frame_t *frame; if (f->offset != 0x0) { ngx_log_error(NGX_LOG_INFO, c->log, 0, @@ -1012,6 +1013,17 @@ ngx_quic_handle_crypto_frame(ngx_connect ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "handshake completed successfully"); + + frame = ngx_pcalloc(c->pool, sizeof(ngx_quic_frame_t)); + if (frame == NULL) { + return NGX_ERROR; + } + + /* 12.4 Frames and frame types, figure 8 */ + frame->level = ssl_encryption_application; + frame->type = NGX_QUIC_FT_HANDSHAKE_DONE; + ngx_sprintf(frame->info, "HANDSHAKE DONE on handshake completed"); + ngx_quic_queue_frame(c->quic, frame); } ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, diff --git a/src/event/ngx_event_quic.h b/src/event/ngx_event_quic.h --- a/src/event/ngx_event_quic.h +++ b/src/event/ngx_event_quic.h @@ -11,7 +11,7 @@ #include -#define NGX_QUIC_DRAFT_VERSION 24 +#define NGX_QUIC_DRAFT_VERSION 27 #define NGX_QUIC_VERSION (0xff000000 + NGX_QUIC_DRAFT_VERSION) #define NGX_QUIC_MAX_SHORT_HEADER 25 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 @@ -66,6 +66,7 @@ static u_char *ngx_quic_copy_bytes(u_cha static size_t ngx_quic_create_ack(u_char *p, ngx_quic_ack_frame_t *ack); static size_t ngx_quic_create_crypto(u_char *p, ngx_quic_crypto_frame_t *crypto); +static size_t ngx_quic_create_hs_done(u_char *p); static size_t ngx_quic_create_stream(u_char *p, ngx_quic_stream_frame_t *sf); static size_t ngx_quic_create_max_streams(u_char *p, ngx_quic_max_streams_frame_t *ms); @@ -882,14 +883,18 @@ ngx_quic_parse_frame(ngx_quic_header_t * break; - /* TODO: implement parsing for all frames below */ + case NGX_QUIC_FT_HANDSHAKE_DONE: + /* only sent by server, not by client */ + goto not_allowed; + case NGX_QUIC_FT_NEW_TOKEN: - case NGX_QUIC_FT_HANDSHAKE_DONE: if (!ngx_quic_short_pkt(flags)) { goto not_allowed; } + /* TODO: implement */ + ngx_log_error(NGX_LOG_ERR, pkt->log, 0, "unimplemented frame type 0x%xi in packet", f->type); @@ -1065,6 +1070,9 @@ ngx_quic_create_frame(u_char *p, u_char case NGX_QUIC_FT_CRYPTO: return ngx_quic_create_crypto(p, &f->u.crypto); + case NGX_QUIC_FT_HANDSHAKE_DONE: + return ngx_quic_create_hs_done(p); + case NGX_QUIC_FT_STREAM0: case NGX_QUIC_FT_STREAM1: case NGX_QUIC_FT_STREAM2: @@ -1148,6 +1156,23 @@ ngx_quic_create_crypto(u_char *p, ngx_qu static size_t +ngx_quic_create_hs_done(u_char *p) +{ + u_char *start; + + if (p == NULL) { + return ngx_quic_varint_len(NGX_QUIC_FT_HANDSHAKE_DONE); + } + + start = p; + + ngx_quic_build_int(&p, NGX_QUIC_FT_HANDSHAKE_DONE); + + return p - start; +} + + +static size_t ngx_quic_create_stream(u_char *p, ngx_quic_stream_frame_t *sf) { size_t len;