cs_mwc_bch/messages/
node_addr.rs1use byteorder::{BigEndian, LittleEndian, ReadBytesExt, WriteBytesExt};
2use std::io;
3use std::io::{Read, Write};
4use std::net::{IpAddr, Ipv6Addr};
5use util::{Result, Serializable};
6
7#[derive(Debug, PartialEq, Eq, Hash, Clone)]
9pub struct NodeAddr {
10 pub services: u64,
12 pub ip: Ipv6Addr,
14 pub port: u16,
16}
17
18impl NodeAddr {
19 pub const SIZE: usize = 26;
21
22 pub fn new(ip: IpAddr, port: u16) -> NodeAddr {
24 NodeAddr {
25 services: 0,
26 ip: match ip {
27 IpAddr::V4(ipv4) => ipv4.to_ipv6_mapped(),
28 IpAddr::V6(ipv6) => ipv6,
29 },
30 port,
31 }
32 }
33
34 pub fn size(&self) -> usize {
36 NodeAddr::SIZE
37 }
38}
39
40impl Serializable<NodeAddr> for NodeAddr {
41 fn read(reader: &mut dyn Read) -> Result<NodeAddr> {
42 let services = reader.read_u64::<LittleEndian>()?;
43 let mut ip = [0; 16];
44 reader.read(&mut ip)?;
45 let ip = Ipv6Addr::from(ip);
46 let port = reader.read_u16::<BigEndian>()?;
47 Ok(NodeAddr { services, ip, port })
48 }
49
50 fn write(&self, writer: &mut dyn Write) -> io::Result<()> {
51 writer.write_u64::<LittleEndian>(self.services)?;
52 writer.write(&self.ip.octets())?;
53 writer.write_u16::<BigEndian>(self.port)?;
54 Ok(())
55 }
56}
57
58impl Default for NodeAddr {
59 fn default() -> NodeAddr {
60 NodeAddr {
61 services: 0,
62 ip: Ipv6Addr::from([0; 16]),
63 port: 0,
64 }
65 }
66}
67
68#[cfg(test)]
69mod tests {
70 use super::*;
71 use hex;
72 use std::io::Cursor;
73
74 #[test]
75 fn read_bytes() {
76 let b =
77 hex::decode("250000000000000000000000000000000000ffff2d32bffbddd3".as_bytes()).unwrap();
78 let a = NodeAddr::read(&mut Cursor::new(&b)).unwrap();
79 assert!(a.services == 37);
80 assert!(a.ip.octets() == [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 45, 50, 191, 251]);
81 assert!(a.port == 56787);
82 }
83
84 #[test]
85 fn write_read() {
86 let mut v = Vec::new();
87 let a = NodeAddr {
88 services: 1,
89 ip: Ipv6Addr::from([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]),
90 port: 123,
91 };
92 a.write(&mut v).unwrap();
93 assert!(v.len() == a.size());
94 assert!(NodeAddr::read(&mut Cursor::new(&v)).unwrap() == a);
95 }
96}