From 7ff3e599a0075b97eb91e754cf222594f7107d4a Mon Sep 17 00:00:00 2001 From: ghost Date: Mon, 15 Jan 2024 11:04:12 +0200 Subject: [PATCH 1/5] init sv_downloadurl_ipv6 support #1559 --- engine/common/net_ws.c | 61 +++++++++++++++++++++++++++++++++++++++ engine/server/server.h | 1 + engine/server/sv_custom.c | 7 ++++- engine/server/sv_main.c | 2 ++ 4 files changed, 70 insertions(+), 1 deletion(-) diff --git a/engine/common/net_ws.c b/engine/common/net_ws.c index de05146a..6ea8ad47 100644 --- a/engine/common/net_ws.c +++ b/engine/common/net_ws.c @@ -2829,6 +2829,63 @@ static httpserver_t *HTTP_ParseURL( const char *url ) return server; } + +/* +================== +HTTP_ParseURL_IPv6 +================== +*/ +static httpserver_t *HTTP_ParseURL_IPv6( const char *url ) +{ + httpserver_t *server; + int i; + + url = Q_strstr( url, "http://[" ); + + if( !url ) + return NULL; + + url += 8; + server = Z_Calloc( sizeof( httpserver_t )); + i = 0; + + while( *url && ( *url != ']' ) && ( *url != '/' ) && ( *url != '\r' ) && ( *url != '\n' )) + { + if( i > sizeof( server->host )) + return NULL; + + server->host[i++] = *url++; + } + + server->host[i] = 0; + + if( *url == ':' ) + { + server->port = Q_atoi( ++url ); + + while( *url && ( *url != '/' ) && ( *url != '\r' ) && ( *url != '\n' )) + url++; + } + else + server->port = 80; + + i = 0; + + while( *url && ( *url != '\r' ) && ( *url != '\n' )) + { + if( i > sizeof( server->path )) + return NULL; + + server->path[i++] = *url++; + } + + server->path[i] = 0; + server->next = NULL; + server->needfree = false; + + return server; +} + /* ======================= HTTP_AddCustomServer @@ -2836,6 +2893,8 @@ HTTP_AddCustomServer */ void HTTP_AddCustomServer( const char *url ) { + // todo condition + // httpserver_t *server = HTTP_ParseURL_IPv6( url ); httpserver_t *server = HTTP_ParseURL( url ); if( !server ) @@ -2996,6 +3055,8 @@ void HTTP_Init( void ) { while(( line = COM_ParseFile( line, token, sizeof( token )))) { + // todo condition + // httpserver_t *server = HTTP_ParseURL_IPv6( token ); httpserver_t *server = HTTP_ParseURL( token ); if( !server ) 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..164eb1a8 100644 --- a/engine/server/sv_custom.c +++ b/engine/server/sv_custom.c @@ -562,7 +562,12 @@ 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 ( 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..3129b65f 100644 --- a/engine/server/sv_main.c +++ b/engine/server/sv_main.c @@ -53,6 +53,7 @@ CVAR_DEFINE( sv_allow_download, "sv_allowdownload", "1", FCVAR_SERVER, "allow do 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_ipv6, "", FCVAR_PROTECTED, "IPv6 location from which clients can download missing files (higher priority)" ); 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 ); From 97112f2780d501505681e577d6b9e00724ed4144 Mon Sep 17 00:00:00 2001 From: ghost Date: Mon, 15 Jan 2024 11:22:19 +0200 Subject: [PATCH 2/5] update option comment #1559 --- engine/server/sv_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/engine/server/sv_main.c b/engine/server/sv_main.c index 3129b65f..c4b47f89 100644 --- a/engine/server/sv_main.c +++ b/engine/server/sv_main.c @@ -52,8 +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_ipv6, "", FCVAR_PROTECTED, "IPv6 location from which clients can download missing files (higher priority)" ); +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" ); From f3e4497b58a256167086e6a980a572a1d7816a9c Mon Sep 17 00:00:00 2001 From: ghost Date: Mon, 15 Jan 2024 12:53:24 +0200 Subject: [PATCH 3/5] make HTTP_ParseURL compatible with IPv4/IPv6 #1559 --- engine/common/net_ws.c | 98 ++++++++++++------------------------------ 1 file changed, 27 insertions(+), 71 deletions(-) diff --git a/engine/common/net_ws.c b/engine/common/net_ws.c index 6ea8ad47..87402ae7 100644 --- a/engine/common/net_ws.c +++ b/engine/common/net_ws.c @@ -2780,81 +2780,41 @@ 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 != ']' ) && ( *url != '/' ) && ( *url != '\r' ) && ( *url != '\n' )) + { + if( i > sizeof( server->host )) + return NULL; + + server->host[i++] = *url++; + } } - server->host[i] = 0; - - if( *url == ':' ) - { - server->port = Q_atoi( ++url ); - - while( *url && ( *url != '/' ) && ( *url != '\r' ) && ( *url != '\n' )) - url++; - } + // IPv4 else - server->port = 80; - - i = 0; - - while( *url && ( *url != '\r' ) && ( *url != '\n' )) { - if( i > sizeof( server->path )) + 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->path[i++] = *url++; - } - - server->path[i] = 0; - server->next = NULL; - server->needfree = false; - - return server; -} - - -/* -================== -HTTP_ParseURL_IPv6 -================== -*/ -static httpserver_t *HTTP_ParseURL_IPv6( const char *url ) -{ - httpserver_t *server; - int i; - - url = Q_strstr( url, "http://[" ); - - if( !url ) - return NULL; - - url += 8; - server = Z_Calloc( sizeof( httpserver_t )); - i = 0; - - while( *url && ( *url != ']' ) && ( *url != '/' ) && ( *url != '\r' ) && ( *url != '\n' )) - { - if( i > sizeof( server->host )) - return NULL; - - server->host[i++] = *url++; } server->host[i] = 0; @@ -2893,8 +2853,6 @@ HTTP_AddCustomServer */ void HTTP_AddCustomServer( const char *url ) { - // todo condition - // httpserver_t *server = HTTP_ParseURL_IPv6( url ); httpserver_t *server = HTTP_ParseURL( url ); if( !server ) @@ -3055,8 +3013,6 @@ void HTTP_Init( void ) { while(( line = COM_ParseFile( line, token, sizeof( token )))) { - // todo condition - // httpserver_t *server = HTTP_ParseURL_IPv6( token ); httpserver_t *server = HTTP_ParseURL( token ); if( !server ) From 1ffd84b1ee72c601411289a65d7563f88f06695b Mon Sep 17 00:00:00 2001 From: ghost Date: Mon, 15 Jan 2024 14:36:49 +0200 Subject: [PATCH 4/5] complete client-side IPv6 support #1559 --- engine/common/net_ws.c | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/engine/common/net_ws.c b/engine/common/net_ws.c index 87402ae7..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 ) { @@ -2788,13 +2806,15 @@ static httpserver_t *HTTP_ParseURL( const char *url ) { url += 8; - while( *url && ( *url != ']' ) && ( *url != '/' ) && ( *url != '\r' ) && ( *url != '\n' )) + while( *url && ( *url != ']' )) { if( i > sizeof( server->host )) return NULL; server->host[i++] = *url++; } + + url++; // skip closing entity } // IPv4 From dcf3eb8f8949b82f752b7782cea3ada50473f3aa Mon Sep 17 00:00:00 2001 From: ghost Date: Mon, 15 Jan 2024 18:30:12 +0200 Subject: [PATCH 5/5] add server-side sv_downloadurl_ipv6 support #1559 --- engine/server/sv_custom.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/engine/server/sv_custom.c b/engine/server/sv_custom.c index 164eb1a8..a5ce12ff 100644 --- a/engine/server/sv_custom.c +++ b/engine/server/sv_custom.c @@ -562,12 +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_ipv6.string ) && Q_strlen( sv_downloadurl_ipv6.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 ) + + else if ( COM_CheckString( sv_downloadurl.string ) && Q_strlen( sv_downloadurl.string ) < 256 ) { MSG_BeginServerCmd( msg, svc_resourcelocation ); MSG_WriteString( msg, sv_downloadurl.string );