The branch, master has been updated
       via  ba33426 s3:torture: transfer 1M message with fds in 
LOCAL-MESSAGING-FDPASS2 test
       via  d4bf2be s3:torture: wait in tevent-loop for child to confirm 
receive in FDPASS2 msg test
       via  3628102 s3:torture: fix a message in LOCAL-MESSAGING-FDPASS2 test
       via  bc5c029 selftest: run LOCAL-MESSAGING-READ4
       via  f16dd64 s3:torture: add LOCAL-MESSAGING-READ4 - send 1MB message
       via  797ada1 s3:messaging: explain why the messaging_send*() functions 
need a tevent-loop.
       via  d7d9ec3 s3:unix_msg: document closing of fds in the receive handler
       via  0ab5e89 s3:unix_msg: close the fds in unix_dgram_recv_handler() 
after the callback has run
       via  6e47886 s3:messaging: upon receiving fds, dup them so the caller 
can safely close them.
       via  00d9ee0 s3:messaging: allow the messaging receive callback to 
change the fds
       via  d8af3e7 s3:unix_msg: don't fill cmsg buffer in unix_dgram_send_job()
       via  b38ed73 s3:unix_msg: add close_fd_array_cmsg()
       via  20cd934 s3:unix_msg: factor extract_fd_array_from_msghdr() out of 
unix_dgram_recv_handler()
       via  67684dc s3:unix_msg: simplify queue_msg() by moving space 
calculations up.
       via  a96f0f4 s3:unix_msg: use an iov in unix_dgram_msg/queue_msg instead 
of buffer and length
       via  e38f4f4 s3:unix_msg: rename a variable buflen->data_len in 
queue_msg()
       via  2564a5f s3:unix_msg: use a buffer pointer instead of array indexes 
for the iov buffer
       via  9ddb661 s3:unix_msg: remember errno in unix_dgram_send_job in case 
of send error.
       via  9fa673b s3:unix_msg: don't close the fd-array at the end of 
unix_dgram_send_job()
       via  698e8a2 s3:unix_msg: add "close_fds" exit point to unix_msg_recv()
       via  2795bdf s3:messaging: msg_type int->uint32_t in struct messaging_hdr
       via  40b4853 s3:messaging: fix uninitialized data introduced by padding
       via  1dbd0be tevent: version 0.9.22
       via  a65df7e tevent: remove unused exit_code in tevent_select.c
       via  1ea3364 tevent: remove unused exit_code in tevent_poll.c
      from  22eb416 repl: Specify the target realm in 
dreplsrv_get_target_principal()

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit ba3342616c54fe9e7f67e46f84d3decd9fa898dd
Author: Michael Adam <[email protected]>
Date:   Tue Sep 30 10:16:23 2014 +0200

    s3:torture: transfer 1M message with fds in LOCAL-MESSAGING-FDPASS2 test
    
    Signed-off-by: Michael Adam <[email protected]>
    Reviewed-by: Stefan Metzmacher <[email protected]>
    Reviewed-by: Volker Lendecke <[email protected]>
    
    Autobuild-User(master): Michael Adam <[email protected]>
    Autobuild-Date(master): Tue Sep 30 19:01:30 CEST 2014 on sn-devel-104

commit d4bf2be62fe1ce5f41a080fdf2301b2124d27eef
Author: Michael Adam <[email protected]>
Date:   Tue Sep 30 10:15:33 2014 +0200

    s3:torture: wait in tevent-loop for child to confirm receive in FDPASS2 msg 
test
    
    This is the only way to correctly transfer bigger messages.
    
    Signed-off-by: Michael Adam <[email protected]>
    Reviewed-by: Stefan Metzmacher <[email protected]>
    Reviewed-by: Volker Lendecke <[email protected]>

commit 36281029384ffdea495bb1da6c68f2905785d270
Author: Michael Adam <[email protected]>
Date:   Tue Sep 30 10:13:17 2014 +0200

    s3:torture: fix a message in LOCAL-MESSAGING-FDPASS2 test
    
    Signed-off-by: Michael Adam <[email protected]>
    Reviewed-by: Stefan Metzmacher <[email protected]>
    Reviewed-by: Volker Lendecke <[email protected]>

commit bc5c029a08a3d2c199379f6244999b57fdad5a0d
Author: Michael Adam <[email protected]>
Date:   Tue Sep 30 00:30:58 2014 +0200

    selftest: run LOCAL-MESSAGING-READ4
    
    Signed-off-by: Michael Adam <[email protected]>
    Reviewed-by: Stefan Metzmacher <[email protected]>
    Reviewed-by: Volker Lendecke <[email protected]>

