rpms/loudmouth/devel loudmouth-connect-fail-async.patch, NONE, 1.1 loudmouth-connect-fail-sync.patch, NONE, 1.1 loudmouth.spec, 1.34, 1.35

Owen Taylor (otaylor) fedora-extras-commits at redhat.com
Wed Feb 20 21:58:28 UTC 2008


Author: otaylor

Update of /cvs/extras/rpms/loudmouth/devel
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv7225

Modified Files:
	loudmouth.spec 
Added Files:
	loudmouth-connect-fail-async.patch 
	loudmouth-connect-fail-sync.patch 
Log Message:
* Thu Feb  7 2008 Owen Taylor <otaylor at redhat.com> - 1.3.3-3
- Add patches fixing reentrancy problems on connection failure


loudmouth-connect-fail-async.patch:

--- NEW FILE loudmouth-connect-fail-async.patch ---
>From 104769cfec145e0f36320b4f70fcb3c198091ecc Mon Sep 17 00:00:00 2001
From: Owen W. Taylor <otaylor at fishsoup.net>
Date: Thu, 7 Feb 2008 16:21:37 -0500
Subject: [PATCH] Ref the LmSocket in places where a callback to user code could result
  it being freed (http://developer.imendio.com/issues/browse/LM-117)

---
 loudmouth/lm-socket.c |   64 +++++++++++++++++++++++++++++-------------------
 1 files changed, 39 insertions(+), 25 deletions(-)

diff --git a/loudmouth/lm-socket.c b/loudmouth/lm-socket.c
index 76fae88..20a2450 100644
--- a/loudmouth/lm-socket.c
+++ b/loudmouth/lm-socket.c
@@ -425,7 +425,7 @@ _lm_socket_failed_with_error (LmConnectData *connect_data, int error)
 	       "Connection failed: %s (error %d)\n",
 	       _lm_sock_get_error_str (error), error);
 	
-	socket = connect_data->socket;
+	socket = lm_socket_ref(connect_data->socket);
 
 	connect_data->current_addr = connect_data->current_addr->ai_next;
 	
@@ -453,6 +453,8 @@ _lm_socket_failed_with_error (LmConnectData *connect_data, int error)
 		return socket_do_connect (connect_data);
 	}
 
+	lm_socket_unref(socket);
+
 	return FALSE;
 }
 
@@ -472,9 +474,10 @@ socket_connect_cb (GIOChannel   *source,
 	struct addrinfo *addr;
 	int              err;
 	socklen_t        len;
-	LmSocketT         fd; 
+	LmSocketT        fd;
+	gboolean         result = FALSE;
 
-	socket = connect_data->socket;
+	socket = lm_socket_ref(connect_data->socket);
 	addr = connect_data->current_addr;
 	fd = g_io_channel_unix_get_fd (source);
 
@@ -488,7 +491,7 @@ socket_connect_cb (GIOChannel   *source,
 			_lm_socket_failed_with_error (connect_data, err);
 
 			socket->watch_connect = NULL;
-			return FALSE;
+			goto out;
 		}
 	}
 
@@ -518,7 +521,7 @@ socket_connect_cb (GIOChannel   *source,
 				_lm_socket_failed_with_error (connect_data, err);
 
 				socket->watch_connect = NULL;
-				return FALSE;
+				goto out;
 			}
 		} 
 	} else {		
@@ -528,7 +531,13 @@ socket_connect_cb (GIOChannel   *source,
 		
 		_lm_socket_succeeded (connect_data);
 	}
- 	return TRUE; 
+
+	result = TRUE;
+
+ out:
+	lm_socket_unref(socket);
+	
+ 	return result; 
 }
 
 static gboolean
