1use socket2::Type as SockType;
2use std::net::SocketAddr;
3use std::time::Duration;
4
5use crate::SocketFamily;
6
7#[derive(Debug, Clone, Copy, PartialEq, Eq)]
9pub enum TcpSocketType {
10 Stream,
11 Raw,
12}
13
14impl TcpSocketType {
15 pub fn is_stream(&self) -> bool {
17 matches!(self, TcpSocketType::Stream)
18 }
19
20 pub fn is_raw(&self) -> bool {
22 matches!(self, TcpSocketType::Raw)
23 }
24
25 pub(crate) fn to_sock_type(&self) -> SockType {
27 match self {
28 TcpSocketType::Stream => SockType::STREAM,
29 TcpSocketType::Raw => SockType::RAW,
30 }
31 }
32}
33
34#[derive(Debug, Clone)]
36pub struct TcpConfig {
37 pub socket_family: SocketFamily,
39 pub socket_type: TcpSocketType,
41 pub bind_addr: Option<SocketAddr>,
43 pub nonblocking: bool,
45 pub reuseaddr: Option<bool>,
47 pub reuseport: Option<bool>,
49 pub nodelay: Option<bool>,
51 pub linger: Option<Duration>,
53 pub ttl: Option<u32>,
55 pub hoplimit: Option<u32>,
57 pub read_timeout: Option<Duration>,
59 pub write_timeout: Option<Duration>,
61 pub recv_buffer_size: Option<usize>,
63 pub send_buffer_size: Option<usize>,
65 pub tos: Option<u32>,
67 pub tclass_v6: Option<u32>,
69 pub only_v6: Option<bool>,
71 pub bind_device: Option<String>,
73 pub keepalive: Option<bool>,
75}
76
77impl TcpConfig {
78 pub fn new(socket_family: SocketFamily) -> Self {
80 match socket_family {
81 SocketFamily::IPV4 => Self::v4_stream(),
82 SocketFamily::IPV6 => Self::v6_stream(),
83 }
84 }
85
86 pub fn v4_stream() -> Self {
88 Self {
89 socket_family: SocketFamily::IPV4,
90 socket_type: TcpSocketType::Stream,
91 bind_addr: None,
92 nonblocking: false,
93 reuseaddr: None,
94 reuseport: None,
95 nodelay: None,
96 linger: None,
97 ttl: None,
98 hoplimit: None,
99 read_timeout: None,
100 write_timeout: None,
101 recv_buffer_size: None,
102 send_buffer_size: None,
103 tos: None,
104 tclass_v6: None,
105 only_v6: None,
106 bind_device: None,
107 keepalive: None,
108 }
109 }
110
111 pub fn raw_v4() -> Self {
113 Self {
114 socket_family: SocketFamily::IPV4,
115 socket_type: TcpSocketType::Raw,
116 ..Self::v4_stream()
117 }
118 }
119
120 pub fn v6_stream() -> Self {
122 Self {
123 socket_family: SocketFamily::IPV6,
124 socket_type: TcpSocketType::Stream,
125 ..Self::v4_stream()
126 }
127 }
128
129 pub fn raw_v6() -> Self {
131 Self {
132 socket_family: SocketFamily::IPV6,
133 socket_type: TcpSocketType::Raw,
134 ..Self::v4_stream()
135 }
136 }
137
138 pub fn with_bind(mut self, addr: SocketAddr) -> Self {
141 self.bind_addr = Some(addr);
142 self
143 }
144
145 pub fn with_bind_addr(self, addr: SocketAddr) -> Self {
146 self.with_bind(addr)
147 }
148
149 pub fn with_nonblocking(mut self, flag: bool) -> Self {
150 self.nonblocking = flag;
151 self
152 }
153
154 pub fn with_reuseaddr(mut self, flag: bool) -> Self {
155 self.reuseaddr = Some(flag);
156 self
157 }
158
159 pub fn with_reuseport(mut self, flag: bool) -> Self {
160 self.reuseport = Some(flag);
161 self
162 }
163
164 pub fn with_nodelay(mut self, flag: bool) -> Self {
165 self.nodelay = Some(flag);
166 self
167 }
168
169 pub fn with_linger(mut self, dur: Duration) -> Self {
170 self.linger = Some(dur);
171 self
172 }
173
174 pub fn with_ttl(mut self, ttl: u32) -> Self {
175 self.ttl = Some(ttl);
176 self
177 }
178
179 pub fn with_hoplimit(mut self, hops: u32) -> Self {
180 self.hoplimit = Some(hops);
181 self
182 }
183
184 pub fn with_hop_limit(self, hops: u32) -> Self {
185 self.with_hoplimit(hops)
186 }
187
188 pub fn with_keepalive(mut self, on: bool) -> Self {
189 self.keepalive = Some(on);
190 self
191 }
192
193 pub fn with_read_timeout(mut self, timeout: Duration) -> Self {
194 self.read_timeout = Some(timeout);
195 self
196 }
197
198 pub fn with_write_timeout(mut self, timeout: Duration) -> Self {
199 self.write_timeout = Some(timeout);
200 self
201 }
202
203 pub fn with_recv_buffer_size(mut self, size: usize) -> Self {
204 self.recv_buffer_size = Some(size);
205 self
206 }
207
208 pub fn with_send_buffer_size(mut self, size: usize) -> Self {
209 self.send_buffer_size = Some(size);
210 self
211 }
212
213 pub fn with_tos(mut self, tos: u32) -> Self {
214 self.tos = Some(tos);
215 self
216 }
217
218 pub fn with_tclass_v6(mut self, tclass: u32) -> Self {
219 self.tclass_v6 = Some(tclass);
220 self
221 }
222
223 pub fn with_only_v6(mut self, only_v6: bool) -> Self {
224 self.only_v6 = Some(only_v6);
225 self
226 }
227
228 pub fn with_bind_device(mut self, iface: impl Into<String>) -> Self {
229 self.bind_device = Some(iface.into());
230 self
231 }
232}
233
234#[cfg(test)]
235mod tests {
236 use super::*;
237
238 #[test]
239 fn tcp_config_builders() {
240 let addr: SocketAddr = "127.0.0.1:80".parse().unwrap();
241 let cfg = TcpConfig::new(SocketFamily::IPV4)
242 .with_bind_addr(addr)
243 .with_nonblocking(true)
244 .with_reuseaddr(true)
245 .with_reuseport(true)
246 .with_nodelay(true)
247 .with_ttl(10)
248 .with_recv_buffer_size(8192)
249 .with_send_buffer_size(8192)
250 .with_tos(0x10)
251 .with_tclass_v6(0x20);
252
253 assert_eq!(cfg.socket_family, SocketFamily::IPV4);
254 assert_eq!(cfg.socket_type, TcpSocketType::Stream);
255 assert_eq!(cfg.bind_addr, Some(addr));
256 assert!(cfg.nonblocking);
257 assert_eq!(cfg.reuseaddr, Some(true));
258 assert_eq!(cfg.reuseport, Some(true));
259 assert_eq!(cfg.nodelay, Some(true));
260 assert_eq!(cfg.ttl, Some(10));
261 assert_eq!(cfg.recv_buffer_size, Some(8192));
262 assert_eq!(cfg.send_buffer_size, Some(8192));
263 assert_eq!(cfg.tos, Some(0x10));
264 assert_eq!(cfg.tclass_v6, Some(0x20));
265 }
266
267 #[test]
268 fn new_with_ipv6_family_creates_v6_stream() {
269 let cfg = TcpConfig::new(SocketFamily::IPV6);
270 assert_eq!(cfg.socket_family, SocketFamily::IPV6);
271 assert_eq!(cfg.socket_type, TcpSocketType::Stream);
272 }
273}