linkerd2_proxy_api/
net.rs1use std::convert::{TryFrom, TryInto};
2use thiserror::Error;
3
4include!("gen/io.linkerd.proxy.net.rs");
5
6#[derive(Clone, Debug, Error)]
8#[error("invalid IP address")]
9pub struct InvalidIpAddress;
10
11#[derive(Clone, Debug, Error)]
13pub enum InvalidIpNetwork {
14 #[error("invalid IP address")]
15 Ip(#[from] InvalidIpAddress),
16 #[error("invalid network prefix length")]
17 PrefixLen(#[from] ipnet::PrefixLenError),
18}
19
20#[cfg(feature = "net")]
23impl TryFrom<IpAddress> for std::net::IpAddr {
24 type Error = InvalidIpAddress;
25
26 fn try_from(ip: IpAddress) -> Result<Self, Self::Error> {
27 use ip_address::Ip;
28 match ip.ip {
29 Some(Ip::Ipv4(v4)) => Ok(std::net::IpAddr::V4(v4.into())),
30 Some(Ip::Ipv6(v6)) => Ok(std::net::IpAddr::V6(v6.into())),
31 None => Err(InvalidIpAddress),
32 }
33 }
34}
35
36#[cfg(feature = "net")]
37impl<T> From<T> for IpAddress
38where
39 ip_address::Ip: From<T>,
40{
41 #[inline]
42 fn from(ip: T) -> Self {
43 Self {
44 ip: Some(ip.into()),
45 }
46 }
47}
48
49impl From<std::net::IpAddr> for IpAddress {
50 fn from(ip: std::net::IpAddr) -> Self {
51 match ip {
52 std::net::IpAddr::V4(v4) => Self {
53 ip: Some(v4.into()),
54 },
55 std::net::IpAddr::V6(v6) => Self {
56 ip: Some(v6.into()),
57 },
58 }
59 }
60}
61
62impl From<[u8; 4]> for ip_address::Ip {
63 fn from(octets: [u8; 4]) -> Self {
64 ip_address::Ip::Ipv4(
65 u32::from(octets[0]) << 24
66 | u32::from(octets[1]) << 16
67 | u32::from(octets[2]) << 8
68 | u32::from(octets[3]),
69 )
70 }
71}
72
73impl TryFrom<IpNetwork> for ipnet::IpNet {
76 type Error = InvalidIpNetwork;
77
78 fn try_from(net: IpNetwork) -> Result<Self, Self::Error> {
79 let ip = net
80 .ip
81 .ok_or(InvalidIpNetwork::Ip(InvalidIpAddress))?
82 .try_into()
83 .map_err(InvalidIpNetwork::Ip)?;
84 let prefix_len = if (0..=u8::MAX as u32).contains(&net.prefix_len) {
85 net.prefix_len as u8
86 } else {
87 return Err(InvalidIpNetwork::PrefixLen(ipnet::PrefixLenError));
88 };
89 match ip {
90 std::net::IpAddr::V4(addr) => ipnet::Ipv4Net::new(addr, prefix_len)
91 .map(Into::into)
92 .map_err(InvalidIpNetwork::PrefixLen),
93 std::net::IpAddr::V6(addr) => ipnet::Ipv6Net::new(addr, prefix_len)
94 .map(Into::into)
95 .map_err(InvalidIpNetwork::PrefixLen),
96 }
97 }
98}
99
100impl<T> From<(T, u8)> for IpNetwork
101where
102 IpAddress: From<T>,
103{
104 #[inline]
105 fn from((ip, prefix_len): (T, u8)) -> Self {
106 Self {
107 ip: Some(ip.into()),
108 prefix_len: prefix_len.into(),
109 }
110 }
111}
112
113impl From<ipnet::IpNet> for IpNetwork {
114 fn from(net: ipnet::IpNet) -> Self {
115 IpNetwork {
116 ip: Some(net.addr().into()),
117 prefix_len: net.prefix_len().into(),
118 }
119 }
120}
121
122impl From<std::net::Ipv4Addr> for ip_address::Ip {
125 #[inline]
126 fn from(v4: std::net::Ipv4Addr) -> Self {
127 Self::from(v4.octets())
128 }
129}
130
131impl<T> From<T> for ip_address::Ip
132where
133 IPv6: From<T>,
134{
135 #[inline]
136 fn from(t: T) -> Self {
137 ip_address::Ip::Ipv6(IPv6::from(t))
138 }
139}
140
141impl From<[u8; 16]> for IPv6 {
144 fn from(octets: [u8; 16]) -> Self {
145 let first = (u64::from(octets[0]) << 56)
146 + (u64::from(octets[1]) << 48)
147 + (u64::from(octets[2]) << 40)
148 + (u64::from(octets[3]) << 32)
149 + (u64::from(octets[4]) << 24)
150 + (u64::from(octets[5]) << 16)
151 + (u64::from(octets[6]) << 8)
152 + u64::from(octets[7]);
153 let last = (u64::from(octets[8]) << 56)
154 + (u64::from(octets[9]) << 48)
155 + (u64::from(octets[10]) << 40)
156 + (u64::from(octets[11]) << 32)
157 + (u64::from(octets[12]) << 24)
158 + (u64::from(octets[13]) << 16)
159 + (u64::from(octets[14]) << 8)
160 + u64::from(octets[15]);
161 Self { first, last }
162 }
163}
164
165impl From<std::net::Ipv6Addr> for IPv6 {
166 #[inline]
167 fn from(v6: std::net::Ipv6Addr) -> Self {
168 Self::from(v6.octets())
169 }
170}
171
172impl From<IPv6> for std::net::Ipv6Addr {
173 fn from(ip: IPv6) -> std::net::Ipv6Addr {
174 std::net::Ipv6Addr::new(
175 (ip.first >> 48) as u16,
176 (ip.first >> 32) as u16,
177 (ip.first >> 16) as u16,
178 (ip.first) as u16,
179 (ip.last >> 48) as u16,
180 (ip.last >> 32) as u16,
181 (ip.last >> 16) as u16,
182 (ip.last) as u16,
183 )
184 }
185}
186
187impl From<std::net::SocketAddr> for TcpAddress {
190 fn from(sa: std::net::SocketAddr) -> TcpAddress {
191 TcpAddress {
192 ip: Some(sa.ip().into()),
193 port: u32::from(sa.port()),
194 }
195 }
196}
197
198impl TryFrom<TcpAddress> for std::net::SocketAddr {
199 type Error = InvalidIpAddress;
200
201 fn try_from(tcp: TcpAddress) -> Result<std::net::SocketAddr, Self::Error> {
202 if let Some(ip) = tcp.ip {
203 let port = tcp.port as u16;
204 let ip = std::net::IpAddr::try_from(ip)?;
205 return Ok(std::net::SocketAddr::from((ip, port)));
206 }
207
208 Err(InvalidIpAddress)
209 }
210}
211
212#[cfg(feature = "arbitrary")]
213mod arbitary {
214 use super::*;
215 use quickcheck::*;
216
217 impl Arbitrary for IpAddress {
218 fn arbitrary(g: &mut Gen) -> Self {
219 IpAddress {
220 ip: Arbitrary::arbitrary(g),
221 }
222 }
223 }
224
225 impl Arbitrary for ip_address::Ip {
226 fn arbitrary(g: &mut Gen) -> Self {
227 if bool::arbitrary(g) {
228 ip_address::Ip::Ipv4(Arbitrary::arbitrary(g))
229 } else {
230 ip_address::Ip::Ipv6(IPv6::arbitrary(g))
231 }
232 }
233 }
234
235 impl Arbitrary for IPv6 {
236 fn arbitrary(g: &mut Gen) -> Self {
237 IPv6 {
238 first: Arbitrary::arbitrary(g),
239 last: Arbitrary::arbitrary(g),
240 }
241 }
242 }
243}