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 );
SCR_UpdateScreen();
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
CL_CheckForResend();
@ -808,7 +808,7 @@ CL_UpdateGUID
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;
int len;
@ -941,7 +941,7 @@ void CL_RequestMotd( void ) {
return;
}
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" );
return;
}
@ -1011,7 +1011,7 @@ void CL_RequestAuthorization( void ) {
if ( !cls.authorizeServer.port ) {
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" );
return;
}
@ -1145,13 +1145,29 @@ CL_Connect_f
*/
void CL_Connect_f( void ) {
char *server;
char serverString[ 22 ];
const char *serverString;
int argc = Cmd_Argc();
netadrtype_t family = NA_UNSPEC;
if ( Cmd_Argc() != 2 ) {
Com_Printf( "usage: connect [server]\n");
if ( argc != 2 && argc != 3 ) {
Com_Printf( "usage: connect [-4|-6] server\n");
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");
// fire a message off to the motd server
@ -1160,8 +1176,6 @@ void CL_Connect_f( void ) {
// clear any previous "server full" type messages
clc.serverMessage[0] = 0;
server = Cmd_Argv (1);
if ( com_sv_running->integer && !strcmp( server, "localhost" ) ) {
// if running a local server, kill it
SV_Shutdown( "Server quit" );
@ -1180,7 +1194,7 @@ void CL_Connect_f( void ) {
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");
cls.state = CA_DISCONNECTED;
return;
@ -1188,10 +1202,8 @@ void CL_Connect_f( void ) {
if (clc.serverAddress.port == 0) {
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 ) );
serverString = NET_AdrToStringwPort(clc.serverAddress);
Com_Printf( "%s resolved to %s\n", cls.servername, serverString);
@ -1260,7 +1272,7 @@ void CL_Rcon_f( void ) {
return;
}
NET_StringToAdr (rconAddress->string, &to);
NET_StringToAdr (rconAddress->string, &to, NA_UNSPEC);
if (to.port == 0) {
to.port = BigShort (PORT_SERVER);
}
@ -1697,8 +1709,8 @@ void CL_CheckForResend( void ) {
switch ( cls.state ) {
case CA_CONNECTING:
// requesting a challenge
if ( !Sys_IsLANAddress( clc.serverAddress ) ) {
// requesting a challenge .. IPv6 users always get in as authorize server supports no ipv6.
if ( clc.serverAddress.type == NA_IP && !Sys_IsLANAddress( clc.serverAddress ) ) {
CL_RequestAuthorization();
}
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
if ( !Q_stricmp(c, "challengeResponse") ) {
if ( cls.state != CA_CONNECTING ) {
Com_Printf( "Unwanted challenge response received. Ignored.\n" );
Com_DPrintf( "Unwanted challenge response received. Ignored.\n" );
} else {
// start sending challenge repsonse instead of challenge request packets
clc.challenge = atoi(Cmd_Argv(1));
@ -3059,7 +3071,7 @@ int CL_ServerStatus( char *serverAddress, char *serverStatusString, int maxLen )
return qfalse;
}
// get the address
if ( !NET_StringToAdr( serverAddress, &to ) ) {
if ( !NET_StringToAdr( serverAddress, &to, NA_UNSPEC) ) {
return qfalse;
}
serverStatus = CL_GetServerStatus( to );
@ -3262,7 +3274,7 @@ void CL_GlobalServers_f( void ) {
// reset the list, waiting for 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 ) {
cls.nummplayerservers = -1;
@ -3465,17 +3477,33 @@ void CL_Ping_f( void ) {
netadr_t to;
ping_t* pingptr;
char* server;
int argc;
netadrtype_t family = NA_UNSPEC;
if ( Cmd_Argc() != 2 ) {
Com_Printf( "usage: ping [server]\n");
argc = Cmd_Argc();
if ( argc != 2 && argc != 3 ) {
Com_Printf( "usage: ping [-4|-6] server\n");
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) );
server = Cmd_Argv(1);
if ( !NET_StringToAdr( server, &to ) ) {
if ( !NET_StringToAdr( server, &to, family ) ) {
return;
}
@ -3603,32 +3631,53 @@ CL_ServerStatus_f
==================
*/
void CL_ServerStatus_f(void) {
netadr_t to;
netadr_t to, *toptr = NULL;
char *server;
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) );
if ( Cmd_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 {
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);
}
if ( !NET_StringToAdr( server, &to ) ) {
toptr = &to;
if ( !NET_StringToAdr( server, toptr, family ) )
return;
}
NET_OutOfBandPrint( NS_CLIENT, to, "getstatus" );
NET_OutOfBandPrint( NS_CLIENT, *toptr, "getstatus" );
serverStatus = CL_GetServerStatus( to );
serverStatus->address = to;
serverStatus = CL_GetServerStatus( *toptr );
serverStatus->address = *toptr;
serverStatus->print = qtrue;
serverStatus->pending = qtrue;
}

View file

@ -156,7 +156,7 @@ static int LAN_AddServer(int source, const char *name, const char *address) {
break;
}
if (servers && *count < max) {
NET_StringToAdr( address, &adr );
NET_StringToAdr( address, &adr, NA_IP );
for ( i = 0; i < *count; i++ ) {
if (NET_CompareAdr(servers[i].adr, adr)) {
break;
@ -203,7 +203,7 @@ static void LAN_RemoveServer(int source, const char *addr) {
}
if (servers) {
netadr_t comp;
NET_StringToAdr( addr, &comp );
NET_StringToAdr( addr, &comp, NA_IP );
for (i = 0; i < *count; i++) {
if (NET_CompareAdr( comp, servers[i].adr)) {
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
=============
*/
qboolean NET_StringToAdr( const char *s, netadr_t *a ) {
qboolean NET_StringToAdr( const char *s, netadr_t *a, netadrtype_t family ) {
qboolean r;
char base[MAX_STRING_CHARS];
char *port;
char base[MAX_STRING_CHARS], *search;
char *port = NULL;
if (!strcmp (s, "localhost")) {
Com_Memset (a, 0, sizeof(*a));
@ -756,21 +688,37 @@ qboolean NET_StringToAdr( const char *s, netadr_t *a ) {
// look for a port number
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 ) {
*port = 0;
*port = '\0';
port++;
}
r = Sys_StringToAdr( base, a );
if ( !r ) {
a->type = NA_BAD;
return qfalse;
search = base;
}
// inet_addr returns this if out of range
if ( a->ip[0] == 255 && a->ip[1] == 255 && a->ip[2] == 255 && a->ip[3] == 255 ) {
r = Sys_StringToAdr( search, a, family );
if ( !r ) {
a->type = NA_BAD;
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_LOOPBACK,
NA_BROADCAST,
NA_IP
NA_IP,
NA_IP6,
NA_UNSPEC
} netadrtype_t;
typedef enum {
@ -144,10 +146,12 @@ typedef enum {
NS_SERVER
} netsrc_t;
#define NET_ADDRSTRMAXLEN 48 // maximum length of an IPv6 address string including trailing '\0'
typedef struct {
netadrtype_t type;
byte ip[4];
byte ip6[16];
unsigned short port;
} 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_IsLocalAddress (netadr_t adr);
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);
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 );
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.
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
if ( !svs.authorizeAddress.ip[0] && svs.authorizeAddress.type != NA_BAD ) {
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" );
return;
}
@ -487,7 +487,7 @@ static void SV_BanNum_f( void ) {
// look up the authorize server's IP
if ( !svs.authorizeAddress.ip[0] && svs.authorizeAddress.type != NA_BAD ) {
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" );
return;
}

View file

@ -88,10 +88,13 @@ void SV_GetChallenge( netadr_t from ) {
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
if ( !svs.authorizeAddress.ip[0] && svs.authorizeAddress.type != NA_BAD ) {
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" );
return;
}
@ -134,6 +137,14 @@ void SV_GetChallenge( netadr_t from ) {
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++) {
if (NET_CompareAdr(from, svs.challenges[i].adr)) {
if ( challenge == svs.challenges[i].challenge ) {
break; // good
}
if ( challenge == svs.challenges[i].challenge )
break;
}
}
if (i == MAX_CHALLENGES) {

View file

@ -252,7 +252,7 @@ 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] ) ) {
if ( !NET_StringToAdr( sv_master[i]->string, &adr[i], NA_IP ) ) {
// 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 );