commit f16dd644aaec0071b06057d74b54fb8b508a74f7
Author: Michael Adam <[email protected]>
Date:   Thu Sep 25 00:28:14 2014 +0200

    s3:torture: add LOCAL-MESSAGING-READ4 - send 1MB message
    
    Signed-off-by: Michael Adam <[email protected]>
    Reviewed-by: Stefan Metzmacher <[email protected]>
    Reviewed-by: Volker Lendecke <[email protected]>

commit 797ada104e4a68f601e473c46dbb33871dda12e1
Author: Michael Adam <[email protected]>
Date:   Tue Sep 30 10:01:51 2014 +0200

    s3:messaging: explain why the messaging_send*() functions need a 
tevent-loop.
    
    Signed-off-by: Michael Adam <[email protected]>
    Reviewed-by: Stefan Metzmacher <[email protected]>
    Reviewed-by: Volker Lendecke <[email protected]>

commit d7d9ec31dfe5d797307a7d107f0874260e7eab4a
Author: Michael Adam <[email protected]>
Date:   Tue Sep 30 13:06:18 2014 +0200

    s3:unix_msg: document closing of fds in the receive handler
    
    Pair-Programmed-With: Volker Lendecke <[email protected]>
    
    Signed-off-by: Michael Adam <[email protected]>
    Signed-off-by: Volker Lendecke <[email protected]>

commit 0ab5e895f7869ea07624c666cc620576a7fde289
Author: Michael Adam <[email protected]>
Date:   Thu Sep 25 00:28:48 2014 +0200

    s3:unix_msg: close the fds in unix_dgram_recv_handler() after the callback 
has run
    
    If the caller wants to use passed fds, he should copy them away
    and set them to -1.
    
    Signed-off-by: Michael Adam <[email protected]>
    Reviewed-by: Stefan Metzmacher <[email protected]>
    Reviewed-by: Volker Lendecke <[email protected]>

commit 6e47886b154ed89182a56233d55c650885432907
Author: Michael Adam <[email protected]>
Date:   Tue Sep 30 09:48:18 2014 +0200

    s3:messaging: upon receiving fds, dup them so the caller can safely close 
them.
    
    Signed-off-by: Michael Adam <[email protected]>
    Reviewed-by: Stefan Metzmacher <[email protected]>
    Reviewed-by: Volker Lendecke <[email protected]>

commit 00d9ee04dd0f5c2fe5e0cd7108ed7da4b981c258
Author: Michael Adam <[email protected]>
Date:   Tue Sep 30 11:29:22 2014 +0200

    s3:messaging: allow the messaging receive callback to change the fds
    
    This allows the callback to consume the fds and e.g. set
    them to -1 so that the caller can then treat (close) only those
    fds that have not been consumed.
    
    Signed-off-by: Michael Adam <[email protected]>
    Reviewed-by: Stefan Metzmacher <[email protected]>
    Reviewed-by: Volker Lendecke <[email protected]>

commit d8af3e76a362328a854aeb83f8699443e77d2a8d
Author: Michael Adam <[email protected]>
Date:   Mon Sep 29 11:08:53 2014 +0200

    s3:unix_msg: don't fill cmsg buffer in unix_dgram_send_job()
    
    Do this in queue_msg, instead.
    This renders unix_dgram_send_job() as simple as it was before
    we introduced fd-passing -- as it is intended.
    
    This also changes struct unix_dgram_msg to not contain
    the fd-array, but the correspondingly filled msghdr and cmsg buf.
    
    Pair-Programmed-With: Volker Lendecke <[email protected]>
    Pair-Programmed-With: Stefan Metzmacher <[email protected]>
    
    Signed-off-by: Michael Adam <[email protected]>
    Signed-off-by: Volker Lendecke <[email protected]>
    Signed-off-by: Stefan Metzmacher <[email protected]>

commit b38ed7311af0862945e417b6f6350b7bc6b0be20
Author: Michael Adam <[email protected]>
Date:   Mon Sep 29 13:31:27 2014 +0200

    s3:unix_msg: add close_fd_array_cmsg()
    
    Variant of close_fd_array() operating on fd_array inside msghdr.
    
    Signed-off-by: Michael Adam <[email protected]>
    Reviewed-by: Stefan Metzmacher <[email protected]>
    Reviewed-by: Volker Lendecke <[email protected]>

