async_tftp/server/
builder.rs1use async_executor::Executor;
2use async_io::Async;
3use async_lock::Mutex;
4use std::collections::HashSet;
5use std::net::{SocketAddr, UdpSocket};
6use std::path::Path;
7use std::sync::Arc;
8use std::time::Duration;
9
10use super::handlers::{DirHandler, DirHandlerMode};
11use super::{Handler, ServerConfig, TftpServer};
12use crate::error::{Error, Result};
13
14pub struct TftpServerBuilder<H: Handler> {
16 handle: H,
17 addr: SocketAddr,
18 socket: Option<Async<UdpSocket>>,
19 timeout: Duration,
20 block_size_limit: Option<u16>,
21 window_size_limit: Option<u16>,
22 max_send_retries: u32,
23 ignore_client_timeout: bool,
24 ignore_client_block_size: bool,
25 ignore_client_window_size: bool,
26}
27
28impl TftpServerBuilder<DirHandler> {
29 pub fn with_dir_ro<P>(dir: P) -> Result<TftpServerBuilder<DirHandler>>
33 where
34 P: AsRef<Path>,
35 {
36 let handler = DirHandler::new(dir, DirHandlerMode::ReadOnly)?;
37 Ok(TftpServerBuilder::with_handler(handler))
38 }
39
40 pub fn with_dir_wo<P>(dir: P) -> Result<TftpServerBuilder<DirHandler>>
42 where
43 P: AsRef<Path>,
44 {
45 let handler = DirHandler::new(dir, DirHandlerMode::WriteOnly)?;
46 Ok(TftpServerBuilder::with_handler(handler))
47 }
48
49 pub fn with_dir_rw<P>(dir: P) -> Result<TftpServerBuilder<DirHandler>>
51 where
52 P: AsRef<Path>,
53 {
54 let handler = DirHandler::new(dir, DirHandlerMode::ReadWrite)?;
55 Ok(TftpServerBuilder::with_handler(handler))
56 }
57}
58
59impl<H: Handler> TftpServerBuilder<H> {
60 pub fn with_handler(handler: H) -> Self {
62 TftpServerBuilder {
63 handle: handler,
64 addr: "0.0.0.0:69".parse().unwrap(),
65 socket: None,
66 timeout: Duration::from_secs(3),
67 block_size_limit: None,
68 window_size_limit: None,
69 max_send_retries: 100,
70 ignore_client_timeout: false,
71 ignore_client_block_size: false,
72 ignore_client_window_size: false,
73 }
74 }
75
76 pub fn bind(self, addr: SocketAddr) -> Self {
82 TftpServerBuilder {
83 addr,
84 ..self
85 }
86 }
87
88 pub fn socket(self, socket: Async<UdpSocket>) -> Self {
90 TftpServerBuilder {
91 socket: Some(socket),
92 ..self
93 }
94 }
95
96 pub fn std_socket(self, socket: UdpSocket) -> Result<Self> {
98 let socket = Async::new(socket)?;
99
100 Ok(TftpServerBuilder {
101 socket: Some(socket),
102 ..self
103 })
104 }
105
106 pub fn timeout(self, timeout: Duration) -> Self {
117 TftpServerBuilder {
118 timeout,
119 ..self
120 }
121 }
122
123 pub fn block_size_limit(self, size: u16) -> Self {
133 TftpServerBuilder {
134 block_size_limit: Some(size),
135 ..self
136 }
137 }
138
139 pub fn window_size_limit(self, window_size: u16) -> Self {
146 TftpServerBuilder {
147 window_size_limit: Some(window_size),
148 ..self
149 }
150 }
151
152 pub fn max_send_retries(self, retries: u32) -> Self {
160 TftpServerBuilder {
161 max_send_retries: retries,
162 ..self
163 }
164 }
165
166 pub fn ignore_client_timeout(self) -> Self {
171 TftpServerBuilder {
172 ignore_client_timeout: true,
173 ..self
174 }
175 }
176
177 pub fn ignore_client_block_size(self) -> Self {
182 TftpServerBuilder {
183 ignore_client_block_size: true,
184 ..self
185 }
186 }
187
188 pub fn ignore_client_window_size(self) -> Self {
194 TftpServerBuilder {
195 ignore_client_window_size: true,
196 ..self
197 }
198 }
199
200 pub async fn build(mut self) -> Result<TftpServer<H>> {
202 let socket = match self.socket.take() {
203 Some(socket) => socket,
204 None => Async::<UdpSocket>::bind(self.addr).map_err(Error::Bind)?,
205 };
206
207 let config = ServerConfig {
208 timeout: self.timeout,
209 block_size_limit: self.block_size_limit,
210 window_size_limit: self.window_size_limit,
211 max_send_retries: self.max_send_retries,
212 ignore_client_timeout: self.ignore_client_timeout,
213 ignore_client_block_size: self.ignore_client_block_size,
214 ignore_client_window_size: self.ignore_client_window_size,
215 };
216
217 let local_ip = socket.as_ref().local_addr()?.ip();
218 Ok(TftpServer {
219 socket,
220 handler: Arc::new(Mutex::new(self.handle)),
221 reqs_in_progress: Arc::new(Mutex::new(HashSet::new())),
222 ex: Executor::new(),
223 config,
224 local_ip,
225 })
226 }
227}