aboutsummaryrefslogtreecommitdiff
path: root/src/stun_actor.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/stun_actor.rs')
-rw-r--r--src/stun_actor.rs44
1 files changed, 36 insertions, 8 deletions
diff --git a/src/stun_actor.rs b/src/stun_actor.rs
index 684d3d8..b112bb0 100644
--- a/src/stun_actor.rs
+++ b/src/stun_actor.rs
@@ -11,7 +11,7 @@ use crate::consul;
pub struct StunActor {
node: String,
consul: consul::Consul,
- stun_server_v4: SocketAddr,
+ stun_server_v4: Option<SocketAddr>,
stun_server_v6: SocketAddr,
refresh_time: Duration,
}
@@ -19,7 +19,7 @@ pub struct StunActor {
#[derive(Serialize, Deserialize, Debug)]
pub struct AutodiscoverResult {
pub timestamp: u64,
- pub address: IpAddr,
+ pub address: Option<IpAddr>,
}
impl StunActor {
@@ -28,7 +28,10 @@ impl StunActor {
stun_config: &RuntimeConfigStun,
node: &str,
) -> Self {
- assert!(stun_config.stun_server_v4.is_ipv4());
+ assert!(stun_config
+ .stun_server_v4
+ .map(|x| x.is_ipv4())
+ .unwrap_or(true));
assert!(stun_config.stun_server_v6.is_ipv6());
Self {
@@ -42,7 +45,11 @@ impl StunActor {
pub async fn listen(&mut self) -> Result<()> {
loop {
- if let Err(e) = self.autodiscover_ip(self.stun_server_v4).await {
+ let ipv4_result = match self.stun_server_v4 {
+ Some(stun_server_v4) => self.autodiscover_ip(stun_server_v4).await,
+ None => self.autodiscover_none_ipv4().await,
+ };
+ if let Err(e) = ipv4_result {
error!("Unable to autodiscover IPv4 address: {}", e);
}
if let Err(e) = self.autodiscover_ip(self.stun_server_v6).await {
@@ -75,10 +82,24 @@ impl StunActor {
.kv_put(
&consul_key,
serde_json::to_vec(&AutodiscoverResult {
- timestamp: SystemTime::now()
- .duration_since(SystemTime::UNIX_EPOCH)?
- .as_secs(),
- address: discovered_addr,
+ timestamp: timestamp(),
+ address: Some(discovered_addr),
+ })?,
+ )
+ .await?;
+
+ Ok(())
+ }
+
+ async fn autodiscover_none_ipv4(&self) -> Result<()> {
+ let consul_key = format!("diplonat/autodiscovery/ipv4/{}", self.node);
+
+ self.consul
+ .kv_put(
+ &consul_key,
+ serde_json::to_vec(&AutodiscoverResult {
+ timestamp: timestamp(),
+ address: None,
})?,
)
.await?;
@@ -101,3 +122,10 @@ async fn get_mapped_addr(stun_server: SocketAddr, binding_addr: SocketAddr) -> R
.ok_or(anyhow!("no XorMappedAddress found in STUN response"))?;
Ok(xor_mapped_addr)
}
+
+fn timestamp() -> u64 {
+ SystemTime::now()
+ .duration_since(SystemTime::UNIX_EPOCH)
+ .expect("clock error")
+ .as_secs()
+}