[bsd, ssl] fix connection between bsd:u and bsd:s and file descriptor copy (#3172)
as seen in repeated epic games api connection in sonic Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3172 Reviewed-by: Caio Oliveira <caiooliveirafarias0@gmail.com> Reviewed-by: CamilleLaVey <camillelavey99@gmail.com> Co-authored-by: Maufeat <sahyno1996@gmail.com> Co-committed-by: Maufeat <sahyno1996@gmail.com>
This commit is contained in:
parent
1eed7efd09
commit
bf68eede05
|
|
@ -578,7 +578,7 @@ std::pair<s32, Errno> BSD::PollImpl(std::vector<u8>& write_buffer, std::span<con
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Network::PollFD> host_pollfds(fds.size());
|
std::vector<Network::PollFD> host_pollfds(fds.size());
|
||||||
std::transform(fds.begin(), fds.end(), host_pollfds.begin(), [this](PollFD pollfd) {
|
std::transform(fds.begin(), fds.end(), host_pollfds.begin(), [](PollFD pollfd) {
|
||||||
Network::PollFD result;
|
Network::PollFD result;
|
||||||
result.socket = file_descriptors[pollfd.fd]->socket.get();
|
result.socket = file_descriptors[pollfd.fd]->socket.get();
|
||||||
result.events = Translate(pollfd.events);
|
result.events = Translate(pollfd.events);
|
||||||
|
|
@ -657,7 +657,11 @@ Errno BSD::ConnectImpl(s32 fd, std::span<const u8> addr) {
|
||||||
|
|
||||||
const auto result = Translate(file_descriptors[fd]->socket->Connect(Translate(addr_in)));
|
const auto result = Translate(file_descriptors[fd]->socket->Connect(Translate(addr_in)));
|
||||||
if (result != Errno::SUCCESS) {
|
if (result != Errno::SUCCESS) {
|
||||||
LOG_ERROR(Service, "Connect fd={} failed with errno={}", fd, static_cast<int>(result));
|
if (result == Errno::INPROGRESS || result == Errno::AGAIN) {
|
||||||
|
LOG_DEBUG(Service, "Connect fd={} in progress (non-blocking), errno={}", fd, static_cast<int>(result));
|
||||||
|
} else {
|
||||||
|
LOG_ERROR(Service, "Connect fd={} failed with errno={}", fd, static_cast<int>(result));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
LOG_INFO(Service, "Connect fd={} succeeded", fd);
|
LOG_INFO(Service, "Connect fd={} succeeded", fd);
|
||||||
}
|
}
|
||||||
|
|
@ -967,7 +971,11 @@ Expected<s32, Errno> BSD::DuplicateSocketImpl(s32 fd) {
|
||||||
return Unexpected(Errno::MFILE);
|
return Unexpected(Errno::MFILE);
|
||||||
}
|
}
|
||||||
|
|
||||||
file_descriptors[new_fd] = file_descriptors[fd];
|
file_descriptors[new_fd] = FileDescriptor{
|
||||||
|
.socket = file_descriptors[fd]->socket,
|
||||||
|
.flags = file_descriptors[fd]->flags,
|
||||||
|
.is_connection_based = file_descriptors[fd]->is_connection_based,
|
||||||
|
};
|
||||||
return new_fd;
|
return new_fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -179,7 +179,7 @@ private:
|
||||||
|
|
||||||
void BuildErrnoResponse(HLERequestContext& ctx, Errno bsd_errno) const noexcept;
|
void BuildErrnoResponse(HLERequestContext& ctx, Errno bsd_errno) const noexcept;
|
||||||
|
|
||||||
std::array<std::optional<FileDescriptor>, MAX_FD> file_descriptors;
|
static inline std::array<std::optional<FileDescriptor>, MAX_FD> file_descriptors{};
|
||||||
|
|
||||||
/// Callback to parse and handle a received wifi packet.
|
/// Callback to parse and handle a received wifi packet.
|
||||||
void OnProxyPacketReceived(const Network::ProxyPacket& packet);
|
void OnProxyPacketReceived(const Network::ProxyPacket& packet);
|
||||||
|
|
|
||||||
|
|
@ -157,22 +157,24 @@ private:
|
||||||
auto bsd = system.ServiceManager().GetService<Service::Sockets::BSD>("bsd:u");
|
auto bsd = system.ServiceManager().GetService<Service::Sockets::BSD>("bsd:u");
|
||||||
ASSERT_OR_EXECUTE(bsd, { return ResultInternalError; });
|
ASSERT_OR_EXECUTE(bsd, { return ResultInternalError; });
|
||||||
|
|
||||||
// Based on https://switchbrew.org/wiki/SSL_services#SetSocketDescriptor
|
auto res = bsd->DuplicateSocketImpl(fd);
|
||||||
|
if (!res.has_value()) {
|
||||||
|
LOG_ERROR(Service_SSL, "Failed to duplicate socket with fd {}", fd);
|
||||||
|
return ResultInvalidSocket;
|
||||||
|
}
|
||||||
|
|
||||||
|
const s32 duplicated_fd = *res;
|
||||||
|
|
||||||
if (do_not_close_socket) {
|
if (do_not_close_socket) {
|
||||||
auto res = bsd->DuplicateSocketImpl(fd);
|
*out_fd = duplicated_fd;
|
||||||
if (!res.has_value()) {
|
|
||||||
LOG_ERROR(Service_SSL, "Failed to duplicate socket with fd {}", fd);
|
|
||||||
return ResultInvalidSocket;
|
|
||||||
}
|
|
||||||
fd = *res;
|
|
||||||
fd_to_close = fd;
|
|
||||||
*out_fd = fd;
|
|
||||||
} else {
|
} else {
|
||||||
*out_fd = -1;
|
*out_fd = -1;
|
||||||
|
fd_to_close = duplicated_fd;
|
||||||
}
|
}
|
||||||
std::optional<std::shared_ptr<Network::SocketBase>> sock = bsd->GetSocket(fd);
|
|
||||||
|
std::optional<std::shared_ptr<Network::SocketBase>> sock = bsd->GetSocket(duplicated_fd);
|
||||||
if (!sock.has_value()) {
|
if (!sock.has_value()) {
|
||||||
LOG_ERROR(Service_SSL, "invalid socket fd {}", fd);
|
LOG_ERROR(Service_SSL, "invalid socket fd {} after duplication", duplicated_fd);
|
||||||
return ResultInvalidSocket;
|
return ResultInvalidSocket;
|
||||||
}
|
}
|
||||||
socket = std::move(*sock);
|
socket = std::move(*sock);
|
||||||
|
|
@ -325,7 +327,19 @@ private:
|
||||||
res = backend->GetServerCerts(&certs);
|
res = backend->GetServerCerts(&certs);
|
||||||
if (res == ResultSuccess) {
|
if (res == ResultSuccess) {
|
||||||
const std::vector<u8> certs_buf = SerializeServerCerts(certs);
|
const std::vector<u8> certs_buf = SerializeServerCerts(certs);
|
||||||
ctx.WriteBuffer(certs_buf);
|
if (ctx.CanWriteBuffer()) {
|
||||||
|
const size_t buffer_size = ctx.GetWriteBufferSize();
|
||||||
|
if (certs_buf.size() <= buffer_size) {
|
||||||
|
ctx.WriteBuffer(certs_buf);
|
||||||
|
} else {
|
||||||
|
LOG_WARNING(Service_SSL, "Certificate buffer too small: {} bytes needed, {} bytes available",
|
||||||
|
certs_buf.size(), buffer_size);
|
||||||
|
ctx.WriteBuffer(std::span<const u8>(certs_buf.data(), buffer_size));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
LOG_DEBUG(Service_SSL, "No output buffer provided for certificates ({} bytes)", certs_buf.size());
|
||||||
|
}
|
||||||
|
|
||||||
out.certs_count = static_cast<u32>(certs.size());
|
out.certs_count = static_cast<u32>(certs.size());
|
||||||
out.certs_size = static_cast<u32>(certs_buf.size());
|
out.certs_size = static_cast<u32>(certs_buf.size());
|
||||||
}
|
}
|
||||||
|
|
@ -664,119 +678,119 @@ class ISslServiceForSystem final : public ServiceFramework<ISslServiceForSystem>
|
||||||
{103, D<&ISslServiceForSystem::VerifySignature>, "VerifySignature"}
|
{103, D<&ISslServiceForSystem::VerifySignature>, "VerifySignature"}
|
||||||
};
|
};
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
RegisterHandlers(functions);
|
RegisterHandlers(functions);
|
||||||
};
|
};
|
||||||
|
|
||||||
Result CreateContext() {
|
Result CreateContext() {
|
||||||
LOG_DEBUG(Service_SSL, "(STUBBED) called.");
|
LOG_DEBUG(Service_SSL, "(STUBBED) called.");
|
||||||
|
|
||||||
// TODO (jarrodnorwell)
|
// TODO (jarrodnorwell)
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess;
|
||||||
};
|
};
|
||||||
|
|
||||||
Result GetContextCount() {
|
Result GetContextCount() {
|
||||||
LOG_DEBUG(Service_SSL, "(STUBBED) called.");
|
LOG_DEBUG(Service_SSL, "(STUBBED) called.");
|
||||||
|
|
||||||
// TODO (jarrodnorwell)
|
// TODO (jarrodnorwell)
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess;
|
||||||
};
|
};
|
||||||
|
|
||||||
Result GetCertificates() {
|
Result GetCertificates() {
|
||||||
LOG_DEBUG(Service_SSL, "(STUBBED) called.");
|
LOG_DEBUG(Service_SSL, "(STUBBED) called.");
|
||||||
|
|
||||||
// TODO (jarrodnorwell)
|
// TODO (jarrodnorwell)
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess;
|
||||||
};
|
};
|
||||||
|
|
||||||
Result GetCertificateBufSize() {
|
Result GetCertificateBufSize() {
|
||||||
LOG_DEBUG(Service_SSL, "(STUBBED) called.");
|
LOG_DEBUG(Service_SSL, "(STUBBED) called.");
|
||||||
|
|
||||||
// TODO (jarrodnorwell)
|
// TODO (jarrodnorwell)
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess;
|
||||||
};
|
};
|
||||||
|
|
||||||
Result DebugIoctl() {
|
Result DebugIoctl() {
|
||||||
LOG_DEBUG(Service_SSL, "(STUBBED) called.");
|
LOG_DEBUG(Service_SSL, "(STUBBED) called.");
|
||||||
|
|
||||||
// TODO (jarrodnorwell)
|
// TODO (jarrodnorwell)
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess;
|
||||||
};
|
};
|
||||||
|
|
||||||
Result SetInterfaceVersion() {
|
Result SetInterfaceVersion() {
|
||||||
LOG_DEBUG(Service_SSL, "(STUBBED) called.");
|
LOG_DEBUG(Service_SSL, "(STUBBED) called.");
|
||||||
|
|
||||||
// TODO (jarrodnorwell)
|
// TODO (jarrodnorwell)
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess;
|
||||||
};
|
};
|
||||||
|
|
||||||
Result FlushSessionCache() {
|
Result FlushSessionCache() {
|
||||||
LOG_DEBUG(Service_SSL, "(STUBBED) called.");
|
LOG_DEBUG(Service_SSL, "(STUBBED) called.");
|
||||||
|
|
||||||
// TODO (jarrodnorwell)
|
// TODO (jarrodnorwell)
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess;
|
||||||
};
|
};
|
||||||
|
|
||||||
Result SetDebugOption() {
|
Result SetDebugOption() {
|
||||||
LOG_DEBUG(Service_SSL, "(STUBBED) called.");
|
LOG_DEBUG(Service_SSL, "(STUBBED) called.");
|
||||||
|
|
||||||
// TODO (jarrodnorwell)
|
// TODO (jarrodnorwell)
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess;
|
||||||
};
|
};
|
||||||
|
|
||||||
Result GetDebugOption() {
|
Result GetDebugOption() {
|
||||||
LOG_DEBUG(Service_SSL, "(STUBBED) called.");
|
LOG_DEBUG(Service_SSL, "(STUBBED) called.");
|
||||||
|
|
||||||
// TODO (jarrodnorwell)
|
// TODO (jarrodnorwell)
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess;
|
||||||
};
|
};
|
||||||
|
|
||||||
Result ClearTls12FallbackFlag() {
|
Result ClearTls12FallbackFlag() {
|
||||||
LOG_DEBUG(Service_SSL, "(STUBBED) called.");
|
LOG_DEBUG(Service_SSL, "(STUBBED) called.");
|
||||||
|
|
||||||
// TODO (jarrodnorwell)
|
// TODO (jarrodnorwell)
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess;
|
||||||
};
|
};
|
||||||
|
|
||||||
Result CreateContextForSystem() {
|
Result CreateContextForSystem() {
|
||||||
LOG_DEBUG(Service_SSL, "(STUBBED) called.");
|
LOG_DEBUG(Service_SSL, "(STUBBED) called.");
|
||||||
|
|
||||||
// TODO (jarrodnorwell)
|
// TODO (jarrodnorwell)
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess;
|
||||||
};
|
};
|
||||||
|
|
||||||
Result SetThreadCoreMask() {
|
Result SetThreadCoreMask() {
|
||||||
LOG_DEBUG(Service_SSL, "(STUBBED) called.");
|
LOG_DEBUG(Service_SSL, "(STUBBED) called.");
|
||||||
|
|
||||||
// TODO (jarrodnorwell)
|
// TODO (jarrodnorwell)
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess;
|
||||||
};
|
};
|
||||||
|
|
||||||
Result GetThreadCoreMask() {
|
Result GetThreadCoreMask() {
|
||||||
LOG_DEBUG(Service_SSL, "(STUBBED) called.");
|
LOG_DEBUG(Service_SSL, "(STUBBED) called.");
|
||||||
|
|
||||||
// TODO (jarrodnorwell)
|
// TODO (jarrodnorwell)
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess;
|
||||||
};
|
};
|
||||||
|
|
||||||
Result VerifySignature() {
|
Result VerifySignature() {
|
||||||
LOG_DEBUG(Service_SSL, "(STUBBED) called.");
|
LOG_DEBUG(Service_SSL, "(STUBBED) called.");
|
||||||
|
|
||||||
// TODO (jarrodnorwell)
|
// TODO (jarrodnorwell)
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue