2023-02-15 10:14:13 +00:00
|
|
|
//! Connection handling and send/receive queues
|
|
|
|
|
2023-02-15 14:50:54 +00:00
|
|
|
pub mod handshake;
|
2023-05-23 16:20:08 +00:00
|
|
|
pub mod packet;
|
2023-05-17 10:05:13 +00:00
|
|
|
pub mod socket;
|
2023-06-19 16:37:28 +00:00
|
|
|
pub mod stream;
|
2023-02-15 14:50:54 +00:00
|
|
|
|
2023-06-22 10:50:47 +00:00
|
|
|
use ::core::num::Wrapping;
|
|
|
|
use ::std::{
|
|
|
|
collections::{BTreeMap, HashMap},
|
|
|
|
vec::Vec,
|
|
|
|
};
|
2023-02-15 14:50:54 +00:00
|
|
|
|
2023-06-19 16:37:28 +00:00
|
|
|
pub use crate::connection::{handshake::Handshake, packet::Packet};
|
2023-02-15 14:50:54 +00:00
|
|
|
|
2023-05-24 15:30:15 +00:00
|
|
|
use crate::{
|
2023-05-28 16:23:14 +00:00
|
|
|
dnssec,
|
2023-05-24 15:30:15 +00:00
|
|
|
enc::{
|
2023-05-28 16:23:14 +00:00
|
|
|
asym::PubKey,
|
2023-05-30 11:47:08 +00:00
|
|
|
hkdf::Hkdf,
|
2023-06-19 17:26:21 +00:00
|
|
|
sym::{self, CipherRecv, CipherSend},
|
2023-05-30 08:52:54 +00:00
|
|
|
Random,
|
2023-05-24 15:30:15 +00:00
|
|
|
},
|
2023-06-20 16:22:34 +00:00
|
|
|
inner::{worker, ThreadTracker},
|
2023-02-26 09:44:21 +00:00
|
|
|
};
|
2023-06-19 16:37:28 +00:00
|
|
|
|
|
|
|
/// Fenrir Connection ID
|
|
|
|
///
|
|
|
|
/// 0 is special as it represents the handshake
|
|
|
|
/// Connection IDs are to be considered u64 little endian
|
|
|
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
|
|
|
pub enum ID {
|
|
|
|
/// Connection id 0 represent the handshake
|
|
|
|
Handshake,
|
|
|
|
/// Non-zero id can represent any connection
|
|
|
|
ID(::core::num::NonZeroU64),
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ID {
|
|
|
|
/// Set the conenction id to handshake
|
|
|
|
pub fn new_handshake() -> Self {
|
|
|
|
Self::Handshake
|
|
|
|
}
|
|
|
|
/// New id from u64. PLZ NON ZERO
|
|
|
|
pub(crate) fn new_u64(raw: u64) -> Self {
|
|
|
|
#[allow(unsafe_code)]
|
|
|
|
unsafe {
|
|
|
|
ID::ID(::core::num::NonZeroU64::new_unchecked(raw))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
pub(crate) fn as_u64(&self) -> u64 {
|
|
|
|
match self {
|
|
|
|
ID::Handshake => 0,
|
|
|
|
ID::ID(id) => id.get(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/// New random service ID
|
|
|
|
pub fn new_rand(rand: &Random) -> Self {
|
|
|
|
let mut raw = [0; 8];
|
|
|
|
let mut num = 0;
|
|
|
|
while num == 0 {
|
|
|
|
rand.fill(&mut raw);
|
|
|
|
num = u64::from_le_bytes(raw);
|
|
|
|
}
|
|
|
|
#[allow(unsafe_code)]
|
|
|
|
unsafe {
|
|
|
|
ID::ID(::core::num::NonZeroU64::new_unchecked(num))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/// Quick check to know if this is an handshake
|
|
|
|
pub fn is_handshake(&self) -> bool {
|
|
|
|
*self == ID::Handshake
|
|
|
|
}
|
|
|
|
/// length if the connection ID in bytes
|
|
|
|
pub const fn len() -> usize {
|
|
|
|
8
|
|
|
|
}
|
|
|
|
/// write the ID to a buffer
|
|
|
|
pub fn serialize(&self, out: &mut [u8]) {
|
|
|
|
match self {
|
|
|
|
ID::Handshake => out[..8].copy_from_slice(&[0; 8]),
|
|
|
|
ID::ID(id) => out[..8].copy_from_slice(&id.get().to_le_bytes()),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<u64> for ID {
|
|
|
|
fn from(raw: u64) -> Self {
|
|
|
|
if raw == 0 {
|
|
|
|
ID::Handshake
|
|
|
|
} else {
|
|
|
|
#[allow(unsafe_code)]
|
|
|
|
unsafe {
|
|
|
|
ID::ID(::core::num::NonZeroU64::new_unchecked(raw))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<[u8; 8]> for ID {
|
|
|
|
fn from(raw: [u8; 8]) -> Self {
|
|
|
|
let raw_u64 = u64::from_le_bytes(raw);
|
|
|
|
raw_u64.into()
|
|
|
|
}
|
|
|
|
}
|
2023-02-26 09:44:21 +00:00
|
|
|
|
2023-05-22 13:05:17 +00:00
|
|
|
/// strong typedef for receiving connection id
|
2023-06-19 16:37:28 +00:00
|
|
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
2023-05-22 13:05:17 +00:00
|
|
|
pub struct IDRecv(pub ID);
|
|
|
|
/// strong typedef for sending connection id
|
2023-06-19 16:37:28 +00:00
|
|
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
2023-05-22 13:05:17 +00:00
|
|
|
pub struct IDSend(pub ID);
|
|
|
|
|
2023-02-15 14:50:54 +00:00
|
|
|
/// Version of the fenrir protocol in use
|
2023-06-09 18:01:18 +00:00
|
|
|
#[derive(::num_derive::FromPrimitive, Debug, Copy, Clone, PartialEq)]
|
2023-02-15 14:50:54 +00:00
|
|
|
#[repr(u8)]
|
|
|
|
pub enum ProtocolVersion {
|
|
|
|
/// First Fenrir Protocol Version
|
|
|
|
V0 = 0,
|
|
|
|
}
|
2023-02-25 14:36:14 +00:00
|
|
|
impl ProtocolVersion {
|
|
|
|
/// actual length of the protocol version field
|
|
|
|
pub const fn len() -> usize {
|
|
|
|
1
|
|
|
|
}
|
|
|
|
/// Serialize into raw bytes
|
|
|
|
pub fn serialize(&self, out: &mut u8) {
|
|
|
|
*out = *self as u8;
|
|
|
|
}
|
|
|
|
}
|
2023-02-25 21:25:52 +00:00
|
|
|
|
2023-06-22 10:50:47 +00:00
|
|
|
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd)]
|
|
|
|
pub(crate) struct UserConnTracker(Wrapping<usize>);
|
2023-06-20 16:22:34 +00:00
|
|
|
impl UserConnTracker {
|
|
|
|
fn advance(&mut self) -> Self {
|
|
|
|
let old = self.0;
|
2023-06-22 10:50:47 +00:00
|
|
|
self.0 = self.0 + Wrapping(1);
|
2023-06-20 16:22:34 +00:00
|
|
|
UserConnTracker(old)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Connection to an Authentication Server
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct AuthSrvConn(pub(crate) Conn);
|
|
|
|
/// Connection to a service
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct ServiceConn(pub(crate) Conn);
|
|
|
|
|
2023-06-19 16:37:28 +00:00
|
|
|
/// The connection, as seen from a user of libFenrir
|
|
|
|
#[derive(Debug)]
|
2023-06-20 16:22:34 +00:00
|
|
|
pub struct Conn {
|
|
|
|
pub(crate) queue: ::async_channel::Sender<worker::Work>,
|
|
|
|
pub(crate) conn: UserConnTracker,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Conn {
|
|
|
|
/// Queue some data to be sent in this connection
|
2023-06-22 10:50:47 +00:00
|
|
|
// TODO: send_and_wait, that wait for recipient ACK
|
|
|
|
pub async fn send(&mut self, stream: stream::ID, data: Vec<u8>) {
|
|
|
|
use crate::inner::worker::Work;
|
|
|
|
let _ = self
|
|
|
|
.queue
|
|
|
|
.send(Work::UserSend((self.conn, stream, data)))
|
|
|
|
.await;
|
2023-06-20 16:22:34 +00:00
|
|
|
}
|
|
|
|
}
|
2023-06-19 16:37:28 +00:00
|
|
|
|
2023-02-25 21:25:52 +00:00
|
|
|
/// A single connection and its data
|
|
|
|
#[derive(Debug)]
|
2023-06-20 16:22:34 +00:00
|
|
|
pub(crate) struct Connection {
|
2023-06-19 16:37:28 +00:00
|
|
|
/// Receiving Conn ID
|
2023-06-22 10:50:47 +00:00
|
|
|
pub(crate) id_recv: IDRecv,
|
2023-06-19 16:37:28 +00:00
|
|
|
/// Sending Conn ID
|
2023-06-22 10:50:47 +00:00
|
|
|
pub(crate) id_send: IDSend,
|
2023-02-25 21:25:52 +00:00
|
|
|
/// The main hkdf used for all secrets in this connection
|
2023-06-22 10:50:47 +00:00
|
|
|
hkdf: Hkdf,
|
2023-02-26 09:44:21 +00:00
|
|
|
/// Cipher for decrypting data
|
2023-06-22 10:50:47 +00:00
|
|
|
pub(crate) cipher_recv: CipherRecv,
|
2023-02-26 09:44:21 +00:00
|
|
|
/// Cipher for encrypting data
|
2023-06-22 10:50:47 +00:00
|
|
|
pub(crate) cipher_send: CipherSend,
|
|
|
|
/// send queue for each Stream
|
|
|
|
send_queue: BTreeMap<stream::ID, Vec<Vec<u8>>>,
|
2023-02-26 09:44:21 +00:00
|
|
|
}
|
|
|
|
|
2023-06-19 16:37:28 +00:00
|
|
|
/// Role: track the connection direction
|
|
|
|
///
|
|
|
|
/// The Role is used to select the correct secrets, and track the direction
|
|
|
|
/// of the connection
|
|
|
|
/// * Server: Conn is Incoming
|
|
|
|
/// * Client: Conn is Outgoing
|
2023-02-26 09:44:21 +00:00
|
|
|
#[derive(Debug, Copy, Clone)]
|
|
|
|
#[repr(u8)]
|
|
|
|
pub enum Role {
|
|
|
|
/// Server: we receive the connection
|
|
|
|
Server = 0,
|
|
|
|
/// Client: we initate the connection
|
|
|
|
Client,
|
2023-02-25 21:25:52 +00:00
|
|
|
}
|
|
|
|
|
2023-06-20 16:22:34 +00:00
|
|
|
impl Connection {
|
2023-03-01 17:20:03 +00:00
|
|
|
pub(crate) fn new(
|
2023-05-30 11:47:08 +00:00
|
|
|
hkdf: Hkdf,
|
2023-06-19 17:26:21 +00:00
|
|
|
cipher: sym::Kind,
|
2023-03-01 17:20:03 +00:00
|
|
|
role: Role,
|
2023-05-30 08:52:54 +00:00
|
|
|
rand: &Random,
|
2023-03-01 17:20:03 +00:00
|
|
|
) -> Self {
|
2023-02-26 09:44:21 +00:00
|
|
|
let (secret_recv, secret_send) = match role {
|
|
|
|
Role::Server => {
|
|
|
|
(hkdf.get_secret(b"to_server"), hkdf.get_secret(b"to_client"))
|
|
|
|
}
|
|
|
|
Role::Client => {
|
|
|
|
(hkdf.get_secret(b"to_client"), hkdf.get_secret(b"to_server"))
|
|
|
|
}
|
|
|
|
};
|
2023-05-26 13:02:21 +00:00
|
|
|
let cipher_recv = CipherRecv::new(cipher, secret_recv);
|
|
|
|
let cipher_send = CipherSend::new(cipher, secret_send, rand);
|
2023-02-26 09:44:21 +00:00
|
|
|
|
|
|
|
Self {
|
2023-05-22 13:05:17 +00:00
|
|
|
id_recv: IDRecv(ID::Handshake),
|
|
|
|
id_send: IDSend(ID::Handshake),
|
2023-02-26 09:44:21 +00:00
|
|
|
hkdf,
|
|
|
|
cipher_recv,
|
|
|
|
cipher_send,
|
2023-06-22 10:50:47 +00:00
|
|
|
send_queue: BTreeMap::new(),
|
2023-02-26 09:44:21 +00:00
|
|
|
}
|
2023-02-25 21:25:52 +00:00
|
|
|
}
|
2023-06-22 10:50:47 +00:00
|
|
|
pub(crate) fn send(&mut self, stream: stream::ID, data: Vec<u8>) {
|
|
|
|
let stream = match self.send_queue.get_mut(&stream) {
|
|
|
|
None => return,
|
|
|
|
Some(stream) => stream,
|
|
|
|
};
|
|
|
|
stream.push(data);
|
|
|
|
}
|
2023-02-25 21:25:52 +00:00
|
|
|
}
|
2023-05-17 10:05:13 +00:00
|
|
|
|
|
|
|
pub(crate) struct ConnList {
|
2023-05-24 15:30:15 +00:00
|
|
|
thread_id: ThreadTracker,
|
2023-06-22 10:50:47 +00:00
|
|
|
connections: Vec<Option<Connection>>,
|
|
|
|
user_tracker: BTreeMap<UserConnTracker, usize>,
|
2023-06-20 16:22:34 +00:00
|
|
|
last_tracked: UserConnTracker,
|
2023-05-17 10:05:13 +00:00
|
|
|
/// Bitmap to track which connection ids are used or free
|
|
|
|
ids_used: Vec<::bitmaps::Bitmap<1024>>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ConnList {
|
2023-05-24 15:30:15 +00:00
|
|
|
pub(crate) fn new(thread_id: ThreadTracker) -> Self {
|
2023-06-17 09:33:47 +00:00
|
|
|
let mut bitmap_id = ::bitmaps::Bitmap::<1024>::new();
|
|
|
|
if thread_id.id == 0 {
|
|
|
|
// make sure we don't count the Handshake ID
|
|
|
|
bitmap_id.set(0, true);
|
|
|
|
}
|
2023-05-26 13:02:21 +00:00
|
|
|
const INITIAL_CAP: usize = 128;
|
|
|
|
let mut ret = Self {
|
2023-05-24 15:30:15 +00:00
|
|
|
thread_id,
|
2023-05-26 13:02:21 +00:00
|
|
|
connections: Vec::with_capacity(INITIAL_CAP),
|
2023-06-22 10:50:47 +00:00
|
|
|
user_tracker: BTreeMap::new(),
|
|
|
|
last_tracked: UserConnTracker(Wrapping(0)),
|
2023-05-17 10:05:13 +00:00
|
|
|
ids_used: vec![bitmap_id],
|
2023-05-26 13:02:21 +00:00
|
|
|
};
|
|
|
|
ret.connections.resize_with(INITIAL_CAP, || None);
|
|
|
|
ret
|
2023-05-17 10:05:13 +00:00
|
|
|
}
|
2023-06-22 10:50:47 +00:00
|
|
|
pub fn get_mut(
|
|
|
|
&mut self,
|
|
|
|
tracker: UserConnTracker,
|
|
|
|
) -> Option<&mut Connection> {
|
|
|
|
let idx = if let Some(idx) = self.user_tracker.get(&tracker) {
|
|
|
|
*idx
|
|
|
|
} else {
|
|
|
|
return None;
|
|
|
|
};
|
|
|
|
match &mut self.connections[idx] {
|
|
|
|
None => None,
|
|
|
|
Some(conn) => Some(conn),
|
|
|
|
}
|
|
|
|
}
|
2023-05-27 08:57:15 +00:00
|
|
|
pub fn len(&self) -> usize {
|
|
|
|
let mut total: usize = 0;
|
|
|
|
for bitmap in self.ids_used.iter() {
|
|
|
|
total = total + bitmap.len()
|
|
|
|
}
|
|
|
|
total
|
|
|
|
}
|
2023-05-26 13:02:21 +00:00
|
|
|
/// Only *Reserve* a connection,
|
|
|
|
/// without actually tracking it in self.connections
|
2023-06-05 07:18:32 +00:00
|
|
|
pub(crate) fn reserve_first(&mut self) -> IDRecv {
|
2023-05-17 10:05:13 +00:00
|
|
|
// uhm... bad things are going on here:
|
|
|
|
// * id must be initialized, but only because:
|
|
|
|
// * rust does not understand that after the `!found` id is always
|
|
|
|
// initialized
|
|
|
|
// * `ID::new_u64` is really safe only with >0, but here it always is
|
|
|
|
// ...we should probably rewrite it in better, safer rust
|
2023-05-26 13:02:21 +00:00
|
|
|
let mut id_in_thread: usize = 0;
|
2023-05-17 10:05:13 +00:00
|
|
|
let mut found = false;
|
|
|
|
for (i, b) in self.ids_used.iter_mut().enumerate() {
|
|
|
|
match b.first_false_index() {
|
|
|
|
Some(idx) => {
|
|
|
|
b.set(idx, true);
|
2023-05-26 13:02:21 +00:00
|
|
|
id_in_thread = (i * 1024) + idx;
|
2023-05-17 10:05:13 +00:00
|
|
|
found = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
None => {}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if !found {
|
|
|
|
let mut new_bitmap = ::bitmaps::Bitmap::<1024>::new();
|
|
|
|
new_bitmap.set(0, true);
|
2023-05-26 13:02:21 +00:00
|
|
|
id_in_thread = self.ids_used.len() * 1024;
|
2023-05-17 10:05:13 +00:00
|
|
|
self.ids_used.push(new_bitmap);
|
|
|
|
}
|
2023-05-26 13:02:21 +00:00
|
|
|
// make sure we have enough space in self.connections
|
|
|
|
let curr_capacity = self.connections.capacity();
|
|
|
|
if self.connections.capacity() <= id_in_thread {
|
|
|
|
// Fill with "None", assure 64 connections without reallocations
|
|
|
|
let multiple = 64 + curr_capacity - 1;
|
|
|
|
let new_capacity = multiple - (multiple % curr_capacity);
|
|
|
|
self.connections.resize_with(new_capacity, || None);
|
|
|
|
}
|
|
|
|
// calculate the actual connection ID
|
|
|
|
let actual_id = ((id_in_thread as u64) * (self.thread_id.total as u64))
|
2023-05-24 15:30:15 +00:00
|
|
|
+ (self.thread_id.id as u64);
|
|
|
|
let new_id = IDRecv(ID::new_u64(actual_id));
|
2023-06-05 07:18:32 +00:00
|
|
|
new_id
|
2023-05-26 13:02:21 +00:00
|
|
|
}
|
|
|
|
/// NOTE: does NOT check if the connection has been previously reserved!
|
2023-06-20 16:22:34 +00:00
|
|
|
pub(crate) fn track(
|
|
|
|
&mut self,
|
2023-06-22 10:50:47 +00:00
|
|
|
conn: Connection,
|
2023-06-20 16:22:34 +00:00
|
|
|
) -> Result<UserConnTracker, ()> {
|
2023-05-26 13:02:21 +00:00
|
|
|
let conn_id = match conn.id_recv {
|
|
|
|
IDRecv(ID::Handshake) => {
|
|
|
|
return Err(());
|
|
|
|
}
|
|
|
|
IDRecv(ID::ID(conn_id)) => conn_id,
|
|
|
|
};
|
|
|
|
let id_in_thread: usize =
|
|
|
|
(conn_id.get() / (self.thread_id.total as u64)) as usize;
|
|
|
|
self.connections[id_in_thread] = Some(conn);
|
2023-06-22 10:50:47 +00:00
|
|
|
let mut tracked;
|
|
|
|
loop {
|
|
|
|
tracked = self.last_tracked.advance();
|
|
|
|
if self.user_tracker.get(&tracked).is_none() {
|
|
|
|
let _ = self.user_tracker.insert(tracked, id_in_thread);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2023-06-20 16:22:34 +00:00
|
|
|
Ok(tracked)
|
2023-05-26 13:02:21 +00:00
|
|
|
}
|
2023-06-06 20:37:34 +00:00
|
|
|
pub(crate) fn remove(&mut self, id: IDRecv) {
|
2023-05-26 13:02:21 +00:00
|
|
|
if let IDRecv(ID::ID(raw_id)) = id {
|
|
|
|
let id_in_thread: usize =
|
|
|
|
(raw_id.get() / (self.thread_id.total as u64)) as usize;
|
|
|
|
let vec_index = id_in_thread / 1024;
|
|
|
|
let bitmask_index = id_in_thread % 1024;
|
|
|
|
if let Some(bitmask) = self.ids_used.get_mut(vec_index) {
|
|
|
|
bitmask.set(bitmask_index, false);
|
|
|
|
self.connections[id_in_thread] = None;
|
|
|
|
}
|
2023-05-17 10:05:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-05-28 13:26:17 +00:00
|
|
|
|
2023-05-28 16:23:14 +00:00
|
|
|
/// return wether we already have a connection, we are waiting for one, or you
|
|
|
|
/// can start one
|
|
|
|
#[derive(Debug, Clone, Copy)]
|
|
|
|
pub(crate) enum Reservation {
|
|
|
|
/// we already have a connection. use this ID.
|
|
|
|
Present(IDSend),
|
|
|
|
/// we don't have a connection, but we are waiting for one to be established.
|
|
|
|
Waiting,
|
|
|
|
/// we have reserved a spot for your connection.
|
|
|
|
Reserved,
|
|
|
|
}
|
|
|
|
|
2023-06-17 09:33:47 +00:00
|
|
|
enum MapEntry {
|
|
|
|
Present(IDSend),
|
|
|
|
Reserved,
|
|
|
|
}
|
|
|
|
|
2023-05-28 16:23:14 +00:00
|
|
|
/// Link the public key of the authentication server to a connection id
|
|
|
|
/// so that we can reuse that connection to ask for more authentications
|
|
|
|
///
|
|
|
|
/// Note that a server can have multiple public keys,
|
|
|
|
/// and the handshake will only ever verify one.
|
|
|
|
/// To avoid malicious publication fo keys that are not yours,
|
|
|
|
/// on connection we:
|
|
|
|
/// * reserve all public keys of the server
|
|
|
|
/// * wait for the connection to finish
|
|
|
|
/// * remove all those reservations, exept the one key that actually succeded
|
|
|
|
/// While searching, we return a connection ID if just one key is a match
|
2023-06-17 09:33:47 +00:00
|
|
|
// TODO: can we shard this per-core by hashing the pubkey? or domain? or...???
|
|
|
|
// This needs a mutex and it will be our goeal to avoid any synchronization
|
2023-05-28 13:26:17 +00:00
|
|
|
pub(crate) struct AuthServerConnections {
|
2023-05-28 16:23:14 +00:00
|
|
|
conn_map: HashMap<PubKey, MapEntry>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl AuthServerConnections {
|
|
|
|
pub(crate) fn new() -> Self {
|
|
|
|
Self {
|
|
|
|
conn_map: HashMap::with_capacity(32),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/// add an ID to the reserved spot,
|
|
|
|
/// and unlock the other pubkeys which have not been verified
|
|
|
|
pub(crate) fn add(
|
|
|
|
&mut self,
|
|
|
|
pubkey: &PubKey,
|
|
|
|
id: IDSend,
|
|
|
|
record: &dnssec::Record,
|
|
|
|
) {
|
|
|
|
let _ = self.conn_map.insert(*pubkey, MapEntry::Present(id));
|
|
|
|
for (_, pk) in record.public_keys.iter() {
|
|
|
|
if pk == pubkey {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
let _ = self.conn_map.remove(pk);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/// remove a dropped connection
|
|
|
|
pub(crate) fn remove_reserved(&mut self, record: &dnssec::Record) {
|
|
|
|
for (_, pk) in record.public_keys.iter() {
|
|
|
|
let _ = self.conn_map.remove(pk);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/// remove a dropped connection
|
|
|
|
pub(crate) fn remove_conn(&mut self, pubkey: &PubKey) {
|
|
|
|
let _ = self.conn_map.remove(pubkey);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// each dnssec::Record has multiple Pubkeys. reserve and ID for them all.
|
|
|
|
/// later on, when `add` is called we will delete
|
|
|
|
/// those that have not actually benn used
|
|
|
|
pub(crate) fn get_or_reserve(
|
|
|
|
&mut self,
|
|
|
|
record: &dnssec::Record,
|
|
|
|
) -> Reservation {
|
|
|
|
for (_, pk) in record.public_keys.iter() {
|
|
|
|
match self.conn_map.get(pk) {
|
|
|
|
None => {}
|
|
|
|
Some(MapEntry::Reserved) => return Reservation::Waiting,
|
|
|
|
Some(MapEntry::Present(id)) => {
|
|
|
|
return Reservation::Present(id.clone())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for (_, pk) in record.public_keys.iter() {
|
|
|
|
let _ = self.conn_map.insert(*pk, MapEntry::Reserved);
|
|
|
|
}
|
|
|
|
Reservation::Reserved
|
|
|
|
}
|
2023-05-28 13:26:17 +00:00
|
|
|
}
|