Skip to content

Commit 35ceb5c

Browse files
committed
add serviceId to server description; reject non load balanced connections
1 parent e165275 commit 35ceb5c

9 files changed

+54
-16
lines changed

src/libmongoc/doc/errors.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ Many C Driver functions report errors by returning ``false`` or -1 and filling o
3131
+-----------------------------------------+---------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
3232
| | ``MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_STATE`` | Failure related to Client-Side Field Level Encryption. |
3333
+-----------------------------------------+---------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
34+
| | ``MONGOC_ERROR_CLIENT_INVALID_LOAD_BALANCER`` | You attempted to connect to a MongoDB server behind a load balancer, but the server does not advertise load balanced support. |
35+
+-----------------------------------------+---------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
3436
| ``MONGOC_ERROR_STREAM`` | ``MONGOC_ERROR_STREAM_NAME_RESOLUTION`` | DNS failure. |
3537
+-----------------------------------------+---------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
3638
| | ``MONGOC_ERROR_STREAM_SOCKET`` | Timeout communicating with server, or connection closed. |

src/libmongoc/src/mongoc/mongoc-cluster.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2282,6 +2282,24 @@ _mongoc_cluster_stream_for_server (mongoc_cluster_t *cluster,
22822282
}
22832283

22842284
// LBTODO: if this is a load balanced topology and the server stream does not have a service id, disconnect and return an error.
2285+
bson_mutex_lock (&topology->mutex);
2286+
if (topology->description.type == MONGOC_TOPOLOGY_LOAD_BALANCED) {
2287+
bson_oid_t service_id;
2288+
2289+
if (!mongoc_server_description_service_id (server_stream->sd,
2290+
&service_id)) {
2291+
bson_set_error (error,
2292+
MONGOC_ERROR_CLIENT,
2293+
MONGOC_ERROR_CLIENT_INVALID_LOAD_BALANCER,
2294+
"Driver attempted to initialize in load balancing "
2295+
"mode, but the server does not support this mode.");
2296+
mongoc_server_stream_cleanup (server_stream);
2297+
mongoc_cluster_disconnect_node (cluster, server_id);
2298+
bson_mutex_unlock (&topology->mutex);
2299+
return NULL;
2300+
}
2301+
}
2302+
bson_mutex_unlock (&topology->mutex);
22852303

22862304
RETURN (server_stream);
22872305
}

src/libmongoc/src/mongoc/mongoc-error.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,9 @@ typedef enum {
131131
MONGOC_ERROR_CLIENT_API_ALREADY_SET,
132132
MONGOC_ERROR_CLIENT_API_FROM_POOL,
133133
MONGOC_ERROR_POOL_API_ALREADY_SET,
134-
MONGOC_ERROR_POOL_API_TOO_LATE
134+
MONGOC_ERROR_POOL_API_TOO_LATE,
135+
136+
MONGOC_ERROR_CLIENT_INVALID_LOAD_BALANCER,
135137
} mongoc_error_code_t;
136138

137139
MONGOC_EXPORT (bool)

src/libmongoc/src/mongoc/mongoc-server-description-private.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ struct _mongoc_server_description_t {
112112
pre-4.2 server.
113113
*/
114114
uint32_t generation;
115+
bson_oid_t service_id;
115116
};
116117

117118
void
@@ -183,4 +184,10 @@ void
183184
mongoc_server_description_set_topology_version (mongoc_server_description_t *sd,
184185
const bson_t *tv);
185186

187+
/* If a service_id is set on the topology description, copies it to @oid and returns true.
188+
* Otherwise returns false and zeros out oid.
189+
*/
190+
bool
191+
mongoc_server_description_service_id (const mongoc_server_description_t *description, bson_oid_t *oid);
192+
186193
#endif

src/libmongoc/src/mongoc/mongoc-server-description.c

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ mongoc_server_description_reset (mongoc_server_description_t *sd)
9292
sd->current_primary = NULL;
9393
sd->set_version = MONGOC_NO_SET_VERSION;
9494
bson_oid_copy_unsafe (&kObjectIdZero, &sd->election_id);
95+
bson_oid_copy_unsafe (&kObjectIdZero, &sd->service_id);
9596
}
9697

