From 884e8a547b3bb1d680c96a8779914ee4954f5b8e Mon Sep 17 00:00:00 2001 From: Hanicef Date: Tue, 23 Jan 2024 22:16:04 +0100 Subject: [PATCH 1/5] Add -noipv4 flag --- src/netcode/http-mserv.c | 104 ++++++++++++++++++++++++++------------- src/netcode/i_tcp.c | 77 ++++++++++++++++------------- 2 files changed, 111 insertions(+), 70 deletions(-) diff --git a/src/netcode/http-mserv.c b/src/netcode/http-mserv.c index 2b52380cf..cd3e353dc 100644 --- a/src/netcode/http-mserv.c +++ b/src/netcode/http-mserv.c @@ -63,7 +63,9 @@ consvar_t cv_masterserver_token = CVAR_INIT static int hms_started; +static boolean hms_args_checked; static boolean hms_allow_ipv6; +static boolean hms_allow_ipv4; static char *hms_api; #ifdef HAVE_THREADS @@ -134,6 +136,16 @@ HMS_on_read (char *s, size_t _1, size_t n, void *userdata) return n; } +static void HMS_check_args_once(void) +{ + if (hms_args_checked) + return; + + hms_allow_ipv6 = !M_CheckParm("-noipv6"); + hms_allow_ipv4 = !M_CheckParm("-noipv4"); + hms_args_checked = true; +} + static struct HMS_buffer * HMS_connect (int proto, const char *format, ...) { @@ -152,7 +164,6 @@ HMS_connect (int proto, const char *format, ...) if (! hms_started) { - hms_allow_ipv6 = !M_CheckParm("-noipv6"); if (curl_global_init(CURL_GLOBAL_ALL) != 0) { Contact_error(); @@ -234,9 +245,9 @@ HMS_connect (int proto, const char *format, ...) curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); #ifndef NO_IPV6 - if (proto == PROTO_V6) + if (proto == PROTO_V6 || (proto == PROTO_ANY && !hms_allow_ipv4)) curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V6); - if (proto == PROTO_V4) + if (proto == PROTO_V4 || (proto == PROTO_ANY && !hms_allow_ipv6)) #endif curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); @@ -326,6 +337,8 @@ HMS_fetch_rooms (int joining, int query_id) (void)query_id; + HMS_check_args_once(); + hms = HMS_connect(PROTO_ANY, "rooms"); if (! hms) @@ -420,18 +433,15 @@ int HMS_register (void) { struct HMS_buffer *hms; - int ok; + int ok = 0; char post[256]; char *title; - hms = HMS_connect(PROTO_V4, "rooms/%d/register", ms_RoomId); + HMS_check_args_once(); - if (! hms) - return 0; - - title = curl_easy_escape(hms->curl, cv_servername.string, 0); + title = curl_easy_escape(NULL, cv_servername.string, 0); snprintf(post, sizeof post, "port=%d&" @@ -447,16 +457,24 @@ HMS_register (void) curl_free(title); - curl_easy_setopt(hms->curl, CURLOPT_POSTFIELDS, post); - - ok = HMS_do(hms); - - if (ok) + if (hms_allow_ipv4) { - hms_server_token = strdup(strtok(hms->buffer, "\n")); - } + hms = HMS_connect(PROTO_V4, "rooms/%d/register", ms_RoomId); - HMS_end(hms); + if (! hms) + return 0; + + curl_easy_setopt(hms->curl, CURLOPT_POSTFIELDS, post); + + ok = HMS_do(hms); + + if (ok) + { + hms_server_token = strdup(strtok(hms->buffer, "\n")); + } + + HMS_end(hms); + } #ifndef NO_IPV6 if (!hms_allow_ipv6) @@ -486,20 +504,25 @@ int HMS_unlist (void) { struct HMS_buffer *hms; - int ok; + int ok = 0; - hms = HMS_connect(PROTO_V4, "servers/%s/unlist", hms_server_token); + HMS_check_args_once(); - if (! hms) - return 0; + if (hms_server_token && hms_allow_ipv4) + { + hms = HMS_connect(PROTO_V4, "servers/%s/unlist", hms_server_token); - curl_easy_setopt(hms->curl, CURLOPT_POST, 1); - curl_easy_setopt(hms->curl, CURLOPT_POSTFIELDSIZE, 0); + if (! hms) + return 0; - ok = HMS_do(hms); - HMS_end(hms); + curl_easy_setopt(hms->curl, CURLOPT_POST, 1); + curl_easy_setopt(hms->curl, CURLOPT_POSTFIELDSIZE, 0); - free(hms_server_token); + ok = HMS_do(hms); + HMS_end(hms); + + free(hms_server_token); + } #ifndef NO_IPV6 if (hms_server_token_ipv6 && hms_allow_ipv6) @@ -526,18 +549,15 @@ int HMS_update (void) { struct HMS_buffer *hms; - int ok; + int ok = 0; char post[256]; char *title; - hms = HMS_connect(PROTO_V4, "servers/%s/update", hms_server_token); + HMS_check_args_once(); - if (! hms) - return 0; - - title = curl_easy_escape(hms->curl, cv_servername.string, 0); + title = curl_easy_escape(NULL, cv_servername.string, 0); snprintf(post, sizeof post, "title=%s", @@ -546,10 +566,18 @@ HMS_update (void) curl_free(title); - curl_easy_setopt(hms->curl, CURLOPT_POSTFIELDS, post); + if (hms_server_token && hms_allow_ipv4) + { + hms = HMS_connect(PROTO_V4, "servers/%s/update", hms_server_token); - ok = HMS_do(hms); - HMS_end(hms); + if (! hms) + return 0; + + curl_easy_setopt(hms->curl, CURLOPT_POSTFIELDS, post); + + ok = HMS_do(hms); + HMS_end(hms); + } #ifndef NO_IPV6 if (hms_server_token_ipv6 && hms_allow_ipv6) @@ -577,6 +605,8 @@ HMS_list_servers (void) char *list; char *p; + HMS_check_args_once(); + hms = HMS_connect(PROTO_ANY, "servers"); if (! hms) @@ -622,6 +652,8 @@ HMS_fetch_servers (msg_server_t *list, int room_number, int query_id) int i; + HMS_check_args_once(); + (void)query_id; if (room_number > 0) @@ -733,6 +765,8 @@ HMS_compare_mod_version (char *buffer, size_t buffer_size) char *version; char *version_name; + HMS_check_args_once(); + hms = HMS_connect(PROTO_ANY, "versions/%d", MODID); if (! hms) diff --git a/src/netcode/i_tcp.c b/src/netcode/i_tcp.c index 6d9a2725a..86cf83d02 100644 --- a/src/netcode/i_tcp.c +++ b/src/netcode/i_tcp.c @@ -908,6 +908,7 @@ static boolean UDP_Socket(void) #ifdef HAVE_IPV6 const INT32 b_ipv6 = !M_CheckParm("-noipv6"); #endif + const INT32 b_ipv4 = !M_CheckParm("-noipv4"); const char *serv; @@ -929,11 +930,34 @@ static boolean UDP_Socket(void) else serv = clientport_name; - if (M_CheckParm("-bindaddr")) + if (b_ipv4) { - while (M_IsNextParm()) + if (M_CheckParm("-bindaddr")) { - gaie = I_getaddrinfo(M_GetNextParm(), serv, &hints, &ai); + while (M_IsNextParm()) + { + gaie = I_getaddrinfo(M_GetNextParm(), serv, &hints, &ai); + if (gaie == 0) + { + runp = ai; + while (runp != NULL && s < MAXNETNODES+1) + { + mysockets[s] = UDP_Bind(runp->ai_family, runp->ai_addr, (socklen_t)runp->ai_addrlen); + if (mysockets[s] != (SOCKET_TYPE)ERRSOCKET) + { + FD_SET(mysockets[s], &masterset); + myfamily[s] = hints.ai_family; + s++; + } + runp = runp->ai_next; + } + I_freeaddrinfo(ai); + } + } + } + else + { + gaie = I_getaddrinfo("0.0.0.0", serv, &hints, &ai); if (gaie == 0) { runp = ai; @@ -945,6 +969,13 @@ static boolean UDP_Socket(void) FD_SET(mysockets[s], &masterset); myfamily[s] = hints.ai_family; s++; +#ifdef HAVE_MINIUPNPC + if (UPNP_support) + { + I_UPnP_rem(serverport_name, "UDP"); + I_UPnP_add(NULL, serverport_name, "UDP"); + } +#endif } runp = runp->ai_next; } @@ -952,33 +983,6 @@ static boolean UDP_Socket(void) } } } - else - { - gaie = I_getaddrinfo("0.0.0.0", serv, &hints, &ai); - if (gaie == 0) - { - runp = ai; - while (runp != NULL && s < MAXNETNODES+1) - { - mysockets[s] = UDP_Bind(runp->ai_family, runp->ai_addr, (socklen_t)runp->ai_addrlen); - if (mysockets[s] != (SOCKET_TYPE)ERRSOCKET) - { - FD_SET(mysockets[s], &masterset); - myfamily[s] = hints.ai_family; - s++; -#ifdef HAVE_MINIUPNPC - if (UPNP_support) - { - I_UPnP_rem(serverport_name, "UDP"); - I_UPnP_add(NULL, serverport_name, "UDP"); - } -#endif - } - runp = runp->ai_next; - } - I_freeaddrinfo(ai); - } - } #ifdef HAVE_IPV6 if (b_ipv6) { @@ -1045,11 +1049,14 @@ static boolean UDP_Socket(void) s = 0; - // setup broadcast adress to BROADCASTADDR entry - broadcastaddress[s].any.sa_family = AF_INET; - broadcastaddress[s].ip4.sin_port = htons(atoi(DEFAULTPORT)); - broadcastaddress[s].ip4.sin_addr.s_addr = htonl(INADDR_BROADCAST); - s++; + if (b_ipv4) + { + // setup broadcast adress to BROADCASTADDR entry + broadcastaddress[s].any.sa_family = AF_INET; + broadcastaddress[s].ip4.sin_port = htons(atoi(DEFAULTPORT)); + broadcastaddress[s].ip4.sin_addr.s_addr = htonl(INADDR_BROADCAST); + s++; + } #ifdef HAVE_IPV6 if (b_ipv6) From 1278bc5727073dab26238ce9ab354ac4702bba4e Mon Sep 17 00:00:00 2001 From: Alam Ed Arias Date: Mon, 3 Feb 2025 01:02:57 +0000 Subject: [PATCH 2/5] Update i_tcp.c Do not error out if we don't have a socket for an address family we have disabled --- src/netcode/i_tcp.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/netcode/i_tcp.c b/src/netcode/i_tcp.c index 18c90582e..63d232f0c 100644 --- a/src/netcode/i_tcp.c +++ b/src/netcode/i_tcp.c @@ -655,6 +655,7 @@ static inline ssize_t SOCK_SendToAddr(SOCKET_TYPE socket, mysockaddr_t *sockaddr static void SOCK_Send(void) { ssize_t c = ERRSOCKET; + int e = -1; // save error code so it can't be modified later code and avoid calling WSAGetLastError() more then once if (!nodeconnected[doomcom->remotenode]) return; @@ -668,8 +669,12 @@ static void SOCK_Send(void) if (myfamily[i] == broadcastaddress[j].any.sa_family) { c = SOCK_SendToAddr(mysockets[i], &broadcastaddress[j]); - if (c == ERRSOCKET && !ALLOWEDERROR(errno)) - break; + if (c == ERRSOCKET) + { + e = errno; + if (!ALLOWEDERROR(e)) + break; + } } } } @@ -681,19 +686,26 @@ static void SOCK_Send(void) if (myfamily[i] == clientaddress[doomcom->remotenode].any.sa_family) { c = SOCK_SendToAddr(mysockets[i], &clientaddress[doomcom->remotenode]); - if (c == ERRSOCKET && !ALLOWEDERROR(errno)) - break; + if (c == ERRSOCKET) + { + e = errno; + if (!ALLOWEDERROR(e)) + break; + } } } } else { c = SOCK_SendToAddr(nodesocket[doomcom->remotenode], &clientaddress[doomcom->remotenode]); + if (c == ERRSOCKET) + { + e = errno; + } } - if (c == ERRSOCKET) + if (c == ERRSOCKET && e != -1) // -1 means no socket for the address family was found { - int e = errno; // save error code so it can't be modified later if (!ALLOWEDERROR(e)) I_Error("SOCK_Send, error sending to node %d (%s) #%u: %s", doomcom->remotenode, SOCK_GetNodeAddress(doomcom->remotenode), e, strerror(e)); From 0fe8c7a57afa84fba92772b22cf42025ddd18b07 Mon Sep 17 00:00:00 2001 From: Alam Ed Arias Date: Sun, 2 Feb 2025 22:29:23 -0500 Subject: [PATCH 3/5] Update m_menu.c Add check netgame check if someone use both -noipv4 and -noipv6 --- src/m_menu.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/m_menu.c b/src/m_menu.c index 37d191a0d..be1b421f7 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -3892,6 +3892,9 @@ void M_Ticker(void) M_SetupScreenshotMenu(); #if defined (MASTERSERVER) && defined (HAVE_THREADS) + if (!netgame) + return; + I_lock_mutex(&ms_ServerList_mutex); { if (ms_ServerList) From 598307f33851d5c1bcc148118686838d0e1c909e Mon Sep 17 00:00:00 2001 From: Alam Ed Arias Date: Sun, 2 Feb 2025 22:50:17 -0500 Subject: [PATCH 4/5] Only check for -noipv6 on IPv6 builds in HTTP code --- src/netcode/http-mserv.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/netcode/http-mserv.c b/src/netcode/http-mserv.c index 5f3490cac..0c96561ef 100644 --- a/src/netcode/http-mserv.c +++ b/src/netcode/http-mserv.c @@ -64,7 +64,9 @@ consvar_t cv_masterserver_token = CVAR_INIT static int hms_started; static boolean hms_args_checked; +#ifndef NO_IPV6 static boolean hms_allow_ipv6; +#endif static boolean hms_allow_ipv4; static char *hms_api; @@ -141,7 +143,9 @@ static void HMS_check_args_once(void) if (hms_args_checked) return; +#ifndef NO_IPV6 hms_allow_ipv6 = !M_CheckParm("-noipv6"); +#endif hms_allow_ipv4 = !M_CheckParm("-noipv4"); hms_args_checked = true; } From ebfea6de0cfc6d98b1a69b7a2b72cd818b1e82fa Mon Sep 17 00:00:00 2001 From: Alam Ed Arias Date: Sun, 2 Feb 2025 22:50:59 -0500 Subject: [PATCH 5/5] use -bindaddr6 for mserv PROTO_V6 calls --- src/netcode/http-mserv.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/netcode/http-mserv.c b/src/netcode/http-mserv.c index 0c96561ef..0fe1e9934 100644 --- a/src/netcode/http-mserv.c +++ b/src/netcode/http-mserv.c @@ -240,20 +240,27 @@ HMS_connect (int proto, const char *format, ...) curl_easy_setopt(curl, CURLOPT_STDERR, logstream); } - if (M_CheckParm("-bindaddr") && M_IsNextParm()) - { - curl_easy_setopt(curl, CURLOPT_INTERFACE, M_GetNextParm()); - } - curl_easy_setopt(curl, CURLOPT_URL, url); curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); #ifndef NO_IPV6 if (proto == PROTO_V6 || (proto == PROTO_ANY && !hms_allow_ipv4)) + { curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V6); + if (M_CheckParm("-bindaddr6") && M_IsNextParm()) + { + curl_easy_setopt(curl, CURLOPT_INTERFACE, M_GetNextParm()); + } + } if (proto == PROTO_V4 || (proto == PROTO_ANY && !hms_allow_ipv6)) #endif + { curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); + if (M_CheckParm("-bindaddr") && M_IsNextParm()) + { + curl_easy_setopt(curl, CURLOPT_INTERFACE, M_GetNextParm()); + } + } curl_easy_setopt(curl, CURLOPT_TIMEOUT, cv_masterserver_timeout.value); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, HMS_on_read);