r1468 - in trunk/code: client qcommon server

DONOTREPLY at icculus.org DONOTREPLY at icculus.org
Sun Aug 31 15:54:29 EDT 2008


Author: thilo
Date: 2008-08-31 15:54:29 -0400 (Sun, 31 Aug 2008)
New Revision: 1468

Modified:
   trunk/code/client/cl_main.c
   trunk/code/qcommon/net_ip.c
   trunk/code/qcommon/q_shared.h
   trunk/code/qcommon/qcommon.h
   trunk/code/server/sv_main.c
Log:
- Add scope id to ipv6 addresses.
- Clean up a few other ipv6 issues like removing the seemingly unnecessary MacOSX workaround.
- Bring ipv6 master server up to speed for dpmaster

Thanks go out to Mathieu Olivier for this work.


Modified: trunk/code/client/cl_main.c
===================================================================
--- trunk/code/client/cl_main.c	2008-08-31 10:41:30 UTC (rev 1467)
+++ trunk/code/client/cl_main.c	2008-08-31 19:54:29 UTC (rev 1468)
@@ -2172,7 +2172,7 @@
 CL_ServersResponsePacket
 ===================
 */
-void CL_ServersResponsePacket( netadr_t from, msg_t *msg ) {
+void CL_ServersResponsePacket( const netadr_t* from, msg_t *msg, qboolean extended ) {
 	int				i, count, total;
 	netadr_t addresses[MAX_SERVERSPERPACKET];
 	int				numservers;
@@ -2195,7 +2195,7 @@
 	// advance to initial token
 	do
 	{
-		if(*buffptr == '\\' || *buffptr == '/')
+		if(*buffptr == '\\' || (extended && *buffptr == '/'))
 			break;
 		
 		buffptr++;
@@ -2203,6 +2203,7 @@
 
 	while (buffptr + 1 < buffend)
 	{
+		// IPv4 address
 		if (*buffptr == '\\')
 		{
 			buffptr++;
@@ -2215,7 +2216,8 @@
 
 			addresses[numservers].type = NA_IP;
 		}
-		else
+		// IPv6 address, if it's an extended response
+		else if (extended && *buffptr == '/')
 		{
 			buffptr++;
 
@@ -2226,7 +2228,11 @@
 				addresses[numservers].ip6[i] = *buffptr++;
 			
 			addresses[numservers].type = NA_IP6;
+			addresses[numservers].scope_id = from->scope_id;
 		}
+		else
+			// syntax error!
+			break;
 			
 		// parse out port
 		addresses[numservers].port = (*buffptr++) << 8;
@@ -2378,12 +2384,18 @@
 		return;
 	}
 
-	// echo request from server
+	// list of servers sent back by a master server (classic)
 	if ( !Q_strncmp(c, "getserversResponse", 18) ) {
-		CL_ServersResponsePacket( from, msg );
+		CL_ServersResponsePacket( &from, msg, qfalse );
 		return;
 	}
 
+	// list of servers sent back by a master server (extended)
+	if ( !Q_strncmp(c, "getserversExtResponse", 21) ) {
+		CL_ServersResponsePacket( &from, msg, qtrue );
+		return;
+	}
+
 	Com_DPrintf ("Unknown connectionless packet command.\n");
 }
 
@@ -3616,6 +3628,7 @@
 	netadr_t	to;
 	int			count, i, masterNum;
 	char		command[1024], *masteraddress;
+	char		*cmdname;
 	
 	if ((count = Cmd_Argc()) < 3 || (masterNum = atoi(Cmd_Argv(1))) < 0 || masterNum > 4)
 	{
@@ -3650,8 +3663,18 @@
 	cls.numglobalservers = -1;
 	cls.pingUpdateSource = AS_GLOBAL;
 
-	Com_sprintf( command, sizeof(command), "getservers %s", Cmd_Argv(2) );
+	// Use the extended query for IPv6 masters
+	if (to.type == NA_IP6 || to.type == NA_MULTICAST6)
+	{
+		cmdname = "getserversExt " GAMENAME;
 
+		// TODO: test if we only have an IPv6 connection. If it's the case,
+		//       request IPv6 servers only by appending " ipv6" to the command
+	}
+	else
+		cmdname = "getservers";
+	Com_sprintf( command, sizeof(command), "%s %s", cmdname, Cmd_Argv(2) );
+
 	for (i=3; i < count; i++)
 	{
 		Q_strcat(command, sizeof(command), " ");

Modified: trunk/code/qcommon/net_ip.c
===================================================================
--- trunk/code/qcommon/net_ip.c	2008-08-31 10:41:30 UTC (rev 1467)
+++ trunk/code/qcommon/net_ip.c	2008-08-31 19:54:29 UTC (rev 1468)
@@ -227,6 +227,7 @@
 		((struct sockaddr_in6 *)s)->sin6_family = AF_INET6;
 		((struct sockaddr_in6 *)s)->sin6_addr = * ((struct in6_addr *) &a->ip6);
 		((struct sockaddr_in6 *)s)->sin6_port = a->port;
+		((struct sockaddr_in6 *)s)->sin6_scope_id = a->scope_id;
 	}
 	else if(a->type == NA_MULTICAST6)
 	{
@@ -248,6 +249,7 @@
 		a->type = NA_IP6;
 		memcpy(a->ip6, &((struct sockaddr_in6 *)s)->sin6_addr, sizeof(a->ip6));
 		a->port = ((struct sockaddr_in6 *)s)->sin6_port;
+		a->scope_id = ((struct sockaddr_in6 *)s)->sin6_scope_id;
 	}
 }
 
@@ -279,14 +281,11 @@
 	memset(sadr, '\0', sizeof(*sadr));
 	memset(&hints, '\0', sizeof(hints));
 
-	// workaround for buggy MacOSX getaddrinfo implementation that doesn't handle AF_UNSPEC in hints correctly.
-	if(family == AF_UNSPEC)
-		hintsp = NULL;
-	else
-	{
-		hintsp = &hints;
-		hintsp->ai_family = family;
-	}
+	hintsp = &hints;
+	hintsp->ai_family = family;
+	hintsp->ai_socktype = SOCK_DGRAM;
+	// FIXME: we should set "->ai_flags" to AI_PASSIVE if we intend
+	//        to use this structure for a bind() - instead of a sendto()
 	
 	retval = getaddrinfo(s, NULL, hintsp, &res);
 
@@ -399,7 +398,7 @@
 	
 	if (a.type == NA_IP6)
 	{
-		if(!memcmp(a.ip6, b.ip6, sizeof(a.ip6)))
+		if(!memcmp(a.ip6, b.ip6, sizeof(a.ip6)) && a.scope_id == b.scope_id)
 				  return qtrue;
 		
 		return qfalse;
@@ -720,6 +719,8 @@
 			}
 			else
 			{
+				// TODO? should we check the scope_id here?
+
 				compareip = (byte *) &((struct sockaddr_in6 *) &localIP[index].addr)->sin6_addr;
 				comparemask = (byte *) &((struct sockaddr_in6 *) &localIP[index].netmask)->sin6_addr;
 				compareadr = adr.ip6;

Modified: trunk/code/qcommon/q_shared.h
===================================================================
--- trunk/code/qcommon/q_shared.h	2008-08-31 10:41:30 UTC (rev 1467)
+++ trunk/code/qcommon/q_shared.h	2008-08-31 19:54:29 UTC (rev 1468)
@@ -38,6 +38,8 @@
   #define CLIENT_WINDOW_MIN_TITLE 	"ioq3"
 #endif
 
+#define GAMENAME BASEGAME
+
 #ifdef _MSC_VER
   #define PRODUCT_VERSION "1.35"
 #endif

Modified: trunk/code/qcommon/qcommon.h
===================================================================
--- trunk/code/qcommon/qcommon.h	2008-08-31 10:41:30 UTC (rev 1467)
+++ trunk/code/qcommon/qcommon.h	2008-08-31 19:54:29 UTC (rev 1468)
@@ -155,6 +155,7 @@
 	byte	ip6[16];
 
 	unsigned short	port;
+	unsigned long	scope_id;	// Needed for IPv6 link-local addresses
 } netadr_t;
 
 void		NET_Init( void );

Modified: trunk/code/server/sv_main.c
===================================================================
--- trunk/code/server/sv_main.c	2008-08-31 10:41:30 UTC (rev 1467)
+++ trunk/code/server/sv_main.c	2008-08-31 19:54:29 UTC (rev 1468)
@@ -233,6 +233,7 @@
 void SV_MasterHeartbeat( void ) {
 	static netadr_t	adr[MAX_MASTER_SERVERS];
 	int			i;
+	int			res;
 
 	// "dedicated 1" is for lan play, "dedicated 2" is for inet public play
 	if ( !com_dedicated || com_dedicated->integer != 2 ) {
@@ -259,7 +260,8 @@
 			sv_master[i]->modified = qfalse;
 	
 			Com_Printf( "Resolving %s\n", sv_master[i]->string );
-			if ( !NET_StringToAdr( sv_master[i]->string, &adr[i], NA_UNSPEC ) ) {
+			res = NET_StringToAdr( sv_master[i]->string, &adr[i], NA_UNSPEC );
+			if ( !res ) {
 				// if the address failed to resolve, clear it
 				// so we don't take repeated dns hits
 				Com_Printf( "Couldn't resolve address: %s\n", sv_master[i]->string );
@@ -267,7 +269,8 @@
 				sv_master[i]->modified = qfalse;
 				continue;
 			}
-			if ( !strchr( sv_master[i]->string, ':' ) ) {
+			if ( res == 2 ) {
+				// if no port was specified, use the default master port
 				adr[i].port = BigShort( PORT_MASTER );
 			}
 			Com_Printf( "%s resolved to %s\n", sv_master[i]->string, NET_AdrToStringwPort(adr[i]));
@@ -410,6 +413,7 @@
 		va("%i", sv_maxclients->integer - sv_privateClients->integer ) );
 	Info_SetValueForKey( infostring, "gametype", va("%i", sv_gametype->integer ) );
 	Info_SetValueForKey( infostring, "pure", va("%i", sv_pure->integer ) );
+	Info_SetValueForKey( infostring, "gamename", GAMENAME );
 
 #ifdef USE_VOIP
 	if (sv_voip->integer) {




More information about the quake3-commits mailing list