9798
/*
@@ -722,8 +723,11 @@ mongoc_server_description_handle_hello (mongoc_server_description_t *sd,
722723
mongoc_server_description_set_topology_version (
723724
sd, &incoming_topology_version);
724725
bson_destroy (&incoming_topology_version);
726+
} else if (strcmp ("serviceId", bson_iter_key (&iter)) == 0) {
727+
if (!BSON_ITER_HOLDS_OID (&iter))
728+
goto failure;
729+
bson_oid_copy_unsafe (bson_iter_oid (&iter), &sd->service_id);
725730
}
726-
// LBTODO: process serviceID
727731
}
728732

729733
if (is_shard) {
@@ -798,6 +802,7 @@ mongoc_server_description_new_copy (
798802
bson_init (&copy->tags);
799803
bson_init (&copy->compressors);
800804
bson_copy_to (&description->topology_version, &copy->topology_version);
805+
bson_oid_copy (&description->service_id, &copy->service_id);
801806

802807
if (description->has_hello_response) {
803808
/* calls mongoc_server_description_reset */
@@ -1242,7 +1247,11 @@ mongoc_server_description_set_topology_version (mongoc_server_description_t *sd,
12421247

12431248
bool
12441249
mongoc_server_description_service_id (const mongoc_server_description_t *description, bson_oid_t *oid) {
1245-
// LBTODO
1246-
memset (oid, 0, sizeof (bson_oid_t));
1247-
return false;
1250+
bson_oid_copy (&description->service_id, oid);
1251+
1252+
if (0 == bson_oid_compare (oid, &kObjectIdZero)) {
1253+
/* serviceID is unset. */
1254+
return false;
1255+
}
1256+
return true;
12481257
}

src/libmongoc/src/mongoc/mongoc-server-description.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,6 @@ MONGOC_EXPORT (int32_t)
6666
mongoc_server_description_compressor_id (
6767
const mongoc_server_description_t *description);
6868

69-
// LBTODO
70-
MONGOC_EXPORT (bool)
71-
mongoc_server_description_service_id (const mongoc_server_description_t *description, bson_oid_t *oid);
72-
7369
BSON_END_DECLS
7470

7571
#endif

src/libmongoc/src/mongoc/mongoc-topology-scanner-private.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,6 @@ typedef struct mongoc_topology_scanner_node {
8383
/* handshake_sd is a server description constructed from the response of the
8484
* initial handshake. It is bound to the lifetime of stream. */
8585
mongoc_server_description_t *handshake_sd;
86-
bool loadbalanced;
8786
} mongoc_topology_scanner_node_t;
8887

8988
typedef struct mongoc_topology_scanner {
@@ -119,6 +118,7 @@ typedef struct mongoc_topology_scanner {
119118
bool speculative_authentication;
120119

121120
mongoc_server_api_t *api;
121+
bool loadbalanced;
122122
} mongoc_topology_scanner_t;
123123

124124
mongoc_topology_scanner_t *

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

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -260,8 +260,6 @@ _build_handshake_cmd (mongoc_topology_scanner_t *ts)
260260
bson_destroy (doc);
261261
bson_copy_to (ts->api ? &ts->hello_cmd : &ts->legacy_hello_cmd, doc);
262262

263-
// LBTODO: if ts->loadbalanced, append loadBalanced: true
264-
265263
BSON_APPEND_DOCUMENT_BEGIN (doc, HANDSHAKE_FIELD, &subdoc);
266264
res = _mongoc_handshake_build_doc_with_application (&subdoc, ts->appname);
267265
bson_append_document_end (doc, &subdoc);
@@ -280,6 +278,10 @@ _build_handshake_cmd (mongoc_topology_scanner_t *ts)
280278
}
281279
bson_append_array_end (doc, &subdoc);
282280

281+
if (ts->loadbalanced) {
282+
BSON_APPEND_BOOL (doc, "loadBalanced", true);
283+
}
284+
283285
/* Return whether the handshake doc fit the size limit */
284286
return res;
285287
}
@@ -1406,4 +1408,4 @@ void
14061408
_mongoc_topology_scanner_set_loadbalanced (mongoc_topology_scanner_t *ts, bool val) {
14071409
BSON_ASSERT (bson_empty (&ts->handshake_cmd));
14081410
ts->loadbalanced = true;
1409-
}
1411+
}

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

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -439,10 +439,10 @@ test_loadbalanced_cooldown_is_bypassed_single (void *unused)
439439

440440
/* Tests:
441441
* - loadBalanced: true is added to the handshake
442-
* - serviceID is set in the server description.
442+
* - serviceId is set in the server description.
443443
*/
444444
#define LB_HELLO \
445-
"{'ismaster': true, 'maxWireVersion': 13, 'msg': 'isdbgrid', 'serviceID', " \
445+
"{'ismaster': true, 'maxWireVersion': 13, 'msg': 'isdbgrid', 'serviceId': " \
446446
"{'$oid': 'AAAAAAAAAAAAAAAAAAAAAAAA'}}"
447447
static void
448448
test_loadbalanced_handshake_sends_loadbalanced (void)
@@ -460,6 +460,7 @@ test_loadbalanced_handshake_sends_loadbalanced (void)
460460

461461
server = mock_server_new ();
462462
mock_server_run (server);
463+
mock_server_auto_endsessions (server);
463464
uri = mongoc_uri_copy (mock_server_get_uri (server));
464465
mongoc_uri_set_option_as_bool (uri, MONGOC_URI_LOADBALANCED, true);
465466
client = mongoc_client_new_from_uri (uri);
@@ -515,6 +516,7 @@ test_loadbalanced_handshake_rejects_non_loadbalanced (void)
515516

516517
server = mock_server_new ();
517518
mock_server_run (server);
519+
mock_server_auto_endsessions (server);
518520
uri = mongoc_uri_copy (mock_server_get_uri (server));
519521
mongoc_uri_set_option_as_bool (uri, MONGOC_URI_LOADBALANCED, true);
520522
client = mongoc_client_new_from_uri (uri);
@@ -534,7 +536,7 @@ test_loadbalanced_handshake_rejects_non_loadbalanced (void)
534536

535537
ASSERT_ERROR_CONTAINS (error,
536538
MONGOC_ERROR_CLIENT,
537-
123,
539+
MONGOC_ERROR_CLIENT_INVALID_LOAD_BALANCER,
538540
"Driver attempted to initialize in load balancing "
539541
"mode, but the server does not support this mode");
540542

0 commit comments

Comments
 (0)