100 lines
2.2 KiB
Rust
100 lines
2.2 KiB
Rust
|
mod client;
|
||
|
mod pseudo_tcp_message;
|
||
|
mod server;
|
||
|
mod socket;
|
||
|
mod state;
|
||
|
|
||
|
pub mod prelude;
|
||
|
|
||
|
#[cfg(feature = "hostname")]
|
||
|
mod hostname;
|
||
|
|
||
|
#[cfg(feature = "local_ip")]
|
||
|
mod local_address;
|
||
|
|
||
|
#[cfg(feature = "public_ip")]
|
||
|
mod public_address;
|
||
|
|
||
|
#[cfg(feature = "resolve_dns")]
|
||
|
mod resolve;
|
||
|
|
||
|
use crate::prelude::*;
|
||
|
use std::{
|
||
|
fs::File,
|
||
|
io::{Error, Write},
|
||
|
mem::swap,
|
||
|
net::SocketAddr,
|
||
|
};
|
||
|
|
||
|
use chrono::Local;
|
||
|
|
||
|
static mut LOG_FILE: Option<NetworkLogFile> = None;
|
||
|
|
||
|
pub struct NetworkLogFile {
|
||
|
file: File,
|
||
|
}
|
||
|
|
||
|
impl NetworkLogFile {
|
||
|
pub fn create(path: &str) -> std::result::Result<(), Error> {
|
||
|
let mut file = File::create(path)?;
|
||
|
|
||
|
file.write_all("================================================\n".as_bytes())?;
|
||
|
file.write_all(format!("{:?}\n", Local::now()).as_bytes())?;
|
||
|
file.write_all("================================================\n\n\n".as_bytes())?;
|
||
|
|
||
|
unsafe {
|
||
|
LOG_FILE = Some(NetworkLogFile { file });
|
||
|
}
|
||
|
|
||
|
Ok(())
|
||
|
}
|
||
|
|
||
|
pub(crate) fn log(mut message: String) -> std::result::Result<(), Error> {
|
||
|
message += "\n";
|
||
|
|
||
|
unsafe {
|
||
|
LOG_FILE
|
||
|
.as_mut()
|
||
|
.expect("log file not set!")
|
||
|
.file
|
||
|
.write_all(message.as_bytes())
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pub fn split_matches(s: &str, c: char) -> (&str, &str) {
|
||
|
match s.find(c) {
|
||
|
Some(pos) => {
|
||
|
let (f, l) = s.split_at(pos);
|
||
|
let l = l.trim_start_matches(c);
|
||
|
|
||
|
(f, l)
|
||
|
}
|
||
|
None => (s, ""),
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pub fn filter_by_content<F>(content: &mut Vec<SocketContent>, mut filter: F) -> Vec<SocketContent>
|
||
|
where
|
||
|
F: FnMut(SocketAddr, &str) -> bool,
|
||
|
{
|
||
|
let mut v = Vec::new();
|
||
|
swap(content, &mut v);
|
||
|
|
||
|
let (filtered, others): (Vec<SocketContent>, Vec<SocketContent>) =
|
||
|
v.into_iter().partition(|content| match content {
|
||
|
SocketContent::Message(addr, msg) => filter(*addr, msg),
|
||
|
SocketContent::NewConnection(_) => false,
|
||
|
SocketContent::TimeOut(_) => false,
|
||
|
});
|
||
|
|
||
|
*content = others;
|
||
|
|
||
|
filtered
|
||
|
}
|
||
|
|
||
|
pub trait Sender {
|
||
|
fn send(&mut self, addr: SocketAddr, msg: &str) -> anyhow::Result<()>;
|
||
|
fn is_server(&self) -> bool;
|
||
|
}
|