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
use super::ProxyModeHandler;
use crate::{
network::{connection::Connection, packet::PacketCodec},
protocol::types::VarInt,
version::Version,
};
use async_trait::async_trait;
use tracing::{debug, error};
use std::io;
/// First attempt at a proxy before realising that Yggdrasil authentication
/// is not possible for a full online mode client -> proxy -> server
pub struct FullMode;
#[async_trait]
impl ProxyModeHandler for FullMode {
async fn handle(
&self,
client: Connection,
response: crate::server::ServerResponse,
proxy_protocol: Version,
) -> io::Result<()> {
if let Some(_addr) = response.server_addr {
let mut server = response.server_conn.unwrap();
let mut encryption_started = false;
debug!("Forwarding initial handshake packets in full mode");
for packet in response.read_packets {
server.write_packet(&packet).await?;
}
server.flush().await?;
let (mut client_read, mut client_write) = client.into_split_raw();
let (mut server_read, mut server_write) = server.into_split_raw();
client_read.set_protocol_version(proxy_protocol);
server_read.set_protocol_version(proxy_protocol);
loop {
tokio::select! {
result = client_read.read_packet() => {
match result {
Ok(packet) => {
if !encryption_started && packet.id == 0x01 { // Encryption Response
encryption_started = true;
debug!("Full mode: encryption started (client)");
}
debug!("Client -> Server: Packet ID: 0x{:02x}", packet.id);
server_write.write_packet(&packet).await?;
server_write.flush().await?;
}
Err(e) => {
error!("Client read error: {}", e);
break;
}
}
},
result = server_read.read_packet() => {
match result {
Ok(packet) => {
match packet.id {
0x01 => { // Encryption Request
encryption_started = true;
debug!("Full mode: encryption started (server)");
}
0x03 => { // Set Compression
if let Ok(threshold) = packet.decode::<VarInt>() {
if threshold.0 >= 0 {
debug!(log_type = LogType::ProxyMode.as_str(), "Enabling compression with threshold {}", threshold.0);
client_write.enable_compression(threshold.0);
client_read.enable_compression(threshold.0);
}
}
}
_ => {}
}
debug!(log_type = LogType::ProxyMode.as_str(), "Server -> Client: Packet ID: 0x{:02x}", packet.id);
client_write.write_packet(&packet).await?;
client_write.flush().await?;
}
Err(e) => {
error!(log_type = LogType::ProxyMode.as_str(), "Server read error: {}", e);
break;
}
}
}
}
}
}
Ok(())
}
}