[PATCH] ipv6 rework in udp_establish_listener

Pascal Terjan <[email protected]> Fri, 12 Aug 2005 17:13:43 +0200
Newsgroups gmane.comp.multimedia.xmms.devel
Organization Mandriva
Message-ID <1123859623.8173.6.camel@plop>
Hello,
even if I don't know the use of this UDP socket, here is a patch to have
bind occur in v4 when the v6 does not work.
This especially occurs when xmms is built with ipv6 support and run on a
system with ipv6 disabled.

Yours,
Pascal Terjan

_______________________________________________
xmms-devel mailing list
[email protected]
http://lists.xmms.org/mailman/listinfo/xmms-devel
xmms-1.2.10-ipv6.patch (text/x-patch, 2.5 KB)
--- ./Input/mpg123/http.c.ipv6	2003-12-07 18:09:49.000000000 +0100
+++ ./Input/mpg123/http.c	2005-08-12 13:21:36.000000000 +0200
@@ -754,39 +754,46 @@
 /* Find a good local udp port and bind udp_sock to it, return the port */
 static int udp_establish_listener(int *sock)
 {
-#ifdef USE_IPV6
-	struct sockaddr_in6 sin;
-	socklen_t sinlen = sizeof (struct sockaddr_in6);
-#else
-	struct sockaddr_in sin;
-	socklen_t sinlen = sizeof (struct sockaddr_in);
-#endif
-	
+	socklen_t sinlen = sizeof (struct sockaddr_in);
+	struct sockaddr *sin;
+	gboolean use_ipv6 = FALSE;
+	int port;
 #ifdef DEBUG_UDP
 	fprintf (stderr,"Establishing udp listener\n");
 #endif
 	
-#ifdef USE_IPV6
-	if ((*sock = socket(AF_INET6, SOCK_DGRAM, 0)) < 0)
-#else
-	if ((*sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
+#ifdef USE_IPV6	
+	sinlen = sizeof (struct sockaddr_in6);
+	use_ipv6 = TRUE;
+	if ((*sock = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {	
+	sinlen = sizeof (struct sockaddr_in);
+	use_ipv6 = FALSE;
 #endif
+	if ((*sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
 	{
 		g_log(NULL, G_LOG_LEVEL_CRITICAL,
 		      "udp_establish_listener(): unable to create socket: %s",
 		      strerror(errno));
 		return -1;
 	}
-
-	memset(&sin, 0, sinlen);
 #ifdef USE_IPV6
-	sin.sin6_family = AF_INET6;
-#else
-	sin.sin_family = AF_INET;
-	sin.sin_addr.s_addr = g_htonl(INADDR_ANY);
+	}
+#endif
+	sin = (struct sockaddr *)g_malloc(sinlen);
+	
+	memset(sin, 0, sinlen);
+#ifdef USE_IPV6
+	if (use_ipv6) {
+		((struct sockaddr_in6 *)sin)->sin6_family = AF_INET6;
+	} else {
+#endif
+ 	((struct sockaddr_in *)sin)->sin_family = AF_INET;
+ 	((struct sockaddr_in *)sin)->sin_addr.s_addr = g_htonl(INADDR_ANY);
+#ifdef USE_IPV6
+	}
 #endif
 			
-	if (bind(*sock, (struct sockaddr *)&sin, sinlen) < 0)
+	if (bind(*sock, sin, sinlen) < 0)
 	{
 		g_log(NULL, G_LOG_LEVEL_CRITICAL,
 		      "udp_establish_listener():  Failed to bind socket to localhost: %s", strerror(errno));
@@ -802,7 +809,7 @@
 	}
 
-	memset(&sin, 0, sinlen);
-	if (getsockname(*sock, (struct sockaddr *)&sin, &sinlen) < 0)
+	memset(sin, 0, sinlen);
+	if (getsockname(*sock, sin, &sinlen) < 0)
 	{
 		g_log(NULL, G_LOG_LEVEL_CRITICAL,
 		      "udp_establish_listener():  Failed to retrieve socket info: %s", strerror(errno));
@@ -815,10 +822,13 @@
 #endif
 	
 #ifdef USE_IPV6
-	return g_ntohs(sin.sin6_port);
-#else
-	return g_ntohs(sin.sin_port);
-#endif
+	if (use_ipv6)
+		port = g_ntohs(((struct sockaddr_in6 *)sin)->sin6_port);
+	else 
+#endif
+	port = g_ntohs(((struct sockaddr_in *)sin)->sin_port);
+	g_free(sin);
+	return port;
 }
 
 static int udp_check_for_data(int sock)