cuprate_wire/
network_address.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
// Rust Levin Library
// Written in 2023 by
//   Cuprate Contributors
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//

//! This module defines the addresses that will get passed around the
//! Monero network. Core Monero has 4 main addresses: IPv4, IPv6, Tor,
//! I2p. Currently this module only has IPv(4/6).
//!
use std::{hash::Hash, net, net::SocketAddr};

use bytes::BufMut;

use cuprate_epee_encoding::EpeeObject;

mod epee_builder;
use epee_builder::*;

#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum NetZone {
    Public,
    Tor,
    I2p,
}

/// A network address which can be encoded into the format required
/// to send to other Monero peers.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum NetworkAddress {
    Clear(SocketAddr),
}

impl EpeeObject for NetworkAddress {
    type Builder = TaggedNetworkAddress;

    fn number_of_fields(&self) -> u64 {
        2
    }

    fn write_fields<B: BufMut>(self, w: &mut B) -> cuprate_epee_encoding::Result<()> {
        TaggedNetworkAddress::from(self).write_fields(w)
    }
}

impl NetworkAddress {
    pub const fn get_zone(&self) -> NetZone {
        match self {
            Self::Clear(_) => NetZone::Public,
        }
    }

    pub const fn is_loopback(&self) -> bool {
        // TODO
        false
    }

    pub const fn is_local(&self) -> bool {
        // TODO
        false
    }

    pub const fn port(&self) -> u16 {
        match self {
            Self::Clear(ip) => ip.port(),
        }
    }
}

impl From<net::SocketAddrV4> for NetworkAddress {
    fn from(value: net::SocketAddrV4) -> Self {
        Self::Clear(value.into())
    }
}

impl From<net::SocketAddrV6> for NetworkAddress {
    fn from(value: net::SocketAddrV6) -> Self {
        Self::Clear(value.into())
    }
}

impl From<SocketAddr> for NetworkAddress {
    fn from(value: SocketAddr) -> Self {
        match value {
            SocketAddr::V4(v4) => v4.into(),
            SocketAddr::V6(v6) => v6.into(),
        }
    }
}

#[derive(Debug, Copy, Clone, Eq, PartialEq, thiserror::Error)]
#[error("Network address is not in the correct zone")]
pub struct NetworkAddressIncorrectZone;

impl TryFrom<NetworkAddress> for SocketAddr {
    type Error = NetworkAddressIncorrectZone;
    fn try_from(value: NetworkAddress) -> Result<Self, Self::Error> {
        match value {
            NetworkAddress::Clear(addr) => Ok(addr),
            //_ => Err(NetworkAddressIncorrectZone)
        }
    }
}