use std::{collections::HashMap, net::IpAddr}; use buffers::{ByteBuf, ByteBufT}; use bytes::Bytes; use clone_to_owned::CloneToOwned; use serde::{Deserialize, Deserializer, Serialize}; use crate::{ EXTENDED_UT_METADATA_KEY, EXTENDED_UT_PEX_KEY, MY_EXTENDED_UT_METADATA, MY_EXTENDED_UT_PEX, }; use super::PeerExtendedMessageIds; #[derive(Deserialize, Serialize, Debug, Default)] pub struct ExtendedHandshake { #[serde(bound(deserialize = "ByteBuf: From<&'de [u8]>"))] pub m: HashMap, #[serde(skip_serializing_if = "Option::is_none")] pub p: Option, #[serde(skip_serializing_if = "Option::is_none")] pub v: Option, #[serde(skip_serializing_if = "Option::is_none")] pub yourip: Option, #[serde(skip_serializing_if = "Option::is_none")] pub ipv6: Option, #[serde(skip_serializing_if = "Option::is_none")] pub ipv4: Option, #[serde(skip_serializing_if = "Option::is_none")] pub reqq: Option, #[serde(skip_serializing_if = "Option::is_none")] pub metadata_size: Option, #[serde(skip_serializing_if = "Option::is_none")] pub complete_ago: Option, #[serde(skip_serializing_if = "Option::is_none")] pub upload_only: Option, } impl ExtendedHandshake> { pub fn new() -> Self { let mut features = HashMap::new(); features.insert(ByteBuf(EXTENDED_UT_METADATA_KEY), MY_EXTENDED_UT_METADATA); features.insert(ByteBuf(EXTENDED_UT_PEX_KEY), MY_EXTENDED_UT_PEX); Self { m: features, ..Default::default() } } } impl<'a, ByteBuf> ExtendedHandshake where ByteBuf: ByteBufT, { fn get_msgid(&self, msg_type: &'a [u8]) -> Option { self.m.get(msg_type).copied() } pub fn ut_metadata(&self) -> Option { self.get_msgid(EXTENDED_UT_METADATA_KEY) } pub fn ut_pex(&self) -> Option { self.get_msgid(EXTENDED_UT_PEX_KEY) } pub fn peer_extended_messages(&self) -> PeerExtendedMessageIds { PeerExtendedMessageIds { ut_metadata: self.ut_metadata(), ut_pex: self.ut_pex(), } } } impl CloneToOwned for ExtendedHandshake where ByteBuf: ByteBufT, ::Target: ByteBufT, { type Target = ExtendedHandshake<::Target>; fn clone_to_owned(&self, within_buffer: Option<&Bytes>) -> Self::Target { ExtendedHandshake { m: self.m.clone_to_owned(within_buffer), p: self.p, v: self.v.clone_to_owned(within_buffer), yourip: self.yourip, ipv6: self.ipv6.clone_to_owned(within_buffer), ipv4: self.ipv4.clone_to_owned(within_buffer), reqq: self.reqq, metadata_size: self.metadata_size, complete_ago: self.complete_ago, upload_only: self.upload_only, } } } #[derive(Debug, Clone, Copy)] pub struct YourIP(pub IpAddr); impl Serialize for YourIP { fn serialize(&self, serializer: S) -> Result where S: serde::Serializer, { match self.0 { IpAddr::V4(ipv4) => { let buf = ipv4.octets(); serializer.serialize_bytes(&buf) } IpAddr::V6(ipv6) => { let buf = ipv6.octets(); serializer.serialize_bytes(&buf) } } } } impl<'de> Deserialize<'de> for YourIP { fn deserialize(de: D) -> Result where D: Deserializer<'de>, { struct Visitor {} impl<'de> serde::de::Visitor<'de> for Visitor { type Value = YourIP; fn expecting(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!(f, "expecting 4 bytes of ipv4 or 16 bytes of ipv6") } fn visit_bytes(self, v: &[u8]) -> Result where E: serde::de::Error, { if v.len() == 4 { let ip_bytes: &[u8; 4] = v[0..4].try_into().unwrap(); // Safe to unwrap as we check slice length return Ok(YourIP(IpAddr::from(*ip_bytes))); } else if v.len() == 16 { let ip_bytes: &[u8; 16] = v[0..16].try_into().unwrap(); // Safe to unwrap as we check slice length return Ok(YourIP(IpAddr::from(*ip_bytes))); } Err(E::custom("expected 4 or 16 byte address")) } } de.deserialize_bytes(Visitor {}) } }