[SCM] Samba Shared Repository - branch master updated - b4f8996ac79309a3ff4cd299e7978ec9f993a5c4

Volker Lendecke vlendec at samba.org
Sun Jan 4 15:43:27 GMT 2009


The branch, master has been updated
       via  b4f8996ac79309a3ff4cd299e7978ec9f993a5c4 (commit)
       via  0cc63c64166d2e26b7a7ffc0e78ea6041de35f53 (commit)
       via  19b783cce9edf7b616cd1a9d9dcb78a02791d89e (commit)
       via  1b328d98208d4245733dc8e04f6b81ab606ead8c (commit)
       via  4df681abf497c24e8abf3df1137023389bfed709 (commit)
       via  8c1691d2139e49d6fb47a6d85400a1b7b91ffd67 (commit)
       via  d933362cb7fdd93fef860feeac1d86b180e29a59 (commit)
       via  c6c33d840ba90686fcdc81b49b5e256270b97f29 (commit)
       via  34e8945cb5d0568e511708779d2c33cc59ed54e1 (commit)
       via  611f0d7ee607bad65b7a40ba2f0195ba987f1cab (commit)
       via  ebacce2efe6dbb27a9e7962597da8ef783473f6a (commit)
      from  e058e51d63d4a476a1b49941cd8a8611d9164eba (commit)

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


- Log -----------------------------------------------------------------
commit b4f8996ac79309a3ff4cd299e7978ec9f993a5c4
Author: Volker Lendecke <vl at samba.org>
Date:   Sun Jan 4 01:46:05 2009 +0100

    Simulate the Windows behaviour to fire 445 and after a timeout 139

commit 0cc63c64166d2e26b7a7ffc0e78ea6041de35f53
Author: Volker Lendecke <vl at samba.org>
Date:   Sun Jan 4 01:45:06 2009 +0100

    Add open_socket_out_defer_send/recv

commit 19b783cce9edf7b616cd1a9d9dcb78a02791d89e
Author: Volker Lendecke <vl at samba.org>
Date:   Sat Jan 3 19:50:05 2009 +0100

    Async wrapper for open_socket_out_send/recv

commit 1b328d98208d4245733dc8e04f6b81ab606ead8c
Author: Volker Lendecke <vl at samba.org>
Date:   Sun Dec 28 17:43:18 2008 +0100

    Add a quick test of wb_trans_send/recv

commit 4df681abf497c24e8abf3df1137023389bfed709
Author: Volker Lendecke <vl at samba.org>
Date:   Sat Dec 27 18:43:03 2008 +0100

    async libwbclient infrastructure

commit 8c1691d2139e49d6fb47a6d85400a1b7b91ffd67
Author: Volker Lendecke <vl at samba.org>
Date:   Sun Dec 28 14:49:22 2008 +0100

    Remove wb_trans_send/recv

commit d933362cb7fdd93fef860feeac1d86b180e29a59
Author: Volker Lendecke <vl at samba.org>
Date:   Sun Dec 28 14:47:40 2008 +0100

    Move winbindd/winbindd_reqtrans.c to lib/wb_reqtrans.c

commit c6c33d840ba90686fcdc81b49b5e256270b97f29
Author: Volker Lendecke <vl at samba.org>
Date:   Sun Jan 4 00:26:49 2009 +0100

    Convert async_connect to "normal" style

commit 34e8945cb5d0568e511708779d2c33cc59ed54e1
Author: Volker Lendecke <vl at samba.org>
Date:   Sat Jan 3 19:23:13 2009 +0100

    Actually do a non-blocking connect.... :-)

commit 611f0d7ee607bad65b7a40ba2f0195ba987f1cab
Author: Volker Lendecke <vl at samba.org>
Date:   Sun Jan 4 11:28:40 2009 +0100

    Add an async queueing mechanism

