mirror of
https://github.com/MeexReay/sRAC.git
synced 2025-05-07 13:48:03 +03:00
contexts
This commit is contained in:
parent
5152c02a0d
commit
21c9d7aa67
10
PROTOCOL.md
10
PROTOCOL.md
@ -81,9 +81,13 @@ Server sends:
|
|||||||
- nothing if user was registered successfully
|
- nothing if user was registered successfully
|
||||||
- `0x01` if the username is already taken
|
- `0x01` if the username is already taken
|
||||||
|
|
||||||
|
# RACS Protocol
|
||||||
|
|
||||||
|
Default port - 42667
|
||||||
|
|
||||||
# WRAC Protocol
|
# WRAC Protocol
|
||||||
|
|
||||||
Default port - 42666
|
Default port - 52666
|
||||||
|
|
||||||
Uses websocket for connections, and sends binary data only
|
Uses websocket for connections, and sends binary data only
|
||||||
|
|
||||||
@ -121,3 +125,7 @@ Client sends:
|
|||||||
Server sends:
|
Server sends:
|
||||||
|
|
||||||
- All new messages
|
- All new messages
|
||||||
|
|
||||||
|
# WRACS Protocol
|
||||||
|
|
||||||
|
Default port - 52667
|
545
src/main.rs
545
src/main.rs
@ -10,6 +10,11 @@ use rustls::{pki_types::{pem::PemObject, CertificateDer, PrivateKeyDer}, ServerC
|
|||||||
use tungstenite::{accept, Bytes, Message};
|
use tungstenite::{accept, Bytes, Message};
|
||||||
|
|
||||||
|
|
||||||
|
pub struct Context {
|
||||||
|
messages: RwLock<Vec<u8>>,
|
||||||
|
accounts: RwLock<Vec<Account>>
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Account {
|
pub struct Account {
|
||||||
name: String,
|
name: String,
|
||||||
@ -140,7 +145,7 @@ fn message_prefix(time_millis: i64, address: Option<String>) -> String {
|
|||||||
|
|
||||||
fn add_message(
|
fn add_message(
|
||||||
buf: &mut Vec<u8>,
|
buf: &mut Vec<u8>,
|
||||||
messages: Arc<RwLock<Vec<u8>>>,
|
context: Arc<Context>,
|
||||||
addr: Option<IpAddr>,
|
addr: Option<IpAddr>,
|
||||||
sanitize: bool,
|
sanitize: bool,
|
||||||
messages_file: Option<String>
|
messages_file: Option<String>
|
||||||
@ -175,283 +180,307 @@ fn add_message(
|
|||||||
file.flush()?;
|
file.flush()?;
|
||||||
}
|
}
|
||||||
|
|
||||||
messages.write().unwrap().append(&mut msg.clone());
|
context.messages.write().unwrap().append(&mut msg.clone());
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn accept_stream(
|
fn accept_wrac_stream(
|
||||||
args: Arc<Args>,
|
stream: impl Read + Write,
|
||||||
mut stream: impl Read + Write,
|
|
||||||
addr: SocketAddr,
|
addr: SocketAddr,
|
||||||
messages: Arc<RwLock<Vec<u8>>>,
|
context: Arc<Context>,
|
||||||
accounts: Arc<RwLock<Vec<Account>>>
|
args: Arc<Args>
|
||||||
) -> Result<(), Box<dyn Error>> {
|
) -> Result<(), Box<dyn Error>> {
|
||||||
if args.enable_wrac {
|
let mut websocket = match accept(stream) {
|
||||||
let mut websocket = match accept(stream) {
|
Ok(i) => i,
|
||||||
Ok(i) => i,
|
Err(e) => return Err(format!("accept websocket error: {}", e).into()),
|
||||||
Err(e) => return Err(format!("accept websocket error: {}", e).into()),
|
};
|
||||||
};
|
|
||||||
|
|
||||||
while let Ok(msg) = websocket.read() {
|
while let Ok(msg) = websocket.read() {
|
||||||
if let Some(data) = match msg {
|
if let Some(data) = match msg {
|
||||||
Message::Binary(o) => Some(o.to_vec()),
|
Message::Binary(o) => Some(o.to_vec()),
|
||||||
Message::Text(o) => Some(o.as_bytes().to_vec()),
|
Message::Text(o) => Some(o.as_bytes().to_vec()),
|
||||||
Message::Close(_) => return Ok(()),
|
Message::Close(_) => return Ok(()),
|
||||||
_ => None
|
_ => None
|
||||||
} {
|
} {
|
||||||
let mut data = data;
|
let mut data = data;
|
||||||
let Some(id) = data.drain(..1).next() else { return Ok(()) };
|
let Some(id) = data.drain(..1).next() else { return Ok(()) };
|
||||||
|
|
||||||
if id == 0x00 {
|
if id == 0x00 {
|
||||||
let mut messages = messages.read().unwrap().clone();
|
let mut messages = context.messages.read().unwrap().clone();
|
||||||
|
|
||||||
if data.is_empty() {
|
if data.is_empty() {
|
||||||
|
if let Some(splash) = &args.splash {
|
||||||
|
websocket.write(Message::Binary(Bytes::from((messages.len() + splash.len()).to_string().as_bytes().to_vec())))?;
|
||||||
|
} else {
|
||||||
|
websocket.write(Message::Binary(Bytes::from(messages.len().to_string().as_bytes().to_vec())))?;
|
||||||
|
}
|
||||||
|
websocket.flush()?;
|
||||||
|
} else {
|
||||||
|
let Some(id) = data.drain(..1).next() else { return Ok(()) };
|
||||||
|
|
||||||
|
if id == 0x01 {
|
||||||
if let Some(splash) = &args.splash {
|
if let Some(splash) = &args.splash {
|
||||||
websocket.write(Message::Binary(Bytes::from((messages.len() + splash.len()).to_string().as_bytes().to_vec())))?;
|
messages.append(&mut splash.clone().as_bytes().to_vec());
|
||||||
|
}
|
||||||
|
websocket.write(Message::Binary(Bytes::from(messages)))?;
|
||||||
|
websocket.flush()?;
|
||||||
|
} else if id == 0x02 {
|
||||||
|
let last_size: usize = String::from_utf8(data)?.parse()?;
|
||||||
|
if let Some(splash) = &args.splash {
|
||||||
|
websocket.write(Message::Binary(Bytes::from(messages[(last_size - splash.len())..].to_vec())))?;
|
||||||
} else {
|
} else {
|
||||||
websocket.write(Message::Binary(Bytes::from(messages.len().to_string().as_bytes().to_vec())))?;
|
websocket.write(Message::Binary(Bytes::from(messages[last_size..].to_vec())))?;
|
||||||
}
|
}
|
||||||
websocket.flush()?;
|
websocket.flush()?;
|
||||||
} else {
|
}
|
||||||
let Some(id) = data.drain(..1).next() else { return Ok(()) };
|
}
|
||||||
|
} else if id == 0x01 {
|
||||||
|
if !args.auth_only {
|
||||||
|
add_message(&mut data, context.clone(), Some(addr.ip()), args.sanitize, args.messages_file.clone())?;
|
||||||
|
}
|
||||||
|
} else if id == 0x02 {
|
||||||
|
let msg = String::from_utf8_lossy(&data).to_string();
|
||||||
|
|
||||||
|
let mut segments = msg.split("\n");
|
||||||
|
|
||||||
|
let Some(name) = segments.next() else { return Ok(()) };
|
||||||
|
let Some(password) = segments.next() else { return Ok(()) };
|
||||||
|
let Some(text) = segments.next() else { return Ok(()) };
|
||||||
|
|
||||||
|
let mut sent = false;
|
||||||
|
|
||||||
if id == 0x01 {
|
for user in context.accounts.read().unwrap().iter() {
|
||||||
if let Some(splash) = &args.splash {
|
if user.name() == name {
|
||||||
messages.append(&mut splash.clone().as_bytes().to_vec());
|
if user.check_password(password) {
|
||||||
}
|
add_message(&mut text.as_bytes().to_vec(), context.clone(), None, args.sanitize, args.messages_file.clone())?;
|
||||||
websocket.write(Message::Binary(Bytes::from(messages)))?;
|
} else {
|
||||||
websocket.flush()?;
|
websocket.write(Message::Binary(Bytes::from(vec![0x02])))?;
|
||||||
} else if id == 0x02 {
|
|
||||||
let last_size: usize = String::from_utf8(data)?.parse()?;
|
|
||||||
if let Some(splash) = &args.splash {
|
|
||||||
websocket.write(Message::Binary(Bytes::from(messages[(last_size - splash.len())..].to_vec())))?;
|
|
||||||
} else {
|
|
||||||
websocket.write(Message::Binary(Bytes::from(messages[last_size..].to_vec())))?;
|
|
||||||
}
|
|
||||||
websocket.flush()?;
|
websocket.flush()?;
|
||||||
}
|
}
|
||||||
|
sent = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
} else if id == 0x01 {
|
}
|
||||||
if !args.auth_only {
|
|
||||||
add_message(&mut data, messages.clone(), Some(addr.ip()), args.sanitize, args.messages_file.clone())?;
|
if !sent {
|
||||||
}
|
websocket.write(Message::Binary(Bytes::from(vec![0x01])))?;
|
||||||
} else if id == 0x02 {
|
websocket.flush()?;
|
||||||
let msg = String::from_utf8_lossy(&data).to_string();
|
}
|
||||||
|
} else if id == 0x03 {
|
||||||
let mut segments = msg.split("\n");
|
let msg = String::from_utf8_lossy(&data).to_string();
|
||||||
|
|
||||||
let Some(name) = segments.next() else { return Ok(()) };
|
let mut segments = msg.split("\n");
|
||||||
let Some(password) = segments.next() else { return Ok(()) };
|
|
||||||
let Some(text) = segments.next() else { return Ok(()) };
|
let Some(name) = segments.next() else { return Ok(()) };
|
||||||
|
let Some(password) = segments.next() else { return Ok(()) };
|
||||||
let mut sent = false;
|
|
||||||
|
let addr = addr.ip().to_string();
|
||||||
|
|
||||||
|
let now: i64 = Local::now().timestamp_millis();
|
||||||
|
|
||||||
for user in accounts.read().unwrap().iter() {
|
let mut continue_send = false;
|
||||||
if user.name() == name {
|
|
||||||
if user.check_password(password) {
|
for user in context.accounts.read().unwrap().iter() {
|
||||||
add_message(&mut text.as_bytes().to_vec(), messages.clone(), None, args.sanitize, args.messages_file.clone())?;
|
if user.name() == name {
|
||||||
} else {
|
|
||||||
websocket.write(Message::Binary(Bytes::from(vec![0x02])))?;
|
|
||||||
websocket.flush()?;
|
|
||||||
}
|
|
||||||
sent = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !sent {
|
|
||||||
websocket.write(Message::Binary(Bytes::from(vec![0x01])))?;
|
websocket.write(Message::Binary(Bytes::from(vec![0x01])))?;
|
||||||
websocket.flush()?;
|
websocket.flush()?;
|
||||||
|
continue_send = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
} else if id == 0x03 {
|
if user.addr() == addr && ((now - user.date()) as usize) < 1000 * args.register_timeout {
|
||||||
let msg = String::from_utf8_lossy(&data).to_string();
|
websocket.write(Message::Binary(Bytes::from(vec![0x01])))?;
|
||||||
|
websocket.flush()?;
|
||||||
let mut segments = msg.split("\n");
|
continue_send = true;
|
||||||
|
break;
|
||||||
let Some(name) = segments.next() else { return Ok(()) };
|
|
||||||
let Some(password) = segments.next() else { return Ok(()) };
|
|
||||||
|
|
||||||
let addr = addr.ip().to_string();
|
|
||||||
|
|
||||||
let now: i64 = Local::now().timestamp_millis();
|
|
||||||
|
|
||||||
let mut continue_send = false;
|
|
||||||
|
|
||||||
for user in accounts.read().unwrap().iter() {
|
|
||||||
if user.name() == name {
|
|
||||||
websocket.write(Message::Binary(Bytes::from(vec![0x01])))?;
|
|
||||||
websocket.flush()?;
|
|
||||||
continue_send = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if user.addr() == addr && ((now - user.date()) as usize) < 1000 * args.register_timeout {
|
|
||||||
websocket.write(Message::Binary(Bytes::from(vec![0x01])))?;
|
|
||||||
websocket.flush()?;
|
|
||||||
continue_send = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if continue_send {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
let account = Account::new(name.to_string(), password.to_string(), addr, now);
|
|
||||||
|
|
||||||
if let Some(accounts_file) = args.accounts_file.clone() {
|
|
||||||
let mut file = OpenOptions::new()
|
|
||||||
.write(true)
|
|
||||||
.append(true)
|
|
||||||
.create(true)
|
|
||||||
.open(accounts_file)?;
|
|
||||||
|
|
||||||
file.write_all(&account.to_bytes())?;
|
|
||||||
file.write_all(b"\n")?;
|
|
||||||
file.flush()?;
|
|
||||||
}
|
|
||||||
|
|
||||||
accounts.write().unwrap().push(account);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if continue_send {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let account = Account::new(name.to_string(), password.to_string(), addr, now);
|
||||||
|
|
||||||
|
if let Some(accounts_file) = args.accounts_file.clone() {
|
||||||
|
let mut file = OpenOptions::new()
|
||||||
|
.write(true)
|
||||||
|
.append(true)
|
||||||
|
.create(true)
|
||||||
|
.open(accounts_file)?;
|
||||||
|
|
||||||
|
file.write_all(&account.to_bytes())?;
|
||||||
|
file.write_all(b"\n")?;
|
||||||
|
file.flush()?;
|
||||||
|
}
|
||||||
|
|
||||||
|
context.accounts.write().unwrap().push(account);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
let mut buf = vec![0];
|
|
||||||
stream.read_exact(&mut buf)?;
|
|
||||||
|
|
||||||
if buf[0] == 0x00 {
|
|
||||||
let mut messages = messages.read().unwrap().clone();
|
|
||||||
|
|
||||||
if let Some(splash) = &args.splash {
|
Ok(())
|
||||||
stream.write_all((splash.len() + messages.len()).to_string().as_bytes())?;
|
}
|
||||||
|
|
||||||
let mut id = vec![0];
|
fn accept_rac_stream(
|
||||||
stream.read_exact(&mut id)?;
|
mut stream: impl Read + Write,
|
||||||
|
addr: SocketAddr,
|
||||||
if id[0] == 0x01 {
|
context: Arc<Context>,
|
||||||
messages.append(&mut splash.clone().as_bytes().to_vec());
|
args: Arc<Args>
|
||||||
stream.write_all(&messages)?;
|
) -> Result<(), Box<dyn Error>> {
|
||||||
} else if id[0] == 0x02 {
|
let mut buf = vec![0];
|
||||||
let mut buf = vec![0; 10];
|
stream.read_exact(&mut buf)?;
|
||||||
let size = stream.read(&mut buf)?;
|
|
||||||
buf.truncate(size);
|
|
||||||
|
|
||||||
let len: usize = String::from_utf8(buf)?.parse()?;
|
|
||||||
stream.write_all(&messages[(len - splash.len())..])?;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
stream.write_all(messages.len().to_string().as_bytes())?;
|
|
||||||
|
|
||||||
let mut id = vec![0];
|
if buf[0] == 0x00 {
|
||||||
stream.read_exact(&mut id)?;
|
let mut messages = context.messages.read().unwrap().clone();
|
||||||
|
|
||||||
if id[0] == 0x01 {
|
if let Some(splash) = &args.splash {
|
||||||
stream.write_all(&messages)?;
|
stream.write_all((splash.len() + messages.len()).to_string().as_bytes())?;
|
||||||
} else if id[0] == 0x02 {
|
|
||||||
let mut buf = vec![0; 10];
|
|
||||||
let size = stream.read(&mut buf)?;
|
|
||||||
buf.truncate(size);
|
|
||||||
|
|
||||||
let len: usize = String::from_utf8(buf)?.parse()?;
|
let mut id = vec![0];
|
||||||
stream.write_all(&messages[len..])?;
|
stream.read_exact(&mut id)?;
|
||||||
}
|
|
||||||
}
|
if id[0] == 0x01 {
|
||||||
} else if buf[0] == 0x01 {
|
messages.append(&mut splash.clone().as_bytes().to_vec());
|
||||||
if !args.auth_only {
|
stream.write_all(&messages)?;
|
||||||
let mut buf = vec![0; 1024];
|
} else if id[0] == 0x02 {
|
||||||
|
let mut buf = vec![0; 10];
|
||||||
let size = stream.read(&mut buf)?;
|
let size = stream.read(&mut buf)?;
|
||||||
buf.truncate(size);
|
buf.truncate(size);
|
||||||
|
|
||||||
add_message(&mut buf, messages.clone(), Some(addr.ip()), args.sanitize, args.messages_file.clone())?;
|
let len: usize = String::from_utf8(buf)?.parse()?;
|
||||||
|
stream.write_all(&messages[(len - splash.len())..])?;
|
||||||
}
|
}
|
||||||
} else if buf[0] == 0x02 {
|
} else {
|
||||||
let mut buf = vec![0; 8192];
|
stream.write_all(messages.len().to_string().as_bytes())?;
|
||||||
let size = stream.read(&mut buf)?;
|
|
||||||
buf.truncate(size);
|
|
||||||
|
|
||||||
let msg = String::from_utf8_lossy(&buf).to_string();
|
let mut id = vec![0];
|
||||||
|
stream.read_exact(&mut id)?;
|
||||||
|
|
||||||
let mut segments = msg.split("\n");
|
if id[0] == 0x01 {
|
||||||
|
stream.write_all(&messages)?;
|
||||||
|
} else if id[0] == 0x02 {
|
||||||
|
let mut buf = vec![0; 10];
|
||||||
|
let size = stream.read(&mut buf)?;
|
||||||
|
buf.truncate(size);
|
||||||
|
|
||||||
let Some(name) = segments.next() else { return Ok(()) };
|
let len: usize = String::from_utf8(buf)?.parse()?;
|
||||||
let Some(password) = segments.next() else { return Ok(()) };
|
stream.write_all(&messages[len..])?;
|
||||||
let Some(text) = segments.next() else { return Ok(()) };
|
|
||||||
|
|
||||||
for user in accounts.read().unwrap().iter() {
|
|
||||||
if user.name() == name {
|
|
||||||
if user.check_password(password) {
|
|
||||||
add_message(&mut text.as_bytes().to_vec(), messages.clone(), None, args.sanitize, args.messages_file.clone())?;
|
|
||||||
} else {
|
|
||||||
stream.write_all(&[0x02])?;
|
|
||||||
}
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
stream.write_all(&[0x01])?;
|
} else if buf[0] == 0x01 {
|
||||||
} else if buf[0] == 0x03 {
|
if !args.auth_only {
|
||||||
let mut buf = vec![0; 1024];
|
let mut buf = vec![0; 1024];
|
||||||
let size = stream.read(&mut buf)?;
|
let size = stream.read(&mut buf)?;
|
||||||
buf.truncate(size);
|
buf.truncate(size);
|
||||||
|
|
||||||
let msg = String::from_utf8_lossy(&buf).to_string();
|
add_message(&mut buf, context.clone(), Some(addr.ip()), args.sanitize, args.messages_file.clone())?;
|
||||||
|
|
||||||
let mut segments = msg.split("\n");
|
|
||||||
|
|
||||||
let Some(name) = segments.next() else { return Ok(()) };
|
|
||||||
let Some(password) = segments.next() else { return Ok(()) };
|
|
||||||
|
|
||||||
let addr = addr.ip().to_string();
|
|
||||||
|
|
||||||
let now: i64 = Local::now().timestamp_millis();
|
|
||||||
|
|
||||||
for user in accounts.read().unwrap().iter() {
|
|
||||||
if user.name() == name {
|
|
||||||
stream.write_all(&[0x01])?;
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
if user.addr() == addr && ((now - user.date()) as usize) < 1000 * args.register_timeout {
|
|
||||||
stream.write_all(&[0x01])?;
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let account = Account::new(name.to_string(), password.to_string(), addr, now);
|
|
||||||
|
|
||||||
if let Some(accounts_file) = args.accounts_file.clone() {
|
|
||||||
let mut file = OpenOptions::new()
|
|
||||||
.write(true)
|
|
||||||
.append(true)
|
|
||||||
.create(true)
|
|
||||||
.open(accounts_file)?;
|
|
||||||
|
|
||||||
file.write_all(&account.to_bytes())?;
|
|
||||||
file.write_all(b"\n")?;
|
|
||||||
file.flush()?;
|
|
||||||
}
|
|
||||||
|
|
||||||
println!("user registered: {name}");
|
|
||||||
|
|
||||||
accounts.write().unwrap().push(account);
|
|
||||||
}
|
}
|
||||||
|
} else if buf[0] == 0x02 {
|
||||||
|
let mut buf = vec![0; 8192];
|
||||||
|
let size = stream.read(&mut buf)?;
|
||||||
|
buf.truncate(size);
|
||||||
|
|
||||||
|
let msg = String::from_utf8_lossy(&buf).to_string();
|
||||||
|
|
||||||
|
let mut segments = msg.split("\n");
|
||||||
|
|
||||||
|
let Some(name) = segments.next() else { return Ok(()) };
|
||||||
|
let Some(password) = segments.next() else { return Ok(()) };
|
||||||
|
let Some(text) = segments.next() else { return Ok(()) };
|
||||||
|
|
||||||
|
for user in context.accounts.read().unwrap().iter() {
|
||||||
|
if user.name() == name {
|
||||||
|
if user.check_password(password) {
|
||||||
|
add_message(&mut text.as_bytes().to_vec(), context.clone(), None, args.sanitize, args.messages_file.clone())?;
|
||||||
|
} else {
|
||||||
|
stream.write_all(&[0x02])?;
|
||||||
|
}
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stream.write_all(&[0x01])?;
|
||||||
|
} else if buf[0] == 0x03 {
|
||||||
|
let mut buf = vec![0; 1024];
|
||||||
|
let size = stream.read(&mut buf)?;
|
||||||
|
buf.truncate(size);
|
||||||
|
|
||||||
|
let msg = String::from_utf8_lossy(&buf).to_string();
|
||||||
|
|
||||||
|
let mut segments = msg.split("\n");
|
||||||
|
|
||||||
|
let Some(name) = segments.next() else { return Ok(()) };
|
||||||
|
let Some(password) = segments.next() else { return Ok(()) };
|
||||||
|
|
||||||
|
let addr = addr.ip().to_string();
|
||||||
|
|
||||||
|
let now: i64 = Local::now().timestamp_millis();
|
||||||
|
|
||||||
|
for user in context.accounts.read().unwrap().iter() {
|
||||||
|
if user.name() == name {
|
||||||
|
stream.write_all(&[0x01])?;
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
if user.addr() == addr && ((now - user.date()) as usize) < 1000 * args.register_timeout {
|
||||||
|
stream.write_all(&[0x01])?;
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let account = Account::new(name.to_string(), password.to_string(), addr, now);
|
||||||
|
|
||||||
|
if let Some(accounts_file) = args.accounts_file.clone() {
|
||||||
|
let mut file = OpenOptions::new()
|
||||||
|
.write(true)
|
||||||
|
.append(true)
|
||||||
|
.create(true)
|
||||||
|
.open(accounts_file)?;
|
||||||
|
|
||||||
|
file.write_all(&account.to_bytes())?;
|
||||||
|
file.write_all(b"\n")?;
|
||||||
|
file.flush()?;
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("user registered: {name}");
|
||||||
|
|
||||||
|
context.accounts.write().unwrap().push(account);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_normal_listener(messages: Arc<RwLock<Vec<u8>>>, accounts: Arc<RwLock<Vec<Account>>>, args: Arc<Args>) {
|
fn accept_stream(
|
||||||
|
stream: impl Read + Write,
|
||||||
|
addr: SocketAddr,
|
||||||
|
context: Arc<Context>,
|
||||||
|
args: Arc<Args>
|
||||||
|
) -> Result<(), Box<dyn Error>> {
|
||||||
|
if args.enable_wrac {
|
||||||
|
accept_wrac_stream(stream, addr, context, args)?;
|
||||||
|
} else {
|
||||||
|
accept_rac_stream(stream, addr, context, args)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn run_normal_listener(
|
||||||
|
context: Arc<Context>,
|
||||||
|
args: Arc<Args>
|
||||||
|
) {
|
||||||
let listener = TcpListener::bind(&args.host).expect("error trying bind to the provided addr");
|
let listener = TcpListener::bind(&args.host).expect("error trying bind to the provided addr");
|
||||||
|
|
||||||
for stream in listener.incoming() {
|
for stream in listener.incoming() {
|
||||||
let Ok(stream) = stream else { continue };
|
let Ok(stream) = stream else { continue };
|
||||||
|
|
||||||
let messages = messages.clone();
|
let context = context.clone();
|
||||||
let accounts = accounts.clone();
|
|
||||||
let args = args.clone();
|
let args = args.clone();
|
||||||
|
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
let Ok(addr) = stream.peer_addr() else { return; };
|
let Ok(addr) = stream.peer_addr() else { return; };
|
||||||
match accept_stream(args, stream, addr, messages, accounts) {
|
match accept_stream(stream, addr, context, args) {
|
||||||
Ok(_) => {},
|
Ok(_) => {},
|
||||||
Err(e) => { println!("{}", e) },
|
Err(e) => { println!("{}", e) },
|
||||||
}
|
}
|
||||||
@ -460,8 +489,7 @@ fn run_normal_listener(messages: Arc<RwLock<Vec<u8>>>, accounts: Arc<RwLock<Vec<
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn run_secure_listener(
|
fn run_secure_listener(
|
||||||
messages: Arc<RwLock<Vec<u8>>>,
|
context: Arc<Context>,
|
||||||
accounts: Arc<RwLock<Vec<Account>>>,
|
|
||||||
args: Arc<Args>
|
args: Arc<Args>
|
||||||
) {
|
) {
|
||||||
let listener = TcpListener::bind(&args.host).expect("error trying bind to the provided addr");
|
let listener = TcpListener::bind(&args.host).expect("error trying bind to the provided addr");
|
||||||
@ -480,8 +508,7 @@ fn run_secure_listener(
|
|||||||
for stream in listener.incoming() {
|
for stream in listener.incoming() {
|
||||||
let Ok(stream) = stream else { continue };
|
let Ok(stream) = stream else { continue };
|
||||||
|
|
||||||
let messages = messages.clone();
|
let context = context.clone();
|
||||||
let accounts = accounts.clone();
|
|
||||||
let args = args.clone();
|
let args = args.clone();
|
||||||
let server_config = server_config.clone();
|
let server_config = server_config.clone();
|
||||||
|
|
||||||
@ -495,7 +522,7 @@ fn run_secure_listener(
|
|||||||
let Ok(_) = stream.conn.complete_io(&mut stream.sock) else { return };
|
let Ok(_) = stream.conn.complete_io(&mut stream.sock) else { return };
|
||||||
}
|
}
|
||||||
|
|
||||||
match accept_stream(args, stream, addr, messages, accounts) {
|
match accept_stream(stream, addr, context, args) {
|
||||||
Ok(_) => {},
|
Ok(_) => {},
|
||||||
Err(e) => { println!("{}", e) },
|
Err(e) => { println!("{}", e) },
|
||||||
}
|
}
|
||||||
@ -551,43 +578,47 @@ struct Args {
|
|||||||
enable_wrac: bool,
|
enable_wrac: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn load_accounts(accounts_file: Option<String>) -> Vec<Account> {
|
||||||
|
if let Some(accounts_file) = accounts_file.clone() {
|
||||||
|
if fs::exists(&accounts_file).expect("error checking accounts file") {
|
||||||
|
fs::read(&accounts_file)
|
||||||
|
.expect("error reading accounts file")
|
||||||
|
.split(|o| *o == b'\n')
|
||||||
|
.filter(|o| !o.is_empty())
|
||||||
|
.map(|o| Account::from_bytes(o.to_vec()))
|
||||||
|
.collect()
|
||||||
|
} else {
|
||||||
|
Vec::new()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Vec::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn load_messages(messages_file: Option<String>) -> Vec<u8> {
|
||||||
|
if let Some(messages_file) = messages_file.clone() {
|
||||||
|
if fs::exists(&messages_file).expect("error checking messages file") {
|
||||||
|
fs::read(&messages_file).expect("error reading messages file")
|
||||||
|
} else {
|
||||||
|
Vec::new()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Vec::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let args = Arc::new(Args::parse());
|
let args = Arc::new(Args::parse());
|
||||||
|
|
||||||
let messages = Arc::new(RwLock::new(
|
let messages = RwLock::new(load_messages(args.messages_file.clone()));
|
||||||
if let Some(messages_file) = args.messages_file.clone() {
|
let accounts = RwLock::new(load_accounts(args.accounts_file.clone()));
|
||||||
if fs::exists(&messages_file).expect("error checking messages file") {
|
let context = Arc::new(Context { messages, accounts });
|
||||||
fs::read(&messages_file).expect("error reading messages file")
|
|
||||||
} else {
|
|
||||||
Vec::new()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Vec::new()
|
|
||||||
}
|
|
||||||
));
|
|
||||||
|
|
||||||
let accounts = Arc::new(RwLock::new(
|
|
||||||
if let Some(accounts_file) = args.accounts_file.clone() {
|
|
||||||
if fs::exists(&accounts_file).expect("error checking accounts file") {
|
|
||||||
fs::read(&accounts_file)
|
|
||||||
.expect("error reading accounts file")
|
|
||||||
.split(|o| *o == b'\n')
|
|
||||||
.filter(|o| !o.is_empty())
|
|
||||||
.map(|o| Account::from_bytes(o.to_vec()))
|
|
||||||
.collect()
|
|
||||||
} else {
|
|
||||||
Vec::new()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Vec::new()
|
|
||||||
}
|
|
||||||
));
|
|
||||||
|
|
||||||
println!("Server started on {}", &args.host);
|
println!("Server started on {}", &args.host);
|
||||||
|
|
||||||
if args.enable_ssl {
|
if args.enable_ssl {
|
||||||
run_secure_listener(messages, accounts, args);
|
run_secure_listener(context, args);
|
||||||
} else {
|
} else {
|
||||||
run_normal_listener(messages, accounts, args);
|
run_normal_listener(context, args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user