x11_input_mirror/
connector.rs1use encryption::ChaCha;
2
3use std::io::{Read, Write};
4use std::net::{SocketAddr, TcpStream};
5use std::time::Duration;
6
7pub struct Connector {
8 conns: Vec<(TcpStream, SocketAddr, ChaCha)>,
9}
10
11impl Connector {
12 pub fn connect(addrs: Vec<SocketAddr>, max_ping: Duration, password: &str) -> Connector {
13 let should_be_encrypted = !password.is_empty();
14 let should_be_encrypted_num = if should_be_encrypted { 1 } else { 0 };
15
16 let conns = addrs
17 .into_iter()
18 .map(|addr| {
19 let mut conn = TcpStream::connect(addr)
20 .unwrap_or_else(|_| panic!("Cannot connect to {}", addr));
21 conn.set_nodelay(true)
22 .unwrap_or_else(|_| panic!("Cannot connect to {} - set_nodelay failed", addr));
23 conn.set_read_timeout(Some(max_ping)).unwrap_or_else(|_| {
24 panic!("Cannot connect to {} - set_read_timeout failed", addr)
25 });
26 conn.set_write_timeout(Some(max_ping)).unwrap_or_else(|_| {
27 panic!("Cannot connect to {} - set_write_timeout failed", addr)
28 });
29
30 let mut buf = [0u8; 1];
32 buf[0] = should_be_encrypted_num;
33 conn.write_all(&buf)
34 .unwrap_or_else(|_| panic!("Cannot connect to {} - handshake3 failed", addr));
35
36 let mut buf = [0u8; 25];
38 conn.read_exact(&mut buf)
39 .unwrap_or_else(|_| panic!("Cannot connect to {} - handshake4 failed", addr));
40 if buf[0] != should_be_encrypted_num {
41 panic!("Server {} has different SecurityConfig", addr);
42 }
43 let mut nonce = [0u8; 24];
44 nonce.copy_from_slice(&buf[1..]);
45
46 let mut chacha = ChaCha::new(should_be_encrypted, password, &nonce);
48 let mut buf = [0u8; 14];
49 buf[..].copy_from_slice(b"ping_fds321sfr");
50 chacha.xor(&mut buf);
51 conn.write_all(&buf)
52 .unwrap_or_else(|_| panic!("Cannot connect to {} - handshake5 failed", addr));
53
54 let mut buf = [0u8; 1];
56 conn.read_exact(&mut buf).unwrap_or_else(|_| {
57 panic!("Server {} uses different password? Cannot connect to {} - handshake6 failed", addr, addr)
58 });
59
60 (conn, addr, chacha)
61 })
62 .collect::<Vec<_>>();
63 Connector { conns }
64 }
65 pub fn write(&mut self, data: [u8; 16]) {
66 for (conn, addr, chacha) in &mut self.conns {
67 let mut conn = conn;
68 let mut data = data;
69 {
70 let (ldata, rdata) = &mut data.split_at_mut(8);
71 rdata.copy_from_slice(ldata);
72 }
73 chacha.xor(&mut data[..8]);
74 chacha.xor(&mut data[8..]);
75 conn.write_all(&data)
76 .unwrap_or_else(|_| panic!("Connection to server {} lost", addr));
77 }
78 }
79}