1use crate::{Buf, EncodeSize, Error, FixedSize, MaxEncodeSize, Read, ReadExt, Write};
4use bytes::BufMut;
5use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6};
6
7impl Write for Ipv4Addr {
8 #[inline]
9 fn write(&self, buf: &mut impl BufMut) {
10 self.to_bits().write(buf);
11 }
12}
13
14impl Read for Ipv4Addr {
15 type Cfg = ();
16
17 #[inline]
18 fn read_cfg(buf: &mut impl Buf, _: &()) -> Result<Self, Error> {
19 Ok(Self::from_bits(u32::read(buf)?))
20 }
21}
22
23impl FixedSize for Ipv4Addr {
24 const SIZE: usize = u32::SIZE;
25}
26
27impl Write for Ipv6Addr {
28 #[inline]
29 fn write(&self, buf: &mut impl BufMut) {
30 self.to_bits().write(buf);
31 }
32}
33
34impl Read for Ipv6Addr {
35 type Cfg = ();
36
37 #[inline]
38 fn read_cfg(buf: &mut impl Buf, _: &()) -> Result<Self, Error> {
39 Ok(Self::from_bits(u128::read(buf)?))
40 }
41}
42
43impl FixedSize for Ipv6Addr {
44 const SIZE: usize = u128::SIZE;
45}
46
47impl Write for SocketAddrV4 {
48 #[inline]
49 fn write(&self, buf: &mut impl BufMut) {
50 self.ip().write(buf);
51 self.port().write(buf);
52 }
53}
54
55impl Read for SocketAddrV4 {
56 type Cfg = ();
57
58 #[inline]
59 fn read_cfg(buf: &mut impl Buf, _: &()) -> Result<Self, Error> {
60 let ip = Ipv4Addr::read(buf)?;
61 let port = u16::read(buf)?;
62 Ok(Self::new(ip, port))
63 }
64}
65
66impl FixedSize for SocketAddrV4 {
67 const SIZE: usize = Ipv4Addr::SIZE + u16::SIZE;
68}
69
70impl Write for SocketAddrV6 {
71 #[inline]
72 fn write(&self, buf: &mut impl BufMut) {
73 self.ip().write(buf);
74 self.port().write(buf);
75 }
76}
77
78impl Read for SocketAddrV6 {
79 type Cfg = ();
80
81 #[inline]
82 fn read_cfg(buf: &mut impl Buf, _: &()) -> Result<Self, Error> {
83 let address = Ipv6Addr::read(buf)?;
84 let port = u16::read(buf)?;
85 Ok(Self::new(address, port, 0, 0))
86 }
87}
88
89impl FixedSize for SocketAddrV6 {
90 const SIZE: usize = Ipv6Addr::SIZE + u16::SIZE;
91}
92
93impl Write for IpAddr {
94 #[inline]
95 fn write(&self, buf: &mut impl BufMut) {
96 match self {
97 Self::V4(v4) => {
98 4u8.write(buf);
99 v4.write(buf);
100 }
101 Self::V6(v6) => {
102 6u8.write(buf);
103 v6.write(buf);
104 }
105 }
106 }
107}
108
109impl EncodeSize for IpAddr {
110 #[inline]
111 fn encode_size(&self) -> usize {
112 u8::SIZE
113 + match self {
114 Self::V4(_) => Ipv4Addr::SIZE,
115 Self::V6(_) => Ipv6Addr::SIZE,
116 }
117 }
118}
119
120impl MaxEncodeSize for IpAddr {
121 const MAX_ENCODE_SIZE: usize = u8::SIZE + Ipv6Addr::SIZE;
122}
123
124impl Read for IpAddr {
125 type Cfg = ();
126
127 #[inline]
128 fn read_cfg(buf: &mut impl Buf, _: &()) -> Result<Self, Error> {
129 let version = u8::read(buf)?;
130 match version {
131 4 => Ok(Self::V4(Ipv4Addr::read(buf)?)),
132 6 => Ok(Self::V6(Ipv6Addr::read(buf)?)),
133 _ => Err(Error::Invalid("IpAddr", "Invalid version")),
134 }
135 }
136}
137
138impl Write for SocketAddr {
140 #[inline]
141 fn write(&self, buf: &mut impl BufMut) {
142 self.ip().write(buf);
143 self.port().write(buf);
144 }
145}
146
147impl EncodeSize for SocketAddr {
148 #[inline]
149 fn encode_size(&self) -> usize {
150 self.ip().encode_size() + u16::SIZE
151 }
152}
153
154impl MaxEncodeSize for SocketAddr {
155 const MAX_ENCODE_SIZE: usize = IpAddr::MAX_ENCODE_SIZE + u16::SIZE;
156}
157
158impl Read for SocketAddr {
159 type Cfg = ();
160
161 #[inline]
162 fn read_cfg(buf: &mut impl Buf, _: &()) -> Result<Self, Error> {
163 let ip = IpAddr::read(buf)?;
164 let port = u16::read(buf)?;
165 Ok(Self::new(ip, port))
166 }
167}
168
169#[cfg(test)]
170mod test {
171 use super::*;
172 use crate::{Copying, DecodeExt, Encode};
173 use bytes::Bytes;
174
175 #[test]
176 fn test_ipv4_addr() {
177 let ips = [
179 Ipv4Addr::UNSPECIFIED,
180 Ipv4Addr::LOCALHOST,
181 Ipv4Addr::new(192, 168, 1, 1),
182 Ipv4Addr::new(255, 255, 255, 255),
183 ];
184
185 for ip in ips.iter() {
186 let encoded = ip.encode();
187 assert_eq!(encoded.len(), 4);
188 let decoded = Ipv4Addr::decode(encoded).unwrap();
189 assert_eq!(*ip, decoded);
190 }
191
192 let insufficient = vec![0, 0, 0]; assert!(Ipv4Addr::decode(insufficient).is_err());
195 }
196
197 #[test]
198 fn test_ipv6_addr() {
199 let ips = [
201 Ipv6Addr::UNSPECIFIED,
202 Ipv6Addr::LOCALHOST,
203 Ipv6Addr::new(0x2001, 0x0db8, 0, 0, 0, 0, 0, 1),
204 Ipv6Addr::new(
205 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
206 ),
207 ];
208
209 for ip in ips.iter() {
210 let encoded = ip.encode();
211 assert_eq!(encoded.len(), 16);
212 let decoded = Ipv6Addr::decode(encoded).unwrap();
213 assert_eq!(*ip, decoded);
214 }
215
216 let insufficient = Bytes::from(vec![0u8; 15]); assert!(Ipv6Addr::decode(insufficient).is_err());
219 }
220
221 #[test]
222 fn test_socket_addr_v4() {
223 let addrs = [
225 SocketAddrV4::new(Ipv4Addr::UNSPECIFIED, 0),
226 SocketAddrV4::new(Ipv4Addr::LOCALHOST, 8080),
227 SocketAddrV4::new(Ipv4Addr::new(192, 168, 1, 1), 65535),
228 ];
229
230 for addr in addrs.iter() {
231 let encoded = addr.encode();
232 assert_eq!(encoded.len(), 6);
233 let decoded = SocketAddrV4::decode(encoded).unwrap();
234 assert_eq!(*addr, decoded);
235 }
236
237 let insufficient = Bytes::from(vec![0u8; 5]); assert!(SocketAddrV4::decode(insufficient).is_err());
240 }
241
242 #[test]
243 fn test_socket_addr_v6() {
244 let addrs = [
246 SocketAddrV6::new(Ipv6Addr::UNSPECIFIED, 0, 0, 0),
247 SocketAddrV6::new(Ipv6Addr::LOCALHOST, 8080, 0, 0),
248 SocketAddrV6::new(Ipv6Addr::new(0x2001, 0x0db8, 0, 0, 0, 0, 0, 1), 65535, 0, 0),
249 ];
250
251 for addr in addrs.iter() {
252 let encoded = addr.encode();
253 assert_eq!(encoded.len(), 18);
254 let decoded = SocketAddrV6::decode(encoded).unwrap();
255 assert_eq!(*addr, decoded);
256 }
257
258 let insufficient = Bytes::from(vec![0u8; 17]); assert!(SocketAddrV6::decode(insufficient).is_err());
261 }
262
263 #[test]
264 fn test_ip_addr() {
265 let addr_v4 = IpAddr::V4(Ipv4Addr::new(192, 168, 1, 1));
267 let encoded_v4 = addr_v4.encode();
268 assert_eq!(encoded_v4.len(), 5);
269 assert_eq!(addr_v4.encode_size(), 5);
270 let decoded_v4 = IpAddr::decode(encoded_v4).unwrap();
271 assert_eq!(addr_v4, decoded_v4);
272
273 let addr_v6 = IpAddr::V6(Ipv6Addr::new(0x2001, 0x0db8, 0, 0, 0, 0, 0, 1));
275 let encoded_v6 = addr_v6.encode();
276 assert_eq!(encoded_v6.len(), 17);
277 assert_eq!(addr_v6.encode_size(), 17);
278 let decoded_v6 = IpAddr::decode(encoded_v6).unwrap();
279 assert_eq!(addr_v6, decoded_v6);
280
281 let invalid_version = [5];
283 assert!(matches!(
284 IpAddr::decode(Copying(&invalid_version)),
285 Err(Error::Invalid(_, _))
286 ));
287
288 let insufficient_v4 = [4, 127, 0, 0]; assert!(IpAddr::decode(Copying(&insufficient_v4)).is_err());
291
292 let mut insufficient_v6 = vec![6];
294 insufficient_v6.extend_from_slice(&[0; 15]); assert!(IpAddr::decode(Copying(&insufficient_v6)).is_err());
296 }
297
298 #[test]
299 fn test_socket_addr() {
300 let addr_v4 = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(196, 168, 0, 1)), 8080);
302 let encoded_v4 = addr_v4.encode();
303 assert_eq!(encoded_v4.len(), 7);
304 assert_eq!(addr_v4.encode_size(), 7);
305 let decoded_v4 = SocketAddr::decode(encoded_v4).unwrap();
306 assert_eq!(addr_v4, decoded_v4);
307
308 let addr_v6 = SocketAddr::new(
310 IpAddr::V6(Ipv6Addr::new(
311 0x2001, 0x0db8, 0xffff, 0x1234, 0x5678, 0x9abc, 0xdeff, 1,
312 )),
313 8080,
314 );
315 let encoded_v6 = addr_v6.encode();
316 assert_eq!(encoded_v6.len(), 19);
317 assert_eq!(addr_v6.encode_size(), 19);
318 let decoded_v6 = SocketAddr::decode(encoded_v6).unwrap();
319 assert_eq!(addr_v6, decoded_v6);
320
321 let invalid_version = [5]; assert!(matches!(
324 SocketAddr::decode(Copying(&invalid_version)),
325 Err(Error::Invalid(_, _))
326 ));
327
328 let mut insufficient_v4 = vec![4]; insufficient_v4.extend_from_slice(&[127, 0, 0, 1, 0x1f]); assert!(SocketAddr::decode(Copying(&insufficient_v4)).is_err());
332
333 let mut insufficient_v6 = vec![6]; insufficient_v6.extend_from_slice(&[0; 17]); assert!(SocketAddr::decode(Copying(&insufficient_v6)).is_err());
337 }
338
339 #[test]
340 fn test_conformity() {
341 assert_eq!(Ipv4Addr::new(0, 0, 0, 0).encode(), &[0, 0, 0, 0][..]);
342 assert_eq!(Ipv4Addr::new(127, 0, 0, 1).encode(), &[127, 0, 0, 1][..]);
343 assert_eq!(
344 Ipv4Addr::new(192, 168, 1, 100).encode(),
345 &[192, 168, 1, 100][..]
346 );
347 assert_eq!(
348 Ipv4Addr::new(255, 255, 255, 255).encode(),
349 &[255, 255, 255, 255][..]
350 );
351
352 assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0).encode(), &[0; 16][..]);
353 assert_eq!(
354 Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1).encode(),
355 &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1][..]
356 );
357 let ipv6_test: Ipv6Addr = "2001:db8::ff00:42:8329".parse().unwrap();
358 assert_eq!(
359 ipv6_test.encode(),
360 &[
361 0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0, 0, 0, 0xff, 0x00, 0, 0x42, 0x83, 0x29
362 ][..]
363 );
364 assert_eq!(
365 Ipv6Addr::new(
366 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff
367 )
368 .encode(),
369 &[0xff; 16][..]
370 );
371
372 let sock_v4_1 = SocketAddrV4::new(Ipv4Addr::new(10, 0, 0, 1), 80);
373 assert_eq!(sock_v4_1.encode(), &[10, 0, 0, 1, 0x00, 0x50][..]);
374 let sock_v4_2 = SocketAddrV4::new(Ipv4Addr::new(192, 168, 20, 30), 65535);
375 assert_eq!(sock_v4_2.encode(), &[192, 168, 20, 30, 0xFF, 0xFF][..]);
376
377 let sock_v6_1 =
378 SocketAddrV6::new(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1), 8080, 0, 0);
379 assert_eq!(
380 sock_v6_1.encode(),
381 &[
382 0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0x1F, 0x90
383 ][..]
384 );
385
386 let sa_v4 = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080);
387 assert_eq!(sa_v4.encode(), &[0x04, 127, 0, 0, 1, 0x1F, 0x90][..]);
388 let sa_v6 = SocketAddr::new(IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)), 443);
389 assert_eq!(
390 sa_v6.encode(),
391 &[
392 0x06, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0x01, 0xBB
393 ][..]
394 );
395 }
396
397 #[test]
398 fn test_max_encode_size() {
399 let v6 = SocketAddr::new(IpAddr::V6(Ipv6Addr::LOCALHOST), u16::MAX);
401 assert_eq!(v6.ip().encode_size(), IpAddr::MAX_ENCODE_SIZE);
402 assert_eq!(v6.encode_size(), SocketAddr::MAX_ENCODE_SIZE);
403
404 let v4 = SocketAddr::new(IpAddr::V4(Ipv4Addr::LOCALHOST), u16::MAX);
406 assert!(v4.ip().encode_size() < IpAddr::MAX_ENCODE_SIZE);
407 assert!(v4.encode_size() < SocketAddr::MAX_ENCODE_SIZE);
408 }
409
410 #[cfg(feature = "arbitrary")]
411 mod conformance {
412 use super::*;
413 use crate::conformance::CodecConformance;
414
415 commonware_conformance::conformance_tests! {
416 CodecConformance<Ipv4Addr>,
417 CodecConformance<Ipv6Addr>,
418 CodecConformance<SocketAddrV4>,
419 CodecConformance<SocketAddrV6>,
420 CodecConformance<IpAddr>,
421 CodecConformance<SocketAddr>,
422 }
423 }
424}