Skip to content

Commit ce22e08

Browse files
committed
CDRIVER-3806 fix DNS result size comparison (#687)
1 parent 443a68b commit ce22e08

File tree

4 files changed

+49
-7
lines changed

4 files changed

+49
-7
lines changed

src/libmongoc/src/mongoc/mongoc-client-private.h

+2
Original file line numberDiff line numberDiff line change
@@ -155,10 +155,12 @@ typedef struct _mongoc_rr_data_t {
155155
char *txt_record_opts;
156156
} mongoc_rr_data_t;
157157

158+
#define MONGOC_RR_DEFAULT_BUFFER_SIZE 1024
158159
bool
159160
_mongoc_client_get_rr (const char *service,
160161
mongoc_rr_type_t rr_type,
161162
mongoc_rr_data_t *rr_data,
163+
size_t initial_buffer_size,
162164
bson_error_t *error);
163165

164166
mongoc_client_t *

src/libmongoc/src/mongoc/mongoc-client.c

+6-3
Original file line numberDiff line numberDiff line change
@@ -411,14 +411,15 @@ static bool
411411
_mongoc_get_rr_search (const char *service,
412412
mongoc_rr_type_t rr_type,
413413
mongoc_rr_data_t *rr_data,
414+
size_t initial_buffer_size,
414415
bson_error_t *error)
415416
{
416417
#ifdef MONGOC_HAVE_RES_NSEARCH
417418
struct __res_state state = {0};
418419
#endif
419420
int size = 0;
420421
unsigned char *search_buf = NULL;
421-
size_t buffer_size = 1024;
422+
size_t buffer_size = initial_buffer_size;
422423
ns_msg ns_answer;
423424
int n;
424425
int i;
@@ -474,7 +475,7 @@ _mongoc_get_rr_search (const char *service,
474475
service,
475476
strerror (h_errno));
476477
}
477-
} while (size > buffer_size);
478+
} while (size >= buffer_size);
478479

479480
if (ns_initparse (search_buf, size, &ns_answer)) {
480481
DNS_ERROR ("Invalid %s answer for \"%s\"", rr_type_name, service);
@@ -582,12 +583,14 @@ bool
582583
_mongoc_client_get_rr (const char *service,
583584
mongoc_rr_type_t rr_type,
584585
mongoc_rr_data_t *rr_data,
586+
size_t initial_buffer_size,
585587
bson_error_t *error)
586588
{
587589
#ifdef MONGOC_HAVE_DNSAPI
588590
return _mongoc_get_rr_dnsapi (service, rr_type, rr_data, error);
589591
#elif (defined(MONGOC_HAVE_RES_NSEARCH) || defined(MONGOC_HAVE_RES_SEARCH))
590-
return _mongoc_get_rr_search (service, rr_type, rr_data, error);
592+
return _mongoc_get_rr_search (
593+
service, rr_type, rr_data, initial_buffer_size, error);
591594
#else
592595
bson_set_error (error,
593596
MONGOC_ERROR_STREAM,

src/libmongoc/src/mongoc/mongoc-topology.c

+11-4
Original file line numberDiff line numberDiff line change
@@ -340,15 +340,19 @@ mongoc_topology_new (const mongoc_uri_t *uri, bool single_threaded)
340340
if (!_mongoc_client_get_rr (prefixed_service,
341341
MONGOC_RR_SRV,
342342
&rr_data,
343+
MONGOC_RR_DEFAULT_BUFFER_SIZE,
343344
&topology->scanner->error)) {
344345
GOTO (srv_fail);
345346
}
346347

347348
/* Failure to find TXT records will not return an error (since it is only
348349
* for options). But _mongoc_client_get_rr may return an error if
349350
* there is more than one TXT record returned. */
350-
if (!_mongoc_client_get_rr (
351-
service, MONGOC_RR_TXT, &rr_data, &topology->scanner->error)) {
351+
if (!_mongoc_client_get_rr (service,
352+
MONGOC_RR_TXT,
353+
&rr_data,
354+
MONGOC_RR_DEFAULT_BUFFER_SIZE,
355+
&topology->scanner->error)) {
352356
GOTO (srv_fail);
353357
}
354358

@@ -656,8 +660,11 @@ mongoc_topology_rescan_srv (mongoc_topology_t *topology)
656660
/* Unlock topology mutex during scan so it does not hold up other operations.
657661
*/
658662
bson_mutex_unlock (&topology->mutex);
659-
ret = _mongoc_client_get_rr (
660-
prefixed_service, MONGOC_RR_SRV, &rr_data, &topology->scanner->error);
663+
ret = _mongoc_client_get_rr (prefixed_service,
664+
MONGOC_RR_SRV,
665+
&rr_data,
666+
MONGOC_RR_DEFAULT_BUFFER_SIZE,
667+
&topology->scanner->error);
661668
bson_mutex_lock (&topology->mutex);
662669

663670
topology->srv_polling_last_scan_ms = bson_get_monotonic_time () / 1000;

src/libmongoc/tests/test-mongoc-dns.c

+30
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,30 @@ test_srv_polling_mocked (void *unused)
473473
mongoc_uri_destroy (uri);
474474
}
475475

476+
static void
477+
test_small_initial_buffer (void *unused)
478+
{
479+
mongoc_rr_type_t rr_type = MONGOC_RR_SRV;
480+
mongoc_rr_data_t rr_data;
481+
bson_error_t error;
482+
/* Size needs to be large enough to fit DNS answer header to not error, but
483+
* smaller than SRV response to test. The SRV response is 155 bytes. This can
484+
* be determined with: dig -t SRV _mongodb._tcp.test1.test.build.10gen.cc */
485+
size_t small_buffer_size = 30;
486+
487+
memset (&rr_data, 0, sizeof (rr_data));
488+
ASSERT_OR_PRINT (
489+
_mongoc_client_get_rr ("_mongodb._tcp.test1.test.build.10gen.cc",
490+
rr_type,
491+
&rr_data,
492+
small_buffer_size,
493+
&error),
494+
error);
495+
ASSERT_CMPINT (rr_data.count, ==, 2);
496+
bson_free (rr_data.txt_record_opts);
497+
_mongoc_host_list_destroy_all (rr_data.hosts);
498+
}
499+
476500
void
477501
test_dns_install (TestSuite *suite)
478502
{
@@ -485,4 +509,10 @@ test_dns_install (TestSuite *suite)
485509
test_framework_skip_if_no_crypto);
486510
TestSuite_AddFull (
487511
suite, "/srv_polling/mocked", test_srv_polling_mocked, NULL, NULL, NULL);
512+
TestSuite_AddFull (suite,
513+
"/initial_dns_seedlist_discovery/small_initial_buffer",
514+
test_small_initial_buffer,
515+
NULL,
516+
NULL,
517+
test_dns_check);
488518
}

0 commit comments

Comments
 (0)