diff --git a/camel/camel-net-utils.c b/camel/camel-net-utils.c
index d447e41..8f212ba 100644
--- a/camel/camel-net-utils.c
+++ b/camel/camel-net-utils.c
@@ -116,6 +116,7 @@ G_LOCK_DEFINE_STATIC (gethost_mutex);
 	if (buflen < req_length) {                                     \
 		*herr = ERANGE;                                        \
 		G_UNLOCK (gethost_mutex);                              \
+		pthread_setcancelstate (old_cancelstate, &old_cancelstate); \
 		return ERANGE;                                         \
 	}                                                              \
 								       \
@@ -205,6 +206,7 @@ static gint
 camel_gethostbyname_r (const gchar *name, struct hostent *host,
 		       gchar *buf, gsize buflen, gint *herr)
 {
+	gint old_cancelstate = PTHREAD_CANCEL_ENABLE;
 #ifdef ENABLE_IPv6
 	struct addrinfo hints, *res;
 	gint retval, len;
@@ -220,10 +222,13 @@ camel_gethostbyname_r (const gchar *name, struct hostent *host,
 	hints.ai_socktype = SOCK_STREAM;
 	hints.ai_protocol = IPPROTO_TCP;
 
+	pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &old_cancelstate);
 	if ((retval = getaddrinfo (name, NULL, &hints, &res)) != 0) {
 		*herr = ai_to_herr (retval);
+		pthread_setcancelstate (old_cancelstate, &old_cancelstate);
 		return -1;
 	}
+	pthread_setcancelstate (old_cancelstate, &old_cancelstate);
 
 	len = ALIGN (strlen (res->ai_canonname) + 1);
 	if (buflen < IPv6_BUFLEN_MIN + len + res->ai_addrlen + sizeof (gchar *))
@@ -266,15 +271,23 @@ camel_gethostbyname_r (const gchar *name, struct hostent *host,
 #else /* No support for IPv6 addresses */
 #ifdef HAVE_GETHOSTBYNAME_R
 #ifdef GETHOSTBYNAME_R_FIVE_ARGS
+	gint retval;
+
+	pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &old_cancelstate);
 	if (gethostbyname_r (name, host, buf, buflen, herr))
-		return 0;
+		retval = 0;
 	else
-		return errno;
+		retval = errno;
+	pthread_setcancelstate (old_cancelstate, &old_cancelstate);
+
+	return retval;
 #else
 	struct hostent *hp;
 	gint retval;
 
+	pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &old_cancelstate);
 	retval = gethostbyname_r (name, host, buf, buflen, &hp, herr);
+	pthread_setcancelstate (old_cancelstate, &old_cancelstate);
 	if (hp != NULL) {
 		*herr = 0;
 	} else if (retval == 0) {
@@ -294,18 +307,21 @@ camel_gethostbyname_r (const gchar *name, struct hostent *host,
 	struct hostent *h;
 
 	G_LOCK (gethost_mutex);
+	pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &old_cancelstate);
 
 	h = gethostbyname (name);
 
 	if (!h) {
 		*herr = h_errno;
 		G_UNLOCK (gethost_mutex);
+		pthread_setcancelstate (old_cancelstate, &old_cancelstate);
 		return -1;
 	}
 
 	GETHOST_PROCESS (h, host, buf, buflen, herr);
 
 	G_UNLOCK (gethost_mutex);
+	pthread_setcancelstate (old_cancelstate, &old_cancelstate);
 
 	return 0;
 #endif /* HAVE_GETHOSTBYNAME_R */
@@ -316,13 +332,17 @@ static gint
 camel_gethostbyaddr_r (const gchar *addr, gint addrlen, gint type, struct hostent *host,
 		       gchar *buf, gsize buflen, gint *herr)
 {
+	gint old_cancelstate = PTHREAD_CANCEL_ENABLE;
 #ifdef ENABLE_IPv6
 	gint retval, len;
 
+	pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &old_cancelstate);
 	if ((retval = getnameinfo (addr, addrlen, buf, buflen, NULL, 0, NI_NAMEREQD)) != 0) {
 		*herr = ai_to_herr (retval);
+		pthread_setcancelstate (old_cancelstate, &old_cancelstate);
 		return -1;
 	}
+	pthread_setcancelstate (old_cancelstate, &old_cancelstate);
 
 	len = ALIGN (strlen (buf) + 1);
 	if (buflen < IPv6_BUFLEN_MIN + len + addrlen + sizeof (gchar *))
@@ -354,15 +374,23 @@ camel_gethostbyaddr_r (const gchar *addr, gint addrlen, gint type, struct hosten
 #else /* No support for IPv6 addresses */
 #ifdef HAVE_GETHOSTBYADDR_R
 #ifdef GETHOSTBYADDR_R_SEVEN_ARGS
+	gint retval;
+
+	pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &old_cancelstate);
 	if (gethostbyaddr_r (addr, addrlen, type, host, buf, buflen, herr))
-		return 0;
+		retval = 0;
 	else
-		return errno;
+		retval = errno;
+	pthread_setcancelstate (old_cancelstate, &old_cancelstate);
+
+	return retval;
 #else
 	struct hostent *hp;
 	gint retval;
 
+	pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &old_cancelstate);
 	retval = gethostbyaddr_r (addr, addrlen, type, host, buf, buflen, &hp, herr);
