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) diff --git a/src/netcode/http-mserv.c b/src/netcode/http-mserv.c index 8ce20af95..0fe1e9934 100644 --- a/src/netcode/http-mserv.c +++ b/src/netcode/http-mserv.c @@ -63,7 +63,11 @@ 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; #ifdef HAVE_THREADS @@ -134,6 +138,18 @@ 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; + +#ifndef NO_IPV6 + hms_allow_ipv6 = !M_CheckParm("-noipv6"); +#endif + hms_allow_ipv4 = !M_CheckParm("-noipv4"); + hms_args_checked = true; +} + FUNCDEBUG static struct HMS_buffer * HMS_connect (int proto, const char *format, ...) { @@ -152,7 +168,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(); @@ -225,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) + if (proto == PROTO_V6 || (proto == PROTO_ANY && !hms_allow_ipv4)) + { curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V6); - if (proto == PROTO_V4) + 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); @@ -326,6 +348,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 +444,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", cv_masterserver_room_id.value); + 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 +468,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", cv_masterserver_room_id.value); - 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) @@ -488,7 +517,9 @@ HMS_unlist (void) struct HMS_buffer *hms; int ok = 0; - if (hms_server_token) + HMS_check_args_once(); + + if (hms_server_token && hms_allow_ipv4) { hms = HMS_connect(PROTO_V4, "servers/%s/unlist", hms_server_token); @@ -535,6 +566,7 @@ HMS_update (void) char *title; + HMS_check_args_once(); title = curl_easy_escape(NULL, cv_servername.string, 0); snprintf(post, sizeof post, @@ -544,7 +576,7 @@ HMS_update (void) curl_free(title); - if (hms_server_token) + if (hms_server_token && hms_allow_ipv4) { hms = HMS_connect(PROTO_V4, "servers/%s/update", hms_server_token); @@ -583,6 +615,8 @@ HMS_list_servers (void) char *list; char *p; + HMS_check_args_once(); + hms = HMS_connect(PROTO_ANY, "servers"); if (! hms) @@ -628,6 +662,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) @@ -739,6 +775,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 256d9992e..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)); @@ -864,6 +876,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; @@ -884,11 +897,33 @@ 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) + { + 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; @@ -899,6 +934,13 @@ static boolean UDP_Socket(void) { 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; } @@ -906,32 +948,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) - { - 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) { @@ -996,11 +1012,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)