commit ebacce2efe6dbb27a9e7962597da8ef783473f6a
Author: Volker Lendecke <vl at samba.org>
Date:   Sat Jan 3 19:10:57 2009 +0100

    Add async timeout helpers

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

Summary of changes:
 source3/Makefile.in                        |    2 +-
 source3/include/async_req.h                |   18 +
 source3/include/async_sock.h               |    8 +-
 source3/include/proto.h                    |   28 +-
 source3/include/smb.h                      |    1 +
 source3/lib/async_req.c                    |  120 +++++
 source3/lib/async_sock.c                   |  216 ++++----
 source3/lib/util_sock.c                    |  337 ++++++++++--
 source3/lib/wb_reqtrans.c                  |  542 +++++++++++++++++++
 source3/lib/wbclient.c                     |  774 ++++++++++++++++++++++++++++
 source3/libads/krb5_setpw.c                |   31 +-
 source3/libsmb/cliconnect.c                |   95 +++-
 source3/modules/vfs_smb_traffic_analyzer.c |    5 +-
 source3/rpc_client/cli_pipe.c              |    5 +-
 source3/torture/torture.c                  |   65 +++
 source3/winbindd/winbindd_proto.h          |    9 -
 source3/winbindd/winbindd_reqtrans.c       |  685 ------------------------
 17 files changed, 2051 insertions(+), 890 deletions(-)
 create mode 100644 source3/lib/wb_reqtrans.c
 create mode 100644 source3/lib/wbclient.c
 delete mode 100644 source3/winbindd/winbindd_reqtrans.c


Changeset truncated at 500 lines:

diff --git a/source3/Makefile.in b/source3/Makefile.in
index 49f576f..c13f5ae 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -930,6 +930,7 @@ SMBTORTURE_OBJ1 = torture/torture.o torture/nbio.o torture/scanner.o torture/uta
 
 SMBTORTURE_OBJ = $(SMBTORTURE_OBJ1) $(PARAM_OBJ) \
 	$(LIBSMB_OBJ) $(KRBCLIENT_OBJ) $(LIB_NONSMBD_OBJ) \
+	lib/wb_reqtrans.o lib/wbclient.o \
 	$(LIBNDR_GEN_OBJ0)
 
 MASKTEST_OBJ = torture/masktest.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) \
@@ -1029,7 +1030,6 @@ IDMAP_ADEX_OBJ = \
 
 WINBINDD_OBJ1 = \
 		winbindd/winbindd.o       \
-		winbindd/winbindd_reqtrans.o \
 		winbindd/winbindd_user.o  \
 		winbindd/winbindd_group.o \
 		winbindd/winbindd_util.o  \
diff --git a/source3/include/async_req.h b/source3/include/async_req.h
index 2633027..1b8dbf3 100644
--- a/source3/include/async_req.h
+++ b/source3/include/async_req.h
@@ -132,4 +132,22 @@ bool async_req_is_error(struct async_req *req, NTSTATUS *status);
 
 NTSTATUS async_req_simple_recv(struct async_req *req);
 
+bool async_req_set_timeout(struct async_req *req, struct event_context *ev,
+			   struct timeval to);
+
+struct async_req *async_wait_send(TALLOC_CTX *mem_ctx,
+				  struct event_context *ev,
+				  struct timeval to);
+
+NTSTATUS async_wait_recv(struct async_req *req);
+
+struct async_req_queue;
+
+struct async_req_queue *async_req_queue_init(TALLOC_CTX *mem_ctx);
+
+bool async_req_enqueue(struct async_req_queue *queue,
+		       struct event_context *ev,
+		       struct async_req *req,
+		       void (*trigger)(struct async_req *req));
+
 #endif
diff --git a/source3/include/async_sock.h b/source3/include/async_sock.h
index 892ffef..c6f95d6 100644
--- a/source3/include/async_sock.h
+++ b/source3/include/async_sock.h
@@ -32,9 +32,11 @@ struct async_req *async_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
 struct async_req *async_recv(TALLOC_CTX *mem_ctx, struct event_context *ev,
 			     int fd, void *buffer, size_t length,
 			     int flags);
