surge_ping/
config.rs

1use std::net::SocketAddr;
2
3use socket2::{SockAddr, Type};
4
5use crate::ICMP;
6
7/// Config is the packaging of various configurations of `sockets`. If you want to make
8/// some `set_socket_opt` and other modifications, please define and implement them in `Config`.
9#[derive(Debug)]
10pub struct Config {
11    pub sock_type_hint: Type,
12    pub kind: ICMP,
13    pub bind: Option<SockAddr>,
14    pub interface: Option<String>,
15    pub ttl: Option<u32>,
16    pub fib: Option<u32>,
17}
18
19impl Default for Config {
20    fn default() -> Self {
21        Self {
22            sock_type_hint: Type::DGRAM,
23            kind: ICMP::default(),
24            bind: None,
25            interface: None,
26            ttl: None,
27            fib: None,
28        }
29    }
30}
31
32impl Config {
33    /// A structure that can be specially configured for socket.
34    pub fn new() -> Self {
35        Self::default()
36    }
37
38    pub fn builder() -> ConfigBuilder {
39        ConfigBuilder::default()
40    }
41}
42
43#[derive(Debug)]
44pub struct ConfigBuilder {
45    sock_type_hint: Type,
46    kind: ICMP,
47    bind: Option<SockAddr>,
48    interface: Option<String>,
49    ttl: Option<u32>,
50    fib: Option<u32>,
51}
52
53impl Default for ConfigBuilder {
54    fn default() -> Self {
55        Self {
56            sock_type_hint: Type::DGRAM,
57            kind: ICMP::default(),
58            bind: None,
59            interface: None,
60            ttl: None,
61            fib: None,
62        }
63    }
64}
65
66impl ConfigBuilder {
67    /// Binds this socket to the specified address.
68    ///
69    /// This function directly corresponds to the `bind(2)` function on Windows
70    /// and Unix.
71    pub fn bind(mut self, bind: SocketAddr) -> Self {
72        self.bind = Some(SockAddr::from(bind));
73        self
74    }
75
76    /// Sets the value for the `SO_BINDTODEVICE` option on this socket.
77    ///
78    /// If a socket is bound to an interface, only packets received from that
79    /// particular interface are processed by the socket. Note that this only
80    /// works for some socket types, particularly `AF_INET` sockets.
81    pub fn interface(mut self, interface: &str) -> Self {
82        self.interface = Some(interface.to_string());
83        self
84    }
85
86    /// Set the value of the `IP_TTL` option for this socket.
87    ///
88    /// This value sets the time-to-live field that is used in every packet sent
89    /// from this socket.
90    pub fn ttl(mut self, ttl: u32) -> Self {
91        self.ttl = Some(ttl);
92        self
93    }
94
95    pub fn fib(mut self, fib: u32) -> Self {
96        self.fib = Some(fib);
97        self
98    }
99
100    /// Identify which ICMP the socket handles.(default: ICMP::V4)
101    pub fn kind(mut self, kind: ICMP) -> Self {
102        self.kind = kind;
103        self
104    }
105
106    /// Try to open the socket with provided at first (DGRAM or RAW)
107    pub fn sock_type_hint(mut self, typ: Type) -> Self {
108        self.sock_type_hint = typ;
109        self
110    }
111
112    pub fn build(self) -> Config {
113        Config {
114            sock_type_hint: self.sock_type_hint,
115            kind: self.kind,
116            bind: self.bind,
117            interface: self.interface,
118            ttl: self.ttl,
119            fib: self.fib,
120        }
121    }
122}