config remove rwlock

This commit is contained in:
MeexReay 2025-04-07 01:41:34 +03:00
parent 903bf23a4c
commit ef9f1b2847
4 changed files with 311 additions and 335 deletions

View File

@ -55,8 +55,7 @@ pub struct Config {
pub https_host: String, pub https_host: String,
pub threadpool_size: usize, pub threadpool_size: usize,
pub connection_timeout: Duration, pub connection_timeout: Duration,
pub incoming_ip_forwarding: IpForwarding, pub incoming_ip_forwarding: IpForwarding
pub websocket_host: Option<String>
} }
impl Config { impl Config {
@ -75,7 +74,6 @@ impl Config {
.map(|o| o.as_str()).flatten() .map(|o| o.as_str()).flatten()
.map(|o| IpForwarding::from_name(o)).flatten() .map(|o| IpForwarding::from_name(o)).flatten()
.unwrap_or(IpForwarding::None); .unwrap_or(IpForwarding::None);
let websocket_host = doc.get("websocket_host").map(|o| o.as_str()).flatten().map(|o| o.to_string());
let mut sites: Vec<SiteConfig> = Vec::new(); let mut sites: Vec<SiteConfig> = Vec::new();
@ -121,8 +119,7 @@ impl Config {
https_host, https_host,
threadpool_size, threadpool_size,
connection_timeout, connection_timeout,
incoming_ip_forwarding, incoming_ip_forwarding
websocket_host
}.clone()) }.clone())
} }

View File

