summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac16
-rw-r--r--src/input/input_http.c29
-rw-r--r--src/input/input_net.c90
-rw-r--r--src/xine-engine/io_helper.c78
4 files changed, 206 insertions, 7 deletions
diff --git a/configure.ac b/configure.ac
index d05d16c0e..5c25556e0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -221,6 +221,11 @@ LIBMPEG2_CFLAGS=""
LIBA52_CFLAGS=""
LIBFFMPEG_CFLAGS="-DSIMPLE_IDCT -DHAVE_AV_CONFIG_H -DRUNTIME_CPUDETECT -DUSE_FASTMEMCPY -DCONFIG_RISKY -DCONFIG_ENCODERS"
+AC_ARG_ENABLE(ipv6,
+ [ --enable-ipv6 enable use of IPv6],
+ enable_ipv6=yes,
+ enable_ipv6=no)
+
AC_ARG_ENABLE(altivec,
[ --disable-altivec use assembly codes for Motorola 74xx CPUs],
enable_altivec=no,
@@ -301,6 +306,17 @@ AC_CHECK_LIB(socket, socket, NET_LIBS="-lsocket $NET_LIBS",)
AC_CHECK_LIB(nsl, gethostbyname, NET_LIBS="-lnsl $NET_LIBS",)
AC_SUBST(NET_LIBS)
+dnl ---------------------------------------------
+dnl IPv6
+dnl ---------------------------------------------
+echo -n "IPv6 is "
+if test x$enable_ipv6 = xyes; then
+ CFLAGS="$CFLAGS -DENABLE_IPV6"
+ echo "enabled"
+else
+ echo "disabled"
+fi
+
dnl ---------------------------------------------
dnl zlib
diff --git a/src/input/input_http.c b/src/input/input_http.c
index ea87ccbe7..d785b52ac 100644
--- a/src/input/input_http.c
+++ b/src/input/input_http.c
@@ -19,7 +19,7 @@
*
* input plugin for http network streams
*
- * $Id: input_http.c,v 1.63 2003/08/21 00:37:29 miguelfreitas Exp $
+ * $Id: input_http.c,v 1.64 2003/09/25 13:42:19 f1rmb Exp $
*/
#ifdef HAVE_CONFIG_H
@@ -205,7 +205,32 @@ static int http_plugin_parse_url (char *urlbuf, char **user, char **password,
} else
if (host != NULL)
*host = start;
-
+
+#ifdef ENABLE_IPV6
+ // Add support for RFC 2732
+ {
+ char *hostbracket, *hostendbracket;
+
+ hostbracket = strchr(start, '[');
+ if (hostbracket != NULL) {
+
+ hostendbracket = strchr(hostbracket, ']');
+
+ if (hostendbracket != NULL) {
+
+ *hostendbracket = '\0';
+ *host = (hostbracket + 1);
+
+ // Might have a trailing port
+
+ if (*(hostendbracket+1) == ':') {
+ portcolon = (hostendbracket + 1);
+ }
+ }
+ }
+ }
+#endif
+
if (slash != 0)
{
*slash = '\0';
diff --git a/src/input/input_net.c b/src/input/input_net.c
index ef31e2694..6d8cc6c39 100644
--- a/src/input/input_net.c
+++ b/src/input/input_net.c
@@ -20,7 +20,7 @@
* Read from a tcp network stream over a lan (put a tweaked mp1e encoder the
* other end and you can watch tv anywhere in the house ..)
*
- * $Id: input_net.c,v 1.50 2003/06/19 14:48:23 guenter Exp $
+ * $Id: input_net.c,v 1.51 2003/09/25 13:42:19 f1rmb Exp $
*
* how to set up mp1e for use with this plugin:
*
@@ -49,6 +49,11 @@
#include <sys/socket.h>
#include <netinet/in.h>
+#ifdef ENABLE_IPV6
+#include <sys/types.h>
+#include <netdb.h>
+#endif
+
#ifndef WIN32
#include <arpa/inet.h>
#include <netdb.h>
@@ -104,7 +109,7 @@ typedef struct {
/* Private functions */
/* **************************************************************** */
-static int host_connect_attempt(struct in_addr ia, int port, xine_t *xine) {
+static int host_connect_attempt_ipv4(struct in_addr ia, int port, xine_t *xine) {
int s;
struct sockaddr_in sin;
@@ -135,7 +140,33 @@ static int host_connect_attempt(struct in_addr ia, int port, xine_t *xine) {
return s;
}
-static int host_connect(const char *host, int port, xine_t *xine) {
+static int host_connect_attempt(int family, struct sockaddr* sin, int addrlen, xine_t *xine) {
+
+ int s;
+
+ s = socket(family, SOCK_STREAM, IPPROTO_TCP);
+ if (s==-1) {
+ xine_log (xine, XINE_LOG_MSG,
+ _("input_net: socket(): %s\n"), strerror(errno));
+ return -1;
+ }
+
+#ifndef WIN32
+ if (connect(s, sin, addrlen)==-1 && errno != EINPROGRESS)
+#else
+ if (connect(s, sin, addrlen)==-1 && WSAGetLastError() != WSAEINPROGRESS)
+#endif
+ {
+ xine_log (xine, XINE_LOG_MSG,
+ _("input_net: connect(): %s\n"), strerror(errno));
+ close(s);
+ return -1;
+ }
+
+ return s;
+}
+
+static int host_connect_ipv4(const char *host, int port, xine_t *xine) {
struct hostent *h;
int i;
int s;
@@ -150,7 +181,7 @@ static int host_connect(const char *host, int port, xine_t *xine) {
for (i=0; h->h_addr_list[i]; i++) {
struct in_addr ia;
memcpy (&ia, h->h_addr_list[i],4);
- s = host_connect_attempt (ia, port, xine);
+ s = host_connect_attempt_ipv4 (ia, port, xine);
if (s != -1)
return s;
}
@@ -160,6 +191,57 @@ static int host_connect(const char *host, int port, xine_t *xine) {
return -1;
}
+static int host_connect(const char *host, int port, xine_t *xine) {
+
+#ifndef ENABLE_IPV6
+ return host_connect_ipv4(host, port, xine);
+#else
+
+ struct addrinfo hints, *res, *tmpaddr;
+ int error;
+ char strport[16];
+ int i;
+ int s;
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_family = PF_UNSPEC;
+
+ snprintf(strport, sizeof(strport), "%d", port);
+
+#ifdef LOG
+ printf("Resolving host '%s' at port '%s'\n", host, strport);
+#endif
+
+ error = getaddrinfo(host, strport, &hints, &res);
+
+ if (error) {
+
+ xine_log (xine, XINE_LOG_MSG,
+ _("input_net: unable to resolve '%s'.\n"), host);
+ return -1;
+ }
+
+ // We loop over all addresses and try to connect
+ tmpaddr = res;
+ while (tmpaddr) {
+
+ s = host_connect_attempt (tmpaddr->ai_family,
+ tmpaddr->ai_addr, tmpaddr->ai_addrlen, xine);
+ if (s != -1)
+ return s;
+
+ tmpaddr = tmpaddr->ai_next;
+ }
+
+ xine_log (xine, XINE_LOG_MSG,
+ _("input_net: unable to connect to '%s'.\n"), host);
+ return -1;
+
+#endif
+
+}
+
#define LOW_WATER_MARK 50
#define HIGH_WATER_MARK 100
diff --git a/src/xine-engine/io_helper.c b/src/xine-engine/io_helper.c
index c47177f75..7b190b2c5 100644
--- a/src/xine-engine/io_helper.c
+++ b/src/xine-engine/io_helper.c
@@ -45,7 +45,7 @@
#define XIO_POLLING_INTERVAL 50000 /* usec */
-int xio_tcp_connect(xine_stream_t *stream, const char *host, int port) {
+int xio_tcp_connect_ipv4(xine_stream_t *stream, const char *host, int port) {
struct hostent *h;
int i, s;
@@ -107,6 +107,82 @@ int xio_tcp_connect(xine_stream_t *stream, const char *host, int port) {
return -1;
}
+int xio_tcp_connect(xine_stream_t *stream, const char *host, int port) {
+
+#ifndef ENABLE_IPV6
+ return xio_tcp_connect_ipv4(stream, host, port);
+#else
+ int s;
+ struct addrinfo hints, *res, *tmpaddr;
+ int error;
+ char strport[16];
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_family = PF_UNSPEC;
+
+ snprintf(strport, sizeof(strport), "%d", port);
+
+ printf("Resolving host '%s' at port '%s'\n", host, strport);
+
+ error = getaddrinfo(host, strport, &hints, &res);
+
+ if (error) {
+ xine_message(stream, XINE_MSG_UNKNOWN_HOST,
+ "unable to resolve", host, NULL);
+ return -1;
+ }
+
+ tmpaddr = res;
+
+ while (tmpaddr) {
+
+ s = socket(tmpaddr->ai_family, SOCK_STREAM, IPPROTO_TCP);
+ if (s == -1) {
+ xine_message(stream, XINE_MSG_CONNECTION_REFUSED,
+ "failed to create socket", strerror(errno), NULL);
+ tmpaddr = tmpaddr->ai_next;
+ continue;
+ }
+
+ /**
+ * Uncommenting nonblocking features due to IPv6 support.
+ * Need to know if the connect failed, in order to try another
+ * address (if available). Error will be reported if no address
+ * worked.
+ */
+
+#ifndef WIN32
+
+ if (connect(s, tmpaddr->ai_addr,
+ tmpaddr->ai_addrlen)==-1 && errno != EINPROGRESS) {
+
+#else
+ if (connect(s, tmpaddr->ai_addr,
+ tmpaddr->ai_addrlen)==-1 &&
+ WSAGetLastError() != WSAEWOULDBLOCK) {
+
+ printf("io_helper: WSAGetLastError() = %d\n", WSAGetLastError());
+#endif /* WIN32 */
+
+ error = errno;
+ close(s);
+ tmpaddr = tmpaddr->ai_next;
+ continue;
+ } else {
+
+ return s;
+ }
+
+ tmpaddr = tmpaddr->ai_next;
+ }
+
+ xine_message(stream, XINE_MSG_CONNECTION_REFUSED, strerror(error), NULL);
+
+ return -1;
+#endif
+}
+
int xio_select (xine_stream_t *stream, int fd, int state, int timeout_msec) {