tsocket_bsd: Attempt to increase the SO_SNDBUF if we get EMSGSIZE in sendto()
authorAndrew Bartlett <abartlet@samba.org>
Mon, 4 Mar 2013 03:06:14 +0000 (14:06 +1100)
committerStefan Metzmacher <metze@samba.org>
Mon, 4 Mar 2013 10:15:35 +0000 (11:15 +0100)
This matches what was done for lib/socket/socket_unix.c in
c692bb02b039ae8fef6ba968fd13b36ad7d62a72.

(and is based on that patch by Landon Fuller <landonf@bikemonkey.org>)

Andrew Bartlett

Reviewed-by: Stefan Metzmacher <metze@samba.org>
Autobuild-User(master): Stefan Metzmacher <metze@samba.org>
Autobuild-Date(master): Mon Mar  4 11:15:35 CET 2013 on sn-devel-104

lib/tsocket/tsocket_bsd.c

index 56dff68dd2f6b21a015ac2729da517d002627abc..4b54d319a0d2fd6aab4d4e3c552656d18e096f92 100644 (file)
@@ -1102,6 +1102,32 @@ static void tdgram_bsd_sendto_handler(void *private_data)
                /* retry later */
                return;
        }
+
+       if (err == EMSGSIZE) {
+               /* round up in 1K increments */
+               int bufsize = ((state->len + 1023) & (~1023));
+
+               ret = setsockopt(bsds->fd, SOL_SOCKET, SO_SNDBUF, &bufsize,
+                                sizeof(bufsize));
+               if (ret == 0) {
+                       /*
+                        * We do the rety here, rather then via the
+                        * handler, as we only want to retry once for
+                        * this condition, so if there is a mismatch
+                        * between what setsockopt() accepts and what can
+                        * actually be sent, we do not end up in a
+                        * loop.
+                        */
+
+                       ret = sendto(bsds->fd, state->buf, state->len,
+                                    0, sa, sa_socklen);
+                       err = tsocket_bsd_error_from_errno(ret, errno, &retry);
+                       if (retry) { /* retry later */
+                               return;
+                       }
+               }
+       }
+
        if (tevent_req_error(req, err)) {
                return;
        }