diff options
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 |