cuprate_wire/
network_address.rs

1// Rust Levin Library
2// Written in 2023 by
3//   Cuprate Contributors
4//
5// Permission is hereby granted, free of charge, to any person obtaining a copy
6// of this software and associated documentation files (the "Software"), to deal
7// in the Software without restriction, including without limitation the rights
8// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9// copies of the Software, and to permit persons to whom the Software is
10// furnished to do so, subject to the following conditions:
11//
12// The above copyright notice and this permission notice shall be included in all
13// copies or substantial portions of the Software.
14//
15
16//! This module defines the addresses that will get passed around the
17//! Monero network. Core Monero has 4 main addresses: IPv4, IPv6, Tor,
18//! I2p. Currently this module only has IPv(4/6).
19//!
20use std::{hash::Hash, net, net::SocketAddr};
21
22use bytes::BufMut;
23
24use cuprate_epee_encoding::EpeeObject;
25
26mod epee_builder;
27use epee_builder::*;
28
29mod onion_addr;
30pub use onion_addr::*;
31
32#[derive(Debug, PartialEq, Eq, Clone, Copy)]
33pub enum NetZone {
34    Public,
35    Tor,
36    I2p,
37}
38
39/// A network address which can be encoded into the format required
40/// to send to other Monero peers.
41#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
42pub enum NetworkAddress {
43    Clear(SocketAddr),
44    Tor(OnionAddr),
45}
46
47impl EpeeObject for NetworkAddress {
48    type Builder = TaggedNetworkAddress;
49
50    fn number_of_fields(&self) -> u64 {
51        2
52    }
53
54    fn write_fields<B: BufMut>(self, w: &mut B) -> cuprate_epee_encoding::Result<()> {
55        TaggedNetworkAddress::from(self).write_fields(w)
56    }
57}
58
59impl NetworkAddress {
60    pub const fn get_zone(&self) -> NetZone {
61        match self {
62            Self::Clear(_) => NetZone::Public,
63            Self::Tor(_) => NetZone::Tor,
64        }
65    }
66
67    pub const fn is_loopback(&self) -> bool {
68        // TODO
69        false
70    }
71
72    pub const fn is_local(&self) -> bool {
73        // TODO
74        false
75    }
76
77    pub const fn port(&self) -> u16 {
78        match self {
79            Self::Clear(ip) => ip.port(),
80            Self::Tor(addr) => addr.port(),
81        }
82    }
83}
84
85impl From<net::SocketAddrV4> for NetworkAddress {
86    fn from(value: net::SocketAddrV4) -> Self {
87        Self::Clear(value.into())
88    }
89}
90
91impl From<net::SocketAddrV6> for NetworkAddress {
92    fn from(value: net::SocketAddrV6) -> Self {
93        Self::Clear(value.into())
94    }
95}
96
97impl From<SocketAddr> for NetworkAddress {
98    fn from(value: SocketAddr) -> Self {
99        match value {
100            SocketAddr::V4(v4) => v4.into(),
101            SocketAddr::V6(v6) => v6.into(),
102        }
103    }
104}
105
106#[derive(Debug, Copy, Clone, Eq, PartialEq, thiserror::Error)]
107#[error("Network address is not in the correct zone")]
108pub struct NetworkAddressIncorrectZone;
109
110impl TryFrom<NetworkAddress> for SocketAddr {
111    type Error = NetworkAddressIncorrectZone;
112    fn try_from(value: NetworkAddress) -> Result<Self, Self::Error> {
113        match value {
114            NetworkAddress::Clear(addr) => Ok(addr),
115            NetworkAddress::Tor(_) => Err(NetworkAddressIncorrectZone),
116        }
117    }
118}