From 6b9660db2213cdb99422872574985ed99034dd24 Mon Sep 17 00:00:00 2001 From: Anisse Astier Date: Thu, 12 Oct 2023 08:04:18 +0200 Subject: [PATCH] diag: add support for SOCK_DESTROY It is implemented on top of SockDiagMessage, and allows using Linux's CONFIG_INET_DIAG_DESTROY feature to close an arbitrary socket. A long running, but buggy process might have hanging sockets kept alive by error. Using SOCK_DESTROY allows closing arbitrary sockets as root; an example tool that uses this feature and this crate is at: https://github.com/anisse/tcpkill --- src/message.rs | 43 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/src/message.rs b/src/message.rs index c792005..16f13db 100644 --- a/src/message.rs +++ b/src/message.rs @@ -8,7 +8,7 @@ use netlink_packet_utils::{ DecodeError, }; -use crate::{inet, unix, SockDiagBuffer, SOCK_DIAG_BY_FAMILY}; +use crate::{inet, unix, SockDiagBuffer, SOCK_DESTROY, SOCK_DIAG_BY_FAMILY}; #[derive(Debug, PartialEq, Eq, Clone)] pub enum SockDiagMessage { @@ -93,3 +93,44 @@ impl From for NetlinkPayload { NetlinkPayload::InnerMessage(message) } } + +#[derive(Debug, PartialEq, Eq, Clone)] +pub struct SockDiagDestroy(SockDiagMessage); + +impl SockDiagDestroy { + pub fn new(message: SockDiagMessage) -> SockDiagDestroy { + SockDiagDestroy(message) + } +} + +impl NetlinkSerializable for SockDiagDestroy { + fn message_type(&self) -> u16 { + SOCK_DESTROY + } + + fn buffer_len(&self) -> usize { + NetlinkSerializable::buffer_len(&self.0) + } + + fn serialize(&self, buffer: &mut [u8]) { + self.0.serialize(buffer) + } +} + +impl NetlinkDeserializable for SockDiagDestroy { + type Error = DecodeError; + fn deserialize( + header: &NetlinkHeader, + payload: &[u8], + ) -> Result { + Ok(SockDiagDestroy::new(SockDiagMessage::deserialize( + header, payload, + )?)) + } +} + +impl From for NetlinkPayload { + fn from(message: SockDiagDestroy) -> Self { + NetlinkPayload::InnerMessage(message) + } +}