Compare commits
18 Commits
feature/te
...
master
Author | SHA1 | Date | |
---|---|---|---|
0be47b8b88 | |||
8b1b64bd87 | |||
bfb550e5a6 | |||
276af0ba97 | |||
d61bd044a4 | |||
0faf0c1773 | |||
06816a16ed | |||
930a1a3692 | |||
84b39aa2a7 | |||
e0a9fe3678 | |||
6530d7b64a | |||
8991a7fbf0 | |||
d992981f22 | |||
ca43b2d75c | |||
dbdfab1fd6 | |||
bb6c062be4 | |||
038faae0e4 | |||
ffab5ed4a5 |
301
Cargo.lock
generated
301
Cargo.lock
generated
@ -3,24 +3,307 @@
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "linked-hash-map"
|
||||
version = "0.5.6"
|
||||
name = "atty"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
|
||||
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "colored"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b3616f750b84d8f0de8a58bda93e08e2a81ad3f523089b05f1dffecab48c6cbd"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"lazy_static",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.12.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.1.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "1.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc"
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.144"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "minecraft_proxy"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"linked-hash-map",
|
||||
"yaml-rust",
|
||||
"log",
|
||||
"serde",
|
||||
"serde_yaml",
|
||||
"simple_logger",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "yaml-rust"
|
||||
version = "0.4.5"
|
||||
name = "num_threads"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85"
|
||||
checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44"
|
||||
dependencies = [
|
||||
"linked-hash-map",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.47"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.147"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d193d69bae983fc11a79df82342761dfbf28a99fc8d203dca4c3c1b590948965"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.147"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4f1d362ca8fc9c3e3a7484440752472d68a6caa98f1ab81d99b5dfe517cec852"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_yaml"
|
||||
version = "0.9.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d232d893b10de3eb7258ff01974d6ee20663d8e833263c99409d4b13a0209da"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
"unsafe-libyaml",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "simple_logger"
|
||||
version = "4.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e78beb34673091ccf96a8816fce8bfd30d1292c7621ca2bcb5f2ba0fae4f558d"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"colored",
|
||||
"log",
|
||||
"time",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.103"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a864042229133ada95abf3b54fdc62ef5ccabe9515b64717bcb9a1919e59445d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.3.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f3403384eaacbca9923fa06940178ac13e4edb725486d70e8e15881d0c836cc"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"libc",
|
||||
"num_threads",
|
||||
"serde",
|
||||
"time-core",
|
||||
"time-macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time-core"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb"
|
||||
|
||||
[[package]]
|
||||
name = "time-macros"
|
||||
version = "0.2.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "372950940a5f07bf38dbe211d7283c9e6d7327df53794992d293e534c733d09b"
|
||||
dependencies = [
|
||||
"time-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3"
|
||||
|
||||
[[package]]
|
||||
name = "unsafe-libyaml"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c1e5fa573d8ac5f1a856f8d7be41d390ee973daf97c806b2c1a465e4e1406e68"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.42.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_gnullvm",
|
||||
"windows_x86_64_msvc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
|
||||
|
@ -4,5 +4,10 @@ version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
yaml-rust = "*"
|
||||
linked-hash-map = "*"
|
||||
serde = { version = "*", features = ["derive"] }
|
||||
serde_yaml = "*"
|
||||
log = "*"
|
||||
simple_logger = "*"
|
||||
|
||||
[profile.release]
|
||||
lto = true
|
11
Dockerfile
Normal file
11
Dockerfile
Normal file
@ -0,0 +1,11 @@
|
||||
FROM alpine:latest
|
||||
EXPOSE 25565 25564
|
||||
RUN mkdir /opt/mrproxy
|
||||
RUN mkdir /etc/mrproxy
|
||||
COPY Cargo.toml /opt/mrproxy
|
||||
COPY src /opt/mrproxy/src
|
||||
COPY config/* /etc/mrproxy
|
||||
WORKDIR /opt/mrproxy
|
||||
RUN apk add cargo
|
||||
RUN cargo build --release
|
||||
CMD /opt/mrproxy/target/release/minecraft_proxy
|
8
config/mrprox.conf
Normal file
8
config/mrprox.conf
Normal file
@ -0,0 +1,8 @@
|
||||
ip: '0.0.0.0'
|
||||
port: '25565'
|
||||
conf:
|
||||
#Can be TCP or UNIX
|
||||
sock_type: 'TCP'
|
||||
#path: '/home/roche/portmrproxy'
|
||||
port: '25564'
|
||||
ip: '0.0.0.0'
|
@ -1,14 +1,14 @@
|
||||
use std::net::TcpStream;
|
||||
use std::io::prelude::*;
|
||||
use std::thread;
|
||||
use std::sync::{Arc, Mutex, RwLock};
|
||||
use std::sync::{Arc, RwLock};
|
||||
|
||||
use crate::protocol;
|
||||
pub mod guard;
|
||||
|
||||
pub struct Client<'a>{
|
||||
client: Arc<Mutex<TcpStream>>,
|
||||
server:Arc<Mutex<TcpStream>>,
|
||||
client: TcpStream,
|
||||
server:TcpStream,
|
||||
hs: protocol::HandShake<'a>,
|
||||
run : Arc<RwLock<bool>>,
|
||||
}
|
||||
@ -16,31 +16,26 @@ pub struct Client<'a>{
|
||||
impl<'a> Client<'a> {
|
||||
pub fn new(client: TcpStream, server: TcpStream, handshake: protocol::HandShake) -> Client{
|
||||
Client {
|
||||
client: Arc::new(Mutex::new(client)),
|
||||
server: Arc::new(Mutex::new(server)),
|
||||
client: client,
|
||||
server: server,
|
||||
hs: handshake,
|
||||
run: Arc::new(RwLock::new(true)),
|
||||
//threads: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_string(&self){
|
||||
println!("len_pack {}", self.hs.get_host_name());
|
||||
}
|
||||
|
||||
fn join_conexions_mutex(c1: Arc<Mutex<TcpStream>>,
|
||||
c2: Arc<Mutex<TcpStream>>,
|
||||
fn join_conexions(mut origin: TcpStream,
|
||||
mut dest: TcpStream,
|
||||
run: Arc<RwLock<bool>>){
|
||||
let mut buf: [u8; 100000] = [0; 100000];
|
||||
let mut client = c1.lock().unwrap().try_clone().unwrap();
|
||||
let mut buf: [u8; 200] = [0; 200];
|
||||
while *run.read().unwrap() {
|
||||
let res=client.read(&mut buf);
|
||||
let res=origin.read(&mut buf);
|
||||
match res {
|
||||
Ok(leng) => {
|
||||
if leng == 0 {
|
||||
*run.write().unwrap()=false;
|
||||
}
|
||||
match c2.lock().unwrap().write(&buf [.. leng]) {
|
||||
match dest.write(&buf [.. leng]) {
|
||||
Ok(_l) => {},
|
||||
Err(_e) => *run.write().unwrap()=false,
|
||||
}
|
||||
@ -54,20 +49,20 @@ impl<'a> Client<'a> {
|
||||
|
||||
pub fn start_proxy(&self) -> (thread::JoinHandle<()>, thread::JoinHandle<()>) {
|
||||
|
||||
let c1 = self.client.clone();
|
||||
let s1 = self.server.clone();
|
||||
let c1 = self.client.try_clone().unwrap();
|
||||
let s1 = self.server.try_clone().unwrap();
|
||||
let r1 = self.run.clone();
|
||||
let handler1 = thread::spawn( || {
|
||||
Self::join_conexions_mutex(s1,
|
||||
Self::join_conexions(s1,
|
||||
c1,
|
||||
r1)}
|
||||
);
|
||||
|
||||
let c2 = self.client.clone();
|
||||
let s2 = self.server.clone();
|
||||
let c2 = self.client.try_clone().unwrap();
|
||||
let s2 = self.server.try_clone().unwrap();
|
||||
let r2 = self.run.clone();
|
||||
let handler2 = thread::spawn( || {
|
||||
Self::join_conexions_mutex(c2,
|
||||
Self::join_conexions(c2,
|
||||
s2,
|
||||
r2)}
|
||||
);
|
||||
|
199
src/conf/mod.rs
199
src/conf/mod.rs
@ -1,60 +1,197 @@
|
||||
use yaml_rust::yaml;
|
||||
use serde::{Serialize, Deserialize};
|
||||
use std::fs::File;
|
||||
use std::str::FromStr;
|
||||
use std::io::prelude::*;
|
||||
use std::collections::HashMap;
|
||||
use log::{error, warn};
|
||||
|
||||
static FILE: &str = "mrprox.conf";
|
||||
#[cfg(not(debug_assertions))]
|
||||
macro_rules! PATH { () => { "/etc/mrproxy/" } }
|
||||
#[cfg(not(debug_assertions))]
|
||||
static FILE_CONF: &str = concat!(PATH!(),"mrprox.conf");
|
||||
#[cfg(not(debug_assertions))]
|
||||
static FILE_SERVERS: &str = concat!(PATH!(),"mrprox_servers.conf");
|
||||
|
||||
pub struct Servers{
|
||||
l_servers : HashMap<String, String>,
|
||||
#[cfg(debug_assertions)]
|
||||
static FILE_CONF: &str = "mrprox.conf";
|
||||
#[cfg(debug_assertions)]
|
||||
static FILE_SERVERS: &str = "mrprox_servers.conf";
|
||||
|
||||
const DEF_PORT: u16 = 25565;
|
||||
|
||||
const TCP_TYPE: &str = "TCP";
|
||||
const UNIX_TYPE: &str = "UNIX";
|
||||
|
||||
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
|
||||
pub struct ConfFile{
|
||||
ip: String,
|
||||
port: String,
|
||||
conf: ConfServer,
|
||||
}
|
||||
|
||||
impl Servers {
|
||||
pub fn new() -> Self {
|
||||
Self{
|
||||
l_servers: Self::get_servers(),
|
||||
}
|
||||
}
|
||||
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
|
||||
pub struct ConfServer{
|
||||
sock_type: String,
|
||||
path: Option<String>,
|
||||
ip: Option<String>,
|
||||
port: Option<String>,
|
||||
}
|
||||
|
||||
fn get_servers() -> HashMap<String, String> {
|
||||
let mut f = File::open(&FILE).unwrap();
|
||||
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
|
||||
pub struct ServerData{
|
||||
pub domain: String,
|
||||
pub ip: String,
|
||||
}
|
||||
|
||||
pub struct Config{
|
||||
l_servers : HashMap<String, String>,
|
||||
port: String,
|
||||
ip: String,
|
||||
conf: ConfServer,
|
||||
}
|
||||
|
||||
pub fn generate_conf_from_file() -> ConfFile{
|
||||
match File::open(&FILE_CONF) {
|
||||
Ok(mut f) => {
|
||||
let mut s = String::new();
|
||||
let mut ret = HashMap::new();
|
||||
f.read_to_string(&mut s).unwrap();
|
||||
let docs = yaml::YamlLoader::load_from_str(&s).unwrap();
|
||||
let docs2 = match &docs[0]["servers"] {
|
||||
yaml::Yaml::Hash(ref h) => h,
|
||||
_ => return ret,
|
||||
};
|
||||
match serde_yaml::from_str(&s) {
|
||||
Ok(result) => result,
|
||||
Err(e) => {error!("Config file malformed: {}",e); panic!("{}", e);},
|
||||
}
|
||||
}
|
||||
Err(e) => {error!("Error open config file: {}",e); panic!("{}",e)}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn generate_slist_from_file() -> Vec<ServerData>{
|
||||
match File::open(&FILE_SERVERS){
|
||||
Ok(mut f) => {
|
||||
let mut s = String::new();
|
||||
f.read_to_string(&mut s).unwrap();
|
||||
match serde_yaml::from_str(&s) {
|
||||
Ok(result) => result,
|
||||
Err(e) => {
|
||||
warn!("IPs list file malformed; creating new one\nerror: {}",e);
|
||||
Vec::new()
|
||||
},
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
warn!("IPs list file can't be open; creating new one \nerror: {}",e);
|
||||
Vec::new()
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
for (k, v) in docs2{
|
||||
ret.insert(String::from(k.as_str().unwrap()),
|
||||
String::from(v.as_str().unwrap()));
|
||||
impl Config {
|
||||
pub fn new() -> Self {
|
||||
let yaml_conf = generate_conf_from_file();
|
||||
Self{
|
||||
l_servers: Self::get_servers(&generate_slist_from_file()),
|
||||
port: yaml_conf.port,
|
||||
ip: yaml_conf.ip,
|
||||
conf: yaml_conf.conf,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add(&mut self, server: ServerData) -> bool{
|
||||
match self.l_servers.insert(server.domain, server.ip){
|
||||
Some(_s) => true, //Modified instead of added
|
||||
None => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn del(&mut self, domain: String) -> bool {
|
||||
match self.l_servers.remove(&domain) {
|
||||
Some(_s) => true,
|
||||
None => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn flush(&self){
|
||||
let servers = Vec::from_iter(self.l_servers.iter()
|
||||
.map(|(x, y)| ServerData{domain: (*x).clone(), ip: (*y).clone()}));
|
||||
let mut file = File::create(FILE_SERVERS).unwrap();
|
||||
file.write(&serde_yaml::to_string(&servers).unwrap().into_bytes());
|
||||
file.flush();
|
||||
|
||||
}
|
||||
|
||||
fn get_servers(file: &Vec<ServerData>) -> HashMap<String, String> {
|
||||
let mut ret = HashMap::new();
|
||||
for j in file{
|
||||
ret.insert(j.domain.clone(),j.ip.clone());
|
||||
}
|
||||
ret
|
||||
}
|
||||
|
||||
fn get_host(&self, host: &String) -> Option<(&String, &String)>{
|
||||
pub fn get_host(&self, host: &String) -> Option<(&String, &String)>{
|
||||
self.l_servers.get_key_value(host)
|
||||
}
|
||||
|
||||
pub fn get_server(&self, host: &String) -> Option<(String, u16)>{
|
||||
let raw: Vec<&str>;
|
||||
let raw: Vec<&str> =
|
||||
match self.get_host(host){
|
||||
Some(h) => raw=h.1.split(":").collect(),
|
||||
Some(h) => h.1.split(":").collect(),
|
||||
None => return None,
|
||||
}
|
||||
|
||||
if raw.len() == 2 {
|
||||
};
|
||||
|
||||
match raw.len() {
|
||||
1 => Some((String::from(raw[0]),DEF_PORT)),
|
||||
2 => {
|
||||
match FromStr::from_str(raw[1]) {
|
||||
Ok(p) => return Some((String::from(raw[0]),p)),
|
||||
Err(_e) => return None,
|
||||
Ok(p) => Some((String::from(raw[0]),p)),
|
||||
Err(_e) => None,
|
||||
}
|
||||
} else {
|
||||
return None;
|
||||
},
|
||||
_=> None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_port(&self) -> &String{
|
||||
&self.port
|
||||
}
|
||||
|
||||
pub fn get_ip(&self) -> &String{
|
||||
&self.ip
|
||||
}
|
||||
|
||||
pub fn get_port_conf(&self) -> &String{
|
||||
match self.conf.sock_type.as_str() {
|
||||
TCP_TYPE => &self.conf.port.as_ref().unwrap(),
|
||||
_=> {error!("Only tcp types have port"); panic!("Only tcp types have port")},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_conf_ip(&self) -> &String{
|
||||
match self.conf.sock_type.as_str() {
|
||||
TCP_TYPE => &self.conf.ip.as_ref().unwrap(),
|
||||
_=> {error!("Only tcp types have IP"); panic!("Only tcp types have IP")},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_bindeable_ip(&self) -> String {
|
||||
build_bindeable_ip(&self.ip,&self.port)
|
||||
}
|
||||
|
||||
pub fn get_bindeable_conf(&self) -> String {
|
||||
match self.conf.sock_type.as_str() {
|
||||
TCP_TYPE => build_bindeable_ip(
|
||||
self.conf.ip.as_ref().unwrap(),
|
||||
self.conf.port.as_ref().unwrap()
|
||||
),
|
||||
UNIX_TYPE => self.conf.path.as_ref().unwrap().to_string(),
|
||||
_=> {error!("Invalid type"); panic!("Invalid type")},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_conf_type(&self) -> &String{
|
||||
&self.conf.sock_type
|
||||
}
|
||||
}
|
||||
|
||||
fn build_bindeable_ip(ip: &String, port: &String) -> String{
|
||||
format!("{}:{}",ip,port)
|
||||
}
|
||||
|
||||
|
72
src/main.rs
72
src/main.rs
@ -1,64 +1,22 @@
|
||||
use std::net::{TcpListener, TcpStream};
|
||||
use std::sync::{Arc, RwLock};
|
||||
use std::io::prelude::*;
|
||||
use crate::client::guard;
|
||||
use std::thread;
|
||||
use std::time::Duration;
|
||||
|
||||
|
||||
//use server_conf::server_conf;
|
||||
use std::sync::{Arc, RwLock};
|
||||
use log::info;
|
||||
use simple_logger::SimpleLogger;
|
||||
mod client;
|
||||
mod conf;
|
||||
mod server_conf;
|
||||
mod protocol;
|
||||
mod server_proxy;
|
||||
|
||||
fn main() {
|
||||
let listener = TcpListener::bind("0.0.0.0:25565").unwrap();
|
||||
let servers = Arc::new(RwLock::new(conf::Servers::new()));
|
||||
let guard = Arc::new(RwLock::new(guard::Guard::new()));
|
||||
for stream in listener.incoming() {
|
||||
if guard.read().unwrap().can_add(){
|
||||
match stream {
|
||||
Ok(stream) => {
|
||||
let g = guard.clone();
|
||||
let s = servers.clone();
|
||||
thread::spawn(|| read_connection(stream, s , g));
|
||||
},
|
||||
|
||||
Err(_e) => println!("{}",_e),
|
||||
}
|
||||
}
|
||||
}
|
||||
SimpleLogger::new().init().unwrap();
|
||||
info!("start server");
|
||||
let servers = Arc::new(RwLock::new(conf::Config::new()));
|
||||
let s1 = servers.clone();
|
||||
let s2 = servers.clone();
|
||||
let stop1 = thread::spawn(|| server_proxy::start(s1));
|
||||
let stop2 = thread::spawn(|| server_conf::server::start(s2));
|
||||
stop1.join();
|
||||
stop2.join();
|
||||
}
|
||||
|
||||
fn read_connection(mut stream: TcpStream,
|
||||
servers: Arc<RwLock<conf::Servers>>,
|
||||
guard: Arc<RwLock<guard::Guard>> ) {
|
||||
let mut buf: [u8; 256] = [1; 256];
|
||||
stream.set_read_timeout(Some(Duration::from_millis(5000)));
|
||||
let leng = match stream.read(&mut buf) {
|
||||
Ok(l) => l,
|
||||
Err(_e) => return,
|
||||
};
|
||||
let hs = protocol::HandShake::new(&mut buf[.. leng]);
|
||||
if hs.is_handshake() { //Filtra los ping, solo controlamos los handshakes
|
||||
conect_server(servers, hs, stream, guard);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fn conect_server(servers: Arc<RwLock<conf::Servers>>,
|
||||
mut hs: protocol::HandShake,
|
||||
stream: TcpStream,
|
||||
guard: Arc<RwLock<guard::Guard>>){
|
||||
|
||||
match servers.read().unwrap().get_server(&hs.get_host_name()) {
|
||||
Some(s) => {
|
||||
hs.replace_port(s.1);
|
||||
let mut sstream = TcpStream::connect(s.0 + ":" + &s.1.to_string()).unwrap();
|
||||
sstream.write(hs.get_raw());
|
||||
let c1 = client::Client::new(stream,sstream, hs);
|
||||
guard.write().unwrap().add_thread(c1.start_proxy());
|
||||
},
|
||||
None => println!("No server found for {}", hs.get_host_name())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,11 @@ minecraft_proxy_sources = [
|
||||
'client/guard.rs',
|
||||
'protocol/mod.rs',
|
||||
'conf/mod.rs',
|
||||
'server_conf/mod.rs',
|
||||
'server_conf/server.rs',
|
||||
'server_conf/conexion.rs',
|
||||
'server_conf/listener.rs',
|
||||
'server_proxy.rs',
|
||||
]
|
||||
|
||||
minecraft_proxy_deps = [
|
||||
|
97
src/server_conf/conexion.rs
Normal file
97
src/server_conf/conexion.rs
Normal file
@ -0,0 +1,97 @@
|
||||
use std::io::prelude::*;
|
||||
use crate::conf;
|
||||
use std::sync::{Arc, RwLock};
|
||||
use log::{error, warn};
|
||||
|
||||
const OP_ADD: u8 = 0;
|
||||
const OP_DEL: u8 = 1;
|
||||
const OP_EXIT: u8 = 2;
|
||||
|
||||
const RE_ADD: u8 = 0;
|
||||
const RE_MOD: u8 = 1;
|
||||
|
||||
const RE_OK: u8 = 0;
|
||||
const RE_KO: u8 = 1;
|
||||
|
||||
pub struct Conexion<TSocket: Read + Write> {
|
||||
conf: Arc<RwLock<conf::Config>>,
|
||||
stream: TSocket,
|
||||
buf:[u8; 256],
|
||||
exit: bool,
|
||||
}
|
||||
|
||||
impl<TSocket: Read + Write> Conexion<TSocket> {
|
||||
pub fn new(conf: Arc<RwLock<conf::Config>>, stream: TSocket) -> Self {
|
||||
Self{
|
||||
conf: conf,
|
||||
stream: stream,
|
||||
buf: [1; 256],
|
||||
exit: false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn process_reques(&mut self) {
|
||||
let mut state: [u8; 1] = [1; 1];
|
||||
while !self.exit {
|
||||
match self.stream.read_exact(&mut state){
|
||||
Ok(len) => self.check_state(state[0]),
|
||||
Err(e) => {self.exit=true; error!("{}", e);},
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fn read_domain_info(&mut self) ->
|
||||
Result<conf::ServerData, std::io::Error>{
|
||||
let mut len = self.stream.read(&mut self.buf)?;
|
||||
let end_domain = (self.buf[0] + 1) as usize;
|
||||
let start_ip = end_domain + 1 as usize;
|
||||
let end_ip = self.buf[end_domain] as usize + start_ip;
|
||||
let domain = String::from_utf8(self.buf[1 .. end_domain].to_vec()).unwrap();
|
||||
let ip = String::from_utf8(self.buf[start_ip .. end_ip].to_vec()).unwrap();
|
||||
Ok(conf::ServerData{
|
||||
domain: domain,
|
||||
ip: ip,
|
||||
})
|
||||
}
|
||||
|
||||
fn read_unique_info(&mut self) ->
|
||||
Result<String, std::io::Error>{
|
||||
self.stream.read_exact(&mut self.buf[0 .. 1])?;
|
||||
let len = self.buf[0] as usize;
|
||||
self.stream.read_exact(&mut self.buf[0 .. len])?;
|
||||
Ok(String::from_utf8(self.buf[0 .. len].to_vec()).unwrap())
|
||||
}
|
||||
|
||||
fn check_state(&mut self, state: u8) {
|
||||
match state{
|
||||
OP_ADD => {
|
||||
match self.read_domain_info() {
|
||||
Ok(sd) => {
|
||||
match self.conf.write().unwrap().add(sd) {
|
||||
true => self.stream.write(&[RE_MOD]),
|
||||
false => self.stream.write(&[RE_ADD]),
|
||||
};
|
||||
self.conf.read().unwrap().flush();
|
||||
},
|
||||
Err(e) => {self.exit=true; warn!("{}", e);},
|
||||
}
|
||||
},
|
||||
|
||||
OP_DEL => match self.read_unique_info(){
|
||||
Ok(domain) => {
|
||||
match self.conf.write().unwrap().del(domain){
|
||||
true => {
|
||||
self.stream.write(&[RE_OK]);
|
||||
},
|
||||
false => {self.stream.write(&[RE_KO]);},
|
||||
};
|
||||
self.conf.read().unwrap().flush();
|
||||
}
|
||||
Err(e) => {self.exit=true; error!("{}", e);},
|
||||
},
|
||||
OP_EXIT => self.exit=true,
|
||||
_=> warn!("no recognice option: {}", state),
|
||||
}
|
||||
}
|
||||
}
|
77
src/server_conf/listener.rs
Normal file
77
src/server_conf/listener.rs
Normal file
@ -0,0 +1,77 @@
|
||||
use std::net::TcpListener;
|
||||
use std::net::TcpStream;
|
||||
use std::os::unix::net::UnixListener;
|
||||
use std::os::unix::net::UnixStream;
|
||||
use std::io::{Error, ErrorKind};
|
||||
use log::{warn};
|
||||
|
||||
pub const TCP_LIS : u8 = 1;
|
||||
pub const UNIX_LIS : u8 = 2;
|
||||
pub const ERROR_LIS : u8 = 0;
|
||||
|
||||
pub trait RWTrait: std::io::Read + std::io::Write + Send {}
|
||||
impl RWTrait for TcpStream {}
|
||||
impl RWTrait for UnixStream {}
|
||||
|
||||
pub struct GenericListener {
|
||||
tcp_lis : Option<TcpListener>,
|
||||
unix_lis : Option<UnixListener>,
|
||||
type_lis : u8,
|
||||
}
|
||||
|
||||
impl GenericListener {
|
||||
fn new_tcp(listener: TcpListener) -> Self{
|
||||
GenericListener{
|
||||
tcp_lis: Some(listener),
|
||||
unix_lis: None,
|
||||
type_lis: TCP_LIS,
|
||||
}
|
||||
}
|
||||
|
||||
fn new_unix(listener: UnixListener) -> Self{
|
||||
GenericListener{
|
||||
tcp_lis: None,
|
||||
unix_lis: Some(listener),
|
||||
type_lis: UNIX_LIS,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn bind(address: String, type_lis: u8) -> Result<Self, String>{
|
||||
let ret = match type_lis {
|
||||
TCP_LIS => Self::new_tcp(
|
||||
match TcpListener::bind(address) {
|
||||
Ok(s) => s,
|
||||
Err(e) => return Err(e.to_string()),
|
||||
}),
|
||||
UNIX_LIS => Self::new_unix(
|
||||
match UnixListener::bind(address){
|
||||
Ok(s) => s,
|
||||
Err(e) => return Err(e.to_string()),
|
||||
}),
|
||||
_ => return Err("No valid option".to_string()),
|
||||
};
|
||||
Ok(ret)
|
||||
}
|
||||
|
||||
|
||||
|
||||
pub fn accept(&self) -> Result<Box<dyn RWTrait>,Error> {
|
||||
match self.type_lis {
|
||||
TCP_LIS => Ok(Box::new(self.tcp_lis.as_ref().unwrap().accept()?.0)),
|
||||
UNIX_LIS => Ok(Box::new(self.unix_lis.as_ref().unwrap().accept()?.0)),
|
||||
_=> Err(Error::new(ErrorKind::Other, "Unexpected type"))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
pub fn string_top_type(s: &String) -> u8 {
|
||||
match (*s).as_str(){
|
||||
"TCP" => TCP_LIS,
|
||||
"UNIX" => UNIX_LIS,
|
||||
&_ => ERROR_LIS,
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
3
src/server_conf/mod.rs
Normal file
3
src/server_conf/mod.rs
Normal file
@ -0,0 +1,3 @@
|
||||
pub mod server;
|
||||
pub mod conexion;
|
||||
pub mod listener;
|
54
src/server_conf/server.rs
Normal file
54
src/server_conf/server.rs
Normal file
@ -0,0 +1,54 @@
|
||||
use crate::conf;
|
||||
use crate::server_conf::conexion::Conexion;
|
||||
use crate::server_conf::listener::GenericListener;
|
||||
use std::thread;
|
||||
use std::sync::{Arc, RwLock};
|
||||
use log::{error,warn,info};
|
||||
|
||||
pub struct ConfSer{
|
||||
path: String,
|
||||
listener: GenericListener,
|
||||
}
|
||||
|
||||
impl ConfSer {
|
||||
fn new(path: String, conf_type: &String) -> ConfSer{
|
||||
ConfSer{
|
||||
path: path.clone(),
|
||||
listener: match GenericListener::bind(path,
|
||||
GenericListener::string_top_type(conf_type)){
|
||||
Ok(l) => l,
|
||||
Err(e) => {
|
||||
warn!("Error al levantar el servidor de configuraciones:{}",e);
|
||||
panic!("Error al levantar el servidor de configuraciones:{}",e)
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for ConfSer {
|
||||
fn drop(&mut self) {
|
||||
// There's no way to return a useful error here
|
||||
let _ = std::fs::remove_file(self.path.clone()).unwrap();
|
||||
info!("> Dropping {}", self.path);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn start(conf: Arc<RwLock<conf::Config>>){
|
||||
let ser = ConfSer::new(
|
||||
conf.read().unwrap().get_bindeable_conf(),
|
||||
conf.read().unwrap().get_conf_type(),
|
||||
);
|
||||
|
||||
loop{
|
||||
match ser.listener.accept() {
|
||||
Ok(stream) => {
|
||||
let c = conf.clone();
|
||||
thread::spawn(|| Conexion::new(c, stream).process_reques());
|
||||
}
|
||||
Err(e) => error!("{}", e)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
65
src/server_proxy.rs
Normal file
65
src/server_proxy.rs
Normal file
@ -0,0 +1,65 @@
|
||||
use std::net::{TcpListener, TcpStream};
|
||||
use std::sync::{Arc, RwLock};
|
||||
use std::io::prelude::*;
|
||||
use crate::client::guard;
|
||||
use crate::client;
|
||||
use std::thread;
|
||||
use std::time::Duration;
|
||||
use crate::protocol;
|
||||
use crate::conf;
|
||||
use log::{error, info};
|
||||
|
||||
pub fn start(servers: Arc<RwLock<conf::Config>>){
|
||||
let listener = TcpListener::bind(
|
||||
servers.read().unwrap().get_bindeable_ip()
|
||||
).unwrap();
|
||||
let guard = Arc::new(RwLock::new(guard::Guard::new()));
|
||||
for stream in listener.incoming() {
|
||||
if guard.read().unwrap().can_add(){
|
||||
match stream {
|
||||
Ok(stream) => {
|
||||
let g = guard.clone();
|
||||
let s = servers.clone();
|
||||
thread::spawn(|| read_connection(stream, s , g));
|
||||
},
|
||||
|
||||
Err(_e) => error!("{}",_e),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn read_connection(mut stream: TcpStream,
|
||||
servers: Arc<RwLock<conf::Config>>,
|
||||
guard: Arc<RwLock<guard::Guard>> ) {
|
||||
let mut buf: [u8; 256] = [1; 256];
|
||||
stream.set_read_timeout(Some(Duration::from_millis(5000)));
|
||||
let leng = match stream.read(&mut buf) {
|
||||
Ok(l) => l,
|
||||
Err(_e) => return,
|
||||
};
|
||||
let hs = protocol::HandShake::new(&mut buf[.. leng]);
|
||||
if hs.is_handshake() { //Filtra los ping, solo controlamos los handshakes
|
||||
conect_server(servers, hs, stream, guard);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fn conect_server(servers: Arc<RwLock<conf::Config>>,
|
||||
mut hs: protocol::HandShake,
|
||||
stream: TcpStream,
|
||||
guard: Arc<RwLock<guard::Guard>>){
|
||||
|
||||
match servers.read().unwrap().get_server(&hs.get_host_name()) {
|
||||
Some(s) => {
|
||||
hs.replace_port(s.1);
|
||||
let mut sstream = TcpStream::connect(s.0 + ":" + &s.1.to_string()).unwrap();
|
||||
sstream.write(hs.get_raw());
|
||||
let c1 = client::Client::new(stream,sstream, hs);
|
||||
guard.write().unwrap().add_thread(c1.start_proxy());
|
||||
},
|
||||
None => info!("No server found for {}", hs.get_host_name())
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user