[CDRIVER-948] TLS / SSL connections fail in pooled mode Created: 20/Oct/15  Updated: 08/May/17  Resolved: 22/Oct/15

Status: Closed
Project: C Driver
Component/s: libmongoc, tls
Affects Version/s: 1.2.0
Fix Version/s: 1.2.1

Type: Bug Priority: Blocker - P1
Reporter: A. Jesse Jiryu Davis Assignee: A. Jesse Jiryu Davis
Resolution: Done Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Duplicate
is duplicated by CDRIVER-931 SSL connection issue in 1.2.0 Closed
Related
is related to CDRIVER-2153 mongoc_client_pool_t cannot connect t... Closed
is related to CDRIVER-673 Test with and without SSL, incl. FIPS... Closed

 Description   

Client operations over SSL will always fail in version 1.2.0 if the client is from a mongoc_pool_t.

Beginning in 1.2.0, clients from a pool all share a set of sockets for server monitoring, but use distinct per-client sockets for application operations (such as queries, writes, etc.). When the pool creates sockets for monitoring, it begins a non-blocking connect on each and uses "poll" to wait asynchronously for all of them to finish connecting. When an individual client creates a socket for application operations, the client connects the socket synchronously.

In the process of a series of refactorings (mainly related to CDRIVER-894) we introduced a new internal function mongoc_stream_wait that a pooled client uses to await connection on a socket before doing application operations on it. We didn't re-test SSL connections in pooled mode after those refactorings were completed.

This allowed a bug to slip through: the new mongoc_stream_wait calls mongoc_stream_poll on a buffered TLS stream, but buffered TLS streams don't implement "poll". So mongoc_stream_poll always errors ("invalid argument", EINVAL) and the connection is considered failed.

Symptom: a "find" and "mongoc_cursor_next" operation with a pooled client and SSL enabled fails, with the error, "Cursor Failure: Failed to connect to target host".



 Comments   
Comment by Githook User [ 22/Oct/15 ]

Author:

{u'username': u'bjori', u'name': u'Hannes Magnusson', u'email': u'bjori@php.net'}

Message: Merge branch 'r1.2'

Comment by Githook User [ 22/Oct/15 ]

Author:

{u'username': u'bjori', u'name': u'Hannes Magnusson', u'email': u'bjori@php.net'}

Message: Merge branch 'r1.2'

Comment by Githook User [ 22/Oct/15 ]

Author:

{u'username': u'ajdavis', u'name': u'A. Jesse Jiryu Davis', u'email': u'jesse@mongodb.com'}

Message: CDRIVER-948 enable poll on buffered streams

Although the previous commit removes the need for this, it's a bug
waiting to happen again: if a stream is wrapped in more than one
layer it can't be passed to mongoc_stream_poll. Now, we unwrap until
we reach the real base stream before calling poll.
Branch: master
https://github.com/mongodb/mongo-c-driver/commit/614544efe1f6214df3ba3152a12b2773c87d29d7

Comment by Githook User [ 22/Oct/15 ]

Author:

{u'username': u'ajdavis', u'name': u'A. Jesse Jiryu Davis', u'email': u'jesse@mongodb.com'}

Message: CDRIVER-948 don't stream_wait in fetch_stream_pooled

Not needed: mongoc_cluster_fetch_stream_pooled ultimately calls
mongoc_client_default_stream_initiator, hence mongoc_client_connect_tcp,
which awaits connectTimeoutMS for the connection to be established.

Calling mongoc_stream_wait in pooled mode with SSL failed with EINVAL:
"stream" is a socket stream, wrapped in a TLS stream, wrapped in a
buffered stream. You can pass a socket stream or TLS stream to
mongoc_stream_poll, but you can't pass a buffered stream since a
buffered stream doesn't implement poll().
Branch: master
https://github.com/mongodb/mongo-c-driver/commit/709532e3e629ad1fb40f7686a581dbe36dbf881c

Comment by Githook User [ 22/Oct/15 ]

Author:

{u'username': u'ajdavis', u'name': u'A. Jesse Jiryu Davis', u'email': u'jesse@mongodb.com'}

Message: CDRIVER-948 enable poll on buffered streams

Although the previous commit removes the need for this, it's a bug
waiting to happen again: if a stream is wrapped in more than one
layer it can't be passed to mongoc_stream_poll. Now, we unwrap until
we reach the real base stream before calling poll.
Branch: r1.2
https://github.com/mongodb/mongo-c-driver/commit/614544efe1f6214df3ba3152a12b2773c87d29d7

Comment by Githook User [ 22/Oct/15 ]

Author:

{u'username': u'ajdavis', u'name': u'A. Jesse Jiryu Davis', u'email': u'jesse@mongodb.com'}

Message: CDRIVER-948 don't stream_wait in fetch_stream_pooled

Not needed: mongoc_cluster_fetch_stream_pooled ultimately calls
mongoc_client_default_stream_initiator, hence mongoc_client_connect_tcp,
which awaits connectTimeoutMS for the connection to be established.

Calling mongoc_stream_wait in pooled mode with SSL failed with EINVAL:
"stream" is a socket stream, wrapped in a TLS stream, wrapped in a
buffered stream. You can pass a socket stream or TLS stream to
mongoc_stream_poll, but you can't pass a buffered stream since a
buffered stream doesn't implement poll().
Branch: r1.2
https://github.com/mongodb/mongo-c-driver/commit/709532e3e629ad1fb40f7686a581dbe36dbf881c

Generated at Wed Feb 07 21:11:06 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.