From 788c1fbdf07baab9d6c03ea8a1e3d13dbfe3ee3a Mon Sep 17 00:00:00 2001 From: lizzie Date: Sat, 15 Aug 2026 19:13:31 +0000 Subject: [PATCH] account for timeout --- src/core/internal_network/network.cpp | 12 ++++++++++++ src/core/internal_network/socket_icmp.cpp | 10 ++++++++-- src/core/internal_network/socket_icmp.h | 2 ++ src/core/internal_network/socket_types.h | 6 ++++++ 4 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/core/internal_network/network.cpp b/src/core/internal_network/network.cpp index 3f26f10e61..92f27b4ad9 100644 --- a/src/core/internal_network/network.cpp +++ b/src/core/internal_network/network.cpp @@ -1059,6 +1059,18 @@ Errno Socket::SetSockOpt(Network::SocketLevel level, Network::OptName optname, s return GetAndLogLastError(CallType::Other); } return Errno::INVAL; + } else if (optname == Network::OptName::RCVTIMEO || optname == Network::OptName::SNDTIMEO) { + if (optval.size() >= sizeof(Network::Timeval)) { + Network::Timeval guest_tv{}; + std::memcpy(&guest_tv, optval.data(), sizeof(guest_tv)); + struct timeval tv{}; + tv.tv_sec = guest_tv.tv_sec; + tv.tv_usec = guest_tv.tv_usec; + if (setsockopt(fd, native_level, native_optname, reinterpret_cast(&tv), sizeof(tv)) != SOCKET_ERROR) + return Errno::SUCCESS; + return GetAndLogLastError(CallType::Other); + } + return Errno::INVAL; } if (setsockopt(fd, native_level, native_optname, reinterpret_cast(optval.data()), socklen_t(optval.size())) != SOCKET_ERROR) return Errno::SUCCESS; diff --git a/src/core/internal_network/socket_icmp.cpp b/src/core/internal_network/socket_icmp.cpp index ad250568f9..93807bd750 100644 --- a/src/core/internal_network/socket_icmp.cpp +++ b/src/core/internal_network/socket_icmp.cpp @@ -42,6 +42,11 @@ IcmpSocket::~IcmpSocket() { Errno IcmpSocket::SetSockOpt(Network::SocketLevel level, Network::OptName optname, std::span optval) { LOG_WARNING(Network, "(stubbed) level={},optname={},optval={}", level, optname, optval.size()); + if (optname == Network::OptName::RCVTIMEO) { + if (optval.size() < sizeof(Network::Timeval)) + return Errno::INVAL; + std::memcpy(&rcv_timeo, optval.data(), sizeof(rcv_timeo)); + } return Errno::SUCCESS; } @@ -99,10 +104,11 @@ std::pair IcmpSocket::RecvFrom(int flags, std::span message, Net return {0, Errno::SUCCESS}; // PLEASE DON'T KILL ME, I SWEAR THIS IS LEGITIMATELY THE BEST WAY TO DO IT // IF YOU OPEN socket() GOOGLE WILL STRAIGHT UP IP BAN YOU AFTER 2 HOURS + auto const rcv_timeout = std::max(rcv_timeo.tv_sec, 0); #ifdef __FreeBSD__ - auto const cmd = fmt::format("ping -t 3 -o {}.{}.{}.{}", addr->ip[0], addr->ip[1], addr->ip[2], addr->ip[3]); + auto const cmd = fmt::format("ping -t {} -o {}.{}.{}.{}", rcv_timeout, addr->ip[0], addr->ip[1], addr->ip[2], addr->ip[3]); #elif defined(__linux__) - auto const cmd = fmt::format("ping -c 1 -W 3 {}.{}.{}.{}", addr->ip[0], addr->ip[1], addr->ip[2], addr->ip[3]); + auto const cmd = fmt::format("ping -c 1 -W {} {}.{}.{}.{}", rcv_timeout, addr->ip[0], addr->ip[1], addr->ip[2], addr->ip[3]); #endif if (::system(cmd.c_str()) == 0) { std::vector data{ diff --git a/src/core/internal_network/socket_icmp.h b/src/core/internal_network/socket_icmp.h index 0ba72c456a..0906b1f8cc 100644 --- a/src/core/internal_network/socket_icmp.h +++ b/src/core/internal_network/socket_icmp.h @@ -4,6 +4,7 @@ #pragma once #include +#include "core/internal_network/socket_types.h" #include "core/internal_network/sockets.h" namespace Network { @@ -32,6 +33,7 @@ public: Errno SetNonBlock(bool enable) override; std::vector seq_ident; + Network::Timeval rcv_timeo; }; } // namespace Network diff --git a/src/core/internal_network/socket_types.h b/src/core/internal_network/socket_types.h index 4ae8d5ff62..410aeee510 100644 --- a/src/core/internal_network/socket_types.h +++ b/src/core/internal_network/socket_types.h @@ -348,6 +348,12 @@ struct Linger { }; static_assert(sizeof(Linger) == 8); +struct Timeval { + u64 tv_sec; + u64 tv_usec; +}; +static_assert(sizeof(Timeval) == 16); + /// @brief Cross-platform addrinfo structure (not guest) struct AddrInfo { Domain family;