-struct async_req *async_connect(TALLOC_CTX *mem_ctx, struct event_context *ev,
-				int fd, const struct sockaddr *address,
-				socklen_t address_len);
+struct async_req *async_connect_send(TALLOC_CTX *mem_ctx,
+				     struct event_context *ev,
+				     int fd, const struct sockaddr *address,
+				     socklen_t address_len);
+NTSTATUS async_connect_recv(struct async_req *req, int *perrno);
 
 struct async_req *sendall_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
 			       int fd, const void *buffer, size_t length,
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 42d1f52..6238ba3 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -1457,9 +1457,21 @@ int open_socket_in(int type,
 		int dlevel,
 		const struct sockaddr_storage *psock,
 		bool rebind);
-int open_socket_out(const struct sockaddr_storage *pss,
-		uint16_t port,
-		int timeout);
+NTSTATUS open_socket_out(const struct sockaddr_storage *pss, uint16_t port,
+			 int timeout, int *pfd);
+struct async_req *open_socket_out_send(TALLOC_CTX *mem_ctx,
+				       struct event_context *ev,
+				       const struct sockaddr_storage *pss,
+				       uint16_t port,
+				       int timeout);
+NTSTATUS open_socket_out_recv(struct async_req *req, int *pfd);
+struct async_req *open_socket_out_defer_send(TALLOC_CTX *mem_ctx,
+					     struct event_context *ev,
+					     struct timeval wait_time,
+					     const struct sockaddr_storage *pss,
+					     uint16_t port,
+					     int timeout);
+NTSTATUS open_socket_out_defer_recv(struct async_req *req, int *pfd);
 bool open_any_socket_out(struct sockaddr_storage *addrs, int num_addrs,
 			 int timeout, int *fd_index, int *fd);
 int open_udp_socket(const char *host, int port);
@@ -7982,4 +7994,14 @@ NTSTATUS idmap_sid_to_gid(const char *domname, DOM_SID *sid, gid_t *gid);
 
 NTSTATUS nss_info_template_init( void );
 
+/* Misc protos */
+
+struct async_req *wb_trans_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
+				struct wb_context *wb_ctx, bool need_priv,
+				const struct winbindd_request *wb_req);
+NTSTATUS wb_trans_recv(struct async_req *req, TALLOC_CTX *mem_ctx,
+		       struct winbindd_response **presponse);
+struct wb_context *wb_context_init(TALLOC_CTX *mem_ctx);
+
+
 #endif /*  _PROTO_H_  */
diff --git a/source3/include/smb.h b/source3/include/smb.h
index 3253773..7fd4fbb 100644
--- a/source3/include/smb.h
+++ b/source3/include/smb.h
@@ -369,6 +369,7 @@ struct share_mode_entry;
 struct uuid;
 struct named_mutex;
 struct pcap_cache;
+struct wb_context;
 
 struct vfs_fsp_data {
     struct vfs_fsp_data *next;
diff --git a/source3/lib/async_req.c b/source3/lib/async_req.c
index 8c9b2e6..ac06df6 100644
--- a/source3/lib/async_req.c
+++ b/source3/lib/async_req.c
@@ -194,3 +194,123 @@ NTSTATUS async_req_simple_recv(struct async_req *req)
 	}
 	return NT_STATUS_OK;
 }
