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(rhs);
80 boxes
81 }
82}
83
84impl PunchModel {
85 pub fn all() -> Self {
86 Self {
87 set: vec![PunchPolicySet::all()],
88 }
89 }
90 pub fn empty() -> Self {
91 Self { set: Vec::new() }
92 }
93 pub fn and(&mut self, punch_model_box: PunchPolicySet) {
94 self.set.push(punch_model_box)
95 }
96 pub fn is_match(&self, punch_model: PunchPolicy) -> bool {
97 if self.set.is_empty() {
98 return false;
99 }
100 for x in &self.set {
101 if !x.is_match(punch_model) {
102 return false;
103 }
104 }
105 true
106 }
107}
108
109#[derive(Clone, Debug, Serialize, Deserialize)]
110pub struct PunchConsultInfo {
111 pub peer_punch_model: PunchPolicySet,
112 pub peer_nat_info: NatInfo,
113}
114
115impl PunchConsultInfo {
116 pub fn new(peer_punch_model: PunchPolicySet, peer_nat_info: NatInfo) -> Self {
117 Self {
118 peer_punch_model,
119 peer_nat_info,
120 }
121 }
122}
123
124#[derive(Clone, Debug)]
125pub struct PunchInfo {
126 pub(crate) punch_model: PunchModel,
127 pub(crate) peer_nat_info: NatInfo,
128}
129
130impl PunchInfo {
131 pub fn new(punch_model: PunchModel, peer_nat_info: NatInfo) -> Self {
132 Self {
133 punch_model,
134 peer_nat_info,
135 }
136 }
137}
138
139impl FromStr for PunchPolicy {
140 type Err = String;
141
142 fn from_str(s: &str) -> Result<Self, Self::Err> {
143 match s.to_lowercase().trim() {
144 "ipv4-tcp" => Ok(PunchPolicy::IPv4Tcp),
145 "ipv4-udp" => Ok(PunchPolicy::IPv4Udp),
146 "ipv6-tcp" => Ok(PunchPolicy::IPv6Tcp),
147 "ipv6-udp" => Ok(PunchPolicy::IPv6Udp),
148 _ => Err(format!(
149 "not match '{}', enum: ipv4-tcp/ipv4-udp/ipv6-tcp/ipv6-udp",
150 s
151 )),
152 }
153 }
154}