Browse Source

Fix miniupnpc setsockopt incompatible pointer type on Windows with GCC 14+

GCC 14+ treats -Wincompatible-pointer-types as an error by default.
On Windows, setsockopt() expects const char* for the option value, and
socket timeouts (SO_RCVTIMEO/SO_SNDTIMEO) use DWORD (milliseconds)
instead of struct timeval.

This was also a latent bug: the original code passed a struct timeval
(8 bytes: {tv_sec=3, tv_usec=0}) but Windows expects a DWORD (4 bytes)
containing milliseconds. Windows would read only the first 4 bytes
(value 3) as 3 milliseconds instead of the intended 3 seconds.
pull/4/head
Leslie P. Polzer 4 months ago
parent
commit
0ca24aa61f
  1. 24
      ext/miniupnpc/connecthostport.c

24
ext/miniupnpc/connecthostport.c

@ -74,7 +74,11 @@ int connecthostport(const char * host, unsigned short port,
struct addrinfo hints;
#endif /* #ifdef USE_GETHOSTBYNAME */
#ifdef MINIUPNPC_SET_SOCKET_TIMEOUT
#ifdef _WIN32
DWORD timeout;
#else
struct timeval timeout;
#endif
#endif /* #ifdef MINIUPNPC_SET_SOCKET_TIMEOUT */
#ifdef USE_GETHOSTBYNAME
@ -94,15 +98,25 @@ int connecthostport(const char * host, unsigned short port,
}
#ifdef MINIUPNPC_SET_SOCKET_TIMEOUT
/* setting a 3 seconds timeout for the connect() call */
#ifdef _WIN32
timeout = 3000; /* milliseconds */
if(setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (const char *)&timeout, sizeof(timeout)) < 0)
#else
timeout.tv_sec = 3;
timeout.tv_usec = 0;
if(setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(struct timeval)) < 0)
#endif
{
PRINT_SOCKET_ERROR("setsockopt SO_RCVTIMEO");
}
#ifdef _WIN32
timeout = 3000; /* milliseconds */
if(setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, (const char *)&timeout, sizeof(timeout)) < 0)
#else
timeout.tv_sec = 3;
timeout.tv_usec = 0;
if(setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(struct timeval)) < 0)
#endif
{
PRINT_SOCKET_ERROR("setsockopt SO_SNDTIMEO");
}
@ -193,15 +207,25 @@ int connecthostport(const char * host, unsigned short port,
}
#ifdef MINIUPNPC_SET_SOCKET_TIMEOUT
/* setting a 3 seconds timeout for the connect() call */
#ifdef _WIN32
timeout = 3000; /* milliseconds */
if(setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (const char *)&timeout, sizeof(timeout)) < 0)
#else
timeout.tv_sec = 3;
timeout.tv_usec = 0;
if(setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(struct timeval)) < 0)
#endif
{
PRINT_SOCKET_ERROR("setsockopt");
}
#ifdef _WIN32
timeout = 3000; /* milliseconds */
if(setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, (const char *)&timeout, sizeof(timeout)) < 0)
#else
timeout.tv_sec = 3;
timeout.tv_usec = 0;
if(setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(struct timeval)) < 0)
#endif
{
PRINT_SOCKET_ERROR("setsockopt");
}

Loading…
Cancel
Save