rust_p2p_core/punch/
config.rs1use crate::nat::NatInfo;
2use serde::{Deserialize, Serialize};
3use std::collections::HashSet;
4use std::ops;
5use std::str::FromStr;
6
7#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, Serialize, Deserialize)]
8pub enum PunchPolicy {
9 IPv4Tcp,
10 IPv4Udp,
11 IPv6Tcp,
12 IPv6Udp,
13}
14
15impl ops::BitOr<PunchPolicy> for PunchPolicy {
16 type Output = PunchPolicySet;
17
18 fn bitor(self, rhs: PunchPolicy) -> Self::Output {
19 let mut model = PunchPolicySet::empty();
20 model.or(self);
21 model.or(rhs);
22 model
23 }
24}
25#[derive(Clone, Debug, Serialize, Deserialize)]
27pub struct PunchPolicySet {
28 models: HashSet<PunchPolicy>,
29}
30
31impl Default for PunchPolicySet {
32 fn default() -> Self {
33 PunchPolicySet::all()
34 }
35}
36
37impl ops::BitOr<PunchPolicy> for PunchPolicySet {
38 type Output = PunchPolicySet;
39
40 fn bitor(mut self, rhs: PunchPolicy) -> Self::Output {
41 self.or(rhs);
42 self
43 }
44}
45
46impl PunchPolicySet {
47 pub fn all() -> Self {
48 PunchPolicy::IPv4Tcp | PunchPolicy::IPv4Udp | PunchPolicy::IPv6Tcp | PunchPolicy::IPv6Udp
49 }
50 pub fn ipv4() -> Self {
51 PunchPolicy::IPv4Tcp | PunchPolicy::IPv4Udp
52 }
53 pub fn ipv6() -> Self {
54 PunchPolicy::IPv6Tcp | PunchPolicy::IPv6Udp
55 }
56 pub fn empty() -> Self {
57 Self {
58 models: Default::default(),
59 }
60 }
61 pub fn or(&mut self, punch_model: PunchPolicy) {
62 self.models.insert(punch_model);
63 }
64 pub fn is_match(&self, punch_model: PunchPolicy) -> bool {
65 self.models.contains(&punch_model)
66 }
67}
68
69#[derive(Clone, Debug)]
70pub struct PunchModel {
71 set: Vec<PunchPolicySet>,
72}
73
74impl ops::BitAnd<PunchPolicySet> for PunchPolicySet {
75 type Output = PunchModel;
76
77 fn bitand(self, rhs: PunchPolicySet) -> Self::Output {
78 let mut boxes = PunchModel::empty();
79 boxes.and(self);
80 boxes.and(rhs);
81 boxes
82 }
83}
84
85impl PunchModel {
86 pub fn all() -> Self {
87 Self {
88 set: vec![PunchPolicySet::all()],
89 }
90 }
91 pub fn empty() -> Self {
92 Self { set: Vec::new() }
93 }
94 pub fn and(&mut self, punch_model_box: PunchPolicySet) {
95 self.set.push(punch_model_box)
96 }
97 pub fn is_match(&self, punch_model: PunchPolicy) -> bool {
98 if self.set.is_empty() {
99 return false;
100 }
101 for x in &self.set {
102 if !x.is_match(punch_model) {
103 return false;
104 }
105 }
106 true
107 }
108}
109
110#[derive(Clone, Debug, Serialize, Deserialize)]
111pub struct PunchConsultInfo {
112 pub peer_punch_model: PunchPolicySet,
113 pub peer_nat_info: NatInfo,
114}
115
116impl PunchConsultInfo {
117 pub fn new(peer_punch_model: PunchPolicySet, peer_nat_info: NatInfo) -> Self {
118 Self {
119 peer_punch_model,
120 peer_nat_info,
121 }
122 }
123}
124
125#[derive(Clone, Debug)]
126pub struct PunchInfo {
127 pub(crate) punch_model: PunchModel,
128 pub(crate) peer_nat_info: NatInfo,
129}
130
131impl PunchInfo {
132 pub fn new(punch_model: PunchModel, peer_nat_info: NatInfo) -> Self {
133 Self {
134 punch_model,
135 peer_nat_info,
136 }
137 }
138}
139
140impl FromStr for PunchPolicy {
141 type Err = String;
142
143 fn from_str(s: &str) -> Result<Self, Self::Err> {
144 match s.to_lowercase().trim() {
145 "ipv4-tcp" => Ok(PunchPolicy::IPv4Tcp),
146 "ipv4-udp" => Ok(PunchPolicy::IPv4Udp),
147 "ipv6-tcp" => Ok(PunchPolicy::IPv6Tcp),
148 "ipv6-udp" => Ok(PunchPolicy::IPv6Udp),
149 _ => Err(format!(
150 "not match '{s}', enum: ipv4-tcp/ipv4-udp/ipv6-tcp/ipv6-udp"
151 )),
152 }
153 }
154}