cuprate_wire/network_address/
epee_builder.rs

1use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6};
2
3use bytes::Buf;
4use thiserror::Error;
5
6use cuprate_epee_encoding::{epee_object, EpeeObjectBuilder};
7
8use crate::NetworkAddress;
9
10#[derive(Default)]
11pub struct TaggedNetworkAddress {
12    ty: Option<u8>,
13    addr: Option<AllFieldsNetworkAddress>,
14}
15
16epee_object!(
17    TaggedNetworkAddress,
18    ty("type"): Option<u8>,
19    addr: Option<AllFieldsNetworkAddress>,
20);
21
22impl EpeeObjectBuilder<NetworkAddress> for TaggedNetworkAddress {
23    fn add_field<B: Buf>(&mut self, name: &str, b: &mut B) -> cuprate_epee_encoding::Result<bool> {
24        match name {
25            "type" => {
26                if std::mem::replace(
27                    &mut self.ty,
28                    Some(cuprate_epee_encoding::read_epee_value(b)?),
29                )
30                .is_some()
31                {
32                    return Err(cuprate_epee_encoding::Error::Format(
33                        "Duplicate field in data.",
34                    ));
35                }
36                Ok(true)
37            }
38            "addr" => {
39                if std::mem::replace(&mut self.addr, cuprate_epee_encoding::read_epee_value(b)?)
40                    .is_some()
41                {
42                    return Err(cuprate_epee_encoding::Error::Format(
43                        "Duplicate field in data.",
44                    ));
45                }
46                Ok(true)
47            }
48            _ => Ok(false),
49        }
50    }
51
52    fn finish(self) -> cuprate_epee_encoding::Result<NetworkAddress> {
53        self.try_into()
54            .map_err(|_| cuprate_epee_encoding::Error::Value("Invalid network address".to_string()))
55    }
56}
57
58#[derive(Error, Debug)]
59#[error("Invalid network address")]
60pub struct InvalidNetworkAddress;
61
62impl TryFrom<TaggedNetworkAddress> for NetworkAddress {
63    type Error = InvalidNetworkAddress;
64
65    fn try_from(value: TaggedNetworkAddress) -> Result<Self, Self::Error> {
66        value
67            .addr
68            .ok_or(InvalidNetworkAddress)?
69            .try_into_network_address(value.ty.ok_or(InvalidNetworkAddress)?)
70            .ok_or(InvalidNetworkAddress)
71    }
72}
73
74impl From<NetworkAddress> for TaggedNetworkAddress {
75    fn from(value: NetworkAddress) -> Self {
76        match value {
77            NetworkAddress::Clear(addr) => match addr {
78                SocketAddr::V4(addr) => Self {
79                    ty: Some(1),
80                    addr: Some(AllFieldsNetworkAddress {
81                        m_ip: Some(u32::from_le_bytes(addr.ip().octets())),
82                        m_port: Some(addr.port()),
83                        addr: None,
84                    }),
85                },
86                SocketAddr::V6(addr) => Self {
87                    ty: Some(2),
88                    addr: Some(AllFieldsNetworkAddress {
89                        addr: Some(addr.ip().octets()),
90                        m_port: Some(addr.port()),
91                        m_ip: None,
92                    }),
93                },
94            },
95        }
96    }
97}
98
99#[derive(Default)]
100struct AllFieldsNetworkAddress {
101    m_ip: Option<u32>,
102    m_port: Option<u16>,
103    addr: Option<[u8; 16]>,
104}
105
106epee_object!(
107    AllFieldsNetworkAddress,
108    m_ip: Option<u32>,
109    m_port: Option<u16>,
110    addr: Option<[u8; 16]>,
111);
112
113impl AllFieldsNetworkAddress {
114    fn try_into_network_address(self, ty: u8) -> Option<NetworkAddress> {
115        Some(match ty {
116            1 => NetworkAddress::from(SocketAddrV4::new(
117                Ipv4Addr::from(self.m_ip?.to_le_bytes()),
118                self.m_port?,
119            )),
120            2 => NetworkAddress::from(SocketAddrV6::new(
121                Ipv6Addr::from(self.addr?),
122                self.m_port?,
123                0,
124                0,
125            )),
126            _ => return None,
127        })
128    }
129}