struct cli_session_request_state {
struct tevent_context *ev;
int sock;
- uint32 len_hdr;
+ uint32_t len_hdr;
struct iovec iov[3];
uint8_t nb_session_response;
};
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);
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)) {
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)
return;
}
tevent_req_set_callback(subreq, nb_connect_done, req);
+ state->session_subreq = subreq;
}
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) {
tevent_req_done(req);
return;
-
}
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;
}
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);
const char *calling_name,
int calling_type)
{
- struct tevent_req *req, *subreq;
+ struct tevent_req *req;
struct smbsock_connect_state *state;
req = tevent_req_create(mem_ctx, &state, struct smbsock_connect_state);
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) {
- subreq = tevent_wakeup_send(state, ev, timeval_set(0, 0));
- if (tevent_req_nomem(subreq, req)) {
+ state->req_139 = nb_connect_send(state, state->ev, state->addr,
+ state->called_name,
+ state->called_type,
+ state->calling_name,
+ state->calling_type);
+ if (tevent_req_nomem(state->req_139, req)) {
return tevent_req_post(req, ev);
}
- tevent_req_set_callback(subreq, smbsock_connect_do_139, req);
+ tevent_req_set_callback(
+ state->req_139, smbsock_connect_connected, req);
return req;
}
if (port != 0) {
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)
NTSTATUS status;
if (tevent_req_is_nterror(req, &status)) {
+ tevent_req_received(req);
return status;
}
*sock = state->sock;
if (ret_port != NULL) {
*ret_port = state->port;
}
+ tevent_req_received(req);
return NT_STATUS_OK;
}
struct tevent_req *req;
NTSTATUS status = NT_STATUS_NO_MEMORY;
- ev = tevent_context_init(frame);
+ ev = samba_tevent_context_init(frame);
if (ev == NULL) {
goto fail;
}
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);
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);
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(
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;
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;
}
struct tevent_req *req;
NTSTATUS status = NT_STATUS_NO_MEMORY;
- ev = tevent_context_init(frame);
+ ev = samba_tevent_context_init(frame);
if (ev == NULL) {
goto fail;
}