@@ -42,11 +42,34 @@ const TUN_PROTO_IP6: [u8; 2] = [0x00, 0x0A];
4242#[ cfg( any( target_os = "macos" , target_os = "ios" ) ) ]
4343const TUN_PROTO_IP4 : [ u8 ; 2 ] = [ 0x00 , 0x02 ] ;
4444
45+ /// Configuration for the IP stack.
46+ ///
47+ /// This structure holds configuration parameters that control the behavior of the IP stack,
48+ /// including network settings and protocol-specific timeouts.
49+ ///
50+ /// # Examples
51+ ///
52+ /// ```
53+ /// use ipstack::IpStackConfig;
54+ /// use std::time::Duration;
55+ ///
56+ /// let mut config = IpStackConfig::default();
57+ /// config.mtu(1500)
58+ /// .udp_timeout(Duration::from_secs(60))
59+ /// .packet_information(false);
60+ /// ```
4561#[ non_exhaustive]
4662pub struct IpStackConfig {
63+ /// Maximum Transmission Unit (MTU) size in bytes.
64+ /// Default is `u16::MAX` (65535).
4765 pub mtu : u16 ,
66+ /// Whether to include packet information headers (Unix platforms only).
67+ /// Default is `false`.
4868 pub packet_information : bool ,
69+ /// TCP-specific configuration parameters.
4970 pub tcp_config : Arc < TcpConfig > ,
71+ /// Timeout for UDP connections.
72+ /// Default is 30 seconds.
5073 pub udp_timeout : Duration ,
5174}
5275
@@ -62,31 +85,157 @@ impl Default for IpStackConfig {
6285}
6386
6487impl IpStackConfig {
65- /// Set custom TCP configuration
88+ /// Set custom TCP configuration.
89+ ///
90+ /// # Arguments
91+ ///
92+ /// * `config` - The TCP configuration to use
93+ ///
94+ /// # Examples
95+ ///
96+ /// ```
97+ /// use ipstack::{IpStackConfig, TcpConfig};
98+ ///
99+ /// let mut config = IpStackConfig::default();
100+ /// config.with_tcp_config(TcpConfig::default());
101+ /// ```
66102 pub fn with_tcp_config ( & mut self , config : TcpConfig ) -> & mut Self {
67103 self . tcp_config = Arc :: new ( config) ;
68104 self
69105 }
106+
107+ /// Set the UDP connection timeout.
108+ ///
109+ /// # Arguments
110+ ///
111+ /// * `timeout` - The timeout duration for UDP connections
112+ ///
113+ /// # Examples
114+ ///
115+ /// ```
116+ /// use ipstack::IpStackConfig;
117+ /// use std::time::Duration;
118+ ///
119+ /// let mut config = IpStackConfig::default();
120+ /// config.udp_timeout(Duration::from_secs(60));
121+ /// ```
70122 pub fn udp_timeout ( & mut self , timeout : Duration ) -> & mut Self {
71123 self . udp_timeout = timeout;
72124 self
73125 }
126+
127+ /// Set the Maximum Transmission Unit (MTU) size.
128+ ///
129+ /// # Arguments
130+ ///
131+ /// * `mtu` - The MTU size in bytes
132+ ///
133+ /// # Examples
134+ ///
135+ /// ```
136+ /// use ipstack::IpStackConfig;
137+ ///
138+ /// let mut config = IpStackConfig::default();
139+ /// config.mtu(1500);
140+ /// ```
74141 pub fn mtu ( & mut self , mtu : u16 ) -> & mut Self {
75142 self . mtu = mtu;
76143 self
77144 }
145+
146+ /// Enable or disable packet information headers (Unix platforms only).
147+ ///
148+ /// When enabled on Unix platforms, the TUN device will include 4-byte packet
149+ /// information headers.
150+ ///
151+ /// # Arguments
152+ ///
153+ /// * `packet_information` - Whether to include packet information headers
154+ ///
155+ /// # Examples
156+ ///
157+ /// ```
158+ /// use ipstack::IpStackConfig;
159+ ///
160+ /// let mut config = IpStackConfig::default();
161+ /// config.packet_information(true);
162+ /// ```
78163 pub fn packet_information ( & mut self , packet_information : bool ) -> & mut Self {
79164 self . packet_information = packet_information;
80165 self
81166 }
82167}
83168
169+ /// The main IP stack instance.
170+ ///
171+ /// `IpStack` provides a userspace TCP/IP stack implementation for TUN devices.
172+ /// It processes network packets and creates stream abstractions for TCP, UDP, and
173+ /// unknown transport protocols.
174+ ///
175+ /// # Examples
176+ ///
177+ /// ```no_run
178+ /// use ipstack::{IpStack, IpStackConfig, IpStackStream};
179+ /// use std::net::Ipv4Addr;
180+ ///
181+ /// #[tokio::main]
182+ /// async fn main() -> Result<(), Box<dyn std::error::Error>> {
183+ /// // Configure TUN device
184+ /// let mut config = tun::Configuration::default();
185+ /// config
186+ /// .address(Ipv4Addr::new(10, 0, 0, 1))
187+ /// .netmask(Ipv4Addr::new(255, 255, 255, 0))
188+ /// .up();
189+ ///
190+ /// // Create IP stack
191+ /// let ipstack_config = IpStackConfig::default();
192+ /// let mut ip_stack = IpStack::new(ipstack_config, tun::create_as_async(&config)?);
193+ ///
194+ /// // Accept incoming streams
195+ /// while let Ok(stream) = ip_stack.accept().await {
196+ /// match stream {
197+ /// IpStackStream::Tcp(tcp) => {
198+ /// // Handle TCP connection
199+ /// }
200+ /// IpStackStream::Udp(udp) => {
201+ /// // Handle UDP connection
202+ /// }
203+ /// _ => {}
204+ /// }
205+ /// }
206+ /// Ok(())
207+ /// }
208+ /// ```
84209pub struct IpStack {
85210 accept_receiver : UnboundedReceiver < IpStackStream > ,
86211 handle : JoinHandle < Result < ( ) > > ,
87212}
88213
89214impl IpStack {
215+ /// Create a new IP stack instance.
216+ ///
217+ /// # Arguments
218+ ///
219+ /// * `config` - Configuration for the IP stack
220+ /// * `device` - An async TUN device implementing `AsyncRead` + `AsyncWrite`
221+ ///
222+ /// # Examples
223+ ///
224+ /// ```no_run
225+ /// use ipstack::{IpStack, IpStackConfig};
226+ /// use std::net::Ipv4Addr;
227+ ///
228+ /// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
229+ /// let mut tun_config = tun::Configuration::default();
230+ /// tun_config.address(Ipv4Addr::new(10, 0, 0, 1))
231+ /// .netmask(Ipv4Addr::new(255, 255, 255, 0))
232+ /// .up();
233+ ///
234+ /// let ipstack_config = IpStackConfig::default();
235+ /// let ip_stack = IpStack::new(ipstack_config, tun::create_as_async(&tun_config)?);
236+ /// # Ok(())
237+ /// # }
238+ /// ```
90239 pub fn new < Device > ( config : IpStackConfig , device : Device ) -> IpStack
91240 where
92241 Device : AsyncRead + AsyncWrite + Unpin + Send + ' static ,
@@ -98,6 +247,39 @@ impl IpStack {
98247 }
99248 }
100249
250+ /// Accept an incoming network stream.
251+ ///
252+ /// This method waits for and returns the next incoming network connection or packet.
253+ /// The returned `IpStackStream` enum indicates the type of stream (TCP, UDP, or unknown).
254+ ///
255+ /// # Returns
256+ ///
257+ /// * `Ok(IpStackStream)` - The next incoming stream
258+ /// * `Err(IpStackError::AcceptError)` - If the IP stack has been shut down
259+ ///
260+ /// # Examples
261+ ///
262+ /// ```no_run
263+ /// use ipstack::{IpStack, IpStackConfig, IpStackStream};
264+ ///
265+ /// # async fn example(mut ip_stack: IpStack) -> Result<(), Box<dyn std::error::Error>> {
266+ /// match ip_stack.accept().await? {
267+ /// IpStackStream::Tcp(tcp) => {
268+ /// println!("New TCP connection from {}", tcp.peer_addr());
269+ /// }
270+ /// IpStackStream::Udp(udp) => {
271+ /// println!("New UDP stream from {}", udp.peer_addr());
272+ /// }
273+ /// IpStackStream::UnknownTransport(unknown) => {
274+ /// println!("Unknown transport protocol: {:?}", unknown.ip_protocol());
275+ /// }
276+ /// IpStackStream::UnknownNetwork(data) => {
277+ /// println!("Unknown network packet: {} bytes", data.len());
278+ /// }
279+ /// }
280+ /// # Ok(())
281+ /// # }
282+ /// ```
101283 pub async fn accept ( & mut self ) -> Result < IpStackStream , IpStackError > {
102284 self . accept_receiver . recv ( ) . await . ok_or ( IpStackError :: AcceptError )
103285 }
0 commit comments