sapio_bitcoin/network/
address.rs

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