mirror of https://github.com/dswd/vpncloud.git
Compare commits
No commits in common. "35bdfafabf7a6c7a3568def80b15530f07645b52" and "fc18245fda948d5bd4f72f2633a1c8ce31218abf" have entirely different histories.
35bdfafabf
...
fc18245fda
|
@ -5,12 +5,6 @@ This project follows [semantic versioning](http://semver.org).
|
||||||
### UNRELEASED
|
### UNRELEASED
|
||||||
|
|
||||||
- [changed] Changed documentation
|
- [changed] Changed documentation
|
||||||
- [changed] Updated dependencies
|
|
||||||
- [changed] Retrying connections for 120 secs
|
|
||||||
- [fixed] Fixed corner case with lost init message
|
|
||||||
- [fixed] Do not reconnect to timed out pending connections
|
|
||||||
- [fixed] Most specific claims beat less specific claims
|
|
||||||
- [fixed] Count all invalid protocol traffic
|
|
||||||
|
|
||||||
### v2.0.0 (2020-10-30)
|
### v2.0.0 (2020-10-30)
|
||||||
|
|
||||||
|
|
34
src/cloud.rs
34
src/cloud.rs
|
@ -55,12 +55,12 @@ struct PeerData {
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct ReconnectEntry {
|
pub struct ReconnectEntry {
|
||||||
address: Option<(String, Time)>,
|
address: String,
|
||||||
resolved: Vec<SocketAddr>,
|
resolved: Vec<SocketAddr>,
|
||||||
|
next_resolve: Time,
|
||||||
tries: u16,
|
tries: u16,
|
||||||
timeout: u16,
|
timeout: u16,
|
||||||
next: Time,
|
next: Time
|
||||||
final_timeout: Option<Time>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -250,12 +250,12 @@ impl<D: Device, P: Protocol, S: Socket, TS: TimeSource> GenericCloud<D, P, S, TS
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
self.reconnect_peers.push(ReconnectEntry {
|
self.reconnect_peers.push(ReconnectEntry {
|
||||||
address: Some((add, now)),
|
address: add,
|
||||||
tries: 0,
|
tries: 0,
|
||||||
timeout: 1,
|
timeout: 1,
|
||||||
resolved,
|
resolved,
|
||||||
next: now,
|
next_resolve: now,
|
||||||
final_timeout: None
|
next: now
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -398,13 +398,11 @@ impl<D: Device, P: Protocol, S: Socket, TS: TimeSource> GenericCloud<D, P, S, TS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Resolve entries anew
|
// Resolve entries anew
|
||||||
if let Some((ref address, ref mut next_resolve)) = entry.address {
|
if entry.next_resolve <= now {
|
||||||
if *next_resolve <= now {
|
if let Ok(addrs) = resolve(&entry.address as &str) {
|
||||||
if let Ok(addrs) = resolve(address as &str) {
|
entry.resolved = addrs;
|
||||||
entry.resolved = addrs;
|
|
||||||
}
|
|
||||||
*next_resolve = now + RESOLVE_INTERVAL;
|
|
||||||
}
|
}
|
||||||
|
entry.next_resolve = now + RESOLVE_INTERVAL;
|
||||||
}
|
}
|
||||||
// Ignore if next attempt is already in the future
|
// Ignore if next attempt is already in the future
|
||||||
if entry.next > now {
|
if entry.next > now {
|
||||||
|
@ -423,7 +421,6 @@ impl<D: Device, P: Protocol, S: Socket, TS: TimeSource> GenericCloud<D, P, S, TS
|
||||||
// Schedule next connection attempt
|
// Schedule next connection attempt
|
||||||
entry.next = now + Time::from(entry.timeout);
|
entry.next = now + Time::from(entry.timeout);
|
||||||
}
|
}
|
||||||
self.reconnect_peers.retain(|e| e.final_timeout.unwrap_or(now) >= now);
|
|
||||||
if self.next_stats_out < now {
|
if self.next_stats_out < now {
|
||||||
// Write out the statistics
|
// Write out the statistics
|
||||||
self.write_out_stats().map_err(|err| Error::FileIo("Failed to write stats file", err))?;
|
self.write_out_stats().map_err(|err| Error::FileIo("Failed to write stats file", err))?;
|
||||||
|
@ -700,10 +697,7 @@ impl<D: Device, P: Protocol, S: Socket, TS: TimeSource> GenericCloud<D, P, S, TS
|
||||||
}
|
}
|
||||||
MESSAGE_TYPE_KEEPALIVE => self.update_peer_info(src, None)?,
|
MESSAGE_TYPE_KEEPALIVE => self.update_peer_info(src, None)?,
|
||||||
MESSAGE_TYPE_CLOSE => self.remove_peer(src),
|
MESSAGE_TYPE_CLOSE => self.remove_peer(src),
|
||||||
_ => {
|
_ => return Err(Error::Message("Unknown message type"))
|
||||||
self.traffic.count_invalid_protocol(data.len());
|
|
||||||
return Err(Error::Message("Unknown message type"))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
MessageResult::Initialized(info) => self.add_new_peer(src, info)?,
|
MessageResult::Initialized(info) => self.add_new_peer(src, info)?,
|
||||||
|
@ -739,17 +733,13 @@ impl<D: Device, P: Protocol, S: Socket, TS: TimeSource> GenericCloud<D, P, S, TS
|
||||||
self.pending_inits.insert(src, init);
|
self.pending_inits.insert(src, init);
|
||||||
Ok(res)
|
Ok(res)
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => return Err(err)
|
||||||
self.traffic.count_invalid_protocol(data.len());
|
|
||||||
return Err(err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if let Some(peer) = self.peers.get_mut(&src) {
|
} else if let Some(peer) = self.peers.get_mut(&src) {
|
||||||
peer.crypto.handle_message(data)
|
peer.crypto.handle_message(data)
|
||||||
} else {
|
} else {
|
||||||
info!("Ignoring non-init message from unknown peer {}", addr_nice(src));
|
info!("Ignoring non-init message from unknown peer {}", addr_nice(src));
|
||||||
self.traffic.count_invalid_protocol(data.len());
|
|
||||||
return Ok(())
|
return Ok(())
|
||||||
};
|
};
|
||||||
match msg_result {
|
match msg_result {
|
||||||
|
|
|
@ -79,8 +79,6 @@ pub const STAGE_PENG: u8 = 3;
|
||||||
pub const WAITING_TO_CLOSE: u8 = 4;
|
pub const WAITING_TO_CLOSE: u8 = 4;
|
||||||
pub const CLOSING: u8 = 5;
|
pub const CLOSING: u8 = 5;
|
||||||
|
|
||||||
pub const MAX_FAILED_RETRIES: usize = 120;
|
|
||||||
|
|
||||||
pub const SALTED_NODE_ID_HASH_LEN: usize = 20;
|
pub const SALTED_NODE_ID_HASH_LEN: usize = 20;
|
||||||
pub type SaltedNodeIdHash = [u8; SALTED_NODE_ID_HASH_LEN];
|
pub type SaltedNodeIdHash = [u8; SALTED_NODE_ID_HASH_LEN];
|
||||||
|
|
||||||
|
@ -449,7 +447,7 @@ impl<P: Payload> InitState<P> {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else if self.next_stage == CLOSING {
|
} else if self.next_stage == CLOSING {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else if self.failed_retries < MAX_FAILED_RETRIES {
|
} else if self.failed_retries < 5 {
|
||||||
self.failed_retries += 1;
|
self.failed_retries += 1;
|
||||||
self.repeat_last_message(out);
|
self.repeat_last_message(out);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -634,9 +632,8 @@ impl<P: Payload> InitState<P> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// decrypt the payload
|
// decrypt the payload
|
||||||
let peer_payload = self
|
let peer_payload =
|
||||||
.decrypt(&mut encrypted_payload)
|
self.decrypt(&mut encrypted_payload).map_err(|_| Error::CryptoInitFatal("Failed to decrypt payload"))?;
|
||||||
.map_err(|_| Error::CryptoInitFatal("Failed to decrypt payload"))?;
|
|
||||||
|
|
||||||
// create and send stage 3 reply
|
// create and send stage 3 reply
|
||||||
self.send_message(STAGE_PENG, None, out);
|
self.send_message(STAGE_PENG, None, out);
|
||||||
|
@ -647,9 +644,8 @@ impl<P: Payload> InitState<P> {
|
||||||
}
|
}
|
||||||
InitMsg::Peng { mut encrypted_payload, .. } => {
|
InitMsg::Peng { mut encrypted_payload, .. } => {
|
||||||
// decrypt the payload
|
// decrypt the payload
|
||||||
let peer_payload = self
|
let peer_payload =
|
||||||
.decrypt(&mut encrypted_payload)
|
self.decrypt(&mut encrypted_payload).map_err(|_| Error::CryptoInitFatal("Failed to decrypt payload"))?;
|
||||||
.map_err(|_| Error::CryptoInitFatal("Failed to decrypt payload"))?;
|
|
||||||
|
|
||||||
self.next_stage = CLOSING; // force resend when receiving any message
|
self.next_stage = CLOSING; // force resend when receiving any message
|
||||||
Ok(InitResult::Success { peer_payload, is_initiator: false })
|
Ok(InitResult::Success { peer_payload, is_initiator: false })
|
||||||
|
@ -794,7 +790,7 @@ mod tests {
|
||||||
let mut out = MsgBuffer::new(8);
|
let mut out = MsgBuffer::new(8);
|
||||||
sender.send_ping(&mut out);
|
sender.send_ping(&mut out);
|
||||||
assert_eq!(sender.stage(), STAGE_PONG);
|
assert_eq!(sender.stage(), STAGE_PONG);
|
||||||
for _ in 0..120 {
|
for _ in 0..5 {
|
||||||
out.clear();
|
out.clear();
|
||||||
sender.every_second(&mut out).unwrap();
|
sender.every_second(&mut out).unwrap();
|
||||||
}
|
}
|
||||||
|
@ -925,7 +921,10 @@ mod tests {
|
||||||
|
|
||||||
// Fail if no match
|
// Fail if no match
|
||||||
test_algorithm_negotiation(
|
test_algorithm_negotiation(
|
||||||
Algorithms { algorithm_speeds: smallvec![(&AES_128_GCM, 600.0)], allow_unencrypted: true },
|
Algorithms {
|
||||||
|
algorithm_speeds: smallvec![(&AES_128_GCM, 600.0)],
|
||||||
|
allow_unencrypted: true
|
||||||
|
},
|
||||||
Algorithms {
|
Algorithms {
|
||||||
algorithm_speeds: smallvec![(&AES_256_GCM, 500.0), (&CHACHA20_POLY1305, 400.0)],
|
algorithm_speeds: smallvec![(&AES_256_GCM, 500.0), (&CHACHA20_POLY1305, 400.0)],
|
||||||
allow_unencrypted: false
|
allow_unencrypted: false
|
||||||
|
|
|
@ -10,7 +10,6 @@ use std::{
|
||||||
io::{self, BufRead, BufReader, Cursor, Error as IoError, Read, Write},
|
io::{self, BufRead, BufReader, Cursor, Error as IoError, Read, Write},
|
||||||
net::{Ipv4Addr, UdpSocket},
|
net::{Ipv4Addr, UdpSocket},
|
||||||
os::unix::io::{AsRawFd, RawFd},
|
os::unix::io::{AsRawFd, RawFd},
|
||||||
convert::TryInto,
|
|
||||||
str,
|
str,
|
||||||
str::FromStr
|
str::FromStr
|
||||||
};
|
};
|
||||||
|
@ -19,6 +18,7 @@ use crate::{crypto, error::Error, util::MsgBuffer};
|
||||||
|
|
||||||
static TUNSETIFF: libc::c_ulong = 1074025674;
|
static TUNSETIFF: libc::c_ulong = 1074025674;
|
||||||
|
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
union IfReqData {
|
union IfReqData {
|
||||||
flags: libc::c_short,
|
flags: libc::c_short,
|
||||||
|
@ -141,7 +141,6 @@ impl TunTapDevice {
|
||||||
///
|
///
|
||||||
/// # Panics
|
/// # Panics
|
||||||
/// This method panics if the interface name is longer than 31 bytes.
|
/// This method panics if the interface name is longer than 31 bytes.
|
||||||
#[allow(clippy::useless_conversion)]
|
|
||||||
pub fn new(ifname: &str, type_: Type, path: Option<&str>) -> io::Result<Self> {
|
pub fn new(ifname: &str, type_: Type, path: Option<&str>) -> io::Result<Self> {
|
||||||
let path = path.unwrap_or_else(|| Self::default_path(type_));
|
let path = path.unwrap_or_else(|| Self::default_path(type_));
|
||||||
if type_ == Type::Dummy {
|
if type_ == Type::Dummy {
|
||||||
|
@ -155,7 +154,7 @@ impl TunTapDevice {
|
||||||
};
|
};
|
||||||
let mut ifreq = IfReq::new(ifname);
|
let mut ifreq = IfReq::new(ifname);
|
||||||
ifreq.data.flags = flags as libc::c_short;
|
ifreq.data.flags = flags as libc::c_short;
|
||||||
let res = unsafe { libc::ioctl(fd.as_raw_fd(), TUNSETIFF.try_into().unwrap(), &mut ifreq) };
|
let res = unsafe { libc::ioctl(fd.as_raw_fd(), TUNSETIFF, &mut ifreq) };
|
||||||
match res {
|
match res {
|
||||||
0 => {
|
0 => {
|
||||||
let mut ifname = String::with_capacity(32);
|
let mut ifname = String::with_capacity(32);
|
||||||
|
@ -399,34 +398,31 @@ impl AsRawFd for MockDevice {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[allow(clippy::useless_conversion)]
|
|
||||||
fn set_device_mtu(ifname: &str, mtu: usize) -> io::Result<()> {
|
fn set_device_mtu(ifname: &str, mtu: usize) -> io::Result<()> {
|
||||||
let sock = UdpSocket::bind("0.0.0.0:0")?;
|
let sock = UdpSocket::bind("0.0.0.0:0")?;
|
||||||
let mut ifreq = IfReq::new(ifname);
|
let mut ifreq = IfReq::new(ifname);
|
||||||
ifreq.data.value = mtu as libc::c_int;
|
ifreq.data.value = mtu as libc::c_int;
|
||||||
let res = unsafe { libc::ioctl(sock.as_raw_fd(), libc::SIOCSIFMTU.try_into().unwrap(), &mut ifreq) };
|
let res = unsafe { libc::ioctl(sock.as_raw_fd(), libc::SIOCSIFMTU, &mut ifreq) };
|
||||||
match res {
|
match res {
|
||||||
0 => Ok(()),
|
0 => Ok(()),
|
||||||
_ => Err(IoError::last_os_error())
|
_ => Err(IoError::last_os_error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::useless_conversion)]
|
|
||||||
fn get_device_mtu(ifname: &str) -> io::Result<usize> {
|
fn get_device_mtu(ifname: &str) -> io::Result<usize> {
|
||||||
let sock = UdpSocket::bind("0.0.0.0:0")?;
|
let sock = UdpSocket::bind("0.0.0.0:0")?;
|
||||||
let mut ifreq = IfReq::new(ifname);
|
let mut ifreq = IfReq::new(ifname);
|
||||||
let res = unsafe { libc::ioctl(sock.as_raw_fd(), libc::SIOCGIFMTU.try_into().unwrap(), &mut ifreq) };
|
let res = unsafe { libc::ioctl(sock.as_raw_fd(), libc::SIOCGIFMTU, &mut ifreq) };
|
||||||
match res {
|
match res {
|
||||||
0 => Ok(unsafe { ifreq.data.value as usize }),
|
0 => Ok(unsafe { ifreq.data.value as usize }),
|
||||||
_ => Err(IoError::last_os_error())
|
_ => Err(IoError::last_os_error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::useless_conversion)]
|
|
||||||
fn get_device_addr(ifname: &str) -> io::Result<Ipv4Addr> {
|
fn get_device_addr(ifname: &str) -> io::Result<Ipv4Addr> {
|
||||||
let sock = UdpSocket::bind("0.0.0.0:0")?;
|
let sock = UdpSocket::bind("0.0.0.0:0")?;
|
||||||
let mut ifreq = IfReq::new(ifname);
|
let mut ifreq = IfReq::new(ifname);
|
||||||
let res = unsafe { libc::ioctl(sock.as_raw_fd(), libc::SIOCGIFADDR.try_into().unwrap(), &mut ifreq) };
|
let res = unsafe { libc::ioctl(sock.as_raw_fd(), libc::SIOCGIFADDR, &mut ifreq) };
|
||||||
match res {
|
match res {
|
||||||
0 => {
|
0 => {
|
||||||
let af = unsafe { ifreq.data.addr.0 };
|
let af = unsafe { ifreq.data.addr.0 };
|
||||||
|
@ -440,12 +436,11 @@ fn get_device_addr(ifname: &str) -> io::Result<Ipv4Addr> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::useless_conversion)]
|
|
||||||
fn set_device_addr(ifname: &str, addr: Ipv4Addr) -> io::Result<()> {
|
fn set_device_addr(ifname: &str, addr: Ipv4Addr) -> io::Result<()> {
|
||||||
let sock = UdpSocket::bind("0.0.0.0:0")?;
|
let sock = UdpSocket::bind("0.0.0.0:0")?;
|
||||||
let mut ifreq = IfReq::new(ifname);
|
let mut ifreq = IfReq::new(ifname);
|
||||||
ifreq.data.addr = (libc::AF_INET as libc::c_short, addr);
|
ifreq.data.addr = (libc::AF_INET as libc::c_short, addr);
|
||||||
let res = unsafe { libc::ioctl(sock.as_raw_fd(), libc::SIOCSIFADDR.try_into().unwrap(), &mut ifreq) };
|
let res = unsafe { libc::ioctl(sock.as_raw_fd(), libc::SIOCSIFADDR, &mut ifreq) };
|
||||||
match res {
|
match res {
|
||||||
0 => Ok(()),
|
0 => Ok(()),
|
||||||
_ => Err(IoError::last_os_error())
|
_ => Err(IoError::last_os_error())
|
||||||
|
@ -453,11 +448,10 @@ fn set_device_addr(ifname: &str, addr: Ipv4Addr) -> io::Result<()> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
#[allow(clippy::useless_conversion)]
|
|
||||||
fn get_device_netmask(ifname: &str) -> io::Result<Ipv4Addr> {
|
fn get_device_netmask(ifname: &str) -> io::Result<Ipv4Addr> {
|
||||||
let sock = UdpSocket::bind("0.0.0.0:0")?;
|
let sock = UdpSocket::bind("0.0.0.0:0")?;
|
||||||
let mut ifreq = IfReq::new(ifname);
|
let mut ifreq = IfReq::new(ifname);
|
||||||
let res = unsafe { libc::ioctl(sock.as_raw_fd(), libc::SIOCGIFNETMASK.try_into().unwrap(), &mut ifreq) };
|
let res = unsafe { libc::ioctl(sock.as_raw_fd(), libc::SIOCGIFNETMASK, &mut ifreq) };
|
||||||
match res {
|
match res {
|
||||||
0 => {
|
0 => {
|
||||||
let af = unsafe { ifreq.data.addr.0 };
|
let af = unsafe { ifreq.data.addr.0 };
|
||||||
|
@ -471,23 +465,21 @@ fn get_device_netmask(ifname: &str) -> io::Result<Ipv4Addr> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::useless_conversion)]
|
|
||||||
fn set_device_netmask(ifname: &str, addr: Ipv4Addr) -> io::Result<()> {
|
fn set_device_netmask(ifname: &str, addr: Ipv4Addr) -> io::Result<()> {
|
||||||
let sock = UdpSocket::bind("0.0.0.0:0")?;
|
let sock = UdpSocket::bind("0.0.0.0:0")?;
|
||||||
let mut ifreq = IfReq::new(ifname);
|
let mut ifreq = IfReq::new(ifname);
|
||||||
ifreq.data.addr = (libc::AF_INET as libc::c_short, addr);
|
ifreq.data.addr = (libc::AF_INET as libc::c_short, addr);
|
||||||
let res = unsafe { libc::ioctl(sock.as_raw_fd(), libc::SIOCSIFNETMASK.try_into().unwrap(), &mut ifreq) };
|
let res = unsafe { libc::ioctl(sock.as_raw_fd(), libc::SIOCSIFNETMASK, &mut ifreq) };
|
||||||
match res {
|
match res {
|
||||||
0 => Ok(()),
|
0 => Ok(()),
|
||||||
_ => Err(IoError::last_os_error())
|
_ => Err(IoError::last_os_error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::useless_conversion)]
|
|
||||||
fn set_device_enabled(ifname: &str, up: bool) -> io::Result<()> {
|
fn set_device_enabled(ifname: &str, up: bool) -> io::Result<()> {
|
||||||
let sock = UdpSocket::bind("0.0.0.0:0")?;
|
let sock = UdpSocket::bind("0.0.0.0:0")?;
|
||||||
let mut ifreq = IfReq::new(ifname);
|
let mut ifreq = IfReq::new(ifname);
|
||||||
if unsafe { libc::ioctl(sock.as_raw_fd(), libc::SIOCGIFFLAGS.try_into().unwrap(), &mut ifreq) } != 0 {
|
if unsafe { libc::ioctl(sock.as_raw_fd(), libc::SIOCGIFFLAGS, &mut ifreq) } != 0 {
|
||||||
return Err(IoError::last_os_error())
|
return Err(IoError::last_os_error())
|
||||||
}
|
}
|
||||||
if up {
|
if up {
|
||||||
|
@ -495,7 +487,7 @@ fn set_device_enabled(ifname: &str, up: bool) -> io::Result<()> {
|
||||||
} else {
|
} else {
|
||||||
unsafe { ifreq.data.value &= !libc::IFF_UP }
|
unsafe { ifreq.data.value &= !libc::IFF_UP }
|
||||||
}
|
}
|
||||||
let res = unsafe { libc::ioctl(sock.as_raw_fd(), libc::SIOCSIFFLAGS.try_into().unwrap(), &mut ifreq) };
|
let res = unsafe { libc::ioctl(sock.as_raw_fd(), libc::SIOCSIFFLAGS, &mut ifreq) };
|
||||||
match res {
|
match res {
|
||||||
0 => Ok(()),
|
0 => Ok(()),
|
||||||
_ => Err(IoError::last_os_error())
|
_ => Err(IoError::last_os_error())
|
||||||
|
|
22
src/table.rs
22
src/table.rs
|
@ -88,21 +88,15 @@ impl<TS: TimeSource> ClaimTable<TS> {
|
||||||
if let Some(entry) = self.cache.get(&addr) {
|
if let Some(entry) = self.cache.get(&addr) {
|
||||||
return Some(entry.peer)
|
return Some(entry.peer)
|
||||||
}
|
}
|
||||||
let mut found = None;
|
|
||||||
let mut prefix_len = -1;
|
|
||||||
for entry in &self.claims {
|
for entry in &self.claims {
|
||||||
if entry.claim.prefix_len as isize > prefix_len && entry.claim.matches(addr) {
|
if entry.claim.matches(addr) {
|
||||||
found = Some(entry);
|
self.cache.insert(addr, CacheValue {
|
||||||
prefix_len = entry.claim.prefix_len as isize;
|
peer: entry.peer,
|
||||||
|
timeout: min(TS::now() + self.cache_timeout as Time, entry.timeout)
|
||||||
|
});
|
||||||
|
return Some(entry.peer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Some(entry) = found {
|
|
||||||
self.cache.insert(addr, CacheValue {
|
|
||||||
peer: entry.peer,
|
|
||||||
timeout: min(TS::now() + self.cache_timeout as Time, entry.timeout)
|
|
||||||
});
|
|
||||||
return Some(entry.peer)
|
|
||||||
}
|
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,9 +149,9 @@ mod bench {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::util::MockTimeSource;
|
use crate::util::MockTimeSource;
|
||||||
|
|
||||||
use smallvec::smallvec;
|
|
||||||
use std::str::FromStr;
|
|
||||||
use test::Bencher;
|
use test::Bencher;
|
||||||
|
use std::str::FromStr;
|
||||||
|
use smallvec::smallvec;
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn lookup_warm(b: &mut Bencher) {
|
fn lookup_warm(b: &mut Bencher) {
|
||||||
|
|
Loading…
Reference in New Issue