From f3c0199e4c59e357dccbc289c687155905fc28e4 Mon Sep 17 00:00:00 2001 From: Bryan Newbold Date: Tue, 5 Dec 2017 23:18:19 -0800 Subject: basic centralized DNS discovery --- src/bin/geniza-net.rs | 17 +++++++++++++++++ src/discovery.rs | 39 +++++++++++++++++++++++++++++++++++++++ src/lib.rs | 5 +++++ 3 files changed, 61 insertions(+) create mode 100644 src/discovery.rs (limited to 'src') diff --git a/src/bin/geniza-net.rs b/src/bin/geniza-net.rs index dd80c4f..e6fa448 100644 --- a/src/bin/geniza-net.rs +++ b/src/bin/geniza-net.rs @@ -55,6 +55,11 @@ fn run() -> Result<()> { .about("Prints the DNS name to query (mDNS or centrally) for peers") .arg_from_usage(" 'dat key (public key) to convert (in hex)'"), ) + .subcommand( + SubCommand::with_name("discover-dns") + .about("Does a centralized DNS lookup for peers with the given key") + .arg_from_usage(" 'dat key (public key) to lookup"), + ) .subcommand( SubCommand::with_name("naive-clone") .about("Pulls a drive from a single (known) peer, using a naive algorithm") @@ -126,6 +131,18 @@ fn run() -> Result<()> { } println!(".dat.local"); } + ("discover-dns", Some(subm)) => { + let dat_key = subm.value_of("dat_key").unwrap(); + let key_bytes = parse_dat_key(&dat_key)?; + let peers = discover_peers_dns(&key_bytes)?; + if peers.len() == 0 { + println!("No peers found!"); + } else { + for p in peers { + println!("{}", p); + } + } + } ("naive-clone", Some(subm)) => { let host_port = subm.value_of("host_port").unwrap(); let dat_key = subm.value_of("dat_key").unwrap(); diff --git a/src/discovery.rs b/src/discovery.rs new file mode 100644 index 0000000..aef2a60 --- /dev/null +++ b/src/discovery.rs @@ -0,0 +1,39 @@ + +use errors::*; +use std::net::{IpAddr, SocketAddr}; +use make_discovery_key; +use data_encoding::HEXLOWER; +use resolve::{self, DnsConfig, DnsResolver, resolve_host}; +use resolve::record::Srv; + +pub fn discover_peers_dns(dat_key: &[u8]) -> Result> { + + let dk = make_discovery_key(dat_key); + let dk_hex = HEXLOWER.encode(&dk); + let dk_name = format!("{}.dat.local", &dk_hex[0..40]); + info!("discovering peers using DNS: {}", dk_name); + + let dns1: Vec = resolve_host("discovery1.publicbits.org")?.collect(); + let dns2: Vec = resolve_host("discovery2.publicbits.org")?.collect(); + + let default_config = resolve::default_config()?; + let config = DnsConfig { + name_servers: vec![ + SocketAddr::from((dns1[0], 53)), + SocketAddr::from((dns2[0], 53))], + search: vec!["dat.local".to_string()], + n_dots: default_config.n_dots, + timeout: default_config.timeout, + attempts: default_config.attempts, + rotate: true, + use_inet6: false, + }; + + let resolver = DnsResolver::new(config)?; + + let peers: Vec = resolver.resolve_record(&dk_name)?; + // target (IP addresses) are returned with a trailing period that must be stripped + let peers: Vec = peers.into_iter().map(|r| format!("{}:{}", &r.target[0..(r.target.len()-1)], r.port).parse().unwrap()).collect(); + info!("found peers: {:?}", peers); + Ok(peers) +} diff --git a/src/lib.rs b/src/lib.rs index 10139d3..bc62d78 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -24,6 +24,8 @@ extern crate protobuf; extern crate rand; extern crate sodiumoxide; extern crate bit_field; +extern crate resolve; +extern crate data_encoding; #[cfg(test)] extern crate tempdir; @@ -35,6 +37,7 @@ mod errors { error_chain! { foreign_links { Fmt(::std::fmt::Error); Io(::std::io::Error) #[cfg(unix)]; + AddrParseError(::std::net::AddrParseError); Protobuf(::protobuf::ProtobufError); } } } @@ -55,6 +58,8 @@ pub mod network_msgs; pub mod metadata_msgs; mod node; pub use node::*; +mod discovery; +pub use discovery::*; // Shared functions use crypto::digest::Digest; -- cgit v1.2.3