mirror of https://github.com/dswd/vpncloud.git
Fixed problem with TUN on dynamic host addresses
This commit is contained in:
parent
86223fb4f9
commit
2fcf2c1e01
|
@ -8,7 +8,10 @@ This project follows [semantic versioning](http://semver.org).
|
||||||
- [added] Added crypto option AES128
|
- [added] Added crypto option AES128
|
||||||
- [added] Default port for peers
|
- [added] Default port for peers
|
||||||
- [changed] Updated dependencies
|
- [changed] Updated dependencies
|
||||||
|
- [changed] Removed C code, now 100% Rust
|
||||||
- [fixed] Fixed keepalive for small timeouts
|
- [fixed] Fixed keepalive for small timeouts
|
||||||
|
- [fixed] Fixed problem with port forwarding
|
||||||
|
- [fixed] Fixed problem with TUN on dynamic host addresses
|
||||||
|
|
||||||
### v1.4.0 (2020-06-03)
|
### v1.4.0 (2020-06-03)
|
||||||
|
|
||||||
|
|
12
src/cloud.rs
12
src/cloud.rs
|
@ -3,7 +3,7 @@
|
||||||
// This software is licensed under GPL-3 or newer (see LICENSE.md)
|
// This software is licensed under GPL-3 or newer (see LICENSE.md)
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
cmp::{min, max},
|
cmp::{max, min},
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
fmt,
|
fmt,
|
||||||
fs::{self, File},
|
fs::{self, File},
|
||||||
|
@ -109,7 +109,6 @@ impl<TS: TimeSource> PeerList<TS> {
|
||||||
self.nodes.contains_key(node_id)
|
self.nodes.contains_key(node_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn add(&mut self, node_id: NodeId, addr: SocketAddr, peer_timeout: u16) {
|
fn add(&mut self, node_id: NodeId, addr: SocketAddr, peer_timeout: u16) {
|
||||||
if self.nodes.insert(node_id, addr).is_none() {
|
if self.nodes.insert(node_id, addr).is_none() {
|
||||||
|
@ -366,7 +365,8 @@ impl<D: Device, P: Protocol, T: Table, S: Socket, TS: TimeSource> GenericCloud<D
|
||||||
/// connect to the peer if it is not already connected.
|
/// connect to the peer if it is not already connected.
|
||||||
pub fn add_reconnect_peer(&mut self, mut add: String) {
|
pub fn add_reconnect_peer(&mut self, mut add: String) {
|
||||||
let now = TS::now();
|
let now = TS::now();
|
||||||
if add.find(':').unwrap_or(0) <= add.find(']').unwrap_or(0) { // : not present or only in IPv6 address
|
if add.find(':').unwrap_or(0) <= add.find(']').unwrap_or(0) {
|
||||||
|
// : not present or only in IPv6 address
|
||||||
add = format!("{}:{}", add, DEFAULT_PORT)
|
add = format!("{}:{}", add, DEFAULT_PORT)
|
||||||
}
|
}
|
||||||
let resolved = match resolve(&add as &str) {
|
let resolved = match resolve(&add as &str) {
|
||||||
|
@ -476,7 +476,7 @@ impl<D: Device, P: Protocol, T: Table, S: Socket, TS: TimeSource> GenericCloud<D
|
||||||
let mut msg = Message::Peers(peers);
|
let mut msg = Message::Peers(peers);
|
||||||
self.broadcast_msg(&mut msg)?;
|
self.broadcast_msg(&mut msg)?;
|
||||||
// Reschedule for next update
|
// Reschedule for next update
|
||||||
let interval = min(self.update_freq as u16, max(self.peers.min_peer_timeout()/2-60, 1));
|
let interval = min(self.update_freq as u16, max(self.peers.min_peer_timeout() / 2 - 60, 1));
|
||||||
self.next_peerlist = now + Time::from(interval);
|
self.next_peerlist = now + Time::from(interval);
|
||||||
}
|
}
|
||||||
// Connect to those reconnect_peers that are due
|
// Connect to those reconnect_peers that are due
|
||||||
|
@ -753,7 +753,7 @@ impl<D: Device, P: Protocol, T: Table, S: Socket, TS: TimeSource> GenericCloud<D
|
||||||
}
|
}
|
||||||
if self.learning {
|
if self.learning {
|
||||||
// Learn single address
|
// Learn single address
|
||||||
self.table.learn(src, None, peer);
|
self.table.learn(src, None, self.node_id, peer);
|
||||||
}
|
}
|
||||||
// Not adding peer in this case to increase performance
|
// Not adding peer in this case to increase performance
|
||||||
}
|
}
|
||||||
|
@ -787,7 +787,7 @@ impl<D: Device, P: Protocol, T: Table, S: Socket, TS: TimeSource> GenericCloud<D
|
||||||
warn!("Ignoring claimed addresses received from {} in learning mode.", addr_nice(peer));
|
warn!("Ignoring claimed addresses received from {} in learning mode.", addr_nice(peer));
|
||||||
} else {
|
} else {
|
||||||
for range in ranges {
|
for range in ranges {
|
||||||
self.table.learn(range.base, Some(range.prefix_len), peer);
|
self.table.learn(range.base, Some(range.prefix_len), node_id, peer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ use std::{
|
||||||
use fnv::FnvHasher;
|
use fnv::FnvHasher;
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
types::{Address, Error, Protocol, Table},
|
types::{Address, Error, NodeId, Protocol, Table},
|
||||||
util::{addr_nice, Duration, Time, TimeSource}
|
util::{addr_nice, Duration, Time, TimeSource}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -125,7 +125,7 @@ impl<TS: TimeSource> Table for SwitchTable<TS> {
|
||||||
|
|
||||||
/// Learns the given address, inserting it in the hash map
|
/// Learns the given address, inserting it in the hash map
|
||||||
#[inline]
|
#[inline]
|
||||||
fn learn(&mut self, key: Address, _prefix_len: Option<u8>, addr: SocketAddr) {
|
fn learn(&mut self, key: Address, _prefix_len: Option<u8>, _: NodeId, addr: SocketAddr) {
|
||||||
let deadline = TS::now() + Time::from(self.timeout);
|
let deadline = TS::now() + Time::from(self.timeout);
|
||||||
match self.table.entry(key) {
|
match self.table.entry(key) {
|
||||||
Entry::Vacant(entry) => {
|
Entry::Vacant(entry) => {
|
||||||
|
@ -212,16 +212,17 @@ fn switch() {
|
||||||
MockTimeSource::set_time(1000);
|
MockTimeSource::set_time(1000);
|
||||||
let mut table = SwitchTable::<MockTimeSource>::new(10, 1);
|
let mut table = SwitchTable::<MockTimeSource>::new(10, 1);
|
||||||
let addr = Address::from_str("12:34:56:78:90:ab").unwrap();
|
let addr = Address::from_str("12:34:56:78:90:ab").unwrap();
|
||||||
|
let node_id = [0; 16];
|
||||||
let peer = "1.2.3.4:5678".to_socket_addrs().unwrap().next().unwrap();
|
let peer = "1.2.3.4:5678".to_socket_addrs().unwrap().next().unwrap();
|
||||||
let peer2 = "1.2.3.5:7890".to_socket_addrs().unwrap().next().unwrap();
|
let peer2 = "1.2.3.5:7890".to_socket_addrs().unwrap().next().unwrap();
|
||||||
assert!(table.lookup(&addr).is_none());
|
assert!(table.lookup(&addr).is_none());
|
||||||
MockTimeSource::set_time(1000);
|
MockTimeSource::set_time(1000);
|
||||||
table.learn(addr, None, peer);
|
table.learn(addr, None, node_id, peer);
|
||||||
assert_eq!(table.lookup(&addr), Some(peer));
|
assert_eq!(table.lookup(&addr), Some(peer));
|
||||||
MockTimeSource::set_time(1000);
|
MockTimeSource::set_time(1000);
|
||||||
table.learn(addr, None, peer2);
|
table.learn(addr, None, node_id, peer2);
|
||||||
assert_eq!(table.lookup(&addr), Some(peer));
|
assert_eq!(table.lookup(&addr), Some(peer));
|
||||||
MockTimeSource::set_time(1010);
|
MockTimeSource::set_time(1010);
|
||||||
table.learn(addr, None, peer2);
|
table.learn(addr, None, node_id, peer2);
|
||||||
assert_eq!(table.lookup(&addr), Some(peer2));
|
assert_eq!(table.lookup(&addr), Some(peer2));
|
||||||
}
|
}
|
||||||
|
|
47
src/ip.rs
47
src/ip.rs
|
@ -12,7 +12,7 @@ use std::{
|
||||||
use fnv::FnvHasher;
|
use fnv::FnvHasher;
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
types::{Address, Error, Protocol, Table},
|
types::{Address, Error, NodeId, Protocol, Table},
|
||||||
util::addr_nice
|
util::addr_nice
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -59,6 +59,7 @@ impl Protocol for Packet {
|
||||||
|
|
||||||
struct RoutingEntry {
|
struct RoutingEntry {
|
||||||
address: SocketAddr,
|
address: SocketAddr,
|
||||||
|
node_id: NodeId,
|
||||||
bytes: Address,
|
bytes: Address,
|
||||||
prefix_len: u8
|
prefix_len: u8
|
||||||
}
|
}
|
||||||
|
@ -82,7 +83,7 @@ impl RoutingTable {
|
||||||
|
|
||||||
impl Table for RoutingTable {
|
impl Table for RoutingTable {
|
||||||
/// Learns the given address, inserting it in the hash map
|
/// Learns the given address, inserting it in the hash map
|
||||||
fn learn(&mut self, addr: Address, prefix_len: Option<u8>, address: SocketAddr) {
|
fn learn(&mut self, addr: Address, prefix_len: Option<u8>, node_id: NodeId, address: SocketAddr) {
|
||||||
// If prefix length is not set, treat the whole address as significant
|
// If prefix length is not set, treat the whole address as significant
|
||||||
let prefix_len = match prefix_len {
|
let prefix_len = match prefix_len {
|
||||||
Some(val) => val,
|
Some(val) => val,
|
||||||
|
@ -96,10 +97,14 @@ impl Table for RoutingTable {
|
||||||
let mut group_bytes = [0; 16];
|
let mut group_bytes = [0; 16];
|
||||||
group_bytes[..group_len].copy_from_slice(&addr.data[..group_len]);
|
group_bytes[..group_len].copy_from_slice(&addr.data[..group_len]);
|
||||||
// Create an entry
|
// Create an entry
|
||||||
let routing_entry = RoutingEntry { address, bytes: addr, prefix_len };
|
let routing_entry = RoutingEntry { address, bytes: addr, node_id, prefix_len };
|
||||||
// Add the entry to the routing table, creating a new list if the prefix group is empty.
|
// Add the entry to the routing table, creating a new list if the prefix group is empty.
|
||||||
match self.0.entry(group_bytes) {
|
match self.0.entry(group_bytes) {
|
||||||
hash_map::Entry::Occupied(mut entry) => entry.get_mut().push(routing_entry),
|
hash_map::Entry::Occupied(mut entry) => {
|
||||||
|
let list = entry.get_mut();
|
||||||
|
list.retain(|e| e.node_id != routing_entry.node_id || e.address == routing_entry.address);
|
||||||
|
list.push(routing_entry)
|
||||||
|
}
|
||||||
hash_map::Entry::Vacant(entry) => {
|
hash_map::Entry::Vacant(entry) => {
|
||||||
entry.insert(vec![routing_entry]);
|
entry.insert(vec![routing_entry]);
|
||||||
}
|
}
|
||||||
|
@ -241,33 +246,36 @@ fn decode_invalid_packet() {
|
||||||
fn routing_table_ipv4() {
|
fn routing_table_ipv4() {
|
||||||
let mut table = RoutingTable::new();
|
let mut table = RoutingTable::new();
|
||||||
let peer1 = "1.2.3.4:1".to_socket_addrs().unwrap().next().unwrap();
|
let peer1 = "1.2.3.4:1".to_socket_addrs().unwrap().next().unwrap();
|
||||||
|
let node1 = [1; 16];
|
||||||
let peer2 = "1.2.3.4:2".to_socket_addrs().unwrap().next().unwrap();
|
let peer2 = "1.2.3.4:2".to_socket_addrs().unwrap().next().unwrap();
|
||||||
|
let node2 = [2; 16];
|
||||||
let peer3 = "1.2.3.4:3".to_socket_addrs().unwrap().next().unwrap();
|
let peer3 = "1.2.3.4:3".to_socket_addrs().unwrap().next().unwrap();
|
||||||
|
let node3 = [3; 16];
|
||||||
assert!(table.lookup(&Address::from_str("192.168.1.1").unwrap()).is_none());
|
assert!(table.lookup(&Address::from_str("192.168.1.1").unwrap()).is_none());
|
||||||
table.learn(Address::from_str("192.168.1.1").unwrap(), Some(32), peer1);
|
table.learn(Address::from_str("192.168.1.1").unwrap(), Some(32), node1, peer1);
|
||||||
assert_eq!(table.lookup(&Address::from_str("192.168.1.1").unwrap()), Some(peer1));
|
assert_eq!(table.lookup(&Address::from_str("192.168.1.1").unwrap()), Some(peer1));
|
||||||
table.learn(Address::from_str("192.168.1.2").unwrap(), None, peer2);
|
table.learn(Address::from_str("192.168.1.2").unwrap(), None, node2, peer2);
|
||||||
assert_eq!(table.lookup(&Address::from_str("192.168.1.1").unwrap()), Some(peer1));
|
assert_eq!(table.lookup(&Address::from_str("192.168.1.1").unwrap()), Some(peer1));
|
||||||
assert_eq!(table.lookup(&Address::from_str("192.168.1.2").unwrap()), Some(peer2));
|
assert_eq!(table.lookup(&Address::from_str("192.168.1.2").unwrap()), Some(peer2));
|
||||||
table.learn(Address::from_str("192.168.1.0").unwrap(), Some(24), peer3);
|
table.learn(Address::from_str("192.168.1.0").unwrap(), Some(24), node3, peer3);
|
||||||
assert_eq!(table.lookup(&Address::from_str("192.168.1.1").unwrap()), Some(peer1));
|
assert_eq!(table.lookup(&Address::from_str("192.168.1.1").unwrap()), Some(peer1));
|
||||||
assert_eq!(table.lookup(&Address::from_str("192.168.1.2").unwrap()), Some(peer2));
|
assert_eq!(table.lookup(&Address::from_str("192.168.1.2").unwrap()), Some(peer2));
|
||||||
assert_eq!(table.lookup(&Address::from_str("192.168.1.3").unwrap()), Some(peer3));
|
assert_eq!(table.lookup(&Address::from_str("192.168.1.3").unwrap()), Some(peer3));
|
||||||
table.learn(Address::from_str("192.168.0.0").unwrap(), Some(16), peer1);
|
table.learn(Address::from_str("192.168.0.0").unwrap(), Some(16), node1, peer1);
|
||||||
assert_eq!(table.lookup(&Address::from_str("192.168.2.1").unwrap()), Some(peer1));
|
assert_eq!(table.lookup(&Address::from_str("192.168.2.1").unwrap()), Some(peer1));
|
||||||
assert_eq!(table.lookup(&Address::from_str("192.168.1.1").unwrap()), Some(peer1));
|
assert_eq!(table.lookup(&Address::from_str("192.168.1.1").unwrap()), Some(peer1));
|
||||||
assert_eq!(table.lookup(&Address::from_str("192.168.1.2").unwrap()), Some(peer2));
|
assert_eq!(table.lookup(&Address::from_str("192.168.1.2").unwrap()), Some(peer2));
|
||||||
assert_eq!(table.lookup(&Address::from_str("192.168.1.3").unwrap()), Some(peer3));
|
assert_eq!(table.lookup(&Address::from_str("192.168.1.3").unwrap()), Some(peer3));
|
||||||
table.learn(Address::from_str("0.0.0.0").unwrap(), Some(0), peer2);
|
table.learn(Address::from_str("0.0.0.0").unwrap(), Some(0), node2, peer2);
|
||||||
assert_eq!(table.lookup(&Address::from_str("192.168.2.1").unwrap()), Some(peer1));
|
assert_eq!(table.lookup(&Address::from_str("192.168.2.1").unwrap()), Some(peer1));
|
||||||
assert_eq!(table.lookup(&Address::from_str("192.168.1.1").unwrap()), Some(peer1));
|
assert_eq!(table.lookup(&Address::from_str("192.168.1.1").unwrap()), Some(peer1));
|
||||||
assert_eq!(table.lookup(&Address::from_str("192.168.1.2").unwrap()), Some(peer2));
|
assert_eq!(table.lookup(&Address::from_str("192.168.1.2").unwrap()), Some(peer2));
|
||||||
assert_eq!(table.lookup(&Address::from_str("192.168.1.3").unwrap()), Some(peer3));
|
assert_eq!(table.lookup(&Address::from_str("192.168.1.3").unwrap()), Some(peer3));
|
||||||
assert_eq!(table.lookup(&Address::from_str("1.2.3.4").unwrap()), Some(peer2));
|
assert_eq!(table.lookup(&Address::from_str("1.2.3.4").unwrap()), Some(peer2));
|
||||||
table.learn(Address::from_str("192.168.2.0").unwrap(), Some(27), peer3);
|
table.learn(Address::from_str("192.168.2.0").unwrap(), Some(27), node3, peer3);
|
||||||
assert_eq!(table.lookup(&Address::from_str("192.168.2.31").unwrap()), Some(peer3));
|
assert_eq!(table.lookup(&Address::from_str("192.168.2.31").unwrap()), Some(peer3));
|
||||||
assert_eq!(table.lookup(&Address::from_str("192.168.2.32").unwrap()), Some(peer1));
|
assert_eq!(table.lookup(&Address::from_str("192.168.2.32").unwrap()), Some(peer1));
|
||||||
table.learn(Address::from_str("192.168.2.0").unwrap(), Some(28), peer3);
|
table.learn(Address::from_str("192.168.2.0").unwrap(), Some(28), node3, peer3);
|
||||||
assert_eq!(table.lookup(&Address::from_str("192.168.2.1").unwrap()), Some(peer3));
|
assert_eq!(table.lookup(&Address::from_str("192.168.2.1").unwrap()), Some(peer3));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -275,34 +283,37 @@ fn routing_table_ipv4() {
|
||||||
fn routing_table_ipv6() {
|
fn routing_table_ipv6() {
|
||||||
let mut table = RoutingTable::new();
|
let mut table = RoutingTable::new();
|
||||||
let peer1 = "::1:1".to_socket_addrs().unwrap().next().unwrap();
|
let peer1 = "::1:1".to_socket_addrs().unwrap().next().unwrap();
|
||||||
|
let node1 = [1; 16];
|
||||||
let peer2 = "::1:2".to_socket_addrs().unwrap().next().unwrap();
|
let peer2 = "::1:2".to_socket_addrs().unwrap().next().unwrap();
|
||||||
|
let node2 = [2; 16];
|
||||||
let peer3 = "::1:3".to_socket_addrs().unwrap().next().unwrap();
|
let peer3 = "::1:3".to_socket_addrs().unwrap().next().unwrap();
|
||||||
|
let node3 = [3; 16];
|
||||||
assert!(table.lookup(&Address::from_str("::1").unwrap()).is_none());
|
assert!(table.lookup(&Address::from_str("::1").unwrap()).is_none());
|
||||||
table.learn(Address::from_str("dead:beef:dead:beef:dead:beef:dead:1").unwrap(), Some(128), peer1);
|
table.learn(Address::from_str("dead:beef:dead:beef:dead:beef:dead:1").unwrap(), Some(128), node1, peer1);
|
||||||
assert_eq!(table.lookup(&Address::from_str("dead:beef:dead:beef:dead:beef:dead:1").unwrap()), Some(peer1));
|
assert_eq!(table.lookup(&Address::from_str("dead:beef:dead:beef:dead:beef:dead:1").unwrap()), Some(peer1));
|
||||||
table.learn(Address::from_str("dead:beef:dead:beef:dead:beef:dead:2").unwrap(), None, peer2);
|
table.learn(Address::from_str("dead:beef:dead:beef:dead:beef:dead:2").unwrap(), None, node2, peer2);
|
||||||
assert_eq!(table.lookup(&Address::from_str("dead:beef:dead:beef:dead:beef:dead:1").unwrap()), Some(peer1));
|
assert_eq!(table.lookup(&Address::from_str("dead:beef:dead:beef:dead:beef:dead:1").unwrap()), Some(peer1));
|
||||||
assert_eq!(table.lookup(&Address::from_str("dead:beef:dead:beef:dead:beef:dead:2").unwrap()), Some(peer2));
|
assert_eq!(table.lookup(&Address::from_str("dead:beef:dead:beef:dead:beef:dead:2").unwrap()), Some(peer2));
|
||||||
table.learn(Address::from_str("dead:beef:dead:beef::").unwrap(), Some(64), peer3);
|
table.learn(Address::from_str("dead:beef:dead:beef::").unwrap(), Some(64), node3, peer3);
|
||||||
assert_eq!(table.lookup(&Address::from_str("dead:beef:dead:beef:dead:beef:dead:1").unwrap()), Some(peer1));
|
assert_eq!(table.lookup(&Address::from_str("dead:beef:dead:beef:dead:beef:dead:1").unwrap()), Some(peer1));
|
||||||
assert_eq!(table.lookup(&Address::from_str("dead:beef:dead:beef:dead:beef:dead:2").unwrap()), Some(peer2));
|
assert_eq!(table.lookup(&Address::from_str("dead:beef:dead:beef:dead:beef:dead:2").unwrap()), Some(peer2));
|
||||||
assert_eq!(table.lookup(&Address::from_str("dead:beef:dead:beef:dead:beef:dead:3").unwrap()), Some(peer3));
|
assert_eq!(table.lookup(&Address::from_str("dead:beef:dead:beef:dead:beef:dead:3").unwrap()), Some(peer3));
|
||||||
table.learn(Address::from_str("dead:beef:dead:be00::").unwrap(), Some(56), peer1);
|
table.learn(Address::from_str("dead:beef:dead:be00::").unwrap(), Some(56), node1, peer1);
|
||||||
assert_eq!(table.lookup(&Address::from_str("dead:beef:dead:beef:dead:beef:1::").unwrap()), Some(peer3));
|
assert_eq!(table.lookup(&Address::from_str("dead:beef:dead:beef:dead:beef:1::").unwrap()), Some(peer3));
|
||||||
assert_eq!(table.lookup(&Address::from_str("dead:beef:dead:be01::").unwrap()), Some(peer1));
|
assert_eq!(table.lookup(&Address::from_str("dead:beef:dead:be01::").unwrap()), Some(peer1));
|
||||||
assert_eq!(table.lookup(&Address::from_str("dead:beef:dead:beef:dead:beef:dead:1").unwrap()), Some(peer1));
|
assert_eq!(table.lookup(&Address::from_str("dead:beef:dead:beef:dead:beef:dead:1").unwrap()), Some(peer1));
|
||||||
assert_eq!(table.lookup(&Address::from_str("dead:beef:dead:beef:dead:beef:dead:2").unwrap()), Some(peer2));
|
assert_eq!(table.lookup(&Address::from_str("dead:beef:dead:beef:dead:beef:dead:2").unwrap()), Some(peer2));
|
||||||
assert_eq!(table.lookup(&Address::from_str("dead:beef:dead:beef:dead:beef:dead:3").unwrap()), Some(peer3));
|
assert_eq!(table.lookup(&Address::from_str("dead:beef:dead:beef:dead:beef:dead:3").unwrap()), Some(peer3));
|
||||||
table.learn(Address::from_str("::").unwrap(), Some(0), peer2);
|
table.learn(Address::from_str("::").unwrap(), Some(0), node2, peer2);
|
||||||
assert_eq!(table.lookup(&Address::from_str("dead:beef:dead:beef:dead:beef:1::").unwrap()), Some(peer3));
|
assert_eq!(table.lookup(&Address::from_str("dead:beef:dead:beef:dead:beef:1::").unwrap()), Some(peer3));
|
||||||
assert_eq!(table.lookup(&Address::from_str("dead:beef:dead:be01::").unwrap()), Some(peer1));
|
assert_eq!(table.lookup(&Address::from_str("dead:beef:dead:be01::").unwrap()), Some(peer1));
|
||||||
assert_eq!(table.lookup(&Address::from_str("dead:beef:dead:beef:dead:beef:dead:1").unwrap()), Some(peer1));
|
assert_eq!(table.lookup(&Address::from_str("dead:beef:dead:beef:dead:beef:dead:1").unwrap()), Some(peer1));
|
||||||
assert_eq!(table.lookup(&Address::from_str("dead:beef:dead:beef:dead:beef:dead:2").unwrap()), Some(peer2));
|
assert_eq!(table.lookup(&Address::from_str("dead:beef:dead:beef:dead:beef:dead:2").unwrap()), Some(peer2));
|
||||||
assert_eq!(table.lookup(&Address::from_str("dead:beef:dead:beef:dead:beef:dead:3").unwrap()), Some(peer3));
|
assert_eq!(table.lookup(&Address::from_str("dead:beef:dead:beef:dead:beef:dead:3").unwrap()), Some(peer3));
|
||||||
assert_eq!(table.lookup(&Address::from_str("::1").unwrap()), Some(peer2));
|
assert_eq!(table.lookup(&Address::from_str("::1").unwrap()), Some(peer2));
|
||||||
table.learn(Address::from_str("dead:beef:dead:beef:dead:beef:dead:be00").unwrap(), Some(123), peer2);
|
table.learn(Address::from_str("dead:beef:dead:beef:dead:beef:dead:be00").unwrap(), Some(123), node2, peer2);
|
||||||
assert_eq!(table.lookup(&Address::from_str("dead:beef:dead:beef:dead:beef:dead:be1f").unwrap()), Some(peer2));
|
assert_eq!(table.lookup(&Address::from_str("dead:beef:dead:beef:dead:beef:dead:be1f").unwrap()), Some(peer2));
|
||||||
assert_eq!(table.lookup(&Address::from_str("dead:beef:dead:beef:dead:beef:dead:be20").unwrap()), Some(peer3));
|
assert_eq!(table.lookup(&Address::from_str("dead:beef:dead:beef:dead:beef:dead:be20").unwrap()), Some(peer3));
|
||||||
table.learn(Address::from_str("dead:beef:dead:beef:dead:beef:dead:be00").unwrap(), Some(124), peer3);
|
table.learn(Address::from_str("dead:beef:dead:beef:dead:beef:dead:be00").unwrap(), Some(124), node3, peer3);
|
||||||
assert_eq!(table.lookup(&Address::from_str("dead:beef:dead:beef:dead:beef:dead:be01").unwrap()), Some(peer3));
|
assert_eq!(table.lookup(&Address::from_str("dead:beef:dead:beef:dead:beef:dead:be01").unwrap()), Some(peer3));
|
||||||
}
|
}
|
||||||
|
|
|
@ -221,7 +221,7 @@ impl FromStr for Mode {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Table {
|
pub trait Table {
|
||||||
fn learn(&mut self, _: Address, _: Option<u8>, _: SocketAddr);
|
fn learn(&mut self, _: Address, _: Option<u8>, _: NodeId, _: SocketAddr);
|
||||||
fn lookup(&mut self, _: &Address) -> Option<SocketAddr>;
|
fn lookup(&mut self, _: &Address) -> Option<SocketAddr>;
|
||||||
fn housekeep(&mut self);
|
fn housekeep(&mut self);
|
||||||
fn write_out<W: Write>(&self, out: &mut W) -> Result<(), io::Error>;
|
fn write_out<W: Write>(&self, out: &mut W) -> Result<(), io::Error>;
|
||||||
|
|
Loading…
Reference in New Issue