Deal with path validation when zero-length CID is used
@@ -3754,6 +3754,8 @@ static int conn_retire_dcid(ngtcp2_conn *conn, const ngtcp2_dcid *dcid,
ngtcp2_dcid *dest, *stale_dcid;
int rv;
+ assert(dcid->cid.datalen);
+
if (ngtcp2_ringbuf_full(rb)) {
stale_dcid = ngtcp2_ringbuf_get(rb, 0);
rv = conn_call_deactivate_dcid(conn, stale_dcid);
@@ -3774,7 +3776,8 @@ static int conn_retire_dcid(ngtcp2_conn *conn, const ngtcp2_dcid *dcid,
/*
* conn_bind_dcid stores the DCID to |*pdcid| bound to |path|. If
* such DCID is not found, bind the new DCID to |path| and stores it
- * to |*pdcid|.
+ * to |*pdcid|. If a remote endpoint uses zero-length connection ID,
+ * the pointer to conn->dcid.current is assigned to |*pdcid|.
*
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
@@ -3796,6 +3799,11 @@ static int conn_bind_dcid(ngtcp2_conn *conn, ngtcp2_dcid **pdcid,
assert(!pv || !(pv->flags & NGTCP2_PV_FLAG_FALLBACK_ON_FAILURE) ||
!ngtcp2_path_eq(&pv->fallback_dcid.ps.path, path));
+ if (conn->dcid.current.cid.datalen == 0) {
+ *pdcid = &conn->dcid.current;
+ return 0;
+ }
+
len = ngtcp2_ringbuf_len(&conn->dcid.bound);
for (i = 0; i < len; ++i) {
dcid = ngtcp2_ringbuf_get(&conn->dcid.bound, i);
@@ -4823,6 +4831,8 @@ static int conn_recv_path_response(ngtcp2_conn *conn, ngtcp2_path_response *fr,
}
if (!(pv->flags & NGTCP2_PV_FLAG_FALLBACK_ON_FAILURE)) {
+ assert(conn->dcid.current.cid.datalen);
+
rv = conn_retire_dcid(conn, &conn->dcid.current, ts);
if (rv != 0) {
goto fail;
@@ -7072,6 +7082,9 @@ static int conn_recv_non_probing_pkt_on_new_path(ngtcp2_conn *conn,
timeout = 3 * conn_compute_pto(conn, &conn->pktns);
timeout = ngtcp2_max(timeout, 6 * conn->cstat.initial_rtt);
+ if (conn->dcid.current.cid.datalen == 0) {
+ ngtcp2_dcid_copy(&dcid, &conn->dcid.current);
+ } else {
len = ngtcp2_ringbuf_len(&conn->dcid.bound);
for (i = 0; i < len; ++i) {
@@ -7119,6 +7132,7 @@ static int conn_recv_non_probing_pkt_on_new_path(ngtcp2_conn *conn,
ngtcp2_dcid_copy(&dcid, &conn->dcid.current);
}
}
+ }
ngtcp2_path_copy(&dcid.ps.path, path);
