X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=src%2Fdatastore.rs;h=1f2221029d6d2d76f79626f574c6fc64b066f86b;hb=5626798a0d61d3eab42edb0feacdda328620c580;hp=5aa4748d732e25b84c11e3b5706a344aa3f69ee2;hpb=5392883632221572ae4450c751e1b102245bc237;p=dnsseed-rust diff --git a/src/datastore.rs b/src/datastore.rs index 5aa4748..1f22210 100644 --- a/src/datastore.rs +++ b/src/datastore.rs @@ -1,11 +1,11 @@ -use std::{cmp, mem}; +use std::cmp; use std::collections::{HashSet, HashMap, hash_map}; use std::sync::{Arc, RwLock}; use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6}; use std::time::{Duration, Instant}; use std::io::{BufRead, BufReader}; -use bitcoin::network::address::Address; +use bitcoin::network::address::{Address, AddrV2Message}; use rand::thread_rng; use rand::seq::{SliceRandom, IteratorRandom}; @@ -132,13 +132,17 @@ struct Node { #[derive(Clone, PartialEq, Eq, Hash)] enum SockAddr { V4(SocketAddrV4), - V6((Ipv6Addr, u16)), + V6(([u16; 8], u16)), +} +#[inline] +fn segs_to_ip6(segs: &[u16; 8]) -> Ipv6Addr { + Ipv6Addr::new(segs[0], segs[1], segs[2], segs[3], segs[4], segs[5], segs[6], segs[7]) } impl From for SockAddr { fn from(addr: SocketAddr) -> SockAddr { match addr { SocketAddr::V4(sa) => SockAddr::V4(sa), - SocketAddr::V6(sa) => SockAddr::V6((sa.ip().clone(), sa.port())), + SocketAddr::V6(sa) => SockAddr::V6((sa.ip().segments(), sa.port())), } } } @@ -146,7 +150,7 @@ impl Into for &SockAddr { fn into(self) -> SocketAddr { match self { &SockAddr::V4(sa) => SocketAddr::V4(sa), - &SockAddr::V6(sa) => SocketAddr::V6(SocketAddrV6::new(sa.0, sa.1, 0, 0)) + &SockAddr::V6(sa) => SocketAddr::V6(SocketAddrV6::new(segs_to_ip6(&sa.0), sa.1, 0, 0)) } } } @@ -166,7 +170,7 @@ impl SockAddr { pub fn ip(&self) -> IpAddr { match *self { SockAddr::V4(sa) => IpAddr::V4(sa.ip().clone()), - SockAddr::V6((ip, _)) => IpAddr::V6(ip), + SockAddr::V6((ip, _)) => IpAddr::V6(segs_to_ip6(&ip)), } } } @@ -174,12 +178,12 @@ impl SockAddr { struct Nodes { good_node_services: [HashSet; 64], nodes_to_state: HashMap, - state_next_scan: Vec>, + state_next_scan: [Vec; AddressState::get_count() as usize], } struct NodesMutRef<'a> { good_node_services: &'a mut [HashSet; 64], nodes_to_state: &'a mut HashMap, - state_next_scan: &'a mut Vec>, + state_next_scan: &'a mut [Vec; AddressState::get_count() as usize], } impl Nodes { @@ -262,10 +266,7 @@ impl Store { macro_rules! nodes_uninitd { () => { { - let mut state_vecs = Vec::with_capacity(AddressState::get_count() as usize); - for _ in 0..AddressState::get_count() { - state_vecs.push(Vec::new()); - } + let state_vecs = [Vec::new(), Vec::new(), Vec::new(), Vec::new(), Vec::new(), Vec::new(), Vec::new(), Vec::new(), Vec::new(), Vec::new(), Vec::new(), Vec::new(), Vec::new(), Vec::new(), Vec::new()]; let good_node_services = [HashSet::new(), HashSet::new(), HashSet::new(), HashSet::new(), HashSet::new(), HashSet::new(), HashSet::new(), HashSet::new(), HashSet::new(), HashSet::new(), HashSet::new(), HashSet::new(), HashSet::new(), HashSet::new(), HashSet::new(), HashSet::new(), HashSet::new(), HashSet::new(), HashSet::new(), HashSet::new(), HashSet::new(), HashSet::new(), HashSet::new(), HashSet::new(), HashSet::new(), HashSet::new(), HashSet::new(), HashSet::new(), HashSet::new(), HashSet::new(), HashSet::new(), HashSet::new(), HashSet::new(), HashSet::new(), HashSet::new(), HashSet::new(), HashSet::new(), HashSet::new(), HashSet::new(), HashSet::new(), HashSet::new(), HashSet::new(), HashSet::new(), HashSet::new(), HashSet::new(), HashSet::new(), HashSet::new(), HashSet::new(), HashSet::new(), HashSet::new(), HashSet::new(), HashSet::new(), HashSet::new(), HashSet::new(), HashSet::new(), HashSet::new(), HashSet::new(), HashSet::new(), HashSet::new(), HashSet::new(), HashSet::new(), HashSet::new(), HashSet::new(), HashSet::new()]; Nodes { good_node_services, @@ -383,6 +384,14 @@ impl Store { } })); } + pub fn add_fresh_nodes_v2(&self, addresses: &Vec) { + self.add_fresh_addrs(addresses.iter().filter_map(|addr| { + match addr.socket_addr() { + Ok(socketaddr) => Some(socketaddr), + Err(_) => None, // TODO: Handle onions + } + })); + } pub fn set_node_state(&self, sockaddr: SocketAddr, state: AddressState, services: u64) -> AddressState { let addr: SockAddr = sockaddr.into(); @@ -470,7 +479,7 @@ impl Store { let mut nodes_buff = String::new(); { let nodes = self.nodes.read().unwrap(); - nodes_buff.reserve(nodes.nodes_to_state.len() * 20); + nodes_buff.reserve(nodes.nodes_to_state.len() * 32); for (ref sockaddr, ref node) in nodes.nodes_to_state.iter() { nodes_buff += &sockaddr.to_string(); nodes_buff += ","; @@ -611,9 +620,7 @@ impl Store { let split_point = cmp::min(cmp::min(SECS_PER_SCAN_RESULTS * state_nodes.len() as u64 / rescan_interval, SECS_PER_SCAN_RESULTS * MAX_CONNS_PER_SEC_PER_STATUS), state_nodes.len() as u64); - let mut new_nodes = state_nodes.split_off(split_point as usize); - mem::swap(&mut new_nodes, state_nodes); - for node in new_nodes.drain(..) { + for node in state_nodes.drain(..split_point as usize) { nodes.nodes_to_state.get_mut(&node).unwrap().queued = false; res.push((&node).into()); }