public IP address autodiscovery #20

Merged
lx merged 10 commits from stun into main 2023-04-21 09:56:22 +00:00
4 changed files with 36 additions and 23 deletions
Showing only changes of commit 2d39adcabb - Show all commits

View file

@ -5,7 +5,8 @@ mod runtime;
pub use options::{ConfigOpts, ConfigOptsAcme, ConfigOptsBase, ConfigOptsConsul};
pub use runtime::{
RuntimeConfig, RuntimeConfigAcme, RuntimeConfigConsul, RuntimeConfigFirewall, RuntimeConfigIgd, RuntimeConfigStun
RuntimeConfig, RuntimeConfigAcme, RuntimeConfigConsul, RuntimeConfigFirewall, RuntimeConfigIgd,
RuntimeConfigStun,
};
pub const EXPIRATION_TIME: u16 = 300;

View file

@ -1,7 +1,7 @@
use std::fs::File;
use std::io::Read;
use std::time::Duration;
use std::net::{SocketAddr, ToSocketAddrs};
use std::time::Duration;
use anyhow::{anyhow, bail, Result};
@ -165,7 +165,12 @@ impl RuntimeConfigStun {
pub(super) fn new(opts: &ConfigOptsBase) -> Result<Self> {
let mut stun_server_v4 = None;
let mut stun_server_v6 = None;
for addr in opts.stun_server.as_deref().unwrap_or(super::STUN_SERVER).to_socket_addrs()? {
for addr in opts
.stun_server
.as_deref()
.unwrap_or(super::STUN_SERVER)
.to_socket_addrs()?
{
if addr.is_ipv4() {
stun_server_v4 = Some(addr);
}
@ -177,8 +182,10 @@ impl RuntimeConfigStun {
let refresh_time = Duration::from_secs(opts.refresh_time.unwrap_or(super::REFRESH_TIME).into());
Ok(Self {
stun_server_v4: stun_server_v4.ok_or(anyhow!("Unable to resolve STUN server's IPv4 address"))?,
stun_server_v6: stun_server_v6.ok_or(anyhow!("Unable to resolve STUN server's IPv6 address"))?,
stun_server_v4: stun_server_v4
.ok_or(anyhow!("Unable to resolve STUN server's IPv4 address"))?,
stun_server_v6: stun_server_v6
.ok_or(anyhow!("Unable to resolve STUN server's IPv6 address"))?,
refresh_time,
})
}

View file

@ -30,11 +30,7 @@ impl Diplonat {
)
.await?;
let sa = StunActor::new(
&rt_cfg.consul,
&rt_cfg.stun,
&rt_cfg.consul.node_name,
);
let sa = StunActor::new(&rt_cfg.consul, &rt_cfg.stun, &rt_cfg.consul.node_name);
let ctx = Self {
consul: ca,

View file

@ -1,9 +1,9 @@
use std::net::{SocketAddr, IpAddr};
use std::net::{IpAddr, SocketAddr};
use std::time::{Duration, SystemTime};
use anyhow::{Result, bail, anyhow};
use anyhow::{anyhow, bail, Result};
use log::*;
use serde::{Serialize, Deserialize};
use serde::{Deserialize, Serialize};
use crate::config::{RuntimeConfigConsul, RuntimeConfigStun};
use crate::consul;
@ -23,7 +23,11 @@ pub struct AutodiscoverResult {
}
impl StunActor {
pub fn new(consul_config: &RuntimeConfigConsul, stun_config: &RuntimeConfigStun, node: &str) -> Self {
pub fn new(
consul_config: &RuntimeConfigConsul,
stun_config: &RuntimeConfigStun,
node: &str,
) -> Self {
assert!(stun_config.stun_server_v4.is_ipv4());
assert!(stun_config.stun_server_v6.is_ipv6());
@ -67,10 +71,18 @@ impl StunActor {
}
};
self.consul.kv_put(&consul_key, serde_json::to_vec(&AutodiscoverResult{
timestamp: SystemTime::now().duration_since(SystemTime::UNIX_EPOCH)?.as_secs(),
address: discovered_addr,
})?).await?;
self
.consul
.kv_put(
&consul_key,
serde_json::to_vec(&AutodiscoverResult {
timestamp: SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)?
.as_secs(),
address: discovered_addr,
})?,
)
.await?;
Ok(())
}
@ -80,16 +92,13 @@ async fn get_mapped_addr(stun_server: SocketAddr, binding_addr: SocketAddr) -> R
use stun_client::*;
let mut client = Client::new(binding_addr, None).await.unwrap();
let res = client
.binding_request(stun_server, None)
.await
.unwrap();
let res = client.binding_request(stun_server, None).await.unwrap();
if res.get_class() != Class::SuccessResponse {
bail!("STUN server did not responde with a success response");
}
let xor_mapped_addr = Attribute::get_xor_mapped_address(&res)
.ok_or(anyhow!("no XorMappedAddress found in STUN response"))?;
.ok_or(anyhow!("no XorMappedAddress found in STUN response"))?;
Ok(xor_mapped_addr)
}