generated from PlexSheep/rs-base
a little tls error handling
cargo devel CI / cargo CI (push) Successful in 2m15s
Details
cargo devel CI / cargo CI (push) Successful in 2m15s
Details
This commit is contained in:
parent
e622a5cc99
commit
8a1407185a
|
@ -1,4 +1,4 @@
|
||||||
use std::{fmt::Display, string::FromUtf8Error};
|
use std::{fmt::Display, str::Utf8Error, string::FromUtf8Error};
|
||||||
|
|
||||||
use anyhow;
|
use anyhow;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
@ -11,7 +11,7 @@ pub enum ServerError {
|
||||||
Timeout(Elapsed),
|
Timeout(Elapsed),
|
||||||
Anyhow(anyhow::Error),
|
Anyhow(anyhow::Error),
|
||||||
IO(std::io::Error),
|
IO(std::io::Error),
|
||||||
Format(FromUtf8Error),
|
Format(Utf8Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<anyhow::Error> for ServerError {
|
impl From<anyhow::Error> for ServerError {
|
||||||
|
@ -26,8 +26,8 @@ impl From<std::io::Error> for ServerError {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<FromUtf8Error> for ServerError {
|
impl From<Utf8Error> for ServerError {
|
||||||
fn from(value: FromUtf8Error) -> Self {
|
fn from(value: Utf8Error) -> Self {
|
||||||
Self::Format(value)
|
Self::Format(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,18 @@
|
||||||
#![cfg(feature = "server")]
|
#![cfg(feature = "server")]
|
||||||
use std::{
|
use std::{
|
||||||
fs::File, net::SocketAddr, sync::{atomic::AtomicUsize, Arc}, time::Duration
|
fs::File,
|
||||||
|
net::SocketAddr,
|
||||||
|
sync::{atomic::AtomicUsize, Arc},
|
||||||
|
time::Duration,
|
||||||
};
|
};
|
||||||
|
|
||||||
use libpt::log::{debug, info, trace, warn};
|
use libpt::log::{debug, error, info, trace, warn};
|
||||||
use rustls::pki_types::{CertificateDer, PrivateKeyDer};
|
use rustls::pki_types::{CertificateDer, PrivateKeyDer};
|
||||||
use rustls_pemfile::{certs, private_key};
|
use rustls_pemfile::{certs, private_key};
|
||||||
use tokio::{
|
use tokio::{
|
||||||
io::{split, AsyncReadExt, AsyncWriteExt, BufReader}, net::{TcpListener, TcpStream}, time::{self, timeout}
|
io::{split, AsyncReadExt, AsyncWriteExt, BufReader},
|
||||||
|
net::{TcpListener, TcpStream},
|
||||||
|
time::{self, timeout},
|
||||||
};
|
};
|
||||||
use tokio_rustls::{rustls, TlsAcceptor};
|
use tokio_rustls::{rustls, TlsAcceptor};
|
||||||
|
|
||||||
|
@ -29,7 +34,7 @@ pub struct Server {
|
||||||
impl Server {
|
impl Server {
|
||||||
pub async fn build(cfg: Config) -> anyhow::Result<Self> {
|
pub async fn build(cfg: Config) -> anyhow::Result<Self> {
|
||||||
let certs = Self::load_certs(cfg.clone())?;
|
let certs = Self::load_certs(cfg.clone())?;
|
||||||
let key = Self::load_key(cfg.clone())?.unwrap();
|
let key = Self::load_key(cfg.clone())?.expect("bad key?");
|
||||||
let tls_config = rustls::ServerConfig::builder()
|
let tls_config = rustls::ServerConfig::builder()
|
||||||
.with_no_client_auth()
|
.with_no_client_auth()
|
||||||
.with_single_cert(certs, key)?;
|
.with_single_cert(certs, key)?;
|
||||||
|
@ -69,12 +74,18 @@ impl Server {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let ref_self = rc_self.clone();
|
let ref_self = rc_self.clone();
|
||||||
let acceptor = rc_self.acceptor.clone();
|
|
||||||
// NOTE: we can only start the task now. If we start it before accepting connections
|
// NOTE: we can only start the task now. If we start it before accepting connections
|
||||||
// (so that the task theoretically accepts the connection), we would create endless
|
// (so that the task theoretically accepts the connection), we would create endless
|
||||||
// tasks in a loop.
|
// tasks in a loop.
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
let stream: tokio_rustls::server::TlsStream<_> = acceptor.accept(stream).await.unwrap();
|
let stream: tokio_rustls::server::TlsStream<_> =
|
||||||
|
match ref_self.acceptor.accept(stream).await {
|
||||||
|
Ok(s) => s,
|
||||||
|
Err(err) => {
|
||||||
|
error!("could not accept tcp stream: {err}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
ref_self.peer_add(1);
|
ref_self.peer_add(1);
|
||||||
match ref_self.handle_stream(stream, addr).await {
|
match ref_self.handle_stream(stream, addr).await {
|
||||||
Ok(_) => (),
|
Ok(_) => (),
|
||||||
|
@ -116,19 +127,25 @@ impl Server {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn handle_stream(&self, stream: tokio_rustls::server::TlsStream<TcpStream>, addr: SocketAddr) -> Result<()> {
|
async fn handle_stream(
|
||||||
let mut pings: usize = 0;
|
&self,
|
||||||
|
stream: tokio_rustls::server::TlsStream<TcpStream>,
|
||||||
|
addr: SocketAddr,
|
||||||
|
) -> Result<()> {
|
||||||
debug!("new peer: {:?}", addr);
|
debug!("new peer: {:?}", addr);
|
||||||
let mut buf = [0; BUF_SIZE];
|
let mut buf = [0; BUF_SIZE];
|
||||||
let (mut reader, mut writer) = split(stream);
|
let (mut reader, mut writer) = split(stream);
|
||||||
loop {
|
loop {
|
||||||
match reader.read(&mut buf).await {
|
match reader.read(&mut buf).await {
|
||||||
Ok(len) if len == 0 => { break;},
|
Ok(len) if len == 0 => {
|
||||||
|
break;
|
||||||
|
}
|
||||||
Ok(_) => (),
|
Ok(_) => (),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
eprintln!("reader.read err: {err}")
|
eprintln!("reader.read err: {err}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
debug!("< {addr:?} : \"{}\"", self.decode(&buf)?);
|
||||||
|
|
||||||
writer.write(b"pong\0").await?;
|
writer.write(b"pong\0").await?;
|
||||||
|
|
||||||
|
@ -140,7 +157,10 @@ impl Server {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn decode(&self, buf: &Vec<u8>) -> Result<String> {
|
fn decode(&self, buf: &[u8]) -> Result<String> {
|
||||||
Ok(String::from_utf8(buf.clone())?.replace('\n', "\\n"))
|
match std::str::from_utf8(buf) {
|
||||||
|
Ok(s) => Ok(s.to_string()),
|
||||||
|
Err(err) => Err(err.into()),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue