memberlist_net/
options.rs

1use std::net::SocketAddr;
2
3use indexmap::IndexSet;
4use memberlist_core::proto::CIDRsPolicy;
5use nodecraft::resolver::AddressResolver;
6
7use crate::StreamLayer;
8
9/// Used to configure a net transport.
10#[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  /// The local node's ID.
27  #[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  /// A set of addresses to bind to for both TCP and UDP
34  /// communications.
35  #[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  /// The address to advertise to other nodes. This address is not bound or listened on,
48  /// only advertised. If not set, the transport will auto-detect an appropriate address
49  /// from the bind addresses.
50  #[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  /// Resolver options, which used to construct the address resolver for this transport.
71  #[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  /// Stream layer options, which used to construct the stream layer for this transport.
78  #[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  /// Policy for Classless Inter-Domain Routing (CIDR).
85  ///
86  /// By default, allow any connection
87  #[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  /// Set the maximum packet size can be sent by UDP
101  #[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  /// Set the receive buffer size of UDP
113  #[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  /// The metrics labels.
120  #[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  /// Creates a new net transport options by id, other configurations are left default.
179  #[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  /// Creates a new net transport options by id and resolver options, other configurations are left default.
191  #[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  /// Creates a new net transport options by id and stream layer options, other configurations are left default.
203  #[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  /// Creates a new net transport options by id, resolver options and stream layer options, other configurations are left default.
217  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  /// Add bind address
237  pub fn add_bind_address(&mut self, addr: A::Address) -> &mut Self {
238    self.bind_addresses.insert(addr);
239    self
240  }
241
242  /// Set the advertise address (builder pattern).
243  /// This address is not bound or listened on, only advertised to other nodes.
244  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}