The Samba-Bugzilla – Attachment 11347 Details for
Bug 11316
tevent_fd needs to be destroyed before closing the fd
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Backport on top of v4-1-test, but not for v4-1-test (requires bug #11330 tevent-0.9.25)
tmp41.diff.txt (text/plain), 102.01 KB, created by
Stefan Metzmacher
on 2015-08-17 20:35:03 UTC
(
hide
)
Description:
Backport on top of v4-1-test, but not for v4-1-test (requires bug #11330 tevent-0.9.25)
Filename:
MIME Type:
Creator:
Stefan Metzmacher
Created:
2015-08-17 20:35:03 UTC
Size:
102.01 KB
patch
obsolete
>From 2568ca2d932d70bab2aef106c38ad754762fd3e0 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 8 Jan 2014 10:31:15 +0100 >Subject: [PATCH 01/31] libcli/smb: make use of tevent_req_set_cleanup_fn() > >This is more better than a custom tevent_req destructor. > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit f08c0b2ef1bb92928ae86ba9d1c276a8e117367c) >--- > libcli/smb/smbXcli_base.c | 26 ++++++++++++++++---------- > 1 file changed, 16 insertions(+), 10 deletions(-) > >diff --git a/libcli/smb/smbXcli_base.c b/libcli/smb/smbXcli_base.c >index 5063e59..8a1a51a 100644 >--- a/libcli/smb/smbXcli_base.c >+++ b/libcli/smb/smbXcli_base.c >@@ -792,7 +792,7 @@ void smbXcli_req_unset_pending(struct tevent_req *req) > return; > } > >- talloc_set_destructor(req, NULL); >+ tevent_req_set_cleanup_fn(req, NULL); > > if (num_pending == 1) { > /* >@@ -835,19 +835,25 @@ void smbXcli_req_unset_pending(struct tevent_req *req) > return; > } > >-static int smbXcli_req_destructor(struct tevent_req *req) >+static void smbXcli_req_cleanup(struct tevent_req *req, >+ enum tevent_req_state req_state) > { > struct smbXcli_req_state *state = > tevent_req_data(req, > struct smbXcli_req_state); > >- /* >- * Make sure we really remove it from >- * the pending array on destruction. >- */ >- state->smb1.mid = 0; >- smbXcli_req_unset_pending(req); >- return 0; >+ switch (req_state) { >+ case TEVENT_REQ_RECEIVED: >+ /* >+ * Make sure we really remove it from >+ * the pending array on destruction. >+ */ >+ state->smb1.mid = 0; >+ smbXcli_req_unset_pending(req); >+ return; >+ default: >+ return; >+ } > } > > static bool smb1cli_req_cancel(struct tevent_req *req); >@@ -900,7 +906,7 @@ bool smbXcli_req_set_pending(struct tevent_req *req) > } > pending[num_pending] = req; > conn->pending = pending; >- talloc_set_destructor(req, smbXcli_req_destructor); >+ tevent_req_set_cleanup_fn(req, smbXcli_req_cleanup); > tevent_req_set_cancel_fn(req, smbXcli_req_cancel); > > if (!smbXcli_conn_receive_next(conn)) { >-- >1.9.1 > > >From db7996b2658000b3b4d0c2ea0f1d57fbe092cce3 Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Sat, 8 Nov 2014 09:00:31 +0000 >Subject: [PATCH 02/31] lib: Add tevent_req_simple_recv_unix > >Signed-off-by: Volker Lendecke <vl@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit f5c17d41e085e083ef970692ff7f50f7a6642ea3) >--- > lib/util/tevent_unix.c | 13 +++++++++++++ > lib/util/tevent_unix.h | 1 + > 2 files changed, 14 insertions(+) > >diff --git a/lib/util/tevent_unix.c b/lib/util/tevent_unix.c >index e4c960e..ee7ec8a 100644 >--- a/lib/util/tevent_unix.c >+++ b/lib/util/tevent_unix.c >@@ -48,3 +48,16 @@ bool tevent_req_is_unix_error(struct tevent_req *req, int *perrno) > } > return true; > } >+ >+int tevent_req_simple_recv_unix(struct tevent_req *req) >+{ >+ int err = 0; >+ >+ /* >+ * Ignore result of tevent_req_is_unix_error, we're only interested in >+ * the status >+ */ >+ tevent_req_is_unix_error(req, &err); >+ tevent_req_received(req); >+ return err; >+} >diff --git a/lib/util/tevent_unix.h b/lib/util/tevent_unix.h >index 377e976..c1b0eb4 100644 >--- a/lib/util/tevent_unix.h >+++ b/lib/util/tevent_unix.h >@@ -27,5 +27,6 @@ > #include <tevent.h> > > bool tevent_req_is_unix_error(struct tevent_req *req, int *perrno); >+int tevent_req_simple_recv_unix(struct tevent_req *req); > > #endif >-- >1.9.1 > > >From 5e5d508b7cfcbec723f90a3bb23853f2813d1ff3 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 21 May 2015 11:37:06 +0200 >Subject: [PATCH 03/31] lib/tsocket: add tdgram_bsd_existing_socket() helper > function > >This is similar to tstream_bsd_existing_socket(). >Both help to migrate strange code path to using the tstream or tdgram >abstractions. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=11316 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit 3a8b7b0518b33b016d2dbb8dd23d35ef1c6aaa5c) >--- > lib/tsocket/tsocket.h | 42 ++++++++++++++++++++++++++++++++++++++++++ > lib/tsocket/tsocket_bsd.c | 24 ++++++++++++++++++++++++ > 2 files changed, 66 insertions(+) > >diff --git a/lib/tsocket/tsocket.h b/lib/tsocket/tsocket.h >index 6b0eef6..296c7c5 100644 >--- a/lib/tsocket/tsocket.h >+++ b/lib/tsocket/tsocket.h >@@ -627,6 +627,48 @@ int _tsocket_address_unix_from_path(TALLOC_CTX *mem_ctx, > char *tsocket_address_unix_path(const struct tsocket_address *addr, > TALLOC_CTX *mem_ctx); > >+#ifdef DOXYGEN >+/** >+ * @brief Wrap an existing file descriptors into the tdgram abstraction. >+ * >+ * You can use this function to wrap an existing file descriptors into the >+ * tdgram abstraction. After that you're not able to use this file descriptor >+ * for anything else. The file descriptor will be closed when the stream gets >+ * freed. If you still want to use the fd you have have to create a duplicate. >+ * >+ * @param[in] mem_ctx The talloc memory context to use. >+ * >+ * @param[in] fd The non blocking fd to use! >+ * >+ * @param[out] dgram A pointer to store an allocated tdgram_context. >+ * >+ * @return 0 on success, -1 on error. >+ * >+ * Example: >+ * @code >+ * fd2 = dup(fd); >+ * rc = tdgram_bsd_existing_socket(mem_ctx, fd2, &tdgram); >+ * if (rc < 0) { >+ * return; >+ * } >+ * @endcode >+ * >+ * @warning This is an internal function. You should read the code to fully >+ * understand it if you plan to use it. >+ */ >+int tdgram_bsd_existing_socket(TALLOC_CTX *mem_ctx, >+ int fd, >+ struct tdgram_context **dgram); >+#else >+int _tdgram_bsd_existing_socket(TALLOC_CTX *mem_ctx, >+ int fd, >+ struct tdgram_context **_dgram, >+ const char *location); >+#define tdgram_bsd_existing_socket(mem_ctx, fd, dgram) \ >+ _tdgram_bsd_existing_socket(mem_ctx, fd, dgram, \ >+ __location__) >+#endif >+ > /** > * @brief Request a syscall optimization for tdgram_recvfrom_send() > * >diff --git a/lib/tsocket/tsocket_bsd.c b/lib/tsocket/tsocket_bsd.c >index fe39dfd..39f5a03 100644 >--- a/lib/tsocket/tsocket_bsd.c >+++ b/lib/tsocket/tsocket_bsd.c >@@ -1409,6 +1409,30 @@ static int tdgram_bsd_dgram_socket(const struct tsocket_address *local, > return 0; > } > >+int _tdgram_bsd_existing_socket(TALLOC_CTX *mem_ctx, >+ int fd, >+ struct tdgram_context **_dgram, >+ const char *location) >+{ >+ struct tdgram_context *dgram; >+ struct tdgram_bsd *bsds; >+ >+ dgram = tdgram_context_create(mem_ctx, >+ &tdgram_bsd_ops, >+ &bsds, >+ struct tdgram_bsd, >+ location); >+ if (!dgram) { >+ return -1; >+ } >+ ZERO_STRUCTP(bsds); >+ bsds->fd = fd; >+ talloc_set_destructor(bsds, tdgram_bsd_destructor); >+ >+ *_dgram = dgram; >+ return 0; >+} >+ > int _tdgram_inet_udp_socket(const struct tsocket_address *local, > const struct tsocket_address *remote, > TALLOC_CTX *mem_ctx, >-- >1.9.1 > > >From 93869aa9c53aebf2f71fa343f6e8bd789094b6f7 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 21 May 2015 11:39:38 +0200 >Subject: [PATCH 04/31] lib/tsocket: add tdgram_inet_udp_broadcast_socket() > >This is similar to tdgram_inet_udp_socket(), but it allows >the use of ipv4 broadcast traffic. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=11316 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit 36b97d0bb9fe004f3d8a500f3af83dff34f86d7b) >--- > lib/tsocket/tsocket.h | 29 +++++++++++++++++++++++++++++ > lib/tsocket/tsocket_bsd.c | 30 ++++++++++++++++++++++++++++++ > 2 files changed, 59 insertions(+) > >diff --git a/lib/tsocket/tsocket.h b/lib/tsocket/tsocket.h >index 296c7c5..f52b746 100644 >--- a/lib/tsocket/tsocket.h >+++ b/lib/tsocket/tsocket.h >@@ -705,6 +705,8 @@ bool tdgram_bsd_optimize_recvfrom(struct tdgram_context *dgram, > * communication. The function will allocate the memory. > * > * @return 0 on success, -1 on error with errno set. >+ * >+ * @see tdgram_inet_udp_broadcast_socket() > */ > int tdgram_inet_udp_socket(const struct tsocket_address *local, > const struct tsocket_address *remote, >@@ -722,6 +724,33 @@ int _tdgram_inet_udp_socket(const struct tsocket_address *local, > > #ifdef DOXYGEN > /** >+ * @brief Create a tdgram_context for a ipv4 UDP broadcast (and unicast) communication. >+ * >+ * @param[in] local An 'inet' (ipv4 only) tsocket_address for the local endpoint. >+ * >+ * @param[in] mem_ctx The talloc memory context to use. >+ * >+ * @param[in] dgram The tdgram_context pointer to setup the udp >+ * communication. The function will allocate the memory. >+ * >+ * @return 0 on success, -1 on error with errno set. >+ * >+ * @see tdgram_inet_udp_socket() >+ */ >+int tdgram_inet_udp_broadcast_socket(const struct tsocket_address *local, >+ TALLOC_CTX *mem_ctx, >+ struct tdgram_context **dgram); >+#else >+int _tdgram_inet_udp_broadcast_socket(const struct tsocket_address *local, >+ TALLOC_CTX *mem_ctx, >+ struct tdgram_context **dgram, >+ const char *location); >+#define tdgram_inet_udp_broadcast_socket(local, mem_ctx, dgram) \ >+ _tdgram_inet_udp_broadcast_socket(local, mem_ctx, dgram, __location__) >+#endif >+ >+#ifdef DOXYGEN >+/** > * @brief Create a tdgram_context for unix domain datagram communication. > * > * @param[in] local An 'unix' tsocket_address for the local endpoint. >diff --git a/lib/tsocket/tsocket_bsd.c b/lib/tsocket/tsocket_bsd.c >index 39f5a03..067d658 100644 >--- a/lib/tsocket/tsocket_bsd.c >+++ b/lib/tsocket/tsocket_bsd.c >@@ -1462,6 +1462,36 @@ int _tdgram_inet_udp_socket(const struct tsocket_address *local, > return ret; > } > >+int _tdgram_inet_udp_broadcast_socket(const struct tsocket_address *local, >+ TALLOC_CTX *mem_ctx, >+ struct tdgram_context **dgram, >+ const char *location) >+{ >+ struct tsocket_address_bsd *lbsda = >+ talloc_get_type_abort(local->private_data, >+ struct tsocket_address_bsd); >+ int ret; >+ >+ switch (lbsda->u.sa.sa_family) { >+ case AF_INET: >+ break; >+#ifdef HAVE_IPV6 >+ case AF_INET6: >+ /* only ipv4 */ >+ errno = EINVAL; >+ return -1; >+#endif >+ default: >+ errno = EINVAL; >+ return -1; >+ } >+ >+ ret = tdgram_bsd_dgram_socket(local, NULL, true, >+ mem_ctx, dgram, location); >+ >+ return ret; >+} >+ > int _tdgram_unix_socket(const struct tsocket_address *local, > const struct tsocket_address *remote, > TALLOC_CTX *mem_ctx, >-- >1.9.1 > > >From 881a9f6a40ebc1a65064dc085a186185b0f0781e Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 28 May 2015 14:25:27 +0200 >Subject: [PATCH 05/31] s4:libcli/raw: make sure > smbcli_transport_connect_send/recv correctly cleanup on error > >We need to make sure that we remove any pending writev_send or read_smb_send >request before closing the socket fd. As a side effect we always close the >socket fd if we don't return success for any any reason. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=11316 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit dd037b0be4ed2df7239cb61bd3d4bb868bb09126) >--- > source4/libcli/raw/clisocket.c | 59 ++++++++++++++++++++++++++++++------------ > 1 file changed, 42 insertions(+), 17 deletions(-) > >diff --git a/source4/libcli/raw/clisocket.c b/source4/libcli/raw/clisocket.c >index dd3ea39..1959a93 100644 >--- a/source4/libcli/raw/clisocket.c >+++ b/source4/libcli/raw/clisocket.c >@@ -36,11 +36,14 @@ > struct smbcli_transport_connect_state { > struct tevent_context *ev; > struct socket_context *sock; >+ struct tevent_req *io_req; > uint8_t *request; > struct iovec iov; > uint8_t *response; > }; > >+static void smbcli_transport_connect_cleanup(struct tevent_req *req, >+ enum tevent_req_state req_state); > static void smbcli_transport_connect_writev_done(struct tevent_req *subreq); > static void smbcli_transport_connect_read_smb_done(struct tevent_req *subreq); > >@@ -72,6 +75,8 @@ static struct tevent_req *smbcli_transport_connect_send(TALLOC_CTX *mem_ctx, > return tevent_req_post(req, ev); > } > >+ tevent_req_set_cleanup_fn(req, smbcli_transport_connect_cleanup); >+ > status = nbt_name_to_blob(state, &calling_blob, calling); > if (tevent_req_nterror(req, status)) { > return tevent_req_post(req, ev); >@@ -115,6 +120,7 @@ static struct tevent_req *smbcli_transport_connect_send(TALLOC_CTX *mem_ctx, > tevent_req_set_callback(subreq, > smbcli_transport_connect_writev_done, > req); >+ state->io_req = subreq; > > if (timeout_msec > 0) { > struct timeval endtime; >@@ -128,6 +134,36 @@ static struct tevent_req *smbcli_transport_connect_send(TALLOC_CTX *mem_ctx, > return req; > } > >+static void smbcli_transport_connect_cleanup(struct tevent_req *req, >+ enum tevent_req_state req_state) >+{ >+ struct smbcli_transport_connect_state *state = >+ tevent_req_data(req, >+ struct smbcli_transport_connect_state); >+ >+ TALLOC_FREE(state->io_req); >+ >+ if (state->sock == NULL) { >+ return; >+ } >+ >+ if (state->sock->fd == -1) { >+ return; >+ } >+ >+ if (req_state == TEVENT_REQ_DONE) { >+ /* >+ * we keep the socket open for the caller to use >+ */ >+ state->sock = NULL; >+ return; >+ } >+ >+ close(state->sock->fd); >+ state->sock->fd = -1; >+ state->sock = NULL; >+} >+ > static void smbcli_transport_connect_writev_done(struct tevent_req *subreq) > { > struct tevent_req *req = >@@ -139,14 +175,12 @@ static void smbcli_transport_connect_writev_done(struct tevent_req *subreq) > ssize_t ret; > int err; > >+ state->io_req = NULL; >+ > ret = writev_recv(subreq, &err); > TALLOC_FREE(subreq); > if (ret == -1) { > NTSTATUS status = map_nt_error_from_unix_common(err); >- >- close(state->sock->fd); >- state->sock->fd = -1; >- > tevent_req_nterror(req, status); > return; > } >@@ -159,6 +193,7 @@ static void smbcli_transport_connect_writev_done(struct tevent_req *subreq) > tevent_req_set_callback(subreq, > smbcli_transport_connect_read_smb_done, > req); >+ state->io_req = subreq; > } > > static void smbcli_transport_connect_read_smb_done(struct tevent_req *subreq) >@@ -174,22 +209,18 @@ static void smbcli_transport_connect_read_smb_done(struct tevent_req *subreq) > NTSTATUS status; > uint8_t error; > >+ state->io_req = NULL; >+ > ret = read_smb_recv(subreq, state, > &state->response, &err); >+ TALLOC_FREE(subreq); > if (ret == -1) { > status = map_nt_error_from_unix_common(err); >- >- close(state->sock->fd); >- state->sock->fd = -1; >- > tevent_req_nterror(req, status); > return; > } > > if (ret < 4) { >- close(state->sock->fd); >- state->sock->fd = -1; >- > tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE); > return; > } >@@ -201,9 +232,6 @@ static void smbcli_transport_connect_read_smb_done(struct tevent_req *subreq) > > case NBSSnegative: > if (ret < 5) { >- close(state->sock->fd); >- state->sock->fd = -1; >- > tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE); > return; > } >@@ -236,9 +264,6 @@ static void smbcli_transport_connect_read_smb_done(struct tevent_req *subreq) > break; > } > >- close(state->sock->fd); >- state->sock->fd = -1; >- > tevent_req_nterror(req, status); > } > >-- >1.9.1 > > >From 0b617b1b4a93b643d416735056025d742165598c Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 21 May 2015 03:45:36 +0200 >Subject: [PATCH 06/31] s3:wscript: move lib/util_tsock.c from 'TLDAP' to > 'samba3util' > >tstream_read_packet_send/recv() is a generic helper function... > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=11316 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(similar to commit 0c108f55d9c3cca0bde1c15c66dccabbc40e6133) >--- > source3/wscript_build | 7 ++++--- > 1 file changed, 4 insertions(+), 3 deletions(-) > >diff --git a/source3/wscript_build b/source3/wscript_build >index 061cc0d..f66f69e 100755 >--- a/source3/wscript_build >+++ b/source3/wscript_build >@@ -80,6 +80,7 @@ LIB_UTIL_SRC = ''' > lib/util_file.c > lib/util.c > lib/util_sock.c >+ lib/util_tsock.c > lib/util_transfer_file.c > lib/sock_exec.c''' > >@@ -122,7 +123,7 @@ LIBNTLMSSP_SRC = ''' > libsmb/ntlmssp.c > libsmb/ntlmssp_wrap.c''' > >-TLDAP_SRC = '''lib/tldap.c lib/tldap_util.c lib/util_tsock.c''' >+TLDAP_SRC = '''lib/tldap.c lib/tldap_util.c''' > > LIBSMB_SRC = '''libsmb/clientgen.c libsmb/cliconnect.c libsmb/clifile.c > libsmb/clispnego.c >@@ -686,7 +687,7 @@ bld.SAMBA3_SUBSYSTEM('GROUPDB', > > bld.SAMBA3_SUBSYSTEM('TLDAP', > source=TLDAP_SRC, >- deps='asn1util LIBTSOCKET') >+ deps='asn1util LIBTSOCKET samba3util') > > # libpdb.so should not expose internal symbols that are only usable > # to the statically linked modules that are merged into libpdb. >@@ -818,7 +819,7 @@ bld.SAMBA3_SUBSYSTEM('KRBCLIENT', > > bld.SAMBA3_SUBSYSTEM('samba3util', > source=LIB_UTIL_SRC, >- deps='ndr samba-security NDR_SECURITY samba-util util_tdb ccan-hash', >+ deps='ndr LIBTSOCKET samba-security NDR_SECURITY samba-util util_tdb ccan-hash', > vars=locals()) > > bld.SAMBA3_SUBSYSTEM('samba3core', >-- >1.9.1 > > >From e45837e5a5f15dfffb1ecc87fb28007c738e9233 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 28 May 2015 13:31:17 +0200 >Subject: [PATCH 07/31] s3:lib/background: make sure we destroy a pending > read_packet_send() before closing the pipe fd > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=11316 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit 9d3444ad887bb3a118eaecd141c79dfd6de53f41) >--- > source3/lib/background.c | 8 ++++++++ > 1 file changed, 8 insertions(+) > >diff --git a/source3/lib/background.c b/source3/lib/background.c >index 6a91783..a564fa6 100644 >--- a/source3/lib/background.c >+++ b/source3/lib/background.c >@@ -34,6 +34,7 @@ struct background_job_state { > > struct tevent_req *wakeup_req; > int pipe_fd; >+ struct tevent_req *pipe_req; > }; > > static int background_job_state_destructor(struct background_job_state *s); >@@ -103,14 +104,18 @@ struct tevent_req *background_job_send(TALLOC_CTX *mem_ctx, > static int background_job_state_destructor(struct background_job_state *state) > { > size_t i; >+ >+ TALLOC_FREE(state->pipe_req); > if (state->pipe_fd != -1) { > close(state->pipe_fd); > state->pipe_fd = -1; > } >+ > for (i=0; i<state->num_trigger_msgs; i++) { > messaging_deregister(state->msg, state->trigger_msgs[i], > state); > } >+ > return 0; > } > >@@ -195,6 +200,7 @@ static void background_job_waited(struct tevent_req *subreq) > return; > } > tevent_req_set_callback(subreq, background_job_done, req); >+ state->pipe_req = subreq; > } > > static void background_job_done(struct tevent_req *subreq) >@@ -208,6 +214,8 @@ static void background_job_done(struct tevent_req *subreq) > int err; > int wait_secs; > >+ state->pipe_req = NULL; >+ > ret = read_packet_recv(subreq, talloc_tos(), &buf, &err); > TALLOC_FREE(subreq); > if (ret == -1) { >-- >1.9.1 > > >From 4b67ba16a34f29f499e94e710bbc2aee2edbc58f Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Fri, 5 Jun 2015 14:19:00 +0200 >Subject: [PATCH 08/31] s3:lib/addrchange: look at the correct nl_pid in > addrchange_done() > >state->fromaddr is the address we got from recvfrom_send/recv. > >state->addr is completely untouched after tevent_req_create(). > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=11316 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit 257bc586c22f9a7f34b913823d5c89592d433454) >--- > source3/lib/addrchange.c | 8 ++++---- > 1 file changed, 4 insertions(+), 4 deletions(-) > >diff --git a/source3/lib/addrchange.c b/source3/lib/addrchange.c >index a5d2041..b85a81f 100644 >--- a/source3/lib/addrchange.c >+++ b/source3/lib/addrchange.c >@@ -126,7 +126,7 @@ static void addrchange_done(struct tevent_req *subreq) > subreq, struct tevent_req); > struct addrchange_state *state = tevent_req_data( > req, struct addrchange_state); >- struct sockaddr_nl *addr; >+ struct sockaddr_nl *fromaddr; > struct nlmsghdr *h; > struct ifaddrmsg *ifa; > struct rtattr *rta; >@@ -148,10 +148,10 @@ static void addrchange_done(struct tevent_req *subreq) > goto retry; > } > >- addr = (struct sockaddr_nl *)(void *)&state->addr; >- if (addr->nl_pid != 0) { >+ fromaddr = (struct sockaddr_nl *)(void *)&state->fromaddr; >+ if (fromaddr->nl_pid != 0) { > DEBUG(10, ("Got msg from pid %d, not from the kernel\n", >- (int)addr->nl_pid)); >+ (int)fromaddr->nl_pid)); > goto retry; > } > >-- >1.9.1 > > >From 7bf60de54c7c8c0b3a3ea5d4af355924b0025286 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 21 May 2015 12:17:24 +0200 >Subject: [PATCH 09/31] s3:lib/addrchange: make use of tdgram_* in > addrchange_*() > >This makes the cleanup handling easier to get right, >as we need to make sure any tevent_fd is removed before >closing a socket fd. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=11316 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit 0d161e42d9aeb155eae2b04eccec497b21de8029) >--- > source3/lib/addrchange.c | 91 +++++++++++++++++++++++++++++------------------- > 1 file changed, 55 insertions(+), 36 deletions(-) > >diff --git a/source3/lib/addrchange.c b/source3/lib/addrchange.c >index b85a81f..9a628f7 100644 >--- a/source3/lib/addrchange.c >+++ b/source3/lib/addrchange.c >@@ -25,33 +25,44 @@ > #include "asm/types.h" > #include "linux/netlink.h" > #include "linux/rtnetlink.h" >-#include "lib/async_req/async_sock.h" >+#include "lib/tsocket/tsocket.h" > > struct addrchange_context { >- int sock; >+ struct tdgram_context *sock; > }; > >-static int addrchange_context_destructor(struct addrchange_context *c); >- > NTSTATUS addrchange_context_create(TALLOC_CTX *mem_ctx, > struct addrchange_context **pctx) > { > struct addrchange_context *ctx; > struct sockaddr_nl addr; > NTSTATUS status; >+ int sock = -1; > int res; >+ bool ok; > > ctx = talloc(mem_ctx, struct addrchange_context); > if (ctx == NULL) { > return NT_STATUS_NO_MEMORY; > } > >- ctx->sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); >- if (ctx->sock == -1) { >+ sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); >+ if (sock == -1) { >+ status = map_nt_error_from_unix(errno); >+ goto fail; >+ } >+ >+ ok = smb_set_close_on_exec(sock); >+ if (!ok) { >+ status = map_nt_error_from_unix(errno); >+ goto fail; >+ } >+ >+ res = set_blocking(sock, false); >+ if (res == -1) { > status = map_nt_error_from_unix(errno); > goto fail; > } >- talloc_set_destructor(ctx, addrchange_context_destructor); > > /* > * We're interested in address changes >@@ -60,7 +71,13 @@ NTSTATUS addrchange_context_create(TALLOC_CTX *mem_ctx, > addr.nl_family = AF_NETLINK; > addr.nl_groups = RTMGRP_IPV6_IFADDR | RTMGRP_IPV4_IFADDR; > >- res = bind(ctx->sock, (struct sockaddr *)(void *)&addr, sizeof(addr)); >+ res = bind(sock, (struct sockaddr *)(void *)&addr, sizeof(addr)); >+ if (res == -1) { >+ status = map_nt_error_from_unix(errno); >+ goto fail; >+ } >+ >+ res = tdgram_bsd_existing_socket(ctx, sock, &ctx->sock); > if (res == -1) { > status = map_nt_error_from_unix(errno); > goto fail; >@@ -69,25 +86,18 @@ NTSTATUS addrchange_context_create(TALLOC_CTX *mem_ctx, > *pctx = ctx; > return NT_STATUS_OK; > fail: >+ if (sock != -1) { >+ close(sock); >+ } > TALLOC_FREE(ctx); > return status; > } > >-static int addrchange_context_destructor(struct addrchange_context *c) >-{ >- if (c->sock != -1) { >- close(c->sock); >- c->sock = -1; >- } >- return 0; >-} >- > struct addrchange_state { > struct tevent_context *ev; > struct addrchange_context *ctx; >- uint8_t buf[8192]; >- struct sockaddr_storage fromaddr; >- socklen_t fromaddr_len; >+ uint8_t *buf; >+ struct tsocket_address *fromaddr; > > enum addrchange_type type; > struct sockaddr_storage addr; >@@ -109,10 +119,7 @@ struct tevent_req *addrchange_send(TALLOC_CTX *mem_ctx, > state->ev = ev; > state->ctx = ctx; > >- state->fromaddr_len = sizeof(state->fromaddr); >- subreq = recvfrom_send(state, state->ev, state->ctx->sock, >- state->buf, sizeof(state->buf), 0, >- &state->fromaddr, &state->fromaddr_len); >+ subreq = tdgram_recvfrom_send(state, state->ev, state->ctx->sock); > if (tevent_req_nomem(subreq, req)) { > return tevent_req_post(req, state->ev); > } >@@ -126,7 +133,11 @@ static void addrchange_done(struct tevent_req *subreq) > subreq, struct tevent_req); > struct addrchange_state *state = tevent_req_data( > req, struct addrchange_state); >- struct sockaddr_nl *fromaddr; >+ union { >+ struct sockaddr sa; >+ struct sockaddr_nl nl; >+ struct sockaddr_storage ss; >+ } fromaddr; > struct nlmsghdr *h; > struct ifaddrmsg *ifa; > struct rtattr *rta; >@@ -135,23 +146,29 @@ static void addrchange_done(struct tevent_req *subreq) > int err; > bool found; > >- received = recvfrom_recv(subreq, &err); >+ received = tdgram_recvfrom_recv(subreq, &err, state, >+ &state->buf, >+ &state->fromaddr); > TALLOC_FREE(subreq); > if (received == -1) { >- DEBUG(10, ("recvfrom returned %s\n", strerror(errno))); >+ DEBUG(10, ("tdgram_recvfrom_recv returned %s\n", strerror(err))); > tevent_req_nterror(req, map_nt_error_from_unix(err)); > return; > } >- if ((state->fromaddr_len != sizeof(struct sockaddr_nl)) >- || (state->fromaddr.ss_family != AF_NETLINK)) { >+ len = tsocket_address_bsd_sockaddr(state->fromaddr, >+ &fromaddr.sa, >+ sizeof(fromaddr)); >+ >+ if ((len != sizeof(fromaddr.nl) || >+ fromaddr.sa.sa_family != AF_NETLINK)) >+ { > DEBUG(10, ("Got message from wrong addr\n")); > goto retry; > } > >- fromaddr = (struct sockaddr_nl *)(void *)&state->fromaddr; >- if (fromaddr->nl_pid != 0) { >+ if (fromaddr.nl.nl_pid != 0) { > DEBUG(10, ("Got msg from pid %d, not from the kernel\n", >- (int)fromaddr->nl_pid)); >+ (int)fromaddr.nl.nl_pid)); > goto retry; > } > >@@ -246,10 +263,10 @@ static void addrchange_done(struct tevent_req *subreq) > return; > > retry: >- state->fromaddr_len = sizeof(state->fromaddr); >- subreq = recvfrom_send(state, state->ev, state->ctx->sock, >- state->buf, sizeof(state->buf), 0, >- &state->fromaddr, &state->fromaddr_len); >+ TALLOC_FREE(state->buf); >+ TALLOC_FREE(state->fromaddr); >+ >+ subreq = tdgram_recvfrom_send(state, state->ev, state->ctx->sock); > if (tevent_req_nomem(subreq, req)) { > return; > } >@@ -264,11 +281,13 @@ NTSTATUS addrchange_recv(struct tevent_req *req, enum addrchange_type *type, > NTSTATUS status; > > if (tevent_req_is_nterror(req, &status)) { >+ tevent_req_received(req); > return status; > } > > *type = state->type; > *addr = state->addr; >+ tevent_req_received(req); > return NT_STATUS_OK; > } > >-- >1.9.1 > > >From 9f04333d56acb5edf86f58a6dcb83b47ad751ced Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 21 May 2015 03:00:17 +0200 >Subject: [PATCH 10/31] s3:libsmb: remove the cli_session_request as early as > possible via a nb_connect_cleanup() hook > >cli_session_request_send() is likely to use tevent_fd objects on the given >socket fd, so we need to destroy the request before closing the socket fd. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=11316 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit 992be06f165c3d05e85d16baf514dba49f55d1ec) >--- > source3/libsmb/smbsock_connect.c | 36 ++++++++++++++++++++++++++++++------ > 1 file changed, 30 insertions(+), 6 deletions(-) > >diff --git a/source3/libsmb/smbsock_connect.c b/source3/libsmb/smbsock_connect.c >index 403750d..054b8af 100644 >--- a/source3/libsmb/smbsock_connect.c >+++ b/source3/libsmb/smbsock_connect.c >@@ -157,12 +157,13 @@ struct nb_connect_state { > const struct sockaddr_storage *addr; > const char *called_name; > int sock; >- >+ struct tevent_req *session_subreq; > struct nmb_name called; > struct nmb_name calling; > }; > >-static int nb_connect_state_destructor(struct nb_connect_state *state); >+static void nb_connect_cleanup(struct tevent_req *req, >+ enum tevent_req_state req_state); > static void nb_connect_connected(struct tevent_req *subreq); > static void nb_connect_done(struct tevent_req *subreq); > >@@ -189,7 +190,7 @@ static struct tevent_req *nb_connect_send(TALLOC_CTX *mem_ctx, > make_nmb_name(&state->called, called_name, called_type); > make_nmb_name(&state->calling, calling_name, calling_type); > >- talloc_set_destructor(state, nb_connect_state_destructor); >+ tevent_req_set_cleanup_fn(req, nb_connect_cleanup); > > subreq = open_socket_out_send(state, ev, addr, NBT_SMB_PORT, 5000); > if (tevent_req_nomem(subreq, req)) { >@@ -199,12 +200,31 @@ static struct tevent_req *nb_connect_send(TALLOC_CTX *mem_ctx, > return req; > } > >-static int nb_connect_state_destructor(struct nb_connect_state *state) >+static void nb_connect_cleanup(struct tevent_req *req, >+ enum tevent_req_state req_state) > { >+ struct nb_connect_state *state = tevent_req_data( >+ req, struct nb_connect_state); >+ >+ /* >+ * we need to free a pending request before closing the >+ * socket, see bug #11141 >+ */ >+ TALLOC_FREE(state->session_subreq); >+ >+ if (req_state == TEVENT_REQ_DONE) { >+ /* >+ * we keep the socket open for the caller to use >+ */ >+ return; >+ } >+ > if (state->sock != -1) { > close(state->sock); >+ state->sock = -1; > } >- return 0; >+ >+ return; > } > > static void nb_connect_connected(struct tevent_req *subreq) >@@ -227,6 +247,7 @@ static void nb_connect_connected(struct tevent_req *subreq) > return; > } > tevent_req_set_callback(subreq, nb_connect_done, req); >+ state->session_subreq = subreq; > } > > static void nb_connect_done(struct tevent_req *subreq) >@@ -239,6 +260,8 @@ static void nb_connect_done(struct tevent_req *subreq) > int err; > uint8_t resp; > >+ state->session_subreq = NULL; >+ > ret = cli_session_request_recv(subreq, &err, &resp); > TALLOC_FREE(subreq); > if (!ret) { >@@ -286,7 +309,6 @@ static void nb_connect_done(struct tevent_req *subreq) > > tevent_req_done(req); > return; >- > } > > static NTSTATUS nb_connect_recv(struct tevent_req *req, int *sock) >@@ -296,10 +318,12 @@ static NTSTATUS nb_connect_recv(struct tevent_req *req, int *sock) > NTSTATUS status; > > if (tevent_req_is_nterror(req, &status)) { >+ tevent_req_received(req); > return status; > } > *sock = state->sock; > state->sock = -1; >+ tevent_req_received(req); > return NT_STATUS_OK; > } > >-- >1.9.1 > > >From f4da2e9b0d0c9fc16381fc9cfa716e653a2eb5df Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 21 May 2015 03:01:05 +0200 >Subject: [PATCH 11/31] s3:libsmb: remove subreqs as early as possible via a > smbsock_connect_cleanup() hook > >open_socket_out_send() or nb_connect_send() likely use socket fds and >tevent_fd objects. We should clean them up as early as possible. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=11316 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit 04f89d4255ed95631aa8f0ada4bcf5f888e126d4) >--- > source3/libsmb/smbsock_connect.c | 32 ++++++++++++++++++++++++++------ > 1 file changed, 26 insertions(+), 6 deletions(-) > >diff --git a/source3/libsmb/smbsock_connect.c b/source3/libsmb/smbsock_connect.c >index 054b8af..1256e5f 100644 >--- a/source3/libsmb/smbsock_connect.c >+++ b/source3/libsmb/smbsock_connect.c >@@ -340,8 +340,8 @@ struct smbsock_connect_state { > uint16_t port; > }; > >-static int smbsock_connect_state_destructor( >- struct smbsock_connect_state *state); >+static void smbsock_connect_cleanup(struct tevent_req *req, >+ enum tevent_req_state req_state); > static void smbsock_connect_connected(struct tevent_req *subreq); > static void smbsock_connect_do_139(struct tevent_req *subreq); > >@@ -373,7 +373,7 @@ struct tevent_req *smbsock_connect_send(TALLOC_CTX *mem_ctx, > state->calling_type = > (calling_type != -1) ? calling_type : 0x00; > >- talloc_set_destructor(state, smbsock_connect_state_destructor); >+ tevent_req_set_cleanup_fn(req, smbsock_connect_cleanup); > > if (port == NBT_SMB_PORT) { > state->req_139 = nb_connect_send(state, state->ev, state->addr, >@@ -424,14 +424,32 @@ struct tevent_req *smbsock_connect_send(TALLOC_CTX *mem_ctx, > return req; > } > >-static int smbsock_connect_state_destructor( >- struct smbsock_connect_state *state) >+static void smbsock_connect_cleanup(struct tevent_req *req, >+ enum tevent_req_state req_state) > { >+ struct smbsock_connect_state *state = tevent_req_data( >+ req, struct smbsock_connect_state); >+ >+ /* >+ * we need to free a pending request before closing the >+ * socket, see bug #11141 >+ */ >+ TALLOC_FREE(state->req_445); >+ TALLOC_FREE(state->req_139); >+ >+ if (req_state == TEVENT_REQ_DONE) { >+ /* >+ * we keep the socket open for the caller to use >+ */ >+ return; >+ } >+ > if (state->sock != -1) { > close(state->sock); > state->sock = -1; > } >- return 0; >+ >+ return; > } > > static void smbsock_connect_do_139(struct tevent_req *subreq) >@@ -515,6 +533,7 @@ NTSTATUS smbsock_connect_recv(struct tevent_req *req, int *sock, > NTSTATUS status; > > if (tevent_req_is_nterror(req, &status)) { >+ tevent_req_received(req); > return status; > } > *sock = state->sock; >@@ -522,6 +541,7 @@ NTSTATUS smbsock_connect_recv(struct tevent_req *req, int *sock, > if (ret_port != NULL) { > *ret_port = state->port; > } >+ tevent_req_received(req); > return NT_STATUS_OK; > } > >-- >1.9.1 > > >From ef5a549ee4df2356537940d4b60a66eaa5bbd0bc Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 21 May 2015 03:01:30 +0200 >Subject: [PATCH 12/31] s3:libsmb: remove pending requests as early as possible > via a smbsock_any_connect_cleanup() hook > >Once we got an error or a valid connection we should destroy all other >connection attempts as early as possible. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=11316 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit 058d84747e75a5f97a02e31bac9c8d0d147174bc) >--- > source3/libsmb/smbsock_connect.c | 33 +++++++++++++++++++++++++++++++-- > 1 file changed, 31 insertions(+), 2 deletions(-) > >diff --git a/source3/libsmb/smbsock_connect.c b/source3/libsmb/smbsock_connect.c >index 1256e5f..dc04b6a 100644 >--- a/source3/libsmb/smbsock_connect.c >+++ b/source3/libsmb/smbsock_connect.c >@@ -598,6 +598,8 @@ struct smbsock_any_connect_state { > size_t chosen_index; > }; > >+static void smbsock_any_connect_cleanup(struct tevent_req *req, >+ enum tevent_req_state req_state); > static bool smbsock_any_connect_send_next( > struct tevent_req *req, struct smbsock_any_connect_state *state); > static void smbsock_any_connect_trynext(struct tevent_req *subreq); >@@ -628,6 +630,9 @@ struct tevent_req *smbsock_any_connect_send(TALLOC_CTX *mem_ctx, > state->calling_names = calling_names; > state->calling_types = calling_types; > state->port = port; >+ state->fd = -1; >+ >+ tevent_req_set_cleanup_fn(req, smbsock_any_connect_cleanup); > > if (num_addrs == 0) { > tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); >@@ -653,6 +658,27 @@ struct tevent_req *smbsock_any_connect_send(TALLOC_CTX *mem_ctx, > return req; > } > >+static void smbsock_any_connect_cleanup(struct tevent_req *req, >+ enum tevent_req_state req_state) >+{ >+ struct smbsock_any_connect_state *state = tevent_req_data( >+ req, struct smbsock_any_connect_state); >+ >+ TALLOC_FREE(state->requests); >+ >+ if (req_state == TEVENT_REQ_DONE) { >+ /* >+ * Keep the socket open for the caller. >+ */ >+ return; >+ } >+ >+ if (state->fd != -1) { >+ close(state->fd); >+ state->fd = -1; >+ } >+} >+ > static void smbsock_any_connect_trynext(struct tevent_req *subreq) > { > struct tevent_req *req = tevent_req_callback_data( >@@ -742,9 +768,9 @@ static void smbsock_any_connect_connected(struct tevent_req *subreq) > > if (NT_STATUS_IS_OK(status)) { > /* >- * This will kill all the other requests >+ * tevent_req_done() will kill all the other requests >+ * via smbsock_any_connect_cleanup(). > */ >- TALLOC_FREE(state->requests); > state->fd = fd; > state->chosen_port = chosen_port; > state->chosen_index = chosen_index; >@@ -776,15 +802,18 @@ NTSTATUS smbsock_any_connect_recv(struct tevent_req *req, int *pfd, > NTSTATUS status; > > if (tevent_req_is_nterror(req, &status)) { >+ tevent_req_received(req); > return status; > } > *pfd = state->fd; >+ state->fd = -1; > if (chosen_index != NULL) { > *chosen_index = state->chosen_index; > } > if (chosen_port != NULL) { > *chosen_port = state->chosen_port; > } >+ tevent_req_received(req); > return NT_STATUS_OK; > } > >-- >1.9.1 > > >From aa25957becf174074d8cae4b78394176ecdf4ac0 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 21 May 2015 02:20:00 +0200 >Subject: [PATCH 13/31] s3:libsmb: let nb_packet_server_destructor() explicitly > destroy the tevent_fd > >The need to destroy the tevent_fd before closing the socket fd. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=11316 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit 9ccf8e6d36618498c4952bb1d4b74152f75ab793) >--- > source3/libsmb/unexpected.c | 13 +++++++++---- > 1 file changed, 9 insertions(+), 4 deletions(-) > >diff --git a/source3/libsmb/unexpected.c b/source3/libsmb/unexpected.c >index 2c01bb7..41dcd7f 100644 >--- a/source3/libsmb/unexpected.c >+++ b/source3/libsmb/unexpected.c >@@ -40,6 +40,7 @@ struct nb_packet_client; > struct nb_packet_server { > struct tevent_context *ev; > int listen_sock; >+ struct tevent_fd *listen_fde; > int max_clients; > int num_clients; > struct nb_packet_client *clients; >@@ -70,7 +71,6 @@ NTSTATUS nb_packet_server_create(TALLOC_CTX *mem_ctx, > struct nb_packet_server **presult) > { > struct nb_packet_server *result; >- struct tevent_fd *fde; > NTSTATUS status; > int rc; > >@@ -95,9 +95,12 @@ NTSTATUS nb_packet_server_create(TALLOC_CTX *mem_ctx, > } > talloc_set_destructor(result, nb_packet_server_destructor); > >- fde = tevent_add_fd(ev, result, result->listen_sock, TEVENT_FD_READ, >- nb_packet_server_listener, result); >- if (fde == NULL) { >+ result->listen_fde = tevent_add_fd(ev, result, >+ result->listen_sock, >+ TEVENT_FD_READ, >+ nb_packet_server_listener, >+ result); >+ if (result->listen_fde == NULL) { > status = NT_STATUS_NO_MEMORY; > goto fail; > } >@@ -111,6 +114,8 @@ fail: > > static int nb_packet_server_destructor(struct nb_packet_server *s) > { >+ TALLOC_FREE(s->listen_fde); >+ > if (s->listen_sock != -1) { > close(s->listen_sock); > s->listen_sock = -1; >-- >1.9.1 > > >From 19735cde734b143b097415e00c7f05a116768321 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 21 May 2015 01:53:44 +0200 >Subject: [PATCH 14/31] s3:libsmb: convert nb_packet_client to tstream_* > functions > >By using the tstream abstraction we don't need to take care >error handling regarding dangling tevent_fd structures. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=11316 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit 3ecf4ec6574de9bdd5a2d55529ed81b17c74d452) >--- > source3/libsmb/unexpected.c | 118 +++++++++++++++++++++++++------------------- > source3/wscript_build | 2 +- > 2 files changed, 68 insertions(+), 52 deletions(-) > >diff --git a/source3/libsmb/unexpected.c b/source3/libsmb/unexpected.c >index 41dcd7f..4a05ee2 100644 >--- a/source3/libsmb/unexpected.c >+++ b/source3/libsmb/unexpected.c >@@ -20,6 +20,7 @@ > > #include "includes.h" > #include "../lib/util/tevent_ntstatus.h" >+#include "lib/tsocket/tsocket.h" > #include "lib/async_req/async_sock.h" > #include "libsmb/nmblib.h" > >@@ -54,8 +55,12 @@ struct nb_packet_client { > int trn_id; > char *mailslot_name; > >- int sock; >- struct tevent_req *read_req; >+ struct { >+ uint8_t byte; >+ struct iovec iov[1]; >+ } ack; >+ >+ struct tstream_context *sock; > struct tevent_queue *out_queue; > }; > >@@ -127,6 +132,7 @@ static int nb_packet_client_destructor(struct nb_packet_client *c); > static ssize_t nb_packet_client_more(uint8_t *buf, size_t buflen, > void *private_data); > static void nb_packet_got_query(struct tevent_req *req); >+static void nb_packet_client_ack_done(struct tevent_req *req); > static void nb_packet_client_read_done(struct tevent_req *req); > > static void nb_packet_server_listener(struct tevent_context *ev, >@@ -141,6 +147,7 @@ static void nb_packet_server_listener(struct tevent_context *ev, > struct sockaddr_un sunaddr; > socklen_t len; > int sock; >+ int ret; > > len = sizeof(sunaddr); > >@@ -157,7 +164,13 @@ static void nb_packet_server_listener(struct tevent_context *ev, > close(sock); > return; > } >- client->sock = sock; >+ ret = tstream_bsd_existing_socket(client, sock, &client->sock); >+ if (ret != 0) { >+ DEBUG(10, ("tstream_bsd_existing_socket failed\n")); >+ close(sock); >+ return; >+ } >+ > client->server = server; > talloc_set_destructor(client, nb_packet_client_destructor); > >@@ -169,11 +182,11 @@ static void nb_packet_server_listener(struct tevent_context *ev, > return; > } > >- req = read_packet_send(client, ev, client->sock, >- sizeof(struct nb_packet_query), >- nb_packet_client_more, NULL); >+ req = tstream_read_packet_send(client, ev, client->sock, >+ sizeof(struct nb_packet_query), >+ nb_packet_client_more, NULL); > if (req == NULL) { >- DEBUG(10, ("read_packet_send failed\n")); >+ DEBUG(10, ("tstream_read_packet_send failed\n")); > TALLOC_FREE(client); > return; > } >@@ -211,10 +224,9 @@ static ssize_t nb_packet_client_more(uint8_t *buf, size_t buflen, > > static int nb_packet_client_destructor(struct nb_packet_client *c) > { >- if (c->sock != -1) { >- close(c->sock); >- c->sock = -1; >- } >+ tevent_queue_stop(c->out_queue); >+ TALLOC_FREE(c->sock); >+ > DLIST_REMOVE(c->server->clients, c); > c->server->num_clients -= 1; > return 0; >@@ -226,11 +238,10 @@ static void nb_packet_got_query(struct tevent_req *req) > req, struct nb_packet_client); > struct nb_packet_query q; > uint8_t *buf; >- ssize_t nread, nwritten; >+ ssize_t nread; > int err; >- char c; > >- nread = read_packet_recv(req, talloc_tos(), &buf, &err); >+ nread = tstream_read_packet_recv(req, talloc_tos(), &buf, &err); > TALLOC_FREE(req); > if (nread < (ssize_t)sizeof(struct nb_packet_query)) { > DEBUG(10, ("read_packet_recv returned %d (%s)\n", >@@ -261,32 +272,51 @@ static void nb_packet_got_query(struct tevent_req *req) > } > } > >- /* >- * Yes, this is a blocking write of 1 byte into a unix >- * domain socket that has never been written to. Highly >- * unlikely that this actually blocks. >- */ >- c = 0; >- nwritten = sys_write(client->sock, &c, sizeof(c)); >- if (nwritten != sizeof(c)) { >- DEBUG(10, ("Could not write success indicator to client: %s\n", >- strerror(errno))); >+ client->ack.byte = 0; >+ client->ack.iov[0].iov_base = &client->ack.byte; >+ client->ack.iov[0].iov_len = 1; >+ req = tstream_writev_queue_send(client, client->server->ev, >+ client->sock, >+ client->out_queue, >+ client->ack.iov, 1); >+ if (req == NULL) { >+ DEBUG(10, ("tstream_writev_queue_send failed\n")); > TALLOC_FREE(client); > return; > } >+ tevent_req_set_callback(req, nb_packet_client_ack_done, client); > >- client->read_req = read_packet_send(client, client->server->ev, >- client->sock, 1, NULL, NULL); >- if (client->read_req == NULL) { >+ req = tstream_read_packet_send(client, client->server->ev, >+ client->sock, 1, NULL, NULL); >+ if (req == NULL) { > DEBUG(10, ("Could not activate reader for client exit " > "detection\n")); > TALLOC_FREE(client); > return; > } >- tevent_req_set_callback(client->read_req, nb_packet_client_read_done, >+ tevent_req_set_callback(req, nb_packet_client_read_done, > client); > } > >+static void nb_packet_client_ack_done(struct tevent_req *req) >+{ >+ struct nb_packet_client *client = tevent_req_callback_data( >+ req, struct nb_packet_client); >+ ssize_t nwritten; >+ int err; >+ >+ nwritten = tstream_writev_queue_recv(req, &err); >+ >+ TALLOC_FREE(req); >+ >+ if (nwritten == -1) { >+ DEBUG(10, ("tstream_writev_queue_recv failed: %s\n", >+ strerror(err))); >+ TALLOC_FREE(client); >+ return; >+ } >+} >+ > static void nb_packet_client_read_done(struct tevent_req *req) > { > struct nb_packet_client *client = tevent_req_callback_data( >@@ -295,7 +325,7 @@ static void nb_packet_client_read_done(struct tevent_req *req) > uint8_t *buf; > int err; > >- nread = read_packet_recv(req, talloc_tos(), &buf, &err); >+ nread = tstream_read_packet_recv(req, talloc_tos(), &buf, &err); > TALLOC_FREE(req); > if (nread == 1) { > DEBUG(10, ("Protocol error, received data on write-only " >@@ -408,12 +438,12 @@ static void nb_packet_client_send(struct nb_packet_client *client, > state->iov[1].iov_base = state->buf; > state->iov[1].iov_len = state->hdr.len; > >- TALLOC_FREE(client->read_req); >- >- req = writev_send(client, client->server->ev, client->out_queue, >- client->sock, true, state->iov, 2); >+ req = tstream_writev_queue_send(state, client->server->ev, >+ client->sock, >+ client->out_queue, >+ state->iov, 2); > if (req == NULL) { >- DEBUG(10, ("writev_send failed\n")); >+ DEBUG(10, ("tstream_writev_queue_send failed\n")); > return; > } > tevent_req_set_callback(req, nb_packet_client_send_done, state); >@@ -427,29 +457,15 @@ static void nb_packet_client_send_done(struct tevent_req *req) > ssize_t nwritten; > int err; > >- nwritten = writev_recv(req, &err); >+ nwritten = tstream_writev_queue_recv(req, &err); > > TALLOC_FREE(req); > TALLOC_FREE(state); > > if (nwritten == -1) { >- DEBUG(10, ("writev failed: %s\n", strerror(err))); >+ DEBUG(10, ("tstream_writev_queue failed: %s\n", strerror(err))); > TALLOC_FREE(client); >- } >- >- if (tevent_queue_length(client->out_queue) == 0) { >- client->read_req = read_packet_send(client, client->server->ev, >- client->sock, 1, >- NULL, NULL); >- if (client->read_req == NULL) { >- DEBUG(10, ("Could not activate reader for client exit " >- "detection\n")); >- TALLOC_FREE(client); >- return; >- } >- tevent_req_set_callback(client->read_req, >- nb_packet_client_read_done, >- client); >+ return; > } > } > >diff --git a/source3/wscript_build b/source3/wscript_build >index f66f69e..f408b5f 100755 >--- a/source3/wscript_build >+++ b/source3/wscript_build >@@ -1054,7 +1054,7 @@ bld.SAMBA3_SUBSYSTEM('LIBEVENTLOG', > > bld.SAMBA3_SUBSYSTEM('LIBNMB', > source=LIBNMB_SRC, >- deps='addns lmhosts resolv', >+ deps='LIBTSOCKET samba3util addns lmhosts resolv', > vars=locals()) > > bld.SAMBA3_SUBSYSTEM('SERVICES', >-- >1.9.1 > > >From 2264e33e03089e97ff52ab33773ca25a9ca18168 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 21 May 2015 02:18:26 +0200 >Subject: [PATCH 15/31] s3:libsmb: convert nb_packet_reader to tstream_* > functions > >By using the tstream abstraction we don't need to take care >error handling regarding dangling tevent_fd structures. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=11316 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit ecb4d041de89441941a112ab3a724887e568117e) >--- > source3/libsmb/unexpected.c | 72 +++++++++++++++++++++------------------------ > 1 file changed, 34 insertions(+), 38 deletions(-) > >diff --git a/source3/libsmb/unexpected.c b/source3/libsmb/unexpected.c >index 4a05ee2..79df11a 100644 >--- a/source3/libsmb/unexpected.c >+++ b/source3/libsmb/unexpected.c >@@ -21,7 +21,6 @@ > #include "includes.h" > #include "../lib/util/tevent_ntstatus.h" > #include "lib/tsocket/tsocket.h" >-#include "lib/async_req/async_sock.h" > #include "libsmb/nmblib.h" > > static const char *nmbd_socket_dir(void) >@@ -470,12 +469,11 @@ static void nb_packet_client_send_done(struct tevent_req *req) > } > > struct nb_packet_reader { >- int sock; >+ struct tstream_context *sock; > }; > > struct nb_packet_reader_state { > struct tevent_context *ev; >- struct sockaddr_un addr; > struct nb_packet_query query; > const char *mailslot_name; > struct iovec iov[2]; >@@ -483,7 +481,6 @@ struct nb_packet_reader_state { > struct nb_packet_reader *reader; > }; > >-static int nb_packet_reader_destructor(struct nb_packet_reader *r); > static void nb_packet_reader_connected(struct tevent_req *subreq); > static void nb_packet_reader_sent_query(struct tevent_req *subreq); > static void nb_packet_reader_got_ack(struct tevent_req *subreq); >@@ -496,7 +493,10 @@ struct tevent_req *nb_packet_reader_send(TALLOC_CTX *mem_ctx, > { > struct tevent_req *req, *subreq; > struct nb_packet_reader_state *state; >- char *path; >+ struct tsocket_address *laddr; >+ char *rpath; >+ struct tsocket_address *raddr; >+ int ret; > > req = tevent_req_create(mem_ctx, &state, > struct nb_packet_reader_state); >@@ -517,25 +517,23 @@ struct tevent_req *nb_packet_reader_send(TALLOC_CTX *mem_ctx, > return tevent_req_post(req, ev); > } > >- path = talloc_asprintf(talloc_tos(), "%s/%s", nmbd_socket_dir(), >+ ret = tsocket_address_unix_from_path(state, "", &laddr); >+ if (ret != 0) { >+ tevent_req_nterror(req, map_nt_error_from_unix(errno)); >+ return tevent_req_post(req, ev); >+ } >+ rpath = talloc_asprintf(state, "%s/%s", nmbd_socket_dir(), > "unexpected"); >- if (tevent_req_nomem(path, req)) { >+ if (tevent_req_nomem(rpath, req)) { > return tevent_req_post(req, ev); > } >- state->addr.sun_family = AF_UNIX; >- strlcpy(state->addr.sun_path, path, sizeof(state->addr.sun_path)); >- TALLOC_FREE(path); >- >- state->reader->sock = socket(AF_UNIX, SOCK_STREAM, 0); >- if (state->reader->sock == -1) { >+ ret = tsocket_address_unix_from_path(state, rpath, &raddr); >+ if (ret != 0) { > tevent_req_nterror(req, map_nt_error_from_unix(errno)); > return tevent_req_post(req, ev); > } >- talloc_set_destructor(state->reader, nb_packet_reader_destructor); > >- subreq = async_connect_send(state, ev, state->reader->sock, >- (struct sockaddr *)(void *)&state->addr, >- sizeof(state->addr), NULL, NULL, NULL); >+ subreq = tstream_unix_connect_send(state, ev, laddr, raddr); > if (tevent_req_nomem(subreq, req)) { > return tevent_req_post(req, ev); > } >@@ -543,15 +541,6 @@ struct tevent_req *nb_packet_reader_send(TALLOC_CTX *mem_ctx, > return req; > } > >-static int nb_packet_reader_destructor(struct nb_packet_reader *r) >-{ >- if (r->sock != -1) { >- close(r->sock); >- r->sock = -1; >- } >- return 0; >-} >- > static void nb_packet_reader_connected(struct tevent_req *subreq) > { > struct tevent_req *req = tevent_req_callback_data( >@@ -561,10 +550,11 @@ static void nb_packet_reader_connected(struct tevent_req *subreq) > int res, err; > int num_iovecs = 1; > >- res = async_connect_recv(subreq, &err); >+ res = tstream_unix_connect_recv(subreq, &err, state->reader, >+ &state->reader->sock); > TALLOC_FREE(subreq); > if (res == -1) { >- DEBUG(10, ("async_connect failed: %s\n", strerror(err))); >+ DEBUG(10, ("tstream_unix_connect failed: %s\n", strerror(err))); > tevent_req_nterror(req, map_nt_error_from_unix(err)); > return; > } >@@ -579,8 +569,8 @@ static void nb_packet_reader_connected(struct tevent_req *subreq) > state->iov[1].iov_len = state->query.mailslot_namelen; > } > >- subreq = writev_send(state, state->ev, NULL, state->reader->sock, >- true, state->iov, num_iovecs); >+ subreq = tstream_writev_send(state, state->ev, state->reader->sock, >+ state->iov, num_iovecs); > if (tevent_req_nomem(subreq, req)) { > return; > } >@@ -596,7 +586,7 @@ static void nb_packet_reader_sent_query(struct tevent_req *subreq) > ssize_t written; > int err; > >- written = writev_recv(subreq, &err); >+ written = tstream_writev_recv(subreq, &err); > TALLOC_FREE(subreq); > if (written == -1) { > tevent_req_nterror(req, map_nt_error_from_unix(err)); >@@ -606,8 +596,9 @@ static void nb_packet_reader_sent_query(struct tevent_req *subreq) > tevent_req_nterror(req, NT_STATUS_UNEXPECTED_IO_ERROR); > return; > } >- subreq = read_packet_send(state, state->ev, state->reader->sock, >- sizeof(state->c), NULL, NULL); >+ subreq = tstream_read_packet_send(state, state->ev, >+ state->reader->sock, >+ sizeof(state->c), NULL, NULL); > if (tevent_req_nomem(subreq, req)) { > return; > } >@@ -624,7 +615,7 @@ static void nb_packet_reader_got_ack(struct tevent_req *subreq) > int err; > uint8_t *buf; > >- nread = read_packet_recv(subreq, state, &buf, &err); >+ nread = tstream_read_packet_recv(subreq, state, &buf, &err); > TALLOC_FREE(subreq); > if (nread == -1) { > DEBUG(10, ("read_packet_recv returned %s\n", >@@ -649,9 +640,11 @@ NTSTATUS nb_packet_reader_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, > NTSTATUS status; > > if (tevent_req_is_nterror(req, &status)) { >+ tevent_req_received(req); > return status; > } > *preader = talloc_move(mem_ctx, &state->reader); >+ tevent_req_received(req); > return NT_STATUS_OK; > } > >@@ -675,9 +668,9 @@ struct tevent_req *nb_packet_read_send(TALLOC_CTX *mem_ctx, > if (req == NULL) { > return NULL; > } >- subreq = read_packet_send(state, ev, reader->sock, >- sizeof(struct nb_packet_client_header), >- nb_packet_read_more, state); >+ subreq = tstream_read_packet_send(state, ev, reader->sock, >+ sizeof(struct nb_packet_client_header), >+ nb_packet_read_more, state); > if (tevent_req_nomem(subreq, req)) { > return tevent_req_post(req, ev); > } >@@ -709,7 +702,7 @@ static void nb_packet_read_done(struct tevent_req *subreq) > ssize_t nread; > int err; > >- nread = read_packet_recv(subreq, state, &state->buf, &err); >+ nread = tstream_read_packet_recv(subreq, state, &state->buf, &err); > if (nread == -1) { > tevent_req_nterror(req, map_nt_error_from_unix(err)); > return; >@@ -728,6 +721,7 @@ NTSTATUS nb_packet_read_recv(struct tevent_req *req, > NTSTATUS status; > > if (tevent_req_is_nterror(req, &status)) { >+ tevent_req_received(req); > return status; > } > >@@ -738,8 +732,10 @@ NTSTATUS nb_packet_read_recv(struct tevent_req *req, > state->buflen - sizeof(struct nb_packet_client_header), > state->hdr.type, state->hdr.ip, state->hdr.port); > if (packet == NULL) { >+ tevent_req_received(req); > return NT_STATUS_INVALID_NETWORK_RESPONSE; > } > *ppacket = packet; >+ tevent_req_received(req); > return NT_STATUS_OK; > } >-- >1.9.1 > > >From dfcc414e7f4830ccde05523ff7154325c830ec72 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 21 May 2015 04:43:27 +0200 >Subject: [PATCH 16/31] s3:libsmb: convert nb_trans_send/recv internals to > tdgram > >This simplifies/fixes the cleanup, because we need to remove any >tevent_fd object before closing the socket fd. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=11316 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit a3282911f6ceb76b2ada567e569a55af8c7ef160) >--- > source3/libsmb/namequery.c | 102 +++++++++++++++++++++++++++++---------------- > 1 file changed, 66 insertions(+), 36 deletions(-) > >diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c >index d86c0ed..ed960a4 100644 >--- a/source3/libsmb/namequery.c >+++ b/source3/libsmb/namequery.c >@@ -24,6 +24,7 @@ > #include "../lib/addns/dnsquery.h" > #include "../libcli/netlogon/netlogon.h" > #include "lib/async_req/async_sock.h" >+#include "lib/tsocket/tsocket.h" > #include "libsmb/nmblib.h" > #include "../libcli/nbt/libnbt.h" > >@@ -294,11 +295,10 @@ struct sock_packet_read_state { > struct nb_packet_reader *reader; > struct tevent_req *reader_req; > >- int sock; >+ struct tdgram_context *sock; > struct tevent_req *socket_req; >- uint8_t buf[1024]; >- struct sockaddr_storage addr; >- socklen_t addr_len; >+ uint8_t *buf; >+ struct tsocket_address *addr; > > bool (*validator)(struct packet_struct *p, > void *private_data); >@@ -314,7 +314,7 @@ static void sock_packet_read_got_socket(struct tevent_req *subreq); > static struct tevent_req *sock_packet_read_send( > TALLOC_CTX *mem_ctx, > struct tevent_context *ev, >- int sock, /* dgram socket */ >+ struct tdgram_context *sock, > struct nb_packet_reader *reader, > enum packet_type type, > int trn_id, >@@ -347,10 +347,7 @@ static struct tevent_req *sock_packet_read_send( > state->reader_req, sock_packet_read_got_packet, req); > } > >- state->addr_len = sizeof(state->addr); >- state->socket_req = recvfrom_send(state, ev, sock, >- state->buf, sizeof(state->buf), 0, >- &state->addr, &state->addr_len); >+ state->socket_req = tdgram_recvfrom_send(state, ev, state->sock); > if (tevent_req_nomem(state->socket_req, req)) { > return tevent_req_post(req, ev); > } >@@ -422,11 +419,17 @@ static void sock_packet_read_got_socket(struct tevent_req *subreq) > subreq, struct tevent_req); > struct sock_packet_read_state *state = tevent_req_data( > req, struct sock_packet_read_state); >- struct sockaddr_in *in_addr; >+ union { >+ struct sockaddr sa; >+ struct sockaddr_in sin; >+ } addr; >+ ssize_t ret; > ssize_t received; > int err; >+ bool ok; > >- received = recvfrom_recv(subreq, &err); >+ received = tdgram_recvfrom_recv(subreq, &err, state, >+ &state->buf, &state->addr); > > TALLOC_FREE(state->socket_req); > >@@ -443,13 +446,20 @@ static void sock_packet_read_got_socket(struct tevent_req *subreq) > tevent_req_nterror(req, map_nt_error_from_unix(err)); > return; > } >- if (state->addr.ss_family != AF_INET) { >+ ok = tsocket_address_is_inet(state->addr, "ipv4"); >+ if (!ok) { > goto retry; > } >- in_addr = (struct sockaddr_in *)(void *)&state->addr; >+ ret = tsocket_address_bsd_sockaddr(state->addr, >+ &addr.sa, >+ sizeof(addr.sin)); >+ if (ret == -1) { >+ tevent_req_nterror(req, map_nt_error_from_unix(errno)); >+ return; >+ } > > state->packet = parse_packet((char *)state->buf, received, state->type, >- in_addr->sin_addr, in_addr->sin_port); >+ addr.sin.sin_addr, addr.sin.sin_port); > if (state->packet == NULL) { > DEBUG(10, ("parse_packet failed\n")); > goto retry; >@@ -475,9 +485,10 @@ retry: > free_packet(state->packet); > state->packet = NULL; > } >- state->socket_req = recvfrom_send(state, state->ev, state->sock, >- state->buf, sizeof(state->buf), 0, >- &state->addr, &state->addr_len); >+ TALLOC_FREE(state->buf); >+ TALLOC_FREE(state->addr); >+ >+ state->socket_req = tdgram_recvfrom_send(state, state->ev, state->sock); > if (tevent_req_nomem(state->socket_req, req)) { > return; > } >@@ -502,10 +513,11 @@ static NTSTATUS sock_packet_read_recv(struct tevent_req *req, > > struct nb_trans_state { > struct tevent_context *ev; >- int sock; >+ struct tdgram_context *sock; > struct nb_packet_reader *reader; > >- const struct sockaddr_storage *dst_addr; >+ struct tsocket_address *src_addr; >+ struct tsocket_address *dst_addr; > uint8_t *buf; > size_t buflen; > enum packet_type type; >@@ -527,8 +539,8 @@ static void nb_trans_send_next(struct tevent_req *subreq); > static struct tevent_req *nb_trans_send( > TALLOC_CTX *mem_ctx, > struct tevent_context *ev, >- const struct sockaddr_storage *my_addr, >- const struct sockaddr_storage *dst_addr, >+ const struct sockaddr_storage *_my_addr, >+ const struct sockaddr_storage *_dst_addr, > bool bcast, > uint8_t *buf, size_t buflen, > enum packet_type type, int trn_id, >@@ -536,8 +548,15 @@ static struct tevent_req *nb_trans_send( > void *private_data), > void *private_data) > { >+ const struct sockaddr *my_addr = >+ discard_const_p(const struct sockaddr, _my_addr); >+ size_t my_addr_len = sizeof(*_my_addr); >+ const struct sockaddr *dst_addr = >+ discard_const_p(const struct sockaddr, _dst_addr); >+ size_t dst_addr_len = sizeof(*_dst_addr); > struct tevent_req *req, *subreq; > struct nb_trans_state *state; >+ int ret; > > req = tevent_req_create(mem_ctx, &state, struct nb_trans_state); > if (req == NULL) { >@@ -545,7 +564,6 @@ static struct tevent_req *nb_trans_send( > } > talloc_set_destructor(state, nb_trans_state_destructor); > state->ev = ev; >- state->dst_addr = dst_addr; > state->buf = buf; > state->buflen = buflen; > state->type = type; >@@ -553,15 +571,27 @@ static struct tevent_req *nb_trans_send( > state->validator = validator; > state->private_data = private_data; > >- state->sock = open_socket_in(SOCK_DGRAM, 0, 3, my_addr, True); >- if (state->sock == -1) { >+ ret = tsocket_address_bsd_from_sockaddr(state, >+ my_addr, my_addr_len, >+ &state->src_addr); >+ if (ret == -1) { > tevent_req_nterror(req, map_nt_error_from_unix(errno)); >- DEBUG(10, ("open_socket_in failed: %s\n", strerror(errno))); > return tevent_req_post(req, ev); > } > >- if (bcast) { >- set_socket_options(state->sock,"SO_BROADCAST"); >+ ret = tsocket_address_bsd_from_sockaddr(state, >+ dst_addr, dst_addr_len, >+ &state->dst_addr); >+ if (ret == -1) { >+ tevent_req_nterror(req, map_nt_error_from_unix(errno)); >+ return tevent_req_post(req, ev); >+ } >+ >+ ret = tdgram_inet_udp_broadcast_socket(state->src_addr, state, >+ &state->sock); >+ if (ret == -1) { >+ tevent_req_nterror(req, map_nt_error_from_unix(errno)); >+ return tevent_req_post(req, ev); > } > > subreq = nb_packet_reader_send(state, ev, type, state->trn_id, NULL); >@@ -574,10 +604,6 @@ static struct tevent_req *nb_trans_send( > > static int nb_trans_state_destructor(struct nb_trans_state *s) > { >- if (s->sock != -1) { >- close(s->sock); >- s->sock = -1; >- } > if (s->packet != NULL) { > free_packet(s->packet); > s->packet = NULL; >@@ -610,8 +636,10 @@ static void nb_trans_got_reader(struct tevent_req *subreq) > } > tevent_req_set_callback(subreq, nb_trans_done, req); > >- subreq = sendto_send(state, state->ev, state->sock, >- state->buf, state->buflen, 0, state->dst_addr); >+ subreq = tdgram_sendto_send(state, state->ev, >+ state->sock, >+ state->buf, state->buflen, >+ state->dst_addr); > if (tevent_req_nomem(subreq, req)) { > return; > } >@@ -627,7 +655,7 @@ static void nb_trans_sent(struct tevent_req *subreq) > ssize_t sent; > int err; > >- sent = sendto_recv(subreq, &err); >+ sent = tdgram_sendto_recv(subreq, &err); > TALLOC_FREE(subreq); > if (sent == -1) { > DEBUG(10, ("sendto failed: %s\n", strerror(err))); >@@ -656,8 +684,10 @@ static void nb_trans_send_next(struct tevent_req *subreq) > tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR); > return; > } >- subreq = sendto_send(state, state->ev, state->sock, >- state->buf, state->buflen, 0, state->dst_addr); >+ subreq = tdgram_sendto_send(state, state->ev, >+ state->sock, >+ state->buf, state->buflen, >+ state->dst_addr); > if (tevent_req_nomem(subreq, req)) { > return; > } >-- >1.9.1 > > >From 24b6a5b605cded1afd29051dc697a02a04b39f85 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 21 May 2015 12:25:38 +0200 >Subject: [PATCH 17/31] lib/async_req: remove unused sendto_{send,recv} and > recvfrom_{send,recv} > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=11316 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit ccd038e1523a69197a9aaeca00305b0958f09ff0) >--- > lib/async_req/async_sock.c | 178 --------------------------------------------- > lib/async_req/async_sock.h | 12 --- > 2 files changed, 190 deletions(-) > >diff --git a/lib/async_req/async_sock.c b/lib/async_req/async_sock.c >index 74b2cb7..531d779 100644 >--- a/lib/async_req/async_sock.c >+++ b/lib/async_req/async_sock.c >@@ -32,184 +32,6 @@ > #include "lib/util/tevent_unix.h" > #include "lib/util/samba_util.h" > >-#ifndef TALLOC_FREE >-#define TALLOC_FREE(ctx) do { talloc_free(ctx); ctx=NULL; } while(0) >-#endif >- >-struct sendto_state { >- int fd; >- const void *buf; >- size_t len; >- int flags; >- const struct sockaddr_storage *addr; >- socklen_t addr_len; >- ssize_t sent; >-}; >- >-static void sendto_handler(struct tevent_context *ev, >- struct tevent_fd *fde, >- uint16_t flags, void *private_data); >- >-struct tevent_req *sendto_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, >- int fd, const void *buf, size_t len, int flags, >- const struct sockaddr_storage *addr) >-{ >- struct tevent_req *result; >- struct sendto_state *state; >- struct tevent_fd *fde; >- >- result = tevent_req_create(mem_ctx, &state, struct sendto_state); >- if (result == NULL) { >- return result; >- } >- state->fd = fd; >- state->buf = buf; >- state->len = len; >- state->flags = flags; >- state->addr = addr; >- >- switch (addr->ss_family) { >- case AF_INET: >- state->addr_len = sizeof(struct sockaddr_in); >- break; >-#if defined(HAVE_IPV6) >- case AF_INET6: >- state->addr_len = sizeof(struct sockaddr_in6); >- break; >-#endif >- case AF_UNIX: >- state->addr_len = sizeof(struct sockaddr_un); >- break; >- default: >- state->addr_len = sizeof(struct sockaddr_storage); >- break; >- } >- >- fde = tevent_add_fd(ev, state, fd, TEVENT_FD_WRITE, sendto_handler, >- result); >- if (fde == NULL) { >- TALLOC_FREE(result); >- return NULL; >- } >- return result; >-} >- >-static void sendto_handler(struct tevent_context *ev, >- struct tevent_fd *fde, >- uint16_t flags, void *private_data) >-{ >- struct tevent_req *req = talloc_get_type_abort( >- private_data, struct tevent_req); >- struct sendto_state *state = >- tevent_req_data(req, struct sendto_state); >- >- state->sent = sendto(state->fd, state->buf, state->len, state->flags, >- (const struct sockaddr *)state->addr, >- state->addr_len); >- if ((state->sent == -1) && (errno == EINTR)) { >- /* retry */ >- return; >- } >- if (state->sent == -1) { >- tevent_req_error(req, errno); >- return; >- } >- tevent_req_done(req); >-} >- >-ssize_t sendto_recv(struct tevent_req *req, int *perrno) >-{ >- struct sendto_state *state = >- tevent_req_data(req, struct sendto_state); >- >- if (tevent_req_is_unix_error(req, perrno)) { >- return -1; >- } >- return state->sent; >-} >- >-struct recvfrom_state { >- int fd; >- void *buf; >- size_t len; >- int flags; >- struct sockaddr_storage *addr; >- socklen_t *addr_len; >- ssize_t received; >-}; >- >-static void recvfrom_handler(struct tevent_context *ev, >- struct tevent_fd *fde, >- uint16_t flags, void *private_data); >- >-struct tevent_req *recvfrom_send(TALLOC_CTX *mem_ctx, >- struct tevent_context *ev, >- int fd, void *buf, size_t len, int flags, >- struct sockaddr_storage *addr, >- socklen_t *addr_len) >-{ >- struct tevent_req *result; >- struct recvfrom_state *state; >- struct tevent_fd *fde; >- >- result = tevent_req_create(mem_ctx, &state, struct recvfrom_state); >- if (result == NULL) { >- return result; >- } >- state->fd = fd; >- state->buf = buf; >- state->len = len; >- state->flags = flags; >- state->addr = addr; >- state->addr_len = addr_len; >- >- fde = tevent_add_fd(ev, state, fd, TEVENT_FD_READ, recvfrom_handler, >- result); >- if (fde == NULL) { >- TALLOC_FREE(result); >- return NULL; >- } >- return result; >-} >- >-static void recvfrom_handler(struct tevent_context *ev, >- struct tevent_fd *fde, >- uint16_t flags, void *private_data) >-{ >- struct tevent_req *req = talloc_get_type_abort( >- private_data, struct tevent_req); >- struct recvfrom_state *state = >- tevent_req_data(req, struct recvfrom_state); >- >- state->received = recvfrom(state->fd, state->buf, state->len, >- state->flags, (struct sockaddr *)state->addr, >- state->addr_len); >- if ((state->received == -1) && (errno == EINTR)) { >- /* retry */ >- return; >- } >- if (state->received == 0) { >- tevent_req_error(req, EPIPE); >- return; >- } >- if (state->received == -1) { >- tevent_req_error(req, errno); >- return; >- } >- tevent_req_done(req); >-} >- >-ssize_t recvfrom_recv(struct tevent_req *req, int *perrno) >-{ >- struct recvfrom_state *state = >- tevent_req_data(req, struct recvfrom_state); >- >- if (tevent_req_is_unix_error(req, perrno)) { >- return -1; >- } >- return state->received; >-} >- > struct async_connect_state { > int fd; > int result; >diff --git a/lib/async_req/async_sock.h b/lib/async_req/async_sock.h >index 494b92e..1b76fab 100644 >--- a/lib/async_req/async_sock.h >+++ b/lib/async_req/async_sock.h >@@ -28,18 +28,6 @@ > #include <tevent.h> > #include "system/network.h" > >-struct tevent_req *sendto_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, >- int fd, const void *buf, size_t len, int flags, >- const struct sockaddr_storage *addr); >-ssize_t sendto_recv(struct tevent_req *req, int *perrno); >- >-struct tevent_req *recvfrom_send(TALLOC_CTX *mem_ctx, >- struct tevent_context *ev, >- int fd, void *buf, size_t len, int flags, >- struct sockaddr_storage *addr, >- socklen_t *addr_len); >-ssize_t recvfrom_recv(struct tevent_req *req, int *perrno); >- > struct tevent_req *async_connect_send( > TALLOC_CTX *mem_ctx, struct tevent_context *ev, int fd, > const struct sockaddr *address, socklen_t address_len, >-- >1.9.1 > > >From cb49cb0c3678faeb1148011740fbc160effd7fd7 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Fri, 5 Jun 2015 13:58:19 +0200 >Subject: [PATCH 18/31] lib/async_req: s/result/req/ in async_connect_send() > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=11316 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit be8c2ff10353df00f05cd378c251a33a9e08563a) >--- > lib/async_req/async_sock.c | 17 ++++++++--------- > 1 file changed, 8 insertions(+), 9 deletions(-) > >diff --git a/lib/async_req/async_sock.c b/lib/async_req/async_sock.c >index 531d779..13c58ff 100644 >--- a/lib/async_req/async_sock.c >+++ b/lib/async_req/async_sock.c >@@ -69,13 +69,12 @@ struct tevent_req *async_connect_send( > void (*after_connect)(void *private_data), > void *private_data) > { >- struct tevent_req *result; >+ struct tevent_req *req; > struct async_connect_state *state; > struct tevent_fd *fde; > >- result = tevent_req_create( >- mem_ctx, &state, struct async_connect_state); >- if (result == NULL) { >+ req = tevent_req_create(mem_ctx, &state, struct async_connect_state); >+ if (req == NULL) { > return NULL; > } > >@@ -115,7 +114,7 @@ struct tevent_req *async_connect_send( > } > > if (state->result == 0) { >- tevent_req_done(result); >+ tevent_req_done(req); > goto done; > } > >@@ -136,18 +135,18 @@ struct tevent_req *async_connect_send( > } > > fde = tevent_add_fd(ev, state, fd, TEVENT_FD_READ | TEVENT_FD_WRITE, >- async_connect_connected, result); >+ async_connect_connected, req); > if (fde == NULL) { > state->sys_errno = ENOMEM; > goto post_errno; > } >- return result; >+ return req; > > post_errno: >- tevent_req_error(result, state->sys_errno); >+ tevent_req_error(req, state->sys_errno); > done: > fcntl(fd, F_SETFL, state->old_sockflags); >- return tevent_req_post(result, ev); >+ return tevent_req_post(req, ev); > } > > /** >-- >1.9.1 > > >From 42a3fd6e77e07f25c99ff0a285717eb444932261 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 21 May 2015 22:28:14 +0200 >Subject: [PATCH 19/31] lib/async_req: simplify async_connect_* using a > _cleanup() hook > >This makes sure we remove the tevent_fd as soon as possible >and always reset the old_sockflags. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=11316 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit d5a4b30f894f0d4d4fa728ebd2c435254bf3b142) >--- > lib/async_req/async_sock.c | 68 ++++++++++++++++++++++------------------------ > 1 file changed, 33 insertions(+), 35 deletions(-) > >diff --git a/lib/async_req/async_sock.c b/lib/async_req/async_sock.c >index 13c58ff..2080ac9 100644 >--- a/lib/async_req/async_sock.c >+++ b/lib/async_req/async_sock.c >@@ -34,8 +34,8 @@ > > struct async_connect_state { > int fd; >+ struct tevent_fd *fde; > int result; >- int sys_errno; > long old_sockflags; > socklen_t address_len; > struct sockaddr_storage address; >@@ -45,6 +45,8 @@ struct async_connect_state { > void *private_data; > }; > >+static void async_connect_cleanup(struct tevent_req *req, >+ enum tevent_req_state req_state); > static void async_connect_connected(struct tevent_context *ev, > struct tevent_fd *fde, uint16_t flags, > void *priv); >@@ -71,7 +73,6 @@ struct tevent_req *async_connect_send( > { > struct tevent_req *req; > struct async_connect_state *state; >- struct tevent_fd *fde; > > req = tevent_req_create(mem_ctx, &state, struct async_connect_state); > if (req == NULL) { >@@ -84,20 +85,22 @@ struct tevent_req *async_connect_send( > */ > > state->fd = fd; >- state->sys_errno = 0; > state->before_connect = before_connect; > state->after_connect = after_connect; > state->private_data = private_data; > > state->old_sockflags = fcntl(fd, F_GETFL, 0); > if (state->old_sockflags == -1) { >- goto post_errno; >+ tevent_req_error(req, errno); >+ return tevent_req_post(req, ev); > } > >+ tevent_req_set_cleanup_fn(req, async_connect_cleanup); >+ > state->address_len = address_len; > if (address_len > sizeof(state->address)) { >- errno = EINVAL; >- goto post_errno; >+ tevent_req_error(req, EINVAL); >+ return tevent_req_post(req, ev); > } > memcpy(&state->address, address, address_len); > >@@ -115,7 +118,7 @@ struct tevent_req *async_connect_send( > > if (state->result == 0) { > tevent_req_done(req); >- goto done; >+ return tevent_req_post(req, ev); > } > > /** >@@ -130,23 +133,31 @@ struct tevent_req *async_connect_send( > errno == EISCONN || > #endif > errno == EAGAIN || errno == EINTR)) { >- state->sys_errno = errno; >- goto post_errno; >+ tevent_req_error(req, errno); >+ return tevent_req_post(req, ev); > } > >- fde = tevent_add_fd(ev, state, fd, TEVENT_FD_READ | TEVENT_FD_WRITE, >- async_connect_connected, req); >- if (fde == NULL) { >- state->sys_errno = ENOMEM; >- goto post_errno; >+ state->fde = tevent_add_fd(ev, state, fd, >+ TEVENT_FD_READ | TEVENT_FD_WRITE, >+ async_connect_connected, req); >+ if (state->fde == NULL) { >+ tevent_req_error(req, ENOMEM); >+ return tevent_req_post(req, ev); > } > return req; >+} > >- post_errno: >- tevent_req_error(req, state->sys_errno); >- done: >- fcntl(fd, F_SETFL, state->old_sockflags); >- return tevent_req_post(req, ev); >+static void async_connect_cleanup(struct tevent_req *req, >+ enum tevent_req_state req_state) >+{ >+ struct async_connect_state *state = >+ tevent_req_data(req, struct async_connect_state); >+ >+ TALLOC_FREE(state->fde); >+ if (state->fd != -1) { >+ fcntl(state->fd, F_SETFL, state->old_sockflags); >+ state->fd = -1; >+ } > } > > /** >@@ -179,8 +190,6 @@ static void async_connect_connected(struct tevent_context *ev, > } > > if (ret == 0) { >- state->sys_errno = 0; >- TALLOC_FREE(fde); > tevent_req_done(req); > return; > } >@@ -188,31 +197,20 @@ static void async_connect_connected(struct tevent_context *ev, > /* Try again later, leave the fde around */ > return; > } >- state->sys_errno = errno; >- TALLOC_FREE(fde); > tevent_req_error(req, errno); > return; > } > > int async_connect_recv(struct tevent_req *req, int *perrno) > { >- struct async_connect_state *state = >- tevent_req_data(req, struct async_connect_state); >- int err; >- >- fcntl(state->fd, F_SETFL, state->old_sockflags); >+ int err = tevent_req_simple_recv_unix(req); > >- if (tevent_req_is_unix_error(req, &err)) { >+ if (err != 0) { > *perrno = err; > return -1; > } > >- if (state->sys_errno == 0) { >- return 0; >- } >- >- *perrno = state->sys_errno; >- return -1; >+ return 0; > } > > struct writev_state { >-- >1.9.1 > > >From ff9d7f4c080284d27becda525f147d588d8b57e8 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 21 May 2015 22:28:14 +0200 >Subject: [PATCH 20/31] lib/async_req: remove the tevent_fd as early as > possible via a writev_cleanup() hook > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=11316 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit 0c1109695639a177d3d739b343e7588a6ecf0949) >--- > lib/async_req/async_sock.c | 41 +++++++++++++++++++++++++++-------------- > 1 file changed, 27 insertions(+), 14 deletions(-) > >diff --git a/lib/async_req/async_sock.c b/lib/async_req/async_sock.c >index 2080ac9..3f659ae 100644 >--- a/lib/async_req/async_sock.c >+++ b/lib/async_req/async_sock.c >@@ -216,6 +216,7 @@ int async_connect_recv(struct tevent_req *req, int *perrno) > struct writev_state { > struct tevent_context *ev; > int fd; >+ struct tevent_fd *fde; > struct iovec *iov; > int count; > size_t total_size; >@@ -223,6 +224,8 @@ struct writev_state { > bool err_on_readability; > }; > >+static void writev_cleanup(struct tevent_req *req, >+ enum tevent_req_state req_state); > static void writev_trigger(struct tevent_req *req, void *private_data); > static void writev_handler(struct tevent_context *ev, struct tevent_fd *fde, > uint16_t flags, void *private_data); >@@ -245,40 +248,46 @@ struct tevent_req *writev_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, > state->count = count; > state->iov = (struct iovec *)talloc_memdup( > state, iov, sizeof(struct iovec) * count); >- if (state->iov == NULL) { >- goto fail; >+ if (tevent_req_nomem(state->iov, req)) { >+ return tevent_req_post(req, ev); > } > state->flags = TEVENT_FD_WRITE|TEVENT_FD_READ; > state->err_on_readability = err_on_readability; > >+ tevent_req_set_cleanup_fn(req, writev_cleanup); >+ > if (queue == NULL) { >- struct tevent_fd *fde; >- fde = tevent_add_fd(state->ev, state, state->fd, >+ state->fde = tevent_add_fd(state->ev, state, state->fd, > state->flags, writev_handler, req); >- if (tevent_req_nomem(fde, req)) { >+ if (tevent_req_nomem(state->fde, req)) { > return tevent_req_post(req, ev); > } > return req; > } > > if (!tevent_queue_add(queue, ev, req, writev_trigger, NULL)) { >- goto fail; >+ tevent_req_nomem(NULL, req); >+ return tevent_req_post(req, ev); > } > return req; >- fail: >- TALLOC_FREE(req); >- return NULL; >+} >+ >+static void writev_cleanup(struct tevent_req *req, >+ enum tevent_req_state req_state) >+{ >+ struct writev_state *state = tevent_req_data(req, struct writev_state); >+ >+ TALLOC_FREE(state->fde); > } > > static void writev_trigger(struct tevent_req *req, void *private_data) > { > struct writev_state *state = tevent_req_data(req, struct writev_state); >- struct tevent_fd *fde; > >- fde = tevent_add_fd(state->ev, state, state->fd, state->flags, >+ state->fde = tevent_add_fd(state->ev, state, state->fd, state->flags, > writev_handler, req); >- if (fde == NULL) { >- tevent_req_error(req, ENOMEM); >+ if (tevent_req_nomem(state->fde, req)) { >+ return; > } > } > >@@ -372,11 +381,15 @@ ssize_t writev_recv(struct tevent_req *req, int *perrno) > { > struct writev_state *state = > tevent_req_data(req, struct writev_state); >+ ssize_t ret; > > if (tevent_req_is_unix_error(req, perrno)) { >+ tevent_req_received(req); > return -1; > } >- return state->total_size; >+ ret = state->total_size; >+ tevent_req_received(req); >+ return ret; > } > > struct read_packet_state { >-- >1.9.1 > > >From 5b21e4fa29a6e90e074266ba4965791cb7ae1a86 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 21 May 2015 22:28:14 +0200 >Subject: [PATCH 21/31] lib/async_req: s/result/req/ in read_packet_send() > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=11316 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit 4f05f68abc1d756bb114260e80d3532f3f959fec) >--- > lib/async_req/async_sock.c | 12 ++++++------ > 1 file changed, 6 insertions(+), 6 deletions(-) > >diff --git a/lib/async_req/async_sock.c b/lib/async_req/async_sock.c >index 3f659ae..cf21246 100644 >--- a/lib/async_req/async_sock.c >+++ b/lib/async_req/async_sock.c >@@ -412,12 +412,12 @@ struct tevent_req *read_packet_send(TALLOC_CTX *mem_ctx, > void *private_data), > void *private_data) > { >- struct tevent_req *result; >+ struct tevent_req *req; > struct read_packet_state *state; > struct tevent_fd *fde; > >- result = tevent_req_create(mem_ctx, &state, struct read_packet_state); >- if (result == NULL) { >+ req = tevent_req_create(mem_ctx, &state, struct read_packet_state); >+ if (req == NULL) { > return NULL; > } > state->fd = fd; >@@ -431,13 +431,13 @@ struct tevent_req *read_packet_send(TALLOC_CTX *mem_ctx, > } > > fde = tevent_add_fd(ev, state, fd, TEVENT_FD_READ, read_packet_handler, >- result); >+ req); > if (fde == NULL) { > goto fail; > } >- return result; >+ return req; > fail: >- TALLOC_FREE(result); >+ TALLOC_FREE(req); > return NULL; > } > >-- >1.9.1 > > >From 9a9c04b61ad634b3a7df1fc10286ce845bfb07dd Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 21 May 2015 22:28:14 +0200 >Subject: [PATCH 22/31] lib/async_req: use tevent_req_nomem/tevent_req_post in > read_packet_send() > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=11316 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit 9a116b28bab20507760f50f25214635a60ea6c43) >--- > lib/async_req/async_sock.c | 11 ++++------- > 1 file changed, 4 insertions(+), 7 deletions(-) > >diff --git a/lib/async_req/async_sock.c b/lib/async_req/async_sock.c >index cf21246..372aaa0 100644 >--- a/lib/async_req/async_sock.c >+++ b/lib/async_req/async_sock.c >@@ -426,19 +426,16 @@ struct tevent_req *read_packet_send(TALLOC_CTX *mem_ctx, > state->private_data = private_data; > > state->buf = talloc_array(state, uint8_t, initial); >- if (state->buf == NULL) { >- goto fail; >+ if (tevent_req_nomem(state->buf, req)) { >+ return tevent_req_post(req, ev); > } > > fde = tevent_add_fd(ev, state, fd, TEVENT_FD_READ, read_packet_handler, > req); >- if (fde == NULL) { >- goto fail; >+ if (tevent_req_nomem(fde, req)) { >+ return tevent_req_post(req, ev); > } > return req; >- fail: >- TALLOC_FREE(req); >- return NULL; > } > > static void read_packet_handler(struct tevent_context *ev, >-- >1.9.1 > > >From c37d9fd0725666a80bc4be284bbdeb55243efc07 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 21 May 2015 22:28:14 +0200 >Subject: [PATCH 23/31] lib/async_req: remove the tevent_fd as early as > possible via a read_packet_cleanup() hook > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=11316 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit a2a7cbc66c4713493e6ade45d0cdde25f64c9007) >--- > lib/async_req/async_sock.c | 24 ++++++++++++++++++++---- > 1 file changed, 20 insertions(+), 4 deletions(-) > >diff --git a/lib/async_req/async_sock.c b/lib/async_req/async_sock.c >index 372aaa0..8e04a08 100644 >--- a/lib/async_req/async_sock.c >+++ b/lib/async_req/async_sock.c >@@ -394,12 +394,15 @@ ssize_t writev_recv(struct tevent_req *req, int *perrno) > > struct read_packet_state { > int fd; >+ struct tevent_fd *fde; > uint8_t *buf; > size_t nread; > ssize_t (*more)(uint8_t *buf, size_t buflen, void *private_data); > void *private_data; > }; > >+static void read_packet_cleanup(struct tevent_req *req, >+ enum tevent_req_state req_state); > static void read_packet_handler(struct tevent_context *ev, > struct tevent_fd *fde, > uint16_t flags, void *private_data); >@@ -414,7 +417,6 @@ struct tevent_req *read_packet_send(TALLOC_CTX *mem_ctx, > { > struct tevent_req *req; > struct read_packet_state *state; >- struct tevent_fd *fde; > > req = tevent_req_create(mem_ctx, &state, struct read_packet_state); > if (req == NULL) { >@@ -425,19 +427,31 @@ struct tevent_req *read_packet_send(TALLOC_CTX *mem_ctx, > state->more = more; > state->private_data = private_data; > >+ tevent_req_set_cleanup_fn(req, read_packet_cleanup); >+ > state->buf = talloc_array(state, uint8_t, initial); > if (tevent_req_nomem(state->buf, req)) { > return tevent_req_post(req, ev); > } > >- fde = tevent_add_fd(ev, state, fd, TEVENT_FD_READ, read_packet_handler, >- req); >- if (tevent_req_nomem(fde, req)) { >+ state->fde = tevent_add_fd(ev, state, fd, >+ TEVENT_FD_READ, read_packet_handler, >+ req); >+ if (tevent_req_nomem(state->fde, req)) { > return tevent_req_post(req, ev); > } > return req; > } > >+static void read_packet_cleanup(struct tevent_req *req, >+ enum tevent_req_state req_state) >+{ >+ struct read_packet_state *state = >+ tevent_req_data(req, struct read_packet_state); >+ >+ TALLOC_FREE(state->fde); >+} >+ > static void read_packet_handler(struct tevent_context *ev, > struct tevent_fd *fde, > uint16_t flags, void *private_data) >@@ -515,9 +529,11 @@ ssize_t read_packet_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, > tevent_req_data(req, struct read_packet_state); > > if (tevent_req_is_unix_error(req, perrno)) { >+ tevent_req_received(req); > return -1; > } > *pbuf = talloc_move(mem_ctx, &state->buf); >+ tevent_req_received(req); > return talloc_get_size(*pbuf); > } > >-- >1.9.1 > > >From 0b9c5ec360637bb0dbe0e0cb769d0f404ee400cd Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 21 May 2015 22:28:14 +0200 >Subject: [PATCH 24/31] lib/async_req: remove the tevent_fd as early as > possible via a wait_for_read_cleanup() hook > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=11316 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit 64640cc99c7b8543ee8d35ca243c57c048cdb490) >--- > lib/async_req/async_sock.c | 30 +++++++++++++++++++++--------- > 1 file changed, 21 insertions(+), 9 deletions(-) > >diff --git a/lib/async_req/async_sock.c b/lib/async_req/async_sock.c >index 8e04a08..2f3225d 100644 >--- a/lib/async_req/async_sock.c >+++ b/lib/async_req/async_sock.c >@@ -538,10 +538,11 @@ ssize_t read_packet_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, > } > > struct wait_for_read_state { >- struct tevent_req *req; > struct tevent_fd *fde; > }; > >+static void wait_for_read_cleanup(struct tevent_req *req, >+ enum tevent_req_state req_state); > static void wait_for_read_done(struct tevent_context *ev, > struct tevent_fd *fde, > uint16_t flags, >@@ -558,36 +559,47 @@ struct tevent_req *wait_for_read_send(TALLOC_CTX *mem_ctx, > if (req == NULL) { > return NULL; > } >- state->req = req; >+ >+ tevent_req_set_cleanup_fn(req, wait_for_read_cleanup); >+ > state->fde = tevent_add_fd(ev, state, fd, TEVENT_FD_READ, >- wait_for_read_done, state); >+ wait_for_read_done, req); > if (tevent_req_nomem(state->fde, req)) { > return tevent_req_post(req, ev); > } > return req; > } > >+static void wait_for_read_cleanup(struct tevent_req *req, >+ enum tevent_req_state req_state) >+{ >+ struct wait_for_read_state *state = >+ tevent_req_data(req, struct wait_for_read_state); >+ >+ TALLOC_FREE(state->fde); >+} >+ > static void wait_for_read_done(struct tevent_context *ev, > struct tevent_fd *fde, > uint16_t flags, > void *private_data) > { >- struct wait_for_read_state *state = talloc_get_type_abort( >- private_data, struct wait_for_read_state); >+ struct tevent_req *req = talloc_get_type_abort( >+ private_data, struct tevent_req); > > if (flags & TEVENT_FD_READ) { >- TALLOC_FREE(state->fde); >- tevent_req_done(state->req); >+ tevent_req_done(req); > } > } > > bool wait_for_read_recv(struct tevent_req *req, int *perr) > { >- int err; >+ int err = tevent_req_simple_recv_unix(req); > >- if (tevent_req_is_unix_error(req, &err)) { >+ if (err != 0) { > *perr = err; > return false; > } >+ > return true; > } >-- >1.9.1 > > >From f8e0796a221a68ec3e1b334fa0025687c7a14c3b Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 21 May 2015 22:29:55 +0200 >Subject: [PATCH 25/31] libcli/smb: use tevent_req_received(req) in > read_smb_recv() > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=11316 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit 26c4b3fc9db507557b2539dd7d1f9e593c3fa35a) >--- > libcli/smb/read_smb.c | 2 ++ > 1 file changed, 2 insertions(+) > >diff --git a/libcli/smb/read_smb.c b/libcli/smb/read_smb.c >index 26816c3..a40f702 100644 >--- a/libcli/smb/read_smb.c >+++ b/libcli/smb/read_smb.c >@@ -105,8 +105,10 @@ ssize_t read_smb_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, > req, struct read_smb_state); > > if (tevent_req_is_unix_error(req, perrno)) { >+ tevent_req_received(req); > return -1; > } > *pbuf = talloc_move(mem_ctx, &state->buf); >+ tevent_req_received(req); > return talloc_get_size(*pbuf); > } >-- >1.9.1 > > >From 0aa29840d6fc44f097485617074b9eb2d3c0beb6 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 28 May 2015 13:09:11 +0200 >Subject: [PATCH 26/31] libcli/smb: close the socket fd at the end of > smbXcli_conn_disconnect() > >We need to cancel all pending requests before closing the socket fds, >otherwise we cause problem with the interaction with the epoll event backend. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=11316 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit 46e1aa22b12eacc3567f7897716ae07837545c23) >--- > libcli/smb/smbXcli_base.c | 15 +++++++++------ > 1 file changed, 9 insertions(+), 6 deletions(-) > >diff --git a/libcli/smb/smbXcli_base.c b/libcli/smb/smbXcli_base.c >index 8a1a51a..9ab3624 100644 >--- a/libcli/smb/smbXcli_base.c >+++ b/libcli/smb/smbXcli_base.c >@@ -971,15 +971,11 @@ static bool smbXcli_conn_receive_next(struct smbXcli_conn *conn) > void smbXcli_conn_disconnect(struct smbXcli_conn *conn, NTSTATUS status) > { > struct smbXcli_session *session; >+ int read_fd = conn->read_fd; >+ int write_fd = conn->write_fd; > > tevent_queue_stop(conn->outgoing); > >- if (conn->read_fd != -1) { >- close(conn->read_fd); >- } >- if (conn->write_fd != -1) { >- close(conn->write_fd); >- } > conn->read_fd = -1; > conn->write_fd = -1; > >@@ -1062,6 +1058,13 @@ void smbXcli_conn_disconnect(struct smbXcli_conn *conn, NTSTATUS status) > } > TALLOC_FREE(chain); > } >+ >+ if (read_fd != -1) { >+ close(read_fd); >+ } >+ if (write_fd != -1) { >+ close(write_fd); >+ } > } > > /* >-- >1.9.1 > > >From c02a3e3382fd5643f37d966c30d2742213974f87 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 28 May 2015 13:22:19 +0200 >Subject: [PATCH 27/31] libcli/smb: remove unused split of read_fd and write_fd > >The tevent epoll backend supports separate read and write tevent_fd structure >on a single fd, so there's no need for a dup() anymore. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=11316 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit 8f42df235dc825a103631fdf0e37e1c1d03cf420) >--- > libcli/smb/smbXcli_base.c | 38 ++++++++++++-------------------------- > 1 file changed, 12 insertions(+), 26 deletions(-) > >diff --git a/libcli/smb/smbXcli_base.c b/libcli/smb/smbXcli_base.c >index 9ab3624..7a79888 100644 >--- a/libcli/smb/smbXcli_base.c >+++ b/libcli/smb/smbXcli_base.c >@@ -39,8 +39,7 @@ struct smbXcli_session; > struct smbXcli_tcon; > > struct smbXcli_conn { >- int read_fd; >- int write_fd; >+ int sock_fd; > struct sockaddr_storage local_ss; > struct sockaddr_storage remote_ss; > const char *remote_name; >@@ -305,18 +304,13 @@ struct smbXcli_conn *smbXcli_conn_create(TALLOC_CTX *mem_ctx, > return NULL; > } > >- conn->read_fd = fd; >- conn->write_fd = dup(fd); >- if (conn->write_fd == -1) { >- goto error; >- } >+ conn->sock_fd = fd; > > conn->remote_name = talloc_strdup(conn, remote_name); > if (conn->remote_name == NULL) { > goto error; > } > >- > ss = (void *)&conn->local_ss; > sa = (struct sockaddr *)ss; > sa_length = sizeof(conn->local_ss); >@@ -401,9 +395,6 @@ struct smbXcli_conn *smbXcli_conn_create(TALLOC_CTX *mem_ctx, > return conn; > > error: >- if (conn->write_fd != -1) { >- close(conn->write_fd); >- } > TALLOC_FREE(conn); > return NULL; > } >@@ -414,7 +405,7 @@ bool smbXcli_conn_is_connected(struct smbXcli_conn *conn) > return false; > } > >- if (conn->read_fd == -1) { >+ if (conn->sock_fd == -1) { > return false; > } > >@@ -441,7 +432,7 @@ bool smbXcli_conn_use_unicode(struct smbXcli_conn *conn) > > void smbXcli_conn_set_sockopt(struct smbXcli_conn *conn, const char *options) > { >- set_socket_options(conn->read_fd, options); >+ set_socket_options(conn->sock_fd, options); > } > > const struct sockaddr_storage *smbXcli_conn_local_sockaddr(struct smbXcli_conn *conn) >@@ -527,7 +518,7 @@ struct tevent_req *smbXcli_conn_samba_suicide_send(TALLOC_CTX *mem_ctx, > state->iov.iov_base = state->buf; > state->iov.iov_len = sizeof(state->buf); > >- subreq = writev_send(state, ev, conn->outgoing, conn->write_fd, >+ subreq = writev_send(state, ev, conn->outgoing, conn->sock_fd, > false, &state->iov, 1); > if (tevent_req_nomem(subreq, req)) { > return tevent_req_post(req, ev); >@@ -960,7 +951,7 @@ static bool smbXcli_conn_receive_next(struct smbXcli_conn *conn) > */ > conn->read_smb_req = read_smb_send(conn->pending, > state->ev, >- conn->read_fd); >+ conn->sock_fd); > if (conn->read_smb_req == NULL) { > return false; > } >@@ -971,13 +962,11 @@ static bool smbXcli_conn_receive_next(struct smbXcli_conn *conn) > void smbXcli_conn_disconnect(struct smbXcli_conn *conn, NTSTATUS status) > { > struct smbXcli_session *session; >- int read_fd = conn->read_fd; >- int write_fd = conn->write_fd; >+ int sock_fd = conn->sock_fd; > > tevent_queue_stop(conn->outgoing); > >- conn->read_fd = -1; >- conn->write_fd = -1; >+ conn->sock_fd = -1; > > session = conn->sessions; > if (talloc_array_length(conn->pending) == 0) { >@@ -1059,11 +1048,8 @@ void smbXcli_conn_disconnect(struct smbXcli_conn *conn, NTSTATUS status) > TALLOC_FREE(chain); > } > >- if (read_fd != -1) { >- close(read_fd); >- } >- if (write_fd != -1) { >- close(write_fd); >+ if (sock_fd != -1) { >+ close(sock_fd); > } > } > >@@ -1529,7 +1515,7 @@ static NTSTATUS smb1cli_req_writev_submit(struct tevent_req *req, > tevent_req_set_cancel_fn(req, smbXcli_req_cancel); > > subreq = writev_send(state, state->ev, state->conn->outgoing, >- state->conn->write_fd, false, iov, iov_count); >+ state->conn->sock_fd, false, iov, iov_count); > if (subreq == NULL) { > return NT_STATUS_NO_MEMORY; > } >@@ -3048,7 +3034,7 @@ skip_credits: > } > > subreq = writev_send(state, state->ev, state->conn->outgoing, >- state->conn->write_fd, false, iov, num_iov); >+ state->conn->sock_fd, false, iov, num_iov); > if (subreq == NULL) { > return NT_STATUS_NO_MEMORY; > } >-- >1.9.1 > > >From 3192a1485e126e3375285a071010df45aec4fe2a Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Fri, 29 May 2015 15:29:31 +0200 >Subject: [PATCH 28/31] libcli/smb: make sure the writev_send of > smbXcli_conn_samba_suicide() is removed before closing the socket > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=11316 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit 59338434274799db1ac60b082a6453bd924c5f4c) >--- > libcli/smb/smbXcli_base.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 53 insertions(+) > >diff --git a/libcli/smb/smbXcli_base.c b/libcli/smb/smbXcli_base.c >index 7a79888..85b7066 100644 >--- a/libcli/smb/smbXcli_base.c >+++ b/libcli/smb/smbXcli_base.c >@@ -47,6 +47,7 @@ struct smbXcli_conn { > struct tevent_queue *outgoing; > struct tevent_req **pending; > struct tevent_req *read_smb_req; >+ struct tevent_req *suicide_req; > > enum protocol_types protocol; > bool allow_signing; >@@ -493,8 +494,11 @@ struct smbXcli_conn_samba_suicide_state { > struct smbXcli_conn *conn; > struct iovec iov; > uint8_t buf[9]; >+ struct tevent_req *write_req; > }; > >+static void smbXcli_conn_samba_suicide_cleanup(struct tevent_req *req, >+ enum tevent_req_state req_state); > static void smbXcli_conn_samba_suicide_done(struct tevent_req *subreq); > > struct tevent_req *smbXcli_conn_samba_suicide_send(TALLOC_CTX *mem_ctx, >@@ -515,6 +519,11 @@ struct tevent_req *smbXcli_conn_samba_suicide_send(TALLOC_CTX *mem_ctx, > SCVAL(state->buf, 8, exitcode); > _smb_setlen_nbt(state->buf, sizeof(state->buf)-4); > >+ if (conn->suicide_req != NULL) { >+ tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); >+ return tevent_req_post(req, ev); >+ } >+ > state->iov.iov_base = state->buf; > state->iov.iov_len = sizeof(state->buf); > >@@ -524,9 +533,39 @@ struct tevent_req *smbXcli_conn_samba_suicide_send(TALLOC_CTX *mem_ctx, > return tevent_req_post(req, ev); > } > tevent_req_set_callback(subreq, smbXcli_conn_samba_suicide_done, req); >+ state->write_req = subreq; >+ >+ tevent_req_set_cleanup_fn(req, smbXcli_conn_samba_suicide_cleanup); >+ >+ /* >+ * We need to use tevent_req_defer_callback() >+ * in order to allow smbXcli_conn_disconnect() >+ * to do a safe cleanup. >+ */ >+ tevent_req_defer_callback(req, ev); >+ conn->suicide_req = req; >+ > return req; > } > >+static void smbXcli_conn_samba_suicide_cleanup(struct tevent_req *req, >+ enum tevent_req_state req_state) >+{ >+ struct smbXcli_conn_samba_suicide_state *state = tevent_req_data( >+ req, struct smbXcli_conn_samba_suicide_state); >+ >+ TALLOC_FREE(state->write_req); >+ >+ if (state->conn == NULL) { >+ return; >+ } >+ >+ if (state->conn->suicide_req == req) { >+ state->conn->suicide_req = NULL; >+ } >+ state->conn = NULL; >+} >+ > static void smbXcli_conn_samba_suicide_done(struct tevent_req *subreq) > { > struct tevent_req *req = tevent_req_callback_data( >@@ -536,9 +575,12 @@ static void smbXcli_conn_samba_suicide_done(struct tevent_req *subreq) > ssize_t nwritten; > int err; > >+ state->write_req = NULL; >+ > nwritten = writev_recv(subreq, &err); > TALLOC_FREE(subreq); > if (nwritten == -1) { >+ /* here, we need to notify all pending requests */ > NTSTATUS status = map_nt_error_from_unix_common(err); > smbXcli_conn_disconnect(state->conn, status); > return; >@@ -980,6 +1022,17 @@ void smbXcli_conn_disconnect(struct smbXcli_conn *conn, NTSTATUS status) > smb2cli_session_increment_channel_sequence(session); > } > >+ if (conn->suicide_req != NULL) { >+ /* >+ * smbXcli_conn_samba_suicide_send() >+ * used tevent_req_defer_callback() already. >+ */ >+ if (!NT_STATUS_IS_OK(status)) { >+ tevent_req_nterror(conn->suicide_req, status); >+ } >+ conn->suicide_req = NULL; >+ } >+ > /* > * Cancel all pending requests. We do not do a for-loop walking > * conn->pending because that array changes in >-- >1.9.1 > > >From ac25405ca46b6adc53201d080aa54a94ecf0dc51 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Fri, 29 May 2015 15:48:26 +0200 >Subject: [PATCH 29/31] libcli/smb: add smb1 requests to the pending array > before writev_send() > >This way we have a change to destroy the pending writev_send request before >closing the socket in smbXcli_conn_disconnect(). > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=11316 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit f3982eb2c7f1d17a013dacfd430a3752e6ef4ae4) >--- > libcli/smb/smbXcli_base.c | 18 ++++++------------ > 1 file changed, 6 insertions(+), 12 deletions(-) > >diff --git a/libcli/smb/smbXcli_base.c b/libcli/smb/smbXcli_base.c >index 85b7066..7bb302d 100644 >--- a/libcli/smb/smbXcli_base.c >+++ b/libcli/smb/smbXcli_base.c >@@ -640,14 +640,9 @@ uint32_t smb1cli_conn_max_xmit(struct smbXcli_conn *conn) > > bool smb1cli_conn_req_possible(struct smbXcli_conn *conn) > { >- size_t pending; >+ size_t pending = talloc_array_length(conn->pending); > uint16_t possible = conn->smb1.server.max_mux; > >- pending = tevent_queue_length(conn->outgoing); >- if (pending >= possible) { >- return false; >- } >- pending += talloc_array_length(conn->pending); > if (pending >= possible) { > return false; > } >@@ -1565,6 +1560,10 @@ static NTSTATUS smb1cli_req_writev_submit(struct tevent_req *req, > state->conn->dispatch_incoming = smb1cli_conn_dispatch_incoming; > } > >+ if (!smbXcli_req_set_pending(req)) { >+ return NT_STATUS_NO_MEMORY; >+ } >+ > tevent_req_set_cancel_fn(req, smbXcli_req_cancel); > > subreq = writev_send(state, state->ev, state->conn->outgoing, >@@ -1632,9 +1631,9 @@ static void smb1cli_req_writev_done(struct tevent_req *subreq) > nwritten = writev_recv(subreq, &err); > TALLOC_FREE(subreq); > if (nwritten == -1) { >+ /* here, we need to notify all pending requests */ > NTSTATUS status = map_nt_error_from_unix_common(err); > smbXcli_conn_disconnect(state->conn, status); >- tevent_req_nterror(req, status); > return; > } > >@@ -1643,11 +1642,6 @@ static void smb1cli_req_writev_done(struct tevent_req *subreq) > tevent_req_done(req); > return; > } >- >- if (!smbXcli_req_set_pending(req)) { >- tevent_req_nterror(req, NT_STATUS_NO_MEMORY); >- return; >- } > } > > static void smbXcli_conn_received(struct tevent_req *subreq) >-- >1.9.1 > > >From 84ba334215a4ec2319eb4477c2ccfbb0cfd8b77c Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Fri, 29 May 2015 16:14:40 +0200 >Subject: [PATCH 30/31] libcli/smb: make sure we remove the writev_send() > request when a request is destroyed > >This way smbXcli_conn_disconnect() removes all tevent_fd structures attached to >the sock_fd before closing it. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=11316 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit 006042ac126261e87089fb9835c28789e8aeae1b) >(cherry picked from commit f02751f9f82ecc57edd4669252d5f2042564ae7d) >--- > libcli/smb/smbXcli_base.c | 14 ++++++++++++++ > 1 file changed, 14 insertions(+) > >diff --git a/libcli/smb/smbXcli_base.c b/libcli/smb/smbXcli_base.c >index 7bb302d..4ded56a 100644 >--- a/libcli/smb/smbXcli_base.c >+++ b/libcli/smb/smbXcli_base.c >@@ -202,6 +202,8 @@ struct smbXcli_req_state { > > uint8_t *inbuf; > >+ struct tevent_req *write_req; >+ > struct { > /* Space for the header including the wct */ > uint8_t hdr[HDR_VWV]; >@@ -812,6 +814,8 @@ void smbXcli_req_unset_pending(struct tevent_req *req) > size_t num_pending = talloc_array_length(conn->pending); > size_t i; > >+ TALLOC_FREE(state->write_req); >+ > if (state->smb1.mid != 0) { > /* > * This is a [nt]trans[2] request which waits >@@ -870,6 +874,8 @@ static void smbXcli_req_cleanup(struct tevent_req *req, > tevent_req_data(req, > struct smbXcli_req_state); > >+ TALLOC_FREE(state->write_req); >+ > switch (req_state) { > case TEVENT_REQ_RECEIVED: > /* >@@ -1572,6 +1578,8 @@ static NTSTATUS smb1cli_req_writev_submit(struct tevent_req *req, > return NT_STATUS_NO_MEMORY; > } > tevent_req_set_callback(subreq, smb1cli_req_writev_done, req); >+ state->write_req = subreq; >+ > return NT_STATUS_OK; > } > >@@ -1628,6 +1636,8 @@ static void smb1cli_req_writev_done(struct tevent_req *subreq) > ssize_t nwritten; > int err; > >+ state->write_req = NULL; >+ > nwritten = writev_recv(subreq, &err); > TALLOC_FREE(subreq); > if (nwritten == -1) { >@@ -3086,6 +3096,8 @@ skip_credits: > return NT_STATUS_NO_MEMORY; > } > tevent_req_set_callback(subreq, smb2cli_req_writev_done, reqs[0]); >+ state->write_req = subreq; >+ > return NT_STATUS_OK; > } > >@@ -3147,6 +3159,8 @@ static void smb2cli_req_writev_done(struct tevent_req *subreq) > ssize_t nwritten; > int err; > >+ state->write_req = NULL; >+ > nwritten = writev_recv(subreq, &err); > TALLOC_FREE(subreq); > if (nwritten == -1) { >-- >1.9.1 > > >From 2e5b5299195620f2e993a7601e387647fd58db38 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Fri, 14 Aug 2015 12:54:00 +0200 >Subject: [PATCH 31/31] s3:lib: fix some corner cases of > open_socket_out_cleanup() > >In case of timeouts we retry the async_connect_send() and forgot >to remember it, this results in an abort() in async_connect_cleanup() >as the fd is already closed when calling fcntl(F_SETFL). > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=11316 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit ce3c77fb45ccf4d45a0fa655325e30e748d89245) >--- > source3/lib/util_sock.c | 3 +++ > 1 file changed, 3 insertions(+) > >diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c >index 22ba764..fdf1c73 100644 >--- a/source3/lib/util_sock.c >+++ b/source3/lib/util_sock.c >@@ -648,6 +648,7 @@ static void open_socket_out_connected(struct tevent_req *subreq) > tevent_req_nterror(req, NT_STATUS_NO_MEMORY); > return; > } >+ state->connect_subreq = subreq; > tevent_req_set_callback(subreq, open_socket_out_connected, req); > return; > } >@@ -670,10 +671,12 @@ NTSTATUS open_socket_out_recv(struct tevent_req *req, int *pfd) > NTSTATUS status; > > if (tevent_req_is_nterror(req, &status)) { >+ tevent_req_received(req); > return status; > } > *pfd = state->fd; > state->fd = -1; >+ tevent_req_received(req); > return NT_STATUS_OK; > } > >-- >1.9.1 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 11316
:
11155
|
11157
|
11161
|
11164
|
11344
|
11345
| 11347 |
11348
|
11480
|
11482
|
11483