diff options
author | Stefan Metzmacher <metze@samba.org> | 2015-05-21 03:01:30 +0200 |
---|---|---|
committer | Stefan Metzmacher <metze@samba.org> | 2015-06-12 17:08:17 +0200 |
commit | 058d84747e75a5f97a02e31bac9c8d0d147174bc (patch) | |
tree | 63218e7ee467a9e5853bfcd907fa2a1b7d9e733e | |
parent | 04f89d4255ed95631aa8f0ada4bcf5f888e126d4 (diff) | |
download | samba-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.c | 33 |
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; } |