diff --git a/src/core/libraries/network/net.h b/src/core/libraries/network/net.h index 06ccb27d1..3cbc5ae87 100644 --- a/src/core/libraries/network/net.h +++ b/src/core/libraries/network/net.h @@ -28,6 +28,15 @@ struct OrbisNetSockaddr { char sa_data[14]; }; +struct OrbisNetSockaddrIn { + u8 sin_len; + u8 sin_family; + u16 sin_port; + u32 sin_addr; + u16 sin_vport; + char sin_zero[6]; +}; + struct OrbisNetIovec { void* iov_base; u64 iov_len; diff --git a/src/core/libraries/network/net_error.h b/src/core/libraries/network/net_error.h index 4634b0765..ab65300c0 100644 --- a/src/core/libraries/network/net_error.h +++ b/src/core/libraries/network/net_error.h @@ -22,6 +22,7 @@ constexpr int ORBIS_NET_EAGAIN = 35; constexpr int ORBIS_NET_EWOULDBLOCK = 35; constexpr int ORBIS_NET_EINPROGRESS = 36; constexpr int ORBIS_NET_EALREADY = 37; +constexpr int ORBIS_NET_ENOTSOCK = 38; constexpr int ORBIS_NET_EDESTADDRREQ = 39; constexpr int ORBIS_NET_EMSGSIZE = 40; constexpr int ORBIS_NET_EPROTOTYPE = 41; @@ -33,6 +34,7 @@ constexpr int ORBIS_NET_EADDRINUSE = 48; constexpr int ORBIS_NET_EADDRNOTAVAIL = 49; constexpr int ORBIS_NET_ENETDOWN = 50; constexpr int ORBIS_NET_ENETUNREACH = 51; +constexpr int ORBIS_NET_ENETRESET = 52; constexpr int ORBIS_NET_ECONNABORTED = 53; constexpr int ORBIS_NET_ECONNRESET = 54; constexpr int ORBIS_NET_EISCONN = 56; @@ -40,6 +42,7 @@ constexpr int ORBIS_NET_ENOTCONN = 57; constexpr int ORBIS_NET_ETOOMANYREFS = 59; constexpr int ORBIS_NET_ETIMEDOUT = 60; constexpr int ORBIS_NET_ECONNREFUSED = 61; +constexpr int ORBIS_NET_ELOOP = 62; constexpr int ORBIS_NET_ENAMETOOLONG = 63; constexpr int ORBIS_NET_EHOSTDOWN = 64; constexpr int ORBIS_NET_EHOSTUNREACH = 65; @@ -99,6 +102,7 @@ constexpr int ORBIS_NET_ERROR_EAGAIN = 0x80410123; constexpr int ORBIS_NET_ERROR_EWOULDBLOCK = 0x80410123; constexpr int ORBIS_NET_ERROR_EINPROGRESS = 0x80410124; constexpr int ORBIS_NET_ERROR_EALREADY = 0x80410125; +constexpr int ORBIS_NET_ERROR_ENOTSOCK = 0x80410126; constexpr int ORBIS_NET_ERROR_EDESTADDRREQ = 0x80410127; constexpr int ORBIS_NET_ERROR_EMSGSIZE = 0x80410128; constexpr int ORBIS_NET_ERROR_EPROTOTYPE = 0x80410129; @@ -111,6 +115,7 @@ constexpr int ORBIS_NET_ERROR_EADDRINUSE = 0x80410130; constexpr int ORBIS_NET_ERROR_EADDRNOTAVAIL = 0x80410131; constexpr int ORBIS_NET_ERROR_ENETDOWN = 0x80410132; constexpr int ORBIS_NET_ERROR_ENETUNREACH = 0x80410133; +constexpr int ORBIS_NET_ERROR_ENETRESET = 0x80410134; constexpr int ORBIS_NET_ERROR_ECONNABORTED = 0x80410135; constexpr int ORBIS_NET_ERROR_ECONNRESET = 0x80410136; constexpr int ORBIS_NET_ERROR_ENOBUFS = 0x80410137; @@ -120,6 +125,7 @@ constexpr int ORBIS_NET_ERROR_ESHUTDOWN = 0x8041013a; constexpr int ORBIS_NET_ERROR_ETOOMANYREFS = 0x8041013b; constexpr int ORBIS_NET_ERROR_ETIMEDOUT = 0x8041013c; constexpr int ORBIS_NET_ERROR_ECONNREFUSED = 0x8041013d; +constexpr int ORBIS_NET_ERROR_ELOOP = 0x8041013e; constexpr int ORBIS_NET_ERROR_ENAMETOOLONG = 0x8041013f; constexpr int ORBIS_NET_ERROR_EHOSTDOWN = 0x80410140; constexpr int ORBIS_NET_ERROR_EHOSTUNREACH = 0x80410141; diff --git a/src/core/libraries/network/posix_sockets.cpp b/src/core/libraries/network/posix_sockets.cpp index 5f36c66f6..0ff21c3be 100644 --- a/src/core/libraries/network/posix_sockets.cpp +++ b/src/core/libraries/network/posix_sockets.cpp @@ -8,6 +8,128 @@ namespace Libraries::Net { +#ifdef _WIN32 +#define ERROR_CASE(errname) \ + case (WSA##errname): \ + return ORBIS_NET_ERROR_##errname; +#else +#define ERROR_CASE(errname) \ + case (errname): \ + return ORBIS_NET_ERROR_##errname; +#endif + +static int ConvertReturnErrorCode(int retval) { + if (retval < 0) { +#ifdef _WIN32 + switch (WSAGetLastError()) { +#else + switch (errno) { +#endif +#ifndef _WIN32 // These errorcodes don't exist in WinSock + ERROR_CASE(EPERM) + ERROR_CASE(ENOENT) + ERROR_CASE(ESRCH) + ERROR_CASE(EIO) + ERROR_CASE(ENXIO) + ERROR_CASE(E2BIG) + ERROR_CASE(ENOEXEC) + ERROR_CASE(EDEADLK) + ERROR_CASE(ENOMEM) + ERROR_CASE(ECHILD) + ERROR_CASE(EBUSY) + ERROR_CASE(EEXIST) + ERROR_CASE(EXDEV) + ERROR_CASE(ENODEV) + ERROR_CASE(ENOTDIR) + ERROR_CASE(EISDIR) + ERROR_CASE(ENFILE) + ERROR_CASE(ENOTTY) + ERROR_CASE(ETXTBSY) + ERROR_CASE(EFBIG) + ERROR_CASE(ENOSPC) + ERROR_CASE(ESPIPE) + ERROR_CASE(EROFS) + ERROR_CASE(EMLINK) + ERROR_CASE(EPIPE) + ERROR_CASE(EDOM) + ERROR_CASE(ERANGE) + ERROR_CASE(ENOLCK) + ERROR_CASE(ENOSYS) + ERROR_CASE(EIDRM) + ERROR_CASE(EOVERFLOW) + ERROR_CASE(EILSEQ) + ERROR_CASE(ENOTSUP) + ERROR_CASE(ECANCELED) + ERROR_CASE(EBADMSG) + ERROR_CASE(ENODATA) + ERROR_CASE(ENOSR) + ERROR_CASE(ENOSTR) + ERROR_CASE(ETIME) +#endif + ERROR_CASE(EINTR) + ERROR_CASE(EBADF) + ERROR_CASE(EACCES) + ERROR_CASE(EFAULT) + ERROR_CASE(EINVAL) + ERROR_CASE(EMFILE) + ERROR_CASE(EWOULDBLOCK) + ERROR_CASE(EINPROGRESS) + ERROR_CASE(EALREADY) + ERROR_CASE(ENOTSOCK) + ERROR_CASE(EDESTADDRREQ) + ERROR_CASE(EMSGSIZE) + ERROR_CASE(EPROTOTYPE) + ERROR_CASE(ENOPROTOOPT) + ERROR_CASE(EPROTONOSUPPORT) +#if defined(__APPLE__) || defined(_WIN32) + ERROR_CASE(EOPNOTSUPP) +#endif + ERROR_CASE(EAFNOSUPPORT) + ERROR_CASE(EADDRINUSE) + ERROR_CASE(EADDRNOTAVAIL) + ERROR_CASE(ENETDOWN) + ERROR_CASE(ENETUNREACH) + ERROR_CASE(ENETRESET) + ERROR_CASE(ECONNABORTED) + ERROR_CASE(ECONNRESET) + ERROR_CASE(ENOBUFS) + ERROR_CASE(EISCONN) + ERROR_CASE(ENOTCONN) + ERROR_CASE(ETIMEDOUT) + ERROR_CASE(ECONNREFUSED) + ERROR_CASE(ELOOP) + ERROR_CASE(ENAMETOOLONG) + ERROR_CASE(EHOSTUNREACH) + ERROR_CASE(ENOTEMPTY) + } + return ORBIS_NET_ERROR_EINTERNAL; + } + // if it is 0 or positive return it as it is + return retval; +} + +static void convertOrbisNetSockaddrToPosix(const OrbisNetSockaddr* src, sockaddr* dst) { + if (src == nullptr || dst == nullptr) + return; + memset(dst, 0, sizeof(sockaddr)); + const OrbisNetSockaddrIn* src_in = (const OrbisNetSockaddrIn*)src; + sockaddr_in* dst_in = (sockaddr_in*)dst; + dst_in->sin_family = src_in->sin_family; + dst_in->sin_port = src_in->sin_port; + memcpy(&dst_in->sin_addr, &src_in->sin_addr, 4); +} + +static void convertPosixSockaddrToOrbis(sockaddr* src, OrbisNetSockaddr* dst) { + if (src == nullptr || dst == nullptr) + return; + memset(dst, 0, sizeof(OrbisNetSockaddr)); + OrbisNetSockaddrIn* dst_in = (OrbisNetSockaddrIn*)dst; + sockaddr_in* src_in = (sockaddr_in*)src; + dst_in->sin_family = static_cast(src_in->sin_family); + dst_in->sin_port = src_in->sin_port; + memcpy(&dst_in->sin_addr, &src_in->sin_addr, 4); +} + int PosixSocket::Close() { return 0; }