+
+static void async_req_timedout(struct event_context *ev,
+			       struct timed_event *te,
+			       const struct timeval *now,
+			       void *priv)
+{
+	struct async_req *req = talloc_get_type_abort(
+		priv, struct async_req);
+	TALLOC_FREE(te);
+	async_req_error(req, NT_STATUS_IO_TIMEOUT);
+}
+
+bool async_req_set_timeout(struct async_req *req, struct event_context *ev,
+			   struct timeval to)
+{
+	return (event_add_timed(ev, req,
+				timeval_current_ofs(to.tv_sec, to.tv_usec),
+				"async_req_timedout", async_req_timedout, req)
+		!= NULL);
+}
+
+struct async_req *async_wait_send(TALLOC_CTX *mem_ctx,
+				  struct event_context *ev,
+				  struct timeval to)
+{
+	struct async_req *result;
+
+	result = async_req_new(mem_ctx);
+	if (result == NULL) {
+		return result;
+	}
+	if (!async_req_set_timeout(result, ev, to)) {
+		TALLOC_FREE(result);
+		return NULL;
+	}
+	return result;
+}
+
+NTSTATUS async_wait_recv(struct async_req *req)
+{
+	return NT_STATUS_OK;
+}
+
+struct async_queue_entry {
+	struct async_queue_entry *prev, *next;
+	struct async_req_queue *queue;
+	struct async_req *req;
+	void (*trigger)(struct async_req *req);
+};
+
+struct async_req_queue {
+	struct async_queue_entry *queue;
+};
+
+struct async_req_queue *async_req_queue_init(TALLOC_CTX *mem_ctx)
+{
+	return TALLOC_ZERO_P(mem_ctx, struct async_req_queue);
+}
+
+static int async_queue_entry_destructor(struct async_queue_entry *e)
+{
+	struct async_req_queue *queue = e->queue;
+
+	DLIST_REMOVE(queue->queue, e);
+
+	if (queue->queue != NULL) {
+		queue->queue->trigger(queue->queue->req);
+	}
+
+	return 0;
+}
+
+static void async_req_immediate_trigger(struct event_context *ev,
+					struct timed_event *te,
+					const struct timeval *now,
+					void *priv)
+{
+	struct async_queue_entry *e = talloc_get_type_abort(
+		priv, struct async_queue_entry);
+
+	TALLOC_FREE(te);
+	e->trigger(e->req);
+}
+
+bool async_req_enqueue(struct async_req_queue *queue, struct event_context *ev,
+		       struct async_req *req,
+		       void (*trigger)(struct async_req *req))
+{
+	struct async_queue_entry *e;
+	bool busy;
+
+	busy = (queue->queue != NULL);
+
+	e = talloc(req, struct async_queue_entry);
+	if (e == NULL) {
+		return false;
+	}
+
+	e->req = req;
+	e->trigger = trigger;
+	e->queue = queue;
+
+	DLIST_ADD_END(queue->queue, e, struct async_queue_entry *);
+	talloc_set_destructor(e, async_queue_entry_destructor);
+
+	if (!busy) {
+		struct timed_event *te;
+
+		te = event_add_timed(ev, e, timeval_zero(),
+				     "async_req_immediate_trigger",
+				     async_req_immediate_trigger,
+				     e);
+		if (te == NULL) {
+			TALLOC_FREE(e);
+			return false;
+		}
+	}
+
+	return true;
+}
diff --git a/source3/lib/async_sock.c b/source3/lib/async_sock.c
index 107d140..bb89a13 100644
--- a/source3/lib/async_sock.c
+++ b/source3/lib/async_sock.c
@@ -535,63 +535,16 @@ NTSTATUS recvall_recv(struct async_req *req)
 	return async_req_simple_recv(req);
 }
 
