[SCM] Samba Shared Repository - branch master updated

Michael Adam obnox at samba.org
Tue Sep 30 11:02:04 MDT 2014


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 <obnox at samba.org>
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 <obnox at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>
    
    Autobuild-User(master): Michael Adam <obnox at samba.org>
    Autobuild-Date(master): Tue Sep 30 19:01:30 CEST 2014 on sn-devel-104

commit d4bf2be62fe1ce5f41a080fdf2301b2124d27eef
Author: Michael Adam <obnox at samba.org>
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 <obnox at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit 36281029384ffdea495bb1da6c68f2905785d270
Author: Michael Adam <obnox at samba.org>
Date:   Tue Sep 30 10:13:17 2014 +0200

    s3:torture: fix a message in LOCAL-MESSAGING-FDPASS2 test
    
    Signed-off-by: Michael Adam <obnox at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit bc5c029a08a3d2c199379f6244999b57fdad5a0d
Author: Michael Adam <obnox at samba.org>
Date:   Tue Sep 30 00:30:58 2014 +0200

    selftest: run LOCAL-MESSAGING-READ4
    
    Signed-off-by: Michael Adam <obnox at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit f16dd644aaec0071b06057d74b54fb8b508a74f7
Author: Michael Adam <obnox at samba.org>
Date:   Thu Sep 25 00:28:14 2014 +0200

    s3:torture: add LOCAL-MESSAGING-READ4 - send 1MB message
    
    Signed-off-by: Michael Adam <obnox at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit 797ada104e4a68f601e473c46dbb33871dda12e1
Author: Michael Adam <obnox at samba.org>
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 <obnox at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit d7d9ec31dfe5d797307a7d107f0874260e7eab4a
Author: Michael Adam <obnox at samba.org>
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 <vl at samba.org>
    
    Signed-off-by: Michael Adam <obnox at samba.org>
    Signed-off-by: Volker Lendecke <vl at samba.org>

commit 0ab5e895f7869ea07624c666cc620576a7fde289
Author: Michael Adam <obnox at samba.org>
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 <obnox at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit 6e47886b154ed89182a56233d55c650885432907
Author: Michael Adam <obnox at samba.org>
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 <obnox at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit 00d9ee04dd0f5c2fe5e0cd7108ed7da4b981c258
Author: Michael Adam <obnox at samba.org>
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 <obnox at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit d8af3e76a362328a854aeb83f8699443e77d2a8d
Author: Michael Adam <obnox at samba.org>
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 <vl at samba.org>
    Pair-Programmed-With: Stefan Metzmacher <metze at samba.org>
    
    Signed-off-by: Michael Adam <obnox at samba.org>
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Signed-off-by: Stefan Metzmacher <metze at samba.org>

commit b38ed7311af0862945e417b6f6350b7bc6b0be20
Author: Michael Adam <obnox at samba.org>
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 <obnox at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit 20cd934ec04e601a6bac6fc1dd61c75767c6213f
Author: Michael Adam <obnox at samba.org>
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 <obnox at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit 67684dc69585559fae6718837bf6c5ba83af267f
Author: Michael Adam <obnox at samba.org>
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 <vl at samba.org>
    Pair-Programmed-With: Stefan Metzmacher <metze at samba.org>
    
    Signed-off-by: Michael Adam <obnox at samba.org>
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Signed-off-by: Stefan Metzmacher <metze at samba.org>

commit a96f0f4c3bd66cb44f882a836bf80b2ce39523e0
Author: Michael Adam <obnox at samba.org>
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 <vl at samba.org>
    Pair-Programmed-With: Stefan Metzmacher <metze at samba.org>
    
    Signed-off-by: Michael Adam <obnox at samba.org>
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Signed-off-by: Stefan Metzmacher <metze at samba.org>

commit e38f4f4ceb5b2605dd0804ab7629f9b5e8d5cd5c
Author: Michael Adam <obnox at samba.org>
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 <vl at samba.org>
    Pair-Programmed-With: Stefan Metzmacher <metze at samba.org>
    
    Signed-off-by: Michael Adam <obnox at samba.org>
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Signed-off-by: Stefan Metzmacher <metze at samba.org>

commit 2564a5fa578058953c9c2890566b4fdd51a744be
Author: Michael Adam <obnox at samba.org>
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 <vl at samba.org>
    Pair-Programmed-With: Stefan Metzmacher <metze at samba.org>
    
    Signed-off-by: Michael Adam <obnox at samba.org>
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Signed-off-by: Stefan Metzmacher <metze at samba.org>

commit 9ddb66128134f9d8386a6db776dc226c6a3b14ac
Author: Michael Adam <obnox at samba.org>
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 <vl at samba.org>
    Pair-Programmed-With: Stefan Metzmacher <metze at samba.org>
    
    Signed-off-by: Michael Adam <obnox at samba.org>
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Signed-off-by: Stefan Metzmacher <metze at samba.org>

commit 9fa673bf37d59b14b113df978da58be4e3e58d7d
Author: Michael Adam <obnox at samba.org>
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 <vl at samba.org>
    Pair-Programmed-With: Stefan Metzmacher <metze at samba.org>
    
    Signed-off-by: Michael Adam <obnox at samba.org>
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Signed-off-by: Stefan Metzmacher <metze at samba.org>

commit 698e8a235740d4cedc5635b9f64da16cb3cb1f01
Author: Michael Adam <obnox at samba.org>
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 <obnox at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit 2795bdfd9ffd5c69402543d6f5f22b53e9d357a6
Author: Michael Adam <obnox at samba.org>
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 <obnox at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit 40b48534dfde7d17112a18d2e4e8fc24ee1adfc8
Author: Michael Adam <obnox at samba.org>
Date:   Mon Sep 29 11:01:11 2014 +0200

    s3:messaging: fix uninitialized data introduced by padding
    
    Signed-off-by: Michael Adam <obnox at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit 1dbd0bec040060193f1d2f1b5a97db1bd340c1ca
Author: Stefan Metzmacher <metze at samba.org>
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 <metze at samba.org>
    Reviewed-by: Michael Adam <obnox at samba.org>

commit a65df7e8c0ce687625a18de5769bf38f92118eca
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Jul 22 14:54:11 2014 +0200

    tevent: remove unused exit_code in tevent_select.c
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Michael Adam <obnox at samba.org>

commit 1ea3364721522dcd68fee629b017e72ab35ff6e1
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Jul 22 14:54:11 2014 +0200

    tevent: remove unused exit_code in tevent_poll.c
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Michael Adam <obnox at samba.org>

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

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


More information about the samba-cvs mailing list