diff options
-rw-r--r-- | Kernel/API/POSIX/sys/socket.h | 2 | ||||
-rw-r--r-- | Kernel/Net/IPv4Socket.cpp | 2 | ||||
-rw-r--r-- | Kernel/Net/Socket.cpp | 16 | ||||
-rw-r--r-- | Kernel/Net/Socket.h | 2 |
4 files changed, 20 insertions, 2 deletions
diff --git a/Kernel/API/POSIX/sys/socket.h b/Kernel/API/POSIX/sys/socket.h index c32dc92c34..9dce41f43f 100644 --- a/Kernel/API/POSIX/sys/socket.h +++ b/Kernel/API/POSIX/sys/socket.h @@ -109,6 +109,7 @@ enum { SO_BROADCAST, SO_LINGER, SO_ACCEPTCONN, + SO_DONTROUTE, }; #define SO_RCVTIMEO SO_RCVTIMEO #define SO_SNDTIMEO SO_SNDTIMEO @@ -125,6 +126,7 @@ enum { #define SO_RCVBUF SO_RCVBUF #define SO_LINGER SO_LINGER #define SO_ACCEPTCONN SO_ACCEPTCONN +#define SO_DONTROUTE SO_DONTROUTE enum { SCM_TIMESTAMP, diff --git a/Kernel/Net/IPv4Socket.cpp b/Kernel/Net/IPv4Socket.cpp index 1b0445d94a..fb0a19052a 100644 --- a/Kernel/Net/IPv4Socket.cpp +++ b/Kernel/Net/IPv4Socket.cpp @@ -210,7 +210,7 @@ ErrorOr<size_t> IPv4Socket::sendto(OpenFileDescription&, const UserOrKernelBuffe if (!is_connected() && m_peer_address.is_zero()) return set_so_error(EPIPE); - auto allow_using_gateway = (flags & MSG_DONTROUTE) ? AllowUsingGateway::No : AllowUsingGateway::Yes; + auto allow_using_gateway = ((flags & MSG_DONTROUTE) || m_routing_disabled) ? 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/Socket.cpp b/Kernel/Net/Socket.cpp index da99bfd724..b3187c585e 100644 --- a/Kernel/Net/Socket.cpp +++ b/Kernel/Net/Socket.cpp @@ -123,6 +123,14 @@ ErrorOr<void> Socket::setsockopt(int level, int option, Userspace<const void*> u return ENOTSUP; } return {}; + case SO_DONTROUTE: { + int routing_disabled; + if (user_value_size != sizeof(routing_disabled)) + return EINVAL; + TRY(copy_from_user(&routing_disabled, static_ptr_cast<const int*>(user_value))); + m_routing_disabled = routing_disabled != 0; + return {}; + } default: dbgln("setsockopt({}) at SOL_SOCKET not implemented.", option); return ENOPROTOOPT; @@ -216,6 +224,14 @@ ErrorOr<void> Socket::getsockopt(OpenFileDescription&, int level, int option, Us size = sizeof(accepting_connections); return copy_to_user(value_size, &size); } + case SO_DONTROUTE: { + int routing_disabled = m_routing_disabled ? 1 : 0; + if (size < sizeof(routing_disabled)) + return EINVAL; + TRY(copy_to_user(static_ptr_cast<int*>(value), &routing_disabled)); + size = sizeof(routing_disabled); + return copy_to_user(value_size, &size); + } default: dbgln("setsockopt({}) at SOL_SOCKET not implemented.", option); return ENOPROTOOPT; diff --git a/Kernel/Net/Socket.h b/Kernel/Net/Socket.h index b7d069c6bf..e3cff41cb4 100644 --- a/Kernel/Net/Socket.h +++ b/Kernel/Net/Socket.h @@ -154,9 +154,9 @@ protected: void set_role(Role role) { m_role = role; } -protected: ucred m_origin { 0, 0, 0 }; ucred m_acceptor { 0, 0, 0 }; + bool m_routing_disabled { false }; private: virtual bool is_socket() const final { return true; } |