mirror of
https://github.com/DrBeef/ioq3quest.git
synced 2024-11-26 22:11:18 +00:00
- 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.
This commit is contained in:
parent
b7799e644a
commit
9dd887b2ea
5 changed files with 48 additions and 17 deletions
|
@ -2172,7 +2172,7 @@ void CL_InitServerInfo( serverInfo_t *server, netadr_t *address ) {
|
|||
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 @@ void CL_ServersResponsePacket( netadr_t from, msg_t *msg ) {
|
|||
// advance to initial token
|
||||
do
|
||||
{
|
||||
if(*buffptr == '\\' || *buffptr == '/')
|
||||
if(*buffptr == '\\' || (extended && *buffptr == '/'))
|
||||
break;
|
||||
|
||||
buffptr++;
|
||||
|
@ -2203,6 +2203,7 @@ void CL_ServersResponsePacket( netadr_t from, msg_t *msg ) {
|
|||
|
||||
while (buffptr + 1 < buffend)
|
||||
{
|
||||
// IPv4 address
|
||||
if (*buffptr == '\\')
|
||||
{
|
||||
buffptr++;
|
||||
|
@ -2215,7 +2216,8 @@ void CL_ServersResponsePacket( netadr_t from, msg_t *msg ) {
|
|||
|
||||
addresses[numservers].type = NA_IP;
|
||||
}
|
||||
else
|
||||
// IPv6 address, if it's an extended response
|
||||
else if (extended && *buffptr == '/')
|
||||
{
|
||||
buffptr++;
|
||||
|
||||
|
@ -2226,7 +2228,11 @@ void CL_ServersResponsePacket( netadr_t from, msg_t *msg ) {
|
|||
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,9 +2384,15 @@ void CL_ConnectionlessPacket( netadr_t from, msg_t *msg ) {
|
|||
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;
|
||||
}
|
||||
|
||||
|
@ -3616,6 +3628,7 @@ void CL_GlobalServers_f( void ) {
|
|||
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,7 +3663,17 @@ void CL_GlobalServers_f( void ) {
|
|||
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++)
|
||||
{
|
||||
|
|
|
@ -227,6 +227,7 @@ static void NetadrToSockadr( netadr_t *a, struct sockaddr *s ) {
|
|||
((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 @@ static void SockadrToNetadr( struct sockaddr *s, netadr_t *a ) {
|
|||
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 @@ static qboolean Sys_StringToSockaddr(const char *s, struct sockaddr *sadr, int s
|
|||
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 @@ qboolean NET_CompareBaseAdr (netadr_t a, netadr_t b)
|
|||
|
||||
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 @@ qboolean Sys_IsLANAddress( netadr_t adr ) {
|
|||
}
|
||||
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;
|
||||
|
|
|
@ -38,6 +38,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
#define CLIENT_WINDOW_MIN_TITLE "ioq3"
|
||||
#endif
|
||||
|
||||
#define GAMENAME BASEGAME
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define PRODUCT_VERSION "1.35"
|
||||
#endif
|
||||
|
|
|
@ -155,6 +155,7 @@ typedef struct {
|
|||
byte ip6[16];
|
||||
|
||||
unsigned short port;
|
||||
unsigned long scope_id; // Needed for IPv6 link-local addresses
|
||||
} netadr_t;
|
||||
|
||||
void NET_Init( void );
|
||||
|
|
|
@ -233,6 +233,7 @@ but not on every player enter or exit.
|
|||
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 @@ void SV_MasterHeartbeat( void ) {
|
|||
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 @@ void SV_MasterHeartbeat( void ) {
|
|||
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 @@ void SVC_Info( netadr_t from ) {
|
|||
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) {
|
||||
|
|
Loading…
Reference in a new issue