1use crate::multihash::Multihash;
20use libp2p_identity::PeerId;
21use litep2p::types::multiaddr::Protocol as LiteP2pProtocol;
22use multiaddr::Protocol as LibP2pProtocol;
23use std::{
24 borrow::Cow,
25 fmt::{self, Debug, Display},
26 net::{IpAddr, Ipv4Addr, Ipv6Addr},
27};
28
29const LOG_TARGET: &str = "sub-libp2p";
31
32#[derive(PartialEq, Eq, Clone, Debug)]
34pub enum Protocol<'a> {
35 Dccp(u16),
36 Dns(Cow<'a, str>),
37 Dns4(Cow<'a, str>),
38 Dns6(Cow<'a, str>),
39 Dnsaddr(Cow<'a, str>),
40 Http,
41 Https,
42 Ip4(Ipv4Addr),
43 Ip6(Ipv6Addr),
44 P2pWebRtcDirect,
45 P2pWebRtcStar,
46 WebRTC,
47 Certhash(Multihash),
48 P2pWebSocketStar,
49 Memory(u64),
51 Onion(Cow<'a, [u8; 10]>, u16),
52 Onion3(Cow<'a, [u8; 35]>, u16),
53 P2p(Multihash),
54 P2pCircuit,
55 Quic,
56 QuicV1,
57 Sctp(u16),
58 Tcp(u16),
59 Tls,
60 Noise,
61 Udp(u16),
62 Udt,
63 Unix(Cow<'a, str>),
64 Utp,
65 Ws(Cow<'a, str>),
66 Wss(Cow<'a, str>),
67}
68
69impl<'a> Display for Protocol<'a> {
70 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
71 let protocol = LiteP2pProtocol::from(self.clone());
72 Display::fmt(&protocol, f)
73 }
74}
75
76impl<'a> From<IpAddr> for Protocol<'a> {
77 #[inline]
78 fn from(addr: IpAddr) -> Self {
79 match addr {
80 IpAddr::V4(addr) => Protocol::Ip4(addr),
81 IpAddr::V6(addr) => Protocol::Ip6(addr),
82 }
83 }
84}
85
86impl<'a> From<Ipv4Addr> for Protocol<'a> {
87 #[inline]
88 fn from(addr: Ipv4Addr) -> Self {
89 Protocol::Ip4(addr)
90 }
91}
92
93impl<'a> From<Ipv6Addr> for Protocol<'a> {
94 #[inline]
95 fn from(addr: Ipv6Addr) -> Self {
96 Protocol::Ip6(addr)
97 }
98}
99
100impl<'a> From<LiteP2pProtocol<'a>> for Protocol<'a> {
101 fn from(protocol: LiteP2pProtocol<'a>) -> Self {
102 match protocol {
103 LiteP2pProtocol::Dccp(port) => Protocol::Dccp(port),
104 LiteP2pProtocol::Dns(str) => Protocol::Dns(str),
105 LiteP2pProtocol::Dns4(str) => Protocol::Dns4(str),
106 LiteP2pProtocol::Dns6(str) => Protocol::Dns6(str),
107 LiteP2pProtocol::Dnsaddr(str) => Protocol::Dnsaddr(str),
108 LiteP2pProtocol::Http => Protocol::Http,
109 LiteP2pProtocol::Https => Protocol::Https,
110 LiteP2pProtocol::Ip4(ipv4_addr) => Protocol::Ip4(ipv4_addr),
111 LiteP2pProtocol::Ip6(ipv6_addr) => Protocol::Ip6(ipv6_addr),
112 LiteP2pProtocol::P2pWebRtcDirect => Protocol::P2pWebRtcDirect,
113 LiteP2pProtocol::P2pWebRtcStar => Protocol::P2pWebRtcStar,
114 LiteP2pProtocol::WebRTC => Protocol::WebRTC,
115 LiteP2pProtocol::Certhash(multihash) => Protocol::Certhash(multihash.into()),
116 LiteP2pProtocol::P2pWebSocketStar => Protocol::P2pWebSocketStar,
117 LiteP2pProtocol::Memory(port) => Protocol::Memory(port),
118 LiteP2pProtocol::Onion(str, port) => Protocol::Onion(str, port),
119 LiteP2pProtocol::Onion3(addr) =>
120 Protocol::Onion3(Cow::Owned(*addr.hash()), addr.port()),
121 LiteP2pProtocol::P2p(multihash) => Protocol::P2p(multihash.into()),
122 LiteP2pProtocol::P2pCircuit => Protocol::P2pCircuit,
123 LiteP2pProtocol::Quic => Protocol::Quic,
124 LiteP2pProtocol::QuicV1 => Protocol::QuicV1,
125 LiteP2pProtocol::Sctp(port) => Protocol::Sctp(port),
126 LiteP2pProtocol::Tcp(port) => Protocol::Tcp(port),
127 LiteP2pProtocol::Tls => Protocol::Tls,
128 LiteP2pProtocol::Noise => Protocol::Noise,
129 LiteP2pProtocol::Udp(port) => Protocol::Udp(port),
130 LiteP2pProtocol::Udt => Protocol::Udt,
131 LiteP2pProtocol::Unix(str) => Protocol::Unix(str),
132 LiteP2pProtocol::Utp => Protocol::Utp,
133 LiteP2pProtocol::Ws(str) => Protocol::Ws(str),
134 LiteP2pProtocol::Wss(str) => Protocol::Wss(str),
135 }
136 }
137}
138
139impl<'a> From<Protocol<'a>> for LiteP2pProtocol<'a> {
140 fn from(protocol: Protocol<'a>) -> Self {
141 match protocol {
142 Protocol::Dccp(port) => LiteP2pProtocol::Dccp(port),
143 Protocol::Dns(str) => LiteP2pProtocol::Dns(str),
144 Protocol::Dns4(str) => LiteP2pProtocol::Dns4(str),
145 Protocol::Dns6(str) => LiteP2pProtocol::Dns6(str),
146 Protocol::Dnsaddr(str) => LiteP2pProtocol::Dnsaddr(str),
147 Protocol::Http => LiteP2pProtocol::Http,
148 Protocol::Https => LiteP2pProtocol::Https,
149 Protocol::Ip4(ipv4_addr) => LiteP2pProtocol::Ip4(ipv4_addr),
150 Protocol::Ip6(ipv6_addr) => LiteP2pProtocol::Ip6(ipv6_addr),
151 Protocol::P2pWebRtcDirect => LiteP2pProtocol::P2pWebRtcDirect,
152 Protocol::P2pWebRtcStar => LiteP2pProtocol::P2pWebRtcStar,
153 Protocol::WebRTC => LiteP2pProtocol::WebRTC,
154 Protocol::Certhash(multihash) => LiteP2pProtocol::Certhash(multihash.into()),
155 Protocol::P2pWebSocketStar => LiteP2pProtocol::P2pWebSocketStar,
156 Protocol::Memory(port) => LiteP2pProtocol::Memory(port),
157 Protocol::Onion(str, port) => LiteP2pProtocol::Onion(str, port),
158 Protocol::Onion3(str, port) => LiteP2pProtocol::Onion3((str.into_owned(), port).into()),
159 Protocol::P2p(multihash) => LiteP2pProtocol::P2p(multihash.into()),
160 Protocol::P2pCircuit => LiteP2pProtocol::P2pCircuit,
161 Protocol::Quic => LiteP2pProtocol::Quic,
162 Protocol::QuicV1 => LiteP2pProtocol::QuicV1,
163 Protocol::Sctp(port) => LiteP2pProtocol::Sctp(port),
164 Protocol::Tcp(port) => LiteP2pProtocol::Tcp(port),
165 Protocol::Tls => LiteP2pProtocol::Tls,
166 Protocol::Noise => LiteP2pProtocol::Noise,
167 Protocol::Udp(port) => LiteP2pProtocol::Udp(port),
168 Protocol::Udt => LiteP2pProtocol::Udt,
169 Protocol::Unix(str) => LiteP2pProtocol::Unix(str),
170 Protocol::Utp => LiteP2pProtocol::Utp,
171 Protocol::Ws(str) => LiteP2pProtocol::Ws(str),
172 Protocol::Wss(str) => LiteP2pProtocol::Wss(str),
173 }
174 }
175}
176
177impl<'a> From<LibP2pProtocol<'a>> for Protocol<'a> {
178 fn from(protocol: LibP2pProtocol<'a>) -> Self {
179 match protocol {
180 LibP2pProtocol::Dccp(port) => Protocol::Dccp(port),
181 LibP2pProtocol::Dns(str) => Protocol::Dns(str),
182 LibP2pProtocol::Dns4(str) => Protocol::Dns4(str),
183 LibP2pProtocol::Dns6(str) => Protocol::Dns6(str),
184 LibP2pProtocol::Dnsaddr(str) => Protocol::Dnsaddr(str),
185 LibP2pProtocol::Http => Protocol::Http,
186 LibP2pProtocol::Https => Protocol::Https,
187 LibP2pProtocol::Ip4(ipv4_addr) => Protocol::Ip4(ipv4_addr),
188 LibP2pProtocol::Ip6(ipv6_addr) => Protocol::Ip6(ipv6_addr),
189 LibP2pProtocol::P2pWebRtcDirect => Protocol::P2pWebRtcDirect,
190 LibP2pProtocol::P2pWebRtcStar => Protocol::P2pWebRtcStar,
191 LibP2pProtocol::Certhash(multihash) => Protocol::Certhash(multihash.into()),
192 LibP2pProtocol::P2pWebSocketStar => Protocol::P2pWebSocketStar,
193 LibP2pProtocol::Memory(port) => Protocol::Memory(port),
194 LibP2pProtocol::Onion(str, port) => Protocol::Onion(str, port),
195 LibP2pProtocol::Onion3(addr) => Protocol::Onion3(Cow::Owned(*addr.hash()), addr.port()),
196 LibP2pProtocol::P2p(peer_id) => Protocol::P2p((*peer_id.as_ref()).into()),
197 LibP2pProtocol::P2pCircuit => Protocol::P2pCircuit,
198 LibP2pProtocol::Quic => Protocol::Quic,
199 LibP2pProtocol::QuicV1 => Protocol::QuicV1,
200 LibP2pProtocol::Sctp(port) => Protocol::Sctp(port),
201 LibP2pProtocol::Tcp(port) => Protocol::Tcp(port),
202 LibP2pProtocol::Tls => Protocol::Tls,
203 LibP2pProtocol::Noise => Protocol::Noise,
204 LibP2pProtocol::Udp(port) => Protocol::Udp(port),
205 LibP2pProtocol::Udt => Protocol::Udt,
206 LibP2pProtocol::Unix(str) => Protocol::Unix(str),
207 LibP2pProtocol::Utp => Protocol::Utp,
208 LibP2pProtocol::Ws(str) => Protocol::Ws(str),
209 LibP2pProtocol::Wss(str) => Protocol::Wss(str),
210 protocol => {
211 log::error!(
212 target: LOG_TARGET,
213 "Got unsupported multiaddr protocol '{}'",
214 protocol.tag(),
215 );
216 Protocol::Dccp(0)
221 },
222 }
223 }
224}
225
226impl<'a> From<Protocol<'a>> for LibP2pProtocol<'a> {
227 fn from(protocol: Protocol<'a>) -> Self {
228 match protocol {
229 Protocol::Dccp(port) => LibP2pProtocol::Dccp(port),
230 Protocol::Dns(str) => LibP2pProtocol::Dns(str),
231 Protocol::Dns4(str) => LibP2pProtocol::Dns4(str),
232 Protocol::Dns6(str) => LibP2pProtocol::Dns6(str),
233 Protocol::Dnsaddr(str) => LibP2pProtocol::Dnsaddr(str),
234 Protocol::Http => LibP2pProtocol::Http,
235 Protocol::Https => LibP2pProtocol::Https,
236 Protocol::Ip4(ipv4_addr) => LibP2pProtocol::Ip4(ipv4_addr),
237 Protocol::Ip6(ipv6_addr) => LibP2pProtocol::Ip6(ipv6_addr),
238 Protocol::P2pWebRtcDirect => LibP2pProtocol::P2pWebRtcDirect,
239 Protocol::P2pWebRtcStar => LibP2pProtocol::P2pWebRtcStar,
240 Protocol::WebRTC => LibP2pProtocol::WebRTCDirect,
243 Protocol::Certhash(multihash) => LibP2pProtocol::Certhash(multihash.into()),
244 Protocol::P2pWebSocketStar => LibP2pProtocol::P2pWebSocketStar,
245 Protocol::Memory(port) => LibP2pProtocol::Memory(port),
246 Protocol::Onion(str, port) => LibP2pProtocol::Onion(str, port),
247 Protocol::Onion3(str, port) => LibP2pProtocol::Onion3((str.into_owned(), port).into()),
248 Protocol::P2p(multihash) =>
249 LibP2pProtocol::P2p(PeerId::from_multihash(multihash.into()).unwrap_or_else(|_| {
250 log::error!(
253 target: LOG_TARGET,
254 "Received multiaddr with p2p multihash which is not a valid \
255 peer_id. Replacing with random peer_id."
256 );
257 PeerId::random()
258 })),
259 Protocol::P2pCircuit => LibP2pProtocol::P2pCircuit,
260 Protocol::Quic => LibP2pProtocol::Quic,
261 Protocol::QuicV1 => LibP2pProtocol::QuicV1,
262 Protocol::Sctp(port) => LibP2pProtocol::Sctp(port),
263 Protocol::Tcp(port) => LibP2pProtocol::Tcp(port),
264 Protocol::Tls => LibP2pProtocol::Tls,
265 Protocol::Noise => LibP2pProtocol::Noise,
266 Protocol::Udp(port) => LibP2pProtocol::Udp(port),
267 Protocol::Udt => LibP2pProtocol::Udt,
268 Protocol::Unix(str) => LibP2pProtocol::Unix(str),
269 Protocol::Utp => LibP2pProtocol::Utp,
270 Protocol::Ws(str) => LibP2pProtocol::Ws(str),
271 Protocol::Wss(str) => LibP2pProtocol::Wss(str),
272 }
273 }
274}