simplify ConnectionId

Currently a ConnectionId can either be a slice or a Vec. Because of this
declarations might need to also declare an explicit lifetime, which make
using the struct slightly annoying.

Instead just use a Vec all the time, and to avoid wasting memory when
cloning (since the CIDs are read-only anyway), wrap the internal Vec in
an Arc.
diff --git a/apps/src/bin/quiche-server.rs b/apps/src/bin/quiche-server.rs
index f5d5691..3d261c1 100644
--- a/apps/src/bin/quiche-server.rs
+++ b/apps/src/bin/quiche-server.rs
@@ -617,7 +617,7 @@
                 );
 
                 for id in c.conn.source_ids() {
-                    let id_owned = id.clone().into_owned();
+                    let id_owned = id.clone();
                     clients_ids.remove(&id_owned);
                 }
             }
@@ -658,9 +658,9 @@
 ///
 /// Note that this function is only an example and doesn't do any cryptographic
 /// authenticate of the token. *It should not be used in production system*.
-fn validate_token<'a>(
-    src: &net::SocketAddr, token: &'a [u8],
-) -> Option<quiche::ConnectionId<'a>> {
+fn validate_token(
+    src: &net::SocketAddr, token: &[u8],
+) -> Option<quiche::ConnectionId> {
     if token.len() < 6 {
         return None;
     }
diff --git a/apps/src/common.rs b/apps/src/common.rs
index e58e4a0..6f4fc83 100644
--- a/apps/src/common.rs
+++ b/apps/src/common.rs
@@ -100,7 +100,7 @@
     pub max_send_burst: usize,
 }
 
-pub type ClientIdMap = HashMap<ConnectionId<'static>, ClientId>;
+pub type ClientIdMap = HashMap<ConnectionId, ClientId>;
 pub type ClientMap = HashMap<ClientId, Client>;
 
 /// Makes a buffered writer for a resource with a target URL.
@@ -255,7 +255,7 @@
 /// Generate a new pair of Source Connection ID and reset token.
 pub fn generate_cid_and_reset_token<T: SecureRandom>(
     rng: &T,
-) -> (quiche::ConnectionId<'static>, u128) {
+) -> (quiche::ConnectionId, u128) {
     let mut scid = [0; quiche::MAX_CONN_ID_LEN];
     rng.fill(&mut scid).unwrap();
     let scid = scid.to_vec().into();
diff --git a/quiche/examples/http3-server.rs b/quiche/examples/http3-server.rs
index 32650cd..bbb5873 100644
--- a/quiche/examples/http3-server.rs
+++ b/quiche/examples/http3-server.rs
@@ -53,7 +53,7 @@
     partial_responses: HashMap<u64, PartialResponse>,
 }
 
-type ClientMap = HashMap<quiche::ConnectionId<'static>, Client>;
+type ClientMap = HashMap<quiche::ConnectionId, Client>;
 
 fn main() {
     let mut buf = [0; 65535];
@@ -476,9 +476,9 @@
 ///
 /// Note that this function is only an example and doesn't do any cryptographic
 /// authenticate of the token. *It should not be used in production system*.
-fn validate_token<'a>(
-    src: &net::SocketAddr, token: &'a [u8],
-) -> Option<quiche::ConnectionId<'a>> {
+fn validate_token(
+    src: &net::SocketAddr, token: &[u8],
+) -> Option<quiche::ConnectionId> {
     if token.len() < 6 {
         return None;
     }
diff --git a/quiche/examples/server.rs b/quiche/examples/server.rs
index 496b51c..bc322e4 100644
--- a/quiche/examples/server.rs
+++ b/quiche/examples/server.rs
@@ -47,7 +47,7 @@
     partial_responses: HashMap<u64, PartialResponse>,
 }
 
