[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:
@@ -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::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;
|
||||
result.socket = file_descriptors[pollfd.fd]->socket.get();
|
||||
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)));
|
||||
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 {
|
||||
LOG_INFO(Service, "Connect fd={} succeeded", fd);
|
||||
}
|
||||
@@ -967,7 +971,11 @@ Expected<s32, Errno> BSD::DuplicateSocketImpl(s32 fd) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -179,7 +179,7 @@ private:
|
||||
|
||||
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.
|
||||
void OnProxyPacketReceived(const Network::ProxyPacket& packet);
|
||||
|
||||
@@ -157,22 +157,24 @@ private:
|
||||
auto bsd = system.ServiceManager().GetService<Service::Sockets::BSD>("bsd:u");
|
||||
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) {
|
||||
auto res = bsd->DuplicateSocketImpl(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;
|
||||
*out_fd = duplicated_fd;
|
||||
} else {
|
||||
*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()) {
|
||||
LOG_ERROR(Service_SSL, "invalid socket fd {}", fd);
|
||||
LOG_ERROR(Service_SSL, "invalid socket fd {} after duplication", duplicated_fd);
|
||||
return ResultInvalidSocket;
|
||||
}
|
||||
socket = std::move(*sock);
|
||||
@@ -325,7 +327,19 @@ private:
|
||||
res = backend->GetServerCerts(&certs);
|
||||
if (res == ResultSuccess) {
|
||||
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_size = static_cast<u32>(certs_buf.size());
|
||||
}
|
||||
@@ -664,119 +678,119 @@ class ISslServiceForSystem final : public ServiceFramework<ISslServiceForSystem>
|
||||
{103, D<&ISslServiceForSystem::VerifySignature>, "VerifySignature"}
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
|
||||
RegisterHandlers(functions);
|
||||
};
|
||||
|
||||
|
||||
Result CreateContext() {
|
||||
LOG_DEBUG(Service_SSL, "(STUBBED) called.");
|
||||
|
||||
|
||||
// TODO (jarrodnorwell)
|
||||
|
||||
|
||||
return ResultSuccess;
|
||||
};
|
||||
|
||||
|
||||
Result GetContextCount() {
|
||||
LOG_DEBUG(Service_SSL, "(STUBBED) called.");
|
||||
|
||||
|
||||
// TODO (jarrodnorwell)
|
||||
|
||||
|
||||
return ResultSuccess;
|
||||
};
|
||||
|
||||
|
||||
Result GetCertificates() {
|
||||
LOG_DEBUG(Service_SSL, "(STUBBED) called.");
|
||||
|
||||
|
||||
// TODO (jarrodnorwell)
|
||||
|
||||
|
||||
return ResultSuccess;
|
||||
};
|
||||
|
||||
|
||||
Result GetCertificateBufSize() {
|
||||
LOG_DEBUG(Service_SSL, "(STUBBED) called.");
|
||||
|
||||
|
||||
// TODO (jarrodnorwell)
|
||||
|
||||
|
||||
return ResultSuccess;
|
||||
};
|
||||
|
||||
|
||||
Result DebugIoctl() {
|
||||
LOG_DEBUG(Service_SSL, "(STUBBED) called.");
|
||||
|
||||
|
||||
// TODO (jarrodnorwell)
|
||||
|
||||
|
||||
return ResultSuccess;
|
||||
};
|
||||
|
||||
|
||||
Result SetInterfaceVersion() {
|
||||
LOG_DEBUG(Service_SSL, "(STUBBED) called.");
|
||||
|
||||
|
||||
// TODO (jarrodnorwell)
|
||||
|
||||
|
||||
return ResultSuccess;
|
||||
};
|
||||
|
||||
|
||||
Result FlushSessionCache() {
|
||||
LOG_DEBUG(Service_SSL, "(STUBBED) called.");
|
||||
|
||||
|
||||
// TODO (jarrodnorwell)
|
||||
|
||||
|
||||
return ResultSuccess;
|
||||
};
|
||||
|
||||
|
||||
Result SetDebugOption() {
|
||||
LOG_DEBUG(Service_SSL, "(STUBBED) called.");
|
||||
|
||||
|
||||
// TODO (jarrodnorwell)
|
||||
|
||||
|
||||
return ResultSuccess;
|
||||
};
|
||||
|
||||
|
||||
Result GetDebugOption() {
|
||||
LOG_DEBUG(Service_SSL, "(STUBBED) called.");
|
||||
|
||||
|
||||
// TODO (jarrodnorwell)
|
||||
|
||||
|
||||
return ResultSuccess;
|
||||
};
|
||||
|
||||
|
||||
Result ClearTls12FallbackFlag() {
|
||||
LOG_DEBUG(Service_SSL, "(STUBBED) called.");
|
||||
|
||||
|
||||
// TODO (jarrodnorwell)
|
||||
|
||||
|
||||
return ResultSuccess;
|
||||
};
|
||||
|
||||
|
||||
Result CreateContextForSystem() {
|
||||
LOG_DEBUG(Service_SSL, "(STUBBED) called.");
|
||||
|
||||
|
||||
// TODO (jarrodnorwell)
|
||||
|
||||
|
||||
return ResultSuccess;
|
||||
};
|
||||
|
||||
|
||||
Result SetThreadCoreMask() {
|
||||
LOG_DEBUG(Service_SSL, "(STUBBED) called.");
|
||||
|
||||
|
||||
// TODO (jarrodnorwell)
|
||||
|
||||
|
||||
return ResultSuccess;
|
||||
};
|
||||
|
||||
|
||||
Result GetThreadCoreMask() {
|
||||
LOG_DEBUG(Service_SSL, "(STUBBED) called.");
|
||||
|
||||
|
||||
// TODO (jarrodnorwell)
|
||||
|
||||
|
||||
return ResultSuccess;
|
||||
};
|
||||
|
||||
|
||||
Result VerifySignature() {
|
||||
LOG_DEBUG(Service_SSL, "(STUBBED) called.");
|
||||
|
||||
|
||||
// TODO (jarrodnorwell)
|
||||
|
||||
|
||||
return ResultSuccess;
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user