[CDRIVER-2483] _mongoc_async_cmd_phase_send may not send entire message Created: 31/Jan/18  Updated: 28/Oct/23  Resolved: 12/Feb/18

Status: Closed
Project: C Driver
Component/s: None
Affects Version/s: 1.9.2
Fix Version/s: 1.10.0

Type: Improvement Priority: Major - P3
Reporter: Kevin Albertson Assignee: Kevin Albertson
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

The function _mongoc_async_cmd_phase_send sends an ismaster command to the node it's checking. It uses mongoc_stream_writev to send the message.
https://github.com/mongodb/mongo-c-driver/blob/1.9.2/src/mongoc/mongoc-async-cmd.c#L248

However, mongoc_stream_writev is not guaranteed to send the entire message of the iovec. If you jerry-rig an ismaster command with fake fields (which mongo doesn't mind) to increase the size of the ismaster command to something like 1MB, it will not send the full command and timeout checking. The repro.patch file is a simple way to reproduce this.

It's unlikely we'd ever hit this, since an ismaster message should be small enough never to be broken up on any reasonable system. But I think a reasonable and simple fix is to use _mongoc_stream_writev_full instead, which sets an error if it cannot send the full message in one call to stream->write.



 Comments   
Comment by Githook User [ 05/Feb/18 ]

Author:

{'email': 'kevin.albertson@10gen.com', 'name': 'Kevin Albertson', 'username': 'kevinAlbs'}

Message: CDRIVER-2483 fix large ismaster test for windows
Branch: master
https://github.com/mongodb/mongo-c-driver/commit/3d8933891be82c9d33f2d5a3f9ceeb0b4bef0b59

Comment by Githook User [ 05/Feb/18 ]

Author:

{'email': 'kevin.albertson@10gen.com', 'name': 'Kevin Albertson', 'username': 'kevinAlbs'}

Message: CDRIVER-2483 send entire ismaster message
Branch: master
https://github.com/mongodb/mongo-c-driver/commit/bc9c76e22576813c1553eef1e4e38e6dbb5f6c4c

Comment by A. Jesse Jiryu Davis [ 31/Jan/18 ]

Let's try instead to call mongoc_stream_writev in _mongoc_async_cmd_phase_send as we currently do but, if the bytes sent is less than the total outgoing message, don't change the async_cmd_t's state. Then the event loop in mongoc_async_run should call _mongoc_async_cmd_phase_send again once the socket is writable (its events match the POLLOUT bitmask) and _mongoc_async_cmd_phase_send can send more bytes.

I agree that, so far, we haven't seen any circumstances where the socket's write buffer is too small to send a whole isMaster in one shot. But if we're going to change this code we might as well do a fully correct solution that can handle any size of write buffer and message size.

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