bitcoin/p2p/
address.rs

1// SPDX-License-Identifier: CC0-1.0
2
3//! Bitcoin network addresses.
4//!
5//! This module defines the structures and functions needed to encode
6//! network addresses in Bitcoin messages.
7//!
8
9use core::{fmt, iter};
10use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6, ToSocketAddrs};
11
12use io::{Read, Write};
13
14use crate::consensus::encode::{self, Decodable, Encodable, ReadExt, VarInt, WriteExt};
15use crate::p2p::ServiceFlags;
16
17/// A message which can be sent on the Bitcoin network
18#[derive(Clone, PartialEq, Eq, Hash)]
19pub struct Address {
20    /// Services provided by the peer whose address this is
21    pub services: ServiceFlags,
22    /// Network byte-order ipv6 address, or ipv4-mapped ipv6 address
23    pub address: [u16; 8],
24    /// Network port
25    pub port: u16,
26}
27
28const ONION: [u16; 3] = [0xFD87, 0xD87E, 0xEB43];
29
30impl Address {
31    /// Create an address message for a socket
32    pub fn new(socket: &SocketAddr, services: ServiceFlags) -> Address {
33        let (address, port) = match *socket {
34            SocketAddr::V4(addr) => (addr.ip().to_ipv6_mapped().segments(), addr.port()),
35            SocketAddr::V6(addr) => (addr.ip().segments(), addr.port()),
36        };
37        Address { address, port, services }
38    }
39
40    /// Extract socket address from an [Address] message.
41    /// This will return [io::Error] [io::ErrorKind::AddrNotAvailable]
42    /// if the message contains a Tor address.
43    pub fn socket_addr(&self) -> Result<SocketAddr, io::Error> {
44        let addr = &self.address;
45        if addr[0..3] == ONION {
46            return Err(io::Error::from(io::ErrorKind::AddrNotAvailable));
47        }
48        let ipv6 =
49            Ipv6Addr::new(addr[0], addr[1], addr[2], addr[3], addr[4], addr[5], addr[6], addr[7]);
50        if let Some(ipv4) = ipv6.to_ipv4() {
51            Ok(SocketAddr::V4(SocketAddrV4::new(ipv4, self.port)))
52        } else {
53            Ok(SocketAddr::V6(SocketAddrV6::new(ipv6, self.port, 0, 0)))
54        }
55    }
56}
57
58impl Encodable for Address {
59    #[inline]
60    fn consensus_encode<W: Write + ?Sized>(&self, w: &mut W) -> Result<usize, io::Error> {
61        let mut len = self.services.consensus_encode(w)?;
62
63        for word in &self.address {
64            w.write_all(&word.to_be_bytes())?;
65            len += 2;
66        }
67
68        w.write_all(&self.port.to_be_bytes())?;
69        len += 2;
70
71        Ok(len)
72    }
73}
74
75impl Decodable for Address {
76    #[inline]
77    fn consensus_decode<R: Read + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
78        Ok(Address {
79            services: Decodable::consensus_decode(r)?,
80            address: read_be_address(r)?,
81            port: u16::swap_bytes(Decodable::consensus_decode(r)?),
82        })
83    }
84}
85
86/// Read a big-endian address from reader.
87fn read_be_address<R: Read + ?Sized>(r: &mut R) -> Result<[u16; 8], encode::Error> {
88    let mut address = [0u16; 8];
89    let mut buf = [0u8; 2];
90
91    for word in &mut address {
92        Read::read_exact(r, &mut buf)?;
93        *word = u16::from_be_bytes(buf)
94    }
95    Ok(address)
96}
97
98impl fmt::Debug for Address {
99    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
100        let ipv6 = Ipv6Addr::from(self.address);
101
102        match ipv6.to_ipv4() {
103            Some(addr) => write!(
104                f,
105                "Address {{services: {}, address: {}, port: {}}}",
106                self.services, addr, self.port
107            ),
108            None => write!(
109                f,
110                "Address {{services: {}, address: {}, port: {}}}",
111                self.services, ipv6, self.port
112            ),
113        }
114    }
115}
116
117impl ToSocketAddrs for Address {
118    type Iter = iter::Once<SocketAddr>;
119    fn to_socket_addrs(&self) -> Result<Self::Iter, std::io::Error> {
120        Ok(iter::once(self.socket_addr()?))
121    }
122}
123
124/// Supported networks for use in BIP155 addrv2 message
125#[derive(Clone, PartialEq, Eq, Hash, Debug)]
126pub enum AddrV2 {
127    /// IPV4
128    Ipv4(Ipv4Addr),
129    /// IPV6
130    Ipv6(Ipv6Addr),
131    /// TORV2
132    TorV2([u8; 10]),
133    /// TORV3
134    TorV3([u8; 32]),
135    /// I2P
136    I2p([u8; 32]),
137    /// CJDNS
138    Cjdns(Ipv6Addr),
139    /// Unknown
140    Unknown(u8, Vec<u8>),
141}
142
143impl Encodable for AddrV2 {
144    fn consensus_encode<W: Write + ?Sized>(&self, w: &mut W) -> Result<usize, io::Error> {
145        fn encode_addr<W: Write + ?Sized>(
146            w: &mut W,
147            network: u8,
148            bytes: &[u8],
149        ) -> Result<usize, io::Error> {
150            let len = network.consensus_encode(w)?
151                + VarInt::from(bytes.len()).consensus_encode(w)?
152                + bytes.len();
153            w.emit_slice(bytes)?;
154            Ok(len)
155        }
156        Ok(match *self {
157            AddrV2::Ipv4(ref addr) => encode_addr(w, 1, &addr.octets())?,
158            AddrV2::Ipv6(ref addr) => encode_addr(w, 2, &addr.octets())?,
159            AddrV2::TorV2(ref bytes) => encode_addr(w, 3, bytes)?,
160            AddrV2::TorV3(ref bytes) => encode_addr(w, 4, bytes)?,
161            AddrV2::I2p(ref bytes) => encode_addr(w, 5, bytes)?,
162            AddrV2::Cjdns(ref addr) => encode_addr(w, 6, &addr.octets())?,
163            AddrV2::Unknown(network, ref bytes) => encode_addr(w, network, bytes)?,
164        })
165    }
166}
167
168impl Decodable for AddrV2 {
169    fn consensus_decode<R: Read + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
170        let network_id = u8::consensus_decode(r)?;
171        let len = VarInt::consensus_decode(r)?.0;
172        if len > 512 {
173            return Err(encode::Error::ParseFailed("IP must be <= 512 bytes"));
174        }
175        Ok(match network_id {
176            1 => {
177                if len != 4 {
178                    return Err(encode::Error::ParseFailed("Invalid IPv4 address"));
179                }
180                let addr: [u8; 4] = Decodable::consensus_decode(r)?;
181                AddrV2::Ipv4(Ipv4Addr::new(addr[0], addr[1], addr[2], addr[3]))
182            }
183            2 => {
184                if len != 16 {
185                    return Err(encode::Error::ParseFailed("Invalid IPv6 address"));
186                }
187                let addr: [u16; 8] = read_be_address(r)?;
188                if addr[0..3] == ONION {
189                    return Err(encode::Error::ParseFailed(
190                        "OnionCat address sent with IPv6 network id",
191                    ));
192                }
193                if addr[0..6] == [0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF] {
194                    return Err(encode::Error::ParseFailed(
195                        "IPV4 wrapped address sent with IPv6 network id",
196                    ));
197                }
198                AddrV2::Ipv6(Ipv6Addr::new(
199                    addr[0], addr[1], addr[2], addr[3], addr[4], addr[5], addr[6], addr[7],
200                ))
201            }
202            3 => {
203                if len != 10 {
204                    return Err(encode::Error::ParseFailed("Invalid TorV2 address"));
205                }
206                let id = Decodable::consensus_decode(r)?;
207                AddrV2::TorV2(id)
208            }
209            4 => {
210                if len != 32 {
211                    return Err(encode::Error::ParseFailed("Invalid TorV3 address"));
212                }
213                let pubkey = Decodable::consensus_decode(r)?;
214                AddrV2::TorV3(pubkey)
215            }
216            5 => {
217                if len != 32 {
218                    return Err(encode::Error::ParseFailed("Invalid I2P address"));
219                }
220                let hash = Decodable::consensus_decode(r)?;
221                AddrV2::I2p(hash)
222            }
223            6 => {
224                if len != 16 {
225                    return Err(encode::Error::ParseFailed("Invalid CJDNS address"));
226                }
227                let addr: [u16; 8] = read_be_address(r)?;
228                // check the first byte for the CJDNS marker
229                if addr[0] >> 8 != 0xFC {
230                    return Err(encode::Error::ParseFailed("Invalid CJDNS address"));
231                }
232                AddrV2::Cjdns(Ipv6Addr::new(
233                    addr[0], addr[1], addr[2], addr[3], addr[4], addr[5], addr[6], addr[7],
234                ))
235            }
236            _ => {
237                // len already checked above to be <= 512
238                let mut addr = vec![0u8; len as usize];
239                r.read_slice(&mut addr)?;
240                AddrV2::Unknown(network_id, addr)
241            }
242        })
243    }
244}
245
246/// Address received from BIP155 addrv2 message
247#[derive(Clone, PartialEq, Eq, Hash, Debug)]
248pub struct AddrV2Message {
249    /// Time that this node was last seen as connected to the network
250    pub time: u32,
251    /// Service bits
252    pub services: ServiceFlags,
253    /// Network ID + Network Address
254    pub addr: AddrV2,
255    /// Network port, 0 if not applicable
256    pub port: u16,
257}
258
259impl AddrV2Message {
260    /// Extract socket address from an [AddrV2Message] message.
261    /// This will return [io::Error] [io::ErrorKind::AddrNotAvailable]
262    /// if the address type can't be converted into a [SocketAddr].
263    pub fn socket_addr(&self) -> Result<SocketAddr, io::Error> {
264        match self.addr {
265            AddrV2::Ipv4(addr) => Ok(SocketAddr::V4(SocketAddrV4::new(addr, self.port))),
266            AddrV2::Ipv6(addr) => Ok(SocketAddr::V6(SocketAddrV6::new(addr, self.port, 0, 0))),
267            _ => Err(io::Error::from(io::ErrorKind::AddrNotAvailable)),
268        }
269    }
270}
271
272impl Encodable for AddrV2Message {
273    fn consensus_encode<W: Write + ?Sized>(&self, w: &mut W) -> Result<usize, io::Error> {
274        let mut len = 0;
275        len += self.time.consensus_encode(w)?;
276        len += VarInt(self.services.to_u64()).consensus_encode(w)?;
277        len += self.addr.consensus_encode(w)?;
278
279        w.write_all(&self.port.to_be_bytes())?;
280        len += 2; // port u16 is two bytes.
281
282        Ok(len)
283    }
284}
285
286impl Decodable for AddrV2Message {
287    fn consensus_decode<R: Read + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
288        Ok(AddrV2Message {
289            time: Decodable::consensus_decode(r)?,
290            services: ServiceFlags::from(VarInt::consensus_decode(r)?.0),
291            addr: Decodable::consensus_decode(r)?,
292            port: u16::swap_bytes(Decodable::consensus_decode(r)?),
293        })
294    }
295}
296
297impl ToSocketAddrs for AddrV2Message {
298    type Iter = iter::Once<SocketAddr>;
299    fn to_socket_addrs(&self) -> Result<Self::Iter, std::io::Error> {
300        Ok(iter::once(self.socket_addr()?))
301    }
302}
303
304#[cfg(test)]
305mod test {
306    use core::str::FromStr;
307    use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr};
308
309    use hex::{test_hex_unwrap as hex, FromHex};
310
311    use super::{AddrV2, AddrV2Message, Address};
312    use crate::consensus::encode::{deserialize, serialize};
313    use crate::p2p::ServiceFlags;
314
315    #[test]
316    fn serialize_address_test() {
317        assert_eq!(
318            serialize(&Address {
319                services: ServiceFlags::NETWORK,
320                address: [0, 0, 0, 0, 0, 0xffff, 0x0a00, 0x0001],
321                port: 8333
322            }),
323            vec![
324                1u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 0x0a, 0, 0, 1,
325                0x20, 0x8d
326            ]
327        );
328    }
329
330    #[test]
331    fn debug_format_test() {
332        let mut flags = ServiceFlags::NETWORK;
333        assert_eq!(
334            format!("The address is: {:?}", Address {
335                services: flags.add(ServiceFlags::WITNESS),
336                address: [0, 0, 0, 0, 0, 0xffff, 0x0a00, 0x0001],
337                port: 8333
338            }),
339            "The address is: Address {services: ServiceFlags(NETWORK|WITNESS), address: 10.0.0.1, port: 8333}"
340        );
341
342        assert_eq!(
343            format!("The address is: {:?}", Address {
344                services: ServiceFlags::NETWORK_LIMITED,
345                address: [0xFD87, 0xD87E, 0xEB43, 0, 0, 0xffff, 0x0a00, 0x0001],
346                port: 8333
347            }),
348            "The address is: Address {services: ServiceFlags(NETWORK_LIMITED), address: fd87:d87e:eb43::ffff:a00:1, port: 8333}"
349        );
350    }
351
352    #[test]
353    fn deserialize_address_test() {
354        let mut addr: Result<Address, _> = deserialize(&[
355            1u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 0x0a, 0, 0, 1,
356            0x20, 0x8d,
357        ]);
358        assert!(addr.is_ok());
359        let full = addr.unwrap();
360        assert!(matches!(full.socket_addr().unwrap(), SocketAddr::V4(_)));
361        assert_eq!(full.services, ServiceFlags::NETWORK);
362        assert_eq!(full.address, [0, 0, 0, 0, 0, 0xffff, 0x0a00, 0x0001]);
363        assert_eq!(full.port, 8333);
364
365        addr = deserialize(&[
366            1u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 0x0a, 0, 0, 1,
367        ]);
368        assert!(addr.is_err());
369    }
370
371    #[test]
372    fn test_socket_addr() {
373        let s4 = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(111, 222, 123, 4)), 5555);
374        let a4 = Address::new(&s4, ServiceFlags::NETWORK | ServiceFlags::WITNESS);
375        assert_eq!(a4.socket_addr().unwrap(), s4);
376        let s6 = SocketAddr::new(
377            IpAddr::V6(Ipv6Addr::new(
378                0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7777, 0x8888,
379            )),
380            9999,
381        );
382        let a6 = Address::new(&s6, ServiceFlags::NETWORK | ServiceFlags::WITNESS);
383        assert_eq!(a6.socket_addr().unwrap(), s6);
384    }
385
386    #[test]
387    fn onion_test() {
388        let onionaddr = SocketAddr::new(
389            IpAddr::V6(Ipv6Addr::from_str("FD87:D87E:EB43:edb1:8e4:3588:e546:35ca").unwrap()),
390            1111,
391        );
392        let addr = Address::new(&onionaddr, ServiceFlags::NONE);
393        assert!(addr.socket_addr().is_err());
394    }
395
396    #[test]
397    fn serialize_addrv2_test() {
398        // Taken from https://github.com/bitcoin/bitcoin/blob/12a1c3ad1a43634d2a98717e49e3f02c4acea2fe/src/test/net_tests.cpp#L348
399
400        let ip = AddrV2::Ipv4(Ipv4Addr::new(1, 2, 3, 4));
401        assert_eq!(serialize(&ip), hex!("010401020304"));
402
403        let ip =
404            AddrV2::Ipv6(Ipv6Addr::from_str("1a1b:2a2b:3a3b:4a4b:5a5b:6a6b:7a7b:8a8b").unwrap());
405        assert_eq!(serialize(&ip), hex!("02101a1b2a2b3a3b4a4b5a5b6a6b7a7b8a8b"));
406
407        let ip = AddrV2::TorV2(FromHex::from_hex("f1f2f3f4f5f6f7f8f9fa").unwrap());
408        assert_eq!(serialize(&ip), hex!("030af1f2f3f4f5f6f7f8f9fa"));
409
410        let ip = AddrV2::TorV3(
411            FromHex::from_hex("53cd5648488c4707914182655b7664034e09e66f7e8cbf1084e654eb56c5bd88")
412                .unwrap(),
413        );
414        assert_eq!(
415            serialize(&ip),
416            hex!("042053cd5648488c4707914182655b7664034e09e66f7e8cbf1084e654eb56c5bd88")
417        );
418
419        let ip = AddrV2::I2p(
420            FromHex::from_hex("a2894dabaec08c0051a481a6dac88b64f98232ae42d4b6fd2fa81952dfe36a87")
421                .unwrap(),
422        );
423        assert_eq!(
424            serialize(&ip),
425            hex!("0520a2894dabaec08c0051a481a6dac88b64f98232ae42d4b6fd2fa81952dfe36a87")
426        );
427
428        let ip = AddrV2::Cjdns(Ipv6Addr::from_str("fc01:1:2:3:4:5:6:7").unwrap());
429        assert_eq!(serialize(&ip), hex!("0610fc010001000200030004000500060007"));
430
431        let ip = AddrV2::Unknown(170, hex!("01020304"));
432        assert_eq!(serialize(&ip), hex!("aa0401020304"));
433    }
434
435    #[test]
436    fn deserialize_addrv2_test() {
437        // Taken from https://github.com/bitcoin/bitcoin/blob/12a1c3ad1a43634d2a98717e49e3f02c4acea2fe/src/test/net_tests.cpp#L386
438
439        // Valid IPv4.
440        let ip: AddrV2 = deserialize(&hex!("010401020304")).unwrap();
441        assert_eq!(ip, AddrV2::Ipv4(Ipv4Addr::new(1, 2, 3, 4)));
442
443        // Invalid IPv4, valid length but address itself is shorter.
444        deserialize::<AddrV2>(&hex!("01040102")).unwrap_err();
445
446        // Invalid IPv4, with bogus length.
447        assert!(deserialize::<AddrV2>(&hex!("010501020304")).is_err());
448
449        // Invalid IPv4, with extreme length.
450        assert!(deserialize::<AddrV2>(&hex!("01fd010201020304")).is_err());
451
452        // Valid IPv6.
453        let ip: AddrV2 = deserialize(&hex!("02100102030405060708090a0b0c0d0e0f10")).unwrap();
454        assert_eq!(
455            ip,
456            AddrV2::Ipv6(Ipv6Addr::from_str("102:304:506:708:90a:b0c:d0e:f10").unwrap())
457        );
458
459        // Invalid IPv6, with bogus length.
460        assert!(deserialize::<AddrV2>(&hex!("020400")).is_err());
461
462        // Invalid IPv6, contains embedded IPv4.
463        assert!(deserialize::<AddrV2>(&hex!("021000000000000000000000ffff01020304")).is_err());
464
465        // Invalid IPv6, contains embedded TORv2.
466        assert!(deserialize::<AddrV2>(&hex!("0210fd87d87eeb430102030405060708090a")).is_err());
467
468        // Valid TORv2.
469        let ip: AddrV2 = deserialize(&hex!("030af1f2f3f4f5f6f7f8f9fa")).unwrap();
470        assert_eq!(ip, AddrV2::TorV2(FromHex::from_hex("f1f2f3f4f5f6f7f8f9fa").unwrap()));
471
472        // Invalid TORv2, with bogus length.
473        assert!(deserialize::<AddrV2>(&hex!("030700")).is_err());
474
475        // Valid TORv3.
476        let ip: AddrV2 = deserialize(&hex!(
477            "042079bcc625184b05194975c28b66b66b0469f7f6556fb1ac3189a79b40dda32f1f"
478        ))
479        .unwrap();
480        assert_eq!(
481            ip,
482            AddrV2::TorV3(
483                FromHex::from_hex(
484                    "79bcc625184b05194975c28b66b66b0469f7f6556fb1ac3189a79b40dda32f1f"
485                )
486                .unwrap()
487            )
488        );
489
490        // Invalid TORv3, with bogus length.
491        assert!(deserialize::<AddrV2>(&hex!("040000")).is_err());
492
493        // Valid I2P.
494        let ip: AddrV2 = deserialize(&hex!(
495            "0520a2894dabaec08c0051a481a6dac88b64f98232ae42d4b6fd2fa81952dfe36a87"
496        ))
497        .unwrap();
498        assert_eq!(
499            ip,
500            AddrV2::I2p(
501                FromHex::from_hex(
502                    "a2894dabaec08c0051a481a6dac88b64f98232ae42d4b6fd2fa81952dfe36a87"
503                )
504                .unwrap()
505            )
506        );
507
508        // Invalid I2P, with bogus length.
509        assert!(deserialize::<AddrV2>(&hex!("050300")).is_err());
510
511        // Valid CJDNS.
512        let ip: AddrV2 = deserialize(&hex!("0610fc000001000200030004000500060007")).unwrap();
513        assert_eq!(ip, AddrV2::Cjdns(Ipv6Addr::from_str("fc00:1:2:3:4:5:6:7").unwrap()));
514
515        // Invalid CJDNS, incorrect marker
516        assert!(deserialize::<AddrV2>(&hex!("0610fd000001000200030004000500060007")).is_err());
517
518        // Invalid CJDNS, with bogus length.
519        assert!(deserialize::<AddrV2>(&hex!("060100")).is_err());
520
521        // Unknown, with extreme length.
522        assert!(deserialize::<AddrV2>(&hex!("aafe0000000201020304050607")).is_err());
523
524        // Unknown, with reasonable length.
525        let ip: AddrV2 = deserialize(&hex!("aa0401020304")).unwrap();
526        assert_eq!(ip, AddrV2::Unknown(170, hex!("01020304")));
527
528        // Unknown, with zero length.
529        let ip: AddrV2 = deserialize(&hex!("aa00")).unwrap();
530        assert_eq!(ip, AddrV2::Unknown(170, vec![]));
531    }
532
533    #[test]
534    fn addrv2message_test() {
535        let raw = hex!("0261bc6649019902abab208d79627683fd4804010409090909208d");
536        let addresses: Vec<AddrV2Message> = deserialize(&raw).unwrap();
537
538        assert_eq!(
539            addresses,
540            vec![
541                AddrV2Message {
542                    services: ServiceFlags::NETWORK,
543                    time: 0x4966bc61,
544                    port: 8333,
545                    addr: AddrV2::Unknown(153, hex!("abab"))
546                },
547                AddrV2Message {
548                    services: ServiceFlags::NETWORK_LIMITED
549                        | ServiceFlags::WITNESS
550                        | ServiceFlags::COMPACT_FILTERS,
551                    time: 0x83766279,
552                    port: 8333,
553                    addr: AddrV2::Ipv4(Ipv4Addr::new(9, 9, 9, 9))
554                },
555            ]
556        );
557
558        assert_eq!(serialize(&addresses), raw);
559    }
560}