// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 //! Defines the internal connection ID /// A connection ID which is stable and internally identifies a connection over /// the whole lifetime of an endpoint. #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct InternalConnectionId(u64); /// Generates internal connection IDs. /// /// Connection IDs are only internal if they are generated by the same generator. pub struct InternalConnectionIdGenerator { next: u64, } impl InternalConnectionIdGenerator { /// Returns a new InternalConnectionIdGenerator pub fn new() -> Self { Self { next: 0 } } /// Returns a new InternalConnectionId pub fn generate_id(&mut self) -> InternalConnectionId { let result = self.next; // This should never happen in production. // If the generator generates 1 million IDs per second, // the number will overflow after 213503982 days of operation. // Even with 1 billion IDs per second - which requires the CPU to spend // a significant amount of time generating IDs - it will take years to // overflow. self.next = self.next.checked_add(1).expect("Connection ID overflow"); InternalConnectionId(result) } } impl From for u64 { fn from(internal_conn_id: InternalConnectionId) -> u64 { internal_conn_id.0 } } #[cfg(test)] mod tests { use super::*; #[test] fn connection_id_generator_test() { let mut id_generator = InternalConnectionIdGenerator::new(); for i in 0..128u64 { let id = id_generator.generate_id(); assert_eq!(InternalConnectionId(i), id); } } }