aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMartin Willi <martin@revosec.ch>2013-10-16 18:31:24 +0200
committerMartin Willi <martin@revosec.ch>2014-06-04 15:52:59 +0200
commit20021277f251d3a272cf5620476159642e21efb7 (patch)
treefcc26581313303c8f9652c192300dd94b7fdc84a /src
parent82fcb8027645957d53ef1c553baec89173e1acd0 (diff)
downloadstrongswan-20021277f251d3a272cf5620476159642e21efb7.tar.bz2
strongswan-20021277f251d3a272cf5620476159642e21efb7.tar.xz
windows: Add send/recv and sendto/recvfrom wrappers supporting MSG_DONTWAIT
Diffstat (limited to 'src')
-rw-r--r--src/libstrongswan/utils/windows.c99
-rw-r--r--src/libstrongswan/utils/windows.h36
2 files changed, 135 insertions, 0 deletions
diff --git a/src/libstrongswan/utils/windows.c b/src/libstrongswan/utils/windows.c
index a519b3b0d..06e0f8295 100644
--- a/src/libstrongswan/utils/windows.c
+++ b/src/libstrongswan/utils/windows.c
@@ -97,3 +97,102 @@ int socketpair(int domain, int type, int protocol, int sv[2])
closesocket(c);
return -1;
}
+
+/**
+ * Check and clear the dontwait flag
+ */
+static bool check_dontwait(int *flags)
+{
+ if (*flags & MSG_DONTWAIT)
+ {
+ *flags &= ~MSG_DONTWAIT;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/**
+ * See header
+ */
+#undef recv
+ssize_t windows_recv(int sockfd, void *buf, size_t len, int flags)
+{
+ u_long on = 1, off = 0;
+ ssize_t outlen = -1;
+
+ if (!check_dontwait(&flags))
+ {
+ return recv(sockfd, buf, len, flags);
+ }
+ if (ioctlsocket(sockfd, FIONBIO, &on) == 0)
+ {
+ outlen = recv(sockfd, buf, len, flags);
+ ioctlsocket(sockfd, FIONBIO, &off);
+ }
+ return outlen;
+}
+
+/**
+ * See header
+ */
+#undef recvfrom
+ssize_t windows_recvfrom(int sockfd, void *buf, size_t len, int flags,
+ struct sockaddr *src_addr, socklen_t *addrlen)
+{
+ u_long on = 1, off = 0;
+ ssize_t outlen = -1;
+
+ if (!check_dontwait(&flags))
+ {
+ return recvfrom(sockfd, buf, len, flags, src_addr, addrlen);
+ }
+ if (ioctlsocket(sockfd, FIONBIO, &on) == 0)
+ {
+ outlen = recvfrom(sockfd, buf, len, flags, src_addr, addrlen);
+ ioctlsocket(sockfd, FIONBIO, &off);
+ }
+ return outlen;
+}
+
+/**
+ * See header
+ */
+#undef send
+ssize_t windows_send(int sockfd, const void *buf, size_t len, int flags)
+{
+ u_long on = 1, off = 0;
+ ssize_t outlen = -1;
+
+ if (!check_dontwait(&flags))
+ {
+ return send(sockfd, buf, len, flags);
+ }
+ if (ioctlsocket(sockfd, FIONBIO, &on) == 0)
+ {
+ outlen = send(sockfd, buf, len, flags);
+ ioctlsocket(sockfd, FIONBIO, &off);
+ }
+ return outlen;
+}
+
+/**
+ * See header
+ */
+#undef sendto
+ssize_t windows_sendto(int sockfd, const void *buf, size_t len, int flags,
+ const struct sockaddr *dest_addr, socklen_t addrlen)
+{
+ u_long on = 1, off = 0;
+ ssize_t outlen = -1;
+
+ if (!check_dontwait(&flags))
+ {
+ return sendto(sockfd, buf, len, flags, dest_addr, addrlen);
+ }
+ if (ioctlsocket(sockfd, FIONBIO, &on) == 0)
+ {
+ outlen = sendto(sockfd, buf, len, flags, dest_addr, addrlen);
+ ioctlsocket(sockfd, FIONBIO, &off);
+ }
+ return outlen;
+}
diff --git a/src/libstrongswan/utils/windows.h b/src/libstrongswan/utils/windows.h
index 23a6666c4..9761c068a 100644
--- a/src/libstrongswan/utils/windows.h
+++ b/src/libstrongswan/utils/windows.h
@@ -251,6 +251,42 @@ static inline int dlclose(void *handle)
*/
int socketpair(int domain, int type, int protocol, int sv[2]);
+/**
+ * Map MSG_DONTWAIT to the reserved, but deprecated MSG_INTERRUPT
+ */
+#define MSG_DONTWAIT MSG_INTERRUPT
+
+/**
+ * EWOULDBLOCK is EAGAIN on other systems as well
+ */
+#define EWOULDBLOCK EAGAIN
+
+/**
+ * recv(2) with support for MSG_DONTWAIT
+ */
+#define recv(...) windows_recv(__VA_ARGS__)
+ssize_t windows_recv(int sockfd, void *buf, size_t len, int flags);
+
+/**
+ * recvfrom(2) with support for MSG_DONTWAIT
+ */
+#define recvfrom(...) windows_recvfrom(__VA_ARGS__)
+ssize_t windows_recvfrom(int sockfd, void *buf, size_t len, int flags,
+ struct sockaddr *src_addr, socklen_t *addrlen);
+
+/**
+ * recvfrom(2) with support for MSG_DONTWAIT
+ */
+#define send(...) windows_send(__VA_ARGS__)
+ssize_t windows_send(int sockfd, const void *buf, size_t len, int flags);
+
+/**
+ * recvfrom(2) with support for MSG_DONTWAIT
+ */
+#define sendto(...) windows_send(__VA_ARGS__)
+ssize_t windows_sendto(int sockfd, const void *buf, size_t len, int flags,
+ const struct sockaddr *dest_addr, socklen_t addrlen);
+
/* Windows does not support "ll" format printf length modifiers. Mingw
* therefore maps these to the Windows specific I64 length modifier. That
* won't work for us, as we use our own printf backend on Windows, which works