mirror of https://github.com/dswd/vpncloud.git
Exchange peer_timeout and adapt keepalive
This commit is contained in:
parent
04d934491c
commit
ee8542307f
30
src/cloud.rs
30
src/cloud.rs
|
@ -40,6 +40,7 @@ pub const STATS_INTERVAL: Time = 60;
|
||||||
|
|
||||||
struct PeerData {
|
struct PeerData {
|
||||||
timeout: Time,
|
timeout: Time,
|
||||||
|
peer_timeout: u16,
|
||||||
node_id: NodeId,
|
node_id: NodeId,
|
||||||
alt_addrs: Vec<SocketAddr>
|
alt_addrs: Vec<SocketAddr>
|
||||||
}
|
}
|
||||||
|
@ -84,6 +85,10 @@ impl<TS: TimeSource> PeerList<TS> {
|
||||||
del
|
del
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn min_peer_timeout(&self) -> u16 {
|
||||||
|
self.peers.iter().map(|p| p.1.peer_timeout).min().unwrap_or(1800)
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn contains_addr(&self, addr: &SocketAddr) -> bool {
|
pub fn contains_addr(&self, addr: &SocketAddr) -> bool {
|
||||||
self.addresses.contains_key(addr)
|
self.addresses.contains_key(addr)
|
||||||
|
@ -106,13 +111,14 @@ impl<TS: TimeSource> PeerList<TS> {
|
||||||
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn add(&mut self, node_id: NodeId, addr: SocketAddr) {
|
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() {
|
||||||
info!("New peer: {}", addr);
|
info!("New peer: {}", addr);
|
||||||
self.peers.insert(addr, PeerData {
|
self.peers.insert(addr, PeerData {
|
||||||
timeout: TS::now() + Time::from(self.timeout),
|
timeout: TS::now() + Time::from(self.timeout),
|
||||||
node_id,
|
node_id,
|
||||||
alt_addrs: vec![]
|
alt_addrs: vec![],
|
||||||
|
peer_timeout
|
||||||
});
|
});
|
||||||
self.addresses.insert(addr, node_id);
|
self.addresses.insert(addr, node_id);
|
||||||
}
|
}
|
||||||
|
@ -221,7 +227,7 @@ pub struct GenericCloud<D: Device, P: Protocol, T: Table, S: Socket, TS: TimeSou
|
||||||
device: D,
|
device: D,
|
||||||
crypto: Crypto,
|
crypto: Crypto,
|
||||||
next_peerlist: Time,
|
next_peerlist: Time,
|
||||||
update_freq: Duration,
|
update_freq: u16,
|
||||||
buffer_out: [u8; 64 * 1024],
|
buffer_out: [u8; 64 * 1024],
|
||||||
next_housekeep: Time,
|
next_housekeep: Time,
|
||||||
next_stats_out: Time,
|
next_stats_out: Time,
|
||||||
|
@ -252,7 +258,7 @@ impl<D: Device, P: Protocol, T: Table, S: Socket, TS: TimeSource> GenericCloud<D
|
||||||
let mut res = GenericCloud {
|
let mut res = GenericCloud {
|
||||||
magic: config.get_magic(),
|
magic: config.get_magic(),
|
||||||
node_id: random(),
|
node_id: random(),
|
||||||
peers: PeerList::new(config.peer_timeout),
|
peers: PeerList::new(config.peer_timeout as Duration),
|
||||||
addresses,
|
addresses,
|
||||||
learning,
|
learning,
|
||||||
broadcast,
|
broadcast,
|
||||||
|
@ -263,7 +269,7 @@ impl<D: Device, P: Protocol, T: Table, S: Socket, TS: TimeSource> GenericCloud<D
|
||||||
socket6,
|
socket6,
|
||||||
device,
|
device,
|
||||||
next_peerlist: now,
|
next_peerlist: now,
|
||||||
update_freq: config.get_keepalive(),
|
update_freq: config.get_keepalive() as u16,
|
||||||
buffer_out: [0; 64 * 1024],
|
buffer_out: [0; 64 * 1024],
|
||||||
next_housekeep: now,
|
next_housekeep: now,
|
||||||
next_stats_out: now + STATS_INTERVAL,
|
next_stats_out: now + STATS_INTERVAL,
|
||||||
|
@ -408,7 +414,7 @@ impl<D: Device, P: Protocol, T: Table, S: Socket, TS: TimeSource> GenericCloud<D
|
||||||
// Send a message to each resolved address
|
// Send a message to each resolved address
|
||||||
for a in resolve(&addr)? {
|
for a in resolve(&addr)? {
|
||||||
// Ignore error this time
|
// Ignore error this time
|
||||||
let mut msg = Message::Init(0, node_id, subnets.clone());
|
let mut msg = Message::Init(0, node_id, subnets.clone(), self.config.peer_timeout as u16);
|
||||||
self.send_msg(a, &mut msg).ok();
|
self.send_msg(a, &mut msg).ok();
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -429,7 +435,7 @@ impl<D: Device, P: Protocol, T: Table, S: Socket, TS: TimeSource> GenericCloud<D
|
||||||
debug!("Connecting to {:?}", addr);
|
debug!("Connecting to {:?}", addr);
|
||||||
let subnets = self.addresses.clone();
|
let subnets = self.addresses.clone();
|
||||||
let node_id = self.node_id;
|
let node_id = self.node_id;
|
||||||
let mut msg = Message::Init(0, node_id, subnets.clone());
|
let mut msg = Message::Init(0, node_id, subnets.clone(), self.config.peer_timeout as u16);
|
||||||
self.send_msg(addr, &mut msg)
|
self.send_msg(addr, &mut msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -466,6 +472,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
|
||||||
|
self.update_freq = min(self.config.get_keepalive() as u16, self.peers.min_peer_timeout());
|
||||||
self.next_peerlist = now + Time::from(self.update_freq);
|
self.next_peerlist = now + Time::from(self.update_freq);
|
||||||
}
|
}
|
||||||
// Connect to those reconnect_peers that are due
|
// Connect to those reconnect_peers that are due
|
||||||
|
@ -697,7 +704,7 @@ impl<D: Device, P: Protocol, T: Table, S: Socket, TS: TimeSource> GenericCloud<D
|
||||||
// Refresh peer
|
// Refresh peer
|
||||||
self.peers.refresh(&peer);
|
self.peers.refresh(&peer);
|
||||||
}
|
}
|
||||||
Message::Init(stage, node_id, ranges) => {
|
Message::Init(stage, node_id, ranges, peer_timeout) => {
|
||||||
// Avoid connecting to self
|
// Avoid connecting to self
|
||||||
if node_id == self.node_id {
|
if node_id == self.node_id {
|
||||||
self.own_addresses.push(peer);
|
self.own_addresses.push(peer);
|
||||||
|
@ -707,7 +714,7 @@ impl<D: Device, P: Protocol, T: Table, S: Socket, TS: TimeSource> GenericCloud<D
|
||||||
if self.peers.contains_node(&node_id) {
|
if self.peers.contains_node(&node_id) {
|
||||||
self.peers.make_primary(node_id, peer);
|
self.peers.make_primary(node_id, peer);
|
||||||
} else {
|
} else {
|
||||||
self.peers.add(node_id, peer);
|
self.peers.add(node_id, peer, peer_timeout);
|
||||||
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), peer);
|
||||||
}
|
}
|
||||||
|
@ -716,7 +723,10 @@ impl<D: Device, P: Protocol, T: Table, S: Socket, TS: TimeSource> GenericCloud<D
|
||||||
if stage == 0 {
|
if stage == 0 {
|
||||||
let own_addrs = self.addresses.clone();
|
let own_addrs = self.addresses.clone();
|
||||||
let own_node_id = self.node_id;
|
let own_node_id = self.node_id;
|
||||||
self.send_msg(peer, &mut Message::Init(stage + 1, own_node_id, own_addrs))?;
|
self.send_msg(
|
||||||
|
peer,
|
||||||
|
&mut Message::Init(stage + 1, own_node_id, own_addrs, self.config.peer_timeout as u16)
|
||||||
|
)?;
|
||||||
}
|
}
|
||||||
// Send peers in any case
|
// Send peers in any case
|
||||||
let peers = self.peers.as_vec();
|
let peers = self.peers.as_vec();
|
||||||
|
|
|
@ -17,24 +17,24 @@ fn connect_v4() {
|
||||||
node1.connect("2.3.4.5:6789").unwrap();
|
node1.connect("2.3.4.5:6789").unwrap();
|
||||||
|
|
||||||
// Node 1 -> Node 2: Init 0
|
// Node 1 -> Node 2: Init 0
|
||||||
assert_message4!(node1, node1_addr, node2, node2_addr, Message::Init(0, node1.node_id(), vec![]));
|
assert_message4!(node1, node1_addr, node2, node2_addr, Message::Init(0, node1.node_id(), vec![], 1800));
|
||||||
assert_clean!(node1);
|
assert_clean!(node1);
|
||||||
assert!(node2.peers().contains_node(&node1.node_id()));
|
assert!(node2.peers().contains_node(&node1.node_id()));
|
||||||
|
|
||||||
// Node 2 -> Node 1: Init 1 | Node 2 -> Node 1: Peers
|
// Node 2 -> Node 1: Init 1 | Node 2 -> Node 1: Peers
|
||||||
assert_message4!(node2, node2_addr, node1, node1_addr, Message::Init(1, node2.node_id(), vec![]));
|
assert_message4!(node2, node2_addr, node1, node1_addr, Message::Init(1, node2.node_id(), vec![], 1800));
|
||||||
assert!(node1.peers().contains_node(&node2.node_id()));
|
assert!(node1.peers().contains_node(&node2.node_id()));
|
||||||
assert_message4!(node2, node2_addr, node1, node1_addr, Message::Peers(vec![node1_addr]));
|
assert_message4!(node2, node2_addr, node1, node1_addr, Message::Peers(vec![node1_addr]));
|
||||||
assert_clean!(node2);
|
assert_clean!(node2);
|
||||||
|
|
||||||
// Node 1 -> Node 2: Peers | Node 1 -> Node 1: Init 0
|
// Node 1 -> Node 2: Peers | Node 1 -> Node 1: Init 0
|
||||||
assert_message4!(node1, node1_addr, node2, node2_addr, Message::Peers(vec![node2_addr]));
|
assert_message4!(node1, node1_addr, node2, node2_addr, Message::Peers(vec![node2_addr]));
|
||||||
assert_message4!(node1, node1_addr, node1, node1_addr, Message::Init(0, node1.node_id(), vec![]));
|
assert_message4!(node1, node1_addr, node1, node1_addr, Message::Init(0, node1.node_id(), vec![], 1800));
|
||||||
assert!(node1.own_addresses().contains(&node1_addr));
|
assert!(node1.own_addresses().contains(&node1_addr));
|
||||||
assert_clean!(node1);
|
assert_clean!(node1);
|
||||||
|
|
||||||
// Node 2 -> Node 2: Init 0
|
// Node 2 -> Node 2: Init 0
|
||||||
assert_message4!(node2, node2_addr, node2, node2_addr, Message::Init(0, node2.node_id(), vec![]));
|
assert_message4!(node2, node2_addr, node2, node2_addr, Message::Init(0, node2.node_id(), vec![], 1800));
|
||||||
assert_clean!(node2);
|
assert_clean!(node2);
|
||||||
assert!(node2.own_addresses().contains(&node2_addr));
|
assert!(node2.own_addresses().contains(&node2_addr));
|
||||||
|
|
||||||
|
@ -156,7 +156,7 @@ fn lost_init1() {
|
||||||
node1.connect("2.3.4.5:6789").unwrap();
|
node1.connect("2.3.4.5:6789").unwrap();
|
||||||
|
|
||||||
// Node 1 -> Node 2: Init 0
|
// Node 1 -> Node 2: Init 0
|
||||||
assert_message4!(node1, node1_addr, node2, node2_addr, Message::Init(0, node1.node_id(), vec![]));
|
assert_message4!(node1, node1_addr, node2, node2_addr, Message::Init(0, node1.node_id(), vec![], 1800));
|
||||||
assert_clean!(node1);
|
assert_clean!(node1);
|
||||||
|
|
||||||
// Node 2 -> Node 1: Init 1 | Node 2 -> Node 1: Peers
|
// Node 2 -> Node 1: Init 1 | Node 2 -> Node 1: Peers
|
||||||
|
@ -177,7 +177,7 @@ fn wrong_magic() {
|
||||||
let node2_addr = addr!("2.3.4.5:6789");
|
let node2_addr = addr!("2.3.4.5:6789");
|
||||||
node1.connect("2.3.4.5:6789").unwrap();
|
node1.connect("2.3.4.5:6789").unwrap();
|
||||||
|
|
||||||
assert_message4!(node1, node1_addr, node2, node2_addr, Message::Init(0, node1.node_id(), vec![]));
|
assert_message4!(node1, node1_addr, node2, node2_addr, Message::Init(0, node1.node_id(), vec![], 1800));
|
||||||
|
|
||||||
assert_clean!(node1, node2);
|
assert_clean!(node1, node2);
|
||||||
|
|
||||||
|
@ -204,3 +204,8 @@ fn remove_dead_peers() {
|
||||||
fn update_primary_address() {
|
fn update_primary_address() {
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn automatic_peer_timeout() {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
|
@ -55,7 +55,7 @@ impl TopHeader {
|
||||||
pub enum Message<'a> {
|
pub enum Message<'a> {
|
||||||
Data(&'a mut [u8], usize, usize), // data, start, end
|
Data(&'a mut [u8], usize, usize), // data, start, end
|
||||||
Peers(Vec<SocketAddr>), // peers
|
Peers(Vec<SocketAddr>), // peers
|
||||||
Init(u8, NodeId, Vec<Range>), // step, node_id, ranges
|
Init(u8, NodeId, Vec<Range>, u16), // step, node_id, ranges
|
||||||
Close
|
Close
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ impl<'a> Message<'a> {
|
||||||
match self {
|
match self {
|
||||||
Message::Data(_, start, end) => Message::Data(&mut [], start, end),
|
Message::Data(_, start, end) => Message::Data(&mut [], start, end),
|
||||||
Message::Peers(peers) => Message::Peers(peers),
|
Message::Peers(peers) => Message::Peers(peers),
|
||||||
Message::Init(step, node_id, ranges) => Message::Init(step, node_id, ranges),
|
Message::Init(step, node_id, ranges, timeout) => Message::Init(step, node_id, ranges, timeout),
|
||||||
Message::Close => Message::Close
|
Message::Close => Message::Close
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -86,8 +86,15 @@ impl<'a> fmt::Debug for Message<'a> {
|
||||||
}
|
}
|
||||||
write!(formatter, "]")
|
write!(formatter, "]")
|
||||||
}
|
}
|
||||||
Message::Init(stage, ref node_id, ref peers) => {
|
Message::Init(stage, ref node_id, ref peers, ref peer_timeout) => {
|
||||||
write!(formatter, "Init(stage={}, node_id={}, {:?})", stage, bytes_to_hex(node_id), peers)
|
write!(
|
||||||
|
formatter,
|
||||||
|
"Init(stage={}, node_id={}, peer_timeout={}, {:?})",
|
||||||
|
stage,
|
||||||
|
bytes_to_hex(node_id),
|
||||||
|
peer_timeout,
|
||||||
|
peers
|
||||||
|
)
|
||||||
}
|
}
|
||||||
Message::Close => write!(formatter, "Close")
|
Message::Close => write!(formatter, "Close")
|
||||||
}
|
}
|
||||||
|
@ -183,7 +190,12 @@ pub fn decode<'a>(data: &'a mut [u8], magic: HeaderMagic, crypto: &Crypto) -> Re
|
||||||
pos += read;
|
pos += read;
|
||||||
addrs.push(range);
|
addrs.push(range);
|
||||||
}
|
}
|
||||||
Message::Init(stage, node_id, addrs)
|
let mut peer_timeout = 1800;
|
||||||
|
if data.len() >= pos + 2 {
|
||||||
|
peer_timeout = Encoder::read_u16(&data[pos..]);
|
||||||
|
// pos += 2; never read
|
||||||
|
}
|
||||||
|
Message::Init(stage, node_id, addrs, peer_timeout)
|
||||||
}
|
}
|
||||||
3 => Message::Close,
|
3 => Message::Close,
|
||||||
_ => return Err(Error::Parse("Unknown message type"))
|
_ => return Err(Error::Parse("Unknown message type"))
|
||||||
|
@ -198,7 +210,7 @@ pub fn encode<'a>(
|
||||||
let header_type = match msg {
|
let header_type = match msg {
|
||||||
Message::Data(_, _, _) => 0,
|
Message::Data(_, _, _) => 0,
|
||||||
Message::Peers(_) => 1,
|
Message::Peers(_) => 1,
|
||||||
Message::Init(_, _, _) => 2,
|
Message::Init(_, _, _, _) => 2,
|
||||||
Message::Close => 3
|
Message::Close => 3
|
||||||
};
|
};
|
||||||
let mut start = 64;
|
let mut start = 64;
|
||||||
|
@ -244,7 +256,7 @@ pub fn encode<'a>(
|
||||||
}
|
}
|
||||||
end = pos;
|
end = pos;
|
||||||
}
|
}
|
||||||
Message::Init(stage, ref node_id, ref ranges) => {
|
Message::Init(stage, ref node_id, ref ranges, peer_timeout) => {
|
||||||
let mut pos = start;
|
let mut pos = start;
|
||||||
assert!(buf.len() >= pos + 2 + NODE_ID_BYTES);
|
assert!(buf.len() >= pos + 2 + NODE_ID_BYTES);
|
||||||
buf[pos] = stage;
|
buf[pos] = stage;
|
||||||
|
@ -257,6 +269,8 @@ pub fn encode<'a>(
|
||||||
for range in ranges {
|
for range in ranges {
|
||||||
pos += range.write_to(&mut buf[pos..]);
|
pos += range.write_to(&mut buf[pos..]);
|
||||||
}
|
}
|
||||||
|
Encoder::write_u16(peer_timeout, &mut buf[pos..]);
|
||||||
|
pos += 2;
|
||||||
end = pos;
|
end = pos;
|
||||||
}
|
}
|
||||||
Message::Close => {}
|
Message::Close => {}
|
||||||
|
@ -299,9 +313,9 @@ impl<'a> PartialEq for Message<'a> {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Message::Init(step1, node_id1, ref ranges1) => {
|
Message::Init(step1, node_id1, ref ranges1, peer_timeout1) => {
|
||||||
if let Message::Init(step2, node_id2, ref ranges2) = *other {
|
if let Message::Init(step2, node_id2, ref ranges2, peer_timeout2) = *other {
|
||||||
step1 == step2 && node_id1 == node_id2 && ranges1 == ranges2
|
step1 == step2 && node_id1 == node_id2 && ranges1 == ranges2 && peer_timeout1 == peer_timeout2
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
@ -421,15 +435,15 @@ fn udpmessage_init() {
|
||||||
Range { base: Address { data: [0, 1, 2, 3, 4, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], len: 6 }, prefix_len: 16 },
|
Range { base: Address { data: [0, 1, 2, 3, 4, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], len: 6 }, prefix_len: 16 },
|
||||||
];
|
];
|
||||||
let node_id = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
|
let node_id = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
|
||||||
let mut msg = Message::Init(0, node_id, addrs);
|
let mut msg = Message::Init(0, node_id, addrs, 1800);
|
||||||
let mut should = [
|
let mut should = [
|
||||||
118, 112, 110, 1, 0, 0, 0, 2, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 2, 4, 0, 1, 2, 3, 24, 6,
|
118, 112, 110, 1, 0, 0, 0, 2, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 2, 4, 0, 1, 2, 3, 24, 6,
|
||||||
0, 1, 2, 3, 4, 5, 16
|
0, 1, 2, 3, 4, 5, 16, 7, 8
|
||||||
];
|
];
|
||||||
{
|
{
|
||||||
let mut buf = [0; 1024];
|
let mut buf = [0; 1024];
|
||||||
let res = encode(&mut msg, &mut buf[..], MAGIC, &mut crypto);
|
let res = encode(&mut msg, &mut buf[..], MAGIC, &mut crypto);
|
||||||
assert_eq!(res.len(), 40);
|
assert_eq!(res.len(), 42);
|
||||||
for i in 0..res.len() {
|
for i in 0..res.len() {
|
||||||
assert_eq!(res[i], should[i]);
|
assert_eq!(res[i], should[i]);
|
||||||
}
|
}
|
||||||
|
@ -502,9 +516,9 @@ fn message_fmt() {
|
||||||
base: Address { data: [0, 1, 2, 3, 4, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], len: 6 },
|
base: Address { data: [0, 1, 2, 3, 4, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], len: 6 },
|
||||||
prefix_len: 16
|
prefix_len: 16
|
||||||
}
|
}
|
||||||
])
|
], 1800)
|
||||||
),
|
),
|
||||||
"Init(stage=0, node_id=000102030405060708090a0b0c0d0e0f, [0.1.2.3/24, 00:01:02:03:04:05/16])"
|
"Init(stage=0, node_id=000102030405060708090a0b0c0d0e0f, peer_timeout=1800, [0.1.2.3/24, 00:01:02:03:04:05/16])"
|
||||||
);
|
);
|
||||||
assert_eq!(format!("{:?}", Message::Close), "Close");
|
assert_eq!(format!("{:?}", Message::Close), "Close");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue