mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2026-10-28 12:38:43 +01:00
* p2p crypto schema * adding p2p keyring * p2p framing and testing * fixups * test fix * missing definations * implementation of host functions * tcp/transport of p2p packets * improvements in binding * guest_net ,improvements and test cases * all mighty clang * fixing macOS tests failures * misc * net_rewrite : net_errors , types and translation schemas * updated fixed chunks transfer on windows * bye bye old net * small updates for the new net * settings and tests * net lib first draft * allow more than 1 P2P instances on from same pc * improved shadnet replies * possible fix for jojo * cleanup * move net files to libaries/net * fixed macOS tests * mighty clang * fixed cmakelists * don't cosume inviation event on client (test code) * fix macOS tests * Large multi-file rework for Signaling and Matching2 network handling / optimization. Consolidates Matching2-signaling and signaling to one process (signaling_handler) General cleanup and consolidation of matching2 context management > nphandler Removal of a lot SIgnaling overall structure cleanup. Matching2: added get and set roommemberdatainternal and the proper type / shadnet call / request / reply. Consolidated signaling/matching2 typedefs to np_types2 Utilized Codex as a reviewer and for general cleanup. * all mighty clang * fixed member attributes * fixed MAPPED address for matching signaling * Fixed sceNpMatching2SignalingGetLocalNetInfo * fixups on net core/library based on fw * improved errno * spilt p2p to net_p2p * some cleanups * fix for localinfo * clang * fix up * cleanups * cleanups * added KernelFstat * fixed fstat * one more fix for fstat... * cleanup old deprecated code * cleanup * General logging cleanup across NP changes. Thanks Stephen! * cleanup based on stephen's suggestions * fixup * fixing tests * blah * fixup * improve memory pools * cleaunp * force https disable option * clang * @stephen's fixes * added network field in settings and ported old network ones --------- Co-authored-by: Metr1k <blackkn1ght1991@gmail.com>
361 lines
14 KiB
C++
361 lines
14 KiB
C++
// SPDX-FileCopyrightText: Copyright 2026 shadPS4 Emulator Project
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
// The guest <-> host translation used by the new libSceNet (src/core/libraries/net): pure
|
|
// functions, tested without sockets.
|
|
|
|
#include <cstddef>
|
|
#include <cstring>
|
|
|
|
#include <gtest/gtest.h>
|
|
|
|
#ifndef _WIN32
|
|
#include <sys/un.h>
|
|
#else
|
|
#include <winsock2.h>
|
|
#include <afunix.h>
|
|
#endif
|
|
|
|
#include "core/libraries/net/net_error.h"
|
|
#include "core/libraries/net/net_translate.h"
|
|
|
|
#ifndef _WIN32
|
|
#include <netinet/tcp.h>
|
|
#endif
|
|
|
|
using namespace Libraries::Net;
|
|
|
|
namespace {
|
|
|
|
OrbisNetSockaddrIn GuestIn(const char* ip, u16 port, u16 vport = 0, u8 sa_len = 16) {
|
|
OrbisNetSockaddrIn in{};
|
|
in.sin_len = sa_len;
|
|
in.sin_family = ORBIS_NET_AF_INET;
|
|
in.sin_port = htons(port);
|
|
inet_pton(AF_INET, ip, &in.sin_addr);
|
|
in.sin_vport = htons(vport);
|
|
return in;
|
|
}
|
|
|
|
const OrbisNetSockaddr* AsGuest(const void* p) {
|
|
return static_cast<const OrbisNetSockaddr*>(p);
|
|
}
|
|
|
|
TEST(NetLibTranslate, SocketKinds) {
|
|
int error = 0;
|
|
auto k = ToHostSocketKind(ORBIS_NET_AF_INET, ORBIS_NET_SOCK_STREAM, 0, &error);
|
|
ASSERT_TRUE(k);
|
|
EXPECT_EQ(k->family, AF_INET);
|
|
EXPECT_EQ(k->type, SOCK_STREAM);
|
|
EXPECT_FALSE(k->p2p);
|
|
|
|
k = ToHostSocketKind(ORBIS_NET_AF_INET, ORBIS_NET_SOCK_DGRAM, ORBIS_NET_IPPROTO_UDP, &error);
|
|
ASSERT_TRUE(k);
|
|
EXPECT_EQ(k->type, SOCK_DGRAM);
|
|
EXPECT_EQ(k->protocol, IPPROTO_UDP);
|
|
|
|
// IPv4-only stack: no IPv6 sockets, P2P included.
|
|
for (const int type : {ORBIS_NET_SOCK_STREAM, ORBIS_NET_SOCK_DGRAM, ORBIS_NET_SOCK_DGRAM_P2P}) {
|
|
error = 0;
|
|
EXPECT_FALSE(ToHostSocketKind(ORBIS_NET_AF_INET6, type, 0, &error));
|
|
EXPECT_EQ(error, ORBIS_NET_EPROTONOSUPPORT); // sceNetSocket's code for a bad family
|
|
}
|
|
|
|
k = ToHostSocketKind(ORBIS_NET_AF_INET, ORBIS_NET_SOCK_STREAM_P2P, 0, &error);
|
|
ASSERT_TRUE(k);
|
|
EXPECT_TRUE(k->p2p);
|
|
EXPECT_EQ(k->type, SOCK_STREAM);
|
|
k = ToHostSocketKind(ORBIS_NET_AF_INET, ORBIS_NET_SOCK_DGRAM_P2P, 0, &error);
|
|
ASSERT_TRUE(k);
|
|
EXPECT_TRUE(k->p2p);
|
|
EXPECT_EQ(k->type, SOCK_DGRAM);
|
|
|
|
// AF_UNIX: stream and datagram, protocol 0, never P2P.
|
|
k = ToHostSocketKind(ORBIS_NET_AF_UNIX, ORBIS_NET_SOCK_DGRAM, 0, &error);
|
|
ASSERT_TRUE(k);
|
|
EXPECT_EQ(k->family, AF_UNIX);
|
|
EXPECT_EQ(k->type, SOCK_DGRAM);
|
|
EXPECT_EQ(k->protocol, 0);
|
|
EXPECT_FALSE(ToHostSocketKind(ORBIS_NET_AF_UNIX, ORBIS_NET_SOCK_DGRAM_P2P, 0, &error));
|
|
EXPECT_EQ(error, ORBIS_NET_EPROTONOSUPPORT);
|
|
|
|
EXPECT_FALSE(ToHostSocketKind(99, ORBIS_NET_SOCK_STREAM, 0, &error));
|
|
EXPECT_EQ(error, ORBIS_NET_EPROTONOSUPPORT);
|
|
// Non-RAW types take 0 or their own protocol; anything else is EPROTOTYPE.
|
|
EXPECT_FALSE(
|
|
ToHostSocketKind(ORBIS_NET_AF_INET, ORBIS_NET_SOCK_DGRAM, ORBIS_NET_IPPROTO_TCP, &error));
|
|
EXPECT_EQ(error, ORBIS_NET_EPROTOTYPE);
|
|
EXPECT_FALSE(ToHostSocketKind(ORBIS_NET_AF_INET, ORBIS_NET_SOCK_DGRAM_P2P,
|
|
ORBIS_NET_IPPROTO_UDP, &error));
|
|
EXPECT_EQ(error, ORBIS_NET_EPROTOTYPE);
|
|
EXPECT_TRUE(
|
|
ToHostSocketKind(ORBIS_NET_AF_INET, ORBIS_NET_SOCK_RAW, ORBIS_NET_IPPROTO_ICMP, &error));
|
|
EXPECT_FALSE(ToHostSocketKind(ORBIS_NET_AF_INET, 77, 0, &error));
|
|
EXPECT_EQ(error, ORBIS_NET_EPROTONOSUPPORT);
|
|
|
|
EXPECT_EQ(ToOrbisSocketType(SOCK_STREAM, false), static_cast<int>(ORBIS_NET_SOCK_STREAM));
|
|
EXPECT_EQ(ToOrbisSocketType(SOCK_DGRAM, true), static_cast<int>(ORBIS_NET_SOCK_DGRAM_P2P));
|
|
EXPECT_EQ(ToOrbisSocketType(SOCK_STREAM, true), static_cast<int>(ORBIS_NET_SOCK_STREAM_P2P));
|
|
EXPECT_EQ(ToOrbisFamily(AF_INET6), static_cast<int>(ORBIS_NET_AF_INET6));
|
|
}
|
|
|
|
TEST(NetLibTranslate, Ipv4SockaddrBothWays) {
|
|
// sa_len is not trusted: games often leave it 0.
|
|
for (const u8 sa_len : {u8{16}, u8{0}}) {
|
|
const auto guest = GuestIn("192.0.2.7", 3658, 0, sa_len);
|
|
sockaddr_storage host{};
|
|
socklen_t len = 0;
|
|
ASSERT_EQ(ToHostSockaddr(AsGuest(&guest), sizeof(guest), &host, &len), 0);
|
|
ASSERT_EQ(len, static_cast<socklen_t>(sizeof(sockaddr_in)));
|
|
const auto* in = reinterpret_cast<const sockaddr_in*>(&host);
|
|
EXPECT_EQ(in->sin_family, AF_INET);
|
|
EXPECT_EQ(ntohs(in->sin_port), 3658);
|
|
char text[32];
|
|
inet_ntop(AF_INET, &in->sin_addr, text, sizeof(text));
|
|
EXPECT_STREQ(text, "192.0.2.7");
|
|
}
|
|
|
|
sockaddr_in host{};
|
|
host.sin_family = AF_INET;
|
|
host.sin_port = htons(80);
|
|
inet_pton(AF_INET, "10.1.2.3", &host.sin_addr);
|
|
OrbisNetSockaddrIn back{};
|
|
u32 len = sizeof(back);
|
|
ToOrbisSockaddr(reinterpret_cast<sockaddr*>(&host), sizeof(host),
|
|
reinterpret_cast<OrbisNetSockaddr*>(&back), &len);
|
|
EXPECT_EQ(len, 16u);
|
|
EXPECT_EQ(back.sin_len, 16);
|
|
EXPECT_EQ(back.sin_family, ORBIS_NET_AF_INET);
|
|
EXPECT_EQ(back.sin_port, htons(80));
|
|
EXPECT_EQ(back.sin_vport, 0);
|
|
}
|
|
|
|
TEST(NetLibTranslate, Ipv6Sockaddr) {
|
|
OrbisNetSockaddrIn6 guest{};
|
|
guest.sin6_len = sizeof(guest);
|
|
guest.sin6_family = ORBIS_NET_AF_INET6;
|
|
guest.sin6_port = htons(443);
|
|
guest.sin6_scope_id = 3;
|
|
inet_pton(AF_INET6, "2001:db8::1", guest.sin6_addr);
|
|
sockaddr_storage host{};
|
|
socklen_t len = 0;
|
|
ASSERT_EQ(ToHostSockaddr(AsGuest(&guest), sizeof(guest), &host, &len), 0);
|
|
const auto* in6 = reinterpret_cast<const sockaddr_in6*>(&host);
|
|
EXPECT_EQ(in6->sin6_family, AF_INET6);
|
|
EXPECT_EQ(ntohs(in6->sin6_port), 443);
|
|
EXPECT_EQ(in6->sin6_scope_id, 3u);
|
|
|
|
OrbisNetSockaddrIn6 back{};
|
|
u32 back_len = sizeof(back);
|
|
ToOrbisSockaddr(reinterpret_cast<sockaddr*>(&host), len,
|
|
reinterpret_cast<OrbisNetSockaddr*>(&back), &back_len);
|
|
EXPECT_EQ(back_len, 28u);
|
|
EXPECT_EQ(back.sin6_len, 28);
|
|
EXPECT_EQ(back.sin6_family, ORBIS_NET_AF_INET6);
|
|
EXPECT_EQ(std::memcmp(back.sin6_addr, guest.sin6_addr, 16), 0);
|
|
}
|
|
|
|
TEST(NetLibTranslate, SockaddrErrorsAndTruncation) {
|
|
sockaddr_storage host{};
|
|
socklen_t len = 0;
|
|
EXPECT_EQ(ToHostSockaddr(nullptr, 16, &host, &len), ORBIS_NET_EFAULT);
|
|
const auto guest = GuestIn("1.2.3.4", 1);
|
|
EXPECT_EQ(ToHostSockaddr(AsGuest(&guest), 8, &host, &len), ORBIS_NET_EINVAL); // too short
|
|
auto unknown = guest;
|
|
unknown.sin_family = 99;
|
|
EXPECT_EQ(ToHostSockaddr(AsGuest(&unknown), 16, &host, &len), ORBIS_NET_EAFNOSUPPORT);
|
|
sockaddr_in in{};
|
|
in.sin_family = AF_INET;
|
|
in.sin_port = htons(0x1234);
|
|
u8 buffer[4]{};
|
|
u32 cap = sizeof(buffer);
|
|
ToOrbisSockaddr(reinterpret_cast<sockaddr*>(&in), sizeof(in),
|
|
reinterpret_cast<OrbisNetSockaddr*>(buffer), &cap);
|
|
EXPECT_EQ(cap, 16u);
|
|
EXPECT_EQ(buffer[0], 16);
|
|
EXPECT_EQ(buffer[1], ORBIS_NET_AF_INET);
|
|
EXPECT_EQ(buffer[2], 0x12);
|
|
EXPECT_EQ(buffer[3], 0x34);
|
|
}
|
|
|
|
TEST(NetLibTranslate, UnixAddresses) {
|
|
OrbisNetSockaddrUn guest{};
|
|
guest.sun_len = sizeof(guest);
|
|
guest.sun_family = ORBIS_NET_AF_UNIX;
|
|
std::strcpy(guest.sun_path, "/tmp/shadps4.sock");
|
|
sockaddr_storage host{};
|
|
socklen_t len = 0;
|
|
ASSERT_EQ(
|
|
ToHostSockaddr(reinterpret_cast<OrbisNetSockaddr*>(&guest), sizeof(guest), &host, &len), 0);
|
|
const auto* un = reinterpret_cast<const sockaddr_un*>(&host);
|
|
EXPECT_EQ(un->sun_family, AF_UNIX);
|
|
EXPECT_STREQ(un->sun_path, "/tmp/shadps4.sock");
|
|
EXPECT_EQ(len, offsetof(sockaddr_un, sun_path) + std::strlen("/tmp/shadps4.sock") + 1);
|
|
|
|
OrbisNetSockaddrUn back{};
|
|
u32 back_len = sizeof(back);
|
|
ToOrbisSockaddr(reinterpret_cast<const sockaddr*>(&host), len,
|
|
reinterpret_cast<OrbisNetSockaddr*>(&back), &back_len);
|
|
EXPECT_EQ(back_len, sizeof(OrbisNetSockaddrUn));
|
|
EXPECT_EQ(back.sun_family, ORBIS_NET_AF_UNIX);
|
|
EXPECT_STREQ(back.sun_path, "/tmp/shadps4.sock");
|
|
|
|
// A path that does not fit the host's sun_path.
|
|
std::memset(guest.sun_path, 'a', sizeof(guest.sun_path));
|
|
EXPECT_EQ(
|
|
ToHostSockaddr(reinterpret_cast<OrbisNetSockaddr*>(&guest), sizeof(guest), &host, &len),
|
|
sizeof(guest.sun_path) >= sizeof(un->sun_path) ? ORBIS_NET_ENAMETOOLONG : 0);
|
|
}
|
|
|
|
TEST(NetLibTranslate, P2PDatagramAddresses) {
|
|
// sin_port = the peer's UDP port, sin_vport = the virtual port.
|
|
const auto guest = GuestIn("198.51.100.4", 3658, 5000);
|
|
Core::Net::P2P::Endpoint endpoint;
|
|
u16 vport = 0;
|
|
ASSERT_EQ(ToP2PAddress(AsGuest(&guest), sizeof(guest), P2PKind::Datagram, &endpoint, &vport),
|
|
0);
|
|
EXPECT_EQ(endpoint, Core::Net::P2P::Endpoint::IPv4("198.51.100.4", 3658));
|
|
EXPECT_EQ(vport, 5000); // host byte order
|
|
|
|
OrbisNetSockaddrIn back{};
|
|
u32 len = sizeof(back);
|
|
ToOrbisP2PAddress(endpoint, vport, P2PKind::Datagram,
|
|
reinterpret_cast<OrbisNetSockaddr*>(&back), &len);
|
|
EXPECT_EQ(len, 16u);
|
|
EXPECT_EQ(std::memcmp(&back, &guest, sizeof(back)), 0); // exact round trip
|
|
}
|
|
|
|
TEST(NetLibTranslate, P2PStreamAddresses) {
|
|
// sin_port = the TCP port inside the encapsulation, sin_vport = the peer's UDP port.
|
|
const auto guest = GuestIn("198.51.100.4", 49200, 3659);
|
|
Core::Net::P2P::Endpoint endpoint;
|
|
u16 tcp_port = 0;
|
|
ASSERT_EQ(ToP2PAddress(AsGuest(&guest), sizeof(guest), P2PKind::Stream, &endpoint, &tcp_port),
|
|
0);
|
|
EXPECT_EQ(endpoint, Core::Net::P2P::Endpoint::IPv4("198.51.100.4", 3659));
|
|
EXPECT_EQ(tcp_port, 49200);
|
|
|
|
OrbisNetSockaddrIn back{};
|
|
u32 len = sizeof(back);
|
|
ToOrbisP2PAddress(endpoint, tcp_port, P2PKind::Stream,
|
|
reinterpret_cast<OrbisNetSockaddr*>(&back), &len);
|
|
EXPECT_EQ(std::memcmp(&back, &guest, sizeof(back)), 0);
|
|
|
|
// No UDP port given: the standard PlayStation P2P port.
|
|
const auto no_udp = GuestIn("198.51.100.4", 49200, 0);
|
|
ASSERT_EQ(ToP2PAddress(AsGuest(&no_udp), sizeof(no_udp), P2PKind::Stream, &endpoint, &tcp_port),
|
|
0);
|
|
EXPECT_EQ(endpoint.Port(), DefaultP2PUdpPort);
|
|
}
|
|
|
|
TEST(NetLibTranslate, P2PAddressesAreIPv4Only) {
|
|
auto guest = GuestIn("198.51.100.4", 3658, 5000);
|
|
Core::Net::P2P::Endpoint endpoint;
|
|
u16 port = 0;
|
|
// Exactly 16 bytes: not shorter, and not the 32-byte IPv6 P2P sockaddr either.
|
|
EXPECT_EQ(ToP2PAddress(AsGuest(&guest), 15, P2PKind::Datagram, &endpoint, &port),
|
|
ORBIS_NET_EINVAL);
|
|
EXPECT_EQ(ToP2PAddress(AsGuest(&guest), 32, P2PKind::Datagram, &endpoint, &port),
|
|
ORBIS_NET_EINVAL);
|
|
guest.sin_family = ORBIS_NET_AF_INET6;
|
|
EXPECT_EQ(ToP2PAddress(AsGuest(&guest), sizeof(guest), P2PKind::Stream, &endpoint, &port),
|
|
ORBIS_NET_EAFNOSUPPORT);
|
|
EXPECT_EQ(ToP2PAddress(nullptr, sizeof(guest), P2PKind::Stream, &endpoint, &port),
|
|
ORBIS_NET_EFAULT);
|
|
}
|
|
|
|
TEST(NetLibTranslate, MessageFlags) {
|
|
auto f = ToHostMsgFlags(ORBIS_NET_MSG_PEEK | ORBIS_NET_MSG_DONTWAIT);
|
|
EXPECT_TRUE(f.peek);
|
|
EXPECT_TRUE(f.dontwait);
|
|
EXPECT_EQ(f.host, MSG_PEEK); // DONTWAIT is the guest layer's business
|
|
EXPECT_EQ(f.unsupported, 0);
|
|
|
|
f = ToHostMsgFlags(ORBIS_NET_MSG_WAITALL | 0x20000 /* MSG_NOSIGNAL */);
|
|
EXPECT_EQ(f.host, MSG_WAITALL); // 0x40 on the PS4, 0x100 on Linux, 0x8 on Windows
|
|
EXPECT_EQ(f.unsupported, 0);
|
|
|
|
f = ToHostMsgFlags(ORBIS_NET_MSG_USECRYPTO | ORBIS_NET_MSG_PEEKLEN);
|
|
EXPECT_TRUE(f.peek);
|
|
EXPECT_TRUE(f.peeklen);
|
|
EXPECT_TRUE(f.crypto); // per-message protection is understood now
|
|
EXPECT_FALSE(f.signature);
|
|
EXPECT_EQ(f.unsupported, 0);
|
|
EXPECT_TRUE(ToHostMsgFlags(ORBIS_NET_MSG_WAITALL).waitall);
|
|
EXPECT_EQ(ToHostMsgFlags(0x1 /* MSG_OOB */).unsupported, 0x1);
|
|
}
|
|
|
|
TEST(NetLibTranslate, OutOfBandIsNotPassedThrough) {
|
|
// The PS4's TCP has no urgent data: MSG_OOB is reported, not handed to the host.
|
|
const auto f = ToHostMsgFlags(0x1 | ORBIS_NET_MSG_DONTWAIT);
|
|
EXPECT_EQ(f.host & MSG_OOB, 0);
|
|
EXPECT_EQ(f.unsupported, 0x1);
|
|
EXPECT_TRUE(f.dontwait);
|
|
}
|
|
|
|
TEST(NetLibTranslate, ReservedPorts) {
|
|
// UDP, TCP and TCP over UDPP2P ports.
|
|
for (const u16 port : {1, 80, 1023, 5353, 8540, 8579, 9293, 9310, 40000, 49152, 65535}) {
|
|
EXPECT_TRUE(IsReservedPort(port)) << port;
|
|
}
|
|
for (const u16 port : {0, 1024, 3658, 5352, 5354, 8539, 8580, 9292, 9311, 39999}) {
|
|
EXPECT_FALSE(IsReservedPort(port)) << port;
|
|
}
|
|
// UDPP2P virtual ports.
|
|
for (const u16 vport : {5353, 32768, 49999, 65535}) {
|
|
EXPECT_TRUE(IsReservedP2PVport(vport)) << vport;
|
|
}
|
|
for (const u16 vport : {0, 1, 80, 3658, 32767}) {
|
|
EXPECT_FALSE(IsReservedP2PVport(vport)) << vport;
|
|
}
|
|
}
|
|
|
|
TEST(NetLibTranslate, DefaultBufferSizes) {
|
|
EXPECT_EQ(DefaultSendBuffer(SOCK_STREAM), 32768);
|
|
EXPECT_EQ(DefaultReceiveBuffer(SOCK_STREAM), 65536);
|
|
EXPECT_EQ(DefaultSendBuffer(SOCK_DGRAM), 9216);
|
|
EXPECT_EQ(DefaultReceiveBuffer(SOCK_DGRAM), 40960);
|
|
EXPECT_EQ(DefaultReceiveBuffer(SOCK_RAW), 40960);
|
|
}
|
|
|
|
TEST(NetLibTranslate, OptionsMapByName) {
|
|
// Host numbering differs (on Linux IP_TTL is 2, not 4): the mapping must use host names.
|
|
auto o = ToHostOption(ORBIS_NET_IPPROTO_IP, ORBIS_NET_IP_TTL);
|
|
ASSERT_TRUE(o);
|
|
EXPECT_EQ(o->level, IPPROTO_IP);
|
|
EXPECT_EQ(o->name, IP_TTL);
|
|
o = ToHostOption(ORBIS_NET_IPPROTO_IP, ORBIS_NET_IP_ADD_MEMBERSHIP);
|
|
ASSERT_TRUE(o);
|
|
EXPECT_EQ(o->name, IP_ADD_MEMBERSHIP);
|
|
EXPECT_EQ(o->value, OptionValue::Raw);
|
|
o = ToHostOption(ORBIS_NET_SOL_SOCKET, ORBIS_NET_SO_RCVBUF);
|
|
ASSERT_TRUE(o);
|
|
EXPECT_EQ(o->level, SOL_SOCKET);
|
|
EXPECT_EQ(o->name, SO_RCVBUF);
|
|
o = ToHostOption(ORBIS_NET_SOL_SOCKET, ORBIS_NET_SO_LINGER);
|
|
ASSERT_TRUE(o);
|
|
EXPECT_EQ(o->value, OptionValue::Linger);
|
|
o = ToHostOption(ORBIS_NET_IPPROTO_TCP, ORBIS_NET_TCP_NODELAY);
|
|
ASSERT_TRUE(o);
|
|
EXPECT_EQ(o->name, TCP_NODELAY);
|
|
|
|
// Guest-owned options are not host options.
|
|
EXPECT_FALSE(ToHostOption(ORBIS_NET_SOL_SOCKET, ORBIS_NET_SO_NBIO));
|
|
EXPECT_FALSE(ToHostOption(ORBIS_NET_SOL_SOCKET, ORBIS_NET_SO_RCVTIMEO));
|
|
EXPECT_FALSE(ToHostOption(0x1234, 1));
|
|
}
|
|
|
|
TEST(NetLibTranslate, EpollEventsAndErrors) {
|
|
const u32 all =
|
|
ORBIS_NET_EPOLLIN | ORBIS_NET_EPOLLOUT | ORBIS_NET_EPOLLERR | ORBIS_NET_EPOLLHUP;
|
|
EXPECT_EQ(ToOrbisEpollEvents(ToHostEpollEvents(all)), all);
|
|
EXPECT_EQ(ToHostEpollEvents(ORBIS_NET_EPOLLHUP), static_cast<u32>(Host::EvHup));
|
|
|
|
EXPECT_EQ(ToOrbisErrno(Host::Error::WouldBlock), ORBIS_NET_EWOULDBLOCK);
|
|
EXPECT_EQ(ToOrbisErrno(Host::Error::ConnRefused), ORBIS_NET_ECONNREFUSED);
|
|
EXPECT_EQ(ToOrbisErrno(Host::Error::NotSock), ORBIS_NET_EBADF);
|
|
EXPECT_EQ(ToOrbisErrno(Host::Error::Intr), ORBIS_NET_EINTR);
|
|
}
|
|
|
|
} // namespace
|