changeset 978:a7b53e6a71e0 trunk

[svn] - IPv6 support
author nenolod
date Thu, 27 Apr 2006 06:52:47 -0700
parents 773c485cf628
children 9c6797f14602
files Plugins/Input/cdaudio/http.c Plugins/Input/mpg123/http.c Plugins/Input/vorbis/http.c configure.ac
diffstat 4 files changed, 172 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/Plugins/Input/cdaudio/http.c	Wed Apr 26 21:26:03 2006 -0700
+++ b/Plugins/Input/cdaudio/http.c	Thu Apr 27 06:52:47 2006 -0700
@@ -26,9 +26,45 @@
 http_open_connection(const gchar * server, gint port)
 {
     gint sock;
+#ifdef USE_IPV6
+    struct addrinfo hints, *res, *res0;
+    char service[6];
+#else
     struct hostent *host;
     struct sockaddr_in address;
+#endif
 
+#ifdef USE_IPV6
+    snprintf(service, 6, "%d", port);
+    memset(&hints, 0, sizeof(hints));
+    hints.ai_socktype = SOCK_STREAM;
+
+    if (getaddrinfo(server, service, &hints, &res0))
+        return 0;
+
+    for (res = res0; res; res = res->ai_next) {
+        sock = socket (res->ai_family, res->ai_socktype, res->ai_protocol);
+        if (sock < 0) {
+            if (res->ai_next)
+                continue;
+            else {
+                freeaddrinfo(res0);
+                return 0;
+            }
+        }
+        if (connect(sock, res->ai_addr, res->ai_addrlen) < 0) {
+            if (res->ai_next) {
+                close(sock);
+                continue;
+            } else {
+                freeaddrinfo(res0);
+                return 0;
+            }
+        }
+        freeaddrinfo(res0);
+        return sock;
+    }
+#else
     sock = socket(AF_INET, SOCK_STREAM, 0);
     address.sin_family = AF_INET;
 
@@ -43,6 +79,7 @@
         (sock, (struct sockaddr *) &address,
          sizeof(struct sockaddr_in)) == -1)
         return 0;
+#endif
 
     return sock;
 }
--- a/Plugins/Input/mpg123/http.c	Wed Apr 26 21:26:03 2006 -0700
+++ b/Plugins/Input/mpg123/http.c	Thu Apr 27 06:52:47 2006 -0700
@@ -346,8 +346,13 @@
     gboolean redirect;
     gint udp_sock = 0;
     fd_set set;
+#ifdef USE_IPV6
+    struct addrinfo hints, *res, *res0;
+    char service[6];
+#else
     struct hostent *hp;
     struct sockaddr_in address;
+#endif
     struct timeval tv;
 
     url = (gchar *) arg;
@@ -368,6 +373,45 @@
         chost = mpg123_cfg.use_proxy ? mpg123_cfg.proxy_host : host;
         cport = mpg123_cfg.use_proxy ? mpg123_cfg.proxy_port : port;
 
+#ifdef USE_IPV6
+        snprintf(service, 6, "%d", cport);
+        memset(&hints, 0, sizeof(hints));
+        hints.ai_socktype = SOCK_STREAM;
+        if (! getaddrinfo(chost, service, &hints, &res0)) {
+            eof = TRUE;
+            for (res = res0; res; res = res->ai_next) {
+                if ((sock = socket (res->ai_family, res->ai_socktype, res->ai_protocol)) < 0)
+                    continue;
+                fcntl(sock, F_SETFL, O_NONBLOCK);
+                status = g_strdup_printf(_("CONNECTING TO %s:%d"), chost, cport);
+                mpg123_ip.set_info_text(status);
+                g_free(status);
+                ((struct sockaddr_in6 *)res->ai_addr)->sin6_port = htons(cport);
+                if (connect(sock, res->ai_addr, res->ai_addrlen) < 0) {
+                    if (errno != EINPROGRESS) {
+                        close(sock);
+                        continue;
+                    }
+                }
+                eof = FALSE;
+                break;
+            }
+            freeaddrinfo(res0);
+            if (eof) {
+                status = g_strdup_printf(_("Couldn't connect to host %s:%d"), chost, cport);
+                show_error_message(status);
+                g_free(status);
+                mpg123_ip.set_info_text(NULL);
+            }
+        } else {
+            status = g_strdup_printf(_("Couldn't look up host %s"), chost);
+            show_error_message(status);
+            g_free(status);
+
+            mpg123_ip.set_info_text(NULL);
+            eof = TRUE;
+        }
+#else
         sock = socket(AF_INET, SOCK_STREAM, 0);
         fcntl(sock, F_SETFL, O_NONBLOCK);
         address.sin_family = AF_INET;
@@ -384,8 +428,10 @@
             mpg123_ip.set_info_text(NULL);
             eof = TRUE;
         }
+#endif
 
         if (!eof) {
+#ifndef USE_IPV6
             memcpy(&address.sin_addr.s_addr, *(hp->h_addr_list),
                    sizeof(address.sin_addr.s_addr));
             address.sin_port = g_htons(cport);
@@ -407,6 +453,7 @@
                     eof = TRUE;
                 }
             }
