Skip to content

Commit b6033dc

Browse files
relay compiles
1 parent d318241 commit b6033dc

File tree

13 files changed

+295
-187
lines changed

13 files changed

+295
-187
lines changed

iroh-relay/src/client.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,9 @@ use tracing::{debug, error, event, info_span, trace, warn, Instrument, Level};
3636
use url::Url;
3737

3838
use crate::{
39-
codec::DerpCodec,
4039
defaults::timeouts::*,
4140
http::{Protocol, RELAY_PATH},
41+
protos::relay::DerpCodec,
4242
RelayUrl,
4343
};
4444

iroh-relay/src/client/conn.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,11 @@ use tracing::{debug, info_span, trace, Instrument};
3030

3131
use crate::{
3232
client::streams::{MaybeTlsStreamReader, MaybeTlsStreamWriter},
33-
codec::{
33+
defaults::timeouts::CLIENT_RECV_TIMEOUT,
34+
protos::relay::{
3435
write_frame, ClientInfo, DerpCodec, Frame, MAX_PACKET_SIZE, PER_CLIENT_READ_QUEUE_DEPTH,
3536
PER_CLIENT_SEND_QUEUE_DEPTH, PROTOCOL_VERSION,
3637
},
37-
defaults::timeouts::CLIENT_RECV_TIMEOUT,
3838
};
3939

4040
impl PartialEq for Conn {
@@ -366,7 +366,8 @@ impl ConnBuilder {
366366
version: PROTOCOL_VERSION,
367367
};
368368
debug!("server_handshake: sending client_key: {:?}", &client_info);
369-
crate::codec::send_client_key(&mut self.writer, &self.secret_key, &client_info).await?;
369+
crate::protos::relay::send_client_key(&mut self.writer, &self.secret_key, &client_info)
370+
.await?;
370371

371372
// TODO: add some actual configuration
372373
let rate_limiter = RateLimiter::new(0, 0)?;

iroh-relay/src/dns.rs

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
use std::net::{IpAddr, Ipv6Addr};
2+
3+
use anyhow::Result;
4+
use hickory_resolver::{AsyncResolver, TokioAsyncResolver};
5+
use once_cell::sync::Lazy;
6+
7+
/// The DNS resolver type used throughout `iroh-net`.
8+
pub(crate) type DnsResolver = TokioAsyncResolver;
9+
10+
static DNS_RESOLVER: Lazy<TokioAsyncResolver> =
11+
Lazy::new(|| create_default_resolver().expect("unable to create DNS resolver"));
12+
13+
/// Get a reference to the default DNS resolver.
14+
///
15+
/// The default resolver can be cheaply cloned and is shared throughout the running process.
16+
/// It is configured to use the system's DNS configuration.
17+
pub fn default_resolver() -> &'static DnsResolver {
18+
&DNS_RESOLVER
19+
}
20+
21+
/// Get the DNS resolver used within iroh-net.
22+
pub fn resolver() -> &'static TokioAsyncResolver {
23+
Lazy::force(&DNS_RESOLVER)
24+
}
25+
26+
/// Deprecated IPv6 site-local anycast addresses still configured by windows.
27+
///
28+
/// Windows still configures these site-local addresses as soon even as an IPv6 loopback
29+
/// interface is configured. We do not want to use these DNS servers, the chances of them
30+
/// being usable are almost always close to zero, while the chance of DNS configuration
31+
/// **only** relying on these servers and not also being configured normally are also almost
32+
/// zero. The chance of the DNS resolver accidentally trying one of these and taking a
33+
/// bunch of timeouts to figure out they're no good are on the other hand very high.
34+
const WINDOWS_BAD_SITE_LOCAL_DNS_SERVERS: [IpAddr; 3] = [
35+
IpAddr::V6(Ipv6Addr::new(0xfec0, 0, 0, 0xffff, 0, 0, 0, 1)),
36+
IpAddr::V6(Ipv6Addr::new(0xfec0, 0, 0, 0xffff, 0, 0, 0, 2)),
37+
IpAddr::V6(Ipv6Addr::new(0xfec0, 0, 0, 0xffff, 0, 0, 0, 3)),
38+
];
39+
40+
/// Get resolver to query MX records.
41+
///
42+
/// We first try to read the system's resolver from `/etc/resolv.conf`.
43+
/// This does not work at least on some Androids, therefore we fallback
44+
/// to the default `ResolverConfig` which uses eg. to google's `8.8.8.8` or `8.8.4.4`.
45+
fn create_default_resolver() -> Result<TokioAsyncResolver> {
46+
let (system_config, mut options) =
47+
hickory_resolver::system_conf::read_system_conf().unwrap_or_default();
48+
49+
// Copy all of the system config, but strip the bad windows nameservers. Unfortunately
50+
// there is no easy way to do this.
51+
let mut config = hickory_resolver::config::ResolverConfig::new();
52+
if let Some(name) = system_config.domain() {
53+
config.set_domain(name.clone());
54+
}
55+
for name in system_config.search() {
56+
config.add_search(name.clone());
57+
}
58+
for nameserver_cfg in system_config.name_servers() {
59+
if !WINDOWS_BAD_SITE_LOCAL_DNS_SERVERS.contains(&nameserver_cfg.socket_addr.ip()) {
60+
config.add_name_server(nameserver_cfg.clone());
61+
}
62+
}
63+
64+
// see [`ResolverExt::lookup_ipv4_ipv6`] for info on why we avoid `LookupIpStrategy::Ipv4AndIpv6`
65+
options.ip_strategy = hickory_resolver::config::LookupIpStrategy::Ipv4thenIpv6;
66+
67+
let resolver = AsyncResolver::tokio(config, options);
68+
Ok(resolver)
69+
}

