STUN actor: try to avoid ip address flapping #21
2 changed files with 28 additions and 9 deletions
|
@ -1,5 +1,4 @@
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
use anyhow::{Context, Result};
|
use anyhow::{Context, Result};
|
||||||
use iptables;
|
use iptables;
|
||||||
|
|
|
@ -8,6 +8,11 @@ use serde::{Deserialize, Serialize};
|
||||||
use crate::config::{RuntimeConfigConsul, RuntimeConfigStun};
|
use crate::config::{RuntimeConfigConsul, RuntimeConfigStun};
|
||||||
use crate::consul;
|
use crate::consul;
|
||||||
|
|
||||||
|
/// If autodiscovery returns None but an address was obtained less than
|
||||||
|
/// this number of seconds ago (here 15 minutes), we keep that address
|
||||||
|
/// in the Consul db instead of insterting a None.
|
||||||
|
const PERSIST_SOME_RESULT_DURATION_SECS: u64 = 900;
|
||||||
|
|
||||||
pub struct StunActor {
|
pub struct StunActor {
|
||||||
consul: consul::Consul,
|
consul: consul::Consul,
|
||||||
refresh_time: Duration,
|
refresh_time: Duration,
|
||||||
|
@ -78,7 +83,7 @@ impl StunActor {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StunAutodiscovery {
|
impl StunAutodiscovery {
|
||||||
async fn do_iteration(&self, consul: &consul::Consul) -> Result<()> {
|
async fn do_iteration(&mut self, consul: &consul::Consul) -> Result<()> {
|
||||||
let binding_ip = match self.is_ipv4 {
|
let binding_ip = match self.is_ipv4 {
|
||||||
true => IpAddr::V4(Ipv4Addr::UNSPECIFIED), // 0.0.0.0
|
true => IpAddr::V4(Ipv4Addr::UNSPECIFIED), // 0.0.0.0
|
||||||
false => IpAddr::V6(Ipv6Addr::UNSPECIFIED), // [::]
|
false => IpAddr::V6(Ipv6Addr::UNSPECIFIED), // [::]
|
||||||
|
@ -96,16 +101,31 @@ impl StunAutodiscovery {
|
||||||
None => None,
|
None => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let now = timestamp();
|
||||||
|
|
||||||
|
if discovered_addr.is_none() {
|
||||||
|
if let Some(last_result) = &self.last_result {
|
||||||
|
if last_result.address.is_some()
|
||||||
|
&& now - last_result.timestamp <= PERSIST_SOME_RESULT_DURATION_SECS
|
||||||
|
{
|
||||||
|
// Keep non-None result that was obtained before by not
|
||||||
|
// writing/taking into account None result.
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let current_result = AutodiscoverResult {
|
||||||
|
timestamp: now,
|
||||||
|
address: discovered_addr,
|
||||||
|
};
|
||||||
|
|
||||||
consul
|
consul
|
||||||
.kv_put(
|
.kv_put(&self.consul_key, serde_json::to_vec(¤t_result)?)
|
||||||
&self.consul_key,
|
|
||||||
serde_json::to_vec(&AutodiscoverResult {
|
|
||||||
timestamp: timestamp(),
|
|
||||||
address: discovered_addr,
|
|
||||||
})?,
|
|
||||||
)
|
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
self.last_result = Some(current_result);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue