mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2025-03-13 06:13:18 +00:00
Merge branch 'fix-bind-with-ipv6-disabled' into 'master'
Update i_tcp.c to support hosts with IPv6 disabled See merge request STJr/SRB2!2628
This commit is contained in:
commit
854fc95672
1 changed files with 89 additions and 21 deletions
|
@ -1,7 +1,7 @@
|
||||||
// SONIC ROBO BLAST 2
|
// SONIC ROBO BLAST 2
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||||
// Copyright (C) 1999-2024 by Sonic Team Junior.
|
// Copyright (C) 1999-2025 by Sonic Team Junior.
|
||||||
//
|
//
|
||||||
// This program is free software distributed under the
|
// This program is free software distributed under the
|
||||||
// terms of the GNU General Public License, version 2.
|
// terms of the GNU General Public License, version 2.
|
||||||
|
@ -386,6 +386,7 @@ static const char *SOCK_AddrToStr(mysockaddr_t *sk)
|
||||||
int v6 = 0;
|
int v6 = 0;
|
||||||
#endif
|
#endif
|
||||||
void *addr;
|
void *addr;
|
||||||
|
int e = 0; // save error code so it can't be modified later code and avoid calling WSAGetLastError() more then once
|
||||||
|
|
||||||
if(sk->any.sa_family == AF_INET)
|
if(sk->any.sa_family == AF_INET)
|
||||||
addr = &sk->ip4.sin_addr;
|
addr = &sk->ip4.sin_addr;
|
||||||
|
@ -399,7 +400,10 @@ static const char *SOCK_AddrToStr(mysockaddr_t *sk)
|
||||||
if(addr == NULL)
|
if(addr == NULL)
|
||||||
sprintf(s, "No address");
|
sprintf(s, "No address");
|
||||||
else if(inet_ntop(sk->any.sa_family, addr, &s[v6], sizeof (s) - v6) == NULL)
|
else if(inet_ntop(sk->any.sa_family, addr, &s[v6], sizeof (s) - v6) == NULL)
|
||||||
sprintf(s, "Unknown family type, error #%u", errno);
|
{
|
||||||
|
e = errno;
|
||||||
|
sprintf(s, "Unknown family type, error #%u: %s", e, strerror(e));
|
||||||
|
}
|
||||||
#ifdef HAVE_IPV6
|
#ifdef HAVE_IPV6
|
||||||
else if(sk->any.sa_family == AF_INET6)
|
else if(sk->any.sa_family == AF_INET6)
|
||||||
{
|
{
|
||||||
|
@ -657,7 +661,7 @@ static inline ssize_t SOCK_SendToAddr(SOCKET_TYPE socket, mysockaddr_t *sockaddr
|
||||||
static void SOCK_Send(void)
|
static void SOCK_Send(void)
|
||||||
{
|
{
|
||||||
ssize_t c = ERRSOCKET;
|
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
|
int e = 0; // save error code so it can't be modified later code and avoid calling WSAGetLastError() more then once
|
||||||
|
|
||||||
if (!nodeconnected[doomcom->remotenode])
|
if (!nodeconnected[doomcom->remotenode])
|
||||||
return;
|
return;
|
||||||
|
@ -709,7 +713,7 @@ static void SOCK_Send(void)
|
||||||
if (c == ERRSOCKET && e != -1) // -1 means no socket for the address family was found
|
if (c == ERRSOCKET && e != -1) // -1 means no socket for the address family was found
|
||||||
{
|
{
|
||||||
if (!ALLOWEDERROR(e))
|
if (!ALLOWEDERROR(e))
|
||||||
I_Error("SOCK_Send, error sending to node %d (%s) #%u: %s", doomcom->remotenode,
|
I_Error("SOCK_Send, error sending to node %d (%s) #%u, %s", doomcom->remotenode,
|
||||||
SOCK_GetNodeAddress(doomcom->remotenode), e, strerror(e));
|
SOCK_GetNodeAddress(doomcom->remotenode), e, strerror(e));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -740,6 +744,8 @@ static SOCKET_TYPE UDP_Bind(int family, struct sockaddr *addr, socklen_t addrlen
|
||||||
{
|
{
|
||||||
SOCKET_TYPE s = socket(family, SOCK_DGRAM, IPPROTO_UDP);
|
SOCKET_TYPE s = socket(family, SOCK_DGRAM, IPPROTO_UDP);
|
||||||
int opt;
|
int opt;
|
||||||
|
int rc;
|
||||||
|
int e = 0; // save error code so it can't be modified later code and avoid calling WSAGetLastError() more then once
|
||||||
socklen_t opts;
|
socklen_t opts;
|
||||||
#ifdef FIONBIO
|
#ifdef FIONBIO
|
||||||
unsigned long trueval = true;
|
unsigned long trueval = true;
|
||||||
|
@ -754,12 +760,17 @@ static SOCKET_TYPE UDP_Bind(int family, struct sockaddr *addr, socklen_t addrlen
|
||||||
#ifdef USE_WINSOCK2
|
#ifdef USE_WINSOCK2
|
||||||
DWORD dwBytesReturned = 0;
|
DWORD dwBytesReturned = 0;
|
||||||
BOOL bfalse = FALSE;
|
BOOL bfalse = FALSE;
|
||||||
WSAIoctl(s, SIO_UDP_CONNRESET, &bfalse, sizeof(bfalse),
|
rc = WSAIoctl(s, SIO_UDP_CONNRESET, &bfalse, sizeof(bfalse),
|
||||||
NULL, 0, &dwBytesReturned, NULL, NULL);
|
NULL, 0, &dwBytesReturned, NULL, NULL);
|
||||||
#else
|
#else
|
||||||
unsigned long falseval = false;
|
unsigned long falseval = false;
|
||||||
ioctl(s, SIO_UDP_CONNRESET, &falseval);
|
rc = ioctl(s, SIO_UDP_CONNRESET, &falseval);
|
||||||
#endif
|
#endif
|
||||||
|
if (rc == -1)
|
||||||
|
{
|
||||||
|
e = errno;
|
||||||
|
I_OutputMsg("SIO_UDP_CONNRESET failed: #%u, %s\n", e, strerror(e));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -772,14 +783,22 @@ static SOCKET_TYPE UDP_Bind(int family, struct sockaddr *addr, socklen_t addrlen
|
||||||
{
|
{
|
||||||
opt = true;
|
opt = true;
|
||||||
opts = (socklen_t)sizeof(opt);
|
opts = (socklen_t)sizeof(opt);
|
||||||
setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, opts);
|
rc = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, opts);
|
||||||
|
if (rc <= -1)
|
||||||
|
{
|
||||||
|
e = errno;
|
||||||
|
I_OutputMsg("setting SO_REUSEADDR failed: #%u, %s\n", e, strerror(e));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// make it broadcastable
|
// make it broadcastable
|
||||||
opt = true;
|
opt = true;
|
||||||
opts = (socklen_t)sizeof(opt);
|
opts = (socklen_t)sizeof(opt);
|
||||||
if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, (char *)&opt, opts))
|
rc = setsockopt(s, SOL_SOCKET, SO_BROADCAST, (char *)&opt, opts);
|
||||||
|
if (rc <= -1)
|
||||||
{
|
{
|
||||||
|
e = errno;
|
||||||
CONS_Alert(CONS_WARNING, M_GetText("Could not get broadcast rights\n")); // I do not care anymore
|
CONS_Alert(CONS_WARNING, M_GetText("Could not get broadcast rights\n")); // I do not care anymore
|
||||||
|
I_OutputMsg("setting SO_BROADCAST failed: #%u, %s\n", e, strerror(e));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef HAVE_IPV6
|
#ifdef HAVE_IPV6
|
||||||
|
@ -789,24 +808,34 @@ static SOCKET_TYPE UDP_Bind(int family, struct sockaddr *addr, socklen_t addrlen
|
||||||
{
|
{
|
||||||
opt = true;
|
opt = true;
|
||||||
opts = (socklen_t)sizeof(opt);
|
opts = (socklen_t)sizeof(opt);
|
||||||
setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, opts);
|
rc = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, opts);
|
||||||
|
if (rc <= -1)
|
||||||
|
{
|
||||||
|
e = errno;
|
||||||
|
I_OutputMsg("setting SO_REUSEADDR failed: #%u, %s\n", e, strerror(e));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#ifdef IPV6_V6ONLY
|
#ifdef IPV6_V6ONLY
|
||||||
// make it IPv6 ony
|
// make it IPv6 ony
|
||||||
opt = true;
|
opt = true;
|
||||||
opts = (socklen_t)sizeof(opt);
|
opts = (socklen_t)sizeof(opt);
|
||||||
if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&opt, opts))
|
rc = setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&opt, opts);
|
||||||
|
if (rc <= -1)
|
||||||
{
|
{
|
||||||
|
e = errno;
|
||||||
CONS_Alert(CONS_WARNING, M_GetText("Could not limit IPv6 bind\n")); // I do not care anymore
|
CONS_Alert(CONS_WARNING, M_GetText("Could not limit IPv6 bind\n")); // I do not care anymore
|
||||||
|
I_OutputMsg("setting IPV6_V6ONLY failed: #%u, %s\n", e, strerror(e));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (bind(s, addr, addrlen) == ERRSOCKET)
|
rc = bind(s, addr, addrlen);
|
||||||
|
if (rc == ERRSOCKET)
|
||||||
{
|
{
|
||||||
|
e = errno;
|
||||||
close(s);
|
close(s);
|
||||||
I_OutputMsg("Binding failed\n");
|
I_OutputMsg("Binding failed: #%u, %s\n", e, strerror(e));
|
||||||
return (SOCKET_TYPE)ERRSOCKET;
|
return (SOCKET_TYPE)ERRSOCKET;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -820,9 +849,18 @@ static SOCKET_TYPE UDP_Bind(int family, struct sockaddr *addr, socklen_t addrlen
|
||||||
|
|
||||||
inet_pton(AF_INET6, IPV6_MULTICAST_ADDRESS, &maddr.ipv6mr_multiaddr);
|
inet_pton(AF_INET6, IPV6_MULTICAST_ADDRESS, &maddr.ipv6mr_multiaddr);
|
||||||
maddr.ipv6mr_interface = 0;
|
maddr.ipv6mr_interface = 0;
|
||||||
if (setsockopt(s, IPPROTO_IPV6, IPV6_JOIN_GROUP, (const char *)&maddr, sizeof(maddr)) != 0)
|
rc = setsockopt(s, IPPROTO_IPV6, IPV6_JOIN_GROUP, (const char *)&maddr, sizeof(maddr));
|
||||||
|
if (rc <= -1)
|
||||||
{
|
{
|
||||||
|
e = errno;
|
||||||
CONS_Alert(CONS_WARNING, M_GetText("Could not register multicast address\n"));
|
CONS_Alert(CONS_WARNING, M_GetText("Could not register multicast address\n"));
|
||||||
|
if (e == ENODEV)
|
||||||
|
{
|
||||||
|
close(s);
|
||||||
|
I_OutputMsg("Binding failed: no IPv6 device\n");
|
||||||
|
return (SOCKET_TYPE)ERRSOCKET;
|
||||||
|
}
|
||||||
|
I_OutputMsg("setting IPV6_JOIN_GROUP failed: #%u, %s \n", e, strerror(e));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -830,33 +868,56 @@ static SOCKET_TYPE UDP_Bind(int family, struct sockaddr *addr, socklen_t addrlen
|
||||||
|
|
||||||
#ifdef FIONBIO
|
#ifdef FIONBIO
|
||||||
// make it non blocking
|
// make it non blocking
|
||||||
opt = true;
|
rc = ioctl(s, FIONBIO, &trueval);
|
||||||
if (ioctl(s, FIONBIO, &trueval) != 0)
|
if (rc == -1)
|
||||||
{
|
{
|
||||||
|
e = errno;
|
||||||
close(s);
|
close(s);
|
||||||
I_OutputMsg("Seting FIOBIO on failed\n");
|
I_OutputMsg("FIOBIO failed: #%u, %s\n", e, strerror(e));
|
||||||
return (SOCKET_TYPE)ERRSOCKET;
|
return (SOCKET_TYPE)ERRSOCKET;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
opt = 0;
|
||||||
opts = (socklen_t)sizeof(opt);
|
opts = (socklen_t)sizeof(opt);
|
||||||
getsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *)&opt, &opts);
|
rc = getsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *)&opt, &opts);
|
||||||
|
if (rc <= -1)
|
||||||
|
{
|
||||||
|
e = errno;
|
||||||
|
I_OutputMsg("getting SO_RCVBUF failed: #%u, %s\n", e, strerror(e));
|
||||||
|
}
|
||||||
CONS_Printf(M_GetText("Network system buffer: %dKb\n"), opt>>10);
|
CONS_Printf(M_GetText("Network system buffer: %dKb\n"), opt>>10);
|
||||||
|
|
||||||
if (opt < 64<<10) // 64k
|
if (opt < 64<<10) // 64k
|
||||||
{
|
{
|
||||||
opt = 64<<10;
|
opt = 64<<10;
|
||||||
opts = (socklen_t)sizeof(opt);
|
opts = (socklen_t)sizeof(opt);
|
||||||
setsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *)&opt, opts);
|
rc = setsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *)&opt, opts);
|
||||||
getsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *)&opt, &opts);
|
if (rc <= -1)
|
||||||
if (opt < 64<<10)
|
{
|
||||||
|
e = errno;
|
||||||
|
I_OutputMsg("setting SO_RCVBUF failed: #%u, %s\n", e, strerror(e));
|
||||||
|
}
|
||||||
|
opt = 0;
|
||||||
|
rc = getsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *)&opt, &opts);
|
||||||
|
if (rc <= -1)
|
||||||
|
{
|
||||||
|
e = errno;
|
||||||
|
I_OutputMsg("getting SO_RCVBUF failed: #%u, %s\n", e, strerror(e));
|
||||||
|
}
|
||||||
|
if (opt <= 64<<10)
|
||||||
CONS_Alert(CONS_WARNING, M_GetText("Can't set buffer length to 64k, file transfer will be bad\n"));
|
CONS_Alert(CONS_WARNING, M_GetText("Can't set buffer length to 64k, file transfer will be bad\n"));
|
||||||
else
|
else
|
||||||
CONS_Printf(M_GetText("Network system buffer set to: %dKb\n"), opt>>10);
|
CONS_Printf(M_GetText("Network system buffer set to: %dKb\n"), opt>>10);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getsockname(s, &straddr.any, &len) == -1)
|
rc = getsockname(s, &straddr.any, &len);
|
||||||
|
if (rc != 0)
|
||||||
|
{
|
||||||
|
e = errno;
|
||||||
CONS_Alert(CONS_WARNING, M_GetText("Failed to get port number\n"));
|
CONS_Alert(CONS_WARNING, M_GetText("Failed to get port number\n"));
|
||||||
|
I_OutputMsg("getsockname failed: #%u, %s\n", e, strerror(e));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (family == AF_INET)
|
if (family == AF_INET)
|
||||||
|
@ -894,6 +955,13 @@ static boolean UDP_Socket(void)
|
||||||
hints.ai_socktype = SOCK_DGRAM;
|
hints.ai_socktype = SOCK_DGRAM;
|
||||||
hints.ai_protocol = IPPROTO_UDP;
|
hints.ai_protocol = IPPROTO_UDP;
|
||||||
|
|
||||||
|
#ifdef HAVE_IPV6
|
||||||
|
if (!b_ipv6)
|
||||||
|
I_OutputMsg("Disabling IPv6 support at runtime\n");
|
||||||
|
#else
|
||||||
|
I_OutputMsg("Compiled without IPv6 support\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
if (serverrunning)
|
if (serverrunning)
|
||||||
serv = serverport_name;
|
serv = serverport_name;
|
||||||
else
|
else
|
||||||
|
|
Loading…
Reference in a new issue