[MPlayer-dev-eng] [PATCH] ipv6 TCP support

mplayer-dev-eng at dlambley.freeserve.co.uk mplayer-dev-eng at dlambley.freeserve.co.uk
Tue Mar 25 12:14:38 CET 2003


> You better use a different MUA, who would use the correct encoding and not that:

Ah, that was me Base64ing first. Using Pine now...

> It should be possible to force a IPv4 connection, even if you have a working
> IPv6 connection. Maybe you added something like that, but I couldn't check that
> because of the broken mime header.

I've changed it to do this, adding a -prefer-ipv4 option. There's also
-ipv4-only-proxy which makes it attempt to connect directly to anything
which doesn't resolve for IPv4.

I've added to the configure script as well, to make it autodetect IPv6
support and gethostbyname2().

Cheers,
Dave
-------------- next part --------------
? ffmpeg
? ~configure
Index: cfg-common.h
===================================================================
RCS file: /cvsroot/mplayer/main/cfg-common.h,v
retrieving revision 1.88
diff -u -r1.88 cfg-common.h
--- cfg-common.h	23 Mar 2003 15:04:51 -0000	1.88
+++ cfg-common.h	25 Mar 2003 11:05:46 -0000
@@ -40,10 +40,21 @@
 	{"user", &network_username, CONF_TYPE_STRING, 0, 0, 0, NULL},
 	{"passwd", &network_password, CONF_TYPE_STRING, 0, 0, 0, NULL},
 	{"bandwidth", &network_bandwidth, CONF_TYPE_INT, CONF_MIN, 0, 0, NULL},
+	
+	{"prefer-ipv4", &network_prefer_ipv4, CONF_TYPE_FLAG, 0, 0, 1, NULL},	
+	{"ipv4-only-proxy", &network_ipv4_only_proxy, CONF_TYPE_FLAG, 0, 0, 1, NULL},	
+
+#ifdef HAVE_AF_INET6
+	{"prefer-ipv6", &network_prefer_ipv4, CONF_TYPE_FLAG, 0, 1, 0, NULL},
+#else
+	{"prefer-ipv6", "MPlayer was compiled without IPv6 support\n", CONF_TYPE_PRINT, 0, 0, NULL},
+#endif
+
 #else
 	{"user", "MPlayer was compiled WITHOUT streaming(network) support\n", CONF_TYPE_PRINT, CONF_NOCFG, 0, 0, NULL},
 	{"bandwidth", "MPlayer was compiled WITHOUT streaming(network) support\n", CONF_TYPE_PRINT, CONF_NOCFG, 0, 0, NULL},
 #endif
+
 	
 // ------------------------- demuxer options --------------------
 
@@ -237,6 +248,10 @@
 extern char *network_username;
 extern char *network_password;
 extern int   network_bandwidth;
+
+extern int network_prefer_ipv4;
+extern int network_ipv4_only_proxy;
+
 #endif
 
 /* defined in libmpdemux: */
Index: configure
===================================================================
RCS file: /cvsroot/mplayer/main/configure,v
retrieving revision 1.688
diff -u -r1.688 configure
--- configure	23 Mar 2003 17:14:28 -0000	1.688
+++ configure	25 Mar 2003 11:05:51 -0000
@@ -168,7 +168,9 @@
   --disable-sortsub      Disable subtitles sorting [enabled]
   --enable-fribidi       Enable using the FriBiDi libs [disabled]
   --disable-macosx       Disable Mac OS X specific features [autodetect]
-
+  --disable-inet6        Disable IPv6 support [autodetect]
+  --disable-gethostbyname2
+                         gethostbyname() is not provided by the c library [autodetect]
 Codecs:
   --enable-gif		 enable gif support [autodetect]
   --enable-png		 enable png input/output support [autodetect]
@@ -1075,7 +1077,8 @@
 _freetypeconfig='freetype-config'
 _fribidi=no
 _fribidiconfig='fribidi-config'
-
+_inet6=auto
+_gethostbyname2=auto
 for ac_option do
   case "$ac_option" in
   # Skip 1st pass
@@ -1265,6 +1268,12 @@
   --enable-fribidi)     _fribidi=yes    ;;
   --disable-fribidi)    _fribidi=no     ;;
 
+  --enable-inet6)	_inet6=yes	;;
+  --disable-inet6)	_inet6=no	;;
+
+  --enable-gethostbyname2)	_gethostbyname2=yes	;;
+  --disable-gethostbyname2)	_gethostbyname2=no	;;
+
   --enable-dga) _dga=auto ;; # as we don't know if it's 1 or 2
   --enable-dga=*) _dga=`echo $ac_option | cut -d '=' -f 2` ;;
   --disable-dga) _dga=no ;;
@@ -4739,6 +4748,48 @@
 fi
 echores "$_xmms"
 
