Skip to content

Commit 626d844

Browse files
committed
add serviceId to server description; reject non load balanced connections
1 parent 5aa6a73 commit 626d844

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
@@ -2281,6 +2281,24 @@ _mongoc_cluster_stream_for_server (mongoc_cluster_t *cluster,
22812281
}
22822282

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

22852303
RETURN (server_stream);
22862304
}

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
/*
@@ -723,8 +724,11 @@ mongoc_server_description_handle_hello (mongoc_server_description_t *sd,
723724
mongoc_server_description_set_topology_version (
724725
sd, &incoming_topology_version);
725726
bson_destroy (&incoming_topology_version);
727+
} else if (strcmp ("serviceId", bson_iter_key (&iter)) == 0) {
728+
if (!BSON_ITER_HOLDS_OID (&iter))
729+
goto failure;
730+
bson_oid_copy_unsafe (bson_iter_oid (&iter), &sd->service_id);
726731
}
727-
// LBTODO: process serviceID
728732
}
729733

730734
if (is_shard) {
@@ -799,6 +803,7 @@ mongoc_server_description_new_copy (
799803
bson_init (&copy->tags);
800804
bson_init (&copy->compressors);
801805
bson_copy_to (&description->topology_version, &copy->topology_version);
806+
bson_oid_copy (&description->service_id, &copy->service_id);
802807

803808
if (description->has_hello_response) {
804809
/* calls mongoc_server_description_reset */
@@ -1243,7 +1248,11 @@ mongoc_server_description_set_topology_version (mongoc_server_description_t *sd,
12431248

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

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
}
@@ -1402,4 +1404,4 @@ void
14021404
_mongoc_topology_scanner_set_loadbalanced (mongoc_topology_scanner_t *ts, bool val) {
14031405
BSON_ASSERT (bson_empty (&ts->handshake_cmd));
14041406
ts->loadbalanced = true;
1405-
}
1407+
}

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

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

444444
/* Tests:
445445
* - loadBalanced: true is added to the handshake
446-
* - serviceID is set in the server description.
446+
* - serviceId is set in the server description.
447447
*/
448448
#define LB_HELLO \
449-
"{'ismaster': true, 'maxWireVersion': 13, 'msg': 'isdbgrid', 'serviceID', " \
449+
"{'ismaster': true, 'maxWireVersion': 13, 'msg': 'isdbgrid', 'serviceId': " \
450450
"{'$oid': 'AAAAAAAAAAAAAAAAAAAAAAAA'}}"
451451
static void
452452
test_loadbalanced_handshake_sends_loadbalanced (void)
@@ -464,6 +464,7 @@ test_loadbalanced_handshake_sends_loadbalanced (void)
464464

465465
server = mock_server_new ();
466466
mock_server_run (server);
467+
mock_server_auto_endsessions (server);
467468
uri = mongoc_uri_copy (mock_server_get_uri (server));
468469
mongoc_uri_set_option_as_bool (uri, MONGOC_URI_LOADBALANCED, true);
469470
client = mongoc_client_new_from_uri (uri);
@@ -519,6 +520,7 @@ test_loadbalanced_handshake_rejects_non_loadbalanced (void)
519520

520521
server = mock_server_new ();
521522
mock_server_run (server);
523+
mock_server_auto_endsessions (server);
522524
uri = mongoc_uri_copy (mock_server_get_uri (server));
523525
mongoc_uri_set_option_as_bool (uri, MONGOC_URI_LOADBALANCED, true);
524526
client = mongoc_client_new_from_uri (uri);
@@ -538,7 +540,7 @@ test_loadbalanced_handshake_rejects_non_loadbalanced (void)
538540

539541
ASSERT_ERROR_CONTAINS (error,
540542
MONGOC_ERROR_CLIENT,
541-
123,
543+
MONGOC_ERROR_CLIENT_INVALID_LOAD_BALANCER,
542544
"Driver attempted to initialize in load balancing "
543545
"mode, but the server does not support this mode");
544546

0 commit comments

Comments
 (0)