diff --git a/engine/common/net_ws.c b/engine/common/net_ws.c index de05146a..35106b69 100644 --- a/engine/common/net_ws.c +++ b/engine/common/net_ws.c @@ -2553,7 +2553,13 @@ void HTTP_Run( void ) { dword mode; - curfile->socket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP ); + // IPv6 + if ( Q_strstr( curfile->server->host, ":" )) + curfile->socket = socket( AF_INET6, SOCK_STREAM, IPPROTO_TCP ); + + // IPv4 + else + curfile->socket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP ); // Now set non-blocking mode // You may skip this if not supported by system, @@ -2575,9 +2581,21 @@ void HTTP_Run( void ) if( fResolving ) continue; - Q_snprintf( hostport, sizeof( hostport ), "%s:%d", curfile->server->host, curfile->server->port ); + // IPv6 + if ( Q_strstr( curfile->server->host, ":" )) + { + Q_snprintf( hostport, sizeof( hostport ), "[%s]:%d", curfile->server->host, curfile->server->port ); - res = NET_StringToSockaddr( hostport, &addr, true, AF_INET ); + res = NET_StringToSockaddr( hostport, &addr, true, AF_INET6 ); + } + + // IPv4 + else + { + Q_snprintf( hostport, sizeof( hostport ), "%s:%d", curfile->server->host, curfile->server->port ); + + res = NET_StringToSockaddr( hostport, &addr, true, AF_INET ); + } if( res == NET_EAI_AGAIN ) { @@ -2780,24 +2798,43 @@ HTTP_ParseURL */ static httpserver_t *HTTP_ParseURL( const char *url ) { - httpserver_t *server; - int i; + httpserver_t *server = Z_Calloc( sizeof( httpserver_t )); + int i = 0; - url = Q_strstr( url, "http://" ); - - if( !url ) - return NULL; - - url += 7; - server = Z_Calloc( sizeof( httpserver_t )); - i = 0; - - while( *url && ( *url != ':' ) && ( *url != '/' ) && ( *url != '\r' ) && ( *url != '\n' )) + // IPv6 + if( Q_strstr( url, "http://[" ) ) { - if( i > sizeof( server->host )) - return NULL; + url += 8; - server->host[i++] = *url++; + while( *url && ( *url != ']' )) + { + if( i > sizeof( server->host )) + return NULL; + + server->host[i++] = *url++; + } + + url++; // skip closing entity + } + + // IPv4 + else + { + if( Q_strstr( url, "http://" ) ) + { + url += 7; + + while( *url && ( *url != ':' ) && ( *url != '/' ) && ( *url != '\r' ) && ( *url != '\n' )) + { + if( i > sizeof( server->host )) + return NULL; + + server->host[i++] = *url++; + } + } + + else + return NULL; } server->host[i] = 0; diff --git a/engine/server/server.h b/engine/server/server.h index b7f40ff7..684d50e8 100644 --- a/engine/server/server.h +++ b/engine/server/server.h @@ -414,6 +414,7 @@ extern convar_t sv_maxupdaterate; extern convar_t sv_minrate; extern convar_t sv_maxrate; extern convar_t sv_downloadurl; +extern convar_t sv_downloadurl_ipv6; extern convar_t sv_newunit; extern convar_t sv_clienttrace; extern convar_t sv_failuretime; diff --git a/engine/server/sv_custom.c b/engine/server/sv_custom.c index f18ad6a3..a5ce12ff 100644 --- a/engine/server/sv_custom.c +++ b/engine/server/sv_custom.c @@ -562,7 +562,14 @@ void SV_SendResources( sv_client_t *cl, sizebuf_t *msg ) MSG_WriteLong( msg, svs.spawncount ); MSG_WriteLong( msg, 0 ); - if( COM_CheckString( sv_downloadurl.string ) && Q_strlen( sv_downloadurl.string ) < 256 ) + if ( cl->netchan.remote_address.type6 == NA_IP6 && // If remote is IPv6 - check for sv_downloadurl_ipv6 first #1559 + COM_CheckString( sv_downloadurl_ipv6.string ) && Q_strlen( sv_downloadurl_ipv6.string ) < 256 ) + { + MSG_BeginServerCmd( msg, svc_resourcelocation ); + MSG_WriteString( msg, sv_downloadurl_ipv6.string ); + } + + else if ( COM_CheckString( sv_downloadurl.string ) && Q_strlen( sv_downloadurl.string ) < 256 ) { MSG_BeginServerCmd( msg, svc_resourcelocation ); MSG_WriteString( msg, sv_downloadurl.string ); diff --git a/engine/server/sv_main.c b/engine/server/sv_main.c index 5a67303d..c4b47f89 100644 --- a/engine/server/sv_main.c +++ b/engine/server/sv_main.c @@ -52,7 +52,8 @@ CVAR_DEFINE_AUTO( sv_allow_upload, "1", FCVAR_SERVER, "allow uploading custom re CVAR_DEFINE( sv_allow_download, "sv_allowdownload", "1", FCVAR_SERVER, "allow downloading custom resources to the client" ); static CVAR_DEFINE_AUTO( sv_allow_dlfile, "1", 0, "compatibility cvar, does nothing" ); CVAR_DEFINE_AUTO( sv_uploadmax, "0.5", FCVAR_SERVER, "max size to upload custom resources (500 kB as default)" ); -CVAR_DEFINE_AUTO( sv_downloadurl, "", FCVAR_PROTECTED, "location from which clients can download missing files" ); +CVAR_DEFINE_AUTO( sv_downloadurl, "", FCVAR_PROTECTED, "IPv4 location from which clients can download missing files (applying for IPv4 connections" ); +CVAR_DEFINE_AUTO( sv_downloadurl_ipv6, "", FCVAR_PROTECTED, "IPv6 location from which clients can download missing files (applying for IPv6 connections)" ); CVAR_DEFINE( sv_consistency, "mp_consistency", "1", FCVAR_SERVER, "enbale consistency check in multiplayer" ); CVAR_DEFINE_AUTO( mp_logecho, "1", 0, "log multiplayer frags to server logfile" ); CVAR_DEFINE_AUTO( mp_logfile, "1", 0, "log multiplayer frags to console" ); @@ -934,6 +935,7 @@ void SV_Init( void ) Cvar_RegisterVariable( &sv_instancedbaseline ); Cvar_RegisterVariable( &sv_consistency ); Cvar_RegisterVariable( &sv_downloadurl ); + Cvar_RegisterVariable( &sv_downloadurl_ipv6 ); Cvar_RegisterVariable( &sv_novis ); Cvar_RegisterVariable( &sv_hostmap ); Cvar_DirectSet( &sv_hostmap, GI->startmap );