Skip to content

Commit d706a68

Browse files
committed
CDRIVER-3653 use handshake metadata for connection checks
- Update change stream wire version check - Update transaction wire version check - Update auth commands to use handshake description to construct commands.
1 parent 68d0948 commit d706a68

20 files changed

+791
-210
lines changed

src/libmongoc/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -983,6 +983,7 @@ set (test-libmongoc-sources
983983
${PROJECT_SOURCE_DIR}/tests/test-mongoc-server-description.c
984984
${PROJECT_SOURCE_DIR}/tests/test-mongoc-server-selection-errors.c
985985
${PROJECT_SOURCE_DIR}/tests/test-mongoc-server-selection.c
986+
${PROJECT_SOURCE_DIR}/tests/test-mongoc-server-stream.c
986987
${PROJECT_SOURCE_DIR}/tests/test-mongoc-set.c
987988
${PROJECT_SOURCE_DIR}/tests/test-mongoc-socket.c
988989
${PROJECT_SOURCE_DIR}/tests/test-mongoc-speculative-auth.c
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
:man_page: mongoc_client_get_handshake_description
2+
3+
mongoc_client_get_handshake_description()
4+
=========================================
5+
6+
Synopsis
7+
--------
8+
9+
.. code-block:: c
10+
11+
mongoc_server_description_t *
12+
mongoc_client_get_handshake_description (mongoc_client_t *client,
13+
uint32_t server_id,
14+
bson_t *opts,
15+
bson_error_t *error);
16+
17+
Returns a description constructed from the initial handshake response to a server.
18+
19+
Description
20+
-----------
21+
22+
:symbol:`mongoc_client_get_handshake_description` is distinct from :symbol:`mongoc_client_get_server_description`. :symbol:`mongoc_client_get_server_description` returns a server description constructed from monitoring, which may differ from the server description constructed from the connection handshake.
23+
24+
:symbol:`mongoc_client_get_handshake_description` does not attempt to establish a connection to the server if a connection was not already established. It will complete authentication on a single-threaded client if the connection has not yet been used by an operation.
25+
26+
To establish a connection on a single-threaded client, ensure the server is selectable (the monitoring connection is the only connection made to the server). This can be done with a function like :symbol:`mongoc_client_select_server`, or any function which performs server selection.
27+
28+
To establish a connection on a pooled client, send a command (e.g. ping) to the server.
29+
30+
Use this function only for building a language driver that wraps the C Driver. When writing applications in C, higher-level functions automatically select a suitable server.
31+
32+
Parameters
33+
----------
34+
35+
* ``client``: A :symbol:`mongoc_client_t`.
36+
* ``server_id``: The ID of the server. This can be obtained from the server description of :symbol:`mongoc_client_select_server`.
37+
* ``opts``: Unused. Pass ``NULL``.
38+
* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``.
39+
40+
Returns
41+
-------
42+
43+
A :symbol:`mongoc_server_description_t` that must be freed with :symbol:`mongoc_server_description_destroy`. If a connection has not been successfully established to a server, returns NULL and ``error`` is filled out.
44+
45+
46+
See Also
47+
--------
48+
49+
- :symbol:`mongoc_client_select_server` To select a server from read preferences.
50+
- :symbol:`mongoc_client_get_server_description` To obtain the server description from monitoring for a server.

src/libmongoc/doc/mongoc_client_t.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ Example
6161
mongoc_client_get_database_names_with_opts
6262
mongoc_client_get_default_database
6363
mongoc_client_get_gridfs
64+
mongoc_client_get_handshake_description
6465
mongoc_client_get_max_bson_size
6566
mongoc_client_get_max_message_size
6667
mongoc_client_get_read_concern

src/libmongoc/src/mongoc/mongoc-change-stream.c

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616

1717
#include <bson/bson.h>
18+
#include "mongoc-cluster-private.h"
1819
#include "mongoc-change-stream-private.h"
1920
#include "mongoc-collection-private.h"
2021
#include "mongoc-client-private.h"
@@ -235,23 +236,12 @@ _make_cursor (mongoc_change_stream_t *stream)
235236
bson_t reply;
236237
bson_t getmore_opts = BSON_INITIALIZER;
237238
bson_iter_t iter;
238-
mongoc_server_description_t *sd;
239-
uint32_t server_id;
239+
mongoc_server_stream_t *server_stream;
240240

241241
BSON_ASSERT (stream);
242242
BSON_ASSERT (!stream->cursor);
243243
bson_init (&command);
244244
bson_copy_to (&(stream->opts.extra), &command_opts);
245-
sd = mongoc_client_select_server (
246-
stream->client, false /* for_writes */, stream->read_prefs, &stream->err);
247-
if (!sd) {
248-
goto cleanup;
249-
}
250-
server_id = mongoc_server_description_id (sd);
251-
bson_append_int32 (&command_opts, "serverId", 8, server_id);
252-
bson_append_int32 (&getmore_opts, "serverId", 8, server_id);
253-
stream->max_wire_version = sd->max_wire_version;
254-
mongoc_server_description_destroy (sd);
255245

256246
if (bson_iter_init_find (&iter, &command_opts, "sessionId")) {
257247
if (!_mongoc_client_session_from_iter (
@@ -289,6 +279,19 @@ _make_cursor (mongoc_change_stream_t *stream)
289279
goto cleanup;
290280
}
291281

282+
server_stream = mongoc_cluster_stream_for_reads (
283+
&stream->client->cluster, stream->read_prefs, cs, &reply, &stream->err);
284+
if (!server_stream) {
285+
bson_destroy (&stream->err_doc);
286+
bson_copy_to (&reply, &stream->err_doc);
287+
bson_destroy (&reply);
288+
goto cleanup;
289+
}
290+
bson_append_int32 (&command_opts, "serverId", 8, server_stream->sd->id);
291+
bson_append_int32 (&getmore_opts, "serverId", 8, server_stream->sd->id);
292+
stream->max_wire_version = server_stream->sd->max_wire_version;
293+
mongoc_server_stream_cleanup (server_stream);
294+
292295
if (stream->read_concern && !bson_has_field (&command_opts, "readConcern")) {
293296
mongoc_read_concern_append (stream->read_concern, &command_opts);
294297
}

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

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717

1818
#include "mongoc-client-session-private.h"
19+
#include "mongoc-cluster-private.h"
1920
#include "mongoc-trace-private.h"
2021
#include "mongoc-client-private.h"
2122
#include "mongoc-rand-private.h"
@@ -1110,16 +1111,16 @@ mongoc_client_session_start_transaction (mongoc_client_session_t *session,
11101111
const mongoc_transaction_opt_t *opts,
11111112
bson_error_t *error)
11121113
{
1113-
mongoc_server_description_t *sd;
1114+
mongoc_server_stream_t *server_stream = NULL;
11141115
bool ret;
11151116

11161117
ENTRY;
11171118
BSON_ASSERT (session);
11181119

11191120
ret = true;
1120-
sd = mongoc_client_select_server (
1121-
session->client, true /* primary */, NULL, error);
1122-
if (!sd) {
1121+
server_stream = mongoc_cluster_stream_for_writes (
1122+
&session->client->cluster, session, NULL /* reply */, error);
1123+
if (!server_stream) {
11231124
ret = false;
11241125
GOTO (done);
11251126
}
@@ -1133,8 +1134,9 @@ mongoc_client_session_start_transaction (mongoc_client_session_t *session,
11331134
GOTO (done);
11341135
}
11351136

1136-
if (sd->max_wire_version < 7 ||
1137-
(sd->max_wire_version < 8 && sd->type == MONGOC_SERVER_MONGOS)) {
1137+
if (server_stream->sd->max_wire_version < 7 ||
1138+
(server_stream->sd->max_wire_version < 8 &&
1139+
server_stream->sd->type == MONGOC_SERVER_MONGOS)) {
11381140
bson_set_error (error,
11391141
MONGOC_ERROR_TRANSACTION,
11401142
MONGOC_ERROR_TRANSACTION_INVALID_STATE,
@@ -1204,7 +1206,7 @@ mongoc_client_session_start_transaction (mongoc_client_session_t *session,
12041206
session->recovery_token = NULL;
12051207

12061208
done:
1207-
mongoc_server_description_destroy (sd);
1209+
mongoc_server_stream_cleanup (server_stream);
12081210
return ret;
12091211
}
12101212

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

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3142,3 +3142,27 @@ mongoc_client_set_server_api (mongoc_client_t *client,
31423142
bson_mutex_unlock (&client->topology->mutex);
31433143
return true;
31443144
}
3145+
3146+
mongoc_server_description_t *
3147+
mongoc_client_get_handshake_description (mongoc_client_t *client,
3148+
uint32_t server_id,
3149+
bson_t *opts,
3150+
bson_error_t *error)
3151+
{
3152+
mongoc_server_stream_t *server_stream;
3153+
mongoc_server_description_t *sd;
3154+
3155+
server_stream = mongoc_cluster_stream_for_server (&client->cluster,
3156+
server_id,
3157+
false /* reconnect */,
3158+
NULL /* client session */,
3159+
NULL /* reply */,
3160+
error);
3161+
if (!server_stream) {
3162+
return NULL;
3163+
}
3164+
3165+
sd = mongoc_server_description_new_copy (server_stream->sd);
3166+
mongoc_server_stream_cleanup (server_stream);
3167+
return sd;
3168+
}

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,12 @@ mongoc_client_set_server_api (mongoc_client_t *client,
274274
const mongoc_server_api_t *api,
275275
bson_error_t *error);
276276

277+
MONGOC_EXPORT (mongoc_server_description_t *)
278+
mongoc_client_get_handshake_description (mongoc_client_t *client,
279+
uint32_t server_id,
280+
bson_t *opts,
281+
bson_error_t *error);
282+
277283
BSON_END_DECLS
278284

279285

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ _run_command (mongoc_cluster_t *cluster,
7070
/* Drivers must not append session ids to auth commands per sessions spec. */
7171
parts.prohibit_lsid = true;
7272
server_stream = _mongoc_cluster_create_server_stream (
73-
cluster->client->topology, sd->id, stream, error);
73+
cluster->client->topology, sd, stream, error);
7474
if (!server_stream) {
7575
/* error was set by mongoc_topology_description_server_by_id */
7676
bson_init (reply);

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ _mongoc_cluster_auth_node_cyrus (mongoc_cluster_t *cluster,
8383
TRACE ("SASL: authenticating (step %d)", sasl.step);
8484

8585
server_stream = _mongoc_cluster_create_server_stream (
86-
cluster->client->topology, sd->id, stream, error);
86+
cluster->client->topology, sd, stream, error);
8787

8888
if (!server_stream) {
8989
bson_destroy (&cmd);

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

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,8 @@ typedef struct _mongoc_cluster_node_t {
4545
mongoc_stream_t *stream;
4646
char *connection_address;
4747
uint32_t generation;
48-
49-
/* TODO CDRIVER-3653, these fields are unused. */
50-
int32_t max_wire_version;
51-
int32_t min_wire_version;
52-
int32_t max_write_batch_size;
53-
int32_t max_bson_obj_size;
54-
int32_t max_msg_size;
48+
/* handshake_sd is a server description created from the handshake on the stream. */
49+
mongoc_server_description_t *handshake_sd;
5550
} mongoc_cluster_node_t;
5651

5752
typedef struct _mongoc_cluster_t {
@@ -172,7 +167,7 @@ _mongoc_cluster_get_conversation_id (const bson_t *reply);
172167

173168
mongoc_server_stream_t *
174169
_mongoc_cluster_create_server_stream (mongoc_topology_t *topology,
175-
uint32_t server_id,
170+
const mongoc_server_description_t *sd,
176171
mongoc_stream_t *stream,
177172
bson_error_t *error /* OUT */);
178173

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ _mongoc_cluster_auth_node_sspi (mongoc_cluster_t *cluster,
223223
}
224224

225225
server_stream = _mongoc_cluster_create_server_stream (
226-
cluster->client->topology, sd->id, stream, error);
226+
cluster->client->topology, sd, stream, error);
227227

228228
if (!server_stream ||
229229
!mongoc_cmd_parts_assemble (&parts, server_stream, error)) {

0 commit comments

Comments
 (0)