forked from LNP-WG/lnp-node
-
Notifications
You must be signed in to change notification settings - Fork 0
/
listen_addr.rs
84 lines (76 loc) · 3.17 KB
/
listen_addr.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
// LNP Node: node running lightning network protocol and generalized lightning
// channels.
// Written in 2020-2022 by
// Dr. Maxim Orlovsky <orlovsky@lnp-bp.org>
//
// To the extent possible under law, the author(s) have dedicated all
// copyright and related and neighboring rights to this software to
// the public domain worldwide. This software is distributed without
// any warranty.
//
// You should have received a copy of the MIT License along with this software.
// If not, see <https://opensource.org/licenses/MIT>.
use std::fmt::{self, Display, Formatter};
use std::net::{IpAddr, SocketAddr};
use std::str::FromStr;
use internet2::addr::{AddrParseError, PartialSocketAddr};
use lnp::p2p;
use lnp::p2p::bifrost::LNP2P_BIFROST_PORT;
use lnp::p2p::bolt::LNP2P_BOLT_PORT;
#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug)]
#[derive(NetworkEncode, NetworkDecode)]
pub struct ListenAddr {
pub protocol: p2p::Protocol,
pub socket_addr: SocketAddr,
}
impl ListenAddr {
/// Construct BOLT-compatible listening address.
pub fn bolt(ip_addr: IpAddr, port: Option<u16>) -> ListenAddr {
ListenAddr {
protocol: p2p::Protocol::Bolt,
socket_addr: SocketAddr::new(ip_addr, port.unwrap_or(LNP2P_BOLT_PORT)),
}
}
/// Construct Bifrost-compatible listening address.
pub fn bifrost(ip_addr: IpAddr, port: Option<u16>) -> ListenAddr {
ListenAddr {
protocol: p2p::Protocol::Bifrost,
socket_addr: SocketAddr::new(ip_addr, port.unwrap_or(LNP2P_BIFROST_PORT)),
}
}
}
impl Display for ListenAddr {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(f, "{}://{}", self.protocol, self.socket_addr.ip())?;
if self.protocol.default_port() != self.socket_addr.port() {
write!(f, ":{}", self.socket_addr.port())?;
}
Ok(())
}
}
impl FromStr for ListenAddr {
type Err = AddrParseError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let mut split = s.split("://");
match (split.next().map(str::to_lowercase).as_deref(), split.next(), split.next()) {
(Some("bolt"), Some(addr), None) => {
let socket_addr = PartialSocketAddr::from_str(addr)?;
let socket_addr: SocketAddr = socket_addr
.inet_socket(LNP2P_BOLT_PORT)
.try_into()
// TODO: Remove mapping
.map_err(|_| AddrParseError::NeedsTorFeature)?;
Ok(ListenAddr { protocol: p2p::Protocol::Bolt, socket_addr })
}
(Some("bifrost"), Some(addr), None) => {
let socket_addr = PartialSocketAddr::from_str(addr)?;
let socket_addr: SocketAddr = socket_addr.inet_socket(LNP2P_BIFROST_PORT).try_into()
// TODO: Remove mapping
.map_err(|_| AddrParseError::NeedsTorFeature)?;
Ok(ListenAddr { protocol: p2p::Protocol::Bifrost, socket_addr })
}
(Some(unknown), ..) => Err(AddrParseError::UnknownProtocolError(unknown.to_owned())),
_ => Err(AddrParseError::WrongAddrFormat(s.to_owned())),
}
}
}