changeset 8235:552d6868091b quic

Implemented send_alert callback, CONNECTION_CLOSE writer. The callback produces a CONNECTION_CLOSE frame, as per quic-tls-24#section-4.9.
author Sergey Kandaurov <pluknet@nginx.com>
date Wed, 18 Mar 2020 23:07:40 +0300
parents 19bb9edcd8bd
children d3b26c3bea22
files src/event/ngx_event_quic.c src/event/ngx_event_quic_transport.c
diffstat 2 files changed, 50 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/src/event/ngx_event_quic.c
+++ b/src/event/ngx_event_quic.c
@@ -251,6 +251,7 @@ ngx_quic_send_alert(ngx_ssl_conn_t *ssl_
     uint8_t alert)
 {
     ngx_connection_t  *c;
+    ngx_quic_frame_t  *frame;
 
     c = ngx_ssl_get_connection((ngx_ssl_conn_t *) ssl_conn);
 
@@ -258,6 +259,21 @@ ngx_quic_send_alert(ngx_ssl_conn_t *ssl_
                    "ngx_quic_send_alert(), lvl=%d, alert=%d",
                    (int) level, (int) alert);
 
+    frame = ngx_pcalloc(c->pool, sizeof(ngx_quic_frame_t));
+    if (frame == NULL) {
+        return 0;
+    }
+
+    frame->level = level;
+    frame->type = NGX_QUIC_FT_CONNECTION_CLOSE;
+    frame->u.close.error_code = 0x100 + alert;
+
+    ngx_quic_queue_frame(c->quic, frame);
+
+    if (ngx_quic_output(c) != NGX_OK) {
+        return 0;
+    }
+
     return 1;
 }
 
--- a/src/event/ngx_event_quic_transport.c
+++ b/src/event/ngx_event_quic_transport.c
@@ -58,6 +58,7 @@ static size_t ngx_quic_create_ack(u_char
 static size_t ngx_quic_create_crypto(u_char *p,
     ngx_quic_crypto_frame_t *crypto);
 static size_t ngx_quic_create_stream(u_char *p, ngx_quic_stream_frame_t *sf);
+static size_t ngx_quic_create_close(u_char *p, ngx_quic_close_frame_t *cl);
 
 
 /* literal errors indexed by corresponding value */
@@ -464,6 +465,9 @@ ngx_quic_create_frame(u_char *p, u_char 
     case NGX_QUIC_FT_STREAM7:
         return ngx_quic_create_stream(p, &f->u.stream);
 
+    case NGX_QUIC_FT_CONNECTION_CLOSE:
+        return ngx_quic_create_close(p, &f->u.close);
+
     default:
         /* BUG: unsupported frame type generated */
         return NGX_ERROR;
@@ -489,6 +493,8 @@ ngx_quic_frame_len(ngx_quic_frame_t *fra
         case NGX_QUIC_FT_STREAM6:
         case NGX_QUIC_FT_STREAM7:
             return ngx_quic_create_stream(NULL, &frame->u.stream);
+        case NGX_QUIC_FT_CONNECTION_CLOSE:
+            return ngx_quic_create_close(NULL, &frame->u.close);
         default:
             /* BUG: unsupported frame type generated */
             return 0;
@@ -597,3 +603,31 @@ ngx_quic_create_stream(u_char *p, ngx_qu
 
     return p - start;
 }
+
+
+static size_t
+ngx_quic_create_close(u_char *p, ngx_quic_close_frame_t *cl)
+{
+    size_t   len;
+    u_char  *start;
+
+    if (p == NULL) {
+        len = ngx_quic_varint_len(NGX_QUIC_FT_CONNECTION_CLOSE);
+        len += ngx_quic_varint_len(cl->error_code);
+        len += ngx_quic_varint_len(cl->frame_type);
+        len += ngx_quic_varint_len(cl->reason.len);
+        len += cl->reason.len;
+
+        return len;
+    }
+
+    start = p;
+
+    ngx_quic_build_int(&p, NGX_QUIC_FT_CONNECTION_CLOSE);
+    ngx_quic_build_int(&p, cl->error_code);
+    ngx_quic_build_int(&p, cl->frame_type);
+    ngx_quic_build_int(&p, cl->reason.len);
+    p = ngx_cpymem(p, cl->reason.data, cl->reason.len);
+
+    return p - start;
+}