Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

change: use DERP port from host_name URL #1143

Merged
merged 5 commits into from
Jul 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 1 addition & 14 deletions iroh-net/examples/magic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,20 +52,7 @@ async fn main() -> anyhow::Result<()> {

let derp_map = match args.derp_url {
None => default_derp_map(),
Some(url) => {
// TODO: This should be done by the DERP client.
let derp_port = match url.port() {
Some(port) => port,
None => match url.scheme() {
"http" => 80,
"https" => 443,
_ => anyhow::bail!(
"Invalid scheme in DERP URL, only http: and https: schemes are supported."
),
},
};
DerpMap::default_from_node(url, 3478, derp_port, UseIpv4::None, UseIpv6::None)
}
Some(url) => DerpMap::default_from_node(url, 3478, UseIpv4::None, UseIpv6::None),
};

let endpoint = MagicEndpoint::builder()
Expand Down
3 changes: 1 addition & 2 deletions iroh-net/src/defaults.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,11 @@ pub fn default_derp_region() -> DerpRegion {
let default_n0_derp = DerpNode {
name: "default-1".into(),
region_id: 1,
host_name: "https://derp.iroh.network".parse().unwrap(),
url: "https://derp.iroh.network".parse().unwrap(),
stun_only: false,
stun_port: 3478,
ipv4: UseIpv4::Some([35, 175, 99, 113].into()),
ipv6: UseIpv6::None,
derp_port: 443,
stun_test_ip: None,
};
DerpRegion {
Expand Down
6 changes: 2 additions & 4 deletions iroh-net/src/hp/derp/http.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,13 +80,12 @@ mod tests {
nodes: vec![DerpNode {
name: "test_node".to_string(),
region_id: 1,
host_name: "http://localhost".parse().unwrap(),
url: format!("http://localhost:{port}").parse().unwrap(),
stun_only: false,
stun_port: 0,
stun_test_ip: None,
ipv4: UseIpv4::Some(addr),
ipv6: UseIpv6::Disabled,
derp_port: port,
}],
region_code: "test_region".to_string(),
};
Expand Down Expand Up @@ -221,13 +220,12 @@ mod tests {
nodes: vec![DerpNode {
name: "test_node".to_string(),
region_id: 1,
host_name: "https://localhost".parse().unwrap(),
url: format!("https://localhost:{port}").parse().unwrap(),
stun_only: false,
stun_port: 0,
stun_test_ip: None,
ipv4: UseIpv4::Some(addr),
ipv6: UseIpv6::Disabled,
derp_port: port,
}],
region_code: "test_region".to_string(),
};
Expand Down
23 changes: 14 additions & 9 deletions iroh-net/src/hp/derp/http/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,7 @@ impl Client {
.and_then(|s| rustls::ServerName::try_from(s).ok());
}
if let Some(node) = node {
if let Some(host) = node.host_name.host_str() {
if let Some(host) = node.url.host_str() {
return rustls::ServerName::try_from(host).ok();
}
}
Expand Down Expand Up @@ -380,7 +380,7 @@ impl Client {
return false;
}
if let Some(node) = node {
if node.host_name.scheme() == "http" {
if node.url.scheme() == "http" {
return false;
}
}
Expand Down Expand Up @@ -664,7 +664,7 @@ impl Client {
UseIp::Ipv6(UseIpv6::Some(addr)) => addr.into(),
_ => {
let host = node
.host_name
.url
.host()
.ok_or_else(|| ClientError::InvalidUrl("missing host".into()))?;
match host {
Expand All @@ -683,10 +683,16 @@ impl Client {
}
}
};
let port = if node.derp_port != 0 {
node.derp_port
} else {
443
let port = match node.url.port() {
Some(port) => port,
None => match node.url.scheme() {
"http" => 80,
"https" => 443,
_ => return Err(ClientError::InvalidUrl(
"Invalid scheme in DERP hostname, only http: and https: schemes are supported."
.into(),
)),
},
};
let dst = format!("{host}:{port}");
debug!("dialing {}", dst);
Expand Down Expand Up @@ -1123,13 +1129,12 @@ mod tests {
nodes: vec![DerpNode {
name: "test_node".to_string(),
region_id: 1,
host_name: "http://bad.url".parse().unwrap(),
url: "https://bad.url".parse().unwrap(),
stun_only: false,
stun_port: 0,
stun_test_ip: None,
ipv4: UseIpv4::Some("35.175.99.112".parse().unwrap()),
ipv6: UseIpv6::Disabled,
derp_port: 443,
}],
region_code: "test_region".to_string(),
};
Expand Down
2 changes: 1 addition & 1 deletion iroh-net/src/hp/derp/http/mesh_clients.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ impl MeshClients {
for (_, region) in derp_map.regions.iter() {
for node in region.nodes.iter() {
// note: `node.host_name` is expected to include the scheme
let mut url = node.host_name.clone();
let mut url = node.url.clone();
url.set_path("/derp");
urls.push(url);
}
Expand Down
9 changes: 3 additions & 6 deletions iroh-net/src/hp/derp/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,8 @@ impl DerpMap {

/// Creates a new [`DerpMap`] with a single Derp server configured.
pub fn default_from_node(
host_name: Url,
url: Url,
stun_port: u16,
derp_port: u16,
derp_ipv4: UseIpv4,
derp_ipv6: UseIpv6,
) -> Self {
Expand All @@ -42,12 +41,11 @@ impl DerpMap {
nodes: vec![DerpNode {
name: "default-1".into(),
region_id: 1,
host_name,
url,
stun_only: !derp_ipv4.is_enabled() && !derp_ipv6.is_enabled(),
stun_port,
ipv4: derp_ipv4,
ipv6: derp_ipv6,
derp_port,
stun_test_ip: None,
}],
avoid: false,
Expand Down Expand Up @@ -79,7 +77,7 @@ pub struct DerpRegion {
pub struct DerpNode {
pub name: String,
pub region_id: u16,
pub host_name: Url,
pub url: Url,
pub stun_only: bool,
pub stun_port: u16,
pub stun_test_ip: Option<IpAddr>,
Expand All @@ -91,7 +89,6 @@ pub struct DerpNode {
/// If `None`, A record(s) from DNS lookups of HostName are used.
/// If `Disabled`, IPv6 is not used;
pub ipv6: UseIpv6,
pub derp_port: u16,
}

#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
Expand Down
8 changes: 5 additions & 3 deletions iroh-net/src/hp/magicsock/conn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2654,13 +2654,15 @@ pub(crate) mod tests {
nodes: vec![DerpNode {
name: "t1".into(),
region_id: 1,
host_name: "https://test-node.invalid".parse().unwrap(),
// In test mode, the DERP client does not validate HTTPS certs, so the host
// name is irrelevant, but the port is used.
url: format!("https://test-node.invalid:{}", https_addr.port())
.parse()
.unwrap(),
stun_only: false,
stun_port: stun_addr.port(),
ipv4: UseIpv4::Some("127.0.0.1".parse().unwrap()),
ipv6: UseIpv6::None,

derp_port: https_addr.port(),
stun_test_ip: Some(stun_addr.ip()),
}],
avoid: false,
Expand Down
13 changes: 6 additions & 7 deletions iroh-net/src/hp/netcheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ async fn check_captive_portal(dm: &DerpMap, preferred_derp: Option<u16>) -> Resu
let node = &dm.regions.get(&preferred_derp).unwrap().nodes[0];

if node
.host_name
.url
.host_str()
.map(|s| s.ends_with(&DOT_INVALID))
.unwrap_or_default()
Expand All @@ -354,7 +354,7 @@ async fn check_captive_portal(dm: &DerpMap, preferred_derp: Option<u16>) -> Resu
// length is limited; see is_challenge_char in bin/derper for more
// details.

let host_name = node.host_name.host_str().unwrap_or_default();
let host_name = node.url.host_str().unwrap_or_default();
let challenge = format!("ts_{}", host_name);
let portal_url = format!("http://{}/generate_204", host_name);
let res = client
Expand Down Expand Up @@ -453,7 +453,7 @@ async fn get_node_addr(n: &DerpNode, proto: ProbeProto) -> Result<SocketAddr> {
}
}

match n.host_name.host() {
match n.url.host() {
Some(url::Host::Domain(hostname)) => {
async move {
debug!(?proto, %hostname, "Performing DNS lookup for derp addr");
Expand Down Expand Up @@ -1788,7 +1788,7 @@ mod tests {
.await
.context("failed to create netcheck client")?;

let stun_servers = vec![("https://derp.iroh.network.", 3478, 0)];
let stun_servers = vec![("https://derp.iroh.network.", 3478)];

let mut dm = DerpMap::default();
dm.regions.insert(
Expand All @@ -1798,15 +1798,14 @@ mod tests {
nodes: stun_servers
.into_iter()
.enumerate()
.map(|(i, (host_name, stun_port, derp_port))| DerpNode {
.map(|(i, (host_name, stun_port))| DerpNode {
name: format!("default-{}", i),
region_id: 1,
host_name: host_name.parse().unwrap(),
url: host_name.parse().unwrap(),
stun_only: true,
stun_port,
ipv4: UseIpv4::None,
ipv6: UseIpv6::None,
derp_port,
stun_test_ip: None,
})
.collect(),
Expand Down
3 changes: 1 addition & 2 deletions iroh-net/src/hp/stun.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,13 +178,12 @@ pub mod test {
let node = DerpNode {
name: format!("{region_id}a"),
region_id,
host_name: format!("http://{region_id}.invalid").parse().unwrap(),
url: format!("http://{region_id}.invalid").parse().unwrap(),
ipv4,
ipv6,
stun_port: port,
stun_only: true,
stun_test_ip: None,
derp_port: 0,
};
m.regions.insert(
region_id,
Expand Down
9 changes: 4 additions & 5 deletions iroh/src/commands/doctor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -195,9 +195,9 @@ async fn report(stun_host: Option<String>, stun_port: u16, config: &Config) -> a

let dm = match stun_host {
Some(host_name) => {
let host_name = host_name.parse()?;
let url = host_name.parse()?;
// creating a derp map from host name and stun port
DerpMap::default_from_node(host_name, stun_port, 0, UseIpv4::None, UseIpv6::None)
DerpMap::default_from_node(url, stun_port, UseIpv4::None, UseIpv6::None)
}
None => config.derp_map().expect("derp map not configured"),
};
Expand Down Expand Up @@ -434,11 +434,10 @@ async fn passive_side(connection: quinn::Connection) -> anyhow::Result<()> {

fn configure_local_derp_map() -> DerpMap {
let stun_port = 3478;
let host_name = "http://derp.invalid".parse().unwrap();
let derp_port = 3340;
let url = "http://derp.invalid:3340".parse().unwrap();
let derp_ipv4 = UseIpv4::Some("127.0.0.1".parse().unwrap());
let derp_ipv6 = UseIpv6::None;
DerpMap::default_from_node(host_name, stun_port, derp_port, derp_ipv4, derp_ipv6)
DerpMap::default_from_node(url, stun_port, derp_ipv4, derp_ipv6)
}

const DR_DERP_ALPN: [u8; 11] = *b"n0/drderp/1";
Expand Down