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 max_send_retries: u32,
22 ignore_client_timeout: bool,
23 ignore_client_block_size: bool,
24}
25
26impl TftpServerBuilder<DirHandler> {
27 pub fn with_dir_ro<P>(dir: P) -> Result<TftpServerBuilder<DirHandler>>
31 where
32 P: AsRef<Path>,
33 {
34 let handler = DirHandler::new(dir, DirHandlerMode::ReadOnly)?;
35 Ok(TftpServerBuilder::with_handler(handler))
36 }
37
38 pub fn with_dir_wo<P>(dir: P) -> Result<TftpServerBuilder<DirHandler>>
40 where
41 P: AsRef<Path>,
42 {
43 let handler = DirHandler::new(dir, DirHandlerMode::WriteOnly)?;
44 Ok(TftpServerBuilder::with_handler(handler))
45 }
46
47 pub fn with_dir_rw<P>(dir: P) -> Result<TftpServerBuilder<DirHandler>>
49 where
50 P: AsRef<Path>,
51 {
52 let handler = DirHandler::new(dir, DirHandlerMode::ReadWrite)?;
53 Ok(TftpServerBuilder::with_handler(handler))
54 }
55}
56
57impl<H: Handler> TftpServerBuilder<H> {
58 pub fn with_handler(handler: H) -> Self {
60 TftpServerBuilder {
61 handle: handler,
62 addr: "0.0.0.0:69".parse().unwrap(),
63 socket: None,
64 timeout: Duration::from_secs(3),
65 block_size_limit: None,
66 max_send_retries: 100,
67 ignore_client_timeout: false,
68 ignore_client_block_size: false,
69 }
70 }
71
72 pub fn bind(self, addr: SocketAddr) -> Self {
78 TftpServerBuilder {
79 addr,
80 ..self
81 }
82 }
83
84 pub fn socket(self, socket: Async<UdpSocket>) -> Self {
86 TftpServerBuilder {
87 socket: Some(socket),
88 ..self
89 }
90 }
91
92 pub fn std_socket(self, socket: UdpSocket) -> Result<Self> {
94 let socket = Async::new(socket)?;
95
96 Ok(TftpServerBuilder {
97 socket: Some(socket),
98 ..self
99 })
100 }
101
102 pub fn timeout(self, timeout: Duration) -> Self {
113 TftpServerBuilder {
114 timeout,
115 ..self
116 }
117 }
118
119 pub fn block_size_limit(self, size: u16) -> Self {
129 TftpServerBuilder {
130 block_size_limit: Some(size),
131 ..self
132 }
133 }
134
135 pub fn max_send_retries(self, retries: u32) -> Self {
143 TftpServerBuilder {
144 max_send_retries: retries,
145 ..self
146 }
147 }
148
149 pub fn ignore_client_timeout(self) -> Self {
154 TftpServerBuilder {
155 ignore_client_timeout: true,
156 ..self
157 }
158 }
159
160 pub fn ignore_client_block_size(self) -> Self {
165 TftpServerBuilder {
166 ignore_client_block_size: true,
167 ..self
168 }
169 }
170
171 pub async fn build(mut self) -> Result<TftpServer<H>> {
173 let socket = match self.socket.take() {
174 Some(socket) => socket,
175 None => Async::<UdpSocket>::bind(self.addr).map_err(Error::Bind)?,
176 };
177
178 let config = ServerConfig {
179 timeout: self.timeout,
180 block_size_limit: self.block_size_limit,
181 max_send_retries: self.max_send_retries,
182 ignore_client_timeout: self.ignore_client_timeout,
183 ignore_client_block_size: self.ignore_client_block_size,
184 };
185
186 let local_ip = socket.as_ref().local_addr()?.ip();
187 Ok(TftpServer {
188 socket,
189 handler: Arc::new(Mutex::new(self.handle)),
190 reqs_in_progress: Arc::new(Mutex::new(HashSet::new())),
191 ex: Executor::new(),
192 config,
193 local_ip,
194 })
195 }
196}