changelog shortlog graph tags branches changeset files revisions annotate raw help

Mercurial > core / rust/lib/net/src/shared.rs

changeset 698: 96958d3eb5b0
parent: c7165d93a9eb
author: Richard Westhaver <ellis@rwest.io>
date: Fri, 04 Oct 2024 22:04:59 -0400
permissions: -rw-r--r--
description: fixes
1 use std::{fmt, net::SocketAddr, time::Instant};
2 use bytes::{Buf, BufMut, BytesMut};
3 use crate::proto::coding::BufExt;
4 
5 pub const MAX_CID_SIZE: usize = 20;
6 
7 /// Events sent from an Endpoint to a Connection
8 #[derive(Debug)]
9 pub struct ConnectionEvent(pub(crate) ConnectionEventInner);
10 
11 #[derive(Debug)]
12 pub(crate) enum ConnectionEventInner {
13  /// A datagram has been received for the Connection
14  Datagram {
15  now: Instant,
16  remote: SocketAddr,
17  remaining: Option<BytesMut>,
18  },
19  /// New connection identifiers have been issued for the Connection
20  NewIdentifiers(Vec<IssuedCid>),
21 }
22 
23 /// Events sent from a Connection to an Endpoint
24 #[derive(Debug)]
25 pub struct EndpointEvent(pub(crate) EndpointEventInner);
26 
27 impl EndpointEvent {
28  /// Construct an event that indicating that a `Connection` will no longer
29  /// emit events
30  ///
31  /// Useful for notifying an `Endpoint` that a `Connection` has been
32  /// destroyed outside of the usual state machine flow, e.g. when being
33  /// dropped by the user.
34  pub fn drained() -> Self {
35  Self(EndpointEventInner::Drained)
36  }
37 
38  /// Determine whether this is the last event a `Connection` will emit
39  ///
40  /// Useful for determining when connection-related event loop state can be
41  /// freed.
42  pub fn is_drained(&self) -> bool {
43  self.0 == EndpointEventInner::Drained
44  }
45 }
46 
47 #[derive(Clone, Debug, Eq, PartialEq)]
48 pub(crate) enum EndpointEventInner {
49  /// The connection has been drained
50  Drained,
51  /// The connection needs connection identifiers
52  NeedIdentifiers(u64),
53  /// Stop routing connection ID for this sequence number to the connection
54  /// When `bool == true`, a new connection ID will be issued to peer
55  RetireConnectionId(u64, bool),
56 }
57 
58 /// Protocol-level identifier for a connection.
59 ///
60 /// Mainly useful for identifying this connection's packets on the wire with
61 /// tools like Wireshark.
62 #[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
63 pub struct ConnectionId {
64  /// length of CID
65  len: u8,
66  /// CID in byte array
67  bytes: [u8; MAX_CID_SIZE],
68 }
69 
70 impl ConnectionId {
71  /// Construct cid from byte array
72  pub fn new(bytes: &[u8]) -> Self {
73  debug_assert!(bytes.len() <= MAX_CID_SIZE);
74  let mut res = Self {
75  len: bytes.len() as u8,
76  bytes: [0; MAX_CID_SIZE],
77  };
78  res.bytes[..bytes.len()].clone_from_slice(&bytes);
79  res
80  }
81 
82  pub(crate) fn decode(buf: &mut impl Buf) -> Option<Self> {
83  let len = buf.get::<u8>().ok()? as usize;
84  if len > MAX_CID_SIZE || buf.remaining() < len {
85  return None;
86  }
87  let cid = ConnectionId::new(&buf.chunk()[..len]);
88  buf.advance(len);
89  Some(cid)
90  }
91 
92  pub(crate) fn encode(&self, buf: &mut impl BufMut) {
93  buf.put_u8(self.len() as u8);
94  buf.put_slice(self);
95  }
96 }
97 
98 impl ::std::ops::Deref for ConnectionId {
99  type Target = [u8];
100  fn deref(&self) -> &[u8] {
101  &self.bytes[0..self.len as usize]
102  }
103 }
104 
105 impl ::std::ops::DerefMut for ConnectionId {
106  fn deref_mut(&mut self) -> &mut [u8] {
107  &mut self.bytes[0..self.len as usize]
108  }
109 }
110 
111 impl fmt::Debug for ConnectionId {
112  fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
113  self.bytes[0..self.len as usize].fmt(f)
114  }
115 }
116 
117 impl fmt::Display for ConnectionId {
118  fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
119  for byte in self.iter() {
120  write!(f, "{:02x}", byte)?;
121  }
122  Ok(())
123  }
124 }
125 
126 #[derive(Debug, Copy, Clone)]
127 pub struct IssuedCid {
128  pub sequence: u64,
129  pub id: ConnectionId,
130 }