-type ClientMap = HashMap<quiche::ConnectionId<'static>, Client>;
+type ClientMap = HashMap<quiche::ConnectionId, Client>;
 
 fn main() {
     let mut buf = [0; 65535];
@@ -418,9 +418,9 @@
 ///
 /// Note that this function is only an example and doesn't do any cryptographic
 /// authenticate of the token. *It should not be used in production system*.
-fn validate_token<'a>(
-    src: &net::SocketAddr, token: &'a [u8],
-) -> Option<quiche::ConnectionId<'a>> {
+fn validate_token(
+    src: &net::SocketAddr, token: &[u8],
+) -> Option<quiche::ConnectionId> {
     if token.len() < 6 {
         return None;
     }
diff --git a/quiche/src/cid.rs b/quiche/src/cid.rs
index fdedfe3..a8edeb4 100644
--- a/quiche/src/cid.rs
+++ b/quiche/src/cid.rs
@@ -36,7 +36,7 @@
 #[derive(Debug, Default)]
 pub struct ConnectionIdEntry {
     /// The Connection ID.
-    pub cid: ConnectionId<'static>,
+    pub cid: ConnectionId,
 
     /// Its associated sequence number.
     pub seq: u64,
@@ -193,11 +193,11 @@
 
 /// An iterator over QUIC Connection IDs.
 pub struct ConnectionIdIter {
-    cids: VecDeque<ConnectionId<'static>>,
+    cids: VecDeque<ConnectionId>,
 }
 
 impl Iterator for ConnectionIdIter {
-    type Item = ConnectionId<'static>;
+    type Item = ConnectionId;
 
     #[inline]
     fn next(&mut self) -> Option<Self::Item> {
@@ -228,7 +228,7 @@
 
     /// Retired Source Connection IDs that should be notified to the
     /// application.
-    retired_scids: VecDeque<ConnectionId<'static>>,
+    retired_scids: VecDeque<ConnectionId>,
 
     /// Largest "Retire Prior To" we received from the peer.
     largest_peer_retire_prior_to: u64,
@@ -271,8 +271,7 @@
         // Record the zero-length SCID status.
         let zero_length_scid = initial_scid.is_empty();
 
-        let initial_scid =
-            ConnectionId::from_ref(initial_scid.as_ref()).into_owned();
+        let initial_scid = ConnectionId::from_ref(initial_scid.as_ref());
 
         // We need to track up to (2 * source_conn_id_limit - 1) source
         // Connection IDs when the host wants to force their renewal.
@@ -366,8 +365,8 @@
     /// [`InvalidState`]: enum.Error.html#InvalidState
     /// [`IdLimit`]: enum.Error.html#IdLimit
     pub fn new_scid(
-        &mut self, cid: ConnectionId<'static>, reset_token: Option<u128>,
-        advertise: bool, path_id: Option<usize>, retire_if_needed: bool,
+        &mut self, cid: ConnectionId, reset_token: Option<u128>, advertise: bool,
+        path_id: Option<usize>, retire_if_needed: bool,
     ) -> Result<u64> {
         if self.zero_length_scid {
             return Err(Error::InvalidState);
@@ -415,7 +414,7 @@
 
     /// Sets the initial destination identifier.
     pub fn set_initial_dcid(
-        &mut self, cid: ConnectionId<'static>, reset_token: Option<u128>,
+        &mut self, cid: ConnectionId, reset_token: Option<u128>,
         path_id: Option<usize>,
     ) {
         // Record the zero-length DCID status.
@@ -438,7 +437,7 @@
     /// sequence number of retired DCIDs that were linked to their respective
     /// Path ID.
     pub fn new_dcid(
-        &mut self, cid: ConnectionId<'static>, seq: u64, reset_token: u128,
+        &mut self, cid: ConnectionId, seq: u64, reset_token: u128,
         retire_prior_to: u64,
     ) -> Result<Vec<(u64, usize)>> {
         if self.zero_length_dcid {
@@ -488,7 +487,7 @@
         }
 
         let new_entry = ConnectionIdEntry {
-            cid: cid.clone(),
+            cid,
             seq,
             reset_token: Some(reset_token),
             path_id: None,
@@ -803,7 +802,7 @@
         self.retired_scids.len()
     }
 
-    pub fn pop_retired_scid(&mut self) -> Option<ConnectionId<'static>> {
+    pub fn pop_retired_scid(&mut self) -> Option<ConnectionId> {
         self.retired_scids.pop_front()
     }
 }
diff --git a/quiche/src/lib.rs b/quiche/src/lib.rs
index 1c8f1a7..43adaa8 100644
--- a/quiche/src/lib.rs
+++ b/quiche/src/lib.rs
@@ -1300,11 +1300,11 @@
 
     /// Peer's original destination connection ID. Used by the client to
     /// validate the server's transport parameter.
-    odcid: Option<ConnectionId<'static>>,
+    odcid: Option<ConnectionId>,
 
     /// Peer's retry source connection ID. Used by the client during stateless
     /// retry to validate the server's transport parameter.
-    rscid: Option<ConnectionId<'static>>,
+    rscid: Option<ConnectionId>,
 
     /// Received address verification token.
     token: Option<Vec<u8>>,
@@ -1521,7 +1521,7 @@
 /// # fn mint_token(hdr: &quiche::Header, src: &std::net::SocketAddr) -> Vec<u8> {
 /// #     vec![]
 /// # }
-/// # fn validate_token<'a>(src: &std::net::SocketAddr, token: &'a [u8]) -> Option<quiche::ConnectionId<'a>> {
+/// # fn validate_token<'a>(src: &std::net::SocketAddr, token: &'a [u8]) -> Option<quiche::ConnectionId> {
 /// #     None
 /// # }
 /// let (len, peer) = socket.recv_from(&mut buf).unwrap();
@@ -2350,7 +2350,7 @@
             self.did_retry = true;
 
             // Remember peer's new connection ID.
-            self.odcid = Some(self.destination_id().into_owned());
+            self.odcid = Some(self.destination_id());
 
             self.set_initial_dcid(
                 hdr.scid.clone(),
@@ -2358,7 +2358,7 @@
                 self.paths.get_active_path_id()?,
             )?;
 
-            self.rscid = Some(self.destination_id().into_owned());
+            self.rscid = Some(self.destination_id());
 
             // Derive Initial secrets using the new connection ID.
             let (aead_open, aead_seal) = crypto::derive_initial_key_material(
@@ -2648,7 +2648,7 @@
 
         if !self.is_server && !self.got_peer_conn_id {
             if self.odcid.is_none() {
-                self.odcid = Some(self.destination_id().into_owned());
+                self.odcid = Some(self.destination_id());
             }
 
             // Replace the randomly generated destination connection ID with
@@ -5829,7 +5829,7 @@
     /// more retired connection IDs.
     ///
     /// [`ConnectionId`]: struct.ConnectionId.html
-    pub fn retired_scid_next(&mut self) -> Option<ConnectionId<'static>> {
+    pub fn retired_scid_next(&mut self) -> Option<ConnectionId> {
         self.ids.pop_retired_scid()
     }
 
@@ -7111,8 +7111,7 @@
     }
 
     fn set_initial_dcid(
-        &mut self, cid: ConnectionId<'static>, reset_token: Option<u128>,
-        path_id: usize,
+        &mut self, cid: ConnectionId, reset_token: Option<u128>, path_id: usize,
     ) -> Result<()> {
         self.ids.set_initial_dcid(cid, reset_token, Some(path_id));
         self.paths.get_mut(path_id)?.active_dcid_seq = Some(0);
@@ -7552,7 +7551,7 @@
 
 #[derive(Clone, Debug, PartialEq)]
 struct TransportParams {
-    pub original_destination_connection_id: Option<ConnectionId<'static>>,
+    pub original_destination_connection_id: Option<ConnectionId>,
     pub max_idle_timeout: u64,
     pub stateless_reset_token: Option<u128>,
     pub max_udp_payload_size: u64,
@@ -7567,8 +7566,8 @@
     pub disable_active_migration: bool,
     // pub preferred_address: ...,
     pub active_conn_id_limit: u64,
-    pub initial_source_connection_id: Option<ConnectionId<'static>>,
-    pub retry_source_connection_id: Option<ConnectionId<'static>>,
+    pub initial_source_connection_id: Option<ConnectionId>,
+    pub retry_source_connection_id: Option<ConnectionId>,
     pub max_datagram_frame_size: Option<u64>,
 }
 
@@ -8420,12 +8419,10 @@
         Ok(frames)
     }
 
-    pub fn create_cid_and_reset_token(
-        cid_len: usize,
-    ) -> (ConnectionId<'static>, u128) {
+    pub fn create_cid_and_reset_token(cid_len: usize) -> (ConnectionId, u128) {
         let mut cid = vec![0; cid_len];
         rand::rand_bytes(&mut cid[..]);
-        let cid = ConnectionId::from_ref(&cid).into_owned();
+        let cid = ConnectionId::from_ref(&cid);
 
         let mut reset_token = [0; 16];
         rand::rand_bytes(&mut reset_token);
@@ -14256,7 +14253,7 @@
         assert_eq!(pipe.server.path_event_next(), None);
         assert_eq!(pipe.client.source_cids_left(), 1);
 
-        let scid = pipe.client.source_id().into_owned();
+        let scid = pipe.client.source_id();
 
         let (scid_1, reset_token_1) = testing::create_cid_and_reset_token(16);
         assert_eq!(
@@ -14351,7 +14348,7 @@
         let mut pipe = testing::Pipe::with_config(&mut config).unwrap();
         assert_eq!(pipe.handshake(), Ok(()));
 
-        let scid = pipe.client.source_id().into_owned();
+        let scid = pipe.client.source_id();
 
         let (scid_1, reset_token_1) = testing::create_cid_and_reset_token(16);
         assert_eq!(
diff --git a/quiche/src/packet.rs b/quiche/src/packet.rs
index 9c7b9c4..1da96b5 100644
--- a/quiche/src/packet.rs
+++ b/quiche/src/packet.rs
@@ -28,6 +28,7 @@
 use std::ops::Index;
 use std::ops::IndexMut;
 use std::ops::RangeInclusive;
+use std::sync::Arc;
 use std::time;
 
 use ring::aead;
@@ -174,103 +175,76 @@
 }
 
 /// A QUIC connection ID.
-pub struct ConnectionId<'a>(ConnectionIdInner<'a>);
+pub struct ConnectionId(Arc<Vec<u8>>);
 
-enum ConnectionIdInner<'a> {
-    Vec(Vec<u8>),
-    Ref(&'a [u8]),
-}
-
-impl<'a> ConnectionId<'a> {
+impl ConnectionId {
     /// Creates a new connection ID from the given vector.
     #[inline]
-    pub const fn from_vec(cid: Vec<u8>) -> Self {
-        Self(ConnectionIdInner::Vec(cid))
+    pub fn from_vec(cid: Vec<u8>) -> Self {
+        Self(Arc::new(cid))
     }
 
     /// Creates a new connection ID from the given slice.
     #[inline]
-    pub const fn from_ref(cid: &'a [u8]) -> Self {
-        Self(ConnectionIdInner::Ref(cid))
-    }
-
-    /// Returns a new owning connection ID from the given existing one.
-    #[inline]
-    pub fn into_owned(self) -> ConnectionId<'static> {
-        ConnectionId::from_vec(self.into())
+    pub fn from_ref(cid: &[u8]) -> Self {
+        Self::from_vec(cid.to_vec())
     }
 }
 
-impl<'a> Default for ConnectionId<'a> {
+impl Default for ConnectionId {
     #[inline]
     fn default() -> Self {
         Self::from_vec(Vec::new())
     }
 }
 
-impl<'a> From<Vec<u8>> for ConnectionId<'a> {
+impl From<Vec<u8>> for ConnectionId {
     #[inline]
     fn from(v: Vec<u8>) -> Self {
         Self::from_vec(v)
     }
 }
 
-impl<'a> From<ConnectionId<'a>> for Vec<u8> {
-    #[inline]
-    fn from(id: ConnectionId<'a>) -> Self {
-        match id.0 {
-            ConnectionIdInner::Vec(cid) => cid,
-            ConnectionIdInner::Ref(cid) => cid.to_vec(),
-        }
-    }
-}
-
-impl<'a> PartialEq for ConnectionId<'a> {
+impl PartialEq for ConnectionId {
     #[inline]
     fn eq(&self, other: &Self) -> bool {
         self.as_ref() == other.as_ref()
     }
 }
 
-impl<'a> Eq for ConnectionId<'a> {}
+impl Eq for ConnectionId {}
 
-impl<'a> AsRef<[u8]> for ConnectionId<'a> {
+impl AsRef<[u8]> for ConnectionId {
     #[inline]
     fn as_ref(&self) -> &[u8] {
-        match &self.0 {
-            ConnectionIdInner::Vec(v) => v.as_ref(),
-            ConnectionIdInner::Ref(v) => v,
-        }
+        self.0.as_ref()
     }
 }
 
-impl<'a> std::hash::Hash for ConnectionId<'a> {
+impl std::hash::Hash for ConnectionId {
     #[inline]
     fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
         self.as_ref().hash(state);
     }
 }
 
-impl<'a> std::ops::Deref for ConnectionId<'a> {
+impl std::ops::Deref for ConnectionId {
     type Target = [u8];
 
     #[inline]
     fn deref(&self) -> &[u8] {
-        match &self.0 {
-            ConnectionIdInner::Vec(v) => v.as_ref(),
-            ConnectionIdInner::Ref(v) => v,
-        }
+        self.0.as_ref()
     }
 }
 
-impl<'a> Clone for ConnectionId<'a> {
+impl Clone for ConnectionId {
     #[inline]
     fn clone(&self) -> Self {
-        Self::from_vec(self.as_ref().to_vec())
+        Self(Arc::clone(&self.0))
     }
 }
 
-impl<'a> std::fmt::Debug for ConnectionId<'a> {
+impl std::fmt::Debug for ConnectionId {
     #[inline]
     fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
         for c in self.as_ref() {
@@ -283,7 +257,7 @@
 
 /// A QUIC packet's header.
 #[derive(Clone, PartialEq, Eq)]
-pub struct Header<'a> {
+pub struct Header {
     /// The type of the packet.
     pub ty: Type,
 
@@ -291,10 +265,10 @@
     pub version: u32,
 
     /// The destination connection ID of the packet.
-    pub dcid: ConnectionId<'a>,
+    pub dcid: ConnectionId,
 
     /// The source connection ID of the packet.
-    pub scid: ConnectionId<'a>,
+    pub scid: ConnectionId,
 
     /// The packet number. It's only meaningful after the header protection is
     /// removed.
@@ -317,7 +291,7 @@
     pub(crate) key_phase: bool,
 }
 
-impl<'a> Header<'a> {
+impl Header {
     /// Parses a QUIC packet header from the given buffer.
     ///
     /// The `dcid_len` parameter is the length of the destination connection ID,
@@ -336,16 +310,14 @@
     /// # Ok::<(), quiche::Error>(())
     /// ```
     #[inline]
-    pub fn from_slice<'b>(
-        buf: &'b mut [u8], dcid_len: usize,
-    ) -> Result<Header<'a>> {
+    pub fn from_slice(buf: &mut [u8], dcid_len: usize) -> Result<Header> {
         let mut b = octets::OctetsMut::with_slice(buf);
         Header::from_bytes(&mut b, dcid_len)
     }
 
-    pub(crate) fn from_bytes<'b>(
-        b: &'b mut octets::OctetsMut, dcid_len: usize,
-    ) -> Result<Header<'a>> {
+    pub(crate) fn from_bytes(
+        b: &mut octets::OctetsMut, dcid_len: usize,
+    ) -> Result<Header> {
         let first = b.get_u8()?;
 
         if !Header::is_long(first) {
@@ -522,7 +494,7 @@
     }
 }
 
-impl<'a> std::fmt::Debug for Header<'a> {
+impl std::fmt::Debug for Header {
     fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
         write!(f, "{:?}", self.ty)?;