blob: effbfe6d05cdaeb6a85b62cf048b1ee4e0697775 [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
use fidl_fuchsia_overnet_protocol::TRANSFER_KEY_LENGTH;
use rand::Rng;
use std::array::TryFromSliceError;
use std::convert::{TryFrom, TryInto};
use std::net::{IpAddr, SocketAddr};
pub use quic::Endpoint;
/// Labels a node with a mesh-unique address
#[derive(PartialEq, PartialOrd, Eq, Ord, Clone, Copy, Hash, Debug)]
pub struct NodeId(pub u64);
impl From<u64> for NodeId {
fn from(id: u64) -> Self {
NodeId(id)
}
}
impl From<NodeId> for fidl_fuchsia_overnet_protocol::NodeId {
fn from(id: NodeId) -> Self {
Self { id: id.0 }
}
}
impl From<&NodeId> for fidl_fuchsia_overnet_protocol::NodeId {
fn from(id: &NodeId) -> Self {
Self { id: id.0 }
}
}
impl From<fidl_fuchsia_overnet_protocol::NodeId> for NodeId {
fn from(id: fidl_fuchsia_overnet_protocol::NodeId) -> Self {
id.id.into()
}
}
impl NodeId {
/// Packs this node ID into a link-local IPv6 address. QUIC needs addresses to associate with
/// connections on occasion and this is a good enough way to provide that.
pub fn to_ipv6_repr(self: NodeId) -> SocketAddr {
let mut addr = [0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
addr[8..].copy_from_slice(&self.0.to_be_bytes());
SocketAddr::new(IpAddr::from(addr), 65535)
}
}
/// Labels a link with a node-unique identifier
#[derive(PartialEq, PartialOrd, Eq, Ord, Clone, Copy, Debug, Hash)]
pub struct NodeLinkId(pub u64);
impl From<u64> for NodeLinkId {
fn from(id: u64) -> Self {
NodeLinkId(id)
}
}
pub(crate) type TransferKey = [u8; TRANSFER_KEY_LENGTH as usize];
pub(crate) fn generate_transfer_key() -> TransferKey {
rand::thread_rng().gen::<TransferKey>()
}
/// Labels a quic connection
#[derive(PartialEq, PartialOrd, Eq, Ord, Clone, Copy, Hash)]
pub struct ConnectionId([u8; quiche::MAX_CONN_ID_LEN]);
impl ConnectionId {
/// Create a new (random) ConnectionId
pub fn new() -> Self {
ConnectionId(rand::thread_rng().gen())
}
fn from_slice(slice: &[u8]) -> Result<Self, TryFromSliceError> {
Ok(ConnectionId(slice.try_into()?))
}
/// Convert this ConnectionId into an array of bytes
pub fn to_array(&self) -> [u8; quiche::MAX_CONN_ID_LEN] {
self.0
}
}
impl std::fmt::Debug for ConnectionId {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str("ConnectionId(")?;
base64::encode(&self.0).fmt(f)?;
f.write_str(")")
}
}
impl TryFrom<&[u8]> for ConnectionId {
type Error = TryFromSliceError;
fn try_from(slice: &[u8]) -> Result<Self, Self::Error> {
ConnectionId::from_slice(slice)
}
}
impl TryFrom<&Vec<u8>> for ConnectionId {
type Error = TryFromSliceError;
fn try_from(vec: &Vec<u8>) -> Result<Self, Self::Error> {
ConnectionId::from_slice(vec.as_slice())
}
}
impl TryFrom<Vec<u8>> for ConnectionId {
type Error = TryFromSliceError;
fn try_from(vec: Vec<u8>) -> Result<Self, Self::Error> {
ConnectionId::from_slice(vec.as_slice())
}
}