1use std::net::SocketAddr;
2
3use indexmap::IndexSet;
4use memberlist_core::proto::CIDRsPolicy;
5use nodecraft::resolver::AddressResolver;
6
7use crate::StreamLayer;
8
9#[viewit::viewit(
11 vis_all = "pub(crate)",
12 getters(vis_all = "pub"),
13 setters(vis_all = "pub", prefix = "with")
14)]
15#[derive(Debug)]
16#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
17#[cfg_attr(
18 feature = "serde",
19 serde(bound(
20 serialize = "I: serde::Serialize, A: AddressResolver, A::Address: serde::Serialize, A::ResolvedAddress: serde::Serialize, A::Options: serde::Serialize, S::Options: serde::Serialize",
21 deserialize = "I: serde::Deserialize<'de>, A: AddressResolver, A::Address: serde::Deserialize<'de>, A::ResolvedAddress: serde::Deserialize<'de>, A::Options: serde::Deserialize<'de>, S::Options: serde::Deserialize<'de>"
22 ))
23)]
24pub struct NetTransportOptions<I, A: AddressResolver<ResolvedAddress = SocketAddr>, S: StreamLayer>
25{
26 #[viewit(
28 getter(const, style = "ref", attrs(doc = "Get the id of the node."),),
29 setter(attrs(doc = "Set the id of the node. (Builder pattern)"),)
30 )]
31 id: I,
32
33 #[viewit(
36 getter(
37 style = "ref",
38 const,
39 attrs(doc = "Get a set of addresses to bind to for both TCP and UDP communications."),
40 ),
41 setter(attrs(
42 doc = "Set the set of addresses to bind to for both TCP and UDP communications. (Builder pattern)"
43 ),)
44 )]
45 bind_addresses: IndexSet<A::Address>,
46
47 #[viewit(
51 getter(
52 const,
53 style = "ref",
54 result(converter(fn = "Option::as_ref"), type = "Option<&A::ResolvedAddress>"),
55 attrs(doc = "Get the address to advertise to other nodes."),
56 ),
57 setter(
58 rename = "maybe_advertise_address",
59 attrs(
60 doc = "Set the address to advertise to other nodes. This address is not bound or listened on. (Builder pattern)"
61 ),
62 )
63 )]
64 #[cfg_attr(
65 feature = "serde",
66 serde(default, skip_serializing_if = "Option::is_none")
67 )]
68 advertise_address: Option<A::ResolvedAddress>,
69
70 #[viewit(
72 getter(const, style = "ref", attrs(doc = "Get the address resolver options."),),
73 setter(attrs(doc = "Set the address resolver options. (Builder pattern)"),)
74 )]
75 resolver: A::Options,
76
77 #[viewit(
79 getter(const, style = "ref", attrs(doc = "Get the stream layer options."),),
80 setter(attrs(doc = "Set the stream layer options. (Builder pattern)"),)
81 )]
82 stream_layer: S::Options,
83
84 #[cfg_attr(feature = "serde", serde(default))]
88 #[viewit(
89 getter(
90 const,
91 style = "ref",
92 attrs(doc = "Get the policy for Classless Inter-Domain Routing (CIDR)."),
93 ),
94 setter(attrs(
95 doc = "Set the policy for Classless Inter-Domain Routing (CIDR). (Builder pattern)"
96 ),)
97 )]
98 cidrs_policy: CIDRsPolicy,
99
100 #[viewit(
102 getter(
103 const,
104 attrs(doc = "Get the maximum payload size can be sent by UDP. Default is `1472` bytes."),
105 ),
106 setter(attrs(
107 doc = "Set the maximum payload size can be sent by UDP. Default is `1472` bytes. (Builder pattern)"
108 ),)
109 )]
110 max_packet_size: usize,
111
112 #[viewit(
114 getter(const, attrs(doc = "Get the UDP receive window. Default is `2MB`."),),
115 setter(attrs(doc = "Set the UDP receive window. Default is `2MB`. (Builder pattern)"),)
116 )]
117 recv_buffer_size: usize,
118
119 #[cfg(feature = "metrics")]
121 #[cfg_attr(docsrs, doc(cfg(feature = "metrics")))]
122 #[viewit(
123 getter(
124 style = "ref",
125 result(
126 converter(fn = "Option::as_deref"),
127 type = "Option<&memberlist_core::proto::MetricLabels>"
128 ),
129 attrs(
130 doc = "Get the metrics labels.",
131 cfg(feature = "metrics"),
132 cfg_attr(docsrs, doc(cfg(feature = "metrics")))
133 ),
134 ),
135 setter(attrs(
136 doc = "Set the metrics labels. (Builder pattern)",
137 cfg(feature = "metrics"),
138 cfg_attr(docsrs, doc(cfg(feature = "metrics")))
139 ))
140 )]
141 #[cfg_attr(
142 feature = "serde",
143 serde(default, skip_serializing_if = "Option::is_none")
144 )]
145 metric_labels: Option<std::sync::Arc<memberlist_core::proto::MetricLabels>>,
146}
147
148impl<I, A: AddressResolver<ResolvedAddress = SocketAddr>, S: StreamLayer> Clone
149 for NetTransportOptions<I, A, S>
150where
151 I: Clone,
152 A::Options: Clone,
153 A::ResolvedAddress: Clone,
154 S::Options: Clone,
155{
156 fn clone(&self) -> Self {
157 Self {
158 id: self.id.clone(),
159 bind_addresses: self.bind_addresses.clone(),
160 advertise_address: self.advertise_address,
161 stream_layer: self.stream_layer.clone(),
162 resolver: self.resolver.clone(),
163 cidrs_policy: self.cidrs_policy.clone(),
164 max_packet_size: self.max_packet_size,
165 recv_buffer_size: self.recv_buffer_size,
166 #[cfg(feature = "metrics")]
167 metric_labels: self.metric_labels.clone(),
168 }
169 }
170}
171
172impl<I, A: AddressResolver<ResolvedAddress = SocketAddr>, S: StreamLayer>
173 NetTransportOptions<I, A, S>
174where
175 A::Options: Default,
176 S::Options: Default,
177{
178 #[inline]
180 pub fn new(id: I) -> Self {
181 Self::with_resolver_options_and_stream_layer_options(id, Default::default(), Default::default())
182 }
183}
184
185impl<I, A: AddressResolver<ResolvedAddress = SocketAddr>, S: StreamLayer>
186 NetTransportOptions<I, A, S>
187where
188 S::Options: Default,
189{
190 #[inline]
192 pub fn with_resolver_options(id: I, resolver_options: A::Options) -> Self {
193 Self::with_resolver_options_and_stream_layer_options(id, resolver_options, Default::default())
194 }
195}
196
197impl<I, A: AddressResolver<ResolvedAddress = SocketAddr>, S: StreamLayer>
198 NetTransportOptions<I, A, S>
199where
200 A::Options: Default,
201{
202 #[inline]
204 pub fn with_stream_layer_options(id: I, stream_layer_options: S::Options) -> Self {
205 Self::with_resolver_options_and_stream_layer_options(
206 id,
207 Default::default(),
208 stream_layer_options,
209 )
210 }
211}
212
213impl<I, A: AddressResolver<ResolvedAddress = SocketAddr>, S: StreamLayer>
214 NetTransportOptions<I, A, S>
215{
216 pub fn with_resolver_options_and_stream_layer_options(
218 id: I,
219 resolver_options: A::Options,
220 stream_layer_opts: S::Options,
221 ) -> Self {
222 Self {
223 id,
224 bind_addresses: IndexSet::new(),
225 advertise_address: None,
226 resolver: resolver_options,
227 stream_layer: stream_layer_opts,
228 cidrs_policy: CIDRsPolicy::allow_all(),
229 max_packet_size: 1472,
230 recv_buffer_size: super::DEFAULT_UDP_RECV_BUF_SIZE,
231 #[cfg(feature = "metrics")]
232 metric_labels: None,
233 }
234 }
235
236 pub fn add_bind_address(&mut self, addr: A::Address) -> &mut Self {
238 self.bind_addresses.insert(addr);
239 self
240 }
241
242 pub fn with_advertise_address(mut self, addr: A::ResolvedAddress) -> Self {
245 self.advertise_address = Some(addr);
246 self
247 }
248}
249
250impl<I, A: AddressResolver<ResolvedAddress = SocketAddr>, S: StreamLayer>
251 From<NetTransportOptions<I, A, S>> for (A::Options, S::Options, Options<I, A>)
252{
253 fn from(opts: NetTransportOptions<I, A, S>) -> (A::Options, S::Options, Options<I, A>) {
254 (
255 opts.resolver,
256 opts.stream_layer,
257 Options {
258 id: opts.id,
259 bind_addresses: opts.bind_addresses,
260 advertise_address: opts.advertise_address,
261 cidrs_policy: opts.cidrs_policy,
262 max_packet_size: opts.max_packet_size,
263 recv_buffer_size: opts.recv_buffer_size,
264 #[cfg(feature = "metrics")]
265 metric_labels: opts.metric_labels,
266 },
267 )
268 }
269}
270
271#[viewit::viewit(getters(skip), setters(skip))]
272pub(crate) struct Options<I, A: AddressResolver<ResolvedAddress = SocketAddr>> {
273 id: I,
274 bind_addresses: IndexSet<A::Address>,
275 advertise_address: Option<A::ResolvedAddress>,
276 cidrs_policy: CIDRsPolicy,
277 max_packet_size: usize,
278 recv_buffer_size: usize,
279 #[cfg(feature = "metrics")]
280 metric_labels: Option<std::sync::Arc<memberlist_core::proto::MetricLabels>>,
281}