Skip to content

Commit ef9aaf2

Browse files
committed
CDRIVER-756: Properly check for error in mongoc_stream_writev
And add additional checks to verify the full write succeeded, or else return descriptive error
1 parent 724948b commit ef9aaf2

File tree

3 files changed

+53
-12
lines changed

3 files changed

+53
-12
lines changed

src/mongoc/mongoc-cluster.c

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2238,18 +2238,8 @@ mongoc_cluster_sendv_to_server (mongoc_cluster_t *cluster,
22382238

22392239
BSON_ASSERT (cluster->iov.len);
22402240

2241-
if (!mongoc_stream_writev (stream, iov, iovcnt,
2242-
cluster->sockettimeoutms)) {
2243-
char buf[128];
2244-
char * errstr;
2245-
errstr = bson_strerror_r(errno, buf, sizeof buf);
2246-
2247-
bson_set_error (error,
2248-
MONGOC_ERROR_STREAM,
2249-
MONGOC_ERROR_STREAM_SOCKET,
2250-
"Failure during socket delivery: %s",
2251-
errstr);
2252-
mongoc_cluster_disconnect_node (cluster, server_id);
2241+
if (!_mongoc_stream_writev_full (stream, iov, iovcnt,
2242+
cluster->sockettimeoutms, error)) {
22532243
RETURN (false);
22542244
}
22552245

src/mongoc/mongoc-stream-private.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,13 @@ BSON_BEGIN_DECLS
3434
#define MONGOC_STREAM_GRIDFS 4
3535
#define MONGOC_STREAM_TLS 5
3636

37+
bool
38+
_mongoc_stream_writev_full (mongoc_stream_t *stream,
39+
mongoc_iovec_t *iov,
40+
size_t iovcnt,
41+
int32_t timeout_msec,
42+
bson_error_t *error);
43+
3744

3845
BSON_END_DECLS
3946

src/mongoc/mongoc-stream.c

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,3 +368,47 @@ mongoc_stream_check_closed (mongoc_stream_t *stream)
368368

369369
RETURN (ret);
370370
}
371+
372+
bool
373+
_mongoc_stream_writev_full (mongoc_stream_t *stream,
374+
mongoc_iovec_t *iov,
375+
size_t iovcnt,
376+
int32_t timeout_msec,
377+
bson_error_t *error)
378+
{
379+
size_t total_bytes = 0;
380+
int i;
381+
ssize_t r;
382+
ENTRY;
383+
384+
for (i = 0; i < iovcnt; i++) {
385+
total_bytes += iov[i].iov_len;
386+
}
387+
388+
r = mongoc_stream_writev(stream, iov, iovcnt, timeout_msec);
389+
TRACE("writev returned: %ld", r);
390+
391+
if (r < 0) {
392+
if (error) {
393+
char buf[128];
394+
char *errstr;
395+
396+
errstr = bson_strerror_r(errno, buf, sizeof(buf));
397+
398+
bson_set_error (error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_SOCKET,
399+
"Failure during socket delivery: %s (%d)", errstr, errno);
400+
}
401+
402+
RETURN(false);
403+
}
404+
405+
if (r != total_bytes) {
406+
bson_set_error (error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_SOCKET,
407+
"Failure to send all requested bytes (only sent: %lld/%llu in %dms) during socket delivery",
408+
(long long)r, (unsigned long long)total_bytes, timeout_msec);
409+
410+
RETURN(false);
411+
}
412+
413+
RETURN(true);
414+
}

0 commit comments

Comments
 (0)