summaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
authorHaru <haru@dotalux.com>2015-12-02 00:52:00 +0100
committerHaru <haru@dotalux.com>2015-12-02 01:29:03 +0100
commit9be1d84752ba2ed733ae29d68304f5825cf29162 (patch)
treebaae270c400ec5a8766ace192fc6aa4cbc53c881 /src/common
parente134bb97526d95d1024bfbf1afa1a37b36a693f1 (diff)
downloadhercules-9be1d84752ba2ed733ae29d68304f5825cf29162.tar.gz
hercules-9be1d84752ba2ed733ae29d68304f5825cf29162.tar.bz2
hercules-9be1d84752ba2ed733ae29d68304f5825cf29162.tar.xz
hercules-9be1d84752ba2ed733ae29d68304f5825cf29162.zip
Fixed an issue with the socket send/receive timeouts in Windows
- According to https://msdn.microsoft.com/en-us/library/windows/desktop/ms740476(v=vs.85).aspx setsockopt() for SO_RCVTIMEO/SO_SNDTIMEO require a DWORD argument, unlike their POSIX equivalent, requiring a struct timeval. - Always keep in mind: When you see a Microsoft API function that looks like a duck, swims like a duck, quacks like a duck, it most certainly is not a duck. - Thanks to ultramage. Signed-off-by: Haru <haru@dotalux.com>
Diffstat (limited to 'src/common')
-rw-r--r--src/common/socket.c39
1 files changed, 27 insertions, 12 deletions
diff --git a/src/common/socket.c b/src/common/socket.c
index b418a468f..362fe78db 100644
--- a/src/common/socket.c
+++ b/src/common/socket.c
@@ -303,18 +303,31 @@ void set_nonblocking(int fd, unsigned long yes)
ShowError("set_nonblocking: Failed to set socket #%d to non-blocking mode (%s) - Please report this!!!\n", fd, error_msg());
}
-void setsocketopts(int fd, struct hSockOpt *opt) {
- int yes = 1; // reuse fix
- struct linger lopt;
+/**
+ * Sets the options for a socket.
+ *
+ * @param fd The socket descriptor
+ * @param opt Optional, additional options to set (Can be NULL).
+ */
+void setsocketopts(int fd, struct hSockOpt *opt)
+{
+#if defined(WIN32)
+ BOOL yes = TRUE;
+#else // not WIN32
+ int yes = 1;
+#endif // WIN32
+ struct linger lopt = { 0 };
+ // Note: We cast the fourth argument to (char *) because, while in UNIX
+ // it takes a const void *, in Windows it takes a const char *.
#if !defined(WIN32)
// set SO_REAUSEADDR to true, unix only. on windows this option causes
// the previous owner of the socket to give up, which is not desirable
// in most cases, neither compatible with unix.
- if (sSetsockopt(fd,SOL_SOCKET,SO_REUSEADDR,(char *)&yes,sizeof(yes)))
+ if (sSetsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&yes, sizeof(yes)))
ShowWarning("setsocketopts: Unable to set SO_REUSEADDR mode for connection #%d!\n", fd);
#ifdef SO_REUSEPORT
- if (sSetsockopt(fd,SOL_SOCKET,SO_REUSEPORT,(char *)&yes,sizeof(yes)))
+ if (sSetsockopt(fd, SOL_SOCKET, SO_REUSEPORT, (char *)&yes, sizeof(yes)))
ShowWarning("setsocketopts: Unable to set SO_REUSEPORT mode for connection #%d!\n", fd);
#endif // SO_REUSEPORT
#endif // WIN32
@@ -324,15 +337,17 @@ void setsocketopts(int fd, struct hSockOpt *opt) {
if (sSetsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&yes, sizeof(yes)))
ShowWarning("setsocketopts: Unable to set TCP_NODELAY mode for connection #%d!\n", fd);
- if( opt && opt->setTimeo ) {
- struct timeval timeout;
-
+ if (opt && opt->setTimeo) {
+#if defined(WIN32)
+ DWORD timeout = 5000; // https://msdn.microsoft.com/en-us/library/windows/desktop/ms740476(v=vs.85).aspx
+#else // not WIN32
+ struct timeval timeout = { 0 };
timeout.tv_sec = 5;
- timeout.tv_usec = 0;
+#endif // WIN32
- if (sSetsockopt(fd,SOL_SOCKET,SO_RCVTIMEO,(char *)&timeout,sizeof(timeout)))
+ if (sSetsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout)))
ShowWarning("setsocketopts: Unable to set SO_RCVTIMEO for connection #%d!\n", fd);
- if (sSetsockopt(fd,SOL_SOCKET,SO_SNDTIMEO,(char *)&timeout,sizeof(timeout)))
+ if (sSetsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(timeout)))
ShowWarning("setsocketopts: Unable to set SO_SNDTIMEO for connection #%d!\n", fd);
}
@@ -340,7 +355,7 @@ void setsocketopts(int fd, struct hSockOpt *opt) {
//(http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/winsock/closesocket_2.asp)
lopt.l_onoff = 0; // SO_DONTLINGER
lopt.l_linger = 0; // Do not care
- if( sSetsockopt(fd, SOL_SOCKET, SO_LINGER, (char*)&lopt, sizeof(lopt)) )
+ if (sSetsockopt(fd, SOL_SOCKET, SO_LINGER, (char *)&lopt, sizeof(lopt)))
ShowWarning("setsocketopts: Unable to set SO_LINGER mode for connection #%d!\n", fd);
#ifdef TCP_THIN_LINEAR_TIMEOUTS