author | alfadur |
Mon, 03 Jun 2019 01:15:57 +0300 | |
changeset 15108 | 823052e66611 |
parent 15107 | 80ff12edf5e6 |
child 15178 | 21e87882df1c |
permissions | -rw-r--r-- |
13124 | 1 |
extern crate slab; |
2 |
||
13419 | 3 |
use std::{ |
13420 | 4 |
collections::HashSet, |
14462 | 5 |
io, |
6 |
io::{Error, ErrorKind, Read, Write}, |
|
7 |
mem::{replace, swap}, |
|
8 |
net::{IpAddr, Ipv4Addr, SocketAddr}, |
|
13419 | 9 |
}; |
10 |
||
14462 | 11 |
use log::*; |
13419 | 12 |
use mio::{ |
14462 | 13 |
net::{TcpListener, TcpStream}, |
14835
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
14 |
Evented, Poll, PollOpt, Ready, Token, |
13419 | 15 |
}; |
14808 | 16 |
use mio_extras::timer; |
13419 | 17 |
use netbuf; |
13124 | 18 |
use slab::Slab; |
19 |
||
13671 | 20 |
use crate::{ |
15080 | 21 |
core::{server::HwServer, types::ClientId}, |
15079 | 22 |
handlers, |
15107 | 23 |
handlers::{IoResult, IoTask}, |
15108
823052e66611
check for account existence before asking passwords
alfadur
parents:
15107
diff
changeset
|
24 |
protocol::{messages::HwServerMessage::Redirect, messages::*, ProtocolDecoder}, |
13671 | 25 |
utils, |
13419 | 26 |
}; |
14784
f43ab2bd76ae
add a thread for internal server IO and implement account checking with it
alfadur
parents:
14702
diff
changeset
|
27 |
|
f43ab2bd76ae
add a thread for internal server IO and implement account checking with it
alfadur
parents:
14702
diff
changeset
|
28 |
#[cfg(feature = "official-server")] |
15103 | 29 |
use super::io::{IoThread, RequestId}; |
14784
f43ab2bd76ae
add a thread for internal server IO and implement account checking with it
alfadur
parents:
14702
diff
changeset
|
30 |
|
13804 | 31 |
#[cfg(feature = "tls-connections")] |
32 |
use openssl::{ |
|
14462 | 33 |
error::ErrorStack, |
13804 | 34 |
ssl::{ |
14462 | 35 |
HandshakeError, MidHandshakeSslStream, Ssl, SslContext, SslContextBuilder, SslFiletype, |
36 |
SslMethod, SslOptions, SslStream, SslStreamBuilder, SslVerifyMode, |
|
13804 | 37 |
}, |
38 |
}; |
|
14808 | 39 |
use std::time::Duration; |
13419 | 40 |
|
41 |
const MAX_BYTES_PER_READ: usize = 2048; |
|
14808 | 42 |
const SEND_PING_TIMEOUT: Duration = Duration::from_secs(30); |
14812 | 43 |
const DROP_CLIENT_TIMEOUT: Duration = Duration::from_secs(30); |
44 |
const PING_PROBES_COUNT: u8 = 2; |
|
13124 | 45 |
|
13420 | 46 |
#[derive(Hash, Eq, PartialEq, Copy, Clone)] |
13419 | 47 |
pub enum NetworkClientState { |
48 |
Idle, |
|
49 |
NeedsWrite, |
|
50 |
NeedsRead, |
|
51 |
Closed, |
|
14835
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
52 |
#[cfg(feature = "tls-connections")] |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
53 |
Connected, |
13419 | 54 |
} |
55 |
||
56 |
type NetworkResult<T> = io::Result<(T, NetworkClientState)>; |
|
13124 | 57 |
|
13804 | 58 |
pub enum ClientSocket { |
14462 | 59 |
Plain(TcpStream), |
14835
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
60 |
#[cfg(feature = "tls-connections")] |
13804 | 61 |
SslHandshake(Option<MidHandshakeSslStream<TcpStream>>), |
14835
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
62 |
#[cfg(feature = "tls-connections")] |
14462 | 63 |
SslStream(SslStream<TcpStream>), |
13804 | 64 |
} |
65 |
||
66 |
impl ClientSocket { |
|
67 |
fn inner(&self) -> &TcpStream { |
|
68 |
match self { |
|
69 |
ClientSocket::Plain(stream) => stream, |
|
14835
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
70 |
#[cfg(feature = "tls-connections")] |
13804 | 71 |
ClientSocket::SslHandshake(Some(builder)) => builder.get_ref(), |
14835
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
72 |
#[cfg(feature = "tls-connections")] |
13804 | 73 |
ClientSocket::SslHandshake(None) => unreachable!(), |
14835
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
74 |
#[cfg(feature = "tls-connections")] |
14462 | 75 |
ClientSocket::SslStream(ssl_stream) => ssl_stream.get_ref(), |
13804 | 76 |
} |
77 |
} |
|
78 |
} |
|
79 |
||
13124 | 80 |
pub struct NetworkClient { |
81 |
id: ClientId, |
|
13804 | 82 |
socket: ClientSocket, |
13124 | 83 |
peer_addr: SocketAddr, |
84 |
decoder: ProtocolDecoder, |
|
14462 | 85 |
buf_out: netbuf::Buf, |
14808 | 86 |
timeout: timer::Timeout, |
13124 | 87 |
} |
88 |
||
89 |
impl NetworkClient { |
|
14808 | 90 |
pub fn new( |
91 |
id: ClientId, |
|
92 |
socket: ClientSocket, |
|
93 |
peer_addr: SocketAddr, |
|
94 |
timeout: timer::Timeout, |
|
95 |
) -> NetworkClient { |
|
13124 | 96 |
NetworkClient { |
14462 | 97 |
id, |
98 |
socket, |
|
99 |
peer_addr, |
|
13124 | 100 |
decoder: ProtocolDecoder::new(), |
14462 | 101 |
buf_out: netbuf::Buf::new(), |
14808 | 102 |
timeout, |
13124 | 103 |
} |
104 |
} |
|
105 |
||
13807 | 106 |
#[cfg(feature = "tls-connections")] |
14462 | 107 |
fn handshake_impl( |
108 |
&mut self, |
|
109 |
handshake: MidHandshakeSslStream<TcpStream>, |
|
110 |
) -> io::Result<NetworkClientState> { |
|
13807 | 111 |
match handshake.handshake() { |
112 |
Ok(stream) => { |
|
113 |
self.socket = ClientSocket::SslStream(stream); |
|
14462 | 114 |
debug!( |
115 |
"TLS handshake with {} ({}) completed", |
|
116 |
self.id, self.peer_addr |
|
117 |
); |
|
14835
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
118 |
Ok(NetworkClientState::Connected) |
13807 | 119 |
} |
120 |
Err(HandshakeError::WouldBlock(new_handshake)) => { |
|
121 |
self.socket = ClientSocket::SslHandshake(Some(new_handshake)); |
|
122 |
Ok(NetworkClientState::Idle) |
|
123 |
} |
|
13808 | 124 |
Err(HandshakeError::Failure(new_handshake)) => { |
125 |
self.socket = ClientSocket::SslHandshake(Some(new_handshake)); |
|
13807 | 126 |
debug!("TLS handshake with {} ({}) failed", self.id, self.peer_addr); |
127 |
Err(Error::new(ErrorKind::Other, "Connection failure")) |
|
128 |
} |
|
14462 | 129 |
Err(HandshakeError::SetupFailure(_)) => unreachable!(), |
13807 | 130 |
} |
131 |
} |
|
132 |
||
14462 | 133 |
fn read_impl<R: Read>( |
134 |
decoder: &mut ProtocolDecoder, |
|
135 |
source: &mut R, |
|
136 |
id: ClientId, |
|
137 |
addr: &SocketAddr, |
|
15080 | 138 |
) -> NetworkResult<Vec<HwProtocolMessage>> { |
13419 | 139 |
let mut bytes_read = 0; |
140 |
let result = loop { |
|
13804 | 141 |
match decoder.read_from(source) { |
13419 | 142 |
Ok(bytes) => { |
13804 | 143 |
debug!("Client {}: read {} bytes", id, bytes); |
13419 | 144 |
bytes_read += bytes; |
145 |
if bytes == 0 { |
|
146 |
let result = if bytes_read == 0 { |
|
13804 | 147 |
info!("EOF for client {} ({})", id, addr); |
13419 | 148 |
(Vec::new(), NetworkClientState::Closed) |
149 |
} else { |
|
13804 | 150 |
(decoder.extract_messages(), NetworkClientState::NeedsRead) |
13419 | 151 |
}; |
152 |
break Ok(result); |
|
14462 | 153 |
} else if bytes_read >= MAX_BYTES_PER_READ { |
154 |
break Ok((decoder.extract_messages(), NetworkClientState::NeedsRead)); |
|
13419 | 155 |
} |
156 |
} |
|
157 |
Err(ref error) if error.kind() == ErrorKind::WouldBlock => { |
|
14462 | 158 |
let messages = if bytes_read == 0 { |
13419 | 159 |
Vec::new() |
160 |
} else { |
|
13804 | 161 |
decoder.extract_messages() |
13419 | 162 |
}; |
163 |
break Ok((messages, NetworkClientState::Idle)); |
|
164 |
} |
|
14462 | 165 |
Err(error) => break Err(error), |
13419 | 166 |
} |
167 |
}; |
|
168 |
result |
|
169 |
} |
|
170 |
||
15080 | 171 |
pub fn read(&mut self) -> NetworkResult<Vec<HwProtocolMessage>> { |
13804 | 172 |
match self.socket { |
14462 | 173 |
ClientSocket::Plain(ref mut stream) => { |
174 |
NetworkClient::read_impl(&mut self.decoder, stream, self.id, &self.peer_addr) |
|
175 |
} |
|
14835
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
176 |
#[cfg(feature = "tls-connections")] |
13804 | 177 |
ClientSocket::SslHandshake(ref mut handshake_opt) => { |
13807 | 178 |
let handshake = std::mem::replace(handshake_opt, None).unwrap(); |
179 |
Ok((Vec::new(), self.handshake_impl(handshake)?)) |
|
14462 | 180 |
} |
14835
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
181 |
#[cfg(feature = "tls-connections")] |
14462 | 182 |
ClientSocket::SslStream(ref mut stream) => { |
13804 | 183 |
NetworkClient::read_impl(&mut self.decoder, stream, self.id, &self.peer_addr) |
14462 | 184 |
} |
13804 | 185 |
} |
186 |
} |
|
187 |
||
188 |
fn write_impl<W: Write>(buf_out: &mut netbuf::Buf, destination: &mut W) -> NetworkResult<()> { |
|
13419 | 189 |
let result = loop { |
13804 | 190 |
match buf_out.write_to(destination) { |
14462 | 191 |
Ok(bytes) if buf_out.is_empty() || bytes == 0 => { |
14676
455865ccd36c
Server action refactoring part 2 of N
alfadur <mail@none>
parents:
14462
diff
changeset
|
192 |
break Ok(((), NetworkClientState::Idle)); |
14462 | 193 |
} |
13420 | 194 |
Ok(_) => (), |
14462 | 195 |
Err(ref error) |
196 |
if error.kind() == ErrorKind::Interrupted |
|
197 |
|| error.kind() == ErrorKind::WouldBlock => |
|
198 |
{ |
|
13419 | 199 |
break Ok(((), NetworkClientState::NeedsWrite)); |
14462 | 200 |
} |
201 |
Err(error) => break Err(error), |
|
13419 | 202 |
} |
203 |
}; |
|
13804 | 204 |
result |
205 |
} |
|
206 |
||
207 |
pub fn write(&mut self) -> NetworkResult<()> { |
|
14835
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
208 |
let result = match self.socket { |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
209 |
ClientSocket::Plain(ref mut stream) => { |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
210 |
NetworkClient::write_impl(&mut self.buf_out, stream) |
13804 | 211 |
} |
14462 | 212 |
#[cfg(feature = "tls-connections")] |
14835
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
213 |
ClientSocket::SslHandshake(ref mut handshake_opt) => { |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
214 |
let handshake = std::mem::replace(handshake_opt, None).unwrap(); |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
215 |
Ok(((), self.handshake_impl(handshake)?)) |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
216 |
} |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
217 |
#[cfg(feature = "tls-connections")] |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
218 |
ClientSocket::SslStream(ref mut stream) => { |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
219 |
NetworkClient::write_impl(&mut self.buf_out, stream) |
13804 | 220 |
} |
221 |
}; |
|
222 |
||
223 |
self.socket.inner().flush()?; |
|
13419 | 224 |
result |
225 |
} |
|
226 |
||
13124 | 227 |
pub fn send_raw_msg(&mut self, msg: &[u8]) { |
13529 | 228 |
self.buf_out.write_all(msg).unwrap(); |
13124 | 229 |
} |
230 |
||
13529 | 231 |
pub fn send_string(&mut self, msg: &str) { |
13124 | 232 |
self.send_raw_msg(&msg.as_bytes()); |
233 |
} |
|
14808 | 234 |
|
235 |
pub fn replace_timeout(&mut self, timeout: timer::Timeout) -> timer::Timeout { |
|
236 |
replace(&mut self.timeout, timeout) |
|
237 |
} |
|
13124 | 238 |
} |
239 |
||
13804 | 240 |
#[cfg(feature = "tls-connections")] |
241 |
struct ServerSsl { |
|
14835
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
242 |
listener: TcpListener, |
14462 | 243 |
context: SslContext, |
13804 | 244 |
} |
245 |
||
14784
f43ab2bd76ae
add a thread for internal server IO and implement account checking with it
alfadur
parents:
14702
diff
changeset
|
246 |
#[cfg(feature = "official-server")] |
f43ab2bd76ae
add a thread for internal server IO and implement account checking with it
alfadur
parents:
14702
diff
changeset
|
247 |
pub struct IoLayer { |
f43ab2bd76ae
add a thread for internal server IO and implement account checking with it
alfadur
parents:
14702
diff
changeset
|
248 |
next_request_id: RequestId, |
f43ab2bd76ae
add a thread for internal server IO and implement account checking with it
alfadur
parents:
14702
diff
changeset
|
249 |
request_queue: Vec<(RequestId, ClientId)>, |
15103 | 250 |
io_thread: IoThread, |
14784
f43ab2bd76ae
add a thread for internal server IO and implement account checking with it
alfadur
parents:
14702
diff
changeset
|
251 |
} |
f43ab2bd76ae
add a thread for internal server IO and implement account checking with it
alfadur
parents:
14702
diff
changeset
|
252 |
|
f43ab2bd76ae
add a thread for internal server IO and implement account checking with it
alfadur
parents:
14702
diff
changeset
|
253 |
#[cfg(feature = "official-server")] |
f43ab2bd76ae
add a thread for internal server IO and implement account checking with it
alfadur
parents:
14702
diff
changeset
|
254 |
impl IoLayer { |
f43ab2bd76ae
add a thread for internal server IO and implement account checking with it
alfadur
parents:
14702
diff
changeset
|
255 |
fn new() -> Self { |
f43ab2bd76ae
add a thread for internal server IO and implement account checking with it
alfadur
parents:
14702
diff
changeset
|
256 |
Self { |
f43ab2bd76ae
add a thread for internal server IO and implement account checking with it
alfadur
parents:
14702
diff
changeset
|
257 |
next_request_id: 0, |
f43ab2bd76ae
add a thread for internal server IO and implement account checking with it
alfadur
parents:
14702
diff
changeset
|
258 |
request_queue: vec![], |
15103 | 259 |
io_thread: IoThread::new(), |
14784
f43ab2bd76ae
add a thread for internal server IO and implement account checking with it
alfadur
parents:
14702
diff
changeset
|
260 |
} |
f43ab2bd76ae
add a thread for internal server IO and implement account checking with it
alfadur
parents:
14702
diff
changeset
|
261 |
} |
f43ab2bd76ae
add a thread for internal server IO and implement account checking with it
alfadur
parents:
14702
diff
changeset
|
262 |
|
f43ab2bd76ae
add a thread for internal server IO and implement account checking with it
alfadur
parents:
14702
diff
changeset
|
263 |
fn send(&mut self, client_id: ClientId, task: IoTask) { |
f43ab2bd76ae
add a thread for internal server IO and implement account checking with it
alfadur
parents:
14702
diff
changeset
|
264 |
let request_id = self.next_request_id; |
f43ab2bd76ae
add a thread for internal server IO and implement account checking with it
alfadur
parents:
14702
diff
changeset
|
265 |
self.next_request_id += 1; |
f43ab2bd76ae
add a thread for internal server IO and implement account checking with it
alfadur
parents:
14702
diff
changeset
|
266 |
self.request_queue.push((request_id, client_id)); |
f43ab2bd76ae
add a thread for internal server IO and implement account checking with it
alfadur
parents:
14702
diff
changeset
|
267 |
self.io_thread.send(request_id, task); |
f43ab2bd76ae
add a thread for internal server IO and implement account checking with it
alfadur
parents:
14702
diff
changeset
|
268 |
} |
f43ab2bd76ae
add a thread for internal server IO and implement account checking with it
alfadur
parents:
14702
diff
changeset
|
269 |
|
f43ab2bd76ae
add a thread for internal server IO and implement account checking with it
alfadur
parents:
14702
diff
changeset
|
270 |
fn try_recv(&mut self) -> Option<(ClientId, IoResult)> { |
f43ab2bd76ae
add a thread for internal server IO and implement account checking with it
alfadur
parents:
14702
diff
changeset
|
271 |
let (request_id, result) = self.io_thread.try_recv()?; |
f43ab2bd76ae
add a thread for internal server IO and implement account checking with it
alfadur
parents:
14702
diff
changeset
|
272 |
if let Some(index) = self |
f43ab2bd76ae
add a thread for internal server IO and implement account checking with it
alfadur
parents:
14702
diff
changeset
|
273 |
.request_queue |
f43ab2bd76ae
add a thread for internal server IO and implement account checking with it
alfadur
parents:
14702
diff
changeset
|
274 |
.iter() |
f43ab2bd76ae
add a thread for internal server IO and implement account checking with it
alfadur
parents:
14702
diff
changeset
|
275 |
.position(|(id, _)| *id == request_id) |
f43ab2bd76ae
add a thread for internal server IO and implement account checking with it
alfadur
parents:
14702
diff
changeset
|
276 |
{ |
f43ab2bd76ae
add a thread for internal server IO and implement account checking with it
alfadur
parents:
14702
diff
changeset
|
277 |
let (_, client_id) = self.request_queue.swap_remove(index); |
f43ab2bd76ae
add a thread for internal server IO and implement account checking with it
alfadur
parents:
14702
diff
changeset
|
278 |
Some((client_id, result)) |
f43ab2bd76ae
add a thread for internal server IO and implement account checking with it
alfadur
parents:
14702
diff
changeset
|
279 |
} else { |
f43ab2bd76ae
add a thread for internal server IO and implement account checking with it
alfadur
parents:
14702
diff
changeset
|
280 |
None |
f43ab2bd76ae
add a thread for internal server IO and implement account checking with it
alfadur
parents:
14702
diff
changeset
|
281 |
} |
f43ab2bd76ae
add a thread for internal server IO and implement account checking with it
alfadur
parents:
14702
diff
changeset
|
282 |
} |
f43ab2bd76ae
add a thread for internal server IO and implement account checking with it
alfadur
parents:
14702
diff
changeset
|
283 |
|
f43ab2bd76ae
add a thread for internal server IO and implement account checking with it
alfadur
parents:
14702
diff
changeset
|
284 |
fn cancel(&mut self, client_id: ClientId) { |
f43ab2bd76ae
add a thread for internal server IO and implement account checking with it
alfadur
parents:
14702
diff
changeset
|
285 |
let mut index = 0; |
f43ab2bd76ae
add a thread for internal server IO and implement account checking with it
alfadur
parents:
14702
diff
changeset
|
286 |
while index < self.request_queue.len() { |
f43ab2bd76ae
add a thread for internal server IO and implement account checking with it
alfadur
parents:
14702
diff
changeset
|
287 |
if self.request_queue[index].1 == client_id { |
f43ab2bd76ae
add a thread for internal server IO and implement account checking with it
alfadur
parents:
14702
diff
changeset
|
288 |
self.request_queue.swap_remove(index); |
f43ab2bd76ae
add a thread for internal server IO and implement account checking with it
alfadur
parents:
14702
diff
changeset
|
289 |
} else { |
f43ab2bd76ae
add a thread for internal server IO and implement account checking with it
alfadur
parents:
14702
diff
changeset
|
290 |
index += 1; |
f43ab2bd76ae
add a thread for internal server IO and implement account checking with it
alfadur
parents:
14702
diff
changeset
|
291 |
} |
f43ab2bd76ae
add a thread for internal server IO and implement account checking with it
alfadur
parents:
14702
diff
changeset
|
292 |
} |
f43ab2bd76ae
add a thread for internal server IO and implement account checking with it
alfadur
parents:
14702
diff
changeset
|
293 |
} |
f43ab2bd76ae
add a thread for internal server IO and implement account checking with it
alfadur
parents:
14702
diff
changeset
|
294 |
} |
f43ab2bd76ae
add a thread for internal server IO and implement account checking with it
alfadur
parents:
14702
diff
changeset
|
295 |
|
14808 | 296 |
enum TimeoutEvent { |
14812 | 297 |
SendPing { probes_count: u8 }, |
14808 | 298 |
DropClient, |
299 |
} |
|
300 |
||
301 |
struct TimerData(TimeoutEvent, ClientId); |
|
302 |
||
13124 | 303 |
pub struct NetworkLayer { |
304 |
listener: TcpListener, |
|
15080 | 305 |
server: HwServer, |
13419 | 306 |
clients: Slab<NetworkClient>, |
13420 | 307 |
pending: HashSet<(ClientId, NetworkClientState)>, |
13804 | 308 |
pending_cache: Vec<(ClientId, NetworkClientState)>, |
309 |
#[cfg(feature = "tls-connections")] |
|
14462 | 310 |
ssl: ServerSsl, |
14784
f43ab2bd76ae
add a thread for internal server IO and implement account checking with it
alfadur
parents:
14702
diff
changeset
|
311 |
#[cfg(feature = "official-server")] |
f43ab2bd76ae
add a thread for internal server IO and implement account checking with it
alfadur
parents:
14702
diff
changeset
|
312 |
io: IoLayer, |
14808 | 313 |
timer: timer::Timer<TimerData>, |
314 |
} |
|
315 |
||
14835
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
316 |
fn register_read<E: Evented>(poll: &Poll, evented: &E, token: mio::Token) -> io::Result<()> { |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
317 |
poll.register(evented, token, Ready::readable(), PollOpt::edge()) |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
318 |
} |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
319 |
|
14812 | 320 |
fn create_ping_timeout( |
321 |
timer: &mut timer::Timer<TimerData>, |
|
322 |
probes_count: u8, |
|
323 |
client_id: ClientId, |
|
324 |
) -> timer::Timeout { |
|
14808 | 325 |
timer.set_timeout( |
326 |
SEND_PING_TIMEOUT, |
|
14812 | 327 |
TimerData(TimeoutEvent::SendPing { probes_count }, client_id), |
14808 | 328 |
) |
329 |
} |
|
330 |
||
331 |
fn create_drop_timeout(timer: &mut timer::Timer<TimerData>, client_id: ClientId) -> timer::Timeout { |
|
332 |
timer.set_timeout( |
|
333 |
DROP_CLIENT_TIMEOUT, |
|
334 |
TimerData(TimeoutEvent::DropClient, client_id), |
|
335 |
) |
|
13124 | 336 |
} |
337 |
||
338 |
impl NetworkLayer { |
|
14835
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
339 |
pub fn register(&self, poll: &Poll) -> io::Result<()> { |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
340 |
register_read(poll, &self.listener, utils::SERVER_TOKEN)?; |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
341 |
#[cfg(feature = "tls-connections")] |
14840 | 342 |
register_read(poll, &self.ssl.listener, utils::SECURE_SERVER_TOKEN)?; |
14835
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
343 |
register_read(poll, &self.timer, utils::TIMER_TOKEN)?; |
14808 | 344 |
|
14784
f43ab2bd76ae
add a thread for internal server IO and implement account checking with it
alfadur
parents:
14702
diff
changeset
|
345 |
#[cfg(feature = "official-server")] |
f43ab2bd76ae
add a thread for internal server IO and implement account checking with it
alfadur
parents:
14702
diff
changeset
|
346 |
self.io.io_thread.register_rx(poll, utils::IO_TOKEN)?; |
f43ab2bd76ae
add a thread for internal server IO and implement account checking with it
alfadur
parents:
14702
diff
changeset
|
347 |
|
f43ab2bd76ae
add a thread for internal server IO and implement account checking with it
alfadur
parents:
14702
diff
changeset
|
348 |
Ok(()) |
13124 | 349 |
} |
350 |
||
351 |
fn deregister_client(&mut self, poll: &Poll, id: ClientId) { |
|
352 |
let mut client_exists = false; |
|
13419 | 353 |
if let Some(ref client) = self.clients.get(id) { |
13804 | 354 |
poll.deregister(client.socket.inner()) |
13529 | 355 |
.expect("could not deregister socket"); |
13124 | 356 |
info!("client {} ({}) removed", client.id, client.peer_addr); |
357 |
client_exists = true; |
|
358 |
} |
|
359 |
if client_exists { |
|
360 |
self.clients.remove(id); |
|
14784
f43ab2bd76ae
add a thread for internal server IO and implement account checking with it
alfadur
parents:
14702
diff
changeset
|
361 |
#[cfg(feature = "official-server")] |
f43ab2bd76ae
add a thread for internal server IO and implement account checking with it
alfadur
parents:
14702
diff
changeset
|
362 |
self.io.cancel(id); |
13124 | 363 |
} |
364 |
} |
|
365 |
||
14462 | 366 |
fn register_client( |
367 |
&mut self, |
|
368 |
poll: &Poll, |
|
369 |
client_socket: ClientSocket, |
|
370 |
addr: SocketAddr, |
|
14921 | 371 |
) -> io::Result<ClientId> { |
14698 | 372 |
let entry = self.clients.vacant_entry(); |
373 |
let client_id = entry.key(); |
|
374 |
||
14462 | 375 |
poll.register( |
376 |
client_socket.inner(), |
|
14698 | 377 |
Token(client_id), |
14462 | 378 |
Ready::readable() | Ready::writable(), |
379 |
PollOpt::edge(), |
|
14921 | 380 |
)?; |
13124 | 381 |
|
14808 | 382 |
let client = NetworkClient::new( |
383 |
client_id, |
|
384 |
client_socket, |
|
385 |
addr, |
|
14812 | 386 |
create_ping_timeout(&mut self.timer, PING_PROBES_COUNT - 1, client_id), |
14808 | 387 |
); |
13124 | 388 |
info!("client {} ({}) added", client.id, client.peer_addr); |
389 |
entry.insert(client); |
|
14698 | 390 |
|
14921 | 391 |
Ok(client_id) |
13124 | 392 |
} |
393 |
||
14784
f43ab2bd76ae
add a thread for internal server IO and implement account checking with it
alfadur
parents:
14702
diff
changeset
|
394 |
fn handle_response(&mut self, mut response: handlers::Response, poll: &Poll) { |
14835
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
395 |
if response.is_empty() { |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
396 |
return; |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
397 |
} |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
398 |
|
14677
6e6632068a33
Server action refactoring part 3 of N
alfadur <mail@none>
parents:
14676
diff
changeset
|
399 |
debug!("{} pending server messages", response.len()); |
6e6632068a33
Server action refactoring part 3 of N
alfadur <mail@none>
parents:
14676
diff
changeset
|
400 |
let output = response.extract_messages(&mut self.server); |
6e6632068a33
Server action refactoring part 3 of N
alfadur <mail@none>
parents:
14676
diff
changeset
|
401 |
for (clients, message) in output { |
13424 | 402 |
debug!("Message {:?} to {:?}", message, clients); |
403 |
let msg_string = message.to_raw_protocol(); |
|
404 |
for client_id in clients { |
|
405 |
if let Some(client) = self.clients.get_mut(client_id) { |
|
406 |
client.send_string(&msg_string); |
|
14462 | 407 |
self.pending |
408 |
.insert((client_id, NetworkClientState::NeedsWrite)); |
|
13419 | 409 |
} |
410 |
} |
|
411 |
} |
|
14701 | 412 |
|
413 |
for client_id in response.extract_removed_clients() { |
|
414 |
self.deregister_client(poll, client_id); |
|
415 |
} |
|
14784
f43ab2bd76ae
add a thread for internal server IO and implement account checking with it
alfadur
parents:
14702
diff
changeset
|
416 |
|
f43ab2bd76ae
add a thread for internal server IO and implement account checking with it
alfadur
parents:
14702
diff
changeset
|
417 |
#[cfg(feature = "official-server")] |
f43ab2bd76ae
add a thread for internal server IO and implement account checking with it
alfadur
parents:
14702
diff
changeset
|
418 |
{ |
f43ab2bd76ae
add a thread for internal server IO and implement account checking with it
alfadur
parents:
14702
diff
changeset
|
419 |
let client_id = response.client_id(); |
f43ab2bd76ae
add a thread for internal server IO and implement account checking with it
alfadur
parents:
14702
diff
changeset
|
420 |
for task in response.extract_io_tasks() { |
f43ab2bd76ae
add a thread for internal server IO and implement account checking with it
alfadur
parents:
14702
diff
changeset
|
421 |
self.io.send(client_id, task); |
f43ab2bd76ae
add a thread for internal server IO and implement account checking with it
alfadur
parents:
14702
diff
changeset
|
422 |
} |
f43ab2bd76ae
add a thread for internal server IO and implement account checking with it
alfadur
parents:
14702
diff
changeset
|
423 |
} |
f43ab2bd76ae
add a thread for internal server IO and implement account checking with it
alfadur
parents:
14702
diff
changeset
|
424 |
} |
f43ab2bd76ae
add a thread for internal server IO and implement account checking with it
alfadur
parents:
14702
diff
changeset
|
425 |
|
14808 | 426 |
pub fn handle_timeout(&mut self, poll: &Poll) -> io::Result<()> { |
427 |
while let Some(TimerData(event, client_id)) = self.timer.poll() { |
|
428 |
match event { |
|
14812 | 429 |
TimeoutEvent::SendPing { probes_count } => { |
14808 | 430 |
if let Some(ref mut client) = self.clients.get_mut(client_id) { |
15080 | 431 |
client.send_string(&HwServerMessage::Ping.to_raw_protocol()); |
14808 | 432 |
client.write()?; |
14812 | 433 |
let timeout = if probes_count != 0 { |
434 |
create_ping_timeout(&mut self.timer, probes_count - 1, client_id) |
|
435 |
} else { |
|
436 |
create_drop_timeout(&mut self.timer, client_id) |
|
437 |
}; |
|
438 |
client.replace_timeout(timeout); |
|
14808 | 439 |
} |
440 |
} |
|
441 |
TimeoutEvent::DropClient => { |
|
442 |
self.operation_failed( |
|
443 |
poll, |
|
444 |
client_id, |
|
445 |
&ErrorKind::TimedOut.into(), |
|
446 |
"No ping response", |
|
447 |
)?; |
|
448 |
} |
|
449 |
} |
|
450 |
} |
|
451 |
Ok(()) |
|
452 |
} |
|
453 |
||
14784
f43ab2bd76ae
add a thread for internal server IO and implement account checking with it
alfadur
parents:
14702
diff
changeset
|
454 |
#[cfg(feature = "official-server")] |
15107 | 455 |
pub fn handle_io_result(&mut self, poll: &Poll) -> io::Result<()> { |
456 |
while let Some((client_id, result)) = self.io.try_recv() { |
|
457 |
debug!("Handling io result {:?} for client {}", result, client_id); |
|
14784
f43ab2bd76ae
add a thread for internal server IO and implement account checking with it
alfadur
parents:
14702
diff
changeset
|
458 |
let mut response = handlers::Response::new(client_id); |
f43ab2bd76ae
add a thread for internal server IO and implement account checking with it
alfadur
parents:
14702
diff
changeset
|
459 |
handlers::handle_io_result(&mut self.server, client_id, &mut response, result); |
15107 | 460 |
self.handle_response(response, poll); |
14784
f43ab2bd76ae
add a thread for internal server IO and implement account checking with it
alfadur
parents:
14702
diff
changeset
|
461 |
} |
14921 | 462 |
Ok(()) |
13419 | 463 |
} |
464 |
||
13804 | 465 |
fn create_client_socket(&self, socket: TcpStream) -> io::Result<ClientSocket> { |
14835
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
466 |
Ok(ClientSocket::Plain(socket)) |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
467 |
} |
13804 | 468 |
|
14835
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
469 |
#[cfg(feature = "tls-connections")] |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
470 |
fn create_client_secure_socket(&self, socket: TcpStream) -> io::Result<ClientSocket> { |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
471 |
let ssl = Ssl::new(&self.ssl.context).unwrap(); |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
472 |
let mut builder = SslStreamBuilder::new(ssl, socket); |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
473 |
builder.set_accept_state(); |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
474 |
match builder.handshake() { |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
475 |
Ok(stream) => Ok(ClientSocket::SslStream(stream)), |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
476 |
Err(HandshakeError::WouldBlock(stream)) => Ok(ClientSocket::SslHandshake(Some(stream))), |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
477 |
Err(e) => { |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
478 |
debug!("OpenSSL handshake failed: {}", e); |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
479 |
Err(Error::new(ErrorKind::Other, "Connection failure")) |
13804 | 480 |
} |
481 |
} |
|
482 |
} |
|
483 |
||
14840 | 484 |
fn init_client(&mut self, poll: &Poll, client_id: ClientId) { |
485 |
let mut response = handlers::Response::new(client_id); |
|
14852 | 486 |
|
487 |
if let ClientSocket::Plain(_) = self.clients[client_id].socket { |
|
488 |
#[cfg(feature = "tls-connections")] |
|
489 |
response.add(Redirect(self.ssl.listener.local_addr().unwrap().port()).send_self()) |
|
490 |
} |
|
14840 | 491 |
|
492 |
handlers::handle_client_accept(&mut self.server, client_id, &mut response); |
|
493 |
self.handle_response(response, poll); |
|
494 |
} |
|
495 |
||
14835
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
496 |
pub fn accept_client(&mut self, poll: &Poll, server_token: mio::Token) -> io::Result<()> { |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
497 |
match server_token { |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
498 |
utils::SERVER_TOKEN => { |
14875 | 499 |
let (client_socket, addr) = self.listener.accept()?; |
500 |
info!("Connected(plaintext): {}", addr); |
|
14835
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
501 |
let client_id = |
14921 | 502 |
self.register_client(poll, self.create_client_socket(client_socket)?, addr)?; |
14840 | 503 |
self.init_client(poll, client_id); |
14835
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
504 |
} |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
505 |
#[cfg(feature = "tls-connections")] |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
506 |
utils::SECURE_SERVER_TOKEN => { |
14875 | 507 |
let (client_socket, addr) = self.ssl.listener.accept()?; |
508 |
info!("Connected(TLS): {}", addr); |
|
14921 | 509 |
self.register_client(poll, self.create_client_secure_socket(client_socket)?, addr)?; |
14835
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
510 |
} |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
511 |
_ => unreachable!(), |
14698 | 512 |
} |
13124 | 513 |
|
514 |
Ok(()) |
|
515 |
} |
|
516 |
||
14462 | 517 |
fn operation_failed( |
518 |
&mut self, |
|
519 |
poll: &Poll, |
|
520 |
client_id: ClientId, |
|
521 |
error: &Error, |
|
522 |
msg: &str, |
|
523 |
) -> io::Result<()> { |
|
13419 | 524 |
let addr = if let Some(ref mut client) = self.clients.get_mut(client_id) { |
525 |
client.peer_addr |
|
526 |
} else { |
|
527 |
SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), 0) |
|
528 |
}; |
|
529 |
debug!("{}({}): {}", msg, addr, error); |
|
530 |
self.client_error(poll, client_id) |
|
13124 | 531 |
} |
532 |
||
14462 | 533 |
pub fn client_readable(&mut self, poll: &Poll, client_id: ClientId) -> io::Result<()> { |
534 |
let messages = if let Some(ref mut client) = self.clients.get_mut(client_id) { |
|
14812 | 535 |
let timeout = client.replace_timeout(create_ping_timeout( |
536 |
&mut self.timer, |
|
537 |
PING_PROBES_COUNT - 1, |
|
538 |
client_id, |
|
539 |
)); |
|
14808 | 540 |
self.timer.cancel_timeout(&timeout); |
14462 | 541 |
client.read() |
542 |
} else { |
|
543 |
warn!("invalid readable client: {}", client_id); |
|
544 |
Ok((Vec::new(), NetworkClientState::Idle)) |
|
545 |
}; |
|
13419 | 546 |
|
14676
455865ccd36c
Server action refactoring part 2 of N
alfadur <mail@none>
parents:
14462
diff
changeset
|
547 |
let mut response = handlers::Response::new(client_id); |
455865ccd36c
Server action refactoring part 2 of N
alfadur <mail@none>
parents:
14462
diff
changeset
|
548 |
|
13419 | 549 |
match messages { |
550 |
Ok((messages, state)) => { |
|
551 |
for message in messages { |
|
14676
455865ccd36c
Server action refactoring part 2 of N
alfadur <mail@none>
parents:
14462
diff
changeset
|
552 |
debug!("Handling message {:?} for client {}", message, client_id); |
14801 | 553 |
handlers::handle(&mut self.server, client_id, &mut response, message); |
13419 | 554 |
} |
555 |
match state { |
|
13420 | 556 |
NetworkClientState::NeedsRead => { |
557 |
self.pending.insert((client_id, state)); |
|
14462 | 558 |
} |
559 |
NetworkClientState::Closed => self.client_error(&poll, client_id)?, |
|
14835
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
560 |
#[cfg(feature = "tls-connections")] |
14840 | 561 |
NetworkClientState::Connected => self.init_client(poll, client_id), |
13419 | 562 |
_ => {} |
563 |
}; |
|
13124 | 564 |
} |
13419 | 565 |
Err(e) => self.operation_failed( |
14462 | 566 |
poll, |
567 |
client_id, |
|
568 |
&e, |
|
569 |
"Error while reading from client socket", |
|
570 |
)?, |
|
13124 | 571 |
} |
572 |
||
14835
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
573 |
self.handle_response(response, poll); |
13124 | 574 |
|
575 |
Ok(()) |
|
576 |
} |
|
577 |
||
14462 | 578 |
pub fn client_writable(&mut self, poll: &Poll, client_id: ClientId) -> io::Result<()> { |
579 |
let result = if let Some(ref mut client) = self.clients.get_mut(client_id) { |
|
580 |
client.write() |
|
581 |
} else { |
|
582 |
warn!("invalid writable client: {}", client_id); |
|
583 |
Ok(((), NetworkClientState::Idle)) |
|
584 |
}; |
|
13419 | 585 |
|
586 |
match result { |
|
13420 | 587 |
Ok(((), state)) if state == NetworkClientState::NeedsWrite => { |
588 |
self.pending.insert((client_id, state)); |
|
14462 | 589 |
} |
13420 | 590 |
Ok(_) => {} |
14462 | 591 |
Err(e) => { |
592 |
self.operation_failed(poll, client_id, &e, "Error while writing to client socket")? |
|
593 |
} |
|
13124 | 594 |
} |
595 |
||
596 |
Ok(()) |
|
597 |
} |
|
598 |
||
14462 | 599 |
pub fn client_error(&mut self, poll: &Poll, client_id: ClientId) -> io::Result<()> { |
13124 | 600 |
self.deregister_client(poll, client_id); |
14678
08a8605bafaf
Server action refactoring part 4 of N
alfadur <mail@none>
parents:
14677
diff
changeset
|
601 |
let mut response = handlers::Response::new(client_id); |
08a8605bafaf
Server action refactoring part 4 of N
alfadur <mail@none>
parents:
14677
diff
changeset
|
602 |
handlers::handle_client_loss(&mut self.server, client_id, &mut response); |
14784
f43ab2bd76ae
add a thread for internal server IO and implement account checking with it
alfadur
parents:
14702
diff
changeset
|
603 |
self.handle_response(response, poll); |
13124 | 604 |
|
605 |
Ok(()) |
|
606 |
} |
|
13419 | 607 |
|
608 |
pub fn has_pending_operations(&self) -> bool { |
|
609 |
!self.pending.is_empty() |
|
610 |
} |
|
611 |
||
612 |
pub fn on_idle(&mut self, poll: &Poll) -> io::Result<()> { |
|
13420 | 613 |
if self.has_pending_operations() { |
13483 | 614 |
let mut cache = replace(&mut self.pending_cache, Vec::new()); |
13420 | 615 |
cache.extend(self.pending.drain()); |
616 |
for (id, state) in cache.drain(..) { |
|
617 |
match state { |
|
14462 | 618 |
NetworkClientState::NeedsRead => self.client_readable(poll, id)?, |
619 |
NetworkClientState::NeedsWrite => self.client_writable(poll, id)?, |
|
13420 | 620 |
_ => {} |
621 |
} |
|
13419 | 622 |
} |
13420 | 623 |
swap(&mut cache, &mut self.pending_cache); |
13419 | 624 |
} |
625 |
Ok(()) |
|
626 |
} |
|
13124 | 627 |
} |
14835
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
628 |
|
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
629 |
pub struct NetworkLayerBuilder { |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
630 |
listener: Option<TcpListener>, |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
631 |
secure_listener: Option<TcpListener>, |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
632 |
clients_capacity: usize, |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
633 |
rooms_capacity: usize, |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
634 |
} |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
635 |
|
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
636 |
impl Default for NetworkLayerBuilder { |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
637 |
fn default() -> Self { |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
638 |
Self { |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
639 |
clients_capacity: 1024, |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
640 |
rooms_capacity: 512, |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
641 |
listener: None, |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
642 |
secure_listener: None, |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
643 |
} |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
644 |
} |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
645 |
} |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
646 |
|
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
647 |
impl NetworkLayerBuilder { |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
648 |
pub fn with_listener(self, listener: TcpListener) -> Self { |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
649 |
Self { |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
650 |
listener: Some(listener), |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
651 |
..self |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
652 |
} |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
653 |
} |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
654 |
|
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
655 |
pub fn with_secure_listener(self, listener: TcpListener) -> Self { |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
656 |
Self { |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
657 |
secure_listener: Some(listener), |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
658 |
..self |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
659 |
} |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
660 |
} |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
661 |
|
14840 | 662 |
#[cfg(feature = "tls-connections")] |
663 |
fn create_ssl_context(listener: TcpListener) -> ServerSsl { |
|
664 |
let mut builder = SslContextBuilder::new(SslMethod::tls()).unwrap(); |
|
665 |
builder.set_verify(SslVerifyMode::NONE); |
|
666 |
builder.set_read_ahead(true); |
|
667 |
builder |
|
668 |
.set_certificate_file("ssl/cert.pem", SslFiletype::PEM) |
|
669 |
.expect("Cannot find certificate file"); |
|
670 |
builder |
|
671 |
.set_private_key_file("ssl/key.pem", SslFiletype::PEM) |
|
672 |
.expect("Cannot find private key file"); |
|
673 |
builder.set_options(SslOptions::NO_COMPRESSION); |
|
674 |
builder.set_cipher_list("DEFAULT:!LOW:!RC4:!EXP").unwrap(); |
|
675 |
ServerSsl { |
|
676 |
listener, |
|
677 |
context: builder.build(), |
|
678 |
} |
|
679 |
} |
|
680 |
||
14835
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
681 |
pub fn build(self) -> NetworkLayer { |
15080 | 682 |
let server = HwServer::new(self.clients_capacity, self.rooms_capacity); |
14835
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
683 |
let clients = Slab::with_capacity(self.clients_capacity); |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
684 |
let pending = HashSet::with_capacity(2 * self.clients_capacity); |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
685 |
let pending_cache = Vec::with_capacity(2 * self.clients_capacity); |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
686 |
let timer = timer::Builder::default().build(); |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
687 |
|
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
688 |
NetworkLayer { |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
689 |
listener: self.listener.expect("No listener provided"), |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
690 |
server, |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
691 |
clients, |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
692 |
pending, |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
693 |
pending_cache, |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
694 |
#[cfg(feature = "tls-connections")] |
14840 | 695 |
ssl: Self::create_ssl_context( |
14835
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
696 |
self.secure_listener.expect("No secure listener provided"), |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
697 |
), |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
698 |
#[cfg(feature = "official-server")] |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
699 |
io: IoLayer::new(), |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
700 |
timer, |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
701 |
} |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
702 |
} |
8ddb5842fe0b
allow running plaintext and tls servers in parallel
alfadur
parents:
14812
diff
changeset
|
703 |
} |