This is an automated email from the ASF dual-hosted git repository.

kgiusti pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/qpid-dispatch.git


The following commit(s) were added to refs/heads/main by this push:
     new c01b84c  DISPATCH-2308: avoid infinite loop when generating temp 
addresses
c01b84c is described below

commit c01b84c87ace9577a594c98cdf298603dbc4e98f
Author: Kenneth Giusti <kgiu...@apache.org>
AuthorDate: Thu Jan 20 10:38:17 2022 -0500

    DISPATCH-2308: avoid infinite loop when generating temp addresses
    
    This closes #1484
---
 include/qpid/dispatch/discriminator.h              |  4 ++
 src/discriminator.c                                |  4 +-
 .../address_lookup_client/address_lookup_client.c  | 44 ++++++++++++++++------
 3 files changed, 39 insertions(+), 13 deletions(-)

diff --git a/include/qpid/dispatch/discriminator.h 
b/include/qpid/dispatch/discriminator.h
index 8666ffd..077cf81 100644
--- a/include/qpid/dispatch/discriminator.h
+++ b/include/qpid/dispatch/discriminator.h
@@ -20,6 +20,10 @@
  */
 
 
+
+// QD_DISCRIMINATOR_SIZE includes null terminator byte. The
+// strlen() of a discriminator will be 15
+
 #define QD_DISCRIMINATOR_SIZE 16
 
 /**
diff --git a/src/discriminator.c b/src/discriminator.c
index f7406f9..a5ee715 100644
--- a/src/discriminator.c
+++ b/src/discriminator.c
@@ -20,6 +20,8 @@
 #include "qpid/dispatch/discriminator.h"
 
 #include <stdlib.h>
+#include <string.h>
+#include <assert.h>
 
 void qd_generate_discriminator(char *string)
 {
@@ -36,6 +38,6 @@ void qd_generate_discriminator(char *string)
         string[cursor++] = table[(rnd3 >> (idx * 6)) & 63];
     }
     string[cursor] = '\0';
-
+    assert(strlen(string) < QD_DISCRIMINATOR_SIZE);
 }
 
diff --git 
a/src/router_core/modules/address_lookup_client/address_lookup_client.c 
b/src/router_core/modules/address_lookup_client/address_lookup_client.c
index a877e43..dc4b67a 100644
--- a/src/router_core/modules/address_lookup_client/address_lookup_client.c
+++ b/src/router_core/modules/address_lookup_client/address_lookup_client.c
@@ -84,28 +84,47 @@ static char* disambiguated_link_name(qdr_connection_info_t 
*conn, char *original
 
 /**
  * Generate a temporary routable address for a destination connected to this
- * router node.
+ * router node. Caller must free() return value when done.
  */
-static void qdr_generate_temp_addr(qdr_core_t *core, char *buffer, size_t 
length)
+static char *qdr_generate_temp_addr(qdr_core_t *core)
 {
+    static const char edge_template[] = "amqp:/_edge/%s/temp.%s";
+    static const char topo_template[] = "amqp:/_topo/%s/%s/temp.%s";
+    const size_t      max_template    = 19;  // printable chars
     char discriminator[QD_DISCRIMINATOR_SIZE];
+
     qd_generate_discriminator(discriminator);
-    if (core->router_mode == QD_ROUTER_MODE_EDGE)
-        snprintf(buffer, length, "amqp:/_edge/%s/temp.%s", core->router_id, 
discriminator);
-    else
-        snprintf(buffer, length, "amqp:/_topo/%s/%s/temp.%s", 
core->router_area, core->router_id, discriminator);
+    size_t len = max_template + QD_DISCRIMINATOR_SIZE +
+        strlen(core->router_id) + strlen(core->router_area) + 1;
+
+    int rc;
+    char *buffer = qd_malloc(len);
+    if (core->router_mode == QD_ROUTER_MODE_EDGE) {
+        rc = snprintf(buffer, len, edge_template, core->router_id, 
discriminator);
+    } else {
+        rc = snprintf(buffer, len, topo_template, core->router_area, 
core->router_id, discriminator);
+    }
+    (void)rc; assert(rc < len);
+    return buffer;
 }
 
 
 /**
  * Generate a temporary mobile address for a producer connected to this
- * router node.
+ * router node. Caller must free() return value when done.
  */
-static void qdr_generate_mobile_addr(qdr_core_t *core, char *buffer, size_t 
length)
+static char *qdr_generate_mobile_addr(qdr_core_t *core)
 {
+    static const char mobile_template[] = "amqp:/_$temp.%s";
+    const size_t      max_template      = 13; // printable chars
     char discriminator[QD_DISCRIMINATOR_SIZE];
+
     qd_generate_discriminator(discriminator);
-    snprintf(buffer, length, "amqp:/_$temp.%s", discriminator);
+    size_t len = max_template + QD_DISCRIMINATOR_SIZE + 1;
+    char *buffer = qd_malloc(len);
+    int rc = snprintf(buffer, len, mobile_template, discriminator);
+    (void)rc; assert(rc < len);
+    return buffer;
 }
 
 
@@ -182,7 +201,6 @@ static qdr_address_t 
*qdr_lookup_terminus_address_CT(qdr_core_t       *core,
         if (!accept_dynamic)
             return 0;
 
-        char temp_addr[200];
         bool generating = true;
         while (generating) {
             //
@@ -190,10 +208,11 @@ static qdr_address_t 
*qdr_lookup_terminus_address_CT(qdr_core_t       *core,
             // address collides with a previously generated address (this 
should be _highly_
             // unlikely).
             //
+            char *temp_addr = 0;
             if (dir == QD_OUTGOING)
-                qdr_generate_temp_addr(core, temp_addr, 200);
+                temp_addr = qdr_generate_temp_addr(core);
             else
-                qdr_generate_mobile_addr(core, temp_addr, 200);
+                temp_addr = qdr_generate_mobile_addr(core);
 
             qd_iterator_t *temp_iter = qd_iterator_string(temp_addr, 
ITER_VIEW_ADDRESS_HASH);
             qd_hash_retrieve(core->addr_hash, temp_iter, (void**) &addr);
@@ -205,6 +224,7 @@ static qdr_address_t 
*qdr_lookup_terminus_address_CT(qdr_core_t       *core,
                 generating = false;
             }
             qd_iterator_free(temp_iter);
+            free(temp_addr);
         }
         return addr;
     }

---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@qpid.apache.org
For additional commands, e-mail: commits-h...@qpid.apache.org

Reply via email to