@ -5,8 +5,6 @@ use std::{
sync::Arc sync::Arc
}; };
use tokio::sync::RwLock;
use ignore_result::Ignore; use ignore_result::Ignore;
use tokio::{ use tokio::{
io::{AsyncReadExt, AsyncWriteExt}, io::{AsyncReadExt, AsyncWriteExt},
@ -26,7 +24,7 @@ use super::config::{
}; };
pub struct FlowgateServer { pub struct FlowgateServer {
config: Arc<RwLock<Config>>, config: Arc<Config>,
} }
struct Connection { struct Connection {
@ -37,50 +35,45 @@ struct Connection {
} }
impl FlowgateServer { impl FlowgateServer {
pub fn new(config: Arc<RwLock<Config>>) -> Self { pub fn new(config: Arc<Config>) -> Self {
FlowgateServer { config } FlowgateServer { config }
} }
pub async fn start(&self) { pub async fn start(self) {
tokio::spawn({ let local_self = Arc::new(self);
let config = self.config.clone();
async move { tokio::spawn({
Self::run_http(config).await.ignore(); let local_self = local_self.clone();
} async move { local_self.run_http().await.ignore(); }
}); });
tokio::spawn({ tokio::spawn({
let config = self.config.clone(); let local_self = local_self.clone();
async move { local_self.run_https().await.ignore(); }
async move {
Self::run_https(config).await.ignore();
}
}); });
} }
pub async fn run_http( pub async fn run_http(
config: Arc<RwLock<Config>> self: Arc<Self>
) -> Result<(), Box<dyn Error>> { ) -> Result<(), Box<dyn Error>> {
let listener = TcpListener::bind(&config.read().await.http_host).await?; let listener = TcpListener::bind(&self.config.http_host).await?;
info!("HTTP server runned on {}", &config.read().await.http_host); info!("HTTP server runned on {}", &self.config.http_host);
loop { loop {
let Ok((stream, addr)) = listener.accept().await else { break }; let Ok((stream, addr)) = listener.accept().await else { break };
let config = config.clone(); let local_self = self.clone();
tokio::spawn(async move { tokio::spawn(async move {
let mut stream = TimeoutStream::new(stream); let mut stream = TimeoutStream::new(stream);
stream.set_write_timeout(Some(config.read().await.connection_timeout)); stream.set_write_timeout(Some(local_self.config.connection_timeout));
stream.set_read_timeout(Some(config.read().await.connection_timeout)); stream.set_read_timeout(Some(local_self.config.connection_timeout));
let mut stream = Box::pin(stream); let mut stream = Box::pin(stream);
Self::accept_stream( local_self.accept_stream(
config,
&mut stream, &mut stream,
addr, addr,
false false
@ -92,29 +85,28 @@ impl FlowgateServer {
} }
pub async fn run_https( pub async fn run_https(
config: Arc<RwLock<Config>> self: Arc<Self>
) -> Result<(), Box<dyn Error>> { ) -> Result<(), Box<dyn Error>> {
let listener = TcpListener::bind(&config.read().await.https_host).await?; let listener = TcpListener::bind(&self.config.https_host).await?;
let acceptor = TlsAcceptor::from(Arc::new(create_server_config(config.clone()).await)); let acceptor = TlsAcceptor::from(Arc::new(create_server_config(self.config.clone()).await));
info!("HTTPS server runned on {}", &config.read().await.https_host); info!("HTTPS server runned on {}", &self.config.https_host);
loop { loop {
let Ok((stream, addr)) = listener.accept().await else { break }; let Ok((stream, addr)) = listener.accept().await else { break };
let config = config.clone(); let local_self = self.clone();
let acceptor = acceptor.clone(); let acceptor = acceptor.clone();
tokio::spawn(async move { tokio::spawn(async move {
let mut stream = TimeoutStream::new(stream); let mut stream = TimeoutStream::new(stream);
stream.set_write_timeout(Some(config.read().await.connection_timeout)); stream.set_write_timeout(Some(local_self.config.connection_timeout));
stream.set_read_timeout(Some(config.read().await.connection_timeout)); stream.set_read_timeout(Some(local_self.config.connection_timeout));
let Ok(mut stream) = acceptor.accept(Box::pin(stream)).await else { return }; let Ok(mut stream) = acceptor.accept(Box::pin(stream)).await else { return };
Self::accept_stream( local_self.accept_stream(
config,
&mut stream, &mut stream,
addr, addr,
true true
@ -125,13 +117,13 @@ impl FlowgateServer {
Ok(()) Ok(())
} }
pub async fn accept_stream( async fn accept_stream(
config: Arc<RwLock<Config>>, self: Arc<Self>,
stream: &mut (impl AsyncReadExt + AsyncWriteExt + Unpin), stream: &mut (impl AsyncReadExt + AsyncWriteExt + Unpin),
addr: SocketAddr, addr: SocketAddr,
https: bool https: bool
) -> Option<()> { ) -> Option<()> {
let mut conn = read_request(config.clone(), stream, addr, https, None).await?; let mut conn = self.clone().read_request(stream, addr, https, None).await?;
if conn.keep_alive && conn.config.enable_keep_alive { if conn.keep_alive && conn.config.enable_keep_alive {
loop { loop {
@ -139,7 +131,7 @@ impl FlowgateServer {
conn.stream.shutdown().await.ignore(); conn.stream.shutdown().await.ignore();
conn.stream = conn.config.connect().await?; conn.stream = conn.config.connect().await?;
} }
conn = read_request(config.clone(), stream, addr, https, Some(conn)).await?; conn = self.clone().read_request(stream, addr, https, Some(conn)).await?;
} }
} }
@ -148,18 +140,17 @@ impl FlowgateServer {
Some(()) Some(())
} }
}
async fn read_request( async fn read_request(
config: Arc<RwLock<Config>>, self: Arc<Self>,
stream: &mut (impl AsyncReadExt + AsyncWriteExt + Unpin), stream: &mut (impl AsyncReadExt + AsyncWriteExt + Unpin),
addr: SocketAddr, addr: SocketAddr,
https: bool, https: bool,
conn: Option<Connection> conn: Option<Connection>
) -> Option<Connection> { ) -> Option<Connection> {
let mut addr = addr; let mut addr = addr;
match &config.read().await.incoming_ip_forwarding { match &self.config.incoming_ip_forwarding {
IpForwarding::Simple => { IpForwarding::Simple => {
let mut header = Vec::new(); let mut header = Vec::new();
@ -242,7 +233,7 @@ async fn read_request(
.map(|o| o.contains(&"chunked".to_string())) .map(|o| o.contains(&"chunked".to_string()))
.unwrap_or(false); .unwrap_or(false);
if let IpForwarding::Header(header) = &config.read().await.incoming_ip_forwarding { if let IpForwarding::Header(header) = &self.config.incoming_ip_forwarding {
if let Some(ip) = headers.iter().find(|o| o.0 == header).map(|o| o.1) { if let Some(ip) = headers.iter().find(|o| o.0 == header).map(|o| o.1) {
addr = SocketAddr::from_str(ip).ok()?; addr = SocketAddr::from_str(ip).ok()?;
} }
@ -260,7 +251,7 @@ async fn read_request(
} }
} }
let site = config.read().await.get_site(&host)?.clone(); let site = self.config.get_site(&host)?.clone();
Connection { Connection {
stream: site.connect().await?, stream: site.connect().await?,
@ -501,4 +492,5 @@ async fn read_request(
info!("{addr} > {} {}://{}{}", status_seq[0], if https { "https" } else { "http" }, conn.host, status_seq[1]); info!("{addr} > {} {}://{}{}", status_seq[0], if https { "https" } else { "http" }, conn.host, status_seq[1]);
Some(conn) Some(conn)
}
} }

View File

@ -1,4 +1,4 @@
use std::{sync::Arc, thread}; use std::sync::Arc;
use rustls::{ use rustls::{
crypto::aws_lc_rs::sign::any_supported_type, crypto::aws_lc_rs::sign::any_supported_type,
@ -8,8 +8,6 @@ use rustls::{
ServerConfig ServerConfig
}; };
use tokio::{runtime::Handle, sync::RwLock};
use super::config::Config; use super::config::Config;
@ -37,29 +35,19 @@ impl TlsCertificate {
#[derive(Debug)] #[derive(Debug)]
struct ResolvesServerCertWildcard { struct ResolvesServerCertWildcard {
config: Arc<RwLock<Config>>, config: Arc<Config>
handle: Handle
} }
impl ResolvesServerCertWildcard { impl ResolvesServerCertWildcard {
pub async fn new(config: Arc<RwLock<Config>>) -> Self { pub async fn new(config: Arc<Config>) -> Self {
Self { config, handle: Handle::current() } Self { config }
} }
} }
impl ResolvesServerCert for ResolvesServerCertWildcard { impl ResolvesServerCert for ResolvesServerCertWildcard {
fn resolve(&self, client_hello: ClientHello<'_>) -> Option<Arc<CertifiedKey>> { fn resolve(&self, client_hello: ClientHello<'_>) -> Option<Arc<CertifiedKey>> {
if let Some(cert) = client_hello.server_name() if let Some(cert) = client_hello.server_name()
.and_then(|name| { .and_then(|name| self.config.get_site(name).cloned())
thread::spawn({
let handle = self.handle.clone();
let config = self.config.clone();
move || {
handle.block_on(config.read()).clone()
}
}).join().unwrap().get_site(name).cloned()
})
.and_then(|site| site.ssl) { .and_then(|site| site.ssl) {
Some(Arc::new(cert.get_key())) Some(Arc::new(cert.get_key()))
} else { } else {
@ -68,7 +56,7 @@ impl ResolvesServerCert for ResolvesServerCertWildcard {
} }
} }
pub async fn create_server_config(config: Arc<RwLock<Config>>) -> ServerConfig { pub async fn create_server_config(config: Arc<Config>) -> ServerConfig {
ServerConfig::builder() ServerConfig::builder()
.with_no_client_auth() .with_no_client_auth()
.with_cert_resolver(Arc::new(ResolvesServerCertWildcard::new(config).await)) .with_cert_resolver(Arc::new(ResolvesServerCertWildcard::new(config).await))

View File

@ -2,7 +2,6 @@ use std::{fs, path::Path, sync::Arc};
use flowgate::{config::Config, server::FlowgateServer}; use flowgate::{config::Config, server::FlowgateServer};
use ignore_result::Ignore; use ignore_result::Ignore;
use tokio::sync::RwLock;
#[tokio::main] #[tokio::main]
async fn main() { async fn main() {
@ -12,7 +11,7 @@ async fn main() {
fs::write("conf.yml", include_bytes!("../conf.yml")).ignore(); fs::write("conf.yml", include_bytes!("../conf.yml")).ignore();
} }
let config = Arc::new(RwLock::new(Config::parse("conf.yml").unwrap())); let config = Arc::new(Config::parse("conf.yml").unwrap());
let server = FlowgateServer::new(config.clone()); let server = FlowgateServer::new(config.clone());
server.start().await; server.start().await;