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 threadpool_size: usize,
pub connection_timeout: Duration,
pub incoming_ip_forwarding: IpForwarding,
pub websocket_host: Option<String>
pub incoming_ip_forwarding: IpForwarding
}
impl Config {
@ -75,7 +74,6 @@ impl Config {
.map(|o| o.as_str()).flatten()
.map(|o| IpForwarding::from_name(o)).flatten()
.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();
@ -121,8 +119,7 @@ impl Config {
https_host,
threadpool_size,
connection_timeout,
incoming_ip_forwarding,
websocket_host
incoming_ip_forwarding
}.clone())
}

View File

@ -5,8 +5,6 @@ use std::{
sync::Arc
};
use tokio::sync::RwLock;
use ignore_result::Ignore;
use tokio::{
io::{AsyncReadExt, AsyncWriteExt},
@ -26,7 +24,7 @@ use super::config::{
};
pub struct FlowgateServer {
config: Arc<RwLock<Config>>,
config: Arc<Config>,
}
struct Connection {
@ -37,50 +35,45 @@ struct Connection {
}
impl FlowgateServer {
pub fn new(config: Arc<RwLock<Config>>) -> Self {
pub fn new(config: Arc<Config>) -> Self {
FlowgateServer { config }
}
pub async fn start(&self) {
tokio::spawn({
let config = self.config.clone();
pub async fn start(self) {
let local_self = Arc::new(self);
async move {
Self::run_http(config).await.ignore();
}
tokio::spawn({
let local_self = local_self.clone();
async move { local_self.run_http().await.ignore(); }
});
tokio::spawn({
let config = self.config.clone();
async move {
Self::run_https(config).await.ignore();
}
let local_self = local_self.clone();
async move { local_self.run_https().await.ignore(); }
});
}
pub async fn run_http(
config: Arc<RwLock<Config>>
self: Arc<Self>
) -> 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 {
let Ok((stream, addr)) = listener.accept().await else { break };
let config = config.clone();
let local_self = self.clone();
tokio::spawn(async move {
let mut stream = TimeoutStream::new(stream);
stream.set_write_timeout(Some(config.read().await.connection_timeout));
stream.set_read_timeout(Some(config.read().await.connection_timeout));
stream.set_write_timeout(Some(local_self.config.connection_timeout));
stream.set_read_timeout(Some(local_self.config.connection_timeout));
let mut stream = Box::pin(stream);
Self::accept_stream(
config,
local_self.accept_stream(
&mut stream,
addr,
false
@ -92,29 +85,28 @@ impl FlowgateServer {
}
pub async fn run_https(
config: Arc<RwLock<Config>>
self: Arc<Self>
) -> Result<(), Box<dyn Error>> {
let listener = TcpListener::bind(&config.read().await.https_host).await?;
let acceptor = TlsAcceptor::from(Arc::new(create_server_config(config.clone()).await));
let listener = TcpListener::bind(&self.config.https_host).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 {
let Ok((stream, addr)) = listener.accept().await else { break };
let config = config.clone();
let local_self = self.clone();
let acceptor = acceptor.clone();
tokio::spawn(async move {
let mut stream = TimeoutStream::new(stream);
stream.set_write_timeout(Some(config.read().await.connection_timeout));
stream.set_read_timeout(Some(config.read().await.connection_timeout));
stream.set_write_timeout(Some(local_self.config.connection_timeout));
stream.set_read_timeout(Some(local_self.config.connection_timeout));
let Ok(mut stream) = acceptor.accept(Box::pin(stream)).await else { return };
Self::accept_stream(
config,
local_self.accept_stream(
&mut stream,
addr,
true
@ -125,13 +117,13 @@ impl FlowgateServer {
Ok(())
}
pub async fn accept_stream(
config: Arc<RwLock<Config>>,
async fn accept_stream(
self: Arc<Self>,
stream: &mut (impl AsyncReadExt + AsyncWriteExt + Unpin),
addr: SocketAddr,
https: bool
) -> 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 {
loop {
@ -139,7 +131,7 @@ impl FlowgateServer {
conn.stream.shutdown().await.ignore();
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(())
}
}
async fn read_request(
config: Arc<RwLock<Config>>,
async fn read_request(
self: Arc<Self>,
stream: &mut (impl AsyncReadExt + AsyncWriteExt + Unpin),
addr: SocketAddr,
https: bool,
conn: Option<Connection>
) -> Option<Connection> {
) -> Option<Connection> {
let mut addr = addr;
match &config.read().await.incoming_ip_forwarding {
match &self.config.incoming_ip_forwarding {
IpForwarding::Simple => {
let mut header = Vec::new();
@ -242,7 +233,7 @@ async fn read_request(
.map(|o| o.contains(&"chunked".to_string()))
.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) {
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 {
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]);
Some(conn)
}
}

View File

@ -1,4 +1,4 @@
use std::{sync::Arc, thread};
use std::sync::Arc;
use rustls::{
crypto::aws_lc_rs::sign::any_supported_type,
@ -8,8 +8,6 @@ use rustls::{
ServerConfig
};
use tokio::{runtime::Handle, sync::RwLock};
use super::config::Config;
@ -37,29 +35,19 @@ impl TlsCertificate {
#[derive(Debug)]
struct ResolvesServerCertWildcard {
config: Arc<RwLock<Config>>,
handle: Handle
config: Arc<Config>
}
impl ResolvesServerCertWildcard {
pub async fn new(config: Arc<RwLock<Config>>) -> Self {
Self { config, handle: Handle::current() }
pub async fn new(config: Arc<Config>) -> Self {
Self { config }
}
}
impl ResolvesServerCert for ResolvesServerCertWildcard {
fn resolve(&self, client_hello: ClientHello<'_>) -> Option<Arc<CertifiedKey>> {
if let Some(cert) = client_hello.server_name()
.and_then(|name| {
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(|name| self.config.get_site(name).cloned())
.and_then(|site| site.ssl) {
Some(Arc::new(cert.get_key()))
} 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()
.with_no_client_auth()
.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 ignore_result::Ignore;
use tokio::sync::RwLock;
#[tokio::main]
async fn main() {
@ -12,7 +11,7 @@ async fn main() {
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());
server.start().await;