commit 20cd934ec04e601a6bac6fc1dd61c75767c6213f
Author: Michael Adam <[email protected]>
Date:   Mon Sep 29 12:54:00 2014 +0200

    s3:unix_msg: factor extract_fd_array_from_msghdr() out of 
unix_dgram_recv_handler()
    
    For re-use.
    
    Signed-off-by: Michael Adam <[email protected]>
    Reviewed-by: Stefan Metzmacher <[email protected]>
    Reviewed-by: Volker Lendecke <[email protected]>

commit 67684dc69585559fae6718837bf6c5ba83af267f
Author: Michael Adam <[email protected]>
Date:   Mon Sep 29 12:27:37 2014 +0200

    s3:unix_msg: simplify queue_msg() by moving space calculations up.
    
    This allows for early direct return instead of the goto invalid,
    since the fds_copy array is filled later.
    
    Pair-Programmed-With: Volker Lendecke <[email protected]>
    Pair-Programmed-With: Stefan Metzmacher <[email protected]>
    
    Signed-off-by: Michael Adam <[email protected]>
    Signed-off-by: Volker Lendecke <[email protected]>
    Signed-off-by: Stefan Metzmacher <[email protected]>

commit a96f0f4c3bd66cb44f882a836bf80b2ce39523e0
Author: Michael Adam <[email protected]>
Date:   Mon Sep 29 12:15:54 2014 +0200

    s3:unix_msg: use an iov in unix_dgram_msg/queue_msg instead of buffer and 
length
    
    This is equivalent, reads more easily and makes extraction
    more obvious.
    
    Pair-Programmed-With: Volker Lendecke <[email protected]>
    Pair-Programmed-With: Stefan Metzmacher <[email protected]>
    
    Signed-off-by: Michael Adam <[email protected]>
    Signed-off-by: Volker Lendecke <[email protected]>
    Signed-off-by: Stefan Metzmacher <[email protected]>

commit e38f4f4ceb5b2605dd0804ab7629f9b5e8d5cd5c
Author: Michael Adam <[email protected]>
Date:   Mon Sep 29 11:39:24 2014 +0200

    s3:unix_msg: rename a variable buflen->data_len in queue_msg()
    
    Pair-Programmed-With: Volker Lendecke <[email protected]>
    Pair-Programmed-With: Stefan Metzmacher <[email protected]>
    
    Signed-off-by: Michael Adam <[email protected]>
    Signed-off-by: Volker Lendecke <[email protected]>
    Signed-off-by: Stefan Metzmacher <[email protected]>

commit 2564a5fa578058953c9c2890566b4fdd51a744be
Author: Michael Adam <[email protected]>
Date:   Mon Sep 29 11:54:12 2014 +0200

    s3:unix_msg: use a buffer pointer instead of array indexes for the iov 
buffer
    
    This is more obvious to read and a preparation for following commits.
    
    Pair-Programmed-With: Volker Lendecke <[email protected]>
    Pair-Programmed-With: Stefan Metzmacher <[email protected]>
    
    Signed-off-by: Michael Adam <[email protected]>
    Signed-off-by: Volker Lendecke <[email protected]>
    Signed-off-by: Stefan Metzmacher <[email protected]>

commit 9ddb66128134f9d8386a6db776dc226c6a3b14ac
Author: Michael Adam <[email protected]>
Date:   Mon Sep 29 11:06:32 2014 +0200

    s3:unix_msg: remember errno in unix_dgram_send_job in case of send error.
    
    Pair-Programmed-With: Volker Lendecke <[email protected]>
    Pair-Programmed-With: Stefan Metzmacher <[email protected]>
    
    Signed-off-by: Michael Adam <[email protected]>
    Signed-off-by: Volker Lendecke <[email protected]>
    Signed-off-by: Stefan Metzmacher <[email protected]>

commit 9fa673bf37d59b14b113df978da58be4e3e58d7d
Author: Michael Adam <[email protected]>
Date:   Mon Sep 29 11:04:03 2014 +0200

    s3:unix_msg: don't close the fd-array at the end of unix_dgram_send_job()
    
    These pthread-pool-jobs should be minimal and ideally only do one
    syscall. The closing of the fds is done in unix_dgram_job_finished().
    
    Pair-Programmed-With: Volker Lendecke <[email protected]>
    Pair-Programmed-With: Stefan Metzmacher <[email protected]>
    
    Signed-off-by: Michael Adam <[email protected]>
    Signed-off-by: Volker Lendecke <[email protected]>
    Signed-off-by: Stefan Metzmacher <[email protected]>

