Do our very best *not* to receive SIGPIPE:
When possible do: * Set socket option SO_NOSIGPIPE * Pass MSG_NOSIGNAL to send(2) git-svn-id: https://warzone2100.svn.sourceforge.net/svnroot/warzone2100/trunk@9917 4a71c877-e1ca-e34f-864e-861f7616d084master
parent
d4b0ab8c21
commit
4aa213a937
|
@ -84,6 +84,11 @@ typedef SSIZE_T ssize_t;
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Fallback for systems that don't #define this flag
|
||||||
|
#ifndef MSG_NOSIGNAL
|
||||||
|
# define MSG_NOSIGNAL 0
|
||||||
|
#endif
|
||||||
|
|
||||||
static int getSockErr(void)
|
static int getSockErr(void)
|
||||||
{
|
{
|
||||||
#if defined(WZ_OS_UNIX)
|
#if defined(WZ_OS_UNIX)
|
||||||
|
@ -540,7 +545,7 @@ static ssize_t writeAll(Socket* sock, const void* buf, size_t size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = send(sock->fd[SOCK_CONNECTION], &((char*)buf)[written], size - written, 0);
|
ret = send(sock->fd[SOCK_CONNECTION], &((char*)buf)[written], size - written, MSG_NOSIGNAL);
|
||||||
if (ret == SOCKET_ERROR)
|
if (ret == SOCKET_ERROR)
|
||||||
{
|
{
|
||||||
switch (getSockErr())
|
switch (getSockErr())
|
||||||
|
@ -843,6 +848,10 @@ static Socket* socketAccept(Socket* sock)
|
||||||
{
|
{
|
||||||
if (sock->fd[i] != INVALID_SOCKET)
|
if (sock->fd[i] != INVALID_SOCKET)
|
||||||
{
|
{
|
||||||
|
#if defined(SO_NOSIGPIPE)
|
||||||
|
static const int no_sigpipe = 1;
|
||||||
|
#endif
|
||||||
|
|
||||||
char textAddress[40];
|
char textAddress[40];
|
||||||
struct sockaddr_storage addr;
|
struct sockaddr_storage addr;
|
||||||
socklen_t addr_len = sizeof(addr);
|
socklen_t addr_len = sizeof(addr);
|
||||||
|
@ -862,6 +871,13 @@ static Socket* socketAccept(Socket* sock)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(SO_NOSIGPIPE)
|
||||||
|
if (setsockopt(newConn, SOL_SOCKET, SO_NOSIGPIPE, &no_sigpipe, sizeof(no_sigpipe)) == SOCKET_ERROR)
|
||||||
|
{
|
||||||
|
debug(LOG_WARNING, "Failed to set SO_NOSIGPIPE on socket, SIGPIPE might be raised when connections gets broken. Error: %s", strSockError(getSockErr()));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
conn = malloc(sizeof(*conn) + addr_len);
|
conn = malloc(sizeof(*conn) + addr_len);
|
||||||
if (conn == NULL)
|
if (conn == NULL)
|
||||||
{
|
{
|
||||||
|
@ -893,6 +909,10 @@ static Socket* socketAccept(Socket* sock)
|
||||||
|
|
||||||
static Socket* SocketOpen(const struct addrinfo* addr, unsigned int timeout)
|
static Socket* SocketOpen(const struct addrinfo* addr, unsigned int timeout)
|
||||||
{
|
{
|
||||||
|
#if defined(SO_NOSIGPIPE)
|
||||||
|
static const int no_sigpipe = 1;
|
||||||
|
#endif
|
||||||
|
|
||||||
char textAddress[40];
|
char textAddress[40];
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -932,6 +952,13 @@ static Socket* SocketOpen(const struct addrinfo* addr, unsigned int timeout)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(SO_NOSIGPIPE)
|
||||||
|
if (setsockopt(newConn, SOL_SOCKET, SO_NOSIGPIPE, &no_sigpipe, sizeof(no_sigpipe)) == SOCKET_ERROR)
|
||||||
|
{
|
||||||
|
debug(LOG_WARNING, "Failed to set SO_NOSIGPIPE on socket, SIGPIPE might be raised when connections gets broken. Error: %s", strSockError(getSockErr()));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
ret = connect(conn->fd[SOCK_CONNECTION], addr->ai_addr, addr->ai_addrlen);
|
ret = connect(conn->fd[SOCK_CONNECTION], addr->ai_addr, addr->ai_addrlen);
|
||||||
if (ret == SOCKET_ERROR)
|
if (ret == SOCKET_ERROR)
|
||||||
{
|
{
|
||||||
|
@ -1019,7 +1046,9 @@ static Socket* socketListen(unsigned int port)
|
||||||
/* Enable the V4 to V6 mapping, but only when available, because it
|
/* Enable the V4 to V6 mapping, but only when available, because it
|
||||||
* isn't available on all platforms.
|
* isn't available on all platforms.
|
||||||
*/
|
*/
|
||||||
|
#if defined(IPV6_V6ONLY)
|
||||||
static const int ipv6_v6only = 0;
|
static const int ipv6_v6only = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
struct sockaddr_in addr4;
|
struct sockaddr_in addr4;
|
||||||
struct sockaddr_in6 addr6;
|
struct sockaddr_in6 addr6;
|
||||||
|
@ -1095,7 +1124,7 @@ static Socket* socketListen(unsigned int port)
|
||||||
|
|
||||||
if (conn->fd[SOCK_IPV4_LISTEN] != INVALID_SOCKET)
|
if (conn->fd[SOCK_IPV4_LISTEN] != INVALID_SOCKET)
|
||||||
{
|
{
|
||||||
if (setsockopt(conn->fd[SOCK_IPV4_LISTEN], SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(int)) == SOCKET_ERROR)
|
if (setsockopt(conn->fd[SOCK_IPV4_LISTEN], SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == SOCKET_ERROR)
|
||||||
{
|
{
|
||||||
debug(LOG_WARNING, "Failed to set SO_REUSEADDR on IPv4 socket. Error: %s", strSockError(getSockErr()));
|
debug(LOG_WARNING, "Failed to set SO_REUSEADDR on IPv4 socket. Error: %s", strSockError(getSockErr()));
|
||||||
}
|
}
|
||||||
|
@ -1116,7 +1145,7 @@ static Socket* socketListen(unsigned int port)
|
||||||
|
|
||||||
if (conn->fd[SOCK_IPV6_LISTEN] != INVALID_SOCKET)
|
if (conn->fd[SOCK_IPV6_LISTEN] != INVALID_SOCKET)
|
||||||
{
|
{
|
||||||
if (setsockopt(conn->fd[SOCK_IPV6_LISTEN], SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(int)) == SOCKET_ERROR)
|
if (setsockopt(conn->fd[SOCK_IPV6_LISTEN], SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == SOCKET_ERROR)
|
||||||
{
|
{
|
||||||
debug(LOG_WARNING, "Failed to set SO_REUSEADDR on IPv6 socket. Error: %s", strSockError(getSockErr()));
|
debug(LOG_WARNING, "Failed to set SO_REUSEADDR on IPv6 socket. Error: %s", strSockError(getSockErr()));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue