feat: dial hint on Address for hosts that resolve DNS themselves
This commit is contained in:
parent
45987fe03d
commit
5559fcce31
2 changed files with 44 additions and 1 deletions
|
|
@ -35,6 +35,13 @@ pub struct Address {
|
||||||
pub port: u16,
|
pub port: u16,
|
||||||
pub scheme: Scheme,
|
pub scheme: Scheme,
|
||||||
pub identity: Option<[u8; KEY_LEN]>,
|
pub identity: Option<[u8; KEY_LEN]>,
|
||||||
|
/// Where to dial instead of resolving `host` again: an embedder that
|
||||||
|
/// resolves DNS itself (an Android app, whose native getaddrinfo can be
|
||||||
|
/// dead while the platform resolver works) sets the address's IP here.
|
||||||
|
/// The hostname keeps every identity role — pins, PoP, display — so
|
||||||
|
/// `dial` is purely a routing hint, and `None` (the default) means
|
||||||
|
/// fumi resolves `host` itself.
|
||||||
|
pub dial: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Address {
|
impl Address {
|
||||||
|
|
@ -53,6 +60,15 @@ impl Address {
|
||||||
format!("{}{}/{}", self.scheme.prefix(), self.short(), b32(identity))
|
format!("{}{}/{}", self.scheme.prefix(), self.short(), b32(identity))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Routing hint: dial this address instead of resolving `host`. The
|
||||||
|
/// hostname is untouched — pins, proof-of-possession and display all
|
||||||
|
/// keep using it, so a dial override changes where the packets go and
|
||||||
|
/// nothing about who the server is.
|
||||||
|
pub fn with_dial(mut self, dial: &str) -> Address {
|
||||||
|
self.dial = Some(dial.to_string());
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// The Reticulum destination hash, for the `rns` carrier only.
|
/// The Reticulum destination hash, for the `rns` carrier only.
|
||||||
pub fn destination(&self) -> Result<[u8; 16], Error> {
|
pub fn destination(&self) -> Result<[u8; 16], Error> {
|
||||||
if self.scheme != Scheme::Rns {
|
if self.scheme != Scheme::Rns {
|
||||||
|
|
@ -109,6 +125,7 @@ impl Address {
|
||||||
port,
|
port,
|
||||||
scheme,
|
scheme,
|
||||||
identity,
|
identity,
|
||||||
|
dial: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Scheme::Rns => {
|
Scheme::Rns => {
|
||||||
|
|
@ -131,6 +148,7 @@ impl Address {
|
||||||
port: 0,
|
port: 0,
|
||||||
scheme,
|
scheme,
|
||||||
identity,
|
identity,
|
||||||
|
dial: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
@ -197,6 +215,23 @@ fn valid_username(name: &str) -> Result<(), Error> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn dial_hint_routes_without_renaming() {
|
||||||
|
let addr = Address::parse("alice@example.org:1961")
|
||||||
|
.unwrap()
|
||||||
|
.with_dial("192.0.2.10");
|
||||||
|
// The hint changes where packets go, never who the server is: pins,
|
||||||
|
// proof-of-possession and display all read `host`.
|
||||||
|
assert_eq!(addr.dial.as_deref(), Some("192.0.2.10"));
|
||||||
|
assert_eq!(addr.host, "example.org");
|
||||||
|
assert_eq!(addr.short(), "alice@example.org:1961");
|
||||||
|
assert_eq!(Address::parse("alice@example.org").unwrap().dial, None);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::crypto::b32;
|
use crate::crypto::b32;
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,15 @@ pub fn connect(
|
||||||
host: addr.host.clone(),
|
host: addr.host.clone(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
let transport = TcpTransport::connect(&addr.host, addr.port, pinned, timeout)?;
|
// The dial hint lets a host that resolves DNS itself (an
|
||||||
|
// Android app) reach the server by IP while `host` keeps its
|
||||||
|
// identity roles.
|
||||||
|
let transport = TcpTransport::connect(
|
||||||
|
addr.dial.as_deref().unwrap_or(&addr.host),
|
||||||
|
addr.port,
|
||||||
|
pinned,
|
||||||
|
timeout,
|
||||||
|
)?;
|
||||||
let unpinned_static = if pinned.is_none() {
|
let unpinned_static = if pinned.is_none() {
|
||||||
Some(*transport.server_static())
|
Some(*transport.server_static())
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue