swrap: Fix sendto() with connected sockets
authorRichard Sharpe <rsharpe@samba.org>
Thu, 12 May 2016 00:03:46 +0000 (17:03 -0700)
committerAndreas Schneider <asn@samba.org>
Tue, 17 May 2016 09:44:04 +0000 (11:44 +0200)
Let the socket wrapper code work with the net ads dns gethostbyname etc
code (lib/addn/dnssock.c) which uses connect on a UDP socket before then
using sendto and recvfrom.

Here, we make sure we don't error out in that case.

Tested by creating a test case for this and then observing that:

1. The test case works when the socket wrapper lib is not being used
   ie, run the test directly after defining some SHELL variables.

2. That the test case fails when run with the un modified socket
   wrapper code.

3. Apply this fix and observe that it runs correctly.

Pair-Programmed-With: Andreas Schneider <asn@samba.org>
Signed-off-by: Richard Sharpe <rsharpe@samba.org>
Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
src/socket_wrapper.c

index 068cb08127a4809c093f355d86eb21e630d54900..ba289e6fbaf96866a8467f708cf7a372d82fa739 100644 (file)
@@ -3922,9 +3922,15 @@ static ssize_t swrap_sendmsg_before(int fd,
        }
        case SOCK_DGRAM:
                if (si->connected) {
-                       if (msg->msg_name) {
-                               errno = EISCONN;
-                               return -1;
+                       if (msg->msg_name != NULL) {
+                               /*
+                                * We are dealing with unix sockets and if we
+                                * are connected, we should only talk to the
+                                * connected unix path. Using the fd to send
+                                * to another server would be hard to achieve.
+                                */
+                               msg->msg_name = NULL;
+                               msg->msg_namelen = 0;
                        }
                } else {
                        const struct sockaddr *msg_name;
@@ -4471,12 +4477,25 @@ static ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags,
                return len;
        }
 
-       ret = libc_sendto(s,
-                         buf,
-                         len,
-                         flags,
-                         (struct sockaddr *)msg.msg_name,
-                         msg.msg_namelen);
+       /*
+        * If it is a dgram socket and we are connected, don't include the
+        * 'to' address.
+        */
+       if (si->type == SOCK_DGRAM && si->connected) {
+               ret = libc_sendto(s,
+                                 buf,
+                                 len,
+                                 flags,
+                                 NULL,
+                                 0);
+       } else {
+               ret = libc_sendto(s,
+                                 buf,
+                                 len,
+                                 flags,
+                                 (struct sockaddr *)msg.msg_name,
+                                 msg.msg_namelen);
+       }
 
        swrap_sendmsg_after(s, si, &msg, to, ret);