diff --git a/src/libs/network.cpp b/src/libs/network.cpp index 55967ba1..dcf8702e 100644 --- a/src/libs/network.cpp +++ b/src/libs/network.cpp @@ -16,11 +16,6 @@ #include #include #include - -// POSIX uses plain int file descriptors for sockets; provide the Winsock spellings -// the shared (non-guarded) code paths reference. -using SOCKET = int; -static constexpr SOCKET INVALID_SOCKET = -1; #endif #include "common/assert.h" @@ -823,9 +818,11 @@ struct NetEtherAddr { #if defined(_WIN32) using NativeSocket = SOCKET; static constexpr NativeSocket INVALID_NATIVE_SOCKET = INVALID_SOCKET; +using SocketLength = int; #else using NativeSocket = int; static constexpr NativeSocket INVALID_NATIVE_SOCKET = -1; +using SocketLength = socklen_t; #endif struct SocketSlot { @@ -898,7 +895,12 @@ static bool EnsureSocketBackend() { return true; } -static int SetPosixSocketError(int error) { +static int SetGuestSocketError(int error) { + *Posix::GetErrorAddr() = error; + return -1; +} + +static int SetHostSocketError(int error) { int posix_error = Posix::POSIX_EIO; #if defined(_WIN32) switch (error) { @@ -933,17 +935,31 @@ static int SetPosixSocketError(int error) { default: break; } #else - posix_error = error; + switch (error) { + case EACCES: posix_error = Posix::POSIX_EACCES; break; + case EADDRINUSE: posix_error = Posix::POSIX_EADDRINUSE; break; + case EADDRNOTAVAIL: posix_error = Posix::POSIX_EADDRNOTAVAIL; break; + case EAFNOSUPPORT: posix_error = Posix::POSIX_EAFNOSUPPORT; break; + case EBADF: posix_error = Posix::POSIX_EBADF; break; + case EFAULT: posix_error = Posix::POSIX_EFAULT; break; + case EINVAL: posix_error = Posix::POSIX_EINVAL; break; + case EMFILE: posix_error = Posix::POSIX_EMFILE; break; + case ENFILE: posix_error = Posix::POSIX_ENFILE; break; + case ENOBUFS: posix_error = Posix::POSIX_ENOBUFS; break; + case ENOMEM: posix_error = Posix::POSIX_ENOMEM; break; + case ENOTSOCK: posix_error = Posix::POSIX_ENOTSOCK; break; + case EPROTONOSUPPORT: posix_error = Posix::POSIX_EPROTONOSUPPORT; break; + default: break; + } #endif - *Posix::GetErrorAddr() = posix_error; - return -1; + return SetGuestSocketError(posix_error); } -static int SetPosixSocketError() { +static int SetHostSocketError() { #if defined(_WIN32) - return SetPosixSocketError(WSAGetLastError()); + return SetHostSocketError(WSAGetLastError()); #else - return SetPosixSocketError(errno); + return SetHostSocketError(errno); #endif } @@ -991,9 +1007,8 @@ static int ConvertMessageFlags(int flags) { #endif } -#if defined(_WIN32) static int ConvertGuestSockaddr(const void* addr, uint32_t addrlen, sockaddr_storage* out, - int* out_len) { + SocketLength* out_len) { EXIT_IF(out == nullptr); EXIT_IF(out_len == nullptr); @@ -1028,6 +1043,7 @@ static int ConvertGuestSockaddr(const void* addr, uint32_t addrlen, sockaddr_sto return 0; } +#if defined(_WIN32) static int ConvertHostSockaddr(const sockaddr_storage* addr, int addrlen, void* out, uint32_t* out_len) { EXIT_IF(addr == nullptr); @@ -1364,7 +1380,7 @@ int KYTY_SYSV_ABI NetGetSockInfo(int s, void* info, int n, int flags) { int KYTY_SYSV_ABI EpollCreate(const char* name, int flags) { if (name == nullptr || flags != 0) { - return SetPosixSocketError(Posix::POSIX_EINVAL); + return SetGuestSocketError(Posix::POSIX_EINVAL); } std::lock_guard lock(g_epoll_mutex); @@ -1378,7 +1394,7 @@ int KYTY_SYSV_ABI EpollCreate(const char* name, int flags) { } } - return SetPosixSocketError(Posix::POSIX_EMFILE); + return SetGuestSocketError(Posix::POSIX_EMFILE); } int KYTY_SYSV_ABI EpollControl(int eid, int op, int id, const NetEpollEvent* event) { @@ -1387,22 +1403,22 @@ int KYTY_SYSV_ABI EpollControl(int eid, int op, int id, const NetEpollEvent* eve constexpr int EPOLL_CTL_DEL = 3; if ((op == EPOLL_CTL_ADD || op == EPOLL_CTL_MOD) && event == nullptr) { - return SetPosixSocketError(Posix::POSIX_EINVAL); + return SetGuestSocketError(Posix::POSIX_EINVAL); } if (op == EPOLL_CTL_DEL && event != nullptr) { - return SetPosixSocketError(Posix::POSIX_EINVAL); + return SetGuestSocketError(Posix::POSIX_EINVAL); } if (op < EPOLL_CTL_ADD || op > EPOLL_CTL_DEL) { - return SetPosixSocketError(Posix::POSIX_EINVAL); + return SetGuestSocketError(Posix::POSIX_EINVAL); } if (!IsSocket(id)) { - return SetPosixSocketError(Posix::POSIX_EBADF); + return SetGuestSocketError(Posix::POSIX_EBADF); } std::lock_guard lock(g_epoll_mutex); auto* slot = GetEpollSlot(eid); if (slot == nullptr) { - return SetPosixSocketError(Posix::POSIX_EBADF); + return SetGuestSocketError(Posix::POSIX_EBADF); } auto registration = std::find_if(slot->registrations.begin(), slot->registrations.end(), @@ -1410,19 +1426,19 @@ int KYTY_SYSV_ABI EpollControl(int eid, int op, int id, const NetEpollEvent* eve switch (op) { case EPOLL_CTL_ADD: if (registration != slot->registrations.end()) { - return SetPosixSocketError(Posix::POSIX_EEXIST); + return SetGuestSocketError(Posix::POSIX_EEXIST); } slot->registrations.push_back({id, *event}); break; case EPOLL_CTL_MOD: if (registration == slot->registrations.end()) { - return SetPosixSocketError(Posix::POSIX_ENOENT); + return SetGuestSocketError(Posix::POSIX_ENOENT); } registration->event = *event; break; case EPOLL_CTL_DEL: if (registration == slot->registrations.end()) { - return SetPosixSocketError(Posix::POSIX_ENOENT); + return SetGuestSocketError(Posix::POSIX_ENOENT); } slot->registrations.erase(registration); break; @@ -1435,10 +1451,10 @@ int KYTY_SYSV_ABI EpollControl(int eid, int op, int id, const NetEpollEvent* eve int KYTY_SYSV_ABI EpollWait(int eid, NetEpollEvent* events, int maxevents, int timeout) { if (events == nullptr) { - return SetPosixSocketError(Posix::POSIX_EFAULT); + return SetGuestSocketError(Posix::POSIX_EFAULT); } if (maxevents <= 0 || timeout < -1) { - return SetPosixSocketError(Posix::POSIX_EINVAL); + return SetGuestSocketError(Posix::POSIX_EINVAL); } std::vector registrations; @@ -1446,7 +1462,7 @@ int KYTY_SYSV_ABI EpollWait(int eid, NetEpollEvent* events, int maxevents, int t std::unique_lock lock(g_epoll_mutex); auto* slot = GetEpollSlot(eid); if (slot == nullptr) { - return SetPosixSocketError(Posix::POSIX_EBADF); + return SetGuestSocketError(Posix::POSIX_EBADF); } if (slot->registrations.empty() && timeout != 0) { @@ -1461,7 +1477,7 @@ int KYTY_SYSV_ABI EpollWait(int eid, NetEpollEvent* events, int maxevents, int t } slot = GetEpollSlot(eid); if (slot == nullptr) { - return SetPosixSocketError(Posix::POSIX_EBADF); + return SetGuestSocketError(Posix::POSIX_EBADF); } } registrations = slot->registrations; @@ -1492,7 +1508,7 @@ int KYTY_SYSV_ABI EpollWait(int eid, NetEpollEvent* events, int maxevents, int t continue; } if (host_registrations.size() >= FD_SETSIZE) { - return SetPosixSocketError(Posix::POSIX_EINVAL); + return SetGuestSocketError(Posix::POSIX_EINVAL); } if ((registration.event.events & EPOLL_IN) != 0) { FD_SET(socket, &host_read); @@ -1518,7 +1534,7 @@ int KYTY_SYSV_ABI EpollWait(int eid, NetEpollEvent* events, int maxevents, int t const int result = ::select(0, &host_read, &host_write, &host_except, host_timeout_ptr); if (result == SOCKET_ERROR) { - return SetPosixSocketError(); + return SetHostSocketError(); } if (result == 0) { return 0; @@ -1552,7 +1568,7 @@ int KYTY_SYSV_ABI EpollWait(int eid, NetEpollEvent* events, int maxevents, int t return count; #else (void)timeout; - return SetPosixSocketError(Posix::POSIX_ENOSYS); + return SetGuestSocketError(Posix::POSIX_ENOSYS); #endif } @@ -1560,7 +1576,7 @@ int KYTY_SYSV_ABI EpollDestroy(int eid) { std::lock_guard lock(g_epoll_mutex); auto* slot = GetEpollSlot(eid); if (slot == nullptr) { - return SetPosixSocketError(Posix::POSIX_EBADF); + return SetGuestSocketError(Posix::POSIX_EBADF); } slot->used = false; @@ -1582,14 +1598,15 @@ int KYTY_SYSV_ABI SocketClose(int s) { RemoveSocketFromEpolls(s); #if defined(_WIN32) - if (closesocket(socket) == SOCKET_ERROR) { + const int result = closesocket(socket); +#else + const int result = ::close(socket); +#endif + if (result != 0) { return NET_ERROR_EBADF; } return OK; -#else - return NET_ERROR_ENOSYS; -#endif } int KYTY_SYSV_ABI Socket(int family, int type, int protocol) { @@ -1601,7 +1618,7 @@ int KYTY_SYSV_ABI Socket(int family, int type, int protocol) { family, type, protocol); if (!EnsureSocketBackend()) { - return SetPosixSocketError(Posix::POSIX_ENETDOWN); + return SetGuestSocketError(Posix::POSIX_ENETDOWN); } const int host_family = ConvertFamily(family); @@ -1610,25 +1627,24 @@ int KYTY_SYSV_ABI Socket(int family, int type, int protocol) { return -1; } -#if defined(_WIN32) NativeSocket socket = ::socket(host_family, type, protocol); if (socket == INVALID_NATIVE_SOCKET) { - return SetPosixSocketError(); + return SetHostSocketError(); } const int fd = AllocSocketFd(socket); if (fd < 0) { +#if defined(_WIN32) closesocket(socket); +#else + ::close(socket); +#endif *Posix::GetErrorAddr() = Posix::POSIX_EMFILE; return -1; } LOGF("\t fd = %d\n", fd); return fd; -#else - *Posix::GetErrorAddr() = Posix::POSIX_ENOSYS; - return -1; -#endif } int KYTY_SYSV_ABI Bind(int s, const void* addr, uint32_t addrlen) { @@ -1645,23 +1661,17 @@ int KYTY_SYSV_ABI Bind(int s, const void* addr, uint32_t addrlen) { return -1; } -#if defined(_WIN32) sockaddr_storage host_addr {}; - int host_addrlen = 0; + SocketLength host_addrlen = 0; if (ConvertGuestSockaddr(addr, addrlen, &host_addr, &host_addrlen) != 0) { return -1; } - if (::bind(socket, reinterpret_cast(&host_addr), host_addrlen) == - SOCKET_ERROR) { - return SetPosixSocketError(); + if (::bind(socket, reinterpret_cast(&host_addr), host_addrlen) != 0) { + return SetHostSocketError(); } return 0; -#else - *Posix::GetErrorAddr() = Posix::POSIX_ENOSYS; - return -1; -#endif } int KYTY_SYSV_ABI Connect(int s, const void* addr, uint32_t addrlen) { @@ -1687,7 +1697,7 @@ int KYTY_SYSV_ABI Connect(int s, const void* addr, uint32_t addrlen) { if (::connect(socket, reinterpret_cast(&host_addr), host_addrlen) == SOCKET_ERROR) { - return SetPosixSocketError(); + return SetHostSocketError(); } return 0; @@ -1712,7 +1722,7 @@ int KYTY_SYSV_ABI Listen(int s, int backlog) { #if defined(_WIN32) if (::listen(socket, backlog) == SOCKET_ERROR) { - return SetPosixSocketError(); + return SetHostSocketError(); } return 0; @@ -1742,7 +1752,7 @@ int KYTY_SYSV_ABI Accept(int s, void* addr, uint32_t* addrlen) { NativeSocket accepted = ::accept(socket, reinterpret_cast(&host_addr), &host_addrlen); if (accepted == INVALID_NATIVE_SOCKET) { - return SetPosixSocketError(); + return SetHostSocketError(); } const int fd = AllocSocketFd(accepted); @@ -1791,7 +1801,7 @@ int KYTY_SYSV_ABI Shutdown(int s, int how) { #if defined(_WIN32) if (::shutdown(socket, how) == SOCKET_ERROR) { - return SetPosixSocketError(); + return SetHostSocketError(); } return 0; @@ -1821,7 +1831,7 @@ int KYTY_SYSV_ABI Getsockname(int s, void* addr, uint32_t* addrlen) { int host_addrlen = sizeof(host_addr); if (::getsockname(socket, reinterpret_cast(&host_addr), &host_addrlen) == SOCKET_ERROR) { - return SetPosixSocketError(); + return SetHostSocketError(); } return ConvertHostSockaddr(&host_addr, host_addrlen, addr, addrlen); @@ -1850,7 +1860,7 @@ int KYTY_SYSV_ABI Getsockopt(int s, int level, int optname, void* optval, uint32 int len = static_cast(*optlen); if (::getsockopt(socket, ConvertSocketOptionLevel(level), optname, static_cast(optval), &len) == SOCKET_ERROR) { - return SetPosixSocketError(); + return SetHostSocketError(); } *optlen = static_cast(len); return 0; @@ -1881,14 +1891,14 @@ int KYTY_SYSV_ABI Setsockopt(int s, int level, int optname, const void* optval, optlen >= sizeof(int)) { u_long enabled = (*static_cast(optval) != 0 ? 1 : 0); if (ioctlsocket(socket, FIONBIO, &enabled) == SOCKET_ERROR) { - return SetPosixSocketError(); + return SetHostSocketError(); } return 0; } if (::setsockopt(socket, ConvertSocketOptionLevel(level), optname, static_cast(optval), static_cast(optlen)) == SOCKET_ERROR) { - return SetPosixSocketError(); + return SetHostSocketError(); } return 0; @@ -1941,7 +1951,7 @@ int64_t KYTY_SYSV_ABI Sendto(int s, const void* buf, uint64_t len, int flags, co reinterpret_cast(&host_addr), host_addrlen); } if (result == SOCKET_ERROR) { - return SetPosixSocketError(); + return SetHostSocketError(); } return result; @@ -2000,7 +2010,7 @@ int64_t KYTY_SYSV_ABI Recvfrom(int s, void* buf, uint64_t len, int flags, void* } } if (result == SOCKET_ERROR) { - return SetPosixSocketError(); + return SetHostSocketError(); } return result; @@ -2101,7 +2111,7 @@ int KYTY_SYSV_ABI Select(int nfds, void* readfds, void* writefds, void* exceptfd const int result = ::select(0, read_ptr, write_ptr, except_ptr, host_timeout_ptr); if (result == SOCKET_ERROR) { - return SetPosixSocketError(); + return SetHostSocketError(); } GuestFdZero(readfds, nfds);