+
+echocheck "inet6"
+if test "$_inet6" = auto ; then
+  cat > $TMPC << EOF
+#include <sys/types.h>
+#include <sys/socket.h>
+int main(void) { socket(AF_INET6, SOCK_STREAM, AF_INET6); }
+EOF
+  _inet6=no
+  if cc_check ; then
+    _inet6=yes
+  fi
+fi
+if test "$_inet6" = yes ; then
+  _def_inet6='#define HAVE_AF_INET6 1'
+else
+  _def_inet6='#undef HAVE_AF_INET6'
+fi
+echores "$_inet6"
+
+
+echocheck "gethostbyname2"
+if test "$_gethostbyname2" = auto ; then
+cat > $TMPC << EOF
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+int main(void) { gethostbyname2("", AF_INET); }
+EOF
+  _gethostbyname2=no
+  if cc_check ; then
+    _gethostbyname2=yes
+  fi
+fi
+
+if test "$_inet6" = yes ; then
+  _def_gethostbyname2='#define HAVE_GETHOSTBYNAME2 1'
+else
+  _def_gethostbyname2='#undef HAVE_GETHOSTBYNAME2'
+fi
+echores "$_gethostbyname2"
+
 # --------------- GUI specific tests begin -------------------
 echocheck "GUI"
 echo "$_gui"
@@ -5536,6 +5587,12 @@
 /* XMMS input plugin support */
 $_def_xmms
 #define XMMS_INPUT_PLUGIN_DIR "$_xmmsplugindir"
+
+/* enables inet6 support */
+$_def_inet6
+
+/* do we have gethostbyname2? */
+$_def_gethostbyname2
 
 /* Extension defines */
 $_def_3dnow	// only define if you have 3DNOW (AMD k6-2, AMD Athlon, iDT WinChip, etc.)
Index: libmpdemux/network.c
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdemux/network.c,v
retrieving revision 1.71
diff -u -r1.71 network.c
--- libmpdemux/network.c	13 Jan 2003 03:10:19 -0000	1.71
+++ libmpdemux/network.c	25 Mar 2003 11:05:53 -0000
@@ -44,6 +44,10 @@
 char *network_password=NULL;
 int   network_bandwidth=0;
 
+/* IPv6 options */
+int   network_prefer_ipv4 = 0;
+int   network_ipv4_only_proxy = 0;
+
 
 static struct {
 	char *mime_type;
@@ -151,49 +155,112 @@
 }
 #endif
 
-// Connect to a server using a TCP connection
+
+// Converts an address family constant to a string
+
+char *af2String(int af) {
+	switch (af) {
+		case AF_INET:	return "AF_INET";
+		
+#ifdef HAVE_AF_INET6
+		case AF_INET6:	return "AF_INET6";
+#endif
+		default:	return "Unknown address family!";
+	}
+}
+
+
+
+// Connect to a server using a TCP connection, with specified address family
 // return -2 for fatal error, like unable to resolve name, connection timeout...
 // return -1 is unable to connect to a particular port
+
 int
