diff options
author | Martin Willi <martin@revosec.ch> | 2013-10-16 18:31:24 +0200 |
---|---|---|
committer | Martin Willi <martin@revosec.ch> | 2014-06-04 15:52:59 +0200 |
commit | 20021277f251d3a272cf5620476159642e21efb7 (patch) | |
tree | fcc26581313303c8f9652c192300dd94b7fdc84a /src | |
parent | 82fcb8027645957d53ef1c553baec89173e1acd0 (diff) | |
download | strongswan-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.c | 99 | ||||
-rw-r--r-- | src/libstrongswan/utils/windows.h | 36 |
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 |