make all fields in utpex optional

This commit is contained in:
Igor Katson 2024-08-29 13:01:12 +01:00
parent 0bb1c77456
commit bafd958d0d
No known key found for this signature in database
GPG key ID: B4EC22B66D61A3F5

View file

@ -3,7 +3,6 @@ use std::net::{IpAddr, SocketAddr};
use byteorder::{ByteOrder, BE}; use byteorder::{ByteOrder, BE};
use bytes::Bytes; use bytes::Bytes;
use clone_to_owned::CloneToOwned; use clone_to_owned::CloneToOwned;
use itertools::{EitherOrBoth, Itertools};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
pub struct PexPeerInfo { pub struct PexPeerInfo {
@ -23,16 +22,20 @@ impl core::fmt::Debug for PexPeerInfo {
#[derive(Serialize, Default, Deserialize)] #[derive(Serialize, Default, Deserialize)]
pub struct UtPex<B> { pub struct UtPex<B> {
added: B, #[serde(skip_serializing_if = "Option::is_none")]
added: Option<B>,
#[serde(rename = "added.f")] #[serde(rename = "added.f")]
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
added_f: Option<B>, added_f: Option<B>,
added6: B, #[serde(skip_serializing_if = "Option::is_none")]
added6: Option<B>,
#[serde(rename = "added6.f")] #[serde(rename = "added6.f")]
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
added6_f: Option<B>, added6_f: Option<B>,
dropped: B, #[serde(skip_serializing_if = "Option::is_none")]
dropped6: B, dropped: Option<B>,
#[serde(skip_serializing_if = "Option::is_none")]
dropped6: Option<B>,
} }
impl<B> core::fmt::Debug for UtPex<B> impl<B> core::fmt::Debug for UtPex<B>
@ -79,11 +82,17 @@ where
{ {
fn added_peers_inner<'a>( fn added_peers_inner<'a>(
&'a self, &'a self,
buf: &'a B, buf: &'a Option<B>,
flags: &'a Option<B>, flags: &'a Option<B>,
ip_len: usize, ip_len: usize,
) -> impl Iterator<Item = PexPeerInfo> + Clone + 'a { ) -> impl Iterator<Item = PexPeerInfo> + Clone + 'a {
let addrs = buf.as_ref().chunks_exact(ip_len + 2).map(move |c| { const PORT_LEN: usize = 2;
const DEFAULT_FLAGS: u8 = 0;
let addrs = buf
.as_ref()
.into_iter()
.flat_map(move |it| it.as_ref().chunks_exact(ip_len + PORT_LEN))
.map(move |c| {
let ip = match ip_len { let ip = match ip_len {
4 => IpAddr::from(TryInto::<[u8; 4]>::try_into(&c[..4]).unwrap()), 4 => IpAddr::from(TryInto::<[u8; 4]>::try_into(&c[..4]).unwrap()),
16 => IpAddr::from(TryInto::<[u8; 16]>::try_into(&c[..16]).unwrap()), 16 => IpAddr::from(TryInto::<[u8; 16]>::try_into(&c[..16]).unwrap()),
@ -92,15 +101,12 @@ where
let port = BE::read_u16(&c[ip_len..]); let port = BE::read_u16(&c[ip_len..]);
SocketAddr::new(ip, port) SocketAddr::new(ip, port)
}); });
let flags = flags addrs.enumerate().map(move |(id, addr)| PexPeerInfo {
addr,
flags: flags
.as_ref() .as_ref()
.map(|b| b.as_ref().iter().copied()) .and_then(|f| f.as_ref().get(id).copied())
.into_iter() .unwrap_or(DEFAULT_FLAGS),
.flatten();
addrs.zip_longest(flags).filter_map(|eob| match eob {
EitherOrBoth::Both(addr, flags) => Some(PexPeerInfo { flags, addr }),
EitherOrBoth::Left(addr) => Some(PexPeerInfo { flags: 0, addr }),
EitherOrBoth::Right(_) => None,
}) })
} }