1use socket2::{Domain, Type as SockType};
2use std::net::SocketAddr;
3use std::time::Duration;
4
5#[derive(Debug, Clone)]
7pub struct TcpConfig {
8 pub domain: Domain,
9 pub sock_type: SockType,
10 pub bind_addr: Option<SocketAddr>,
11 pub nonblocking: bool,
12 pub reuseaddr: Option<bool>,
13 pub nodelay: Option<bool>,
14 pub linger: Option<Duration>,
15 pub ttl: Option<u32>,
16 pub bind_device: Option<String>,
17}
18
19impl TcpConfig {
20 pub fn v4_stream() -> Self {
22 Self {
23 domain: Domain::IPV4,
24 sock_type: SockType::STREAM,
25 bind_addr: None,
26 nonblocking: false,
27 reuseaddr: None,
28 nodelay: None,
29 linger: None,
30 ttl: None,
31 bind_device: None,
32 }
33 }
34
35 pub fn raw_v4() -> Self {
37 Self {
38 domain: Domain::IPV4,
39 sock_type: SockType::RAW,
40 ..Self::v4_stream()
41 }
42 }
43
44 pub fn v6_stream() -> Self {
46 Self {
47 domain: Domain::IPV6,
48 sock_type: SockType::STREAM,
49 ..Self::v4_stream()
50 }
51 }
52
53 pub fn raw_v6() -> Self {
55 Self {
56 domain: Domain::IPV6,
57 sock_type: SockType::RAW,
58 ..Self::v4_stream()
59 }
60 }
61
62 pub fn with_bind(mut self, addr: SocketAddr) -> Self {
65 self.bind_addr = Some(addr);
66 self
67 }
68
69 pub fn with_nonblocking(mut self, flag: bool) -> Self {
70 self.nonblocking = flag;
71 self
72 }
73
74 pub fn with_reuseaddr(mut self, flag: bool) -> Self {
75 self.reuseaddr = Some(flag);
76 self
77 }
78
79 pub fn with_nodelay(mut self, flag: bool) -> Self {
80 self.nodelay = Some(flag);
81 self
82 }
83
84 pub fn with_linger(mut self, dur: Duration) -> Self {
85 self.linger = Some(dur);
86 self
87 }
88
89 pub fn with_ttl(mut self, ttl: u32) -> Self {
90 self.ttl = Some(ttl);
91 self
92 }
93
94 pub fn with_bind_device(mut self, iface: impl Into<String>) -> Self {
95 self.bind_device = Some(iface.into());
96 self
97 }
98}
99
100#[cfg(test)]
101mod tests {
102 use super::*;
103
104 #[test]
105 fn tcp_config_builders() {
106 let addr: SocketAddr = "127.0.0.1:80".parse().unwrap();
107 let cfg = TcpConfig::v4_stream()
108 .with_bind(addr)
109 .with_nonblocking(true)
110 .with_reuseaddr(true)
111 .with_nodelay(true)
112 .with_ttl(10);
113
114 assert_eq!(cfg.domain, Domain::IPV4);
115 assert_eq!(cfg.sock_type, SockType::STREAM);
116 assert_eq!(cfg.bind_addr, Some(addr));
117 assert!(cfg.nonblocking);
118 assert_eq!(cfg.reuseaddr, Some(true));
119 assert_eq!(cfg.nodelay, Some(true));
120 assert_eq!(cfg.ttl, Some(10));
121 }
122}