[PATCH] lib: Fix rundown of open_socket_out()

Volker Lendecke Volker.Lendecke at SerNet.DE
Tue Jun 30 04:08:59 MDT 2015


Hi!

Maybe another contributor to flaky builds.

Review&push appreciated!

Thanks,

Volker

-- 
SerNet GmbH, Bahnhofsallee 1b, 37081 Göttingen
phone: +49-551-370000-0, fax: +49-551-370000-9
AG Göttingen, HRB 2816, GF: Dr. Johannes Loxen
http://www.sernet.de, mailto:kontakt at sernet.de
-------------- next part --------------
From 3371d14c5eaf36541745c06dfe7896e3790be2e2 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Mon, 29 Jun 2015 19:00:55 +0200
Subject: [PATCH] lib: Fix rundown of open_socket_out()

Under valgrind I've seen the abort in async_connect_cleanup kick in. Yes, it's
good that we check these return codes!

Signed-off-by: Volker Lendecke <vl at samba.org>
---
 source3/lib/util_sock.c |   45 +++++++++++++++++++++++++++++++++------------
 1 file changed, 33 insertions(+), 12 deletions(-)

diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c
index c4de85d..a8a9cca 100644
--- a/source3/lib/util_sock.c
+++ b/source3/lib/util_sock.c
@@ -418,16 +418,34 @@ struct open_socket_out_state {
 	socklen_t salen;
 	uint16_t port;
 	int wait_usec;
+	struct tevent_req *connect_subreq;
 };
 
 static void open_socket_out_connected(struct tevent_req *subreq);
 
-static int open_socket_out_state_destructor(struct open_socket_out_state *s)
+static void open_socket_out_cleanup(struct tevent_req *req,
+				    enum tevent_req_state req_state)
 {
-	if (s->fd != -1) {
-		close(s->fd);
+	struct open_socket_out_state *state =
+		tevent_req_data(req, struct open_socket_out_state);
+
+	/*
+	 * Make sure that the async_connect_send subreq has a chance to reset
+	 * fcntl before the socket goes away.
+	 */
+	TALLOC_FREE(state->connect_subreq);
+
+	if (req_state == TEVENT_REQ_DONE) {
+		/*
+		 * we keep the socket open for the caller to use
+		 */
+		return;
+	}
+
+	if (state->fd != -1) {
+		close(state->fd);
+		state->fd = -1;
 	}
-	return 0;
 }
 
 /****************************************************************************
@@ -441,7 +459,7 @@ struct tevent_req *open_socket_out_send(TALLOC_CTX *mem_ctx,
 					int timeout)
 {
 	char addr[INET6_ADDRSTRLEN];
-	struct tevent_req *result, *subreq;
+	struct tevent_req *result;
 	struct open_socket_out_state *state;
 	NTSTATUS status;
 
@@ -461,7 +479,8 @@ struct tevent_req *open_socket_out_send(TALLOC_CTX *mem_ctx,
 		status = map_nt_error_from_unix(errno);
 		goto post_status;
 	}
-	talloc_set_destructor(state, open_socket_out_state_destructor);
+
+	tevent_req_set_cleanup_fn(result, open_socket_out_cleanup);
 
 	if (!tevent_req_set_endtime(
 		    result, ev, timeval_current_ofs_msec(timeout))) {
@@ -495,16 +514,17 @@ struct tevent_req *open_socket_out_send(TALLOC_CTX *mem_ctx,
 	print_sockaddr(addr, sizeof(addr), &state->ss);
 	DEBUG(3,("Connecting to %s at port %u\n", addr,	(unsigned int)port));
 
-	subreq = async_connect_send(state, state->ev, state->fd,
-				    (struct sockaddr *)&state->ss,
-				    state->salen, NULL, NULL, NULL);
-	if ((subreq == NULL)
+	state->connect_subreq = async_connect_send(
+		state, state->ev, state->fd, (struct sockaddr *)&state->ss,
+		state->salen, NULL, NULL, NULL);
+	if ((state->connect_subreq == NULL)
 	    || !tevent_req_set_endtime(
-		    subreq, state->ev,
+		    state->connect_subreq, state->ev,
 		    timeval_current_ofs(0, state->wait_usec))) {
 		goto fail;
 	}
-	tevent_req_set_callback(subreq, open_socket_out_connected, result);
+	tevent_req_set_callback(state->connect_subreq,
+				open_socket_out_connected, result);
 	return result;
 
  post_status:
@@ -526,6 +546,7 @@ static void open_socket_out_connected(struct tevent_req *subreq)
 
 	ret = async_connect_recv(subreq, &sys_errno);
 	TALLOC_FREE(subreq);
+	state->connect_subreq = NULL;
 	if (ret == 0) {
 		tevent_req_done(req);
 		return;
-- 
1.7.9.5



More information about the samba-technical mailing list