Skip to content
This repository has been archived by the owner on Feb 10, 2024. It is now read-only.

Abort connect when IP fails to bind #2793

Open
konsolebox opened this issue Jul 25, 2023 · 3 comments
Open

Abort connect when IP fails to bind #2793

konsolebox opened this issue Jul 25, 2023 · 3 comments

Comments

@konsolebox
Copy link
Contributor

Hexchat probably needs to abort when it fails to bind to configured bind hostname otherwise it will use a network that it isn't supposed to use.

I just created a patch for it but I'm not getting the expected error message. I'm getting "Unknown host. Maybe you misspelled it?" instead. This happens both when the IP address to bind to is available or not, and I'm not sure where I made a mistake.

diff --git a/src/common/network.c b/src/common/network.c
index fcdaf547..a4a4a7de 100644
--- a/src/common/network.c
+++ b/src/common/network.c
@@ -164,13 +164,15 @@ net_connect (netstore * ns, int sok4, int sok6, int *sok_return)
 	return error;
 }
 
-void
+int
 net_bind (netstore * tobindto, int sok4, int sok6)
 {
-	bind (sok4, tobindto->ip6_hostent->ai_addr,
-			tobindto->ip6_hostent->ai_addrlen);
-	bind (sok6, tobindto->ip6_hostent->ai_addr,
-			tobindto->ip6_hostent->ai_addrlen);
+	if (bind (sok4, tobindto->ip6_hostent->ai_addr,
+			tobindto->ip6_hostent->ai_addrlen) == 0)
+		if (bind (sok6, tobindto->ip6_hostent->ai_addr,
+				tobindto->ip6_hostent->ai_addrlen) == 0)
+			return 0;
+	return -1;
 }
 
 void
diff --git a/src/common/network.h b/src/common/network.h
index 8c1c0c79..5c47b261 100644
--- a/src/common/network.h
+++ b/src/common/network.h
@@ -35,7 +35,7 @@ netstore *net_store_new (void);
 void net_store_destroy (netstore *ns);
 int net_connect (netstore *ns, int sok4, int sok6, int *sok_return);
 char *net_resolve (netstore *ns, char *hostname, int port, char **real_host);
-void net_bind (netstore *tobindto, int sok4, int sok6);
+int net_bind (netstore *tobindto, int sok4, int sok6);
 char *net_ip (guint32 addr);
 void net_sockets (int *sok4, int *sok6);
 
diff --git a/src/common/server.c b/src/common/server.c
index e14da237..8d23ea97 100644
--- a/src/common/server.c
+++ b/src/common/server.c
@@ -909,6 +909,11 @@ server_read_child (GIOChannel *source, GIOCondition condition, server *serv)
 		waitline2 (source, tbuf, sizeof tbuf);
 		EMIT_SIGNAL (XP_TE_SERVERLOOKUP, sess, tbuf, NULL, NULL, NULL, 0);
 		break;
+	case '10':						  /* netbind failed */
+		waitline2 (source, tbuf, sizeof tbuf);
+		sprintf (outbuf, _("Failed to bind %s to socket\n"), tbuf);
+		PrintText (sess, outbuf);
+		break;
 	}
 
 	return TRUE;
@@ -1383,13 +1388,20 @@ server_child (server * serv)
 		{
 			g_snprintf (buf, sizeof (buf), "5\n%s\n", local_ip);
 			write (serv->childwrite, buf, strlen (buf));
-			net_bind (ns_local, serv->sok4, serv->sok6);
-			bound = 1;
+			if (net_bind (ns_local, serv->sok4, serv->sok6) == 0)
+				bound = 1;
+			else
+			{
+				g_snprintf (buf, sizeof (buf), "10\n%s\n", local_ip);
+				write (serv->childwrite, buf, strlen (buf));
+			}
 		} else
 		{
 			write (serv->childwrite, "7\n", 2);
 		}
 		net_store_destroy (ns_local);
+		if (! bound)
+			goto xit;
 	}
 
 	if (!serv->dont_use_proxy) /* blocked in serverlist? */
@konsolebox
Copy link
Contributor Author

It seems like net_resolve fails if hostname is already a raw IP address. Any suggestion on how to go around about this? I can only think of modifying net_resolve so it returns "hostname" if it's already an IP address, or creating a function that tests if a "hostname" is already an IP address and call it before calling net_resolve in all parts of hexchat's code that may need it.

