diff options
| author | Maufeat <sahyno1996@gmail.com> | 2025-12-17 06:32:22 +0100 |
|---|---|---|
| committer | crueter <crueter@eden-emu.dev> | 2025-12-17 06:32:22 +0100 |
| commit | bf68eede05cc825373dc59b2605b213968969d95 (patch) | |
| tree | e6b589aa67655ea3dce149e9b9261b3787fdd7f0 /src/core | |
| parent | 1eed7efd09ce9c7cb85cf799711fadd89ecf5a88 (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.cpp | 14 | ||||
| -rw-r--r-- | src/core/hle/service/sockets/bsd.h | 2 | ||||
| -rw-r--r-- | src/core/hle/service/ssl/ssl.cpp | 124 |
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; }; }; |