iroh-relay/src/lib.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,11 @@
1010
#![deny(missing_docs, rustdoc::broken_intra_doc_links)]
1111

1212
pub(crate) mod client;
13-
pub(crate) mod codec;
1413
mod defaults;
14+
mod dns;
1515
pub mod http;
1616
mod map;
17+
pub mod protos;
1718
#[cfg(feature = "iroh-relay")]
1819
#[cfg_attr(iroh_docsrs, doc(cfg(feature = "iroh-relay")))]
1920
pub mod server;
@@ -36,6 +37,6 @@ pub use self::{
3637
Client as HttpClient, ClientBuilder as HttpClientBuilder, ClientError as HttpClientError,
3738
ClientReceiver as HttpClientReceiver,
3839
},
39-
codec::MAX_PACKET_SIZE,
4040
map::{RelayMap, RelayMode, RelayNode},
41+
protos::relay::MAX_PACKET_SIZE,
4142
};

iroh-relay/src/protos.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
//! Protocols used by the iroh-relay
2+
3+
pub mod disco;
4+
pub mod relay;
5+
pub mod stun;

iroh-relay/src/protos/disco.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//! This module exports [`looks_like_disco_wrapper`] as the only disco-related relay
2+
//! funcionality.
3+
//!
4+
//! Despite the relay not being able to read disco messages by design, it does attempt to
5+
//! identify this trafic to ensure hole-punching messages are not lost do to congestion.
6+
7+
/// The 6 byte header of all discovery messages.
8+
pub const MAGIC: &str = "TS💬"; // 6 bytes: 0x54 53 f0 9f 92 ac
9+
pub(crate) const MAGIC_LEN: usize = MAGIC.as_bytes().len();
10+
pub(crate) const KEY_LEN: usize = 32;
11+
12+
const MESSAGE_HEADER_LEN: usize = MAGIC_LEN + KEY_LEN;
13+
/// Reports whether p looks like it's a packet containing an encrypted disco message.
14+
pub fn looks_like_disco_wrapper(p: &[u8]) -> bool {
15+
if p.len() < MESSAGE_HEADER_LEN {
16+
return false;
17+
}
18+
19+
&p[..MAGIC_LEN] == MAGIC.as_bytes()
20+
}

iroh-relay/src/codec.rs renamed to iroh-relay/src/protos/relay.rs

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
//! This module implements the relaying protocol used the [`crate::server`] and [`crate::client`].
2+
13
use std::time::Duration;
24

35
use anyhow::{bail, ensure};
@@ -26,14 +28,14 @@ const MAGIC: &str = "RELAY🔑";
2628

2729
#[cfg(feature = "iroh-relay")]
2830
#[cfg_attr(iroh_docsrs, doc(cfg(feature = "iroh-relay")))]
29-
pub(super) const KEEP_ALIVE: Duration = Duration::from_secs(60);
31+
pub(crate) const KEEP_ALIVE: Duration = Duration::from_secs(60);
3032
// TODO: what should this be?
3133
#[cfg(feature = "iroh-relay")]
3234
#[cfg_attr(iroh_docsrs, doc(cfg(feature = "iroh-relay")))]
33-
pub(super) const SERVER_CHANNEL_SIZE: usize = 1024 * 100;
35+
pub(crate) const SERVER_CHANNEL_SIZE: usize = 1024 * 100;
3436
/// The number of packets buffered for sending per client
35-
pub(super) const PER_CLIENT_SEND_QUEUE_DEPTH: usize = 512; //32;
36-
pub(super) const PER_CLIENT_READ_QUEUE_DEPTH: usize = 512;
37+
pub(crate) const PER_CLIENT_SEND_QUEUE_DEPTH: usize = 512; //32;
38+
pub(crate) const PER_CLIENT_READ_QUEUE_DEPTH: usize = 512;
3739

3840
/// ProtocolVersion is bumped whenever there's a wire-incompatible change.
3941
/// - version 1 (zero on wire): consistent box headers, in use by employee dev nodes a bit
@@ -47,7 +49,7 @@ pub(super) const PER_CLIENT_READ_QUEUE_DEPTH: usize = 512;
4749
/// The server will error on that connection if a client sends one of these frames.
4850
/// This materially affects the handshake protocol, and so relay nodes on version 3 will be unable to communicate
4951
/// with nodes running earlier protocol versions.
50-
pub(super) const PROTOCOL_VERSION: usize = 3;
52+
pub(crate) const PROTOCOL_VERSION: usize = 3;
5153

5254
///
5355
/// Protocol flow:
@@ -129,7 +131,7 @@ pub(crate) struct ClientInfo {
129131
/// Ignores the timeout if `None`
130132
///
131133
/// Does not flush.
132-
pub(super) async fn write_frame<S: Sink<Frame, Error = std::io::Error> + Unpin>(
134+
pub(crate) async fn write_frame<S: Sink<Frame, Error = std::io::Error> + Unpin>(
133135
mut writer: S,
134136
frame: Frame,
135137
timeout: Option<Duration>,
@@ -171,7 +173,7 @@ pub(crate) async fn send_client_key<S: Sink<Frame, Error = std::io::Error> + Unp
171173
// TODO(@divma): weird I had to change this
172174
// #[cfg(feature = "iroh-relay")]
173175
// #[cfg_attr(iroh_docsrs, doc(cfg(feature = "iroh-relay")))]
174-
pub(super) async fn recv_client_key<S: Stream<Item = anyhow::Result<Frame>> + Unpin>(
176+
pub(crate) async fn recv_client_key<S: Stream<Item = anyhow::Result<Frame>> + Unpin>(
175177
stream: S,
176178
) -> anyhow::Result<(PublicKey, ClientInfo)> {
177179
use anyhow::Context;
@@ -244,7 +246,7 @@ pub(crate) enum Frame {
244246
}
245247

246248
impl Frame {
247-
pub(super) fn typ(&self) -> FrameType {
249+
pub(crate) fn typ(&self) -> FrameType {
248250
match self {
249251
Frame::ClientInfo { .. } => FrameType::ClientInfo,
250252
Frame::SendPacket { .. } => FrameType::SendPacket,
@@ -260,7 +262,7 @@ impl Frame {
260262
}
261263

262264
/// Serialized length (without the frame header)
263-
pub(super) fn len(&self) -> usize {
265+
pub(crate) fn len(&self) -> usize {
264266
match self {
265267
Frame::ClientInfo {
266268
client_public_key: _,
@@ -543,7 +545,7 @@ impl Encoder<Frame> for DerpCodec {
543545
// TODO(@divma): what's going on
544546
// #[cfg(feature = "iroh-relay")]
545547
// #[cfg_attr(iroh_docsrs, doc(cfg(feature = "iroh-relay")))]
546-
pub(super) async fn recv_frame<S: Stream<Item = anyhow::Result<Frame>> + Unpin>(
548+
pub(crate) async fn recv_frame<S: Stream<Item = anyhow::Result<Frame>> + Unpin>(
547549
frame_type: FrameType,
548550
mut stream: S,
549551
) -> anyhow::Result<Frame> {

0 commit comments

Comments
 (0)