1//! Declare the TargetPort type.
23use serde::{Deserialize, Serialize};
4use std::fmt;
56/// A port that we want to connect to as a client.
7///
8/// Ordinarily, this is a TCP port, plus a flag to indicate whether we
9/// must support IPv4 or IPv6.
10#[derive(
11 Clone, Copy, Debug, Deserialize, Eq, PartialEq, Hash, PartialOrd, Ord, Serialize, Default,
12)]
13#[non_exhaustive]
14pub struct TargetPort {
15/// True if this is a request to connect to an IPv6 address
16pub ipv6: bool,
17/// The port that the client wants to connect to
18pub port: u16,
19}
2021impl TargetPort {
22/// Create a request to make sure that a circuit supports a given
23 /// ipv4 exit port.
24pub fn ipv4(port: u16) -> TargetPort {
25 TargetPort { ipv6: false, port }
26 }
2728/// Create a request to make sure that a circuit supports a given
29 /// ipv6 exit port.
30pub fn ipv6(port: u16) -> TargetPort {
31 TargetPort { ipv6: true, port }
32 }
3334/// Return true if this port is supported by the provided Relay.
35pub fn is_supported_by(&self, r: &tor_netdir::details::RelayDetails<'_>) -> bool {
36if self.ipv6 {
37 r.supports_exit_port_ipv6(self.port)
38 } else {
39 r.supports_exit_port_ipv4(self.port)
40 }
41 }
42}
4344impl fmt::Display for TargetPort {
45fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
46write!(f, "{}{}", self.port, if self.ipv6 { "v6" } else { "v4" })
47 }
48}