commit 698e8a235740d4cedc5635b9f64da16cb3cb1f01
Author: Michael Adam <[email protected]>
Date:   Sun Sep 28 01:42:39 2014 +0200

    s3:unix_msg: add "close_fds" exit point to unix_msg_recv()
    
    Signed-off-by: Michael Adam <[email protected]>
    Reviewed-by: Stefan Metzmacher <[email protected]>
    Reviewed-by: Volker Lendecke <[email protected]>

commit 2795bdfd9ffd5c69402543d6f5f22b53e9d357a6
Author: Michael Adam <[email protected]>
Date:   Mon Sep 29 11:01:54 2014 +0200

    s3:messaging: msg_type int->uint32_t in struct messaging_hdr
    
    Signed-off-by: Michael Adam <[email protected]>
    Reviewed-by: Stefan Metzmacher <[email protected]>
    Reviewed-by: Volker Lendecke <[email protected]>

commit 40b48534dfde7d17112a18d2e4e8fc24ee1adfc8
Author: Michael Adam <[email protected]>
Date:   Mon Sep 29 11:01:11 2014 +0200

    s3:messaging: fix uninitialized data introduced by padding
    
    Signed-off-by: Michael Adam <[email protected]>
    Reviewed-by: Stefan Metzmacher <[email protected]>
    Reviewed-by: Volker Lendecke <[email protected]>

commit 1dbd0bec040060193f1d2f1b5a97db1bd340c1ca
Author: Stefan Metzmacher <[email protected]>
Date:   Tue Sep 30 14:44:30 2014 +0200

    tevent: version 0.9.22
    
    * pkgconfig fixes
    * Bug #10640 - smbd is not responding - tevent_common_signal_handler()
      increments non-atomic variables.
      https://bugzilla.samba.org/show_bug.cgi?id=10640
    * Minor compile fixes
    
    Signed-off-by: Stefan Metzmacher <[email protected]>
    Reviewed-by: Michael Adam <[email protected]>

commit a65df7e8c0ce687625a18de5769bf38f92118eca
Author: Stefan Metzmacher <[email protected]>
Date:   Tue Jul 22 14:54:11 2014 +0200

    tevent: remove unused exit_code in tevent_select.c
    
    Signed-off-by: Stefan Metzmacher <[email protected]>
    Reviewed-by: Michael Adam <[email protected]>

commit 1ea3364721522dcd68fee629b017e72ab35ff6e1
Author: Stefan Metzmacher <[email protected]>
Date:   Tue Jul 22 14:54:11 2014 +0200

    tevent: remove unused exit_code in tevent_poll.c
    
    Signed-off-by: Stefan Metzmacher <[email protected]>
    Reviewed-by: Michael Adam <[email protected]>

-----------------------------------------------------------------------

Summary of changes:
 .../ABI/{tevent-0.9.21.sigs => tevent-0.9.22.sigs} |    0
 lib/tevent/tevent_poll.c                           |    3 -
 lib/tevent/tevent_select.c                         |    5 +-
 lib/tevent/wscript                                 |    2 +-
 source3/include/messages.h                         |   10 +
 source3/lib/messages.c                             |   10 +-
 source3/lib/messages_dgm.c                         |    4 +-
 source3/lib/messages_dgm.h                         |    2 +-
 source3/lib/unix_msg/unix_msg.c                    |  261 +++++++++++---------
 source3/lib/unix_msg/unix_msg.h                    |    7 +
 source3/selftest/tests.py                          |    1 +
 source3/torture/proto.h                            |    1 +
 source3/torture/test_messaging_fd_passing.c        |   59 +++++-
 source3/torture/test_messaging_read.c              |  230 +++++++++++++++++
 source3/torture/torture.c                          |    1 +
 15 files changed, 464 insertions(+), 132 deletions(-)
 copy lib/tevent/ABI/{tevent-0.9.21.sigs => tevent-0.9.22.sigs} (100%)


Changeset truncated at 500 lines:

