aboutsummaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorMaufeat <sahyno1996@gmail.com>2025-12-17 06:32:22 +0100
committercrueter <crueter@eden-emu.dev>2025-12-17 06:32:22 +0100
commitbf68eede05cc825373dc59b2605b213968969d95 (patch)
treee6b589aa67655ea3dce149e9b9261b3787fdd7f0 /src/core
parent1eed7efd09ce9c7cb85cf799711fadd89ecf5a88 (diff)
[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>
Diffstat (limited to 'src/core')
-rw-r--r--src/core/hle/service/sockets/bsd.cpp14
-rw-r--r--src/core/hle/service/sockets/bsd.h2
-rw-r--r--src/core/hle/service/ssl/ssl.cpp124
3 files changed, 81 insertions, 59 deletions
diff --git a/src/core/hle/service/sockets/bsd.cpp b/src/core/hle/service/sockets/bsd.cpp
index d6c06bb9b4..55b428e353 100644
--- a/src/core/hle/service/sockets/bsd.cpp
+++ b/src/core/hle/service/sockets/bsd.cpp
@@ -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;
}
diff --git a/src/core/hle/service/sockets/bsd.h b/src/core/hle/service/sockets/bsd.h
index ccc6a7d7f2..77d17377ca 100644
--- a/src/core/hle/service/sockets/bsd.h
+++ b/src/core/hle/service/sockets/bsd.h
@@ -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);
diff --git a/src/core/hle/service/ssl/ssl.cpp b/src/core/hle/service/ssl/ssl.cpp
index 0b0108bbd5..5a1ae0dbc9 100644
--- a/src/core/hle/service/ssl/ssl.cpp
+++ b/src/core/hle/service/ssl/ssl.cpp
@@ -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;
};
};