chore: lintathon
This commit is contained in:
parent
d6470c2827
commit
3d381e017f
5 changed files with 70 additions and 96 deletions
52
Cargo.lock
generated
52
Cargo.lock
generated
|
@ -556,7 +556,7 @@ dependencies = [
|
||||||
"parking_lot",
|
"parking_lot",
|
||||||
"quinn",
|
"quinn",
|
||||||
"rand",
|
"rand",
|
||||||
"rustls 0.22.2",
|
"rustls",
|
||||||
"rustls-pemfile",
|
"rustls-pemfile",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
@ -575,7 +575,7 @@ dependencies = [
|
||||||
"quinn-proto",
|
"quinn-proto",
|
||||||
"quinn-udp",
|
"quinn-udp",
|
||||||
"rustc-hash",
|
"rustc-hash",
|
||||||
"rustls 0.21.10",
|
"rustls",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tracing",
|
"tracing",
|
||||||
|
@ -591,7 +591,7 @@ dependencies = [
|
||||||
"rand",
|
"rand",
|
||||||
"ring 0.16.20",
|
"ring 0.16.20",
|
||||||
"rustc-hash",
|
"rustc-hash",
|
||||||
"rustls 0.21.10",
|
"rustls",
|
||||||
"rustls-native-certs",
|
"rustls-native-certs",
|
||||||
"slab",
|
"slab",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
|
@ -748,24 +748,11 @@ name = "rustls"
|
||||||
version = "0.21.10"
|
version = "0.21.10"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba"
|
checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba"
|
||||||
dependencies = [
|
|
||||||
"ring 0.17.7",
|
|
||||||
"rustls-webpki 0.101.7",
|
|
||||||
"sct",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rustls"
|
|
||||||
version = "0.22.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e87c9956bd9807afa1f77e0f7594af32566e830e088a5576d27c5b6f30f49d41"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"ring 0.17.7",
|
"ring 0.17.7",
|
||||||
"rustls-pki-types",
|
"rustls-webpki",
|
||||||
"rustls-webpki 0.102.2",
|
"sct",
|
||||||
"subtle",
|
|
||||||
"zeroize",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -789,12 +776,6 @@ dependencies = [
|
||||||
"base64",
|
"base64",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rustls-pki-types"
|
|
||||||
version = "1.2.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "0a716eb65e3158e90e17cd93d855216e27bde02745ab842f2cab4a39dba1bacf"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustls-webpki"
|
name = "rustls-webpki"
|
||||||
version = "0.101.7"
|
version = "0.101.7"
|
||||||
|
@ -805,17 +786,6 @@ dependencies = [
|
||||||
"untrusted 0.9.0",
|
"untrusted 0.9.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rustls-webpki"
|
|
||||||
version = "0.102.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "faaa0a62740bedb9b2ef5afa303da42764c012f743917351dc9a237ea1663610"
|
|
||||||
dependencies = [
|
|
||||||
"ring 0.17.7",
|
|
||||||
"rustls-pki-types",
|
|
||||||
"untrusted 0.9.0",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustversion"
|
name = "rustversion"
|
||||||
version = "1.0.14"
|
version = "1.0.14"
|
||||||
|
@ -966,12 +936,6 @@ version = "0.9.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
|
checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "subtle"
|
|
||||||
version = "2.5.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "2.0.48"
|
version = "2.0.48"
|
||||||
|
@ -1401,9 +1365,3 @@ name = "windows_x86_64_msvc"
|
||||||
version = "0.52.0"
|
version = "0.52.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04"
|
checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "zeroize"
|
|
||||||
version = "1.7.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d"
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ log = "0.4.19"
|
||||||
parking_lot = "0.12.1"
|
parking_lot = "0.12.1"
|
||||||
quinn = "0.10.1"
|
quinn = "0.10.1"
|
||||||
rand = "0.8.5"
|
rand = "0.8.5"
|
||||||
rustls = "*"
|
rustls = "0.21.9"
|
||||||
rustls-pemfile = "1.0.2"
|
rustls-pemfile = "1.0.2"
|
||||||
serde = { version = "1.0.164", features = ["derive"] }
|
serde = { version = "1.0.164", features = ["derive"] }
|
||||||
serde_json = "1.0.97"
|
serde_json = "1.0.97"
|
||||||
|
|
68
src/main.rs
68
src/main.rs
|
@ -1,12 +1,16 @@
|
||||||
use std::{net::SocketAddr, sync::Arc, time::Duration, convert::Infallible};
|
#![warn(clippy::pedantic)]
|
||||||
|
#![allow(clippy::cast_possible_truncation)]
|
||||||
|
#![allow(clippy::cast_possible_wrap)]
|
||||||
|
|
||||||
use anyhow::{Context, anyhow};
|
use std::{convert::Infallible, net::SocketAddr, sync::Arc, time::Duration};
|
||||||
|
|
||||||
|
use anyhow::{anyhow, Context};
|
||||||
use axum::{
|
use axum::{
|
||||||
http::StatusCode,
|
http::StatusCode,
|
||||||
routing::{get, post},
|
routing::{get, post},
|
||||||
};
|
};
|
||||||
use log::{error, info};
|
use log::{error, info};
|
||||||
use netty::{Handshake, NettyReadError};
|
use netty::{Handshake, ReadError};
|
||||||
use quinn::{Connecting, ConnectionError, Endpoint, ServerConfig, TransportConfig};
|
use quinn::{Connecting, ConnectionError, Endpoint, ServerConfig, TransportConfig};
|
||||||
use routing::RoutingTable;
|
use routing::RoutingTable;
|
||||||
use rustls::{Certificate, PrivateKey};
|
use rustls::{Certificate, PrivateKey};
|
||||||
|
@ -16,7 +20,7 @@ use tokio::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
netty::{WriteExtNetty, ReadExtNetty},
|
netty::{ReadExt, WriteExt},
|
||||||
proto::{ClientboundControlMessage, ServerboundControlMessage},
|
proto::{ClientboundControlMessage, ServerboundControlMessage},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -32,9 +36,11 @@ fn any_private_keys(rd: &mut dyn std::io::BufRead) -> Result<Vec<Vec<u8>>, std::
|
||||||
loop {
|
loop {
|
||||||
match rustls_pemfile::read_one(rd)? {
|
match rustls_pemfile::read_one(rd)? {
|
||||||
None => return Ok(keys),
|
None => return Ok(keys),
|
||||||
Some(rustls_pemfile::Item::ECKey(key)) => keys.push(key),
|
Some(
|
||||||
Some(rustls_pemfile::Item::PKCS8Key(key)) => keys.push(key),
|
rustls_pemfile::Item::RSAKey(key)
|
||||||
Some(rustls_pemfile::Item::RSAKey(key)) => keys.push(key),
|
| rustls_pemfile::Item::PKCS8Key(key)
|
||||||
|
| rustls_pemfile::Item::ECKey(key),
|
||||||
|
) => keys.push(key),
|
||||||
_ => {}
|
_ => {}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -117,7 +123,7 @@ async fn try_handle_quic(
|
||||||
if let Ok(parsed) = serde_json::from_slice(&buf) {
|
if let Ok(parsed) = serde_json::from_slice(&buf) {
|
||||||
match parsed {
|
match parsed {
|
||||||
ServerboundControlMessage::RequestDomainAssignment => {
|
ServerboundControlMessage::RequestDomainAssignment => {
|
||||||
let handle = routing_table.register().await;
|
let handle = routing_table.register();
|
||||||
info!(
|
info!(
|
||||||
"Domain assigned to {}: {}",
|
"Domain assigned to {}: {}",
|
||||||
connection.remote_address(),
|
connection.remote_address(),
|
||||||
|
@ -132,19 +138,19 @@ async fn try_handle_quic(
|
||||||
break handle;
|
break handle;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
let response = serde_json::to_vec(&ClientboundControlMessage::UnknownMessage)?;
|
|
||||||
send_control.write_all(&[response.len() as u8]).await?;
|
|
||||||
send_control.write_all(&response).await?;
|
|
||||||
}
|
}
|
||||||
|
let response = serde_json::to_vec(&ClientboundControlMessage::UnknownMessage)?;
|
||||||
|
send_control.write_all(&[response.len() as u8]).await?;
|
||||||
|
send_control.write_all(&response).await?;
|
||||||
};
|
};
|
||||||
|
|
||||||
tokio::select! {
|
tokio::select! {
|
||||||
e = connection.closed() => {
|
e = connection.closed() => {
|
||||||
match e {
|
match e {
|
||||||
ConnectionError::ConnectionClosed(_) => Ok(()),
|
ConnectionError::ConnectionClosed(_)
|
||||||
ConnectionError::ApplicationClosed(_) => Ok(()),
|
| ConnectionError::ApplicationClosed(_)
|
||||||
ConnectionError::LocallyClosed => Ok(()),
|
| ConnectionError::LocallyClosed => Ok(()),
|
||||||
e => Err(e.into())
|
e => Err(e.into()),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
r = async {
|
r = async {
|
||||||
|
@ -208,7 +214,7 @@ async fn listen_control(
|
||||||
endpoint.set_server_config(Some(config));
|
endpoint.set_server_config(Some(config));
|
||||||
(StatusCode::OK, "Success".to_string())
|
(StatusCode::OK, "Success".to_string())
|
||||||
}
|
}
|
||||||
Err(e) => (StatusCode::INTERNAL_SERVER_ERROR, format!("{}", e)),
|
Err(e) => (StatusCode::INTERNAL_SERVER_ERROR, format!("{e}")),
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
@ -239,20 +245,18 @@ async fn try_handle_minecraft(
|
||||||
let peer = connection.peer_addr()?;
|
let peer = connection.peer_addr()?;
|
||||||
info!("Minecraft client connected from: {}", peer);
|
info!("Minecraft client connected from: {}", peer);
|
||||||
let handshake = netty::read_packet(&mut connection).await;
|
let handshake = netty::read_packet(&mut connection).await;
|
||||||
if let Err(NettyReadError::LegacyServerListPing) = handshake {
|
if let Err(ReadError::LegacyServerListPing) = handshake {
|
||||||
connection
|
connection
|
||||||
.write_all(include_bytes!("legacy_serverlistping_response.bin"))
|
.write_all(include_bytes!("legacy_serverlistping_response.bin"))
|
||||||
.await?;
|
.await?;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
let handshake = Handshake::new(&handshake?)?;
|
let handshake = Handshake::new(&handshake?)?;
|
||||||
let address = match handshake.normalized_address() {
|
let Some(address) = handshake.normalized_address() else {
|
||||||
Some(addr) => addr,
|
return politely_disconnect(connection, handshake).await;
|
||||||
None => return politely_disconnect(connection, handshake).await,
|
|
||||||
};
|
};
|
||||||
let (mut send_host, mut recv_host) = match routing_table.route(&address).await {
|
let Some((mut send_host, mut recv_host)) = routing_table.route(&address).await else {
|
||||||
Some(pair) => pair,
|
return politely_disconnect(connection, handshake).await;
|
||||||
None => return politely_disconnect(connection, handshake).await,
|
|
||||||
};
|
};
|
||||||
handshake.send(&mut send_host).await?;
|
handshake.send(&mut send_host).await?;
|
||||||
let (mut recv_client, mut send_client) = connection.split();
|
let (mut recv_client, mut send_client) = connection.split();
|
||||||
|
@ -277,7 +281,10 @@ async fn politely_disconnect(
|
||||||
let mut packet = packet.as_slice();
|
let mut packet = packet.as_slice();
|
||||||
let id = packet.read_varint()?;
|
let id = packet.read_varint()?;
|
||||||
if id != 0 {
|
if id != 0 {
|
||||||
return Err(anyhow!("Packet isn't a Status Request(0x00), but {:#04x}", id));
|
return Err(anyhow!(
|
||||||
|
"Packet isn't a Status Request(0x00), but {:#04x}",
|
||||||
|
id
|
||||||
|
));
|
||||||
}
|
}
|
||||||
let mut buf = vec![];
|
let mut buf = vec![];
|
||||||
buf.write_varint(0).await?;
|
buf.write_varint(0).await?;
|
||||||
|
@ -289,7 +296,10 @@ async fn politely_disconnect(
|
||||||
let mut packet = packet.as_slice();
|
let mut packet = packet.as_slice();
|
||||||
let id = packet.read_varint()?;
|
let id = packet.read_varint()?;
|
||||||
if id != 1 {
|
if id != 1 {
|
||||||
return Err(anyhow!("Packet isn't a Ping Request(0x01), but {:#04x}", id));
|
return Err(anyhow!(
|
||||||
|
"Packet isn't a Ping Request(0x01), but {:#04x}",
|
||||||
|
id
|
||||||
|
));
|
||||||
}
|
}
|
||||||
let payload = packet.read_long()?;
|
let payload = packet.read_long()?;
|
||||||
let mut buf = Vec::with_capacity(1 + 8);
|
let mut buf = Vec::with_capacity(1 + 8);
|
||||||
|
@ -326,10 +336,12 @@ async fn listen_minecraft(routing_table: &'static RoutingTable) -> anyhow::Resul
|
||||||
.await?;
|
.await?;
|
||||||
loop {
|
loop {
|
||||||
match server.accept().await {
|
match server.accept().await {
|
||||||
Ok((connection, _)) => { tokio::spawn(handle_minecraft(connection, routing_table)); },
|
Ok((connection, _)) => {
|
||||||
|
tokio::spawn(handle_minecraft(connection, routing_table));
|
||||||
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!("Error accepting minecraft connection: {}", e);
|
error!("Error accepting minecraft connection: {}", e);
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
38
src/netty.rs
38
src/netty.rs
|
@ -1,3 +1,5 @@
|
||||||
|
#![allow(clippy::cast_sign_loss)]
|
||||||
|
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
|
|
||||||
use tokio::io::{AsyncReadExt, AsyncWriteExt};
|
use tokio::io::{AsyncReadExt, AsyncWriteExt};
|
||||||
|
@ -7,56 +9,56 @@ use log::error;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
#[derive(Error, Debug)]
|
#[derive(Error, Debug)]
|
||||||
pub enum NettyReadError {
|
pub enum ReadError {
|
||||||
#[error("{0}")]
|
#[error("{0}")]
|
||||||
IoError(std::io::Error),
|
IoError(std::io::Error),
|
||||||
#[error("Was not a netty packet, but a Legacy ServerListPing")]
|
#[error("Was not a netty packet, but a Legacy ServerListPing")]
|
||||||
LegacyServerListPing,
|
LegacyServerListPing,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<std::io::Error> for NettyReadError {
|
impl From<std::io::Error> for ReadError {
|
||||||
fn from(value: std::io::Error) -> Self {
|
fn from(value: std::io::Error) -> Self {
|
||||||
Self::IoError(value)
|
Self::IoError(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<std::io::ErrorKind> for NettyReadError {
|
impl From<std::io::ErrorKind> for ReadError {
|
||||||
fn from(value: std::io::ErrorKind) -> Self {
|
fn from(value: std::io::ErrorKind) -> Self {
|
||||||
Self::IoError(value.into())
|
Self::IoError(value.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait ReadExtNetty: Read {
|
pub trait ReadExt: Read {
|
||||||
fn read_u8(&mut self) -> Result<u8, NettyReadError> {
|
fn read_u8(&mut self) -> Result<u8, ReadError> {
|
||||||
let mut buf = [0u8];
|
let mut buf = [0u8];
|
||||||
self.read_exact(&mut buf)?;
|
self.read_exact(&mut buf)?;
|
||||||
Ok(buf[0])
|
Ok(buf[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_u16(&mut self) -> Result<u16, NettyReadError> {
|
fn read_u16(&mut self) -> Result<u16, ReadError> {
|
||||||
let mut buf = [0u8; 2];
|
let mut buf = [0u8; 2];
|
||||||
self.read_exact(&mut buf)?;
|
self.read_exact(&mut buf)?;
|
||||||
Ok(u16::from_be_bytes(buf))
|
Ok(u16::from_be_bytes(buf))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_long(&mut self) -> Result<u64, NettyReadError> {
|
fn read_long(&mut self) -> Result<u64, ReadError> {
|
||||||
let mut buf = [0u8; 8];
|
let mut buf = [0u8; 8];
|
||||||
self.read_exact(&mut buf)?;
|
self.read_exact(&mut buf)?;
|
||||||
Ok(u64::from_be_bytes(buf))
|
Ok(u64::from_be_bytes(buf))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_string(&mut self) -> Result<String, NettyReadError> {
|
fn read_string(&mut self) -> Result<String, ReadError> {
|
||||||
let len = self.read_varint()?;
|
let len = self.read_varint()?;
|
||||||
let mut buf = vec![0u8; len as usize];
|
let mut buf = vec![0u8; len as usize];
|
||||||
self.read_exact(&mut buf)?;
|
self.read_exact(&mut buf)?;
|
||||||
String::from_utf8(buf).map_err(|_| std::io::ErrorKind::InvalidData.into())
|
String::from_utf8(buf).map_err(|_| std::io::ErrorKind::InvalidData.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_varint(&mut self) -> Result<i32, NettyReadError> {
|
fn read_varint(&mut self) -> Result<i32, ReadError> {
|
||||||
let mut res = 0i32;
|
let mut res = 0i32;
|
||||||
for i in 0..5 {
|
for i in 0..5 {
|
||||||
let part = self.read_u8()?;
|
let part = self.read_u8()?;
|
||||||
res |= (part as i32 & 0x7F) << (7 * i);
|
res |= (i32::from(part) & 0x7F) << (7 * i);
|
||||||
if part & 0x80 == 0 {
|
if part & 0x80 == 0 {
|
||||||
return Ok(res);
|
return Ok(res);
|
||||||
}
|
}
|
||||||
|
@ -84,7 +86,7 @@ pub trait ReadExtNetty: Read {
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn read_packet(mut reader: impl AsyncReadExt + Unpin) -> Result<Vec<u8>, NettyReadError> {
|
pub async fn read_packet(mut reader: impl AsyncReadExt + Unpin) -> Result<Vec<u8>, ReadError> {
|
||||||
let len = read_varint(&mut reader).await?;
|
let len = read_varint(&mut reader).await?;
|
||||||
let mut buf = vec![0u8; len as usize];
|
let mut buf = vec![0u8; len as usize];
|
||||||
if len == 254 {
|
if len == 254 {
|
||||||
|
@ -92,7 +94,7 @@ pub async fn read_packet(mut reader: impl AsyncReadExt + Unpin) -> Result<Vec<u8
|
||||||
reader.read_exact(&mut temp).await?;
|
reader.read_exact(&mut temp).await?;
|
||||||
if temp[0] == 0xFA {
|
if temp[0] == 0xFA {
|
||||||
// FE 01 FA: Legacy ServerListPing
|
// FE 01 FA: Legacy ServerListPing
|
||||||
return Err(NettyReadError::LegacyServerListPing);
|
return Err(ReadError::LegacyServerListPing);
|
||||||
}
|
}
|
||||||
buf[0] = temp[0];
|
buf[0] = temp[0];
|
||||||
reader.read_exact(&mut buf[1..]).await?;
|
reader.read_exact(&mut buf[1..]).await?;
|
||||||
|
@ -102,11 +104,11 @@ pub async fn read_packet(mut reader: impl AsyncReadExt + Unpin) -> Result<Vec<u8
|
||||||
Ok(buf)
|
Ok(buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn read_varint(mut reader: impl AsyncReadExt + Unpin) -> Result<i32, NettyReadError> {
|
async fn read_varint(mut reader: impl AsyncReadExt + Unpin) -> Result<i32, ReadError> {
|
||||||
let mut res = 0i32;
|
let mut res = 0i32;
|
||||||
for i in 0..5 {
|
for i in 0..5 {
|
||||||
let part = reader.read_u8().await?;
|
let part = reader.read_u8().await?;
|
||||||
res |= (part as i32 & 0x7F) << (7 * i);
|
res |= (i32::from(part) & 0x7F) << (7 * i);
|
||||||
if part & 0x80 == 0 {
|
if part & 0x80 == 0 {
|
||||||
return Ok(res);
|
return Ok(res);
|
||||||
}
|
}
|
||||||
|
@ -115,10 +117,10 @@ async fn read_varint(mut reader: impl AsyncReadExt + Unpin) -> Result<i32, Netty
|
||||||
Err(std::io::ErrorKind::InvalidData.into())
|
Err(std::io::ErrorKind::InvalidData.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Read> ReadExtNetty for T {}
|
impl<T: Read> ReadExt for T {}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
pub trait WriteExtNetty: AsyncWriteExt + Unpin {
|
pub trait WriteExt: AsyncWriteExt + Unpin {
|
||||||
async fn write_varint(&mut self, mut val: i32) -> std::io::Result<()> {
|
async fn write_varint(&mut self, mut val: i32) -> std::io::Result<()> {
|
||||||
for _ in 0..5 {
|
for _ in 0..5 {
|
||||||
if val & !0x7F == 0 {
|
if val & !0x7F == 0 {
|
||||||
|
@ -161,7 +163,7 @@ impl Handshake {
|
||||||
} else {
|
} else {
|
||||||
let protocol_version = packet.read_varint()?;
|
let protocol_version = packet.read_varint()?;
|
||||||
let server_address = packet.read_string()?;
|
let server_address = packet.read_string()?;
|
||||||
let server_port = ReadExtNetty::read_u16(&mut packet)?;
|
let server_port = ReadExt::read_u16(&mut packet)?;
|
||||||
let next_state = match packet.read_varint()? {
|
let next_state = match packet.read_varint()? {
|
||||||
1 => HandshakeType::Status,
|
1 => HandshakeType::Status,
|
||||||
2 => HandshakeType::Login,
|
2 => HandshakeType::Login,
|
||||||
|
@ -207,4 +209,4 @@ impl Handshake {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: AsyncWriteExt + Unpin> WriteExtNetty for T {}
|
impl<T: AsyncWriteExt + Unpin> WriteExt for T {}
|
||||||
|
|
|
@ -17,6 +17,7 @@ pub enum RouterRequest {
|
||||||
type RouterCallback = oneshot::Sender<(SendStream, RecvStream)>;
|
type RouterCallback = oneshot::Sender<(SendStream, RecvStream)>;
|
||||||
type RouteRequestReceiver = mpsc::UnboundedSender<RouterRequest>;
|
type RouteRequestReceiver = mpsc::UnboundedSender<RouterRequest>;
|
||||||
|
|
||||||
|
#[allow(clippy::module_name_repetitions)]
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct RoutingTable {
|
pub struct RoutingTable {
|
||||||
table: RwLock<HashMap<String, RouteRequestReceiver>>,
|
table: RwLock<HashMap<String, RouteRequestReceiver>>,
|
||||||
|
@ -26,7 +27,7 @@ pub struct RoutingTable {
|
||||||
impl RoutingTable {
|
impl RoutingTable {
|
||||||
pub fn new(base_domain: String) -> Self {
|
pub fn new(base_domain: String) -> Self {
|
||||||
RoutingTable {
|
RoutingTable {
|
||||||
table: Default::default(),
|
table: RwLock::default(),
|
||||||
base_domain,
|
base_domain,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -53,7 +54,7 @@ impl RoutingTable {
|
||||||
recv.await.ok()
|
recv.await.ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn register(&self) -> RoutingHandle {
|
pub fn register(&self) -> RoutingHandle {
|
||||||
let mut lock = self.table.write();
|
let mut lock = self.table.write();
|
||||||
let mut domain = format!(
|
let mut domain = format!(
|
||||||
"{}-{}.{}",
|
"{}-{}.{}",
|
||||||
|
@ -93,6 +94,7 @@ impl RoutingTable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::module_name_repetitions)]
|
||||||
pub struct RoutingHandle<'a> {
|
pub struct RoutingHandle<'a> {
|
||||||
recv: mpsc::UnboundedReceiver<RouterRequest>,
|
recv: mpsc::UnboundedReceiver<RouterRequest>,
|
||||||
domain: String,
|
domain: String,
|
||||||
|
|
Loading…
Reference in a new issue