diff --git a/lib/tevent/ABI/tevent-0.9.21.sigs 
b/lib/tevent/ABI/tevent-0.9.22.sigs
similarity index 100%
copy from lib/tevent/ABI/tevent-0.9.21.sigs
copy to lib/tevent/ABI/tevent-0.9.22.sigs
diff --git a/lib/tevent/tevent_poll.c b/lib/tevent/tevent_poll.c
index 75d0ced..573ba93 100644
--- a/lib/tevent/tevent_poll.c
+++ b/lib/tevent/tevent_poll.c
@@ -58,9 +58,6 @@ struct poll_event_context {
         * Signal fd to wake the poll() thread
         */
        int signal_fd;
-
-       /* information for exiting from the event loop */
-       int exit_code;
 };
 
 static int poll_event_context_destructor(struct poll_event_context *poll_ev)
diff --git a/lib/tevent/tevent_select.c b/lib/tevent/tevent_select.c
index 73f27b7..40a4dc0 100644
--- a/lib/tevent/tevent_select.c
+++ b/lib/tevent/tevent_select.c
@@ -35,9 +35,6 @@ struct select_event_context {
 
        /* the maximum file descriptor number in fd_events */
        int maxfd;
-
-       /* information for exiting from the event loop */
-       int exit_code;
 };
 
 /*
@@ -198,7 +195,7 @@ static int select_event_loop_select(struct 
select_event_context *select_ev, stru
                   fatal error. */
                tevent_debug(select_ev->ev, TEVENT_DEBUG_FATAL,
                             "ERROR: EBADF on select_event_loop_once\n");
-               select_ev->exit_code = EBADF;
+               errno = select_errno;
                return -1;
        }
 
diff --git a/lib/tevent/wscript b/lib/tevent/wscript
index 8d29e04..a991fed 100755
--- a/lib/tevent/wscript
+++ b/lib/tevent/wscript
@@ -1,7 +1,7 @@
 #!/usr/bin/env python
 
 APPNAME = 'tevent'
-VERSION = '0.9.21'
+VERSION = '0.9.22'
 
 blddir = 'bin'
 
diff --git a/source3/include/messages.h b/source3/include/messages.h
index eb0943a..fac561b 100644
--- a/source3/include/messages.h
+++ b/source3/include/messages.h
@@ -105,6 +105,16 @@ NTSTATUS messaging_register(struct messaging_context 
*msg_ctx,
                                       DATA_BLOB *data));
 void messaging_deregister(struct messaging_context *ctx, uint32_t msg_type,
                          void *private_data);
+
+/**
+ * CAVEAT:
+ *
+ * While the messaging_send*() functions are synchronuous by API,
+ * they trigger a tevent-based loop upon sending bigger messages.
+ *
+ * Hence callers should not use these in purely synchonous code,
+ * but run a tevent_loop instead.
+ */
 NTSTATUS messaging_send(struct messaging_context *msg_ctx,
                        struct server_id server, 
                        uint32_t msg_type, const DATA_BLOB *data);
diff --git a/source3/lib/messages.c b/source3/lib/messages.c
index 84147de..aaaee52 100644
--- a/source3/lib/messages.c
+++ b/source3/lib/messages.c
@@ -77,7 +77,7 @@ struct messaging_context {
 };
 
 struct messaging_hdr {
-       int msg_type;
+       uint32_t msg_type;
        struct server_id dst;
        struct server_id src;
 };
