document possible errors
This commit is contained in:
parent
d917afe58c
commit
ac72742c2a
@ -5,6 +5,9 @@ use tracing::debug;
|
|||||||
|
|
||||||
use crate::packets::{Header, Packet, PacketKind};
|
use crate::packets::{Header, Packet, PacketKind};
|
||||||
|
|
||||||
|
/// # Errors
|
||||||
|
/// - the dyn ip server returns a malformed response or is unreachable
|
||||||
|
/// - the authentication fails
|
||||||
pub async fn dyn_ip_update(
|
pub async fn dyn_ip_update(
|
||||||
server: &SocketAddr,
|
server: &SocketAddr,
|
||||||
number: u32,
|
number: u32,
|
||||||
|
@ -20,6 +20,8 @@ use crate::{
|
|||||||
Config, HandlerMetadata,
|
Config, HandlerMetadata,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// # Errors
|
||||||
|
/// - the client authentication fails
|
||||||
async fn authenticate(
|
async fn authenticate(
|
||||||
config: &Config,
|
config: &Config,
|
||||||
port_handler: &Mutex<PortHandler>,
|
port_handler: &Mutex<PortHandler>,
|
||||||
@ -57,37 +59,33 @@ async fn authenticate(
|
|||||||
TcpListener::bind((config.listen_addr.ip(), port)).await
|
TcpListener::bind((config.listen_addr.ip(), port)).await
|
||||||
};
|
};
|
||||||
|
|
||||||
match listener {
|
if let Ok(listener) = listener {
|
||||||
Ok(listener) => {
|
// make sure that if we have an error, we still have access
|
||||||
// make sure that if we have an error, we still have access
|
// to the listener in the error handler.
|
||||||
// to the listener in the error handler.
|
handler_metadata.listener = Some(listener);
|
||||||
handler_metadata.listener = Some(listener);
|
|
||||||
|
|
||||||
// if we authenticated a client for a port we then failed to open
|
// if we authenticated a client for a port we then failed to open
|
||||||
// we need to update the server here once a port that can be opened
|
// we need to update the server here once a port that can be opened
|
||||||
// has been found
|
// has been found
|
||||||
if !updated_server {
|
if !updated_server {
|
||||||
let _ip = dyn_ip_update(&config.dyn_ip_server, number, pin, port)
|
let _ip = dyn_ip_update(&config.dyn_ip_server, number, pin, port)
|
||||||
.await
|
.await
|
||||||
.context("dy-ip update")?;
|
.context("dy-ip update")?;
|
||||||
}
|
|
||||||
|
|
||||||
port_handler.register_update();
|
|
||||||
port_handler
|
|
||||||
.port_state
|
|
||||||
.entry(port)
|
|
||||||
.or_default()
|
|
||||||
.new_state(PortStatus::Idle);
|
|
||||||
|
|
||||||
handler_metadata.port = Some(port);
|
|
||||||
|
|
||||||
break Ok(Some(port));
|
|
||||||
}
|
}
|
||||||
Err(_err) => {
|
|
||||||
port_handler.mark_port_error(number, port);
|
port_handler.register_update();
|
||||||
continue;
|
port_handler
|
||||||
}
|
.port_state
|
||||||
};
|
.entry(port)
|
||||||
|
.or_default()
|
||||||
|
.new_state(PortStatus::Idle);
|
||||||
|
|
||||||
|
handler_metadata.port = Some(port);
|
||||||
|
|
||||||
|
break Ok(Some(port));
|
||||||
|
}
|
||||||
|
|
||||||
|
port_handler.mark_port_error(number, port);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -183,7 +181,7 @@ async fn notify_or_disconnect(
|
|||||||
.take()
|
.take()
|
||||||
.expect("tried to start rejector twice"),
|
.expect("tried to start rejector twice"),
|
||||||
packet,
|
packet,
|
||||||
)?;
|
);
|
||||||
Ok(None)
|
Ok(None)
|
||||||
} else {
|
} else {
|
||||||
Err(anyhow!("unexpected packet: {:?}", packet.kind()))
|
Err(anyhow!("unexpected packet: {:?}", packet.kind()))
|
||||||
@ -248,7 +246,7 @@ async fn connect(
|
|||||||
.take()
|
.take()
|
||||||
.expect("tried to start rejector twice"),
|
.expect("tried to start rejector twice"),
|
||||||
packet,
|
packet,
|
||||||
)?;
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
stream.set_nodelay(true)?;
|
stream.set_nodelay(true)?;
|
||||||
@ -282,6 +280,12 @@ async fn connect(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// # Errors
|
||||||
|
/// - the connection to the client or the caller is interupted
|
||||||
|
/// - the clients sends unexpected or malformed packets
|
||||||
|
/// - accepting a tcp connection fails
|
||||||
|
/// - settings tcp socket properties fails
|
||||||
|
/// - the client authentication fails
|
||||||
pub async fn handler(
|
pub async fn handler(
|
||||||
stream: &mut TcpStream,
|
stream: &mut TcpStream,
|
||||||
addr: SocketAddr,
|
addr: SocketAddr,
|
||||||
@ -354,7 +358,7 @@ pub async fn handler(
|
|||||||
.take()
|
.take()
|
||||||
.expect("tried to start rejector twice"),
|
.expect("tried to start rejector twice"),
|
||||||
packet,
|
packet,
|
||||||
)?;
|
);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
11
src/main.rs
11
src/main.rs
@ -1,5 +1,5 @@
|
|||||||
#![warn(clippy::pedantic)]
|
#![warn(clippy::pedantic)]
|
||||||
#![allow(clippy::missing_errors_doc)]
|
// #![allow(clippy::missing_errors_doc)]
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
fmt::Debug,
|
fmt::Debug,
|
||||||
@ -42,10 +42,13 @@ type UnixTimestamp = u64;
|
|||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
allowed_ports: AllowedList,
|
allowed_ports: AllowedList,
|
||||||
|
|
||||||
#[serde(deserialize_with = "parse_socket_addr")]
|
#[serde(deserialize_with = "parse_socket_addr")]
|
||||||
listen_addr: SocketAddr,
|
listen_addr: SocketAddr,
|
||||||
|
|
||||||
#[serde(deserialize_with = "parse_socket_addr")]
|
#[serde(deserialize_with = "parse_socket_addr")]
|
||||||
dyn_ip_server: SocketAddr,
|
dyn_ip_server: SocketAddr,
|
||||||
|
|
||||||
#[cfg(feature = "debug_server")]
|
#[cfg(feature = "debug_server")]
|
||||||
#[serde(deserialize_with = "maybe_parse_socket_addr")]
|
#[serde(deserialize_with = "maybe_parse_socket_addr")]
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
@ -220,7 +223,7 @@ async fn connection_handler(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Some(listener) = handler_metadata.listener.take() {
|
if let Some(listener) = handler_metadata.listener.take() {
|
||||||
let res = port_handler.start_rejector(
|
port_handler.start_rejector(
|
||||||
port,
|
port,
|
||||||
listener,
|
listener,
|
||||||
Packet {
|
Packet {
|
||||||
@ -231,10 +234,6 @@ async fn connection_handler(
|
|||||||
data: b"nc\0".to_vec(),
|
data: b"nc\0".to_vec(),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Err(error) = res {
|
|
||||||
error!(%port, %error, "failed to start rejector");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,12 +108,14 @@ pub struct RemConnect {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Packet {
|
impl Packet {
|
||||||
|
#[allow(clippy::missing_errors_doc)]
|
||||||
pub async fn peek_packet_kind(stream: &mut ReadHalf<'_>) -> std::io::Result<PacketKind> {
|
pub async fn peek_packet_kind(stream: &mut ReadHalf<'_>) -> std::io::Result<PacketKind> {
|
||||||
Self::peek_packet_kind_raw(stream)
|
Self::peek_packet_kind_raw(stream)
|
||||||
.await
|
.await
|
||||||
.map(PacketKind::from_u8)
|
.map(PacketKind::from_u8)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::missing_errors_doc)]
|
||||||
pub async fn peek_packet_kind_raw(stream: &mut ReadHalf<'_>) -> std::io::Result<u8> {
|
pub async fn peek_packet_kind_raw(stream: &mut ReadHalf<'_>) -> std::io::Result<u8> {
|
||||||
let mut kind = 0;
|
let mut kind = 0;
|
||||||
let n = stream.peek(std::slice::from_mut(&mut kind)).await?;
|
let n = stream.peek(std::slice::from_mut(&mut kind)).await?;
|
||||||
@ -125,6 +127,7 @@ impl Packet {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::missing_errors_doc)]
|
||||||
pub async fn recv_into_cancelation_safe(
|
pub async fn recv_into_cancelation_safe(
|
||||||
&mut self,
|
&mut self,
|
||||||
stream: &mut ReadHalf<'_>,
|
stream: &mut ReadHalf<'_>,
|
||||||
@ -139,6 +142,7 @@ impl Packet {
|
|||||||
self.recv_into(stream).await
|
self.recv_into(stream).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::missing_errors_doc)]
|
||||||
pub async fn recv_into(&mut self, stream: &mut ReadHalf<'_>) -> std::io::Result<()> {
|
pub async fn recv_into(&mut self, stream: &mut ReadHalf<'_>) -> std::io::Result<()> {
|
||||||
let header_bytes = bytemuck::bytes_of_mut(&mut self.header);
|
let header_bytes = bytemuck::bytes_of_mut(&mut self.header);
|
||||||
|
|
||||||
@ -151,6 +155,7 @@ impl Packet {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::missing_errors_doc)]
|
||||||
pub async fn send(&self, stream: &mut WriteHalf<'_>) -> std::io::Result<()> {
|
pub async fn send(&self, stream: &mut WriteHalf<'_>) -> std::io::Result<()> {
|
||||||
stream.write_all(bytemuck::bytes_of(&self.header)).await?;
|
stream.write_all(bytemuck::bytes_of(&self.header)).await?;
|
||||||
stream.write_all(&self.data).await?;
|
stream.write_all(&self.data).await?;
|
||||||
@ -162,6 +167,8 @@ impl Packet {
|
|||||||
PacketKind::from_u8(self.header.kind)
|
PacketKind::from_u8(self.header.kind)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// # Errors
|
||||||
|
/// the packet must be a `RemConnect` packet and must contain at least 6 bytes of data
|
||||||
pub fn as_rem_connect(&self) -> anyhow::Result<RemConnect> {
|
pub fn as_rem_connect(&self) -> anyhow::Result<RemConnect> {
|
||||||
if self.kind() != PacketKind::RemConnect {
|
if self.kind() != PacketKind::RemConnect {
|
||||||
bail!("Unexpected Packet: {:?} expected RemConnect", self.kind());
|
bail!("Unexpected Packet: {:?} expected RemConnect", self.kind());
|
||||||
|
18
src/ports.rs
18
src/ports.rs
@ -278,7 +278,8 @@ impl PortHandler {
|
|||||||
.expect("failed to notify cache writer");
|
.expect("failed to notify cache writer");
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn store(&self, cache: &Path) -> anyhow::Result<()> {
|
#[allow(clippy::missing_errors_doc)]
|
||||||
|
pub fn store(&self, cache: &Path) -> std::io::Result<()> {
|
||||||
debug!("storing cache");
|
debug!("storing cache");
|
||||||
let temp_file = cache.with_extension(".temp");
|
let temp_file = cache.with_extension(".temp");
|
||||||
|
|
||||||
@ -288,6 +289,7 @@ impl PortHandler {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::missing_errors_doc)]
|
||||||
pub fn load(
|
pub fn load(
|
||||||
cache: &Path,
|
cache: &Path,
|
||||||
change_sender: tokio::sync::watch::Sender<Instant>,
|
change_sender: tokio::sync::watch::Sender<Instant>,
|
||||||
@ -344,12 +346,7 @@ impl PortHandler {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn start_rejector(
|
pub fn start_rejector(&mut self, port: Port, listener: TcpListener, packet: Packet) {
|
||||||
&mut self,
|
|
||||||
port: Port,
|
|
||||||
listener: TcpListener,
|
|
||||||
packet: Packet,
|
|
||||||
) -> anyhow::Result<()> {
|
|
||||||
info!(port, ?packet, "starting rejector");
|
info!(port, ?packet, "starting rejector");
|
||||||
|
|
||||||
let port_guard = Rejector::start(listener, packet);
|
let port_guard = Rejector::start(listener, packet);
|
||||||
@ -357,7 +354,6 @@ impl PortHandler {
|
|||||||
if self.port_guards.insert(port, port_guard).is_some() {
|
if self.port_guards.insert(port, port_guard).is_some() {
|
||||||
unreachable!("Tried to start rejector that is already running. This should have been impossible since it requires two listeners on the same port.");
|
unreachable!("Tried to start rejector that is already running. This should have been impossible since it requires two listeners on the same port.");
|
||||||
}
|
}
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn stop_rejector(&mut self, port: Port) -> Option<(TcpListener, Packet)> {
|
pub async fn stop_rejector(&mut self, port: Port) -> Option<(TcpListener, Packet)> {
|
||||||
@ -366,6 +362,8 @@ impl PortHandler {
|
|||||||
Some(self.port_guards.remove(&port)?.stop().await)
|
Some(self.port_guards.remove(&port)?.stop().await)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// # Errors
|
||||||
|
/// - the rejector must be running
|
||||||
pub async fn change_rejector(
|
pub async fn change_rejector(
|
||||||
&mut self,
|
&mut self,
|
||||||
port: Port,
|
port: Port,
|
||||||
@ -378,7 +376,9 @@ impl PortHandler {
|
|||||||
|
|
||||||
f(&mut packet);
|
f(&mut packet);
|
||||||
|
|
||||||
self.start_rejector(port, listener, packet)
|
self.start_rejector(port, listener, packet);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user