commonware_codec/types/
net.rs

1//! Codec implementations for network-related types
2
3use crate::{EncodeSize, Error, FixedSize, Read, ReadExt, Write};
4use bytes::{Buf, BufMut};
5use std::net::{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(Ipv4Addr::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(Ipv6Addr::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(SocketAddrV6::new(address, port, 0, 0))
86    }
87}
88
89impl FixedSize for SocketAddrV6 {
90    const SIZE: usize = Ipv6Addr::SIZE + u16::SIZE;
91}
92
93// SocketAddr implementation
94impl Write for SocketAddr {
95    #[inline]
96    fn write(&self, buf: &mut impl BufMut) {
97        match self {
98            SocketAddr::V4(v4) => {
99                4u8.write(buf);
100                v4.write(buf);
101            }
102            SocketAddr::V6(v6) => {
103                6u8.write(buf);
104                v6.write(buf);
105            }
106        }
107    }
108}
109
110impl EncodeSize for SocketAddr {
111    #[inline]
112    fn encode_size(&self) -> usize {
113        (match self {
114            SocketAddr::V4(_) => SocketAddrV4::SIZE,
115            SocketAddr::V6(_) => SocketAddrV6::SIZE,
116        }) + u8::SIZE
117    }
118}
119
120impl Read for SocketAddr {
121    type Cfg = ();
122
123    #[inline]
124    fn read_cfg(buf: &mut impl Buf, _: &()) -> Result<Self, Error> {
125        let version = u8::read(buf)?;
126        match version {
127            4 => Ok(SocketAddr::V4(SocketAddrV4::read(buf)?)),
128            6 => Ok(SocketAddr::V6(SocketAddrV6::read(buf)?)),
129            _ => Err(Error::Invalid("SocketAddr", "Invalid version")),
130        }
131    }
132}
133
134#[cfg(test)]
135mod test {
136    use super::*;
137    use crate::{DecodeExt, Encode};
138    use bytes::Bytes;
139
140    #[test]
141    fn test_ipv4_addr() {
142        // Test various IPv4 addresses
143        let ips = [
144            Ipv4Addr::UNSPECIFIED,
145            Ipv4Addr::LOCALHOST,
146            Ipv4Addr::new(192, 168, 1, 1),
147            Ipv4Addr::new(255, 255, 255, 255),
148        ];
149
150        for ip in ips.iter() {
151            let encoded = ip.encode();
152            assert_eq!(encoded.len(), 4);
153            let decoded = Ipv4Addr::decode(encoded).unwrap();
154            assert_eq!(*ip, decoded);
155        }
156
157        // Test insufficient data
158        let insufficient = vec![0, 0, 0]; // 3 bytes instead of 4
159        assert!(Ipv4Addr::decode(Bytes::from(insufficient)).is_err());
160    }
161
162    #[test]
163    fn test_ipv6_addr() {
164        // Test various IPv6 addresses
165        let ips = [
166            Ipv6Addr::UNSPECIFIED,
167            Ipv6Addr::LOCALHOST,
168            Ipv6Addr::new(0x2001, 0x0db8, 0, 0, 0, 0, 0, 1),
169            Ipv6Addr::new(
170                0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
171            ),
172        ];
173
174        for ip in ips.iter() {
175            let encoded = ip.encode();
176            assert_eq!(encoded.len(), 16);
177            let decoded = Ipv6Addr::decode(encoded).unwrap();
178            assert_eq!(*ip, decoded);
179        }
180
181        // Test insufficient data
182        let insufficient = Bytes::from(vec![0u8; 15]); // 15 bytes instead of 16
183        assert!(Ipv6Addr::decode(insufficient).is_err());
184    }
185
186    #[test]
187    fn test_socket_addr_v4() {
188        // Test various SocketAddrV4 instances
189        let addrs = [
190            SocketAddrV4::new(Ipv4Addr::UNSPECIFIED, 0),
191            SocketAddrV4::new(Ipv4Addr::LOCALHOST, 8080),
192            SocketAddrV4::new(Ipv4Addr::new(192, 168, 1, 1), 65535),
193        ];
194
195        for addr in addrs.iter() {
196            let encoded = addr.encode();
197            assert_eq!(encoded.len(), 6);
198            let decoded = SocketAddrV4::decode(encoded).unwrap();
199            assert_eq!(*addr, decoded);
200        }
201
202        // Test insufficient data
203        let insufficient = Bytes::from(vec![0u8; 5]); // 5 bytes instead of 6
204        assert!(SocketAddrV4::decode(insufficient).is_err());
205    }
206
207    #[test]
208    fn test_socket_addr_v6() {
209        // Test various SocketAddrV6 instances
210        let addrs = [
211            SocketAddrV6::new(Ipv6Addr::UNSPECIFIED, 0, 0, 0),
212            SocketAddrV6::new(Ipv6Addr::LOCALHOST, 8080, 0, 0),
213            SocketAddrV6::new(Ipv6Addr::new(0x2001, 0x0db8, 0, 0, 0, 0, 0, 1), 65535, 0, 0),
214        ];
215
216        for addr in addrs.iter() {
217            let encoded = addr.encode();
218            assert_eq!(encoded.len(), 18);
219            let decoded = SocketAddrV6::decode(encoded).unwrap();
220            assert_eq!(*addr, decoded);
221        }
222
223        // Test insufficient data
224        let insufficient = Bytes::from(vec![0u8; 17]); // 17 bytes instead of 18
225        assert!(SocketAddrV6::decode(insufficient).is_err());
226    }
227
228    #[test]
229    fn test_socket_addr() {
230        // Test SocketAddr::V4
231        let addr_v4 = SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(196, 168, 0, 1), 8080));
232        let encoded_v4 = addr_v4.encode();
233        assert_eq!(encoded_v4.len(), 7);
234        assert_eq!(addr_v4.encode_size(), 7);
235        let decoded_v4 = SocketAddr::decode(encoded_v4).unwrap();
236        assert_eq!(addr_v4, decoded_v4);
237
238        // Test SocketAddr::V6
239        let addr_v6 = SocketAddr::V6(SocketAddrV6::new(
240            Ipv6Addr::new(0x2001, 0x0db8, 0xffff, 0x1234, 0x5678, 0x9abc, 0xdeff, 1),
241            8080,
242            0,
243            0,
244        ));
245        let encoded_v6 = addr_v6.encode();
246        assert_eq!(encoded_v6.len(), 19);
247        assert_eq!(addr_v6.encode_size(), 19);
248        let decoded_v6 = SocketAddr::decode(encoded_v6).unwrap();
249        assert_eq!(addr_v6, decoded_v6);
250
251        // Test invalid version
252        let invalid_version = [5]; // Neither 4 nor 6
253        assert!(matches!(
254            SocketAddr::decode(&invalid_version[..]),
255            Err(Error::Invalid(_, _))
256        ));
257
258        // Test insufficient data for V4
259        let mut insufficient_v4 = vec![4]; // Version byte
260        insufficient_v4.extend_from_slice(&[127, 0, 0, 1, 0x1f]); // IP + 1 byte of port (5 bytes total)
261        assert!(SocketAddr::decode(&insufficient_v4[..]).is_err());
262
263        // Test insufficient data for V6
264        let mut insufficient_v6 = vec![6]; // Version byte
265        insufficient_v6.extend_from_slice(&[0; 17]); // 17 bytes instead of 18
266        assert!(SocketAddr::decode(&insufficient_v6[..]).is_err());
267    }
268
269    #[test]
270    fn test_conformity() {
271        assert_eq!(Ipv4Addr::new(0, 0, 0, 0).encode(), &[0, 0, 0, 0][..]);
272        assert_eq!(Ipv4Addr::new(127, 0, 0, 1).encode(), &[127, 0, 0, 1][..]);
273        assert_eq!(
274            Ipv4Addr::new(192, 168, 1, 100).encode(),
275            &[192, 168, 1, 100][..]
276        );
277        assert_eq!(
278            Ipv4Addr::new(255, 255, 255, 255).encode(),
279            &[255, 255, 255, 255][..]
280        );
281
282        assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0).encode(), &[0; 16][..]);
283        assert_eq!(
284            Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1).encode(),
285            &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1][..]
286        );
287        let ipv6_test: Ipv6Addr = "2001:db8::ff00:42:8329".parse().unwrap();
288        assert_eq!(
289            ipv6_test.encode(),
290            &[0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0, 0, 0, 0xff, 0x00, 0, 0x42, 0x83, 0x29][..]
291        );
292        assert_eq!(
293            Ipv6Addr::new(0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff).encode(),
294            &[0xff; 16][..]
295        );
296
297        let sock_v4_1 = SocketAddrV4::new(Ipv4Addr::new(10, 0, 0, 1), 80);
298        assert_eq!(sock_v4_1.encode(), &[10, 0, 0, 1, 0x00, 0x50][..]);
299        let sock_v4_2 = SocketAddrV4::new(Ipv4Addr::new(192, 168, 20, 30), 65535);
300        assert_eq!(sock_v4_2.encode(), &[192, 168, 20, 30, 0xFF, 0xFF][..]);
301
302        let sock_v6_1 =
303            SocketAddrV6::new(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1), 8080, 0, 0);
304        assert_eq!(
305            sock_v6_1.encode(),
306            &[0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0x1F, 0x90][..]
307        );
308
309        let sa_v4 = SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080));
310        assert_eq!(sa_v4.encode(), &[0x04, 127, 0, 0, 1, 0x1F, 0x90][..]);
311        let sa_v6 = SocketAddr::V6(SocketAddrV6::new(
312            Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1),
313            443,
314            0,
315            0,
316        ));
317        assert_eq!(
318            sa_v6.encode(),
319            &[0x06, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0x01, 0xBB][..]
320        );
321    }
322}