+#endif
             while (going) {
                 tv.tv_sec = 0;
                 tv.tv_usec = 10000;
@@ -711,22 +758,35 @@
 static gint
 udp_establish_listener(gint * 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
 
 #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) {
+#endif
         g_log(NULL, G_LOG_LEVEL_CRITICAL,
               "udp_establish_listener(): unable to create socket");
         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
 
     if (bind(*sock, (struct sockaddr *) &sin, sinlen) < 0) {
         g_log(NULL, G_LOG_LEVEL_CRITICAL,
@@ -756,7 +816,11 @@
             g_ntohs(sin.sin_port));
 #endif
 
+#ifdef USE_IPV6
+    return g_ntohs(sin.sin6_port);
+#else
     return g_ntohs(sin.sin_port);
+#endif
 }
 
 static int
@@ -766,10 +830,14 @@
     char *valptr;
     gchar *title;
     gint len, i;
+#ifdef USE_IPV6
+    struct sockaddr_in6 from;
+#else
     struct sockaddr_in from;
+#endif
     socklen_t fromlen;
 
-    fromlen = sizeof(struct sockaddr_in);
+    fromlen = sizeof from;
 
     if ((len =
          recvfrom(sock, buf, 1024, 0, (struct sockaddr *) &from,
@@ -851,9 +919,18 @@
 #ifdef DEBUG_UDP
             else
                 fprintf(stderr, "Sent ack: %s", obuf);
+#ifdef USE_IPV6
+            {
+                char adr[INET6_ADDRSTRLEN];
+                inet_ntop(AF_INET6, &from.sin6_addr, adr, INET6_ADDRSTRLEN);
+                fprintf(stderr, "Remote: [%s]:%d\n", adr,
+                        g_ntohs(from.sin6_port));
+            }
+#else
             fprintf(stderr, "Remote: %s:%d\n", inet_ntoa(from.sin_addr),
                     g_ntohs(from.sin_port));
 #endif
+#endif
         }
     }
     g_strfreev(lines);
--- a/Plugins/Input/vorbis/http.c	Wed Apr 26 21:26:03 2006 -0700
+++ b/Plugins/Input/vorbis/http.c	Thu Apr 27 06:52:47 2006 -0700
@@ -298,8 +298,13 @@
     guint err_len;
     gboolean redirect;
     fd_set set;
+#ifdef USE_IPV6
+    struct addrinfo hints, *res, *res0;
+    char service[6];
+#else
     struct hostent *hp;
     struct sockaddr_in address;
+#endif
     struct timeval tv;
 
     url = (gchar *) arg;
@@ -320,6 +325,44 @@
         chost = vorbis_cfg.use_proxy ? vorbis_cfg.proxy_host : host;
         cport = vorbis_cfg.use_proxy ? vorbis_cfg.proxy_port : port;
 
+#ifdef USE_IPV6
+        snprintf(service, 6, "%d", cport);
+        memset(&hints, 0, sizeof(hints));
+        hints.ai_socktype = SOCK_STREAM;
+        if (! getaddrinfo(chost, service, &hints, &res0)) {
+            eof = TRUE;
+            for (res = res0; res; res = res->ai_next) {
+                if ((sock = socket (res->ai_family, res->ai_socktype, res->ai_protocol)) < 0)
+                    continue;
+                fcntl(sock, F_SETFL, O_NONBLOCK);
+                status = g_strdup_printf(_("CONNECTING TO %s:%d"), chost, cport);
+                vorbis_ip.set_info_text(status);
+                g_free(status);
+                ((struct sockaddr_in6 *)res->ai_addr)->sin6_port = htons(cport);
+                if (connect(sock, res->ai_addr, res->ai_addrlen) < 0) {
+                    if (errno != EINPROGRESS) {
+                        close(sock);
+                        continue;
+                    }
+                }
+                eof = FALSE;
+                break;
+            }
+            freeaddrinfo(res0);
+            if (eof) {
+                status = g_strdup_printf(_("Couldn't connect to host %s:%d"), chost, cport);
+                vorbis_ip.set_info_text(status);
+                g_free(status);
+                eof = TRUE;
+                break;
+            }
+        } else {
+            status = g_strdup_printf(_("Couldn't look up host %s"), chost);
+            vorbis_ip.set_info_text(status);
+            g_free(status);
+            eof = TRUE;
+        }
+#else
         sock = socket(AF_INET, SOCK_STREAM, 0);
         fcntl(sock, F_SETFL, O_NONBLOCK);
         address.sin_family = AF_INET;
@@ -336,8 +379,10 @@
             vorbis_ip.set_info_text(NULL);
             eof = TRUE;
         }
+#endif
 
         if (!eof) {
+#ifndef USE_IPV6
             memcpy(&address.sin_addr.s_addr, *(hp->h_addr_list),
                    sizeof(address.sin_addr.s_addr));
             address.sin_port = g_htons(cport);
@@ -359,6 +404,7 @@
                     eof = TRUE;
                 }
             }
+#endif
             while (going) {
                 tv.tv_sec = 0;
                 tv.tv_usec = 10000;
--- a/configure.ac	Wed Apr 26 21:26:03 2006 -0700
+++ b/configure.ac	Thu Apr 27 06:52:47 2006 -0700
@@ -175,6 +175,17 @@
     AC_DEFINE(socklen_t, int, [Define to int if the socklen_t type is missing])
 fi
 
+dnl IPv6 support
+dnl ========================
+AC_ARG_ENABLE(ipv6,
+	[  --enable-ipv6		  enable IPv6 support (default=no)],
+			enable_ipv6=$enableval, enable_ipv6=no)
+if test "x$enable_ipv6" = xyes; then
+    AC_DEFINE(USE_IPV6,, [Define if building with IPv6 support] )
+fi
+AM_CONDITIONAL(USE_IPV6,test "x$enable_ipv6" = xyes)
+AC_SUBST(USE_IPV6)
+
 
 dnl GConf support