make dyn-ip server configurable
This commit is contained in:
parent
5b3c13e86d
commit
4e7fb3b444
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,2 +1,3 @@
|
|||||||
/target
|
/target
|
||||||
cache.json
|
cache.json
|
||||||
|
config.json
|
||||||
|
@ -1,8 +0,0 @@
|
|||||||
{
|
|
||||||
"allowed_ports": [
|
|
||||||
[
|
|
||||||
3000,
|
|
||||||
3005
|
|
||||||
]
|
|
||||||
]
|
|
||||||
}
|
|
51
src/main.rs
51
src/main.rs
@ -5,7 +5,7 @@ use std::{
|
|||||||
fmt::Debug,
|
fmt::Debug,
|
||||||
fs::File,
|
fs::File,
|
||||||
io::{BufReader, BufWriter},
|
io::{BufReader, BufWriter},
|
||||||
net::{IpAddr, SocketAddr},
|
net::{IpAddr, SocketAddr, ToSocketAddrs},
|
||||||
ops::Range,
|
ops::Range,
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
sync::Arc,
|
sync::Arc,
|
||||||
@ -14,7 +14,7 @@ use std::{
|
|||||||
|
|
||||||
use anyhow::{anyhow, bail};
|
use anyhow::{anyhow, bail};
|
||||||
use packets::{Header, Packet, RemConnect};
|
use packets::{Header, Packet, RemConnect};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Deserializer, Serialize};
|
||||||
use tokio::{
|
use tokio::{
|
||||||
io::AsyncWriteExt,
|
io::AsyncWriteExt,
|
||||||
net::{TcpListener, TcpStream},
|
net::{TcpListener, TcpStream},
|
||||||
@ -42,23 +42,32 @@ type Port = u16;
|
|||||||
type Number = u32;
|
type Number = u32;
|
||||||
type UnixTimestamp = u64;
|
type UnixTimestamp = u64;
|
||||||
|
|
||||||
#[derive(Default, Debug, Serialize, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
struct Config {
|
struct Config {
|
||||||
allowed_ports: AllowedPorts,
|
allowed_ports: AllowedPorts,
|
||||||
|
#[serde(deserialize_with = "parse_socket_addr")]
|
||||||
|
dyn_ip_server: SocketAddr,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_socket_addr<'de, D>(deserializer: D) -> Result<SocketAddr, D::Error>
|
||||||
|
where
|
||||||
|
D: Deserializer<'de>,
|
||||||
|
{
|
||||||
|
use serde::de::Error;
|
||||||
|
|
||||||
|
let addr = String::deserialize(deserializer)?
|
||||||
|
.to_socket_addrs()
|
||||||
|
.map_err(|err| D::Error::custom(err))?
|
||||||
|
.next()
|
||||||
|
.ok_or_else(|| D::Error::invalid_length(0, &"one or more"))?;
|
||||||
|
|
||||||
|
Ok(addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Config {
|
impl Config {
|
||||||
fn load(cache: &Path) -> std::io::Result<Self> {
|
fn load(path: impl AsRef<Path>) -> std::io::Result<Self> {
|
||||||
println!("loading config");
|
println!("loading config");
|
||||||
Ok(serde_json::from_reader(BufReader::new(File::open(cache)?))?)
|
Ok(serde_json::from_reader(BufReader::new(File::open(path)?))?)
|
||||||
}
|
|
||||||
|
|
||||||
fn load_or_default(cache: &Path) -> std::io::Result<Self> {
|
|
||||||
match Self::load(cache) {
|
|
||||||
Ok(cache) => Ok(cache),
|
|
||||||
Err(err) if err.kind() == std::io::ErrorKind::NotFound => Ok(Self::default()),
|
|
||||||
Err(err) => Err(err),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -364,6 +373,7 @@ struct HandlerMetadata {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn connection_handler(
|
async fn connection_handler(
|
||||||
|
config: &Config,
|
||||||
handler_metadata: &mut HandlerMetadata,
|
handler_metadata: &mut HandlerMetadata,
|
||||||
port_handler: &Mutex<PortHandler>,
|
port_handler: &Mutex<PortHandler>,
|
||||||
stream: &mut TcpStream,
|
stream: &mut TcpStream,
|
||||||
@ -397,8 +407,9 @@ async fn connection_handler(
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// make sure the client is authenticated before opening any ports
|
||||||
if !authenticated {
|
if !authenticated {
|
||||||
let _ip = dyn_ip_update(number, pin, port).await?;
|
let _ip = dyn_ip_update(&config.dyn_ip_server, number, pin, port).await?;
|
||||||
authenticated = true;
|
authenticated = true;
|
||||||
updated_server = true;
|
updated_server = true;
|
||||||
}
|
}
|
||||||
@ -417,8 +428,11 @@ async fn connection_handler(
|
|||||||
// 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
|
||||||
|
// we need to update the server here once a port that can be opened
|
||||||
|
// has been found
|
||||||
if !updated_server {
|
if !updated_server {
|
||||||
let _ip = dyn_ip_update(number, pin, port).await?;
|
let _ip = dyn_ip_update(&config.dyn_ip_server, number, pin, port).await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
port_handler
|
port_handler
|
||||||
@ -626,7 +640,7 @@ async fn connection_handler(
|
|||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> anyhow::Result<()> {
|
async fn main() -> anyhow::Result<()> {
|
||||||
let config = Config::load_or_default("config.json".as_ref())?;
|
let config = Arc::new(Config::load("config.json")?);
|
||||||
|
|
||||||
if config.allowed_ports.0.is_empty() {
|
if config.allowed_ports.0.is_empty() {
|
||||||
panic!("no allowed ports");
|
panic!("no allowed ports");
|
||||||
@ -668,11 +682,14 @@ async fn main() -> anyhow::Result<()> {
|
|||||||
println!("connection from {addr}");
|
println!("connection from {addr}");
|
||||||
|
|
||||||
let port_handler = port_handler.clone();
|
let port_handler = port_handler.clone();
|
||||||
|
let config = config.clone();
|
||||||
|
|
||||||
let mut handler_metadata = HandlerMetadata::default();
|
let mut handler_metadata = HandlerMetadata::default();
|
||||||
|
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
let res = connection_handler(&mut handler_metadata, &port_handler, &mut stream).await;
|
let res =
|
||||||
|
connection_handler(&config, &mut handler_metadata, &port_handler, &mut stream)
|
||||||
|
.await;
|
||||||
|
|
||||||
if let Err(err) = res {
|
if let Err(err) = res {
|
||||||
println!("client at {addr} had an error: {err}");
|
println!("client at {addr} had an error: {err}");
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
use std::net::SocketAddr;
|
||||||
|
|
||||||
use anyhow::bail;
|
use anyhow::bail;
|
||||||
use bytemuck::{Pod, Zeroable};
|
use bytemuck::{Pod, Zeroable};
|
||||||
use tokio::{
|
use tokio::{
|
||||||
@ -156,7 +158,12 @@ impl Packet {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn dyn_ip_update(number: u32, pin: u16, port: u16) -> anyhow::Result<std::net::Ipv4Addr> {
|
pub async fn dyn_ip_update(
|
||||||
|
server: &SocketAddr,
|
||||||
|
number: u32,
|
||||||
|
pin: u16,
|
||||||
|
port: u16,
|
||||||
|
) -> anyhow::Result<std::net::Ipv4Addr> {
|
||||||
println!("dyn ip update: number={number} port={port}...");
|
println!("dyn ip update: number={number} port={port}...");
|
||||||
|
|
||||||
let mut packet = Packet::default();
|
let mut packet = Packet::default();
|
||||||
@ -171,7 +178,7 @@ pub async fn dyn_ip_update(number: u32, pin: u16, port: u16) -> anyhow::Result<s
|
|||||||
packet.data.extend_from_slice(&pin.to_le_bytes());
|
packet.data.extend_from_slice(&pin.to_le_bytes());
|
||||||
packet.data.extend_from_slice(&port.to_le_bytes());
|
packet.data.extend_from_slice(&port.to_le_bytes());
|
||||||
|
|
||||||
let mut socket = tokio::net::TcpStream::connect(("127.0.0.1", 11811)).await?;
|
let mut socket = tokio::net::TcpStream::connect(server).await?;
|
||||||
|
|
||||||
let (mut reader, mut writer) = socket.split();
|
let (mut reader, mut writer) = socket.split();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user