In this new patch I changed XP_TE_UKNHOST's message so the "hostname" is also included.

diff --git a/src/common/network.c b/src/common/network.c
index fcdaf547..a4a4a7de 100644
--- a/src/common/network.c
+++ b/src/common/network.c
@@ -164,13 +164,15 @@ net_connect (netstore * ns, int sok4, int sok6, int *sok_return)
 	return error;
 }
 
-void
+int
 net_bind (netstore * tobindto, int sok4, int sok6)
 {
-	bind (sok4, tobindto->ip6_hostent->ai_addr,
-			tobindto->ip6_hostent->ai_addrlen);
-	bind (sok6, tobindto->ip6_hostent->ai_addr,
-			tobindto->ip6_hostent->ai_addrlen);
+	if (bind (sok4, tobindto->ip6_hostent->ai_addr,
+			tobindto->ip6_hostent->ai_addrlen) == 0)
+		if (bind (sok6, tobindto->ip6_hostent->ai_addr,
+				tobindto->ip6_hostent->ai_addrlen) == 0)
+			return 0;
+	return -1;
 }
 
 void
diff --git a/src/common/network.h b/src/common/network.h
index 8c1c0c79..5c47b261 100644
--- a/src/common/network.h
+++ b/src/common/network.h
@@ -35,7 +35,7 @@ netstore *net_store_new (void);
 void net_store_destroy (netstore *ns);
 int net_connect (netstore *ns, int sok4, int sok6, int *sok_return);
 char *net_resolve (netstore *ns, char *hostname, int port, char **real_host);
-void net_bind (netstore *tobindto, int sok4, int sok6);
+int net_bind (netstore *tobindto, int sok4, int sok6);
 char *net_ip (guint32 addr);
 void net_sockets (int *sok4, int *sok6);
 
diff --git a/src/common/server.c b/src/common/server.c
index e14da237..dc8b996a 100644
--- a/src/common/server.c
+++ b/src/common/server.c
@@ -815,6 +815,7 @@ server_read_child (GIOChannel *source, GIOCondition condition, server *serv)
 		PrintText (serv->server_session, tbuf);
 		break;
 	case '1':						  /* unknown host */
+		waitline2 (source, tbuf, sizeof tbuf);
 		server_stopconnecting (serv);
 		closesocket (serv->sok4);
 		if (serv->proxy_sok4 != -1)
@@ -823,7 +824,7 @@ server_read_child (GIOChannel *source, GIOCondition condition, server *serv)
 			closesocket (serv->sok6);
 		if (serv->proxy_sok6 != -1)
 			closesocket (serv->proxy_sok6);
-		EMIT_SIGNAL (XP_TE_UKNHOST, sess, NULL, NULL, NULL, NULL, 0);
+		EMIT_SIGNAL (XP_TE_UKNHOST, sess, tbuf, NULL, NULL, NULL, 0);
 		if (!servlist_cycle (serv))
 			if (prefs.hex_net_auto_reconnectonfail)
 				auto_reconnect (serv, FALSE, -1);
@@ -909,6 +910,11 @@ server_read_child (GIOChannel *source, GIOCondition condition, server *serv)
 		waitline2 (source, tbuf, sizeof tbuf);
 		EMIT_SIGNAL (XP_TE_SERVERLOOKUP, sess, tbuf, NULL, NULL, NULL, 0);
 		break;
+	case '10':						  /* netbind failed */
+		waitline2 (source, tbuf, sizeof tbuf);
+		sprintf (outbuf, _("Failed to bind %s to socket\n"), tbuf);
+		PrintText (sess, outbuf);
+		break;
 	}
 
 	return TRUE;
@@ -1367,7 +1373,7 @@ server_child (server * serv)
 	char *local_ip;
 	int connect_port;
 	char buf[512];
-	char bound = 0;
+	int bound = 0;
 	int proxy_type = 0;
 	char *proxy_host = NULL;
 	int proxy_port;
@@ -1383,13 +1389,20 @@ server_child (server * serv)
 		{
 			g_snprintf (buf, sizeof (buf), "5\n%s\n", local_ip);
 			write (serv->childwrite, buf, strlen (buf));
-			net_bind (ns_local, serv->sok4, serv->sok6);
-			bound = 1;
+			if (net_bind (ns_local, serv->sok4, serv->sok6) == 0)
+				bound = 1;
+			else
+			{
+				g_snprintf (buf, sizeof (buf), "10\n%s\n", local_ip);
+				write (serv->childwrite, buf, strlen (buf));
+			}
 		} else
 		{
 			write (serv->childwrite, "7\n", 2);
 		}
 		net_store_destroy (ns_local);