-connect2Server(char *host, int port) {
+connect2Server_with_af(char *host, int port, int af) {
 	int socket_server_fd;
 	int err, err_len;
 	int ret,count = 0;
 	fd_set set;
 	struct timeval tv;
-	struct sockaddr_in server_address;
+	union {
+		struct sockaddr_in four;
+#ifdef HAVE_AF_INET6
+		struct sockaddr_in6 six;
+#endif
+	} server_address;
+	size_t server_address_size;
+	void *our_s_addr;	// Pointer to sin_addr or sin6_addr
 	struct hostent *hp=NULL;
-
-	socket_server_fd = socket(AF_INET, SOCK_STREAM, 0);
+	char buf[255];
+	
+	socket_server_fd = socket(af, SOCK_STREAM, 0);
+	
+	
 	if( socket_server_fd==-1 ) {
-		mp_msg(MSGT_NETWORK,MSGL_ERR,"Failed to create socket\n");
+		mp_msg(MSGT_NETWORK,MSGL_ERR,"Failed to create %s socket:\n", af2String(af));
 		return -2;
 	}
 
-	if( isalpha(host[0]) ) {
-		mp_msg(MSGT_NETWORK,MSGL_STATUS,"Resolving %s ...\n", host );
+	switch (af) {
+		case AF_INET:  our_s_addr = (void *) &server_address.four.sin_addr; break;
+#ifdef HAVE_AF_INET6
+		case AF_INET6: our_s_addr = (void *) &server_address.six.sin6_addr; break;
+#endif
+		default:
+			mp_msg(MSGT_NETWORK,MSGL_ERR, "Unknown address family %d:\n", af);
+			return -2;
+	}
+	
+	
+	bzero(&server_address, sizeof(server_address));
+	
+#ifdef USE_ATON
+	if (inet_aton(host, our_s_addr)!=1)
+#else
+	if (inet_pton(af, host, our_s_addr)!=1)
+#endif
+	{
+		mp_msg(MSGT_NETWORK,MSGL_STATUS,"Resolving %s for %s...\n", host, af2String(af));
+		
+#ifdef HAVE_GETHOSTBYNAME2
+		hp=(struct hostent*)gethostbyname2( host, af );
+#else
 		hp=(struct hostent*)gethostbyname( host );
+#endif
 		if( hp==NULL ) {
-			mp_msg(MSGT_NETWORK,MSGL_ERR,"Counldn't resolve name: %s\n", host);
+			mp_msg(MSGT_NETWORK,MSGL_ERR,"Couldn't resolve name for %s: %s\n", af2String(af), host);
 			return -2;
 		}
-		memcpy( (void*)&server_address.sin_addr.s_addr, (void*)hp->h_addr, hp->h_length );
-	} else {
-		inet_pton(AF_INET, host, &server_address.sin_addr);
+		
+		memcpy( our_s_addr, (void*)hp->h_addr, hp->h_length );
 	}
-	server_address.sin_family=AF_INET;
-	server_address.sin_port=htons(port);
 	
-	// Turn the socket as non blocking so we can timeout on the connection
-	if( isalpha(host[0]) && hp!=NULL ) {
-		mp_msg(MSGT_NETWORK,MSGL_STATUS,"Connecting to server %s[%d.%d.%d.%d]:%d ...\n", host, (hp->h_addr_list[0][0])&0xff, (hp->h_addr_list[0][1])&0xff, (hp->h_addr_list[0][2])&0xff, (hp->h_addr_list[0][3])&0xff, port );
-	} else {
-		mp_msg(MSGT_NETWORK,MSGL_STATUS,"Connecting to server %s:%d ...\n", host, port );
+	switch (af) {
+		case AF_INET:
+			server_address.four.sin_family=af;
+			server_address.four.sin_port=htons(port);			
+			server_address_size = sizeof(server_address.four);
+			break;
+#ifdef HAVE_AF_INET6		
+		case AF_INET6:
+			server_address.six.sin6_family=af;
+			server_address.six.sin6_port=htons(port);
+			server_address_size = sizeof(server_address.six);
+			break;
+#endif
+		default:
+			mp_msg(MSGT_NETWORK,MSGL_ERR, "Unknown address family %d:\n", af);
+			return -2;
 	}
+
+	inet_ntop(af, our_s_addr, buf, 255);			
+	mp_msg(MSGT_NETWORK,MSGL_STATUS,"Connecting to server %s[%s]:%d ...\n", host, buf , port );
+
+	// Turn the socket as non blocking so we can timeout on the connection
 	fcntl( socket_server_fd, F_SETFL, fcntl(socket_server_fd, F_GETFL) | O_NONBLOCK );
-	if( connect( socket_server_fd, (struct sockaddr*)&server_address, sizeof(server_address) )==-1 ) {
+	if( connect( socket_server_fd, (struct sockaddr*)&server_address, server_address_size )==-1 ) {
 		if( errno!=EINPROGRESS ) {
-			mp_msg(MSGT_NETWORK,MSGL_ERR,"Failed to connect to server\n");
+			mp_msg(MSGT_NETWORK,MSGL_ERR,"Failed to connect to server with %s\n", af2String(af));
 			close(socket_server_fd);
 			return -1;
 		}
@@ -233,9 +300,34 @@
 		mp_msg(MSGT_NETWORK,MSGL_ERR,"Connect error : %s\n",strerror(err));
 		return -1;
 	}
+	
 	return socket_server_fd;
 }
 
+// Connect to a server using a TCP connection
+// return -2 for fatal error, like unable to resolve name, connection timeout...
+// return -1 is unable to connect to a particular port
+
+
+int
+connect2Server(char *host, int  port) {
+#ifdef HAVE_AF_INET6
+	int r;
+	int s = -2;
+
+	r = connect2Server_with_af(host, port, network_prefer_ipv4 ? AF_INET:AF_INET6);	
+	if (r > -1) return r;
+
+	s = connect2Server_with_af(host, port, network_prefer_ipv4 ? AF_INET6:AF_INET);
+	if (s == -2) return r;
+	return s;
+#else	
+	return connect2Server_with_af(host, port, AF_INET);
+#endif
+
+	
+}
+
 URL_t*
 check4proxies( URL_t *url ) {
 	URL_t *url_out = NULL;
@@ -260,6 +352,14 @@
 				mp_msg(MSGT_NETWORK,MSGL_WARN,"Invalid proxy setting...Trying without proxy.\n");
 				return url_out;
 			}
+			
+#ifdef HAVE_AF_INET6
+			if (network_ipv4_only_proxy && (gethostbyname(url->hostname)==NULL)) {
+				mp_msg(MSGT_NETWORK,MSGL_WARN,
+					"Could not find resolve remote hostname for AF_INET. Trying without proxy.\n");
+				return url_out;
+			}
+#endif
 
 			mp_msg(MSGT_NETWORK,MSGL_V,"Using HTTP proxy: %s\n", proxy_url->url );
 			len = strlen( proxy_url->hostname ) + strlen( url->url ) + 20;	// 20 = http_proxy:// + port


More information about the MPlayer-dev-eng mailing list