-/**
- * fde event handler for connect(2)
- * @param[in] ev	The event context that sent us here
- * @param[in] fde	The file descriptor event associated with the connect
- * @param[in] flags	Indicate read/writeability of the socket
- * @param[in] priv	private data, "struct async_req *" in this case
- */
-
-static void async_connect_callback(struct event_context *ev,
-				   struct fd_event *fde, uint16_t flags,
-				   void *priv)
-{
-	struct async_req *req = talloc_get_type_abort(
-		priv, struct async_req);
-	struct async_syscall_state *state = talloc_get_type_abort(
-		req->private_data, struct async_syscall_state);
-	struct param_connect *p = &state->param.param_connect;
-
-	if (state->syscall_type != ASYNC_SYSCALL_CONNECT) {
-		async_req_error(req, NT_STATUS_INTERNAL_ERROR);
-		return;
-	}
-
-	TALLOC_FREE(state->fde);
-
-	/*
-	 * Stevens, Network Programming says that if there's a
-	 * successful connect, the socket is only writable. Upon an
-	 * error, it's both readable and writable.
-	 */
-	if ((flags & (EVENT_FD_READ|EVENT_FD_WRITE))
-	    == (EVENT_FD_READ|EVENT_FD_WRITE)) {
-		int sockerr;
-		socklen_t err_len = sizeof(sockerr);
-
-		if (getsockopt(p->fd, SOL_SOCKET, SO_ERROR,
-			       (void *)&sockerr, &err_len) == 0) {
-			errno = sockerr;
-		}
-
-		state->sys_errno = errno;
-
-		DEBUG(10, ("connect returned %s\n", strerror(errno)));
-
-		sys_fcntl_long(p->fd, F_SETFL, p->old_sockflags);
-
-		async_req_error(req, map_nt_error_from_unix(state->sys_errno));
-		return;
-	}
-
-	sys_fcntl_long(p->fd, F_SETFL, p->old_sockflags);
-
-	state->result.result_int = 0;
-	state->sys_errno = 0;
+struct async_connect_state {
+	int fd;
+	int result;
+	int sys_errno;
+	long old_sockflags;
+};
 
-	async_req_done(req);
-}
+static void async_connect_connected(struct event_context *ev,
+				    struct fd_event *fde, uint16_t flags,
+				    void *priv);
 
 /**
  * @brief async version of connect(2)
@@ -606,48 +559,46 @@ static void async_connect_callback(struct event_context *ev,
  * connect in an async state. This will be reset when the request is finished.
  */
 
