Browse Source

airplane mode takes priority

lizzie/refactor-networking-12
lizzie 1 month ago
parent
commit
3aea5c941b
  1. 17
      src/core/hle/service/sockets/bsd.cpp
  2. 68
      src/core/internal_network/network.cpp

17
src/core/hle/service/sockets/bsd.cpp

@ -495,7 +495,7 @@ std::pair<s32, Network::Errno> BSD::SocketImpl(Network::Domain domain, Network::
UNIMPLEMENTED_MSG("SOCK_RAW errno management"); UNIMPLEMENTED_MSG("SOCK_RAW errno management");
} }
[[maybe_unused]] const bool unk_flag = (static_cast<u32>(type) & 0x20000000) != 0;
[[maybe_unused]] const bool unk_flag = (u32(type) & 0x20000000) != 0;
UNIMPLEMENTED_IF_MSG(unk_flag, "Unknown flag in type"); UNIMPLEMENTED_IF_MSG(unk_flag, "Unknown flag in type");
type = Network::Type(u32(type) & ~0x20000000); type = Network::Type(u32(type) & ~0x20000000);
@ -505,11 +505,17 @@ std::pair<s32, Network::Errno> BSD::SocketImpl(Network::Domain domain, Network::
return {-1, Network::Errno::MFILE}; return {-1, Network::Errno::MFILE};
} }
if (Settings::values.airplane_mode.GetValue() && IsConnectionBased(type)) {
LOG_ERROR(Service, "Airplane mode is enabled, cannot create socket");
file_descriptors[fd].reset();
return {-1, Network::Errno::NOTCONN};
}
file_descriptors[fd] = FileDescriptor{}; file_descriptors[fd] = FileDescriptor{};
FileDescriptor& descriptor = *file_descriptors[fd]; FileDescriptor& descriptor = *file_descriptors[fd];
// ENONMEM might be thrown here
LOG_INFO(Service, "New socket fd={}", fd);
// ENONMEM might be thrown here
LOG_INFO(Service, "New socket fd={},domain={},type={},prot={}", fd, domain, type, protocol);
auto room_member = Network::GetRoomMember().lock(); auto room_member = Network::GetRoomMember().lock();
if (room_member && room_member->IsConnected()) { if (room_member && room_member->IsConnected()) {
@ -519,11 +525,6 @@ std::pair<s32, Network::Errno> BSD::SocketImpl(Network::Domain domain, Network::
} }
auto const bsd_errno = descriptor.socket->Initialize(domain, type, protocol); auto const bsd_errno = descriptor.socket->Initialize(domain, type, protocol);
descriptor.is_connection_based = IsConnectionBased(type); descriptor.is_connection_based = IsConnectionBased(type);
if (Settings::values.airplane_mode.GetValue() && descriptor.is_connection_based) {
LOG_ERROR(Service, "Airplane mode is enabled, cannot create socket");
file_descriptors[fd].reset();
return {-1, Network::Errno::NOTCONN};
}
if (descriptor.socket->fd == Network::Socket::INVALID_SOCKET) { if (descriptor.socket->fd == Network::Socket::INVALID_SOCKET) {
file_descriptors[fd].reset(); file_descriptors[fd].reset();
return {-1, bsd_errno}; return {-1, bsd_errno};

68
src/core/internal_network/network.cpp

@ -834,8 +834,7 @@ std::string IPv4AddressToString(IPv4Address ip_addr) {
} }
u32 IPv4AddressToInteger(IPv4Address ip_addr) { u32 IPv4AddressToInteger(IPv4Address ip_addr) {
return static_cast<u32>(ip_addr[0]) << 24 | static_cast<u32>(ip_addr[1]) << 16 |
static_cast<u32>(ip_addr[2]) << 8 | static_cast<u32>(ip_addr[3]);
return u32(ip_addr[0]) << 24 | u32(ip_addr[1]) << 16 | u32(ip_addr[2]) << 8 | u32(ip_addr[3]);
} }
std::variant<std::vector<AddrInfo>, GetAddrInfoError> GetAddressInfo(const std::string& host, const std::optional<std::string>& service) { std::variant<std::vector<AddrInfo>, GetAddrInfoError> GetAddressInfo(const std::string& host, const std::optional<std::string>& service) {
@ -890,25 +889,24 @@ std::variant<std::vector<AddrInfo>, GetAddrInfoError> GetAddressInfo(const std::
} }
std::pair<s32, Errno> Poll(std::span<HostPollFD> pollfds, s32 timeout) { std::pair<s32, Errno> Poll(std::span<HostPollFD> pollfds, s32 timeout) {
LOG_DEBUG(Network, "pollfds={},timeout={}", pollfds.size(), timeout);
LOG_DEBUG(Network, "#fds={},timeout={}", pollfds.size(), timeout);
std::vector<WSAPOLLFD> host_pollfds(pollfds.size());
std::vector<WSAPOLLFD> host_pollfds(pollfds.size() + 1);
std::transform(pollfds.begin(), pollfds.end(), host_pollfds.begin(), [](auto const e) { std::transform(pollfds.begin(), pollfds.end(), host_pollfds.begin(), [](auto const e) {
WSAPOLLFD result;
result.fd = e.socket->GetFD();
result.events = TranslatePollEvents(e.events);
result.revents = 0;
return result;
return WSAPOLLFD{
.fd = e.socket->fd,
.events = TranslatePollEvents(e.events),
.revents = 0,
};
}); });
host_pollfds.push_back(WSAPOLLFD{
host_pollfds[host_pollfds.size() - 1] = WSAPOLLFD{
.fd = GetInterruptSocket(), .fd = GetInterruptSocket(),
.events = POLLIN,
.events = TranslatePollEvents(Network::PollEvents::IN_),
.revents = 0, .revents = 0,
});
};
const int result = WSAPoll(host_pollfds.data(), ULONG(host_pollfds.size()), timeout);
if (result == 0) {
auto const res = WSAPoll(host_pollfds.data(), ULONG(host_pollfds.size()), timeout);
if (res == 0) {
ASSERT(std::all_of(host_pollfds.begin(), host_pollfds.end(), [](auto const fd) { ASSERT(std::all_of(host_pollfds.begin(), host_pollfds.end(), [](auto const fd) {
return fd.revents == 0; return fd.revents == 0;
})); }));
@ -918,11 +916,11 @@ std::pair<s32, Errno> Poll(std::span<HostPollFD> pollfds, s32 timeout) {
for (size_t i = 0; i < pollfds.size(); ++i) for (size_t i = 0; i < pollfds.size(); ++i)
pollfds[i].revents = TranslatePollRevents(host_pollfds[i].revents); pollfds[i].revents = TranslatePollRevents(host_pollfds[i].revents);
if (result <= 0) {
ASSERT(result == SOCKET_ERROR);
if (res <= 0) {
ASSERT(res == SOCKET_ERROR);
return {-1, GetAndLogLastError()}; return {-1, GetAndLogLastError()};
} }
return {result, Errno::SUCCESS};
return {res, Errno::SUCCESS};
} }
Socket::~Socket() { Socket::~Socket() {
@ -1053,15 +1051,15 @@ Errno Socket::SetSockOpt(Network::SocketLevel level, Network::OptName optname, s
Network::Linger linger{}; Network::Linger linger{};
std::memcpy(&linger, optval.data(), sizeof(linger)); std::memcpy(&linger, optval.data(), sizeof(linger));
auto const linger_optval = MakeLinger(bool(linger.onoff), linger.linger); auto const linger_optval = MakeLinger(bool(linger.onoff), linger.linger);
return setsockopt(fd, native_level, native_optname, reinterpret_cast<const char*>(&linger_optval), sizeof(linger_optval)) != SOCKET_ERROR
? Errno::SUCCESS
: GetAndLogLastError();
if (setsockopt(fd, native_level, native_optname, reinterpret_cast<const char*>(&linger_optval), sizeof(linger_optval)) == SOCKET_ERROR)
return GetAndLogLastError();
return Errno::SUCCESS;
} }
return Errno::INVAL; return Errno::INVAL;
} }
return setsockopt(fd, native_level, native_optname, reinterpret_cast<const char*>(optval.data()), socklen_t(optval.size())) != SOCKET_ERROR
? Errno::SUCCESS
: GetAndLogLastError();
if (setsockopt(fd, native_level, native_optname, reinterpret_cast<const char*>(optval.data()), socklen_t(optval.size())) == SOCKET_ERROR)
return GetAndLogLastError();
return Errno::SUCCESS;
} }
Errno Socket::Initialize(Domain domain, Type type, Protocol protocol) { Errno Socket::Initialize(Domain domain, Type type, Protocol protocol) {
@ -1074,29 +1072,22 @@ Errno Socket::Initialize(Domain domain, Type type, Protocol protocol) {
std::pair<Socket::AcceptResult, Errno> Socket::Accept() { std::pair<Socket::AcceptResult, Errno> Socket::Accept() {
sockaddr_in addr; sockaddr_in addr;
socklen_t addrlen = sizeof(addr); socklen_t addrlen = sizeof(addr);
const bool wait_for_accept = !is_non_blocking;
auto const wait_for_accept = !is_non_blocking;
if (wait_for_accept) { if (wait_for_accept) {
std::vector<WSAPOLLFD> host_pollfds{
std::array<WSAPOLLFD, 2> host_pollfds{
WSAPOLLFD{fd, POLLIN, 0}, WSAPOLLFD{fd, POLLIN, 0},
WSAPOLLFD{GetInterruptSocket(), POLLIN, 0}, WSAPOLLFD{GetInterruptSocket(), POLLIN, 0},
}; };
while (true) {
const int pollres =
WSAPoll(host_pollfds.data(), static_cast<ULONG>(host_pollfds.size()), -1);
if (host_pollfds[1].revents != 0) {
// Interrupt signaled before a client could be accepted, break
int pollres = 0;
while (pollres <= 0) {
pollres = WSAPoll(host_pollfds.data(), ULONG(host_pollfds.size()), -1);
// Interrupt signaled before a client could be accepted, break
if (host_pollfds[1].revents != 0)
return {AcceptResult{}, Errno::AGAIN}; return {AcceptResult{}, Errno::AGAIN};
}
if (pollres > 0) {
break;
}
} }
} }
const SOCKET new_socket = accept(fd, reinterpret_cast<sockaddr*>(&addr), &addrlen); const SOCKET new_socket = accept(fd, reinterpret_cast<sockaddr*>(&addr), &addrlen);
if (new_socket == INVALID_SOCKET) { if (new_socket == INVALID_SOCKET) {
return {AcceptResult{}, GetAndLogLastError()}; return {AcceptResult{}, GetAndLogLastError()};
} }
@ -1114,7 +1105,6 @@ Errno Socket::Connect(Network::SockAddrIn addr_in) {
if (connect(fd, &host_addr_in, sizeof(host_addr_in)) != SOCKET_ERROR) { if (connect(fd, &host_addr_in, sizeof(host_addr_in)) != SOCKET_ERROR) {
return Errno::SUCCESS; return Errno::SUCCESS;
} }
return GetAndLogLastError(); return GetAndLogLastError();
} }

Loading…
Cancel
Save