+ queued: bool,
+}
+impl Node {
+ #[inline]
+ fn last_services(&self) -> u64 {
+ ((self.last_services.0 as u64) << 32) |
+ ((self.last_services.1 as u64) )
+ }
+ #[inline]
+ fn services(inp: u64) -> (u32, u32) {
+ (
+ ((inp & 0xffffffff00000000) >> 32) as u32,
+ ((inp & 0x00000000ffffffff) ) as u32
+ )
+ }
+}
+
+#[test]
+fn services_test() {
+ assert_eq!(
+ Node { last_good: 0, state: AddressState::Good, queued: false, last_services: Node::services(0x1badcafedeadbeef) }
+ .last_services(),
+ 0x1badcafedeadbeef);
+}
+
+/// Essentially SocketAddr but without a traffic class or scope
+#[derive(Clone, PartialEq, Eq, Hash)]
+enum SockAddr {
+ V4(SocketAddrV4),
+ V6(([u16; 8], u16)),
+}
+#[inline]
+fn segs_to_ip6(segs: &[u16; 8]) -> Ipv6Addr {
+ Ipv6Addr::new(segs[0], segs[1], segs[2], segs[3], segs[4], segs[5], segs[6], segs[7])
+}
+impl From<SocketAddr> for SockAddr {
+ fn from(addr: SocketAddr) -> SockAddr {
+ match addr {
+ SocketAddr::V4(sa) => SockAddr::V4(sa),
+ SocketAddr::V6(sa) => SockAddr::V6((sa.ip().segments(), sa.port())),
+ }
+ }
+}
+impl Into<SocketAddr> for &SockAddr {
+ fn into(self) -> SocketAddr {
+ match self {
+ &SockAddr::V4(sa) => SocketAddr::V4(sa),
+ &SockAddr::V6(sa) => SocketAddr::V6(SocketAddrV6::new(segs_to_ip6(&sa.0), sa.1, 0, 0))
+ }
+ }
+}
+impl ToString for SockAddr {
+ fn to_string(&self) -> String {
+ let sa: SocketAddr = self.into();
+ sa.to_string()
+ }
+}
+impl SockAddr {
+ pub fn port(&self) -> u16 {
+ match *self {
+ SockAddr::V4(sa) => sa.port(),
+ SockAddr::V6((_, port)) => port,
+ }
+ }
+ pub fn ip(&self) -> IpAddr {
+ match *self {
+ SockAddr::V4(sa) => IpAddr::V4(sa.ip().clone()),
+ SockAddr::V6((ip, _)) => IpAddr::V6(segs_to_ip6(&ip)),
+ }
+ }