When a listener is configured to deal with TLS upstreams, we use the SNI field of the TLS ClientHello message to decide where to send the traffic. Therefore, a buffer of 1024 bytes was used to temporarily store this message. However, a TLS ClientHello message can be larger than that, up to 16K bytes. So now the first few bytes are read and manually parsed to find out how long the message is. And then the entire ClientHello message is retrieved. So hopefully that will fix the issue causing the ClientHello determination to fail. Closes #10 Signed-off-by: Jacob Kiers <code@kiers.eu>
56 lines
1.7 KiB
Rust
56 lines
1.7 KiB
Rust
use crate::servers::protocol::tls::determine_upstream_name;
|
|
use crate::servers::Proxy;
|
|
use log::{debug, error, info, trace, warn};
|
|
use std::error::Error;
|
|
use std::sync::Arc;
|
|
use tokio::net::{TcpListener, TcpStream};
|
|
|
|
pub(crate) async fn proxy(config: Arc<Proxy>) -> Result<(), Box<dyn Error>> {
|
|
let listener = TcpListener::bind(config.listen).await?;
|
|
let config = config.clone();
|
|
|
|
loop {
|
|
let thread_proxy = config.clone();
|
|
match listener.accept().await {
|
|
Err(err) => {
|
|
error!("Failed to accept connection: {}", err);
|
|
return Err(Box::new(err));
|
|
}
|
|
Ok((stream, _)) => {
|
|
tokio::spawn(async move {
|
|
match accept(stream, thread_proxy).await {
|
|
Ok(_) => {}
|
|
Err(err) => {
|
|
error!("Relay thread returned an error: {}", err);
|
|
}
|
|
};
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
async fn accept(inbound: TcpStream, proxy: Arc<Proxy>) -> Result<(), Box<dyn Error>> {
|
|
info!("New connection from {:?}", inbound.peer_addr()?);
|
|
|
|
let upstream_name = match proxy.tls {
|
|
false => proxy.default_action.clone(),
|
|
true => determine_upstream_name(&inbound, &proxy).await?,
|
|
};
|
|
|
|
debug!("Upstream: {}", upstream_name);
|
|
|
|
let upstream = match proxy.upstream.get(&upstream_name) {
|
|
Some(upstream) => upstream,
|
|
None => {
|
|
warn!(
|
|
"No upstream named {:?} on server {:?}",
|
|
proxy.default_action, proxy.name
|
|
);
|
|
proxy.upstream.get(&proxy.default_action).unwrap()
|
|
}
|
|
};
|
|
|
|
upstream.process(inbound).await
|
|
}
|