From 4536a0b1135002c80e003b1ecbefe3cac22b8363 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Fri, 15 Dec 2023 21:28:18 -0300 Subject: [PATCH] utils: refactor socket extension traits This commit creates the following hierarchy of socket extensions traits: SocketExt -> RawSocketExt -> UdpSocketExt -> TcpSocketExt -> TcpStreamExt SocketExt, for instance, is implemented by all socket types used in Holo. TcpSocketExt is implemented by TcpSocket, TcpStream and TcpListener. This restructuring promotes code reuse by consolidating extension methods in a unified location (e.g. six `set_ipv4_tos` definitions now unified). Signed-off-by: Renato Westphal --- holo-bfd/src/network.rs | 8 +- holo-ldp/src/events.rs | 2 +- holo-ldp/src/neighbor.rs | 2 +- holo-ldp/src/network/tcp.rs | 2 +- holo-ldp/src/network/udp.rs | 2 +- holo-ospf/src/ospfv2/network.rs | 2 +- holo-ospf/src/ospfv3/network.rs | 2 +- holo-rip/src/ripng/network.rs | 6 +- holo-rip/src/ripv2/network.rs | 2 +- holo-utils/src/socket.rs | 486 +++++++++++--------------------- 10 files changed, 175 insertions(+), 339 deletions(-) diff --git a/holo-bfd/src/network.rs b/holo-bfd/src/network.rs index 1fdd1118..9945e7bf 100644 --- a/holo-bfd/src/network.rs +++ b/holo-bfd/src/network.rs @@ -15,7 +15,7 @@ use std::sync::Arc; use holo_utils::bfd::PathType; use holo_utils::ip::{AddressFamily, IpAddrExt}; -use holo_utils::socket::{UdpSocket, UdpSocketExt, TTL_MAX}; +use holo_utils::socket::{SocketExt, UdpSocket, UdpSocketExt, TTL_MAX}; use holo_utils::{capabilities, Sender}; use nix::sys::socket::{self, ControlMessageOwned}; use serde::{Deserialize, Serialize}; @@ -63,7 +63,7 @@ pub(crate) fn socket_rx( } AddressFamily::Ipv6 => { socket.set_ipv6_pktinfo(true)?; - socket.set_min_hopcount_v6(TTL_MAX)?; + socket.set_ipv6_min_hopcount(TTL_MAX)?; } }, PathType::IpMultihop => { @@ -121,11 +121,11 @@ pub(crate) fn socket_tx( match af { AddressFamily::Ipv4 => { socket.set_ipv4_tos(libc::IPTOS_PREC_INTERNETCONTROL)?; - socket.set_ttl(ttl as u32)?; + socket.set_ipv4_ttl(ttl)?; } AddressFamily::Ipv6 => { socket.set_ipv6_tclass(libc::IPTOS_PREC_INTERNETCONTROL)?; - socket.set_unicast_hops_v6(ttl as u32)?; + socket.set_ipv6_unicast_hops(ttl)?; } } diff --git a/holo-ldp/src/events.rs b/holo-ldp/src/events.rs index 6ea5ee67..11e3bf81 100644 --- a/holo-ldp/src/events.rs +++ b/holo-ldp/src/events.rs @@ -10,7 +10,7 @@ use std::net::{IpAddr, Ipv4Addr}; use chrono::Utc; use holo_utils::ip::IpNetworkKind; use holo_utils::mpls::Label; -use holo_utils::socket::{TcpConnInfo, TcpStream, TcpStreamExt, TTL_MAX}; +use holo_utils::socket::{SocketExt, TcpConnInfo, TcpStream, TTL_MAX}; use tracing::{debug_span, Span}; use crate::collections::{AdjacencyId, NeighborId, NeighborIndex}; diff --git a/holo-ldp/src/neighbor.rs b/holo-ldp/src/neighbor.rs index 94f8ae49..19fbd9f2 100644 --- a/holo-ldp/src/neighbor.rs +++ b/holo-ldp/src/neighbor.rs @@ -14,7 +14,7 @@ use bitflags::bitflags; use chrono::{DateTime, Utc}; use holo_utils::ip::AddressFamily; use holo_utils::mpls::Label; -use holo_utils::socket::{TcpConnInfo, TcpListener, TcpListenerExt, TcpStream}; +use holo_utils::socket::{TcpConnInfo, TcpListener, TcpSocketExt, TcpStream}; use holo_utils::task::{IntervalTask, Task, TimeoutTask}; use holo_utils::{Sender, UnboundedSender}; use ipnetwork::IpNetwork; diff --git a/holo-ldp/src/network/tcp.rs b/holo-ldp/src/network/tcp.rs index e84b8236..d279c574 100644 --- a/holo-ldp/src/network/tcp.rs +++ b/holo-ldp/src/network/tcp.rs @@ -10,7 +10,7 @@ use std::sync::Arc; use std::time::Duration; use holo_utils::socket::{ - OwnedReadHalf, OwnedWriteHalf, TcpConnInfo, TcpListener, TcpListenerExt, + OwnedReadHalf, OwnedWriteHalf, SocketExt, TcpConnInfo, TcpListener, TcpSocket, TcpSocketExt, TcpStream, TcpStreamExt, TTL_MAX, }; use holo_utils::task::TimeoutTask; diff --git a/holo-ldp/src/network/udp.rs b/holo-ldp/src/network/udp.rs index be497394..1e9e4bde 100644 --- a/holo-ldp/src/network/udp.rs +++ b/holo-ldp/src/network/udp.rs @@ -9,7 +9,7 @@ use std::str::FromStr; use std::sync::{Arc, LazyLock as Lazy}; use holo_utils::ip::{AddressFamily, IpAddrExt}; -use holo_utils::socket::{UdpSocket, UdpSocketExt}; +use holo_utils::socket::{SocketExt, UdpSocket, UdpSocketExt}; use holo_utils::{capabilities, Sender}; use tokio::sync::mpsc::error::SendError; diff --git a/holo-ospf/src/ospfv2/network.rs b/holo-ospf/src/ospfv2/network.rs index 716867f9..4e3d7dec 100644 --- a/holo-ospf/src/ospfv2/network.rs +++ b/holo-ospf/src/ospfv2/network.rs @@ -10,7 +10,7 @@ use std::sync::LazyLock as Lazy; use bytes::{Buf, Bytes}; use holo_utils::capabilities; -use holo_utils::socket::{Socket, SocketExt}; +use holo_utils::socket::{RawSocketExt, Socket}; use ipnetwork::Ipv4Network; use nix::sys::socket::{self, SockaddrIn}; use socket2::InterfaceIndexOrAddress; diff --git a/holo-ospf/src/ospfv3/network.rs b/holo-ospf/src/ospfv3/network.rs index 2efb3088..0a1c8981 100644 --- a/holo-ospf/src/ospfv3/network.rs +++ b/holo-ospf/src/ospfv3/network.rs @@ -10,7 +10,7 @@ use std::sync::LazyLock as Lazy; use bytes::Bytes; use holo_utils::capabilities; -use holo_utils::socket::{Socket, SocketExt}; +use holo_utils::socket::{RawSocketExt, Socket, SocketExt}; use ipnetwork::Ipv6Network; use nix::sys::socket::{self, SockaddrIn6}; diff --git a/holo-rip/src/ripng/network.rs b/holo-rip/src/ripng/network.rs index 872bd74b..6e6df99a 100644 --- a/holo-rip/src/ripng/network.rs +++ b/holo-rip/src/ripng/network.rs @@ -9,7 +9,7 @@ use std::str::FromStr; use std::sync::LazyLock as Lazy; use holo_utils::capabilities; -use holo_utils::socket::{UdpSocket, UdpSocketExt, TTL_MAX}; +use holo_utils::socket::{SocketExt, UdpSocket, UdpSocketExt, TTL_MAX}; use crate::network::NetworkVersion; use crate::version::Ripng; @@ -44,8 +44,8 @@ impl NetworkVersion for Ripng { // sent from the RIPng port (i.e. periodic advertisement // or triggered update packets) must be examined to // ensure that the hop count is 255". - socket.set_multicast_hopcount_v6(TTL_MAX)?; - socket.set_min_hopcount_v6(TTL_MAX)?; + socket.set_ipv6_multicast_hopcount(TTL_MAX)?; + socket.set_ipv6_min_hopcount(TTL_MAX)?; Ok(socket) } diff --git a/holo-rip/src/ripv2/network.rs b/holo-rip/src/ripv2/network.rs index 34ed264a..59ec868c 100644 --- a/holo-rip/src/ripv2/network.rs +++ b/holo-rip/src/ripv2/network.rs @@ -9,7 +9,7 @@ use std::str::FromStr; use std::sync::LazyLock as Lazy; use holo_utils::capabilities; -use holo_utils::socket::{UdpSocket, UdpSocketExt}; +use holo_utils::socket::{SocketExt, UdpSocket, UdpSocketExt}; use crate::network::NetworkVersion; use crate::version::Ripv2; diff --git a/holo-utils/src/socket.rs b/holo-utils/src/socket.rs index 99c707a0..6093a36b 100644 --- a/holo-utils/src/socket.rs +++ b/holo-utils/src/socket.rs @@ -57,159 +57,100 @@ pub const TTL_MAX: u8 = 255; // Useful type definition. type Result = std::io::Result; -// Extension methods for UdpSocket. -pub trait UdpSocketExt { - // Creates a UDP socket not bound to any address. - #[allow(clippy::new_ret_no_self)] - fn new(af: AddressFamily) -> Result; - - // Creates a UDP socket from the given address. - // - // This is the same as [`UdpSocket::bind`], except that the `SO_REUSEADDR` - // option is set before binding. - fn bind_reuseaddr(addr: SocketAddr) -> Result; - - // Executes an operation of the IP_ADD_MEMBERSHIP type. - fn join_multicast_ifindex_v4( - &self, - multiaddr: &Ipv4Addr, - ifindex: u32, - ) -> Result<()>; - - // Executes an operation of the IP_DROP_MEMBERSHIP type. - fn leave_multicast_ifindex_v4( - &self, - multiaddr: &Ipv4Addr, - ifindex: u32, - ) -> Result<()>; - - // Sets the value of the IP_MULTICAST_IF option for this socket. - fn set_multicast_if_v4(&self, ifindex: u32) -> Result<()>; - - // Sets the value of the IPV6_MULTICAST_IF option for this socket. - fn set_multicast_if_v6(&self, ifindex: u32) -> Result<()>; - +// Extension methods for all socket types. +pub trait SocketExt: Sized + AsRawFd { // Sets the value of the IP_TOS option for this socket. - fn set_ipv4_tos(&self, tos: u8) -> Result<()>; - - // Sets the value of the IP_MINTTL option for this socket. - fn set_ipv4_minttl(&self, ttl: u8) -> Result<()>; - - // Sets the value of the IPV6_TCLASS option for this socket. - fn set_ipv6_tclass(&self, dscp: u8) -> Result<()>; - - // Sets the value of the IPV6_UNICAST_HOPS option for this socket. - fn set_unicast_hops_v6(&self, hops: u32) -> Result<()>; - - // Sets the value of the IPV6_MULTICAST_HOPS option for this socket. - fn set_multicast_hopcount_v6(&self, hopcount: u8) -> Result<()>; - - // Sets the value of the IPV6_MINHOPCOUNT option for this socket. - fn set_min_hopcount_v6(&self, hopcount: u8) -> Result<()>; - - // Sets the value of the IP_PKTINFO option for this socket. - fn set_ipv4_pktinfo(&self, value: bool) -> Result<()>; + fn set_ipv4_tos(&self, tos: u8) -> Result<()> { + let optval = tos as c_int; - // Sets the value of the IPV6_RECVPKTINFO option for this socket. - fn set_ipv6_pktinfo(&self, value: bool) -> Result<()>; -} + setsockopt( + self, + libc::IPPROTO_IP, + libc::IP_TOS, + &optval as *const _ as *const libc::c_void, + std::mem::size_of::() as libc::socklen_t, + ) + } -// Extension methods for TcpSocket. -pub trait TcpSocketExt { // Sets the value of the IP_MINTTL option for this socket. - fn set_ipv4_minttl(&self, ttl: u8) -> Result<()>; - - // Sets the value of the IP_TTL option for this socket. - fn set_ipv4_ttl(&self, ttl: u8) -> Result<()>; - - // Sets the value of the IP_TOS option for this socket. - fn set_ipv4_tos(&self, tos: u8) -> Result<()>; - - // Sets the value of the IPV6_V6ONLY option for this socket. - fn set_ipv6_only(&self, enable: bool) -> Result<()>; - - // Sets the value of the IPV6_TCLASS option for this socket. - fn set_ipv6_tclass(&self, dscp: u8) -> Result<()>; - - // Sets the value of the TCP_MD5SIG option for this socket. - fn set_md5sig( - &self, - dst: &SocketAddr, - password: Option<&str>, - ) -> Result<()>; -} + fn set_ipv4_minttl(&self, ttl: u8) -> Result<()> { + let optval = ttl as c_int; -// Extension methods for TcpStream. -pub trait TcpStreamExt { - // Returns address and port information about the TCP connection. - fn conn_info(&self) -> Result; + setsockopt( + self, + libc::IPPROTO_IP, + libc::IP_MINTTL, + &optval as *const _ as *const libc::c_void, + std::mem::size_of::() as libc::socklen_t, + ) + } - // Sets the value of the IP_MINTTL option for this socket. - fn set_ipv4_minttl(&self, ttl: u8) -> Result<()>; -} + // Sets the value of the IP_TTL option for this socket. + fn set_ipv4_ttl(&self, ttl: u8) -> Result<()> { + let optval = ttl as c_int; -// Extension methods for TcpListener. -pub trait TcpListenerExt { - // Sets the value of the IP_TOS option for this socket. - fn set_ipv4_tos(&self, tos: u8) -> Result<()>; + setsockopt( + self, + libc::IPPROTO_IP, + libc::IP_TTL, + &optval as *const _ as *const libc::c_void, + std::mem::size_of::() as libc::socklen_t, + ) + } // Sets the value of the IPV6_TCLASS option for this socket. - fn set_ipv6_tclass(&self, dscp: u8) -> Result<()>; - - // Sets the value of the TCP_MD5SIG option for this socket. - fn set_md5sig( - &self, - dst: &SocketAddr, - password: Option<&str>, - ) -> Result<()>; -} - -// Extension methods for Socket. -pub trait SocketExt { - // Sets the value of the IP_PKTINFO option for this socket. - fn set_ipv4_pktinfo(&self, value: bool) -> Result<()>; - - // Sets the value of the IPV6_CHECKSUM option for this socket. - fn set_ipv6_checksum(&self, offset: i32) -> Result<()>; + fn set_ipv6_tclass(&self, dscp: u8) -> Result<()> { + let optval = dscp as c_int; - // Sets the value of the IPV6_TCLASS option for this socket. - fn set_ipv6_tclass(&self, dscp: u8) -> Result<()>; + setsockopt( + self, + libc::IPPROTO_IPV6, + libc::IPV6_TCLASS, + &optval as *const _ as *const libc::c_void, + std::mem::size_of::() as libc::socklen_t, + ) + } - // Sets the value of the IPV6_RECVPKTINFO option for this socket. - fn set_ipv6_pktinfo(&self, value: bool) -> Result<()>; -} + // Sets the value of the IPV6_MINHOPCOUNT option for this socket. + fn set_ipv6_min_hopcount(&self, hopcount: u8) -> Result<()> { + let optval = hopcount as c_int; -// ===== impl UdpSocket ===== + setsockopt( + self, + libc::IPPROTO_IPV6, + libc::IPV6_MINHOPCOUNT, + &optval as *const _ as *const libc::c_void, + std::mem::size_of::() as libc::socklen_t, + ) + } -#[cfg(not(feature = "testing"))] -impl UdpSocketExt for UdpSocket { - fn new(af: AddressFamily) -> Result { - use socket2::{Domain, Type}; + // Sets the value of the IPV6_UNICAST_HOPS option for this socket. + fn set_ipv6_unicast_hops(&self, hops: u8) -> Result<()> { + let optval = hops as c_int; - let domain = match af { - AddressFamily::Ipv4 => Domain::IPV4, - AddressFamily::Ipv6 => Domain::IPV6, - }; - let socket = Socket::new(domain, Type::DGRAM, None)?; - socket.set_nonblocking(true)?; - socket.set_reuse_address(true)?; - UdpSocket::from_std(socket.into()) + setsockopt( + self, + libc::IPPROTO_IPV6, + libc::IPV6_UNICAST_HOPS, + &optval as *const _ as *const libc::c_void, + std::mem::size_of::() as libc::socklen_t, + ) } +} - fn bind_reuseaddr(addr: SocketAddr) -> Result { - use socket2::{Domain, Type}; +// Extension methods for UdpSocket. +pub trait UdpSocketExt: SocketExt { + // Creates a UDP socket not bound to any address. + #[allow(clippy::new_ret_no_self)] + fn new(af: AddressFamily) -> Result; - let domain = match addr.ip().address_family() { - AddressFamily::Ipv4 => Domain::IPV4, - AddressFamily::Ipv6 => Domain::IPV6, - }; - let socket = Socket::new(domain, Type::DGRAM, None)?; - socket.set_nonblocking(true)?; - socket.set_reuse_address(true)?; - socket.bind(&addr.into())?; - UdpSocket::from_std(socket.into()) - } + // Creates a UDP socket from the given address. + // + // This is the same as [`UdpSocket::bind`], except that the `SO_REUSEADDR` + // option is set before binding. + fn bind_reuseaddr(addr: SocketAddr) -> Result; + // Executes an operation of the IP_ADD_MEMBERSHIP type. fn join_multicast_ifindex_v4( &self, multiaddr: &Ipv4Addr, @@ -234,6 +175,7 @@ impl UdpSocketExt for UdpSocket { ) } + // Executes an operation of the IP_DROP_MEMBERSHIP type. fn leave_multicast_ifindex_v4( &self, multiaddr: &Ipv4Addr, @@ -258,6 +200,7 @@ impl UdpSocketExt for UdpSocket { ) } + // Sets the value of the IP_MULTICAST_IF option for this socket. fn set_multicast_if_v4(&self, ifindex: u32) -> Result<()> { let optval = ip_mreqn { imr_multiaddr: libc::in_addr { s_addr: 0 }, @@ -274,6 +217,7 @@ impl UdpSocketExt for UdpSocket { ) } + // Sets the value of the IPV6_MULTICAST_IF option for this socket. fn set_multicast_if_v6(&self, ifindex: u32) -> Result<()> { let optval = ifindex as i32; @@ -286,55 +230,8 @@ impl UdpSocketExt for UdpSocket { ) } - fn set_ipv4_tos(&self, tos: u8) -> Result<()> { - let optval = tos as c_int; - - setsockopt( - self, - libc::IPPROTO_IP, - libc::IP_TOS, - &optval as *const _ as *const libc::c_void, - std::mem::size_of::() as libc::socklen_t, - ) - } - - fn set_ipv4_minttl(&self, ttl: u8) -> Result<()> { - let optval = ttl as c_int; - - setsockopt( - self, - libc::IPPROTO_IP, - libc::IP_MINTTL, - &optval as *const _ as *const libc::c_void, - std::mem::size_of::() as libc::socklen_t, - ) - } - - fn set_ipv6_tclass(&self, dscp: u8) -> Result<()> { - let optval = dscp as c_int; - - setsockopt( - self, - libc::IPPROTO_IPV6, - libc::IPV6_TCLASS, - &optval as *const _ as *const libc::c_void, - std::mem::size_of::() as libc::socklen_t, - ) - } - - fn set_unicast_hops_v6(&self, hops: u32) -> Result<()> { - let optval = hops as c_int; - - setsockopt( - self, - libc::IPPROTO_IPV6, - libc::IPV6_UNICAST_HOPS, - &optval as *const _ as *const libc::c_void, - std::mem::size_of::() as libc::socklen_t, - ) - } - - fn set_multicast_hopcount_v6(&self, hopcount: u8) -> Result<()> { + // Sets the value of the IPV6_MULTICAST_HOPS option for this socket. + fn set_ipv6_multicast_hopcount(&self, hopcount: u8) -> Result<()> { let optval = hopcount as c_int; setsockopt( @@ -346,18 +243,7 @@ impl UdpSocketExt for UdpSocket { ) } - fn set_min_hopcount_v6(&self, hopcount: u8) -> Result<()> { - let optval = hopcount as c_int; - - setsockopt( - self, - libc::IPPROTO_IPV6, - libc::IPV6_MINHOPCOUNT, - &optval as *const _ as *const libc::c_void, - std::mem::size_of::() as libc::socklen_t, - ) - } - + // Sets the value of the IP_PKTINFO option for this socket. fn set_ipv4_pktinfo(&self, value: bool) -> Result<()> { let optval = value as c_int; @@ -370,6 +256,7 @@ impl UdpSocketExt for UdpSocket { ) } + // Sets the value of the IPV6_RECVPKTINFO option for this socket. fn set_ipv6_pktinfo(&self, value: bool) -> Result<()> { let optval = value as c_int; @@ -383,46 +270,9 @@ impl UdpSocketExt for UdpSocket { } } -// ===== impl TcpSocket ===== - -#[cfg(not(feature = "testing"))] -impl TcpSocketExt for TcpSocket { - fn set_ipv4_minttl(&self, ttl: u8) -> Result<()> { - let optval = ttl as c_int; - - setsockopt( - self, - libc::IPPROTO_IP, - libc::IP_MINTTL, - &optval as *const _ as *const libc::c_void, - std::mem::size_of::() as libc::socklen_t, - ) - } - - fn set_ipv4_ttl(&self, ttl: u8) -> Result<()> { - let optval = ttl as c_int; - - setsockopt( - self, - libc::IPPROTO_IP, - libc::IP_TTL, - &optval as *const _ as *const libc::c_void, - std::mem::size_of::() as libc::socklen_t, - ) - } - - fn set_ipv4_tos(&self, tos: u8) -> Result<()> { - let optval = tos as c_int; - - setsockopt( - self, - libc::IPPROTO_IP, - libc::IP_TOS, - &optval as *const _ as *const libc::c_void, - std::mem::size_of::() as libc::socklen_t, - ) - } - +// Extension methods for TcpSocket, TcpListener and TcpStream. +pub trait TcpSocketExt: SocketExt { + // Sets the value of the IPV6_V6ONLY option for this socket. fn set_ipv6_only(&self, enable: bool) -> Result<()> { let optval = enable as c_int; @@ -435,18 +285,7 @@ impl TcpSocketExt for TcpSocket { ) } - fn set_ipv6_tclass(&self, dscp: u8) -> Result<()> { - let optval = dscp as c_int; - - setsockopt( - self, - libc::IPPROTO_IPV6, - libc::IPV6_TCLASS, - &optval as *const _ as *const libc::c_void, - std::mem::size_of::() as libc::socklen_t, - ) - } - + // Sets the value of the TCP_MD5SIG option for this socket. fn set_md5sig( &self, dst: &SocketAddr, @@ -476,8 +315,75 @@ impl TcpSocketExt for TcpSocket { } } +// Extension methods for TcpStream. +pub trait TcpStreamExt: TcpSocketExt { + // Returns address and port information about the TCP connection. + fn conn_info(&self) -> Result; +} + +// Extension methods for Socket. +pub trait RawSocketExt: SocketExt { + // Sets the value of the IP_PKTINFO option for this socket. + fn set_ipv4_pktinfo(&self, value: bool) -> Result<()>; + + // Sets the value of the IPV6_CHECKSUM option for this socket. + fn set_ipv6_checksum(&self, offset: i32) -> Result<()>; + + // Sets the value of the IPV6_RECVPKTINFO option for this socket. + fn set_ipv6_pktinfo(&self, value: bool) -> Result<()>; +} + +// ===== impl UdpSocket ===== + +#[cfg(not(feature = "testing"))] +impl SocketExt for UdpSocket {} + +#[cfg(not(feature = "testing"))] +impl UdpSocketExt for UdpSocket { + fn new(af: AddressFamily) -> Result { + use socket2::{Domain, Type}; + + let domain = match af { + AddressFamily::Ipv4 => Domain::IPV4, + AddressFamily::Ipv6 => Domain::IPV6, + }; + let socket = Socket::new(domain, Type::DGRAM, None)?; + socket.set_nonblocking(true)?; + socket.set_reuse_address(true)?; + UdpSocket::from_std(socket.into()) + } + + fn bind_reuseaddr(addr: SocketAddr) -> Result { + use socket2::{Domain, Type}; + + let domain = match addr.ip().address_family() { + AddressFamily::Ipv4 => Domain::IPV4, + AddressFamily::Ipv6 => Domain::IPV6, + }; + let socket = Socket::new(domain, Type::DGRAM, None)?; + socket.set_nonblocking(true)?; + socket.set_reuse_address(true)?; + socket.bind(&addr.into())?; + UdpSocket::from_std(socket.into()) + } +} + +// ===== impl TcpSocket ===== + +#[cfg(not(feature = "testing"))] +impl SocketExt for TcpSocket {} + +#[cfg(not(feature = "testing"))] +impl TcpSocketExt for TcpSocket {} + // ===== impl TcpStream ===== +#[cfg(not(feature = "testing"))] +impl SocketExt for TcpStream {} + +#[cfg(not(feature = "testing"))] +impl TcpSocketExt for TcpStream {} + #[cfg(not(feature = "testing"))] impl TcpStreamExt for TcpStream { fn conn_info(&self) -> Result { @@ -491,81 +397,23 @@ impl TcpStreamExt for TcpStream { remote_port: remote_addr.port(), }) } - - fn set_ipv4_minttl(&self, ttl: u8) -> Result<()> { - let optval = ttl as c_int; - - setsockopt( - self, - libc::IPPROTO_IP, - libc::IP_MINTTL, - &optval as *const _ as *const libc::c_void, - std::mem::size_of::() as libc::socklen_t, - ) - } } // ===== impl TcpListener ===== #[cfg(not(feature = "testing"))] -impl TcpListenerExt for TcpListener { - fn set_ipv4_tos(&self, tos: u8) -> Result<()> { - let optval = tos as c_int; - - setsockopt( - self, - libc::IPPROTO_IP, - libc::IP_TOS, - &optval as *const _ as *const libc::c_void, - std::mem::size_of::() as libc::socklen_t, - ) - } - - fn set_ipv6_tclass(&self, dscp: u8) -> Result<()> { - let optval = dscp as c_int; - - setsockopt( - self, - libc::IPPROTO_IPV6, - libc::IPV6_TCLASS, - &optval as *const _ as *const libc::c_void, - std::mem::size_of::() as libc::socklen_t, - ) - } - - fn set_md5sig( - &self, - dst: &SocketAddr, - password: Option<&str>, - ) -> Result<()> { - let mut optval = tcp_md5sig { - tcpm_addr: (*dst).into(), - tcpm_flags: 0, - tcpm_prefixlen: 0, - tcpm_keylen: 0, - __tcpm_pad: 0, - tcpm_key: [0; 108], - }; - if let Some(password) = password { - optval.tcpm_keylen = password.len() as u16; - optval.tcpm_key[..password.len()] - .copy_from_slice(password.as_bytes()); - } +impl SocketExt for TcpListener {} - setsockopt( - self, - libc::IPPROTO_TCP, - libc::TCP_MD5SIG, - &optval as *const _ as *const libc::c_void, - std::mem::size_of::() as libc::socklen_t, - ) - } -} +#[cfg(not(feature = "testing"))] +impl TcpSocketExt for TcpListener {} // ===== impl Socket ===== #[cfg(not(feature = "testing"))] -impl SocketExt for Socket { +impl SocketExt for Socket {} + +#[cfg(not(feature = "testing"))] +impl RawSocketExt for Socket { fn set_ipv4_pktinfo(&self, value: bool) -> Result<()> { let optval = value as c_int; @@ -590,18 +438,6 @@ impl SocketExt for Socket { ) } - fn set_ipv6_tclass(&self, dscp: u8) -> Result<()> { - let optval = dscp as c_int; - - setsockopt( - self, - libc::IPPROTO_IPV6, - libc::IPV6_TCLASS, - &optval as *const _ as *const libc::c_void, - std::mem::size_of::() as libc::socklen_t, - ) - } - fn set_ipv6_pktinfo(&self, value: bool) -> Result<()> { let optval = value as c_int;