summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2015-05-21 03:01:30 +0200
committerStefan Metzmacher <metze@samba.org>2015-06-12 17:08:17 +0200
commit058d84747e75a5f97a02e31bac9c8d0d147174bc (patch)
tree63218e7ee467a9e5853bfcd907fa2a1b7d9e733e
parent04f89d4255ed95631aa8f0ada4bcf5f888e126d4 (diff)
downloadsamba-058d84747e75a5f97a02e31bac9c8d0d147174bc.tar.gz
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>
-rw-r--r--source3/libsmb/smbsock_connect.c33
1 files changed, 31 insertions, 2 deletions
diff --git a/source3/libsmb/smbsock_connect.c b/source3/libsmb/smbsock_connect.c
index 365e9f1d83a..9f915e1bb42 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;
}