Skip to content

Commit c01b84c

Browse files
committed
DISPATCH-2308: avoid infinite loop when generating temp addresses
This closes #1484
1 parent 51fb44a commit c01b84c

File tree

3 files changed

+39
-13
lines changed

3 files changed

+39
-13
lines changed

include/qpid/dispatch/discriminator.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@
2020
*/
2121

2222

23+
24+
// QD_DISCRIMINATOR_SIZE includes null terminator byte. The
25+
// strlen() of a discriminator will be 15
26+
2327
#define QD_DISCRIMINATOR_SIZE 16
2428

2529
/**

src/discriminator.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
#include "qpid/dispatch/discriminator.h"
2121

2222
#include <stdlib.h>
23+
#include <string.h>
24+
#include <assert.h>
2325

2426
void qd_generate_discriminator(char *string)
2527
{
@@ -36,6 +38,6 @@ void qd_generate_discriminator(char *string)
3638
string[cursor++] = table[(rnd3 >> (idx * 6)) & 63];
3739
}
3840
string[cursor] = '\0';
39-
41+
assert(strlen(string) < QD_DISCRIMINATOR_SIZE);
4042
}
4143

src/router_core/modules/address_lookup_client/address_lookup_client.c

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -84,28 +84,47 @@ static char* disambiguated_link_name(qdr_connection_info_t *conn, char *original
8484

8585
/**
8686
* Generate a temporary routable address for a destination connected to this
87-
* router node.
87+
* router node. Caller must free() return value when done.
8888
*/
89-
static void qdr_generate_temp_addr(qdr_core_t *core, char *buffer, size_t length)
89+
static char *qdr_generate_temp_addr(qdr_core_t *core)
9090
{
91+
static const char edge_template[] = "amqp:/_edge/%s/temp.%s";
92+
static const char topo_template[] = "amqp:/_topo/%s/%s/temp.%s";
93+
const size_t max_template = 19; // printable chars
9194
char discriminator[QD_DISCRIMINATOR_SIZE];
95+
9296
qd_generate_discriminator(discriminator);
93-
if (core->router_mode == QD_ROUTER_MODE_EDGE)
94-
snprintf(buffer, length, "amqp:/_edge/%s/temp.%s", core->router_id, discriminator);
95-
else
96-
snprintf(buffer, length, "amqp:/_topo/%s/%s/temp.%s", core->router_area, core->router_id, discriminator);
97+
size_t len = max_template + QD_DISCRIMINATOR_SIZE +
98+
strlen(core->router_id) + strlen(core->router_area) + 1;
99+
100+
int rc;
101+
char *buffer = qd_malloc(len);
102+
if (core->router_mode == QD_ROUTER_MODE_EDGE) {
103+
rc = snprintf(buffer, len, edge_template, core->router_id, discriminator);
104+
} else {
105+
rc = snprintf(buffer, len, topo_template, core->router_area, core->router_id, discriminator);
106+
}
107+
(void)rc; assert(rc < len);
108+
return buffer;
97109
}
98110

99111

100112
/**
101113
* Generate a temporary mobile address for a producer connected to this
102-
* router node.
114+
* router node. Caller must free() return value when done.
103115
*/
104-
static void qdr_generate_mobile_addr(qdr_core_t *core, char *buffer, size_t length)
116+
static char *qdr_generate_mobile_addr(qdr_core_t *core)
105117
{
118+
static const char mobile_template[] = "amqp:/_$temp.%s";
119+
const size_t max_template = 13; // printable chars
106120
char discriminator[QD_DISCRIMINATOR_SIZE];
121+
107122
qd_generate_discriminator(discriminator);
108-
snprintf(buffer, length, "amqp:/_$temp.%s", discriminator);
123+
size_t len = max_template + QD_DISCRIMINATOR_SIZE + 1;
124+
char *buffer = qd_malloc(len);
125+
int rc = snprintf(buffer, len, mobile_template, discriminator);
126+
(void)rc; assert(rc < len);
127+
return buffer;
109128
}
110129

111130

@@ -182,18 +201,18 @@ static qdr_address_t *qdr_lookup_terminus_address_CT(qdr_core_t *core,
182201
if (!accept_dynamic)
183202
return 0;
184203

185-
char temp_addr[200];
186204
bool generating = true;
187205
while (generating) {
188206
//
189207
// The address-generation process is performed in a loop in case the generated
190208
// address collides with a previously generated address (this should be _highly_
191209
// unlikely).
192210
//
211+
char *temp_addr = 0;
193212
if (dir == QD_OUTGOING)
194-
qdr_generate_temp_addr(core, temp_addr, 200);
213+
temp_addr = qdr_generate_temp_addr(core);
195214
else
196-
qdr_generate_mobile_addr(core, temp_addr, 200);
215+
temp_addr = qdr_generate_mobile_addr(core);
197216

198217
qd_iterator_t *temp_iter = qd_iterator_string(temp_addr, ITER_VIEW_ADDRESS_HASH);
199218
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,
205224
generating = false;
206225
}
207226
qd_iterator_free(temp_iter);
227+
free(temp_addr);
208228
}
209229
return addr;
210230
}

0 commit comments

Comments
 (0)