diff Plugins/Input/mpg123/http.c @ 978:a7b53e6a71e0 trunk

[svn] - IPv6 support
author nenolod
date Thu, 27 Apr 2006 06:52:47 -0700
parents 71189eb31ea9
children 05de825c2765
line wrap: on
line diff
--- 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);