From 191e264fedc77f14bbd7ca042e32142b29a171e2 Mon Sep 17 00:00:00 2001
From: Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
Date: Tue, 26 May 2020 18:00:06 +0900
Subject: [PATCH] Use ngtcp2_vec for ngtcp2_pkt_hd.token

---
 examples/server.cc           | 51 ++++++++++++++++++++----------------
 lib/includes/ngtcp2/ngtcp2.h |  3 +--
 lib/ngtcp2_conn.c            | 11 ++++----
 lib/ngtcp2_pkt.c             | 16 +++++------
 lib/ngtcp2_ppe.c             |  2 +-
 tests/ngtcp2_conn_test.c     |  4 +--
 tests/ngtcp2_test_helper.c   |  4 +--
 7 files changed, 47 insertions(+), 44 deletions(-)

diff --git a/examples/server.cc b/examples/server.cc
index e1539a07..4020e95c 100644
--- a/examples/server.cc
+++ b/examples/server.cc
@@ -2383,14 +2383,19 @@ int Server::on_read(Endpoint &ep) {
         ngtcp2_cid *pocid = nullptr;
         switch (hd.type) {
         case NGTCP2_PKT_INITIAL:
-          if (config.validate_addr || hd.tokenlen) {
+          if (config.validate_addr || hd.token.len) {
             std::cerr << "Perform stateless address validation" << std::endl;
-            if (hd.tokenlen == 0) {
+            if (hd.token.len == 0) {
               send_retry(&hd, ep, &su.sa, addrlen);
               continue;
             }
 
-            switch (hd.token[0]) {
+            if (hd.token.base[0] != RETRY_TOKEN_MAGIC && hd.dcid.datalen < 8) {
+              send_stateless_connection_close(&hd, ep, &su.sa, addrlen);
+              continue;
+            }
+
+            switch (hd.token.base[0]) {
             case RETRY_TOKEN_MAGIC:
               if (verify_retry_token(&ocid, &hd, &su.sa, addrlen) != 0) {
                 send_stateless_connection_close(&hd, ep, &su.sa, addrlen);
@@ -2405,8 +2410,8 @@ int Server::on_read(Endpoint &ep) {
                   continue;
                 }
 
-                hd.token = nullptr;
-                hd.tokenlen = 0;
+                hd.token.base = nullptr;
+                hd.token.len = 0;
               }
               break;
             default:
@@ -2418,8 +2423,8 @@ int Server::on_read(Endpoint &ep) {
                 continue;
               }
 
-              hd.token = nullptr;
-              hd.tokenlen = 0;
+              hd.token.base = nullptr;
+              hd.token.len = 0;
               break;
             }
           }
@@ -2430,8 +2435,8 @@ int Server::on_read(Endpoint &ep) {
         }
 
         auto h = std::make_unique<Handler>(loop_, ssl_ctx_, this, &hd.dcid);
-        if (h->init(ep, &su.sa, addrlen, &hd.scid, &hd.dcid, pocid, hd.token,
-                    hd.tokenlen, hd.version) != 0) {
+        if (h->init(ep, &su.sa, addrlen, &hd.scid, &hd.dcid, pocid,
+                    hd.token.base, hd.token.len, hd.version) != 0) {
           continue;
         }
 
@@ -2750,28 +2755,28 @@ int Server::verify_retry_token(ngtcp2_cid *ocid, const ngtcp2_pkt_hd *hd,
   if (!config.quiet) {
     std::cerr << "Verifying Retry token from [" << host.data()
               << "]:" << port.data() << std::endl;
-    util::hexdump(stderr, hd->token, hd->tokenlen);
+    util::hexdump(stderr, hd->token.base, hd->token.len);
   }
 
   /* 1 for RETRY_TOKEN_MAGIC */
-  if (hd->tokenlen < TOKEN_RAND_DATALEN + 1) {
+  if (hd->token.len < TOKEN_RAND_DATALEN + 1) {
     if (!config.quiet) {
       std::cerr << "Token is too short" << std::endl;
     }
     return -1;
   }
-  if (hd->tokenlen > MAX_RETRY_TOKENLEN) {
+  if (hd->token.len > MAX_RETRY_TOKENLEN) {
     if (!config.quiet) {
       std::cerr << "Token is too long" << std::endl;
     }
     return -1;
   }
 
-  assert(hd->token[0] == RETRY_TOKEN_MAGIC);
+  assert(hd->token.base[0] == RETRY_TOKEN_MAGIC);
 
-  auto rand_data = hd->token + hd->tokenlen - TOKEN_RAND_DATALEN;
-  auto ciphertext = hd->token + 1;
-  auto ciphertextlen = hd->tokenlen - TOKEN_RAND_DATALEN - 1;
+  auto rand_data = hd->token.base + hd->token.len - TOKEN_RAND_DATALEN;
+  auto ciphertext = hd->token.base + 1;
+  auto ciphertextlen = hd->token.len - TOKEN_RAND_DATALEN - 1;
 
   std::array<uint8_t, 32> key, iv;
   auto keylen = key.size();
@@ -2928,31 +2933,31 @@ int Server::verify_token(const ngtcp2_pkt_hd *hd, const sockaddr *sa,
   if (!config.quiet) {
     std::cerr << "Verifying token from [" << host.data() << "]:" << port.data()
               << std::endl;
-    util::hexdump(stderr, hd->token, hd->tokenlen);
+    util::hexdump(stderr, hd->token.base, hd->token.len);
   }
 
   /* 1 for TOKEN_MAGIC */
-  if (hd->tokenlen < TOKEN_RAND_DATALEN + 1) {
+  if (hd->token.len < TOKEN_RAND_DATALEN + 1) {
     if (!config.quiet) {
       std::cerr << "Token is too short" << std::endl;
     }
     return -1;
   }
-  if (hd->tokenlen > MAX_TOKENLEN) {
+  if (hd->token.len > MAX_TOKENLEN) {
     if (!config.quiet) {
       std::cerr << "Token is too long" << std::endl;
     }
     return -1;
   }
 
-  assert(hd->token[0] == TOKEN_MAGIC);
+  assert(hd->token.base[0] == TOKEN_MAGIC);
 
   std::array<uint8_t, 256> aad;
   auto aadlen = generate_token_aad(aad.data(), aad.size(), sa, salen);
 
-  auto rand_data = hd->token + hd->tokenlen - TOKEN_RAND_DATALEN;
-  auto ciphertext = hd->token + 1;
-  auto ciphertextlen = hd->tokenlen - TOKEN_RAND_DATALEN - 1;
+  auto rand_data = hd->token.base + hd->token.len - TOKEN_RAND_DATALEN;
+  auto ciphertext = hd->token.base + 1;
+  auto ciphertextlen = hd->token.len - TOKEN_RAND_DATALEN - 1;
 
   std::array<uint8_t, 32> key, iv;
   auto keylen = key.size();
diff --git a/lib/includes/ngtcp2/ngtcp2.h b/lib/includes/ngtcp2/ngtcp2.h
index c9e29822..9567dde9 100644
--- a/lib/includes/ngtcp2/ngtcp2.h
+++ b/lib/includes/ngtcp2/ngtcp2.h
@@ -359,8 +359,7 @@ typedef struct ngtcp2_pkt_hd {
   ngtcp2_cid dcid;
   ngtcp2_cid scid;
   int64_t pkt_num;
-  uint8_t *token;
-  size_t tokenlen;
+  ngtcp2_vec token;
   /**
    * pkt_numlen is the number of bytes spent to encode pkt_num.
    */
diff --git a/lib/ngtcp2_conn.c b/lib/ngtcp2_conn.c
index 2ab1d35f..b70d030e 100644
--- a/lib/ngtcp2_conn.c
+++ b/lib/ngtcp2_conn.c
@@ -1736,8 +1736,7 @@ static ngtcp2_ssize conn_write_handshake_pkt(ngtcp2_conn *conn, uint8_t *dest,
 
   if (!conn->server && type == NGTCP2_PKT_INITIAL &&
       conn->local.settings.token.len) {
-    hd.token = conn->local.settings.token.base;
-    hd.tokenlen = conn->local.settings.token.len;
+    hd.token = conn->local.settings.token;
   }
 
   ngtcp2_ppe_init(&ppe, dest, destlen, &cc);
@@ -4243,8 +4242,8 @@ static int pktns_commit_recv_pkt_num(ngtcp2_pktns *pktns, int64_t pkt_num) {
  * returns 0 if it succeeds, or NGTCP2_ERR_PROTO.
  */
 static int verify_token(const ngtcp2_vec *token, const ngtcp2_pkt_hd *hd) {
-  if (token->len == hd->tokenlen &&
-      ngtcp2_cmemeq(token->base, hd->token, token->len)) {
+  if (token->len == hd->token.len &&
+      ngtcp2_cmemeq(token->base, hd->token.base, token->len)) {
     return 0;
   }
   return NGTCP2_ERR_PROTO;
@@ -4492,7 +4491,7 @@ static ngtcp2_ssize conn_recv_handshake_pkt(ngtcp2_conn *conn,
           return rv;
         }
       }
-    } else if (hd.tokenlen != 0) {
+    } else if (hd.token.len != 0) {
       ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_PKT,
                       "packet was ignored because token is not empty");
       return NGTCP2_ERR_DISCARD_PKT;
@@ -7846,7 +7845,7 @@ int ngtcp2_accept(ngtcp2_pkt_hd *dest, const uint8_t *pkt, size_t pktlen) {
     if (pktlen < NGTCP2_MIN_INITIAL_PKTLEN) {
       return -1;
     }
-    if (p->tokenlen == 0 && p->dcid.datalen < 8) {
+    if (p->token.len == 0 && p->dcid.datalen < 8) {
       return -1;
     }
     break;
diff --git a/lib/ngtcp2_pkt.c b/lib/ngtcp2_pkt.c
index 00d2d885..07c9e146 100644
--- a/lib/ngtcp2_pkt.c
+++ b/lib/ngtcp2_pkt.c
@@ -141,8 +141,8 @@ void ngtcp2_pkt_hd_init(ngtcp2_pkt_hd *hd, uint8_t flags, uint8_t type,
     ngtcp2_cid_zero(&hd->scid);
   }
   hd->pkt_num = pkt_num;
-  hd->token = NULL;
-  hd->tokenlen = 0;
+  hd->token.base = NULL;
+  hd->token.len = 0;
   hd->pkt_numlen = pkt_numlen;
   hd->version = version;
   hd->len = len;
@@ -284,8 +284,8 @@ ngtcp2_ssize ngtcp2_pkt_decode_hd_long(ngtcp2_pkt_hd *dest, const uint8_t *pkt,
   ngtcp2_cid_init(&dest->scid, p, scil);
   p += scil;
 
-  dest->token = (uint8_t *)token;
-  dest->tokenlen = tokenlen;
+  dest->token.base = (uint8_t *)token;
+  dest->token.len = tokenlen;
   p += ntokenlen + tokenlen;
 
   switch (type) {
@@ -357,7 +357,7 @@ ngtcp2_ssize ngtcp2_pkt_encode_hd_long(uint8_t *out, size_t outlen,
   }
 
   if (hd->type == NGTCP2_PKT_INITIAL) {
-    len += ngtcp2_put_varint_len(hd->tokenlen) + hd->tokenlen;
+    len += ngtcp2_put_varint_len(hd->token.len) + hd->token.len;
   }
 
   if (outlen < len) {
@@ -379,9 +379,9 @@ ngtcp2_ssize ngtcp2_pkt_encode_hd_long(uint8_t *out, size_t outlen,
   }
 
   if (hd->type == NGTCP2_PKT_INITIAL) {
-    p = ngtcp2_put_varint(p, hd->tokenlen);
-    if (hd->tokenlen) {
-      p = ngtcp2_cpymem(p, hd->token, hd->tokenlen);
+    p = ngtcp2_put_varint(p, hd->token.len);
+    if (hd->token.len) {
+      p = ngtcp2_cpymem(p, hd->token.base, hd->token.len);
     }
   }
 
diff --git a/lib/ngtcp2_ppe.c b/lib/ngtcp2_ppe.c
index e4aab22c..c1856d0f 100644
--- a/lib/ngtcp2_ppe.c
+++ b/lib/ngtcp2_ppe.c
@@ -55,7 +55,7 @@ int ngtcp2_ppe_encode_hd(ngtcp2_ppe *ppe, const ngtcp2_pkt_hd *hd) {
   if (hd->flags & NGTCP2_PKT_FLAG_LONG_FORM) {
     ppe->len_offset = 1 + 4 + 1 + hd->dcid.datalen + 1 + hd->scid.datalen;
     if (hd->type == NGTCP2_PKT_INITIAL) {
-      ppe->len_offset += ngtcp2_put_varint_len(hd->tokenlen) + hd->tokenlen;
+      ppe->len_offset += ngtcp2_put_varint_len(hd->token.len) + hd->token.len;
     }
     ppe->pkt_num_offset = ppe->len_offset + 2;
     rv = ngtcp2_pkt_encode_hd_long(
diff --git a/tests/ngtcp2_conn_test.c b/tests/ngtcp2_conn_test.c
index b704af1a..256b3c1e 100644
--- a/tests/ngtcp2_conn_test.c
+++ b/tests/ngtcp2_conn_test.c
@@ -5123,8 +5123,8 @@ void test_ngtcp2_conn_send_initial_token(void) {
   shdlen = ngtcp2_pkt_decode_hd_long(&hd, buf, (size_t)spktlen);
 
   CU_ASSERT(shdlen > 0);
-  CU_ASSERT(sizeof(token) == hd.tokenlen);
-  CU_ASSERT(0 == memcmp(token, hd.token, sizeof(token)));
+  CU_ASSERT(sizeof(token) == hd.token.len);
+  CU_ASSERT(0 == memcmp(token, hd.token.base, sizeof(token)));
 
   ngtcp2_conn_del(conn);
 }
diff --git a/tests/ngtcp2_test_helper.c b/tests/ngtcp2_test_helper.c
index 0576774e..231e37c3 100644
--- a/tests/ngtcp2_test_helper.c
+++ b/tests/ngtcp2_test_helper.c
@@ -279,8 +279,8 @@ size_t write_single_frame_initial_pkt(ngtcp2_conn *conn, uint8_t *out,
 
   ngtcp2_pkt_hd_init(&hd, NGTCP2_PKT_FLAG_LONG_FORM, NGTCP2_PKT_INITIAL, dcid,
                      scid, pkt_num, 4, version, 0);
-  hd.token = (uint8_t *)token;
-  hd.tokenlen = tokenlen;
+  hd.token.base = (uint8_t *)token;
+  hd.token.len = tokenlen;
 
   ngtcp2_ppe_init(&ppe, out, outlen, &cc);
   rv = ngtcp2_ppe_encode_hd(&ppe, &hd);
-- 
GitLab