[CDRIVER-630] default_stream_initiator can block forever in TLS handshake Created: 01/May/15  Updated: 08/Jan/24  Resolved: 10/Aug/15

Status: Closed
Project: C Driver
Component/s: None
Affects Version/s: 1.1.4
Fix Version/s: 1.2-beta0, 1.1.5

Type: Bug Priority: Major - P3
Reporter: Mira Carey Assignee: Hannes Magnusson
Resolution: Done Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Related
is related to CDRIVER-577 v1.2 no longer uses stream initiator ... Closed

 Description   

*UPDATE*: Fixed in 1.1.5, still reproducible in 1.2.0. Uncomment the "/TLS/handshake_stall" test and fix in 1.2.0-dev branch.

The default stream initiator in mongoc_client.c makes a blocking call to mongoc_stream_tls_do_handshake(). This can cause the driver to full hang until some kind of network error is returned.

https://github.com/mongodb/mongo-c-driver/blob/master/src/mongoc/mongoc-client.c#L339

We should pull connecttimeoutms or sockettimeoutms out of the uri and use that in lieu of permanent blocking.



 Comments   
Comment by Githook User [ 10/Aug/15 ]

Author:

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

Message: CDRIVER-630: default_stream_initiator can block forever in TLS handshake
Branch: 1.2.0-dev
https://github.com/mongodb/mongo-c-driver/commit/b27a5da2c2c9a6bed3db14cf311e491bf3720d04

Comment by Githook User [ 27/May/15 ]

Author:

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

Message: CDRIVER-630 disable TLS timeout test on 1.2.0-dev
Branch: 1.2.0-dev
https://github.com/mongodb/mongo-c-driver/commit/064ca7230e51dcffdcc5c825b075f9f4cdbe960a

Comment by Githook User [ 08/May/15 ]

Author:

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

Message: Merge pull request #229 from ajdavis/CDRIVER-630-block-in-tls-handshake

fix hang in TLS handshake
Branch: master
https://github.com/mongodb/mongo-c-driver/commit/651518303d1b7c2611c229f086e034784069ddd4

Comment by Githook User [ 08/May/15 ]

Author:

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

Message: CDRIVER-630 "0" value means "default" for TLS handshake timeout
Branch: master
https://github.com/mongodb/mongo-c-driver/commit/30162bb1a0d70a3ed4f9885e47b206d3ec1aa962

Comment by Githook User [ 08/May/15 ]

Author:

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

Message: CDRIVER-630 apply connecttimeout to TLS handshake
Branch: master
https://github.com/mongodb/mongo-c-driver/commit/a1a677e47be859e5b1da12dac3423fbaa01fe1ef

Comment by Githook User [ 08/May/15 ]

Author:

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

Message: CDRIVER-630 test connect timeout and TLS handshake
Branch: master
https://github.com/mongodb/mongo-c-driver/commit/7c3e455297b2a0420dc13a495e13c54a3e88e42c

Comment by A. Jesse Jiryu Davis [ 03/May/15 ]

To reproduce, make a trivial server in Python:

import socket
 
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server.bind(('localhost', 27017))
server.listen(5)
 
while True:
    client, address = server.accept()
    print client, address, 'connected'

Connect to it with the "example-client" program from the mongo-c-driver repository:

$ time ./example-client 'mongodb://localhost/?connecttimeoutms=1000&sockettimeoutms=1000&ssl=true'
2015/05/03 10:48:19.0248: [16883]:    DEBUG:      cluster: Client initialized in direct mode.

This hangs forever, because the client successfully connects but the server doesn't respond when the client initiates a TLS handshake. Without TLS, on the other hand:

$ time ./example-client 'mongodb://localhost/?connecttimeoutms=1000&sockettimeoutms=1000'
2015/05/03 10:51:00.0697: [17089]:    DEBUG:      cluster: Client initialized in direct mode.
2015/05/03 10:51:01.0699: [17089]:  WARNING:       stream: Failure to buffer 4 bytes: Failed to buffer 4 bytes within 1000 milliseconds.
Cursor Failure: Failed to read 4 bytes from socket within 1000 milliseconds.
./example-client   0.01s user 0.01s system 2% cpu 1.022 total

The example client connects and begins a query, which times out after a second, as designed.

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