Merge branch 'fix-enetunreach-crash' into 'next'

Fix crash if a packet fails to reach the client

See merge request STJr/SRB2!2480
This commit is contained in:
Lactozilla 2024-08-24 21:07:02 +00:00
commit e6124eaec5

View file

@ -87,6 +87,10 @@
#undef EHOSTUNREACH #undef EHOSTUNREACH
#endif #endif
#define EHOSTUNREACH WSAEHOSTUNREACH #define EHOSTUNREACH WSAEHOSTUNREACH
#ifdef ENETUNREACH
#undef ENETUNREACH
#endif
#define ENETUNREACH WSAENETUNREACH
#ifndef IOC_VENDOR #ifndef IOC_VENDOR
#define IOC_VENDOR 0x18000000 #define IOC_VENDOR 0x18000000
#endif #endif
@ -685,7 +689,6 @@ static inline ssize_t SOCK_SendToAddr(SOCKET_TYPE socket, mysockaddr_t *sockaddr
socklen_t d6 = (socklen_t)sizeof(struct sockaddr_in6); socklen_t d6 = (socklen_t)sizeof(struct sockaddr_in6);
#endif #endif
socklen_t d, da = (socklen_t)sizeof(mysockaddr_t); socklen_t d, da = (socklen_t)sizeof(mysockaddr_t);
ssize_t status;
switch (sockaddr->any.sa_family) switch (sockaddr->any.sa_family)
{ {
@ -696,14 +699,11 @@ static inline ssize_t SOCK_SendToAddr(SOCKET_TYPE socket, mysockaddr_t *sockaddr
default: d = da; break; default: d = da; break;
} }
status = sendto(socket, (char *)&doomcom->data, doomcom->datalength, 0, &sockaddr->any, d); return sendto(socket, (char *)&doomcom->data, doomcom->datalength, 0, &sockaddr->any, d);
if (status == -1)
{
CONS_Alert(CONS_WARNING, "Unable to send packet to %s: %s\n", SOCK_AddrToStr(sockaddr), strerror(errno));
}
return status;
} }
#define ALLOWEDERROR(x) ((x) == ECONNREFUSED || (x) == EWOULDBLOCK || (x) == EHOSTUNREACH || (x) == ENETUNREACH)
static void SOCK_Send(void) static void SOCK_Send(void)
{ {
ssize_t c = ERRSOCKET; ssize_t c = ERRSOCKET;
@ -718,19 +718,25 @@ static void SOCK_Send(void)
for (size_t j = 0; j < broadcastaddresses; j++) for (size_t j = 0; j < broadcastaddresses; j++)
{ {
if (myfamily[i] == broadcastaddress[j].any.sa_family) if (myfamily[i] == broadcastaddress[j].any.sa_family)
SOCK_SendToAddr(mysockets[i], &broadcastaddress[j]); {
c = SOCK_SendToAddr(mysockets[i], &broadcastaddress[j]);
if (c == ERRSOCKET && !ALLOWEDERROR(errno))
break;
}
} }
} }
return;
} }
else if (nodesocket[doomcom->remotenode] == (SOCKET_TYPE)ERRSOCKET) else if (nodesocket[doomcom->remotenode] == (SOCKET_TYPE)ERRSOCKET)
{ {
for (size_t i = 0; i < mysocketses; i++) for (size_t i = 0; i < mysocketses; i++)
{ {
if (myfamily[i] == clientaddress[doomcom->remotenode].any.sa_family) if (myfamily[i] == clientaddress[doomcom->remotenode].any.sa_family)
SOCK_SendToAddr(mysockets[i], &clientaddress[doomcom->remotenode]); {
c = SOCK_SendToAddr(mysockets[i], &clientaddress[doomcom->remotenode]);
if (c == ERRSOCKET && !ALLOWEDERROR(errno))
break;
}
} }
return;
} }
else else
{ {
@ -740,12 +746,14 @@ static void SOCK_Send(void)
if (c == ERRSOCKET) if (c == ERRSOCKET)
{ {
int e = errno; // save error code so it can't be modified later int e = errno; // save error code so it can't be modified later
if (e != ECONNREFUSED && e != EWOULDBLOCK && e != EHOSTUNREACH) 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));
} }
} }
#undef ALLOWEDERROR
static void SOCK_FreeNodenum(INT32 numnode) static void SOCK_FreeNodenum(INT32 numnode)
{ {
// can't disconnect from self :) // can't disconnect from self :)