diff --git a/Kernel/API/POSIX/sys/socket.h b/Kernel/API/POSIX/sys/socket.h index 11f1e942dc..e08199be86 100644 --- a/Kernel/API/POSIX/sys/socket.h +++ b/Kernel/API/POSIX/sys/socket.h @@ -52,6 +52,7 @@ extern "C" { #define MSG_CTRUNC 0x2 #define MSG_PEEK 0x4 #define MSG_OOB 0x8 +#define MSG_DONTROUTE 0x10 #define MSG_DONTWAIT 0x40 typedef uint16_t sa_family_t; diff --git a/Kernel/Net/IPv4Socket.cpp b/Kernel/Net/IPv4Socket.cpp index e94ca3758b..3cc09f3f26 100644 --- a/Kernel/Net/IPv4Socket.cpp +++ b/Kernel/Net/IPv4Socket.cpp @@ -210,7 +210,8 @@ ErrorOr IPv4Socket::sendto(OpenFileDescription&, const UserOrKernelBuffe if (!is_connected() && m_peer_address.is_zero()) return set_so_error(EPIPE); - auto routing_decision = route_to(m_peer_address, m_local_address, bound_interface()); + auto allow_using_gateway = (flags & MSG_DONTROUTE) ? AllowUsingGateway::No : AllowUsingGateway::Yes; + auto routing_decision = route_to(m_peer_address, m_local_address, bound_interface(), allow_using_gateway); if (routing_decision.is_zero()) return set_so_error(EHOSTUNREACH); diff --git a/Kernel/Net/Routing.cpp b/Kernel/Net/Routing.cpp index 7630fc48b1..3e5d066301 100644 --- a/Kernel/Net/Routing.cpp +++ b/Kernel/Net/Routing.cpp @@ -139,7 +139,7 @@ static MACAddress multicast_ethernet_address(IPv4Address const& address) return MACAddress { 0x01, 0x00, 0x5e, (u8)(address[1] & 0x7f), address[2], address[3] }; } -RoutingDecision route_to(IPv4Address const& target, IPv4Address const& source, RefPtr const through) +RoutingDecision route_to(IPv4Address const& target, IPv4Address const& source, RefPtr const through, AllowUsingGateway allow_using_gateway) { auto matches = [&](auto& adapter) { if (!through) @@ -206,7 +206,7 @@ RoutingDecision route_to(IPv4Address const& target, IPv4Address const& source, R adapter = local_adapter; next_hop_ip = target; - } else if (gateway_adapter) { + } else if (gateway_adapter && allow_using_gateway == AllowUsingGateway::Yes) { dbgln_if(ROUTING_DEBUG, "Routing: Got adapter for route (using gateway {}): {} ({}/{}) for {}", gateway_adapter->ipv4_gateway(), gateway_adapter->name(), diff --git a/Kernel/Net/Routing.h b/Kernel/Net/Routing.h index 5ec2e706c9..df33b60cb8 100644 --- a/Kernel/Net/Routing.h +++ b/Kernel/Net/Routing.h @@ -25,7 +25,13 @@ enum class UpdateArp { }; void update_arp_table(IPv4Address const&, MACAddress const&, UpdateArp update); -RoutingDecision route_to(IPv4Address const& target, IPv4Address const& source, RefPtr const through = nullptr); + +enum class AllowUsingGateway { + Yes, + No, +}; + +RoutingDecision route_to(IPv4Address const& target, IPv4Address const& source, RefPtr const through = nullptr, AllowUsingGateway = AllowUsingGateway::Yes); MutexProtected>& arp_table(); diff --git a/Userland/Utilities/strace.cpp b/Userland/Utilities/strace.cpp index 662d62f2a0..2edf434154 100644 --- a/Userland/Utilities/strace.cpp +++ b/Userland/Utilities/strace.cpp @@ -607,7 +607,7 @@ static void format_connect(FormattedSyscallBuilder& builder, int socket, const s struct MsgOptions : BitflagBase { static constexpr auto options = { BITFLAG(MSG_TRUNC), BITFLAG(MSG_CTRUNC), BITFLAG(MSG_PEEK), - BITFLAG(MSG_OOB), BITFLAG(MSG_DONTWAIT) + BITFLAG(MSG_OOB), BITFLAG(MSG_DONTROUTE), BITFLAG(MSG_DONTWAIT) // TODO: add MSG_WAITALL once its definition is added }; };