+		if (! bound)
+			goto xit;
 	}
 
 	if (!serv->dont_use_proxy) /* blocked in serverlist? */
@@ -1454,7 +1467,8 @@ server_child (server * serv)
 		g_free (proxy_host);
 		if (!ip)
 		{
-			write (serv->childwrite, "1\n", 2);
+			g_snprintf (buf, sizeof (buf), "1\n%s\n", proxy_host);
+			write (serv->childwrite, buf, strlen (buf));
 			goto xit;
 		}
 		connect_port = proxy_port;
@@ -1466,7 +1480,8 @@ server_child (server * serv)
 			proxy_ip = net_resolve (ns_proxy, hostname, port, &real_hostname);
 			if (!proxy_ip)
 			{
-				write (serv->childwrite, "1\n", 2);
+				g_snprintf (buf, sizeof (buf), "1\n%s\n", hostname);
+				write (serv->childwrite, buf, strlen (buf));
 				goto xit;
 			}
 		} else						  /* otherwise we can just use the hostname */
@@ -1476,7 +1491,8 @@ server_child (server * serv)
 		ip = net_resolve (ns_server, hostname, port, &real_hostname);
 		if (!ip)
 		{
-			write (serv->childwrite, "1\n", 2);
+			g_snprintf (buf, sizeof (buf), "1\n%s\n", hostname);
+			write (serv->childwrite, buf, strlen (buf));
 			goto xit;
 		}
 		connect_port = port;
diff --git a/src/common/textevents.in b/src/common/textevents.in
index 19b0d497..75fcb98f 100644
--- a/src/common/textevents.in
+++ b/src/common/textevents.in
@@ -811,8 +811,8 @@ pevt_topicdate_help
 Unknown Host
 XP_TE_UKNHOST
 pevt_generic_none_help
-%C20*%O$tUnknown host. Maybe you misspelled it?
-0
+%C20*%O$tUnknown host '%C22$1%C'. Maybe you misspelled it?
+1
 
 User Limit
 XP_TE_USERLIMIT

@konsolebox
Copy link
Contributor Author

konsolebox commented Jul 26, 2023

Apparently my code was just broken and '10' was just being interpreted as '1'. Elementary mistake.

Now I made it convert code to int. And bind is actually failing in this case.

diff --git a/src/common/network.c b/src/common/network.c
index fcdaf547..a4a4a7de 100644
--- a/src/common/network.c
+++ b/src/common/network.c
@@ -164,13 +164,15 @@ net_connect (netstore * ns, int sok4, int sok6, int *sok_return)
 	return error;
 }
 
-void
+int
 net_bind (netstore * tobindto, int sok4, int sok6)
 {
-	bind (sok4, tobindto->ip6_hostent->ai_addr,
-			tobindto->ip6_hostent->ai_addrlen);
-	bind (sok6, tobindto->ip6_hostent->ai_addr,
-			tobindto->ip6_hostent->ai_addrlen);
+	if (bind (sok4, tobindto->ip6_hostent->ai_addr,
+			tobindto->ip6_hostent->ai_addrlen) == 0)
+		if (bind (sok6, tobindto->ip6_hostent->ai_addr,
+				tobindto->ip6_hostent->ai_addrlen) == 0)
+			return 0;
+	return -1;
 }
 
 void
diff --git a/src/common/network.h b/src/common/network.h
index 8c1c0c79..5c47b261 100644
--- a/src/common/network.h
+++ b/src/common/network.h
@@ -35,7 +35,7 @@ netstore *net_store_new (void);
 void net_store_destroy (netstore *ns);
 int net_connect (netstore *ns, int sok4, int sok6, int *sok_return);
 char *net_resolve (netstore *ns, char *hostname, int port, char **real_host);
-void net_bind (netstore *tobindto, int sok4, int sok6);
+int net_bind (netstore *tobindto, int sok4, int sok6);
 char *net_ip (guint32 addr);
 void net_sockets (int *sok4, int *sok6);
 
diff --git a/src/common/server.c b/src/common/server.c
index e14da237..ce9d30e5 100644
--- a/src/common/server.c
+++ b/src/common/server.c
@@ -805,16 +805,23 @@ server_read_child (GIOChannel *source, GIOCondition condition, server *serv)
 	char outbuf[512];
 	char host[100];
 	char ip[100];
+	int code;
 
 	waitline2 (source, tbuf, sizeof tbuf);
 
-	switch (tbuf[0])
+	if (tbuf[0] == '0')
+		code = 0;
+	else if ((code = atoi (tbuf)) == 0)
+		code = -1;
+
+	switch (code)
 	{
-	case '0':	/* print some text */
+	case 0:	/* print some text */
 		waitline2 (source, tbuf, sizeof tbuf);
 		PrintText (serv->server_session, tbuf);
 		break;
-	case '1':						  /* unknown host */
+	case 1:						  /* unknown host */
+		waitline2 (source, tbuf, sizeof tbuf);
 		server_stopconnecting (serv);
 		closesocket (serv->sok4);
 		if (serv->proxy_sok4 != -1)
@@ -823,12 +830,12 @@ server_read_child (GIOChannel *source, GIOCondition condition, server *serv)
 			closesocket (serv->sok6);
 		if (serv->proxy_sok6 != -1)
 			closesocket (serv->proxy_sok6);
-		EMIT_SIGNAL (XP_TE_UKNHOST, sess, NULL, NULL, NULL, NULL, 0);
+		EMIT_SIGNAL (XP_TE_UKNHOST, sess, tbuf, NULL, NULL, NULL, 0);
 		if (!servlist_cycle (serv))
 			if (prefs.hex_net_auto_reconnectonfail)
 				auto_reconnect (serv, FALSE, -1);
 		break;
-	case '2':						  /* connection failed */
+	case 2:						  /* connection failed */
 		waitline2 (source, tbuf, sizeof tbuf);
 		server_stopconnecting (serv);
 		closesocket (serv->sok4);
@@ -844,13 +851,13 @@ server_read_child (GIOChannel *source, GIOCondition condition, server *serv)
 			if (prefs.hex_net_auto_reconnectonfail)
 				auto_reconnect (serv, FALSE, -1);
 		break;
-	case '3':						  /* gethostbyname finished */
+	case 3:						  /* gethostbyname finished */
 		waitline2 (source, host, sizeof host);
 		waitline2 (source, ip, sizeof ip);
 		waitline2 (source, outbuf, sizeof outbuf);
 		EMIT_SIGNAL (XP_TE_CONNECT, sess, host, ip, outbuf, NULL, 0);
 		break;
-	case '4':						  /* success */
+	case 4:						  /* success */
 		waitline2 (source, tbuf, sizeof (tbuf));
 		serv->sok = atoi (tbuf);
 		/* close the one we didn't end up using */
@@ -891,24 +898,29 @@ server_read_child (GIOChannel *source, GIOCondition condition, server *serv)
 
 		server_connect_success (serv);
 		break;
-	case '5':						  /* prefs ip discovered */
+	case 5:						  /* prefs ip discovered */
 		waitline2 (source, tbuf, sizeof tbuf);
 		prefs.local_ip = inet_addr (tbuf);
 		break;
-	case '7':						  /* gethostbyname (prefs.hex_net_bind_host) failed */
+	case 7:						  /* gethostbyname (prefs.hex_net_bind_host) failed */
 		sprintf (outbuf,
 					_("Cannot resolve hostname %s\nCheck your IP Settings!\n"),
 					prefs.hex_net_bind_host);
 		PrintText (sess, outbuf);
 		break;
-	case '8':
+	case 8:
 		PrintText (sess, _("Proxy traversal failed.\n"));
 		server_disconnect (sess, FALSE, -1);
 		break;
-	case '9':
+	case 9:
 		waitline2 (source, tbuf, sizeof tbuf);
 		EMIT_SIGNAL (XP_TE_SERVERLOOKUP, sess, tbuf, NULL, NULL, NULL, 0);
 		break;
+	case 10:						  /* netbind failed */
+		waitline2 (source, tbuf, sizeof tbuf);
+		sprintf (outbuf, _("Failed to bind %s to socket\n"), tbuf);
+		PrintText (sess, outbuf);
+		break;
 	}
 
 	return TRUE;
@@ -1367,7 +1379,7 @@ server_child (server * serv)
 	char *local_ip;
 	int connect_port;
 	char buf[512];
-	char bound = 0;
+	int bound = 0;
 	int proxy_type = 0;
 	char *proxy_host = NULL;
 	int proxy_port;
@@ -1383,13 +1395,20 @@ server_child (server * serv)
 		{
 			g_snprintf (buf, sizeof (buf), "5\n%s\n", local_ip);
 			write (serv->childwrite, buf, strlen (buf));
-			net_bind (ns_local, serv->sok4, serv->sok6);
-			bound = 1;
+			if (net_bind (ns_local, serv->sok4, serv->sok6) == 0)
+				bound = 1;
+			else
+			{
+				g_snprintf (buf, sizeof (buf), "10\n%s\n", local_ip);
+				write (serv->childwrite, buf, strlen (buf));
+			}
 		} else
 		{
 			write (serv->childwrite, "7\n", 2);
 		}
 		net_store_destroy (ns_local);
+		if (! bound)
+			goto xit;
 	}
 
 	if (!serv->dont_use_proxy) /* blocked in serverlist? */
@@ -1454,7 +1473,8 @@ server_child (server * serv)
 		g_free (proxy_host);
 		if (!ip)
 		{
-			write (serv->childwrite, "1\n", 2);
+			g_snprintf (buf, sizeof (buf), "1\n%s\n", proxy_host);
+			write (serv->childwrite, buf, strlen (buf));
 			goto xit;
 		}
 		connect_port = proxy_port;
@@ -1466,7 +1486,8 @@ server_child (server * serv)
 			proxy_ip = net_resolve (ns_proxy, hostname, port, &real_hostname);
 			if (!proxy_ip)
 			{
-				write (serv->childwrite, "1\n", 2);
+				g_snprintf (buf, sizeof (buf), "1\n%s\n", hostname);
+				write (serv->childwrite, buf, strlen (buf));
 				goto xit;
 			}
 		} else						  /* otherwise we can just use the hostname */
@@ -1476,7 +1497,8 @@ server_child (server * serv)
 		ip = net_resolve (ns_server, hostname, port, &real_hostname);
 		if (!ip)
 		{
-			write (serv->childwrite, "1\n", 2);
+			g_snprintf (buf, sizeof (buf), "1\n%s\n", hostname);
+			write (serv->childwrite, buf, strlen (buf));
 			goto xit;
 		}
 		connect_port = port;
@@ -1692,7 +1714,7 @@ server_set_encoding (server *serv, char *new_encoding)
 	if (new_encoding)
 	{
 		serv->encoding = g_strdup (new_encoding);
-		/* the serverlist GUI might have added a space 
+		/* the serverlist GUI might have added a space
 			and short description - remove it. */
 		space = strchr (serv->encoding, ' ');
 		if (space)
diff --git a/src/common/textevents.in b/src/common/textevents.in
index 19b0d497..75fcb98f 100644
--- a/src/common/textevents.in
+++ b/src/common/textevents.in
@@ -811,8 +811,8 @@ pevt_topicdate_help
 Unknown Host
 XP_TE_UKNHOST
 pevt_generic_none_help
-%C20*%O$tUnknown host. Maybe you misspelled it?
-0
+%C20*%O$tUnknown host '%C22$1%C'. Maybe you misspelled it?
+1
 
 User Limit
 XP_TE_USERLIMIT

@konsolebox
Copy link
Contributor Author

This last patch adds cause of error to the error message. I received "Address family not supported by protocol" for specifying an IPv6 and "Invalid argument" for specifying an IPv4.

diff --git a/src/common/network.c b/src/common/network.c
index fcdaf547..a4a4a7de 100644
--- a/src/common/network.c
+++ b/src/common/network.c
@@ -164,13 +164,15 @@ net_connect (netstore * ns, int sok4, int sok6, int *sok_return)
 	return error;
 }
 
-void
+int
 net_bind (netstore * tobindto, int sok4, int sok6)
 {
-	bind (sok4, tobindto->ip6_hostent->ai_addr,
-			tobindto->ip6_hostent->ai_addrlen);
-	bind (sok6, tobindto->ip6_hostent->ai_addr,
-			tobindto->ip6_hostent->ai_addrlen);
+	if (bind (sok4, tobindto->ip6_hostent->ai_addr,
+			tobindto->ip6_hostent->ai_addrlen) == 0)
+		if (bind (sok6, tobindto->ip6_hostent->ai_addr,
+				tobindto->ip6_hostent->ai_addrlen) == 0)
+			return 0;
+	return -1;
 }
 
 void