@@ -835,35 +844,40 @@ _lm_socket_resolver_done (GSource *source,
     			  GIOCondition condition,
 			  gpointer data)
 {
-	LmSocket	*socket = (LmSocket *) data;
+	LmSocket	*socket = lm_socket_ref((LmSocket *) data);
 	struct addrinfo	*ans;
 	unsigned char   *srv_ans;
 	int 		 err;
+	gboolean         result = FALSE;
 
 	/* process pending data */
 	asyncns_wait (socket->asyncns_ctx, FALSE);
 
 	if (!asyncns_isdone (socket->asyncns_ctx, socket->resolv_query)) {
-		return TRUE;
-	}
-
-	switch ((guint) asyncns_getuserdata (socket->asyncns_ctx, socket->resolv_query)) {
-	case PHASE_1:
-		err = asyncns_res_done (socket->asyncns_ctx, socket->resolv_query, &srv_ans);
-		socket->resolv_query = NULL;
-		_lm_socket_create_phase1 (socket, (err <= 0) ? NULL : srv_ans, err);
-		return TRUE;
-		break;
-	case PHASE_2:
-		err = asyncns_getaddrinfo_done (socket->asyncns_ctx, socket->resolv_query, &ans);
-		socket->resolv_query = NULL;
-		_lm_socket_create_phase2 (socket, (err) ? NULL : ans);
-		_asyncns_done (socket);
-		return FALSE;
+		result = TRUE;
+	} else {
+		switch ((guint) asyncns_getuserdata (socket->asyncns_ctx, socket->resolv_query)) {
+		case PHASE_1:
+			err = asyncns_res_done (socket->asyncns_ctx, socket->resolv_query, &srv_ans);
+			socket->resolv_query = NULL;
+			_lm_socket_create_phase1 (socket, (err <= 0) ? NULL : srv_ans, err);
+			result = TRUE;
+			break;
+		case PHASE_2:
+			err = asyncns_getaddrinfo_done (socket->asyncns_ctx, socket->resolv_query, &ans);
+			socket->resolv_query = NULL;
+			_lm_socket_create_phase2 (socket, (err) ? NULL : ans);
+			_asyncns_done (socket);
+			break;
+		default:
+			g_assert_not_reached();
+			break;
+		}
 	}
 
-	g_assert_not_reached ();
-	return FALSE;
+	lm_socket_unref(socket);
+	
+	return result;
 }
 
 #endif
-- 
1.5.3.7


loudmouth-connect-fail-sync.patch:

--- NEW FILE loudmouth-connect-fail-sync.patch ---
>From 3e7050fc78ce77885ae3980e214c770fe10dab1a Mon Sep 17 00:00:00 2001
From: Owen W. Taylor <otaylor at fishsoup.net>
Date: Thu, 7 Feb 2008 16:41:49 -0500
Subject: [PATCH] If lm_socket_create() fails synchronously don't call the user's
    callback, instead return the correct error indication from
    lm_connection_open().

---
 loudmouth/lm-connection.c |   10 +++++-----
 loudmouth/lm-socket.c     |   41 ++++++++++++++++++++++++++++++++---------
 2 files changed, 37 insertions(+), 14 deletions(-)

diff --git a/loudmouth/lm-connection.c b/loudmouth/lm-connection.c
index 7ee646f..451d0ce 100644
--- a/loudmouth/lm-connection.c
+++ b/loudmouth/lm-connection.c
@@ -456,14 +456,9 @@ connection_do_open (LmConnection *connection, GError **error)
 		return FALSE;
 	}
 
-	lm_message_queue_attach (connection->queue, connection->context);
-	
 	lm_verbose ("Connecting to: %s:%d\n", 
 		    connection->server, connection->port);
 
-	connection->state = LM_CONNECTION_STATE_OPENING;
-	connection->async_connect_waiting = FALSE;
-
 	connection->socket = lm_socket_create (connection->context,
 					       (IncomingDataFunc) connection_incoming_data,
 					       (SocketClosedFunc) connection_socket_closed_cb,
@@ -484,6 +479,11 @@ connection_do_open (LmConnection *connection, GError **error)
 		return FALSE;
 	}
 
+	lm_message_queue_attach (connection->queue, connection->context);
+	
+	connection->state = LM_CONNECTION_STATE_OPENING;
+	connection->async_connect_waiting = FALSE;
+
 	return TRUE;
 }
 					
diff --git a/loudmouth/lm-socket.c b/loudmouth/lm-socket.c
index 20a2450..620fe50 100644
--- a/loudmouth/lm-socket.c
+++ b/loudmouth/lm-socket.c
@@ -329,7 +329,7 @@ _lm_socket_ssl_init (LmSocket *socket, gboolean delayed)
 		_lm_sock_shutdown (socket->fd);
 		_lm_sock_close (socket->fd);
 
-		if (!delayed)
+		if (!delayed && socket->connect_func)
 			(socket->connect_func) (socket, FALSE, socket->user_data);
 
 		return FALSE;
@@ -369,7 +369,8 @@ _lm_socket_succeeded (LmConnectData *connect_data)
 	/* Need some way to report error/success */
 	if (socket->cancel_open) {
 		lm_verbose ("Cancelling connection...\n");
-		(socket->connect_func) (socket, FALSE, socket->user_data);
+		if (socket->connect_func)
+			(socket->connect_func) (socket, FALSE, socket->user_data);
 		return;
 	}
 	
@@ -413,7 +414,8 @@ _lm_socket_succeeded (LmConnectData *connect_data)
 				      socket);
 #endif
 
