1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
use crate::gameplay_socket::PeerIdentifier;
use crate::secure_rand;
use anyhow::Context;
use rustls::{Certificate, PrivateKey, ServerConfig, ServerConnection};
use std::io::Write;
use std::net::{Shutdown, TcpListener, TcpStream};
use std::sync::mpsc::{self, Receiver, SyncSender};
use std::sync::Arc;
use std::thread;
#[allow(unused_imports)]
use crate::gameplay_socket::GameplaySocket;
#[allow(unused_imports)]
use common::protocol::MessageOrderer;
pub struct LoginServer {
peer_id_receiver: Receiver<(PeerIdentifier, [u8; 32])>,
}
impl LoginServer {
pub fn new() -> anyhow::Result<LoginServer> {
let addr = "0.0.0.0:7812";
let listener = TcpListener::bind(addr)
.context("Could not bind the TCP listener! Is the server already running?")?;
let cert_chain = vec![Certificate(
include_bytes!("../../certs/server.crt").to_vec(),
)];
let cert_key = PrivateKey(include_bytes!("../../certs/server.key").to_vec());
let server_config = Arc::new(
ServerConfig::builder()
.with_safe_defaults()
.with_no_client_auth()
.with_single_cert(cert_chain, cert_key)
.context("Could not create rustls ServerConfig!")?,
);
log::info!("Login server init done, listening for TCP connections on {addr}.");
let (sender, peer_id_receiver) = mpsc::sync_channel(0);
thread::spawn(move || {
for stream in listener.incoming() {
match stream {
Ok(stream) => {
let server_config = server_config.clone();
let sender = sender.clone();
thread::spawn(move || {
if let Err(err) = handle_login_conn(stream, server_config, sender) {
log::debug!("Error during login: {err:?}")
}
});
}
Err(err) => log::debug!("Failed to accept TCP connection: {err}"),
}
}
});
Ok(LoginServer { peer_id_receiver })
}
pub fn try_recv_new_peers(&mut self) -> Option<(PeerIdentifier, [u8; 32])> {
self.peer_id_receiver.try_recv().ok()
}
}
fn handle_login_conn(
mut stream: TcpStream,
server_config: Arc<ServerConfig>,
peer_id_sender: SyncSender<(PeerIdentifier, [u8; 32])>,
) -> anyhow::Result<()> {
let mut connection = ServerConnection::new(server_config)
.context("Failed to create new rustls ServerConnection for this tcp stream")?;
connection
.complete_io(&mut stream)
.context("Failed to establish TLS connection.")?;
let mut stream = rustls::Stream::new(&mut connection, &mut stream);
let mut peer_identifier_bytes = [0u8; 16];
let mut encryption_key = [0u8; 32];
secure_rand::gen_bytes(&mut peer_identifier_bytes);
secure_rand::gen_bytes(&mut encryption_key);
let peer_id = u128::from_be_bytes(peer_identifier_bytes);
peer_id_sender
.send((PeerIdentifier(peer_id), encryption_key))
.context("Could not send peer identifier from new connection")?;
log::info!("New peer: {peer_id:032x}");
stream
.write_all(&peer_identifier_bytes)
.context("Failed to write the peer identifier to the tcp stream")?;
stream
.write_all(&encryption_key)
.context("Failed to write the peer identifier to the tcp stream")?;
stream
.sock
.shutdown(Shutdown::Both)
.context("Failed to shutdown tcp connection")?;
Ok(())
}