checkpoint
This commit is contained in:
@@ -2,7 +2,7 @@ use super::*;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct ConnectionHandle {
|
||||
id: u64,
|
||||
id: NetworkConnectionId,
|
||||
descriptor: ConnectionDescriptor,
|
||||
channel: flume::Sender<(Option<Id>, Vec<u8>)>,
|
||||
}
|
||||
@@ -15,7 +15,7 @@ pub enum ConnectionHandleSendResult {
|
||||
|
||||
impl ConnectionHandle {
|
||||
pub(super) fn new(
|
||||
id: u64,
|
||||
id: NetworkConnectionId,
|
||||
descriptor: ConnectionDescriptor,
|
||||
channel: flume::Sender<(Option<Id>, Vec<u8>)>,
|
||||
) -> Self {
|
||||
@@ -26,7 +26,7 @@ impl ConnectionHandle {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn connection_id(&self) -> u64 {
|
||||
pub fn connection_id(&self) -> NetworkConnectionId {
|
||||
self.id
|
||||
}
|
||||
|
||||
|
@@ -41,7 +41,7 @@ impl ConnectionLimits {
|
||||
}
|
||||
}
|
||||
|
||||
fn purge_old_timestamps(&mut self, cur_ts: u64) {
|
||||
fn purge_old_timestamps(&mut self, cur_ts: Timestamp) {
|
||||
// v4
|
||||
{
|
||||
let mut dead_keys = Vec::<Ipv4Addr>::new();
|
||||
@@ -78,7 +78,7 @@ impl ConnectionLimits {
|
||||
|
||||
pub fn add(&mut self, addr: IpAddr) -> Result<(), AddressFilterError> {
|
||||
let ipblock = ip_to_ipblock(self.max_connections_per_ip6_prefix_size, addr);
|
||||
let ts = get_timestamp();
|
||||
let ts = get_aligned_timestamp();
|
||||
|
||||
self.purge_old_timestamps(ts);
|
||||
|
||||
@@ -134,7 +134,7 @@ impl ConnectionLimits {
|
||||
pub fn remove(&mut self, addr: IpAddr) -> Result<(), AddressNotInTableError> {
|
||||
let ipblock = ip_to_ipblock(self.max_connections_per_ip6_prefix_size, addr);
|
||||
|
||||
let ts = get_timestamp();
|
||||
let ts = get_aligned_timestamp();
|
||||
self.purge_old_timestamps(ts);
|
||||
|
||||
match ipblock {
|
||||
|
@@ -48,9 +48,9 @@ impl ConnectionManager {
|
||||
async_processor_jh: MustJoinHandle<()>,
|
||||
) -> ConnectionManagerInner {
|
||||
ConnectionManagerInner {
|
||||
next_id: 0,
|
||||
next_id: 0.into(),
|
||||
stop_source: Some(stop_source),
|
||||
sender: sender,
|
||||
sender,
|
||||
async_processor_jh: Some(async_processor_jh),
|
||||
}
|
||||
}
|
||||
@@ -149,7 +149,7 @@ impl ConnectionManager {
|
||||
) -> EyreResult<NetworkResult<ConnectionHandle>> {
|
||||
// Get next connection id to use
|
||||
let id = inner.next_id;
|
||||
inner.next_id += 1;
|
||||
inner.next_id += 1u64;
|
||||
log_net!(
|
||||
"on_new_protocol_network_connection: id={} prot_conn={:?}",
|
||||
id,
|
||||
@@ -398,7 +398,7 @@ impl ConnectionManager {
|
||||
// Callback from network connection receive loop when it exits
|
||||
// cleans up the entry in the connection table
|
||||
#[instrument(level = "trace", skip(self))]
|
||||
pub(super) async fn report_connection_finished(&self, connection_id: u64) {
|
||||
pub(super) async fn report_connection_finished(&self, connection_id: NetworkConnectionId) {
|
||||
// Get channel sender
|
||||
let sender = {
|
||||
let mut inner = self.arc.inner.lock();
|
||||
|
@@ -67,7 +67,7 @@ struct NetworkComponents {
|
||||
// Statistics per address
|
||||
#[derive(Clone, Default)]
|
||||
pub struct PerAddressStats {
|
||||
last_seen_ts: u64,
|
||||
last_seen_ts: Timestamp,
|
||||
transfer_stats_accounting: TransferStatsAccounting,
|
||||
transfer_stats: TransferStatsDownUp,
|
||||
}
|
||||
@@ -99,7 +99,7 @@ impl Default for NetworkManagerStats {
|
||||
|
||||
#[derive(Debug)]
|
||||
struct ClientWhitelistEntry {
|
||||
last_seen_ts: u64,
|
||||
last_seen_ts: Timestamp,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
@@ -400,11 +400,11 @@ impl NetworkManager {
|
||||
let mut inner = self.inner.lock();
|
||||
match inner.client_whitelist.entry(client) {
|
||||
hashlink::lru_cache::Entry::Occupied(mut entry) => {
|
||||
entry.get_mut().last_seen_ts = get_timestamp()
|
||||
entry.get_mut().last_seen_ts = get_aligned_timestamp()
|
||||
}
|
||||
hashlink::lru_cache::Entry::Vacant(entry) => {
|
||||
entry.insert(ClientWhitelistEntry {
|
||||
last_seen_ts: get_timestamp(),
|
||||
last_seen_ts: get_aligned_timestamp(),
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -416,7 +416,7 @@ impl NetworkManager {
|
||||
|
||||
match inner.client_whitelist.entry(client) {
|
||||
hashlink::lru_cache::Entry::Occupied(mut entry) => {
|
||||
entry.get_mut().last_seen_ts = get_timestamp();
|
||||
entry.get_mut().last_seen_ts = get_aligned_timestamp();
|
||||
true
|
||||
}
|
||||
hashlink::lru_cache::Entry::Vacant(_) => false,
|
||||
@@ -426,7 +426,7 @@ impl NetworkManager {
|
||||
pub fn purge_client_whitelist(&self) {
|
||||
let timeout_ms = self.with_config(|c| c.network.client_whitelist_timeout_ms);
|
||||
let mut inner = self.inner.lock();
|
||||
let cutoff_timestamp = get_timestamp() - ((timeout_ms as u64) * 1000u64);
|
||||
let cutoff_timestamp = get_aligned_timestamp() - ((timeout_ms as u64) * 1000u64);
|
||||
// Remove clients from the whitelist that haven't been since since our whitelist timeout
|
||||
while inner
|
||||
.client_whitelist
|
||||
@@ -526,7 +526,7 @@ impl NetworkManager {
|
||||
.wrap_err("failed to generate signed receipt")?;
|
||||
|
||||
// Record the receipt for later
|
||||
let exp_ts = get_timestamp() + expiration_us;
|
||||
let exp_ts = get_aligned_timestamp() + expiration_us;
|
||||
receipt_manager.record_receipt(receipt, exp_ts, expected_returns, callback);
|
||||
|
||||
Ok(out)
|
||||
@@ -550,7 +550,7 @@ impl NetworkManager {
|
||||
.wrap_err("failed to generate signed receipt")?;
|
||||
|
||||
// Record the receipt for later
|
||||
let exp_ts = get_timestamp() + expiration_us;
|
||||
let exp_ts = get_aligned_timestamp() + expiration_us;
|
||||
let eventual = SingleShotEventual::new(Some(ReceiptEvent::Cancelled));
|
||||
let instance = eventual.instance();
|
||||
receipt_manager.record_single_shot_receipt(receipt, exp_ts, eventual);
|
||||
@@ -717,7 +717,7 @@ impl NetworkManager {
|
||||
// XXX: do we need a delay here? or another hole punch packet?
|
||||
|
||||
// Set the hole punch as our 'last connection' to ensure we return the receipt over the direct hole punch
|
||||
peer_nr.set_last_connection(connection_descriptor, get_timestamp());
|
||||
peer_nr.set_last_connection(connection_descriptor, get_aligned_timestamp());
|
||||
|
||||
// Return the receipt using the same dial info send the receipt to it
|
||||
rpc.rpc_call_return_receipt(Destination::direct(peer_nr), receipt)
|
||||
@@ -741,7 +741,7 @@ impl NetworkManager {
|
||||
let node_id_secret = routing_table.node_id_secret();
|
||||
|
||||
// Get timestamp, nonce
|
||||
let ts = get_timestamp();
|
||||
let ts = get_aligned_timestamp();
|
||||
let nonce = Crypto::get_random_nonce();
|
||||
|
||||
// Encode envelope
|
||||
@@ -1136,7 +1136,7 @@ impl NetworkManager {
|
||||
// );
|
||||
|
||||
// Update timestamp for this last connection since we just sent to it
|
||||
node_ref.set_last_connection(connection_descriptor, get_timestamp());
|
||||
node_ref.set_last_connection(connection_descriptor, get_aligned_timestamp());
|
||||
|
||||
return Ok(NetworkResult::value(SendDataKind::Existing(
|
||||
connection_descriptor,
|
||||
@@ -1168,7 +1168,7 @@ impl NetworkManager {
|
||||
this.net().send_data_to_dial_info(dial_info, data).await?
|
||||
);
|
||||
// If we connected to this node directly, save off the last connection so we can use it again
|
||||
node_ref.set_last_connection(connection_descriptor, get_timestamp());
|
||||
node_ref.set_last_connection(connection_descriptor, get_aligned_timestamp());
|
||||
|
||||
Ok(NetworkResult::value(SendDataKind::Direct(
|
||||
connection_descriptor,
|
||||
@@ -1337,28 +1337,28 @@ impl NetworkManager {
|
||||
// Get timestamp range
|
||||
let (tsbehind, tsahead) = self.with_config(|c| {
|
||||
(
|
||||
c.network.rpc.max_timestamp_behind_ms.map(ms_to_us),
|
||||
c.network.rpc.max_timestamp_ahead_ms.map(ms_to_us),
|
||||
c.network.rpc.max_timestamp_behind_ms.map(ms_to_us).map(TimestampDuration::new),
|
||||
c.network.rpc.max_timestamp_ahead_ms.map(ms_to_us).map(TimestampDuration::new),
|
||||
)
|
||||
});
|
||||
|
||||
// Validate timestamp isn't too old
|
||||
let ts = get_timestamp();
|
||||
let ts = get_aligned_timestamp();
|
||||
let ets = envelope.get_timestamp();
|
||||
if let Some(tsbehind) = tsbehind {
|
||||
if tsbehind > 0 && (ts > ets && ts.saturating_sub(ets) > tsbehind) {
|
||||
if tsbehind.as_u64() != 0 && (ts > ets && ts.saturating_sub(ets) > tsbehind) {
|
||||
log_net!(debug
|
||||
"envelope time was too far in the past: {}ms ",
|
||||
timestamp_to_secs(ts.saturating_sub(ets)) * 1000f64
|
||||
timestamp_to_secs(ts.saturating_sub(ets).as_u64()) * 1000f64
|
||||
);
|
||||
return Ok(false);
|
||||
}
|
||||
}
|
||||
if let Some(tsahead) = tsahead {
|
||||
if tsahead > 0 && (ts < ets && ets.saturating_sub(ts) > tsahead) {
|
||||
if tsahead.as_u64() != 0 && (ts < ets && ets.saturating_sub(ts) > tsahead) {
|
||||
log_net!(debug
|
||||
"envelope time was too far in the future: {}ms",
|
||||
timestamp_to_secs(ets.saturating_sub(ts)) * 1000f64
|
||||
timestamp_to_secs(ets.saturating_sub(ts).as_u64()) * 1000f64
|
||||
);
|
||||
return Ok(false);
|
||||
}
|
||||
@@ -1497,8 +1497,8 @@ impl NetworkManager {
|
||||
if !has_state {
|
||||
return VeilidStateNetwork {
|
||||
started: false,
|
||||
bps_down: 0,
|
||||
bps_up: 0,
|
||||
bps_down: 0.into(),
|
||||
bps_up: 0.into(),
|
||||
peers: Vec::new(),
|
||||
};
|
||||
}
|
||||
@@ -1650,7 +1650,7 @@ impl NetworkManager {
|
||||
// public dialinfo
|
||||
let inconsistent = if inconsistencies.len() >= PUBLIC_ADDRESS_CHANGE_DETECTION_COUNT
|
||||
{
|
||||
let exp_ts = get_timestamp() + PUBLIC_ADDRESS_INCONSISTENCY_TIMEOUT_US;
|
||||
let exp_ts = get_aligned_timestamp() + PUBLIC_ADDRESS_INCONSISTENCY_TIMEOUT_US;
|
||||
for i in &inconsistencies {
|
||||
pait.insert(*i, exp_ts);
|
||||
}
|
||||
@@ -1664,7 +1664,7 @@ impl NetworkManager {
|
||||
.entry(key)
|
||||
.or_insert_with(|| HashMap::new());
|
||||
let exp_ts =
|
||||
get_timestamp() + PUBLIC_ADDRESS_INCONSISTENCY_PUNISHMENT_TIMEOUT_US;
|
||||
get_aligned_timestamp() + PUBLIC_ADDRESS_INCONSISTENCY_PUNISHMENT_TIMEOUT_US;
|
||||
for i in inconsistencies {
|
||||
pait.insert(i, exp_ts);
|
||||
}
|
||||
|
@@ -6,7 +6,7 @@ use std::net::UdpSocket;
|
||||
const UPNP_GATEWAY_DETECT_TIMEOUT_MS: u32 = 5_000;
|
||||
const UPNP_MAPPING_LIFETIME_MS: u32 = 120_000;
|
||||
const UPNP_MAPPING_ATTEMPTS: u32 = 3;
|
||||
const UPNP_MAPPING_LIFETIME_US:u64 = (UPNP_MAPPING_LIFETIME_MS as u64) * 1000u64;
|
||||
const UPNP_MAPPING_LIFETIME_US:TimestampDuration = TimestampDuration::new(UPNP_MAPPING_LIFETIME_MS as u64 * 1000u64);
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
struct PortMapKey {
|
||||
@@ -19,8 +19,8 @@ struct PortMapKey {
|
||||
struct PortMapValue {
|
||||
ext_ip: IpAddr,
|
||||
mapped_port: u16,
|
||||
timestamp: u64,
|
||||
renewal_lifetime: u64,
|
||||
timestamp: Timestamp,
|
||||
renewal_lifetime: TimestampDuration,
|
||||
renewal_attempts: u32,
|
||||
}
|
||||
|
||||
@@ -276,7 +276,7 @@ impl IGDManager {
|
||||
};
|
||||
|
||||
// Add to mapping list to keep alive
|
||||
let timestamp = get_timestamp();
|
||||
let timestamp = get_aligned_timestamp();
|
||||
inner.port_maps.insert(PortMapKey {
|
||||
llpt,
|
||||
at,
|
||||
@@ -285,7 +285,7 @@ impl IGDManager {
|
||||
ext_ip,
|
||||
mapped_port,
|
||||
timestamp,
|
||||
renewal_lifetime: (UPNP_MAPPING_LIFETIME_MS / 2) as u64 * 1000u64,
|
||||
renewal_lifetime: ((UPNP_MAPPING_LIFETIME_MS / 2) as u64 * 1000u64).into(),
|
||||
renewal_attempts: 0,
|
||||
});
|
||||
|
||||
@@ -302,7 +302,7 @@ impl IGDManager {
|
||||
let mut renews: Vec<(PortMapKey, PortMapValue)> = Vec::new();
|
||||
{
|
||||
let inner = self.inner.lock();
|
||||
let now = get_timestamp();
|
||||
let now = get_aligned_timestamp();
|
||||
|
||||
for (k, v) in &inner.port_maps {
|
||||
let mapping_lifetime = now.saturating_sub(v.timestamp);
|
||||
@@ -357,8 +357,8 @@ impl IGDManager {
|
||||
inner.port_maps.insert(k, PortMapValue {
|
||||
ext_ip: v.ext_ip,
|
||||
mapped_port,
|
||||
timestamp: get_timestamp(),
|
||||
renewal_lifetime: (UPNP_MAPPING_LIFETIME_MS / 2) as u64 * 1000u64,
|
||||
timestamp: get_aligned_timestamp(),
|
||||
renewal_lifetime: TimestampDuration::new((UPNP_MAPPING_LIFETIME_MS / 2) as u64 * 1000u64),
|
||||
renewal_attempts: 0,
|
||||
});
|
||||
},
|
||||
@@ -398,8 +398,8 @@ impl IGDManager {
|
||||
inner.port_maps.insert(k, PortMapValue {
|
||||
ext_ip: v.ext_ip,
|
||||
mapped_port: v.mapped_port,
|
||||
timestamp: get_timestamp(),
|
||||
renewal_lifetime: (UPNP_MAPPING_LIFETIME_MS / 2) as u64 * 1000u64,
|
||||
timestamp: get_aligned_timestamp(),
|
||||
renewal_lifetime: ((UPNP_MAPPING_LIFETIME_MS / 2) as u64 * 1000u64).into(),
|
||||
renewal_attempts: 0,
|
||||
});
|
||||
},
|
||||
@@ -407,7 +407,7 @@ impl IGDManager {
|
||||
log_net!(debug "failed to renew mapped port {:?} -> {:?}: {}", v, k, e);
|
||||
|
||||
// Get closer to the maximum renewal timeline by a factor of two each time
|
||||
v.renewal_lifetime = (v.renewal_lifetime + UPNP_MAPPING_LIFETIME_US) / 2;
|
||||
v.renewal_lifetime = (v.renewal_lifetime + UPNP_MAPPING_LIFETIME_US) / 2u64;
|
||||
v.renewal_attempts += 1;
|
||||
|
||||
// Store new value to try again
|
||||
|
@@ -78,19 +78,19 @@ enum RecvLoopAction {
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct NetworkConnectionStats {
|
||||
last_message_sent_time: Option<u64>,
|
||||
last_message_recv_time: Option<u64>,
|
||||
last_message_sent_time: Option<Timestamp>,
|
||||
last_message_recv_time: Option<Timestamp>,
|
||||
}
|
||||
|
||||
|
||||
pub type NetworkConnectionId = u64;
|
||||
pub type NetworkConnectionId = AlignedU64;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct NetworkConnection {
|
||||
connection_id: NetworkConnectionId,
|
||||
descriptor: ConnectionDescriptor,
|
||||
processor: Option<MustJoinHandle<()>>,
|
||||
established_time: u64,
|
||||
established_time: Timestamp,
|
||||
stats: Arc<Mutex<NetworkConnectionStats>>,
|
||||
sender: flume::Sender<(Option<Id>, Vec<u8>)>,
|
||||
stop_source: Option<StopSource>,
|
||||
@@ -105,7 +105,7 @@ impl NetworkConnection {
|
||||
connection_id: id,
|
||||
descriptor,
|
||||
processor: None,
|
||||
established_time: get_timestamp(),
|
||||
established_time: get_aligned_timestamp(),
|
||||
stats: Arc::new(Mutex::new(NetworkConnectionStats {
|
||||
last_message_sent_time: None,
|
||||
last_message_recv_time: None,
|
||||
@@ -153,7 +153,7 @@ impl NetworkConnection {
|
||||
connection_id,
|
||||
descriptor,
|
||||
processor: Some(processor),
|
||||
established_time: get_timestamp(),
|
||||
established_time: get_aligned_timestamp(),
|
||||
stats,
|
||||
sender,
|
||||
stop_source: Some(stop_source),
|
||||
@@ -185,7 +185,7 @@ impl NetworkConnection {
|
||||
stats: Arc<Mutex<NetworkConnectionStats>>,
|
||||
message: Vec<u8>,
|
||||
) -> io::Result<NetworkResult<()>> {
|
||||
let ts = get_timestamp();
|
||||
let ts = get_aligned_timestamp();
|
||||
let out = network_result_try!(protocol_connection.send(message).await?);
|
||||
|
||||
let mut stats = stats.lock();
|
||||
@@ -199,7 +199,7 @@ impl NetworkConnection {
|
||||
protocol_connection: &ProtocolNetworkConnection,
|
||||
stats: Arc<Mutex<NetworkConnectionStats>>,
|
||||
) -> io::Result<NetworkResult<Vec<u8>>> {
|
||||
let ts = get_timestamp();
|
||||
let ts = get_aligned_timestamp();
|
||||
let out = network_result_try!(protocol_connection.recv().await?);
|
||||
|
||||
let mut stats = stats.lock();
|
||||
@@ -217,7 +217,7 @@ impl NetworkConnection {
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn established_time(&self) -> u64 {
|
||||
pub fn established_time(&self) -> Timestamp {
|
||||
self.established_time
|
||||
}
|
||||
|
||||
|
@@ -6,8 +6,8 @@ impl NetworkManager {
|
||||
pub(crate) async fn public_address_check_task_routine(
|
||||
self,
|
||||
stop_token: StopToken,
|
||||
_last_ts: u64,
|
||||
cur_ts: u64,
|
||||
_last_ts: Timestamp,
|
||||
cur_ts: Timestamp,
|
||||
) -> EyreResult<()> {
|
||||
// go through public_address_inconsistencies_table and time out things that have expired
|
||||
let mut inner = self.inner.lock();
|
||||
|
@@ -6,8 +6,8 @@ impl NetworkManager {
|
||||
pub(crate) async fn rolling_transfers_task_routine(
|
||||
self,
|
||||
_stop_token: StopToken,
|
||||
last_ts: u64,
|
||||
cur_ts: u64,
|
||||
last_ts: Timestamp,
|
||||
cur_ts: Timestamp,
|
||||
) -> EyreResult<()> {
|
||||
// log_net!("--- network manager rolling_transfers task");
|
||||
{
|
||||
|
@@ -50,13 +50,13 @@ pub async fn test_add_get_remove() {
|
||||
))),
|
||||
);
|
||||
|
||||
let c1 = NetworkConnection::dummy(1, a1);
|
||||
let c1b = NetworkConnection::dummy(10, a1);
|
||||
let c1 = NetworkConnection::dummy(1.into(), a1);
|
||||
let c1b = NetworkConnection::dummy(10.into(), a1);
|
||||
let c1h = c1.get_handle();
|
||||
let c2 = NetworkConnection::dummy(2, a2);
|
||||
let c3 = NetworkConnection::dummy(3, a3);
|
||||
let c4 = NetworkConnection::dummy(4, a4);
|
||||
let c5 = NetworkConnection::dummy(5, a5);
|
||||
let c2 = NetworkConnection::dummy(2.into(), a2);
|
||||
let c3 = NetworkConnection::dummy(3.into(), a3);
|
||||
let c4 = NetworkConnection::dummy(4.into(), a4);
|
||||
let c5 = NetworkConnection::dummy(5.into(), a5);
|
||||
|
||||
assert_eq!(a1, c2.connection_descriptor());
|
||||
assert_ne!(a3, c4.connection_descriptor());
|
||||
@@ -68,8 +68,8 @@ pub async fn test_add_get_remove() {
|
||||
assert!(table.add_connection(c1b).is_err());
|
||||
|
||||
assert_eq!(table.connection_count(), 1);
|
||||
assert!(table.remove_connection_by_id(4).is_none());
|
||||
assert!(table.remove_connection_by_id(5).is_none());
|
||||
assert!(table.remove_connection_by_id(4.into()).is_none());
|
||||
assert!(table.remove_connection_by_id(5.into()).is_none());
|
||||
assert_eq!(table.connection_count(), 1);
|
||||
assert_eq!(table.get_connection_by_descriptor(a1), Some(c1h.clone()));
|
||||
assert_eq!(table.get_connection_by_descriptor(a1), Some(c1h.clone()));
|
||||
@@ -81,41 +81,41 @@ pub async fn test_add_get_remove() {
|
||||
assert_eq!(table.connection_count(), 1);
|
||||
assert_eq!(
|
||||
table
|
||||
.remove_connection_by_id(1)
|
||||
.remove_connection_by_id(1.into())
|
||||
.map(|c| c.connection_descriptor())
|
||||
.unwrap(),
|
||||
a1
|
||||
);
|
||||
assert_eq!(table.connection_count(), 0);
|
||||
assert!(table.remove_connection_by_id(2).is_none());
|
||||
assert!(table.remove_connection_by_id(2.into()).is_none());
|
||||
assert_eq!(table.connection_count(), 0);
|
||||
assert_eq!(table.get_connection_by_descriptor(a2), None);
|
||||
assert_eq!(table.get_connection_by_descriptor(a1), None);
|
||||
assert_eq!(table.connection_count(), 0);
|
||||
let c1 = NetworkConnection::dummy(6, a1);
|
||||
let c1 = NetworkConnection::dummy(6.into(), a1);
|
||||
table.add_connection(c1).unwrap();
|
||||
let c2 = NetworkConnection::dummy(7, a2);
|
||||
let c2 = NetworkConnection::dummy(7.into(), a2);
|
||||
assert_err!(table.add_connection(c2));
|
||||
table.add_connection(c3).unwrap();
|
||||
table.add_connection(c4).unwrap();
|
||||
assert_eq!(table.connection_count(), 3);
|
||||
assert_eq!(
|
||||
table
|
||||
.remove_connection_by_id(6)
|
||||
.remove_connection_by_id(6.into())
|
||||
.map(|c| c.connection_descriptor())
|
||||
.unwrap(),
|
||||
a2
|
||||
);
|
||||
assert_eq!(
|
||||
table
|
||||
.remove_connection_by_id(3)
|
||||
.remove_connection_by_id(3.into())
|
||||
.map(|c| c.connection_descriptor())
|
||||
.unwrap(),
|
||||
a3
|
||||
);
|
||||
assert_eq!(
|
||||
table
|
||||
.remove_connection_by_id(4)
|
||||
.remove_connection_by_id(4.into())
|
||||
.map(|c| c.connection_descriptor())
|
||||
.unwrap(),
|
||||
a4
|
||||
|
Reference in New Issue
Block a user