diff --git a/src/common/network.h b/src/common/network.h
index 8c1c0c79..5c47b261 100644
--- a/src/common/network.h
+++ b/src/common/network.h
@@ -35,7 +35,7 @@ netstore *net_store_new (void);
 void net_store_destroy (netstore *ns);
 int net_connect (netstore *ns, int sok4, int sok6, int *sok_return);
 char *net_resolve (netstore *ns, char *hostname, int port, char **real_host);
-void net_bind (netstore *tobindto, int sok4, int sok6);
+int net_bind (netstore *tobindto, int sok4, int sok6);
 char *net_ip (guint32 addr);
 void net_sockets (int *sok4, int *sok6);
 
diff --git a/src/common/server.c b/src/common/server.c
index e14da237..a6c8342b 100644
--- a/src/common/server.c
+++ b/src/common/server.c
@@ -802,19 +802,27 @@ server_read_child (GIOChannel *source, GIOCondition condition, server *serv)
 {
 	session *sess = serv->server_session;
 	char tbuf[128];
+	char tbuf2[128];
 	char outbuf[512];
 	char host[100];
 	char ip[100];
+	int code;
 
 	waitline2 (source, tbuf, sizeof tbuf);
 
-	switch (tbuf[0])
+	if (tbuf[0] == '0')
+		code = 0;
+	else if ((code = atoi (tbuf)) == 0)
+		code = -1;
+
+	switch (code)
 	{
-	case '0':	/* print some text */
+	case 0:	/* print some text */
 		waitline2 (source, tbuf, sizeof tbuf);
 		PrintText (serv->server_session, tbuf);
 		break;
-	case '1':						  /* unknown host */
+	case 1:						  /* unknown host */
+		waitline2 (source, tbuf, sizeof tbuf);
 		server_stopconnecting (serv);
 		closesocket (serv->sok4);
 		if (serv->proxy_sok4 != -1)
@@ -823,12 +831,12 @@ server_read_child (GIOChannel *source, GIOCondition condition, server *serv)
 			closesocket (serv->sok6);
 		if (serv->proxy_sok6 != -1)
 			closesocket (serv->proxy_sok6);
-		EMIT_SIGNAL (XP_TE_UKNHOST, sess, NULL, NULL, NULL, NULL, 0);
+		EMIT_SIGNAL (XP_TE_UKNHOST, sess, tbuf, NULL, NULL, NULL, 0);
 		if (!servlist_cycle (serv))
 			if (prefs.hex_net_auto_reconnectonfail)
 				auto_reconnect (serv, FALSE, -1);
 		break;
-	case '2':						  /* connection failed */
+	case 2:						  /* connection failed */
 		waitline2 (source, tbuf, sizeof tbuf);
 		server_stopconnecting (serv);
 		closesocket (serv->sok4);
@@ -844,13 +852,13 @@ server_read_child (GIOChannel *source, GIOCondition condition, server *serv)
 			if (prefs.hex_net_auto_reconnectonfail)
 				auto_reconnect (serv, FALSE, -1);
 		break;
-	case '3':						  /* gethostbyname finished */
+	case 3:						  /* gethostbyname finished */
 		waitline2 (source, host, sizeof host);
 		waitline2 (source, ip, sizeof ip);
 		waitline2 (source, outbuf, sizeof outbuf);
 		EMIT_SIGNAL (XP_TE_CONNECT, sess, host, ip, outbuf, NULL, 0);
 		break;
-	case '4':						  /* success */
+	case 4:						  /* success */
 		waitline2 (source, tbuf, sizeof (tbuf));
 		serv->sok = atoi (tbuf);
 		/* close the one we didn't end up using */
@@ -891,24 +899,30 @@ server_read_child (GIOChannel *source, GIOCondition condition, server *serv)
 
 		server_connect_success (serv);
 		break;
-	case '5':						  /* prefs ip discovered */
+	case 5:						  /* prefs ip discovered */
 		waitline2 (source, tbuf, sizeof tbuf);
 		prefs.local_ip = inet_addr (tbuf);
 		break;
-	case '7':						  /* gethostbyname (prefs.hex_net_bind_host) failed */
+	case 7:						  /* gethostbyname (prefs.hex_net_bind_host) failed */
 		sprintf (outbuf,
 					_("Cannot resolve hostname %s\nCheck your IP Settings!\n"),
 					prefs.hex_net_bind_host);
 		PrintText (sess, outbuf);
 		break;
-	case '8':
+	case 8:
 		PrintText (sess, _("Proxy traversal failed.\n"));
 		server_disconnect (sess, FALSE, -1);
 		break;
-	case '9':
+	case 9:
 		waitline2 (source, tbuf, sizeof tbuf);
 		EMIT_SIGNAL (XP_TE_SERVERLOOKUP, sess, tbuf, NULL, NULL, NULL, 0);
 		break;
+	case 10:						  /* netbind failed */
+		waitline2 (source, tbuf, sizeof tbuf);
+		waitline2 (source, tbuf2, sizeof tbuf2);
+		sprintf (outbuf, _("Failed to bind %s to socket: %s\n"), tbuf, tbuf2);
+		PrintText (sess, outbuf);
+		break;
 	}
 
 	return TRUE;
@@ -1367,7 +1381,7 @@ server_child (server * serv)
 	char *local_ip;
 	int connect_port;
 	char buf[512];
-	char bound = 0;
+	int bound = 0;
 	int proxy_type = 0;
 	char *proxy_host = NULL;
 	int proxy_port;
@@ -1383,13 +1397,20 @@ server_child (server * serv)
 		{
 			g_snprintf (buf, sizeof (buf), "5\n%s\n", local_ip);
 			write (serv->childwrite, buf, strlen (buf));
-			net_bind (ns_local, serv->sok4, serv->sok6);
-			bound = 1;
+			if (net_bind (ns_local, serv->sok4, serv->sok6) == 0)
+				bound = 1;
+			else
+			{
+				g_snprintf (buf, sizeof (buf), "10\n%s\n%s\n", local_ip, strerror (errno));
+				write (serv->childwrite, buf, strlen (buf));
+			}
 		} else
 		{
 			write (serv->childwrite, "7\n", 2);
 		}
 		net_store_destroy (ns_local);
+		if (! bound)
+			goto xit;
 	}
 
 	if (!serv->dont_use_proxy) /* blocked in serverlist? */
@@ -1454,7 +1475,8 @@ server_child (server * serv)
 		g_free (proxy_host);
 		if (!ip)
 		{
-			write (serv->childwrite, "1\n", 2);
+			g_snprintf (buf, sizeof (buf), "1\n%s\n", proxy_host);
+			write (serv->childwrite, buf, strlen (buf));
 			goto xit;
 		}
 		connect_port = proxy_port;
@@ -1466,7 +1488,8 @@ server_child (server * serv)
 			proxy_ip = net_resolve (ns_proxy, hostname, port, &real_hostname);
 			if (!proxy_ip)
 			{
-				write (serv->childwrite, "1\n", 2);
+				g_snprintf (buf, sizeof (buf), "1\n%s\n", hostname);
+				write (serv->childwrite, buf, strlen (buf));
 				goto xit;
 			}
 		} else						  /* otherwise we can just use the hostname */
@@ -1476,7 +1499,8 @@ server_child (server * serv)
 		ip = net_resolve (ns_server, hostname, port, &real_hostname);
 		if (!ip)
 		{
-			write (serv->childwrite, "1\n", 2);
+			g_snprintf (buf, sizeof (buf), "1\n%s\n", hostname);
+			write (serv->childwrite, buf, strlen (buf));
 			goto xit;
 		}
 		connect_port = port;
@@ -1692,7 +1716,7 @@ server_set_encoding (server *serv, char *new_encoding)
 	if (new_encoding)
 	{
 		serv->encoding = g_strdup (new_encoding);
-		/* the serverlist GUI might have added a space 
+		/* the serverlist GUI might have added a space
 			and short description - remove it. */
 		space = strchr (serv->encoding, ' ');
 		if (space)
diff --git a/src/common/textevents.in b/src/common/textevents.in
index 19b0d497..75fcb98f 100644
--- a/src/common/textevents.in
+++ b/src/common/textevents.in
@@ -811,8 +811,8 @@ pevt_topicdate_help
 Unknown Host
 XP_TE_UKNHOST
 pevt_generic_none_help
-%C20*%O$tUnknown host. Maybe you misspelled it?
-0
+%C20*%O$tUnknown host '%C22$1%C'. Maybe you misspelled it?
+1
 
 User Limit
 XP_TE_USERLIMIT

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Development

No branches or pull requests

1 participant