Basic IPv6 support. Some inspiration from the patches by Lubos Dolezel and JF Tremblay at https://bugzilla.icculus.org/show_bug.cgi?id=2355.

This commit is contained in:
Thilo Schulz 2008-04-04 23:22:22 +00:00
parent c5980568e1
commit 5d63a38ad9
8 changed files with 926 additions and 481 deletions

View file

@ -780,7 +780,7 @@ void CL_MapLoading( void ) {
Key_SetCatcher( 0 ); Key_SetCatcher( 0 );
SCR_UpdateScreen(); SCR_UpdateScreen();
clc.connectTime = -RETRANSMIT_TIMEOUT; clc.connectTime = -RETRANSMIT_TIMEOUT;
NET_StringToAdr( cls.servername, &clc.serverAddress); NET_StringToAdr( cls.servername, &clc.serverAddress, NA_UNSPEC);
// we don't need a challenge on the localhost // we don't need a challenge on the localhost
CL_CheckForResend(); CL_CheckForResend();
@ -808,7 +808,7 @@ CL_UpdateGUID
update cl_guid using QKEY_FILE and optional prefix update cl_guid using QKEY_FILE and optional prefix
==================== ====================
*/ */
static void CL_UpdateGUID( char *prefix, int prefix_len ) static void CL_UpdateGUID( const char *prefix, int prefix_len )
{ {
fileHandle_t f; fileHandle_t f;
int len; int len;
@ -941,7 +941,7 @@ void CL_RequestMotd( void ) {
return; return;
} }
Com_Printf( "Resolving %s\n", UPDATE_SERVER_NAME ); Com_Printf( "Resolving %s\n", UPDATE_SERVER_NAME );
if ( !NET_StringToAdr( UPDATE_SERVER_NAME, &cls.updateServer ) ) { if ( !NET_StringToAdr( UPDATE_SERVER_NAME, &cls.updateServer, NA_IP ) ) {
Com_Printf( "Couldn't resolve address\n" ); Com_Printf( "Couldn't resolve address\n" );
return; return;
} }
@ -1011,7 +1011,7 @@ void CL_RequestAuthorization( void ) {
if ( !cls.authorizeServer.port ) { if ( !cls.authorizeServer.port ) {
Com_Printf( "Resolving %s\n", AUTHORIZE_SERVER_NAME ); Com_Printf( "Resolving %s\n", AUTHORIZE_SERVER_NAME );
if ( !NET_StringToAdr( AUTHORIZE_SERVER_NAME, &cls.authorizeServer ) ) { if ( !NET_StringToAdr( AUTHORIZE_SERVER_NAME, &cls.authorizeServer, NA_IP ) ) {
Com_Printf( "Couldn't resolve address\n" ); Com_Printf( "Couldn't resolve address\n" );
return; return;
} }
@ -1145,13 +1145,29 @@ CL_Connect_f
*/ */
void CL_Connect_f( void ) { void CL_Connect_f( void ) {
char *server; char *server;
char serverString[ 22 ]; const char *serverString;
int argc = Cmd_Argc();
netadrtype_t family = NA_UNSPEC;
if ( Cmd_Argc() != 2 ) { if ( argc != 2 && argc != 3 ) {
Com_Printf( "usage: connect [server]\n"); Com_Printf( "usage: connect [-4|-6] server\n");
return; return;
} }
if(argc == 2)
server = Cmd_Argv(1);
else
{
if(!strcmp(Cmd_Argv(1), "-4"))
family = NA_IP;
else if(!strcmp(Cmd_Argv(1), "-6"))
family = NA_IP6;
else
Com_Printf( "warning: only -4 or -6 as address type understood.\n");
server = Cmd_Argv(2);
}
Cvar_Set("ui_singlePlayerActive", "0"); Cvar_Set("ui_singlePlayerActive", "0");
// fire a message off to the motd server // fire a message off to the motd server
@ -1160,8 +1176,6 @@ void CL_Connect_f( void ) {
// clear any previous "server full" type messages // clear any previous "server full" type messages
clc.serverMessage[0] = 0; clc.serverMessage[0] = 0;
server = Cmd_Argv (1);
if ( com_sv_running->integer && !strcmp( server, "localhost" ) ) { if ( com_sv_running->integer && !strcmp( server, "localhost" ) ) {
// if running a local server, kill it // if running a local server, kill it
SV_Shutdown( "Server quit" ); SV_Shutdown( "Server quit" );
@ -1180,7 +1194,7 @@ void CL_Connect_f( void ) {
Q_strncpyz( cls.servername, server, sizeof(cls.servername) ); Q_strncpyz( cls.servername, server, sizeof(cls.servername) );
if (!NET_StringToAdr( cls.servername, &clc.serverAddress) ) { if (!NET_StringToAdr(cls.servername, &clc.serverAddress, family) ) {
Com_Printf ("Bad server address\n"); Com_Printf ("Bad server address\n");
cls.state = CA_DISCONNECTED; cls.state = CA_DISCONNECTED;
return; return;
@ -1188,12 +1202,10 @@ void CL_Connect_f( void ) {
if (clc.serverAddress.port == 0) { if (clc.serverAddress.port == 0) {
clc.serverAddress.port = BigShort( PORT_SERVER ); clc.serverAddress.port = BigShort( PORT_SERVER );
} }
Com_sprintf( serverString, sizeof( serverString ), "%i.%i.%i.%i:%i",
clc.serverAddress.ip[0], clc.serverAddress.ip[1],
clc.serverAddress.ip[2], clc.serverAddress.ip[3],
BigShort( clc.serverAddress.port ) );
Com_Printf( "%s resolved to %s\n", cls.servername, serverString ); serverString = NET_AdrToStringwPort(clc.serverAddress);
Com_Printf( "%s resolved to %s\n", cls.servername, serverString);
if( cl_guidServerUniq->integer ) if( cl_guidServerUniq->integer )
CL_UpdateGUID( serverString, strlen( serverString ) ); CL_UpdateGUID( serverString, strlen( serverString ) );
@ -1260,7 +1272,7 @@ void CL_Rcon_f( void ) {
return; return;
} }
NET_StringToAdr (rconAddress->string, &to); NET_StringToAdr (rconAddress->string, &to, NA_UNSPEC);
if (to.port == 0) { if (to.port == 0) {
to.port = BigShort (PORT_SERVER); to.port = BigShort (PORT_SERVER);
} }
@ -1697,8 +1709,8 @@ void CL_CheckForResend( void ) {
switch ( cls.state ) { switch ( cls.state ) {
case CA_CONNECTING: case CA_CONNECTING:
// requesting a challenge // requesting a challenge .. IPv6 users always get in as authorize server supports no ipv6.
if ( !Sys_IsLANAddress( clc.serverAddress ) ) { if ( clc.serverAddress.type == NA_IP && !Sys_IsLANAddress( clc.serverAddress ) ) {
CL_RequestAuthorization(); CL_RequestAuthorization();
} }
NET_OutOfBandPrint(NS_CLIENT, clc.serverAddress, "getchallenge"); NET_OutOfBandPrint(NS_CLIENT, clc.serverAddress, "getchallenge");
@ -1968,7 +1980,7 @@ void CL_ConnectionlessPacket( netadr_t from, msg_t *msg ) {
// challenge from the server we are connecting to // challenge from the server we are connecting to
if ( !Q_stricmp(c, "challengeResponse") ) { if ( !Q_stricmp(c, "challengeResponse") ) {
if ( cls.state != CA_CONNECTING ) { if ( cls.state != CA_CONNECTING ) {
Com_Printf( "Unwanted challenge response received. Ignored.\n" ); Com_DPrintf( "Unwanted challenge response received. Ignored.\n" );
} else { } else {
// start sending challenge repsonse instead of challenge request packets // start sending challenge repsonse instead of challenge request packets
clc.challenge = atoi(Cmd_Argv(1)); clc.challenge = atoi(Cmd_Argv(1));
@ -3059,7 +3071,7 @@ int CL_ServerStatus( char *serverAddress, char *serverStatusString, int maxLen )
return qfalse; return qfalse;
} }
// get the address // get the address
if ( !NET_StringToAdr( serverAddress, &to ) ) { if ( !NET_StringToAdr( serverAddress, &to, NA_UNSPEC) ) {
return qfalse; return qfalse;
} }
serverStatus = CL_GetServerStatus( to ); serverStatus = CL_GetServerStatus( to );
@ -3262,7 +3274,7 @@ void CL_GlobalServers_f( void ) {
// reset the list, waiting for response // reset the list, waiting for response
// -1 is used to distinguish a "no response" // -1 is used to distinguish a "no response"
NET_StringToAdr( cl_master->string, &to ); NET_StringToAdr( cl_master->string, &to, NA_IP );
if( cls.masterNum == 1 ) { if( cls.masterNum == 1 ) {
cls.nummplayerservers = -1; cls.nummplayerservers = -1;
@ -3465,17 +3477,33 @@ void CL_Ping_f( void ) {
netadr_t to; netadr_t to;
ping_t* pingptr; ping_t* pingptr;
char* server; char* server;
int argc;
netadrtype_t family = NA_UNSPEC;
if ( Cmd_Argc() != 2 ) { argc = Cmd_Argc();
Com_Printf( "usage: ping [server]\n");
if ( argc != 2 && argc != 3 ) {
Com_Printf( "usage: ping [-4|-6] server\n");
return; return;
} }
if(argc == 2)
server = Cmd_Argv(1);
else
{
if(!strcmp(Cmd_Argv(1), "-4"))
family = NA_IP;
else if(!strcmp(Cmd_Argv(1), "-6"))
family = NA_IP6;
else
Com_Printf( "warning: only -4 or -6 as address type understood.\n");
server = Cmd_Argv(2);
}
Com_Memset( &to, 0, sizeof(netadr_t) ); Com_Memset( &to, 0, sizeof(netadr_t) );
server = Cmd_Argv(1); if ( !NET_StringToAdr( server, &to, family ) ) {
if ( !NET_StringToAdr( server, &to ) ) {
return; return;
} }
@ -3603,32 +3631,53 @@ CL_ServerStatus_f
================== ==================
*/ */
void CL_ServerStatus_f(void) { void CL_ServerStatus_f(void) {
netadr_t to; netadr_t to, *toptr = NULL;
char *server; char *server;
serverStatus_t *serverStatus; serverStatus_t *serverStatus;
int argc;
netadrtype_t family = NA_UNSPEC;
argc = Cmd_Argc();
if ( argc != 2 && argc != 3 )
{
if (cls.state != CA_ACTIVE || clc.demoplaying)
{
Com_Printf ("Not connected to a server.\n");
Com_Printf( "usage: serverstatus [-4|-6] server\n");
return;
}
toptr = &clc.serverAddress;
}
if(!toptr)
{
Com_Memset( &to, 0, sizeof(netadr_t) ); Com_Memset( &to, 0, sizeof(netadr_t) );
if ( Cmd_Argc() != 2 ) { if(argc == 2)
if ( cls.state != CA_ACTIVE || clc.demoplaying ) {
Com_Printf ("Not connected to a server.\n");
Com_Printf( "Usage: serverstatus [server]\n");
return;
}
server = cls.servername;
}
else {
server = Cmd_Argv(1); server = Cmd_Argv(1);
else
{
if(!strcmp(Cmd_Argv(1), "-4"))
family = NA_IP;
else if(!strcmp(Cmd_Argv(1), "-6"))
family = NA_IP6;
else
Com_Printf( "warning: only -4 or -6 as address type understood.\n");
server = Cmd_Argv(2);
} }
if ( !NET_StringToAdr( server, &to ) ) { toptr = &to;
if ( !NET_StringToAdr( server, toptr, family ) )
return; return;
} }
NET_OutOfBandPrint( NS_CLIENT, to, "getstatus" ); NET_OutOfBandPrint( NS_CLIENT, *toptr, "getstatus" );
serverStatus = CL_GetServerStatus( to ); serverStatus = CL_GetServerStatus( *toptr );
serverStatus->address = to; serverStatus->address = *toptr;
serverStatus->print = qtrue; serverStatus->print = qtrue;
serverStatus->pending = qtrue; serverStatus->pending = qtrue;
} }

View file

@ -156,7 +156,7 @@ static int LAN_AddServer(int source, const char *name, const char *address) {
break; break;
} }
if (servers && *count < max) { if (servers && *count < max) {
NET_StringToAdr( address, &adr ); NET_StringToAdr( address, &adr, NA_IP );
for ( i = 0; i < *count; i++ ) { for ( i = 0; i < *count; i++ ) {
if (NET_CompareAdr(servers[i].adr, adr)) { if (NET_CompareAdr(servers[i].adr, adr)) {
break; break;
@ -203,7 +203,7 @@ static void LAN_RemoveServer(int source, const char *addr) {
} }
if (servers) { if (servers) {
netadr_t comp; netadr_t comp;
NET_StringToAdr( addr, &comp ); NET_StringToAdr( addr, &comp, NA_IP );
for (i = 0; i < *count; i++) { for (i = 0; i < *count; i++) {
if (NET_CompareAdr( comp, servers[i].adr)) { if (NET_CompareAdr( comp, servers[i].adr)) {
int j = i; int j = i;

View file

@ -460,74 +460,6 @@ qboolean Netchan_Process( netchan_t *chan, msg_t *msg ) {
//============================================================================== //==============================================================================
/*
===================
NET_CompareBaseAdr
Compares without the port
===================
*/
qboolean NET_CompareBaseAdr (netadr_t a, netadr_t b)
{
if (a.type != b.type)
return qfalse;
if (a.type == NA_LOOPBACK)
return qtrue;
if (a.type == NA_IP)
{
if (a.ip[0] == b.ip[0] && a.ip[1] == b.ip[1] && a.ip[2] == b.ip[2] && a.ip[3] == b.ip[3])
return qtrue;
return qfalse;
}
Com_Printf ("NET_CompareBaseAdr: bad address type\n");
return qfalse;
}
const char *NET_AdrToString (netadr_t a)
{
static char s[64];
if (a.type == NA_LOOPBACK) {
Com_sprintf (s, sizeof(s), "loopback");
} else if (a.type == NA_BOT) {
Com_sprintf (s, sizeof(s), "bot");
} else if (a.type == NA_IP) {
Com_sprintf (s, sizeof(s), "%i.%i.%i.%i:%hu",
a.ip[0], a.ip[1], a.ip[2], a.ip[3], BigShort(a.port));
}
return s;
}
qboolean NET_CompareAdr (netadr_t a, netadr_t b)
{
if (a.type != b.type)
return qfalse;
if (a.type == NA_LOOPBACK)
return qtrue;
if (a.type == NA_IP)
{
if (a.ip[0] == b.ip[0] && a.ip[1] == b.ip[1] && a.ip[2] == b.ip[2] && a.ip[3] == b.ip[3] && a.port == b.port)
return qtrue;
return qfalse;
}
Com_Printf ("NET_CompareAdr: bad address type\n");
return qfalse;
}
qboolean NET_IsLocalAddress( netadr_t adr ) {
return adr.type == NA_LOOPBACK;
}
/* /*
============================================================================= =============================================================================
@ -743,10 +675,10 @@ NET_StringToAdr
Traps "localhost" for loopback, passes everything else to system Traps "localhost" for loopback, passes everything else to system
============= =============
*/ */
qboolean NET_StringToAdr( const char *s, netadr_t *a ) { qboolean NET_StringToAdr( const char *s, netadr_t *a, netadrtype_t family ) {
qboolean r; qboolean r;
char base[MAX_STRING_CHARS]; char base[MAX_STRING_CHARS], *search;
char *port; char *port = NULL;
if (!strcmp (s, "localhost")) { if (!strcmp (s, "localhost")) {
Com_Memset (a, 0, sizeof(*a)); Com_Memset (a, 0, sizeof(*a));
@ -756,21 +688,37 @@ qboolean NET_StringToAdr( const char *s, netadr_t *a ) {
// look for a port number // look for a port number
Q_strncpyz( base, s, sizeof( base ) ); Q_strncpyz( base, s, sizeof( base ) );
port = strstr( base, ":" );
if(*base == '[')
{
// This is an ipv6 address, handle it specially.
search = strchr(base, ']');
if(search)
{
*search = '\0';
search++;
if(*search == ':')
port = search + 1;
}
search = base + 1;
}
else
{
port = strchr( base, ':' );
if ( port ) { if ( port ) {
*port = 0; *port = '\0';
port++; port++;
} }
r = Sys_StringToAdr( base, a ); search = base;
if ( !r ) {
a->type = NA_BAD;
return qfalse;
} }
// inet_addr returns this if out of range r = Sys_StringToAdr( search, a, family );
if ( a->ip[0] == 255 && a->ip[1] == 255 && a->ip[2] == 255 && a->ip[3] == 255 ) {
if ( !r ) {
a->type = NA_BAD; a->type = NA_BAD;
return qfalse; return qfalse;
} }

File diff suppressed because it is too large Load diff

View file

@ -136,7 +136,9 @@ typedef enum {
NA_BAD, // an address lookup failed NA_BAD, // an address lookup failed
NA_LOOPBACK, NA_LOOPBACK,
NA_BROADCAST, NA_BROADCAST,
NA_IP NA_IP,
NA_IP6,
NA_UNSPEC
} netadrtype_t; } netadrtype_t;
typedef enum { typedef enum {
@ -144,10 +146,12 @@ typedef enum {
NS_SERVER NS_SERVER
} netsrc_t; } netsrc_t;
#define NET_ADDRSTRMAXLEN 48 // maximum length of an IPv6 address string including trailing '\0'
typedef struct { typedef struct {
netadrtype_t type; netadrtype_t type;
byte ip[4]; byte ip[4];
byte ip6[16];
unsigned short port; unsigned short port;
} netadr_t; } netadr_t;
@ -165,7 +169,8 @@ qboolean NET_CompareAdr (netadr_t a, netadr_t b);
qboolean NET_CompareBaseAdr (netadr_t a, netadr_t b); qboolean NET_CompareBaseAdr (netadr_t a, netadr_t b);
qboolean NET_IsLocalAddress (netadr_t adr); qboolean NET_IsLocalAddress (netadr_t adr);
const char *NET_AdrToString (netadr_t a); const char *NET_AdrToString (netadr_t a);
qboolean NET_StringToAdr ( const char *s, netadr_t *a); const char *NET_AdrToStringwPort (netadr_t a);
qboolean NET_StringToAdr ( const char *s, netadr_t *a, netadrtype_t family);
qboolean NET_GetLoopPacket (netsrc_t sock, netadr_t *net_from, msg_t *net_message); qboolean NET_GetLoopPacket (netsrc_t sock, netadr_t *net_from, msg_t *net_message);
void NET_Sleep(int msec); void NET_Sleep(int msec);
@ -1015,7 +1020,7 @@ void Sys_SetErrorText( const char *text );
void Sys_SendPacket( int length, const void *data, netadr_t to ); void Sys_SendPacket( int length, const void *data, netadr_t to );
qboolean Sys_GetPacket( netadr_t *net_from, msg_t *net_message ); qboolean Sys_GetPacket( netadr_t *net_from, msg_t *net_message );
qboolean Sys_StringToAdr( const char *s, netadr_t *a ); qboolean Sys_StringToAdr( const char *s, netadr_t *a, netadrtype_t family );
//Does NOT parse port numbers, only base addresses. //Does NOT parse port numbers, only base addresses.
qboolean Sys_IsLANAddress (netadr_t adr); qboolean Sys_IsLANAddress (netadr_t adr);

View file

@ -433,7 +433,7 @@ static void SV_Ban_f( void ) {
// look up the authorize server's IP // look up the authorize server's IP
if ( !svs.authorizeAddress.ip[0] && svs.authorizeAddress.type != NA_BAD ) { if ( !svs.authorizeAddress.ip[0] && svs.authorizeAddress.type != NA_BAD ) {
Com_Printf( "Resolving %s\n", AUTHORIZE_SERVER_NAME ); Com_Printf( "Resolving %s\n", AUTHORIZE_SERVER_NAME );
if ( !NET_StringToAdr( AUTHORIZE_SERVER_NAME, &svs.authorizeAddress ) ) { if ( !NET_StringToAdr( AUTHORIZE_SERVER_NAME, &svs.authorizeAddress, NA_IP ) ) {
Com_Printf( "Couldn't resolve address\n" ); Com_Printf( "Couldn't resolve address\n" );
return; return;
} }
@ -487,7 +487,7 @@ static void SV_BanNum_f( void ) {
// look up the authorize server's IP // look up the authorize server's IP
if ( !svs.authorizeAddress.ip[0] && svs.authorizeAddress.type != NA_BAD ) { if ( !svs.authorizeAddress.ip[0] && svs.authorizeAddress.type != NA_BAD ) {
Com_Printf( "Resolving %s\n", AUTHORIZE_SERVER_NAME ); Com_Printf( "Resolving %s\n", AUTHORIZE_SERVER_NAME );
if ( !NET_StringToAdr( AUTHORIZE_SERVER_NAME, &svs.authorizeAddress ) ) { if ( !NET_StringToAdr( AUTHORIZE_SERVER_NAME, &svs.authorizeAddress, NA_IP ) ) {
Com_Printf( "Couldn't resolve address\n" ); Com_Printf( "Couldn't resolve address\n" );
return; return;
} }

View file

@ -88,10 +88,13 @@ void SV_GetChallenge( netadr_t from ) {
return; return;
} }
// Drop the authorize stuff if this client is coming in via v6 as the auth server does not support ipv6.
if(challenge->adr.type == NA_IP)
{
// look up the authorize server's IP // look up the authorize server's IP
if ( !svs.authorizeAddress.ip[0] && svs.authorizeAddress.type != NA_BAD ) { if ( !svs.authorizeAddress.ip[0] && svs.authorizeAddress.type != NA_BAD ) {
Com_Printf( "Resolving %s\n", AUTHORIZE_SERVER_NAME ); Com_Printf( "Resolving %s\n", AUTHORIZE_SERVER_NAME );
if ( !NET_StringToAdr( AUTHORIZE_SERVER_NAME, &svs.authorizeAddress ) ) { if ( !NET_StringToAdr( AUTHORIZE_SERVER_NAME, &svs.authorizeAddress, NA_IP ) ) {
Com_Printf( "Couldn't resolve address\n" ); Com_Printf( "Couldn't resolve address\n" );
return; return;
} }
@ -133,6 +136,14 @@ void SV_GetChallenge( netadr_t from ) {
"getIpAuthorize %i %i.%i.%i.%i %s 0 %s", svs.challenges[i].challenge, "getIpAuthorize %i %i.%i.%i.%i %s 0 %s", svs.challenges[i].challenge,
from.ip[0], from.ip[1], from.ip[2], from.ip[3], game, sv_strictAuth->string ); from.ip[0], from.ip[1], from.ip[2], from.ip[3], game, sv_strictAuth->string );
} }
}
else
{
challenge->pingTime = svs.time;
NET_OutOfBandPrint( NS_SERVER, challenge->adr,
"challengeResponse %i", challenge->challenge );
}
} }
/* /*
@ -284,9 +295,8 @@ void SV_DirectConnect( netadr_t from ) {
for (i=0 ; i<MAX_CHALLENGES ; i++) { for (i=0 ; i<MAX_CHALLENGES ; i++) {
if (NET_CompareAdr(from, svs.challenges[i].adr)) { if (NET_CompareAdr(from, svs.challenges[i].adr)) {
if ( challenge == svs.challenges[i].challenge ) { if ( challenge == svs.challenges[i].challenge )
break; // good break;
}
} }
} }
if (i == MAX_CHALLENGES) { if (i == MAX_CHALLENGES) {

View file

@ -252,7 +252,7 @@ void SV_MasterHeartbeat( void ) {
sv_master[i]->modified = qfalse; sv_master[i]->modified = qfalse;
Com_Printf( "Resolving %s\n", sv_master[i]->string ); Com_Printf( "Resolving %s\n", sv_master[i]->string );
if ( !NET_StringToAdr( sv_master[i]->string, &adr[i] ) ) { if ( !NET_StringToAdr( sv_master[i]->string, &adr[i], NA_IP ) ) {
// if the address failed to resolve, clear it // if the address failed to resolve, clear it
// so we don't take repeated dns hits // so we don't take repeated dns hits
Com_Printf( "Couldn't resolve address: %s\n", sv_master[i]->string ); Com_Printf( "Couldn't resolve address: %s\n", sv_master[i]->string );