Details
-
Bug
-
Resolution: Done
-
Blocker - P1
-
1.1.4
-
None
-
None
-
Fully Compatible
Description
In 1.1.4, a network error at certain point(s) in the TLS code path causes the driver to spin infinitely.
To reproduce, first install pip, then mongo-mockup-db:
$ wget https://bootstrap.pypa.io/get-pip.py
|
$ sudo python get-pip.py
|
$ sudo python -m pip install https://github.com/ajdavis/mongo-mockup-db/archive/master.zip
|
Then save this in a Python file and run it like "python file.py":
from mockupdb import MockupDB, Command
|
|
|
server = MockupDB(port=27017, auto_ismaster=True, verbose=True, ssl=True)
|
server.autoresponds('ping')
|
server.run()
|
server.receives(Command('listCollections'), timeout=100).hangup()
|
That'll wait up to 100 seconds for a driver to issue listCollections, then when it receives the command it hangs up.
I've started this mock server and run this file, using the C Driver built from master (0bd7850609):
#include <mongoc.h>
|
|
|
int
|
main (int argc,
|
char *argv[])
|
{
|
mongoc_client_t *client;
|
mongoc_database_t *db;
|
bson_error_t error;
|
mongoc_ssl_opt_t ssl_options = { 0 };
|
const char *uristr = "mongodb://127.0.0.1/?ssl=true";
|
char **names = NULL;
|
int i = 0;
|
mongoc_init ();
|
|
|
if (argc > 1) {
|
uristr = argv [1];
|
}
|
|
|
client = mongoc_client_new (uristr);
|
ssl_options.weak_cert_validation = true;
|
mongoc_client_set_ssl_opts (client, &ssl_options);
|
|
|
if (!client) {
|
fprintf (stderr, "Failed to parse URI.\n");
|
return EXIT_FAILURE;
|
}
|
|
|
db = mongoc_client_get_database (client, "test");
|
if ((names = mongoc_database_get_collection_names (db, &error))) {
|
printf ("got collection names\n");
|
for (i = 0; names [i]; i++)
|
printf ("collection: %s\n", names [i]);
|
bson_strfreev (names);
|
} else {
|
fprintf (stderr, "Command failed: %s\n", error.message);
|
}
|
mongoc_database_destroy (db);
|
mongoc_client_destroy (client);
|
|
|
mongoc_cleanup ();
|
|
|
return EXIT_SUCCESS;
|
}
|
The Python server hangs up, and the client hangs and spins the CPU.
If I remove "ssl=True" from the Python and "ssl=true" from the C, and rerun both sides, I instead get an immediate log about the hangup from the C Driver and it exits as desired:
stream: Failure to buffer 4 bytes: Failed to buffer 4 bytes within 300000 milliseconds.
|
The C code also gets a non-NULL return value from mongoc_database_get_collection_names, which is filed as a separate bug CDRIVER-618.