diff options
author | Daniel Caujolle-Bert <f1rmb@users.sourceforge.net> | 2003-09-25 13:42:19 +0000 |
---|---|---|
committer | Daniel Caujolle-Bert <f1rmb@users.sourceforge.net> | 2003-09-25 13:42:19 +0000 |
commit | f70bc36953d83daf54df12a7b83cd169ecaadd11 (patch) | |
tree | 995e719e66ca400e6646b427b5a1a2e2b31ad4f9 | |
parent | af6491f4959e4a289f0e11fb2c79f3d7ab635601 (diff) | |
download | xine-lib-f70bc36953d83daf54df12a7b83cd169ecaadd11.tar.gz xine-lib-f70bc36953d83daf54df12a7b83cd169ecaadd11.tar.bz2 |
IPv6 patch from Njål T. Borch <Njaal.Borch@njaal.net>
CVS patchset: 5413
CVS date: 2003/09/25 13:42:19
-rw-r--r-- | configure.ac | 16 | ||||
-rw-r--r-- | src/input/input_http.c | 29 | ||||
-rw-r--r-- | src/input/input_net.c | 90 | ||||
-rw-r--r-- | src/xine-engine/io_helper.c | 78 |
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) { |