changeset 8531:4ff2a0b747d1 quic

QUIC: handle PATH_CHALLENGE frame. A PATH_RESPONSE frame with the same data is sent in response.
author Roman Arutyunyan <arut@nginx.com>
date Fri, 28 Aug 2020 12:01:35 +0300
parents f882b1784f30
children b13141d6d250
files src/event/ngx_event_quic.c src/event/ngx_event_quic_transport.c
diffstat 2 files changed, 69 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/src/event/ngx_event_quic.c
+++ b/src/event/ngx_event_quic.c
@@ -251,6 +251,8 @@ static ngx_int_t ngx_quic_handle_stop_se
     ngx_quic_header_t *pkt, ngx_quic_stop_sending_frame_t *f);
 static ngx_int_t ngx_quic_handle_max_streams_frame(ngx_connection_t *c,
     ngx_quic_header_t *pkt, ngx_quic_max_streams_frame_t *f);
+static ngx_int_t ngx_quic_handle_path_challenge_frame(ngx_connection_t *c,
+    ngx_quic_header_t *pkt, ngx_quic_path_challenge_frame_t *f);
 
 static void ngx_quic_queue_frame(ngx_quic_connection_t *qc,
     ngx_quic_frame_t *frame);
@@ -2202,9 +2204,19 @@ ngx_quic_payload_handler(ngx_connection_
 
             break;
 
+        case NGX_QUIC_FT_PATH_CHALLENGE:
+
+            if (ngx_quic_handle_path_challenge_frame(c, pkt,
+                                                     &frame.u.path_challenge)
+                != NGX_OK)
+            {
+                return NGX_ERROR;
+            }
+
+            break;
+
         case NGX_QUIC_FT_NEW_CONNECTION_ID:
         case NGX_QUIC_FT_RETIRE_CONNECTION_ID:
-        case NGX_QUIC_FT_PATH_CHALLENGE:
         case NGX_QUIC_FT_PATH_RESPONSE:
 
             /* TODO: handle */
@@ -3422,6 +3434,30 @@ ngx_quic_handle_max_streams_frame(ngx_co
 }
 
 
+static ngx_int_t
+ngx_quic_handle_path_challenge_frame(ngx_connection_t *c,
+    ngx_quic_header_t *pkt, ngx_quic_path_challenge_frame_t *f)
+{
+    ngx_quic_frame_t  *frame;
+
+    frame = ngx_quic_alloc_frame(c, 0);
+    if (frame == NULL) {
+        return NGX_ERROR;
+    }
+
+    frame->level = pkt->level;
+    frame->type = NGX_QUIC_FT_PATH_RESPONSE;
+    frame->u.path_response = *f;
+
+    ngx_sprintf(frame->info, "PATH_RESPONSE data:0x%xL level:%d",
+                *(uint64_t *) &f->data, frame->level);
+
+    ngx_quic_queue_frame(c->quic, frame);
+
+    return NGX_OK;
+}
+
+
 static void
 ngx_quic_queue_frame(ngx_quic_connection_t *qc, ngx_quic_frame_t *frame)
 {
--- a/src/event/ngx_event_quic_transport.c
+++ b/src/event/ngx_event_quic_transport.c
@@ -84,6 +84,8 @@ static size_t ngx_quic_create_max_stream
     ngx_quic_max_stream_data_frame_t *ms);
 static size_t ngx_quic_create_max_data(u_char *p,
     ngx_quic_max_data_frame_t *md);
+static size_t ngx_quic_create_path_response(u_char *p,
+    ngx_quic_path_challenge_frame_t *pc);
 static size_t ngx_quic_create_close(u_char *p, ngx_quic_close_frame_t *cl);
 
 static ngx_int_t ngx_quic_parse_transport_param(u_char *p, u_char *end,
@@ -1004,13 +1006,9 @@ ngx_quic_parse_frame(ngx_quic_header_t *
             goto error;
         }
 
-        ngx_log_debug0(NGX_LOG_DEBUG_EVENT, pkt->log, 0,
-                       "quic frame in: PATH_CHALLENGE");
-
-#ifdef NGX_QUIC_DEBUG_FRAMES
-        ngx_quic_hexdump(pkt->log, "quic PATH_CHALLENGE frame data",
-                         f->u.path_challenge.data, 8);
-#endif
+        ngx_log_debug1(NGX_LOG_DEBUG_EVENT, pkt->log, 0,
+                       "quic frame in: PATH_CHALLENGE data:0x%xL",
+                       *(uint64_t *) &f->u.path_challenge.data);
         break;
 
     case NGX_QUIC_FT_PATH_RESPONSE:
@@ -1020,13 +1018,9 @@ ngx_quic_parse_frame(ngx_quic_header_t *
             goto error;
         }
 
-        ngx_log_debug0(NGX_LOG_DEBUG_EVENT, pkt->log, 0,
-                       "quic frame in: PATH_RESPONSE");
-
-#ifdef NGX_QUIC_DEBUG_FRAMES
-        ngx_quic_hexdump(pkt->log, "quic PATH_RESPONSE frame data",
-                         f->u.path_response.data, 8);
-#endif
+        ngx_log_debug1(NGX_LOG_DEBUG_EVENT, pkt->log, 0,
+                       "quic frame in: PATH_RESPONSE data:0x%xL",
+                       *(uint64_t *) &f->u.path_response.data);
         break;
 
     default:
@@ -1203,6 +1197,9 @@ ngx_quic_create_frame(u_char *p, ngx_qui
     case NGX_QUIC_FT_MAX_DATA:
         return ngx_quic_create_max_data(p, &f->u.max_data);
 
+    case NGX_QUIC_FT_PATH_RESPONSE:
+        return ngx_quic_create_path_response(p, &f->u.path_response);
+
     default:
         /* BUG: unsupported frame type generated */
         return NGX_ERROR;
@@ -1661,6 +1658,27 @@ ngx_quic_create_max_data(u_char *p, ngx_
 }
 
 
+static size_t
+ngx_quic_create_path_response(u_char *p, ngx_quic_path_challenge_frame_t *pc)
+{
+    size_t   len;
+    u_char  *start;
+
+    if (p == NULL) {
+        len = ngx_quic_varint_len(NGX_QUIC_FT_PATH_RESPONSE);
+        len += sizeof(pc->data);
+        return len;
+    }
+
+    start = p;
+
+    ngx_quic_build_int(&p, NGX_QUIC_FT_PATH_RESPONSE);
+    p = ngx_cpymem(p, &pc->data, sizeof(pc->data));
+
+    return p - start;
+}
+
+
 ssize_t
 ngx_quic_create_transport_params(u_char *pos, u_char *end, ngx_quic_tp_t *tp,
     size_t *clen)