+	pthread_setcancelstate (old_cancelstate, &old_cancelstate);
 	if (hp != NULL) {
 		*herr = 0;
 		retval = 0;
@@ -383,18 +411,21 @@ camel_gethostbyaddr_r (const gchar *addr, gint addrlen, gint type, struct hosten
 	struct hostent *h;
 
 	G_LOCK (gethost_mutex);
+	pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &old_cancelstate);
 
 	h = gethostbyaddr (addr, addrlen, type);
 
 	if (!h) {
 		*herr = h_errno;
 		G_UNLOCK (gethost_mutex);
+		pthread_setcancelstate (old_cancelstate, &old_cancelstate);
 		return -1;
 	}
 
 	GETHOST_PROCESS (h, host, buf, buflen, herr);
 
 	G_UNLOCK (gethost_mutex);
+	pthread_setcancelstate (old_cancelstate, &old_cancelstate);
 
 	return 0;
 #endif /* HAVE_GETHOSTBYADDR_R */
@@ -512,7 +543,18 @@ cs_waitinfo(gpointer (worker)(gpointer), struct _addrinfo_msg *msg, const gchar
 		} else {
 			struct _addrinfo_msg *reply = (struct _addrinfo_msg *)camel_msgport_try_pop(reply_port);
 
-			g_assert(reply == msg);
+			if (!msg->cancelled) {
+				if (reply != msg) {
+					printf ("%s: would crash, port:%p reply:%p msg:%p cancel:%d\n", __FUNCTION__, reply_port, reply, msg, cancel);
+				}
+				/*g_assert(reply == msg);*/
+			} else {
+				static gboolean first = TRUE;
+				if (first) {
+					printf ("%s: thread was cancelled, reply:%p msg:%p\n", __FUNCTION__, reply, msg);
+					first = FALSE;
+				}
+			}
 			d(printf("waiting for child to exit\n"));
 			pthread_join(id, NULL);
 			d(printf("child done\n"));
@@ -525,6 +567,11 @@ cs_waitinfo(gpointer (worker)(gpointer), struct _addrinfo_msg *msg, const gchar
 	return cancel;
 }
 
+#define test_cancelled(_msg)	G_STMT_START {				\
+	gint old_cancelled = (_msg)->cancelled; (_msg)->cancelled = 1;	\
+	pthread_testcancel ();						\
+	(_msg)->cancelled = old_cancelled; } G_STMT_END
+
 #ifdef NEED_ADDRINFO
 static gpointer
 cs_getaddrinfo(gpointer data)
@@ -535,17 +582,17 @@ cs_getaddrinfo(gpointer data)
 	struct addrinfo *res, *last = NULL;
 	struct sockaddr_in *sin;
 	in_port_t port = 0;
-	gint i;
+	gint i, old_cancelstate = PTHREAD_CANCEL_ENABLE;
 
 	/* This is a pretty simplistic emulation of getaddrinfo */
 
 	while ((msg->result = camel_gethostbyname_r(msg->name, &h, msg->hostbufmem, msg->hostbuflen, &herr)) == ERANGE) {
-		pthread_testcancel();
+		test_cancelled (msg);
                 msg->hostbuflen *= 2;
                 msg->hostbufmem = g_realloc(msg->hostbufmem, msg->hostbuflen);
 	}
 
-	pthread_testcancel ();
+	test_cancelled (msg);
 
 	/* If we got cancelled, dont reply, just free it */
 	if (msg->cancelled)
@@ -588,7 +635,9 @@ cs_getaddrinfo(gpointer data)
 					socktype = "udp";
 			}
 