@@ -204,7 +204,7 @@ bool message_send_all(struct messaging_context *msg_ctx,
 }
 
 static void messaging_recv_cb(const uint8_t *msg, size_t msg_len,
-                             const int *fds, size_t num_fds,
+                             int *fds, size_t num_fds,
                              void *private_data)
 {
        struct messaging_context *msg_ctx = talloc_get_type_abort(
@@ -231,8 +231,13 @@ static void messaging_recv_cb(const uint8_t *msg, size_t 
msg_len,
                return;
        }
 
+       /*
+        * "consume" the fds by copying them and setting
+        * the original variable to -1
+        */
        for (i=0; i < num_fds; i++) {
                fds64[i] = fds[i];
+               fds[i] = -1;
        }
 
        /*
@@ -515,6 +520,7 @@ NTSTATUS messaging_send_iov(struct messaging_context 
*msg_ctx,
                return NT_STATUS_OK;
        }
 
+       ZERO_STRUCT(hdr);
        hdr = (struct messaging_hdr) {
                .msg_type = msg_type,
                .dst = server,
diff --git a/source3/lib/messages_dgm.c b/source3/lib/messages_dgm.c
index 30ab743..ae35282 100644
--- a/source3/lib/messages_dgm.c
+++ b/source3/lib/messages_dgm.c
@@ -44,7 +44,7 @@ struct messaging_dgm_context {
 
        void (*recv_cb)(const uint8_t *msg,
                        size_t msg_len,
-                       const int *fds,
+                       int *fds,
                        size_t num_fds,
                        void *private_data);
        void *recv_cb_private_data;
@@ -181,7 +181,7 @@ int messaging_dgm_init(struct tevent_context *ev,
                       uid_t dir_owner,
                       void (*recv_cb)(const uint8_t *msg,
                                       size_t msg_len,
-                                      const int *fds,
+                                      int *fds,
                                       size_t num_fds,
                                       void *private_data),
                       void *recv_cb_private_data)
diff --git a/source3/lib/messages_dgm.h b/source3/lib/messages_dgm.h
index be4b1e5..00ff56f 100644
--- a/source3/lib/messages_dgm.h
+++ b/source3/lib/messages_dgm.h
@@ -26,7 +26,7 @@ int messaging_dgm_init(struct tevent_context *ev,
                       uid_t dir_owner,
                       void (*recv_cb)(const uint8_t *msg,
                                       size_t msg_len,
-                                      const int *fds,
+                                      int *fds,
                                       size_t num_fds,
                                       void *private_data),
                       void *recv_cb_private_data);
diff --git a/source3/lib/unix_msg/unix_msg.c b/source3/lib/unix_msg/unix_msg.c
index 01554a2..4870068 100644
--- a/source3/lib/unix_msg/unix_msg.c
+++ b/source3/lib/unix_msg/unix_msg.c
@@ -43,9 +43,8 @@ struct unix_dgram_msg {
        ssize_t sent;
        int sys_errno;
        size_t num_fds;
-       int *fds;
-       size_t buflen;
-       uint8_t buf[];
+       struct msghdr msg;
+       struct iovec iov;
 };
 
 struct unix_dgram_send_queue {
@@ -138,6 +137,32 @@ static int prepare_socket(int sock)
        return prepare_socket_cloexec(sock);
 }
 
+static void extract_fd_array_from_msghdr(struct msghdr *msg, int **fds,
+                                        size_t *num_fds)
+{
+#ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
+       struct cmsghdr *cmsg;
+
+       for(cmsg = CMSG_FIRSTHDR(msg);
+           cmsg != NULL;
+           cmsg = CMSG_NXTHDR(msg, cmsg))
+       {
+               void *data = CMSG_DATA(cmsg);
+
+               if (cmsg->cmsg_type != SCM_RIGHTS) {
+                       continue;
+               }
+               if (cmsg->cmsg_level != SOL_SOCKET) {
+                       continue;
+               }
+
+               *fds = (int *)data;
+               *num_fds = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof (int);
+               break;
+       }
+#endif
+}
+
 static void close_fd_array(int *fds, size_t num_fds)
 {
        size_t i;
@@ -152,6 +177,19 @@ static void close_fd_array(int *fds, size_t num_fds)
        }
 }
 
+static void close_fd_array_cmsg(struct msghdr *msg)
+{
+       int *fds = NULL;
+       size_t num_fds = 0;
+
+       extract_fd_array_from_msghdr(msg, &fds, &num_fds);
+
+       /*
+        * TODO: caveat - side-effect - changing msg ???
+        */
+       close_fd_array(fds, num_fds);
+}
+
 static int unix_dgram_init(const struct sockaddr_un *addr, size_t max_msg,
                           const struct poll_funcs *ev_funcs,
                           void (*recv_callback)(struct unix_dgram_ctx *ctx,
@@ -249,7 +287,6 @@ static void unix_dgram_recv_handler(struct poll_watch *w, 
int fd, short events,
        struct iovec iov;
 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
        char buf[CMSG_SPACE(sizeof(int)*INT8_MAX)] = { 0, };
-       struct cmsghdr *cmsg;
 #endif /* HAVE_STRUCT_MSGHDR_MSG_CONTROL */
        int *fds = NULL;
        size_t i, num_fds = 0;
@@ -289,24 +326,7 @@ static void unix_dgram_recv_handler(struct poll_watch *w, 
int fd, short events,
                return;
        }
 
-#ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
-       for(cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;
-           cmsg = CMSG_NXTHDR(&msg, cmsg))
-       {
-               void *data = CMSG_DATA(cmsg);
-
-               if (cmsg->cmsg_type != SCM_RIGHTS) {
-                       continue;
-               }
-               if (cmsg->cmsg_level != SOL_SOCKET) {
-                       continue;
-               }
-
-               fds = (int *)data;
-               num_fds = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof (int);
-               break;
-       }
-#endif
+       extract_fd_array_from_msghdr(&msg, &fds, &num_fds);
 
        for (i = 0; i < num_fds; i++) {
                int err;
@@ -319,6 +339,12 @@ static void unix_dgram_recv_handler(struct poll_watch *w, 
int fd, short events,
 
        ctx->recv_callback(ctx, ctx->recv_buf, received,
                           fds, num_fds, ctx->private_data);
+
+       /*
+        * Close those fds that the callback has not set to -1.
+        */
+       close_fd_array(fds, num_fds);
+
        return;
 
 cleanup_fds:
@@ -423,7 +449,7 @@ static void unix_dgram_send_queue_free(struct 
unix_dgram_send_queue *q)
                struct unix_dgram_msg *msg;
                msg = q->msgs;
                DLIST_REMOVE(q->msgs, msg);
-               close_fd_array(msg->fds, msg->num_fds);
+               close_fd_array_cmsg(&msg->msg);
                free(msg);
        }
        close(q->sock);
@@ -449,138 +475,139 @@ static int queue_msg(struct unix_dgram_send_queue *q,
                     const int *fds, size_t num_fds)
 {
        struct unix_dgram_msg *msg;
-       ssize_t buflen;
+       ssize_t data_len;
+       uint8_t *data_buf;
        size_t msglen;
-       size_t fds_size = sizeof(int) * num_fds;
-       int fds_copy[MIN(num_fds, INT8_MAX)];
-       size_t fds_padding = 0;
        int i;
        size_t tmp;
        int ret = -1;
+#ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
+       size_t fds_size = sizeof(int) * MIN(num_fds, INT8_MAX);
+       int fds_copy[MIN(num_fds, INT8_MAX)];
+       size_t cmsg_len = CMSG_LEN(fds_size);
+       size_t cmsg_space = CMSG_SPACE(fds_size);
+       char *cmsg_buf;
+#endif /*  HAVE_STRUCT_MSGHDR_MSG_CONTROL */
 
        if (num_fds > INT8_MAX) {
                return EINVAL;
        }
 
-       for (i = 0; i < num_fds; i++) {
-               fds_copy[i] = -1;
+#ifndef HAVE_STRUCT_MSGHDR_MSG_CONTROL
+       if (num_fds > 0) {
+               return ENOSYS;
        }
+#endif
 
-       for (i = 0; i < num_fds; i++) {
-               fds_copy[i] = dup(fds[i]);
-               if (fds_copy[i] == -1) {
-                       ret = errno;
-                       goto fail;
-               }
-       }
+       msglen = sizeof(struct unix_dgram_msg);
+
+       /*
+        * Note: No need to check for overflow here,
+        * since cmsg will store <= INT8_MAX fds.
+        */
+       msglen += cmsg_space;
 
-       buflen = iov_buflen(iov, iovlen);
-       if (buflen == -1) {
-               goto invalid;
+       data_len = iov_buflen(iov, iovlen);
+       if (data_len == -1) {
+               return EINVAL;
        }
 
-       msglen = offsetof(struct unix_dgram_msg, buf);
-       tmp = msglen + buflen;
-       if ((tmp < msglen) || (tmp < buflen)) {
+       tmp = msglen + data_len;
+       if ((tmp < msglen) || (tmp < data_len)) {
                /* overflow */
-               goto invalid;
+               return EINVAL;
        }
        msglen = tmp;
 
-       if (num_fds > 0) {
-               const size_t fds_align = sizeof(int) - 1;
-
-               tmp = msglen + fds_align;
-               if ((tmp < msglen) || (tmp < fds_align)) {
-                       /* overflow */
-                       goto invalid;
-               }
-               tmp &= ~fds_align;
-
-               fds_padding = tmp - msglen;
-               msglen = tmp;
+#ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
+       for (i = 0; i < num_fds; i++) {
+               fds_copy[i] = -1;
+       }
 
-               tmp = msglen + fds_size;
-               if ((tmp < msglen) || (tmp < fds_size)) {
-                       /* overflow */
-                       goto invalid;
+       for (i = 0; i < num_fds; i++) {
+               fds_copy[i] = dup(fds[i]);
+               if (fds_copy[i] == -1) {
+                       ret = errno;
+                       goto fail;
                }
-               msglen = tmp;
        }
+#endif
 
        msg = malloc(msglen);
        if (msg == NULL) {
                ret = ENOMEM;
                goto fail;
        }
-       msg->buflen = buflen;
+
        msg->sock = q->sock;
+       msg->num_fds = num_fds;
 
-       buflen = 0;
-       for (i=0; i<iovlen; i++) {
-               memcpy(&msg->buf[buflen], iov[i].iov_base, iov[i].iov_len);
-               buflen += iov[i].iov_len;
-       }
+       data_buf = (uint8_t *)(msg + 1);
 
-       msg->num_fds = num_fds;
-       if (msg->num_fds > 0) {
-               void *fds_ptr = (void *)&msg->buf[buflen+fds_padding];
-               memcpy(fds_ptr, fds_copy, fds_size);
-               msg->fds = (int *)fds_ptr;
+#ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
+       if (num_fds > 0) {
+               cmsg_buf = (char *)data_buf;
+               memset(cmsg_buf, 0, cmsg_space);
+               data_buf += cmsg_space;
        } else {
-               msg->fds = NULL;
+               cmsg_buf = NULL;
+               cmsg_space = 0;
        }
+#endif
 
-       DLIST_ADD_END(q->msgs, msg, struct unix_dgram_msg);
-       return 0;
-
-invalid:
-       ret = EINVAL;
-fail:
-       close_fd_array(fds_copy, num_fds);
-       return ret;
-}
-
-static void unix_dgram_send_job(void *private_data)
-{
-       struct unix_dgram_msg *dmsg = private_data;
-       struct iovec iov = {
-               .iov_base = (void *)dmsg->buf,
-               .iov_len = dmsg->buflen,
+       msg->iov = (struct iovec) {
+               .iov_base = (void *)data_buf,
+               .iov_len = data_len,
        };
-       struct msghdr msg = {
-               .msg_iov = &iov,
+
+       msg->msg = (struct msghdr) {
+               .msg_iov = &msg->iov,
                .msg_iovlen = 1,
-       };
 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
-       struct cmsghdr *cmsg;
-       size_t fds_size = sizeof(int) * dmsg->num_fds;
-       size_t cmsg_len = CMSG_LEN(fds_size);
-       size_t cmsg_space = CMSG_SPACE(fds_size);
-       char cmsg_buf[cmsg_space];
+               .msg_control = cmsg_buf,
+               .msg_controllen = cmsg_space,
+#endif
+       };
 
-       if (dmsg->num_fds > 0) {
+#ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
+       if (num_fds > 0) {
+               struct cmsghdr *cmsg;
                void *fdptr;
 
-               memset(cmsg_buf, 0, cmsg_space);
-
-               msg.msg_control = cmsg_buf;
-               msg.msg_controllen = cmsg_space;
-               cmsg = CMSG_FIRSTHDR(&msg);
+               cmsg = CMSG_FIRSTHDR(&msg->msg);
                cmsg->cmsg_level = SOL_SOCKET;
                cmsg->cmsg_type = SCM_RIGHTS;
                cmsg->cmsg_len = cmsg_len;
                fdptr = CMSG_DATA(cmsg);
-               memcpy(fdptr, dmsg->fds, fds_size);
-               msg.msg_controllen = cmsg->cmsg_len;
+               memcpy(fdptr, fds_copy, fds_size);
+               msg->msg.msg_controllen = cmsg->cmsg_len;
        }
 #endif /*  HAVE_STRUCT_MSGHDR_MSG_CONTROL */
 
+       for (i=0; i<iovlen; i++) {
+               memcpy(data_buf, iov[i].iov_base, iov[i].iov_len);
+               data_buf += iov[i].iov_len;
+       }
+
+       DLIST_ADD_END(q->msgs, msg, struct unix_dgram_msg);
+       return 0;
+
+fail:
+       close_fd_array(fds_copy, num_fds);
+       return ret;
+}
+
+static void unix_dgram_send_job(void *private_data)
+{
+       struct unix_dgram_msg *dmsg = private_data;
+
        do {
-               dmsg->sent = sendmsg(dmsg->sock, &msg, 0);
+               dmsg->sent = sendmsg(dmsg->sock, &dmsg->msg, 0);
        } while ((dmsg->sent == -1) && (errno == EINTR));
 
-       close_fd_array(dmsg->fds, dmsg->num_fds);
+       if (dmsg->sent == -1) {
+               dmsg->sys_errno = errno;
+       }
 }


-- 
Samba Shared Repository

Reply via email to