-struct async_req *async_connect(TALLOC_CTX *mem_ctx, struct event_context *ev,
-				int fd, const struct sockaddr *address,
-				socklen_t address_len)
+struct async_req *async_connect_send(TALLOC_CTX *mem_ctx,
+				     struct event_context *ev,
+				     int fd, const struct sockaddr *address,
+				     socklen_t address_len)
 {
 	struct async_req *result;
-	struct async_syscall_state *state;
-	struct param_connect *p;
+	struct async_connect_state *state;
+	struct fd_event *fde;
+	NTSTATUS status;
 
-	result = async_syscall_new(mem_ctx, ev, ASYNC_SYSCALL_CONNECT, &state);
+	result = async_req_new(mem_ctx);
 	if (result == NULL) {
 		return NULL;
 	}
-	p = &state->param.param_connect;
+	state = talloc(result, struct async_connect_state);
+	if (state == NULL) {
+		goto fail;
+	}
+	result->private_data = state;
 
 	/**
 	 * We have to set the socket to nonblocking for async connect(2). Keep
 	 * the old sockflags around.
 	 */
 
-	p->old_sockflags = sys_fcntl_long(fd, F_GETFL, 0);
+	state->fd = fd;
+	state->sys_errno = 0;
 
-	if (p->old_sockflags == -1) {
-		if (async_post_status(result, ev,
-				      map_nt_error_from_unix(errno))) {
-			return result;
-		}
-		TALLOC_FREE(result);
-		return NULL;
+	state->old_sockflags = sys_fcntl_long(fd, F_GETFL, 0);
+	if (state->old_sockflags == -1) {
+		goto post_errno;
 	}
 
-	set_blocking(fd, true);
-
-	state->result.result_int = connect(fd, address, address_len);
+	set_blocking(fd, false);
 
-	if (state->result.result_int == 0) {
+	state->result = connect(fd, address, address_len);
+	if (state->result == 0) {
 		state->sys_errno = 0;
-		if (async_post_status(result, ev, NT_STATUS_OK)) {
-			return result;
-		}
-		sys_fcntl_long(fd, F_SETFL, p->old_sockflags);
-		TALLOC_FREE(result);
-		return NULL;
+		status = NT_STATUS_OK;
+		goto post_status;
 	}
 
 	/**
@@ -662,32 +613,93 @@ struct async_req *async_connect(TALLOC_CTX *mem_ctx, struct event_context *ev,
 	      errno == EISCONN ||
 #endif
 	      errno == EAGAIN || errno == EINTR)) {
+		goto post_errno;
+	}
 
-		state->sys_errno = errno;
-
-		if (async_post_status(result, ev,
-				      map_nt_error_from_unix(errno))) {
-			return result;
-		}
-		sys_fcntl_long(fd, F_SETFL, p->old_sockflags);
-		TALLOC_FREE(result);
-		return NULL;
+	fde = event_add_fd(ev, state, fd, EVENT_FD_READ | EVENT_FD_WRITE,
+			   async_connect_connected, result);
+	if (fde == NULL) {
+		status = NT_STATUS_NO_MEMORY;
+		goto post_status;
 	}
+	return result;
 
-	state->fde = event_add_fd(ev, state, fd,
-				  EVENT_FD_READ | EVENT_FD_WRITE,
-				  async_connect_callback, result);
-	if (state->fde == NULL) {
-		sys_fcntl_long(fd, F_SETFL, p->old_sockflags);
-		TALLOC_FREE(result);
-		return NULL;
+ post_errno:
+	state->sys_errno = errno;
+	status = map_nt_error_from_unix(state->sys_errno);
+ post_status:
+	sys_fcntl_long(fd, F_SETFL, state->old_sockflags);
+	if (!async_post_status(result, ev, status)) {
+		goto fail;
 	}
-	result->private_data = state;
+	return result;
+ fail:
+	TALLOC_FREE(result);
+	return NULL;
+}
 
-	state->param.param_connect.fd = fd;
-	state->param.param_connect.address = address;
-	state->param.param_connect.address_len = address_len;
+/**
+ * fde event handler for connect(2)
+ * @param[in] ev	The event context that sent us here
+ * @param[in] fde	The file descriptor event associated with the connect
+ * @param[in] flags	Indicate read/writeability of the socket
+ * @param[in] priv	private data, "struct async_req *" in this case
+ */
 
-	return result;
+static void async_connect_connected(struct event_context *ev,
+				    struct fd_event *fde, uint16_t flags,
+				    void *priv)
+{
+	struct async_req *req = talloc_get_type_abort(
+		priv, struct async_req);
+	struct async_connect_state *state = talloc_get_type_abort(
+		req->private_data, struct async_connect_state);
+
+	TALLOC_FREE(fde);
+
+	/*
+	 * Stevens, Network Programming says that if there's a
+	 * successful connect, the socket is only writable. Upon an
+	 * error, it's both readable and writable.
+	 */
+	if ((flags & (EVENT_FD_READ|EVENT_FD_WRITE))
+	    == (EVENT_FD_READ|EVENT_FD_WRITE)) {
+		int sockerr;
+		socklen_t err_len = sizeof(sockerr);
+
+		if (getsockopt(state->fd, SOL_SOCKET, SO_ERROR,
+			       (void *)&sockerr, &err_len) == 0) {
+			errno = sockerr;
+		}
+
+		state->sys_errno = errno;
+
+		DEBUG(10, ("connect returned %s\n", strerror(errno)));
+
+		sys_fcntl_long(state->fd, F_SETFL, state->old_sockflags);
+		async_req_error(req, map_nt_error_from_unix(state->sys_errno));
+		return;
+	}
+
+	state->sys_errno = 0;
+	async_req_done(req);
 }
 
+NTSTATUS async_connect_recv(struct async_req *req, int *perrno)
+{
+	struct async_connect_state *state = talloc_get_type_abort(
+		req->private_data, struct async_connect_state);


-- 
Samba Shared Repository


More information about the samba-cvs mailing list