From b2268957c2b00cdd271e8266bdf00021e421f5a5 Mon Sep 17 00:00:00 2001
From: Amir Livneh <alivneh@fb.com>
Date: Mon, 4 Nov 2019 23:24:35 -0500
Subject: [PATCH] Fix condition checking for Initial packet

The code previously determined whether a packet was an Initial packet by looking at its type value, without first checking it was not a Version Negotiation packet. In the case of a Version Negotiation packet, reading the type value returned the random value in the Unused field. This occasionally caused Version Negotiation packets to be misinterpreted as Initial packets. When this happened, ngtcp2_conn_read_pkt() returned NGTCP2_ERR_DRAINING instead of NGTCP2_ERR_RECV_VERSION_NEGOTIATION.
---
 lib/ngtcp2_conn.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/lib/ngtcp2_conn.c b/lib/ngtcp2_conn.c
index 65aaedde..f2e20bb9 100644
--- a/lib/ngtcp2_conn.c
+++ b/lib/ngtcp2_conn.c
@@ -4702,7 +4702,11 @@ static int conn_recv_handshake_cpkt(ngtcp2_conn *conn, const ngtcp2_path *path,
       if (nread == NGTCP2_ERR_DISCARD_PKT) {
         goto fin;
       }
-      if (nread != NGTCP2_ERR_CRYPTO && (pkt[0] & NGTCP2_HEADER_FORM_BIT) &&
+      if (nread != NGTCP2_ERR_CRYPTO &&
+          (pkt[0] & NGTCP2_HEADER_FORM_BIT) &&
+          /* Not a Version Negotiation packet */
+          pktlen > 4 &&
+          ngtcp2_get_uint32(&pkt[1]) > 0 &&
           ngtcp2_pkt_get_type_long(pkt[0]) == NGTCP2_PKT_INITIAL) {
         goto fin;
       }
-- 
GitLab