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.rs40
1 files changed, 28 insertions, 12 deletions
diff --git a/src/stun_actor.rs b/src/stun_actor.rs
index b112bb0..6740c83 100644
--- a/src/stun_actor.rs
+++ b/src/stun_actor.rs
@@ -1,4 +1,4 @@
-use std::net::{IpAddr, SocketAddr};
+use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr};
use std::time::{Duration, SystemTime};
use anyhow::{anyhow, bail, Result};
@@ -60,20 +60,23 @@ impl StunActor {
}
async fn autodiscover_ip(&self, stun_server: SocketAddr) -> Result<()> {
- let binding_addr = match stun_server.is_ipv4() {
- true => "0.0.0.0:34791".parse().unwrap(),
- false => "[::]:34792".parse().unwrap(),
+ let binding_ip = match stun_server.is_ipv4() {
+ true => IpAddr::V4(Ipv4Addr::UNSPECIFIED), // 0.0.0.0
+ false => IpAddr::V6(Ipv6Addr::UNSPECIFIED), // [::]
};
+ let binding_addr = SocketAddr::new(binding_ip, 0);
- let discovered_addr = get_mapped_addr(stun_server, binding_addr).await?.ip();
+ let discovered_addr = get_mapped_addr(stun_server, binding_addr)
+ .await?
+ .map(|x| x.ip());
let consul_key = match stun_server.is_ipv4() {
true => {
- debug!("Autodiscovered IPv4: {}", discovered_addr);
+ debug!("Autodiscovered IPv4: {:?}", discovered_addr);
format!("diplonat/autodiscovery/ipv4/{}", self.node)
}
false => {
- debug!("Autodiscovered IPv6: {}", discovered_addr);
+ debug!("Autodiscovered IPv6: {:?}", discovered_addr);
format!("diplonat/autodiscovery/ipv6/{}", self.node)
}
};
@@ -83,7 +86,7 @@ impl StunActor {
&consul_key,
serde_json::to_vec(&AutodiscoverResult {
timestamp: timestamp(),
- address: Some(discovered_addr),
+ address: discovered_addr,
})?,
)
.await?;
@@ -108,11 +111,23 @@ impl StunActor {
}
}
-async fn get_mapped_addr(stun_server: SocketAddr, binding_addr: SocketAddr) -> Result<SocketAddr> {
+async fn get_mapped_addr(
+ stun_server: SocketAddr,
+ binding_addr: SocketAddr,
+) -> Result<Option<SocketAddr>> {
use stun_client::*;
- let mut client = Client::new(binding_addr, None).await.unwrap();
- let res = client.binding_request(stun_server, None).await.unwrap();
+ let mut client = Client::new(binding_addr, None).await?;
+ let res = match client.binding_request(stun_server, None).await {
+ Err(e) => {
+ info!(
+ "STUN binding request to {} failed, assuming no address (error: {})",
+ binding_addr, e
+ );
+ return Ok(None);
+ }
+ Ok(r) => r,
+ };
if res.get_class() != Class::SuccessResponse {
bail!("STUN server did not responde with a success response");
@@ -120,7 +135,8 @@ async fn get_mapped_addr(stun_server: SocketAddr, binding_addr: SocketAddr) -> R
let xor_mapped_addr = Attribute::get_xor_mapped_address(&res)
.ok_or(anyhow!("no XorMappedAddress found in STUN response"))?;
- Ok(xor_mapped_addr)
+
+ Ok(Some(xor_mapped_addr))
}
fn timestamp() -> u64 {