commonware_codec/types/
net.rs

1use crate::{Codec, Error, SizedCodec};
2use bytes::{Buf, BufMut};
3use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6};
4
5impl Codec for Ipv4Addr {
6    #[inline]
7    fn write(&self, buf: &mut impl BufMut) {
8        self.to_bits().write(buf);
9    }
10
11    #[inline]
12    fn len_encoded(&self) -> usize {
13        Self::LEN_ENCODED
14    }
15
16    #[inline]
17    fn read(buf: &mut impl Buf) -> Result<Self, Error> {
18        let bits = <u32>::read(buf)?;
19        Ok(Ipv4Addr::from_bits(bits))
20    }
21}
22
23impl SizedCodec for Ipv4Addr {
24    const LEN_ENCODED: usize = u32::LEN_ENCODED;
25}
26
27impl Codec for Ipv6Addr {
28    #[inline]
29    fn write(&self, buf: &mut impl BufMut) {
30        self.to_bits().write(buf);
31    }
32
33    #[inline]
34    fn len_encoded(&self) -> usize {
35        Self::LEN_ENCODED
36    }
37
38    #[inline]
39    fn read(buf: &mut impl Buf) -> Result<Self, Error> {
40        let bits = <u128>::read(buf)?;
41        Ok(Ipv6Addr::from_bits(bits))
42    }
43}
44
45impl SizedCodec for Ipv6Addr {
46    const LEN_ENCODED: usize = u128::LEN_ENCODED;
47}
48
49impl Codec for SocketAddrV4 {
50    #[inline]
51    fn write(&self, buf: &mut impl BufMut) {
52        self.ip().write(buf);
53        self.port().write(buf);
54    }
55
56    #[inline]
57    fn len_encoded(&self) -> usize {
58        Self::LEN_ENCODED
59    }
60
61    #[inline]
62    fn read(buf: &mut impl Buf) -> Result<Self, Error> {
63        let ip = Ipv4Addr::read(buf)?;
64        let port = u16::read(buf)?;
65        Ok(Self::new(ip, port))
66    }
67}
68
69impl SizedCodec for SocketAddrV4 {
70    const LEN_ENCODED: usize = Ipv4Addr::LEN_ENCODED + u16::LEN_ENCODED;
71}
72
73impl Codec for SocketAddrV6 {
74    #[inline]
75    fn write(&self, buf: &mut impl BufMut) {
76        self.ip().write(buf);
77        self.port().write(buf);
78    }
79
80    #[inline]
81    fn len_encoded(&self) -> usize {
82        Self::LEN_ENCODED
83    }
84
85    #[inline]
86    fn read(buf: &mut impl Buf) -> Result<Self, Error> {
87        let address = Ipv6Addr::read(buf)?;
88        let port = u16::read(buf)?;
89        Ok(SocketAddrV6::new(address, port, 0, 0))
90    }
91}
92
93impl SizedCodec for SocketAddrV6 {
94    const LEN_ENCODED: usize = Ipv6Addr::LEN_ENCODED + u16::LEN_ENCODED;
95}
96
97// SocketAddr implementation
98impl Codec for SocketAddr {
99    #[inline]
100    fn write(&self, buf: &mut impl BufMut) {
101        match self {
102            SocketAddr::V4(v4) => {
103                u8::write(&4, buf);
104                v4.write(buf);
105            }
106            SocketAddr::V6(v6) => {
107                u8::write(&6, buf);
108                v6.write(buf);
109            }
110        }
111    }
112
113    #[inline]
114    fn len_encoded(&self) -> usize {
115        (match self {
116            SocketAddr::V4(_) => SocketAddrV4::LEN_ENCODED,
117            SocketAddr::V6(_) => SocketAddrV6::LEN_ENCODED,
118        }) + u8::LEN_ENCODED
119    }
120
121    #[inline]
122    fn read(buf: &mut impl Buf) -> Result<Self, Error> {
123        let version = u8::read(buf)?;
124        match version {
125            4 => Ok(SocketAddr::V4(SocketAddrV4::read(buf)?)),
126            6 => Ok(SocketAddr::V6(SocketAddrV6::read(buf)?)),
127            _ => Err(Error::Invalid("SocketAddr", "Invalid version")),
128        }
129    }
130}
131
132#[cfg(test)]
133mod test {
134    use super::*;
135    use bytes::Bytes;
136
137    #[test]
138    fn test_ipv4_addr() {
139        // Test various IPv4 addresses
140        let ips = [
141            Ipv4Addr::UNSPECIFIED,
142            Ipv4Addr::LOCALHOST,
143            Ipv4Addr::new(192, 168, 1, 1),
144            Ipv4Addr::new(255, 255, 255, 255),
145        ];
146
147        for ip in ips.iter() {
148            let encoded = ip.encode();
149            assert_eq!(encoded.len(), 4);
150            let decoded = Ipv4Addr::decode(encoded).unwrap();
151            assert_eq!(*ip, decoded);
152        }
153
154        // Test insufficient data
155        let insufficient = vec![0, 0, 0]; // 3 bytes instead of 4
156        assert!(Ipv4Addr::decode(Bytes::from(insufficient)).is_err());
157    }
158
159    #[test]
160    fn test_ipv6_addr() {
161        // Test various IPv6 addresses
162        let ips = [
163            Ipv6Addr::UNSPECIFIED,
164            Ipv6Addr::LOCALHOST,
165            Ipv6Addr::new(0x2001, 0x0db8, 0, 0, 0, 0, 0, 1),
166            Ipv6Addr::new(
167                0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
168            ),
169        ];
170
171        for ip in ips.iter() {
172            let encoded = ip.encode();
173            assert_eq!(encoded.len(), 16);
174            let decoded = Ipv6Addr::decode(encoded).unwrap();
175            assert_eq!(*ip, decoded);
176        }
177
178        // Test insufficient data
179        let insufficient = Bytes::from(vec![0u8; 15]); // 15 bytes instead of 16
180        assert!(Ipv6Addr::decode(insufficient).is_err());
181    }
182
183    #[test]
184    fn test_socket_addr_v4() {
185        // Test various SocketAddrV4 instances
186        let addrs = [
187            SocketAddrV4::new(Ipv4Addr::UNSPECIFIED, 0),
188            SocketAddrV4::new(Ipv4Addr::LOCALHOST, 8080),
189            SocketAddrV4::new(Ipv4Addr::new(192, 168, 1, 1), 65535),
190        ];
191
192        for addr in addrs.iter() {
193            let encoded = addr.encode();
194            assert_eq!(encoded.len(), 6);
195            let decoded = SocketAddrV4::decode(encoded).unwrap();
196            assert_eq!(*addr, decoded);
197        }
198
199        // Test insufficient data
200        let insufficient = Bytes::from(vec![0u8; 5]); // 5 bytes instead of 6
201        assert!(SocketAddrV4::decode(insufficient).is_err());
202    }
203
204    #[test]
205    fn test_socket_addr_v6() {
206        // Test various SocketAddrV6 instances
207        let addrs = [
208            SocketAddrV6::new(Ipv6Addr::UNSPECIFIED, 0, 0, 0),
209            SocketAddrV6::new(Ipv6Addr::LOCALHOST, 8080, 0, 0),
210            SocketAddrV6::new(Ipv6Addr::new(0x2001, 0x0db8, 0, 0, 0, 0, 0, 1), 65535, 0, 0),
211        ];
212
213        for addr in addrs.iter() {
214            let encoded = addr.encode();
215            assert_eq!(encoded.len(), 18);
216            let decoded = SocketAddrV6::decode(encoded).unwrap();
217            assert_eq!(*addr, decoded);
218        }
219
220        // Test insufficient data
221        let insufficient = Bytes::from(vec![0u8; 17]); // 17 bytes instead of 18
222        assert!(SocketAddrV6::decode(insufficient).is_err());
223    }
224
225    #[test]
226    fn test_socket_addr() {
227        // Test SocketAddr::V4
228        let addr_v4 = SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(196, 168, 0, 1), 8080));
229        let encoded_v4 = addr_v4.encode();
230        assert_eq!(encoded_v4.len(), 7);
231        assert_eq!(addr_v4.len_encoded(), 7);
232        let decoded_v4 = SocketAddr::decode(encoded_v4).unwrap();
233        assert_eq!(addr_v4, decoded_v4);
234
235        // Test SocketAddr::V6
236        let addr_v6 = SocketAddr::V6(SocketAddrV6::new(
237            Ipv6Addr::new(0x2001, 0x0db8, 0xffff, 0x1234, 0x5678, 0x9abc, 0xdeff, 1),
238            8080,
239            0,
240            0,
241        ));
242        let encoded_v6 = addr_v6.encode();
243        assert_eq!(encoded_v6.len(), 19);
244        assert_eq!(addr_v6.len_encoded(), 19);
245        let decoded_v6 = SocketAddr::decode(encoded_v6).unwrap();
246        assert_eq!(addr_v6, decoded_v6);
247
248        // Test invalid version
249        let invalid_version = [5]; // Neither 4 nor 6
250        assert!(matches!(
251            SocketAddr::decode(&invalid_version[..]),
252            Err(Error::Invalid(_, _))
253        ));
254
255        // Test insufficient data for V4
256        let mut insufficient_v4 = vec![4]; // Version byte
257        insufficient_v4.extend_from_slice(&[127, 0, 0, 1, 0x1f]); // IP + 1 byte of port (5 bytes total)
258        assert!(SocketAddr::decode(&insufficient_v4[..]).is_err());
259
260        // Test insufficient data for V6
261        let mut insufficient_v6 = vec![6]; // Version byte
262        insufficient_v6.extend_from_slice(&[0; 17]); // 17 bytes instead of 18
263        assert!(SocketAddr::decode(&insufficient_v6[..]).is_err());
264    }
265}