veilid/veilid-core/src/connection_table.rs

95 lines
3.0 KiB
Rust
Raw Normal View History

2022-01-04 04:58:26 +00:00
use crate::network_connection::*;
2021-11-22 16:28:30 +00:00
use crate::xx::*;
use crate::*;
2022-01-05 17:01:02 +00:00
use alloc::collections::btree_map::Entry;
2021-11-22 16:28:30 +00:00
#[derive(Debug)]
pub struct ConnectionTable {
2022-01-05 17:01:02 +00:00
conn_by_descriptor: BTreeMap<ConnectionDescriptor, NetworkConnection>,
conns_by_remote: BTreeMap<PeerAddress, Vec<NetworkConnection>>,
2021-11-22 16:28:30 +00:00
}
impl ConnectionTable {
pub fn new() -> Self {
Self {
2022-01-05 17:01:02 +00:00
conn_by_descriptor: BTreeMap::new(),
conns_by_remote: BTreeMap::new(),
2021-11-22 16:28:30 +00:00
}
}
2022-01-04 04:58:26 +00:00
pub fn add_connection(&mut self, conn: NetworkConnection) -> Result<(), String> {
let descriptor = conn.connection_descriptor();
2021-11-22 16:28:30 +00:00
assert_ne!(
descriptor.protocol_type(),
ProtocolType::UDP,
"Only connection oriented protocols go in the table!"
);
2022-01-05 17:01:02 +00:00
if self.conn_by_descriptor.contains_key(&descriptor) {
2021-12-14 14:48:33 +00:00
return Err(format!(
"Connection already added to table: {:?}",
descriptor
));
2021-11-22 16:28:30 +00:00
}
2022-01-05 17:01:02 +00:00
let res = self.conn_by_descriptor.insert(descriptor, conn.clone());
2021-11-22 16:28:30 +00:00
assert!(res.is_none());
2022-01-05 17:01:02 +00:00
let conns = self.conns_by_remote.entry(descriptor.remote).or_default();
2022-01-05 21:58:18 +00:00
//warn!("add_connection: {:?}", conn);
2022-01-05 17:01:02 +00:00
conns.push(conn);
2022-01-04 14:53:30 +00:00
Ok(())
2021-11-22 16:28:30 +00:00
}
2022-01-04 19:25:32 +00:00
pub fn get_connection(&self, descriptor: ConnectionDescriptor) -> Option<NetworkConnection> {
2022-01-05 17:01:02 +00:00
let out = self.conn_by_descriptor.get(&descriptor).cloned();
2022-01-05 21:58:18 +00:00
//warn!("get_connection: {:?} -> {:?}", descriptor, out);
2022-01-05 17:01:02 +00:00
out
}
pub fn get_last_connection_by_remote(&self, remote: PeerAddress) -> Option<NetworkConnection> {
let out = self
.conns_by_remote
.get(&remote)
.map(|v| v[(v.len() - 1)].clone());
2022-01-05 21:58:18 +00:00
//warn!("get_last_connection_by_remote: {:?} -> {:?}", remote, out);
2022-01-05 17:01:02 +00:00
out
2021-11-22 16:28:30 +00:00
}
pub fn connection_count(&self) -> usize {
2022-01-05 17:01:02 +00:00
self.conn_by_descriptor.len()
2021-11-22 16:28:30 +00:00
}
pub fn remove_connection(
&mut self,
2022-01-04 19:25:32 +00:00
descriptor: ConnectionDescriptor,
2022-01-04 14:53:30 +00:00
) -> Result<NetworkConnection, String> {
2022-01-05 21:58:18 +00:00
//warn!("remove_connection: {:?}", descriptor);
2022-01-05 17:01:02 +00:00
let out = self
.conn_by_descriptor
2022-01-04 19:25:32 +00:00
.remove(&descriptor)
2022-01-05 17:01:02 +00:00
.ok_or_else(|| format!("Connection not in table: {:?}", descriptor))?;
match self.conns_by_remote.entry(descriptor.remote) {
Entry::Vacant(_) => {
panic!("inconsistency in connection table")
}
Entry::Occupied(mut o) => {
let v = o.get_mut();
// Remove one matching connection from the list
for (n, elem) in v.iter().enumerate() {
if elem.connection_descriptor() == descriptor {
v.remove(n);
break;
}
}
// No connections left for this remote, remove the entry from conns_by_remote
if v.is_empty() {
o.remove_entry();
}
}
}
Ok(out)
2021-11-22 16:28:30 +00:00
}
}