From 525ca2fd04d8f982032b30cfde7133f9a8066a73 Mon Sep 17 00:00:00 2001
From: huitema <huitema@huitema.net>
Date: Mon, 17 Dec 2018 18:15:12 -0800
Subject: [PATCH] Keep count of published CNXID

---
 picoquic/frames.c            | 10 ++++++++--
 picoquic/packet.c            | 14 ++++++++------
 picoquic/picoquic_internal.h |  1 +
 picoquic/quicctx.c           |  2 ++
 picoquic/sender.c            |  6 +++++-
 5 files changed, 24 insertions(+), 9 deletions(-)

diff --git a/picoquic/frames.c b/picoquic/frames.c
index e1184583..b0564139 100644
--- a/picoquic/frames.c
+++ b/picoquic/frames.c
@@ -569,14 +569,20 @@ uint8_t* picoquic_decode_retire_connection_id_frame(picoquic_cnx_t* cnx, uint8_t
     }
     else {
         /* Go through the list of paths to find the connection ID */
+        int nb_demoted = 0;
 
         for (int i = 0; i < cnx->nb_paths; i++) {
-            if (cnx->path[i]->path_sequence == sequence) {
+            if (cnx->path[i]->path_sequence == sequence &&
+                cnx->path[i]->path_is_activated == 0){
                 /* Mark the corresponding path as demoted */
                 picoquic_demote_path(cnx, i, current_time);
-                break;
+                nb_demoted++;
             }
         }
+
+        if (nb_demoted != 0 && cnx->nb_cnxid_published > 0) {
+            cnx->nb_cnxid_published--;
+        }
     }
 
     return bytes;
diff --git a/picoquic/packet.c b/picoquic/packet.c
index 2ca8703e..ab235843 100644
--- a/picoquic/packet.c
+++ b/picoquic/packet.c
@@ -1206,21 +1206,23 @@ int picoquic_incoming_0rtt(
 
 /*
  * Find path of incoming encrypted packet. (This code is not used during the
- * handshake, or if the conenction is closing.)
+ * handshake, or if the connection is closing.)
  *
  * Check whether this matches a path defined by Local & Remote Addr, Local CNXID:
  *  - if local CID length > 0 and does not match: no match;
  *  - if local addr defined and does not match: no match;
  *  - if peer addr defined and does not match: no match.
+ * Keep the "best match", if local cid match and local addr match.
  *
- * If no path matches: new path. Check whether the addresses match a pending probe.
+ * If no path matches: new path. Check pathological conditions, such as
+ * too many open paths.
+ * Check whether the addresses match a pending probe.
  * If they do, merge probe, retain probe's CID as dest CID. If they don't, get CID
  * from stash or use null CID if peer uses null CID; initiated required probing. If
- * no CID available, accept packet but no not create a path.
+ * no CID available, reuse CID from best match.
+ * Ask verification of new path.
  *
- * If path matched: existing path. If peer address changed: NAT rebinding. If
- * source address changed: if undef, update; else NAT rebinding. If NAT rebinding:
- * change the probe secret; mark probe as required.
+ * If there is a best match: ask verification on best match.
  */
 
 int picoquic_find_incoming_path(picoquic_cnx_t* cnx, picoquic_packet_header * ph,
diff --git a/picoquic/picoquic_internal.h b/picoquic/picoquic_internal.h
index c994ab53..ab175953 100644
--- a/picoquic/picoquic_internal.h
+++ b/picoquic/picoquic_internal.h
@@ -731,6 +731,7 @@ typedef struct st_picoquic_cnx_t {
     int nb_paths;
     int nb_path_alloc;
     int path_sequence_next;
+    int nb_cnxid_published;
     /* Management of the CNX-ID stash */
     picoquic_cnxid_stash_t * cnxid_stash_first;
     /* Management of ongoing probes */
diff --git a/picoquic/quicctx.c b/picoquic/quicctx.c
index 6e1ac741..daf56098 100644
--- a/picoquic/quicctx.c
+++ b/picoquic/quicctx.c
@@ -1493,6 +1493,8 @@ picoquic_cnx_t* picoquic_create_cnx(picoquic_quic_t* quic,
         picoquic_register_path(cnx, cnx->path[0]);
 
         picoquic_open_cc_dump(cnx);
+
+        cnx->nb_cnxid_published = 1;
     }
 
     return cnx;
diff --git a/picoquic/sender.c b/picoquic/sender.c
index d6e89160..68486f03 100644
--- a/picoquic/sender.c
+++ b/picoquic/sender.c
@@ -2003,6 +2003,10 @@ int picoquic_prepare_new_path_and_id(picoquic_cnx_t* cnx, uint8_t* bytes, size_t
         *consumed = 0;
     }
 
+    if (ret == 0) {
+        cnx->nb_cnxid_published++;
+    }
+
     return ret;
 }
 
@@ -2204,7 +2208,7 @@ int picoquic_prepare_packet_ready(picoquic_cnx_t* cnx, picoquic_path_t * path_x,
                     /* If there are not enough paths, create and advertise */
                     while (ret == 0 && cnx->remote_parameters.migration_disabled == 0 &&
                         cnx->local_parameters.migration_disabled == 0 &&
-                        cnx->nb_paths < PICOQUIC_NB_PATH_TARGET) {
+                        cnx->nb_cnxid_published < PICOQUIC_NB_PATH_TARGET) {
                         ret = picoquic_prepare_new_path_and_id(cnx, &bytes[length],
                             send_buffer_min_max - checksum_overhead - length,
                             current_time, &data_bytes);
-- 
GitLab