+			pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &old_cancelstate);
 			serv = getservbyname(msg->service, socktype);
+			pthread_setcancelstate (old_cancelstate, &old_cancelstate);
 			if (serv == NULL) {
 				msg->result = EAI_NONAME;
 				goto reply;
@@ -599,7 +648,7 @@ cs_getaddrinfo(gpointer data)
 		}
 	}
 
-	pthread_testcancel ();
+	test_cancelled (msg);
 
 	for (i=0;h.h_addr_list[i];i++) {
 		res = g_malloc0(sizeof(*res));
@@ -630,7 +679,9 @@ cs_getaddrinfo(gpointer data)
 		}
 	}
 reply:
+	pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &old_cancelstate);
 	camel_msgport_reply((CamelMsg *)msg);
+	pthread_setcancelstate (old_cancelstate, &old_cancelstate);
 cancel:
 	return NULL;
 }
@@ -639,8 +690,11 @@ static gpointer
 cs_getaddrinfo(gpointer data)
 {
 	struct _addrinfo_msg *info = data;
+	gint old_cancelstate = PTHREAD_CANCEL_ENABLE;
 
+	pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &old_cancelstate);
 	info->result = getaddrinfo(info->name, info->service, info->hints, info->res);
+	pthread_setcancelstate (old_cancelstate, &old_cancelstate);
 
 	/* On Solaris, the service name 'http' or 'https' is not defined.
 	   Use the port as the service name directly. */
@@ -651,10 +705,13 @@ cs_getaddrinfo(gpointer data)
 			info->result = getaddrinfo(info->name, "443", info->hints, info->res);
 	}
 
-	pthread_testcancel ();
+	test_cancelled (info);
 
-	if (!info->cancelled)
+	if (!info->cancelled) {
+		pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &old_cancelstate);
 		camel_msgport_reply((CamelMsg *)info);
+		pthread_setcancelstate (old_cancelstate, &old_cancelstate);
+	}
 
 	return NULL;
 }
@@ -747,7 +804,7 @@ cs_getnameinfo(gpointer data)
 
 	while ((msg->result = camel_gethostbyaddr_r((const gchar *)&sin->sin_addr, sizeof(sin->sin_addr), AF_INET, &h,
 						    msg->hostbufmem, msg->hostbuflen, &herr)) == ERANGE) {
-		pthread_testcancel ();
+		test_cancelled (msg);
                 msg->hostbuflen *= 2;
                 msg->hostbufmem = g_realloc(msg->hostbufmem, msg->hostbuflen);
 	}
@@ -755,7 +812,7 @@ cs_getnameinfo(gpointer data)
 	if (msg->cancelled)
 		goto cancel;
 
-	pthread_testcancel ();
+	test_cancelled (msg);
 
 	if (msg->host) {
 		g_free(msg->host);
@@ -782,14 +839,20 @@ static gpointer
 cs_getnameinfo(gpointer data)
 {
 	struct _addrinfo_msg *msg = data;
+	gint old_cancelstate = PTHREAD_CANCEL_ENABLE;
 
+	pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &old_cancelstate);
 	/* there doens't appear to be a return code which says host or serv buffers are too short, lengthen them */
 	msg->result = getnameinfo(msg->addr, msg->addrlen, msg->host, msg->hostlen, msg->serv, msg->servlen, msg->flags);
+	pthread_setcancelstate (old_cancelstate, &old_cancelstate);
 
-	pthread_testcancel ();
+	test_cancelled (msg);
 
-	if (!msg->cancelled)
+	if (!msg->cancelled) {
+		pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &old_cancelstate);
 		camel_msgport_reply((CamelMsg *)msg);
+		pthread_setcancelstate (old_cancelstate, &old_cancelstate);
+	}
 
 	return NULL;
 }