-	(socket->connect_func) (socket, TRUE, socket->user_data);
+	if (socket->connect_func)
+		(socket->connect_func) (socket, TRUE, socket->user_data);
 }
 
 gboolean 
@@ -440,7 +442,8 @@ _lm_socket_failed_with_error (LmConnectData *connect_data, int error)
 	}
 	
 	if (connect_data->current_addr == NULL) {
-		(socket->connect_func) (socket, FALSE, socket->user_data);
+		if (socket->connect_func)		
+			(socket->connect_func) (socket, FALSE, socket->user_data);
 		
 		 /* if the user callback called connection_close(), this is already freed */
 		if (socket->connect_data != NULL) {
@@ -963,7 +966,8 @@ _lm_socket_create_phase2 (LmSocket *socket, struct addrinfo *ans)
 {
 	if (ans == NULL) {
 		lm_verbose ("error while resolving, bailing out\n");
-		(socket->connect_func) (socket, FALSE, socket->user_data);
+		if (socket->connect_func)
+			(socket->connect_func) (socket, FALSE, socket->user_data);
 		g_free (socket->connect_data);
 		socket->connect_data = NULL;
 		return;
@@ -1016,10 +1020,6 @@ lm_socket_create (GMainContext      *context,
 	socket->ssl_started = FALSE;
 	socket->proxy = NULL;
 	socket->blocking = blocking;
-	socket->data_func = data_func;
-	socket->closed_func = closed_func;
-	socket->connect_func = connect_func;
-	socket->user_data = user_data;
 
 	if (context) {
 		socket->context = g_main_context_ref (context);
@@ -1053,6 +1053,29 @@ lm_socket_create (GMainContext      *context,
 		_lm_socket_create_phase1 (socket, NULL, 0);
 	}
 
+	if (socket->connect_data == NULL) {
+		/* Open failed synchronously, probably a DNS lookup problem */
+		lm_socket_unref(socket);
+		
+		g_set_error (error,
+			     LM_ERROR,                 
+			     LM_ERROR_CONNECTION_FAILED,   
+			     "Failed to resolve server");
+		
+		return NULL;
+	}
+		
+
+	/* If the connection fails synchronously, we don't want to call the
+	 * connect_func to indicate an error, we return an error indication
+	 * instead. So, we delay saving the functions until after we know
+	 * we are going to return success.
+	 */
+	socket->data_func = data_func;
+	socket->closed_func = closed_func;
+	socket->connect_func = connect_func;
+	socket->user_data = user_data;
+	
 	return socket;
 }
 
-- 
1.5.3.7



Index: loudmouth.spec
===================================================================
RCS file: /cvs/extras/rpms/loudmouth/devel/loudmouth.spec,v
retrieving revision 1.34
retrieving revision 1.35
diff -u -r1.34 -r1.35
--- loudmouth.spec	30 Jan 2008 22:38:56 -0000	1.34
+++ loudmouth.spec	20 Feb 2008 21:57:41 -0000	1.35
@@ -2,7 +2,7 @@
 
 Name:           loudmouth
 Version:        1.3.3
-Release:        2%{?dist}
+Release:        3%{?dist}
 Summary:        Loudmouth is a Jabber programming library written in C
 
 Group:          System Environment/Libraries
@@ -11,7 +11,10 @@
 Source0:        http://ftp.gnome.org/pub/GNOME/sources/%{name}/%{version}/%{name}-%{version}.tar.bz2
 # http://developer.imendio.com/issues/browse/LM-104
 Patch0:         %{name}-stream-error.patch
-
+# http://developer.imendio.com/issues/browse/LM-117
+Patch1:         %{name}-connect-fail-async.patch
+# http://developer.imendio.com/issues/browse/LM-117
+Patch2:         %{name}-connect-fail-sync.patch
 
 BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 
@@ -52,6 +55,8 @@
 %setup -q
 
 %patch0 -p1 -b .stream-error
+%patch1 -p1 -b .connect-fail-async
+%patch2 -p1 -b .connect-fail-sync
 
 %build
 %configure --enable-gtk-doc	\
@@ -96,6 +101,9 @@
 
 
 %changelog
+* Thu Feb  7 2008 Owen Taylor <otaylor at redhat.com> - 1.3.3-3
+- Add patches fixing reentrancy problems on connection failure
+
 * Wed Jan 30 2008 Owen Taylor <otaylor at redhat.com> - 1.3.3-2
 - Add back stream-error patch, it wasn't fixed in the 1.3 branch
 




More information about the fedora-extras-commits mailing list