fix sockets

This commit is contained in:
lizzie
2026-07-18 23:03:36 +00:00
parent 0330b90f1a
commit 8513d3da7c
2 changed files with 78 additions and 86 deletions
+31 -21
View File
@@ -488,7 +488,7 @@ void BSD::ExecuteWork(HLERequestContext& ctx, Work work) {
}
std::pair<s32, Network::Errno> BSD::SocketImpl(Network::Domain domain, Network::Type type, Network::Protocol protocol) {
LOG_DEBUG(Network, "domain={},type,protocol={}", u32(domain), u32(type), u32(protocol));
if (type == Network::Type::SEQPACKET) {
UNIMPLEMENTED_MSG("SOCK_SEQPACKET errno management");
} else if (type == Network::Type::RAW && (domain != Network::Domain::INET || protocol != Network::Protocol::ICMP)) {
@@ -537,6 +537,7 @@ std::pair<s32, Network::Errno> BSD::SocketImpl(Network::Domain domain, Network::
}
std::pair<s32, Network::Errno> BSD::PollImpl(std::vector<u8>& write_buffer, std::span<const u8> read_buffer, s32 nfds, s32 timeout) {
LOG_DEBUG(Network, "nfds={},timeout={}", nfds, timeout);
if (nfds <= 0) {
// When no entries are provided, -1 is returned with errno zero
return {-1, Network::Errno::SUCCESS};
@@ -590,6 +591,7 @@ std::pair<s32, Network::Errno> BSD::PollImpl(std::vector<u8>& write_buffer, std:
}
std::pair<s32, Network::Errno> BSD::AcceptImpl(s32 fd, std::vector<u8>& write_buffer) {
LOG_DEBUG(Network, "fd={}", fd);
if (!IsFileDescriptorValid(fd)) {
return {-1, Network::Errno::BADF};
}
@@ -616,6 +618,7 @@ std::pair<s32, Network::Errno> BSD::AcceptImpl(s32 fd, std::vector<u8>& write_bu
}
Network::Errno BSD::BindImpl(s32 fd, std::span<const u8> addr) {
LOG_DEBUG(Network, "fd={}", fd);
if (!IsFileDescriptorValid(fd)) {
return Network::Errno::BADF;
}
@@ -630,6 +633,7 @@ Network::Errno BSD::BindImpl(s32 fd, std::span<const u8> addr) {
}
Network::Errno BSD::ConnectImpl(s32 fd, std::span<const u8> addr) {
LOG_DEBUG(Network, "fd={}", fd);
if (!IsFileDescriptorValid(fd)) {
return Network::Errno::BADF;
}
@@ -651,6 +655,7 @@ Network::Errno BSD::ConnectImpl(s32 fd, std::span<const u8> addr) {
}
Network::Errno BSD::GetPeerNameImpl(s32 fd, std::vector<u8>& write_buffer) {
LOG_DEBUG(Network, "fd={}", fd);
if (!IsFileDescriptorValid(fd)) {
return Network::Errno::BADF;
}
@@ -671,6 +676,7 @@ Network::Errno BSD::GetPeerNameImpl(s32 fd, std::vector<u8>& write_buffer) {
}
Network::Errno BSD::GetSockNameImpl(s32 fd, std::vector<u8>& write_buffer) {
LOG_DEBUG(Network, "fd={}", fd);
if (!IsFileDescriptorValid(fd)) {
return Network::Errno::BADF;
}
@@ -691,6 +697,7 @@ Network::Errno BSD::GetSockNameImpl(s32 fd, std::vector<u8>& write_buffer) {
}
Network::Errno BSD::ListenImpl(s32 fd, s32 backlog) {
LOG_DEBUG(Network, "fd={},backlog={}", fd, backlog);
if (!IsFileDescriptorValid(fd)) {
return Network::Errno::BADF;
}
@@ -702,6 +709,7 @@ Network::Errno BSD::ListenImpl(s32 fd, s32 backlog) {
}
std::pair<s32, Network::Errno> BSD::FcntlImpl(s32 fd, Network::FcntlCmd cmd, s32 arg) {
LOG_DEBUG(Network, "fd={},cmd={},arg={}", fd, u32(cmd), arg);
if (!IsFileDescriptorValid(fd)) {
return {-1, Network::Errno::BADF};
}
@@ -711,13 +719,12 @@ std::pair<s32, Network::Errno> BSD::FcntlImpl(s32 fd, Network::FcntlCmd cmd, s32
}
FileDescriptor& descriptor = *file_descriptors[fd];
switch (cmd) {
case Network::FcntlCmd::GETFL:
ASSERT(arg == 0);
return {descriptor.flags, Network::Errno::SUCCESS};
case Network::FcntlCmd::SETFL: {
const bool enable = (arg & u32(Network::FcntlFlags::NONBLOCK_ANY)) != 0;
const bool enable = (arg & u32(Network::FcntlFlags::NONBLOCK_NX)) != 0;
const Network::Errno bsd_errno = descriptor.socket->SetNonBlock(enable);
if (bsd_errno != Network::Errno::SUCCESS) {
return {-1, bsd_errno};
@@ -732,6 +739,7 @@ std::pair<s32, Network::Errno> BSD::FcntlImpl(s32 fd, Network::FcntlCmd cmd, s32
}
Network::Errno BSD::GetSockOptImpl(s32 fd, Network::SocketLevel level, Network::OptName optname, std::vector<u8>& optval) {
LOG_DEBUG(Network, "fd={},level={},optname={}", fd, u32(level), u32(optname));
if (!IsFileDescriptorValid(fd)) {
return Network::Errno::BADF;
}
@@ -775,13 +783,11 @@ Network::Errno BSD::SetSockOptImpl(s32 fd, Network::SocketLevel level, Network::
}
Network::SocketBase* const socket = file_descriptors[fd]->socket.get();
if (level != Network::SocketLevel::SOCKET) {
LOG_WARNING(Service, "(stubbed) level fd={}, level={}, optname={}", fd, level, optname);
}
return socket->SetSockOpt(level, optname, optval);
}
Network::Errno BSD::ShutdownImpl(s32 fd, s32 how) {
LOG_DEBUG(Network, "fd={},how={}", fd, how);
if (!IsFileDescriptorValid(fd)) {
return Network::Errno::BADF;
}
@@ -793,6 +799,7 @@ Network::Errno BSD::ShutdownImpl(s32 fd, s32 how) {
}
std::pair<s32, Network::Errno> BSD::RecvImpl(s32 fd, u32 flags, std::vector<u8>& message) {
LOG_DEBUG(Network, "fd={},flags={}", fd, flags);
if (!IsFileDescriptorValid(fd)) {
return {-1, Network::Errno::BADF};
}
@@ -802,20 +809,20 @@ std::pair<s32, Network::Errno> BSD::RecvImpl(s32 fd, u32 flags, std::vector<u8>&
// Apply flags
if ((flags & u32(Network::MsgOpt::DONTWAIT)) != 0) {
flags &= ~u32(Network::MsgOpt::DONTWAIT);
if ((descriptor.flags & u32(Network::FcntlFlags::NONBLOCK_ANY)) == 0) {
if ((descriptor.flags & u32(Network::FcntlFlags::NONBLOCK_NX)) == 0) {
descriptor.socket->SetNonBlock(true);
}
}
const auto [ret, bsd_errno] = descriptor.socket->Recv(flags, message);
// Restore original state
if ((descriptor.flags & u32(Network::FcntlFlags::NONBLOCK_ANY)) == 0)
if ((descriptor.flags & u32(Network::FcntlFlags::NONBLOCK_NX)) == 0)
descriptor.socket->SetNonBlock(false);
return {ret, bsd_errno};
}
std::pair<s32, Network::Errno> BSD::RecvFromImpl(s32 fd, u32 flags, std::vector<u8>& message,
std::vector<u8>& addr) {
std::pair<s32, Network::Errno> BSD::RecvFromImpl(s32 fd, u32 flags, std::vector<u8>& message, std::vector<u8>& addr) {
LOG_DEBUG(Network, "fd={},flags={}", fd, flags);
if (!IsFileDescriptorValid(fd)) {
return {-1, Network::Errno::BADF};
}
@@ -834,7 +841,7 @@ std::pair<s32, Network::Errno> BSD::RecvFromImpl(s32 fd, u32 flags, std::vector<
// Apply flags
if ((flags & u32(Network::MsgOpt::DONTWAIT)) != 0) {
flags &= ~u32(Network::MsgOpt::DONTWAIT);
if ((descriptor.flags & u32(Network::FcntlFlags::NONBLOCK_ANY)) == 0) {
if ((descriptor.flags & u32(Network::FcntlFlags::NONBLOCK_NX)) == 0) {
descriptor.socket->SetNonBlock(true);
}
}
@@ -842,7 +849,7 @@ std::pair<s32, Network::Errno> BSD::RecvFromImpl(s32 fd, u32 flags, std::vector<
const auto [ret, bsd_errno] = descriptor.socket->RecvFrom(flags, message, p_addr_in);
// Restore original state
if ((descriptor.flags & u32(Network::FcntlFlags::NONBLOCK_ANY)) == 0) {
if ((descriptor.flags & u32(Network::FcntlFlags::NONBLOCK_NX)) == 0) {
descriptor.socket->SetNonBlock(false);
}
@@ -859,6 +866,7 @@ std::pair<s32, Network::Errno> BSD::RecvFromImpl(s32 fd, u32 flags, std::vector<
}
std::pair<s32, Network::Errno> BSD::SendImpl(s32 fd, u32 flags, std::span<const u8> message) {
LOG_DEBUG(Network, "fd={},flags={}", fd, flags);
if (!IsFileDescriptorValid(fd)) {
return {-1, Network::Errno::BADF};
}
@@ -869,8 +877,8 @@ std::pair<s32, Network::Errno> BSD::SendImpl(s32 fd, u32 flags, std::span<const
return file_descriptors[fd]->socket->Send(message, flags);
}
std::pair<s32, Network::Errno> BSD::SendToImpl(s32 fd, u32 flags, std::span<const u8> message,
std::span<const u8> addr) {
std::pair<s32, Network::Errno> BSD::SendToImpl(s32 fd, u32 flags, std::span<const u8> message, std::span<const u8> addr) {
LOG_DEBUG(Network, "fd={},flags={}", fd, flags);
if (!IsFileDescriptorValid(fd)) {
return {-1, Network::Errno::BADF};
}
@@ -892,6 +900,7 @@ std::pair<s32, Network::Errno> BSD::SendToImpl(s32 fd, u32 flags, std::span<cons
}
Network::Errno BSD::CloseImpl(s32 fd) {
LOG_DEBUG(Network, "fd={}", fd);
if (!IsFileDescriptorValid(fd)) {
return Network::Errno::BADF;
}
@@ -912,6 +921,7 @@ Network::Errno BSD::CloseImpl(s32 fd) {
}
std::variant<s32, Network::Errno> BSD::DuplicateSocketImpl(s32 fd) {
LOG_DEBUG(Network, "fd={}", fd);
if (!IsFileDescriptorValid(fd)) {
return Network::Errno::BADF;
}
@@ -931,6 +941,7 @@ std::variant<s32, Network::Errno> BSD::DuplicateSocketImpl(s32 fd) {
}
std::optional<std::shared_ptr<Network::SocketBase>> BSD::GetSocket(s32 fd) {
LOG_DEBUG(Network, "fd={}", fd);
if (!IsFileDescriptorValid(fd)) {
return std::nullopt;
}
@@ -951,12 +962,12 @@ s32 BSD::FindFreeFileDescriptorHandle() noexcept {
}
bool BSD::IsFileDescriptorValid(s32 fd) const noexcept {
if (fd > s32(MAX_FD) || fd < 0) {
LOG_ERROR(Service, "Invalid file descriptor handle={}", fd);
if (fd < 0 || fd >= s32(file_descriptors.size())) {
LOG_ERROR(Service, "Invalid handle={}", fd);
return false;
}
if (!file_descriptors[fd]) {
LOG_ERROR(Service, "File descriptor handle={} is not allocated", fd);
LOG_ERROR(Service, "handle={} is not allocated", fd);
return false;
}
return true;
@@ -972,11 +983,10 @@ void BSD::BuildErrnoResponse(HLERequestContext& ctx, Network::Errno bsd_errno) c
void BSD::OnProxyPacketReceived(const Network::ProxyPacket& packet) {
for (auto& optional_descriptor : file_descriptors) {
if (!optional_descriptor.has_value()) {
continue;
if (optional_descriptor.has_value()) {
FileDescriptor& descriptor = *optional_descriptor;
descriptor.socket.get()->HandleProxyPacket(packet);
}
FileDescriptor& descriptor = *optional_descriptor;
descriptor.socket.get()->HandleProxyPacket(packet);
}
}