Skip to content

Commit

Permalink
[refactor] config: Use dedicated functions to set options
Browse files Browse the repository at this point in the history
With public members in the config structs the public API breaks each
time we're adding new options as the users MUST or MUST NOT add "..
Default::default()" depending on wheter they're setting all options or
not. So adding new options breaks for those users who use all options.

This change hides the members form the users and replaces access by
dedicated setter functions for each option so adding new options does
not break API in the future. (This change obviously is an API break in
itself.)

Signed-off-by: Konrad Gräfe <[email protected]>
  • Loading branch information
kgraefe committed Apr 28, 2023
1 parent 2f8efe1 commit a07fde4
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 14 deletions.
18 changes: 16 additions & 2 deletions src/adapters/framed_tcp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,28 @@ const INPUT_BUFFER_SIZE: usize = u16::MAX as usize; // 2^16 - 1

#[derive(Clone, Debug, Default)]
pub struct FramedTcpConnectConfig {
keepalive: Option<TcpKeepalive>,
}

impl FramedTcpConnectConfig {
/// Enables TCP keepalive settings on the socket.
pub keepalive: Option<TcpKeepalive>,
pub fn with_keepalive(mut self, keepalive: TcpKeepalive) -> Self {
self.keepalive = Some(keepalive);
self
}
}

#[derive(Clone, Debug, Default)]
pub struct FramedTcpListenConfig {
keepalive: Option<TcpKeepalive>,
}

impl FramedTcpListenConfig {
/// Enables TCP keepalive settings on client connection sockets.
pub keepalive: Option<TcpKeepalive>,
pub fn with_keepalive(mut self, keepalive: TcpKeepalive) -> Self {
self.keepalive = Some(keepalive);
self
}
}

pub(crate) struct FramedTcpAdapter;
Expand Down
18 changes: 16 additions & 2 deletions src/adapters/tcp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,28 @@ pub const INPUT_BUFFER_SIZE: usize = u16::MAX as usize; // 2^16 - 1

#[derive(Clone, Debug, Default)]
pub struct TcpConnectConfig {
keepalive: Option<TcpKeepalive>,
}

impl TcpConnectConfig {
/// Enables TCP keepalive settings on the socket.
pub keepalive: Option<TcpKeepalive>,
pub fn with_keepalive(mut self, keepalive: TcpKeepalive) -> Self {
self.keepalive = Some(keepalive);
self
}
}

#[derive(Clone, Debug, Default)]
pub struct TcpListenConfig {
keepalive: Option<TcpKeepalive>,
}

impl TcpListenConfig {
/// Enables TCP keepalive settings on client connection sockets.
pub keepalive: Option<TcpKeepalive>,
pub fn with_keepalive(mut self, keepalive: TcpKeepalive) -> Self {
self.keepalive = Some(keepalive);
self
}
}

pub(crate) struct TcpAdapter;
Expand Down
54 changes: 46 additions & 8 deletions src/adapters/udp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,22 +39,41 @@ pub const MAX_LOCAL_PAYLOAD_LEN: usize = 9216 - 20 - 8;

#[derive(Clone, PartialEq, Eq, Hash, Debug)]
pub struct UdpConnectConfig {
source_address: SocketAddr,
broadcast: bool,
reuse_address: bool,
reuse_port: bool,
}

impl UdpConnectConfig {
/// Specify the source address and port.
pub source_address: SocketAddr,
pub fn with_source_address(mut self, addr: SocketAddr) -> Self {
self.source_address = addr;
self
}

/// Enables the socket capabilities to send broadcast messages.
pub broadcast: bool,
pub fn with_broadcast(mut self) -> Self {
self.broadcast = true;
self
}

/// Set value for the `SO_REUSEADDR` option on this socket. This indicates that futher calls to
/// `bind` may allow reuse of local addresses. For IPv4 sockets this means that a socket may
/// bind even when there’s a socket already listening on this port.
pub reuse_address: bool,
pub fn with_reuse_address(mut self) -> Self {
self.reuse_address = true;
self
}

/// Set value for the `SO_REUSEPORT` option on this socket. This indicates that further calls
/// to `bind` may allow reuse of local addresses. For IPv4 sockets this means that a socket may
/// bind even when there’s a socket already listening on this port. This option is always-on on
/// Windows and cannot be configured.
pub reuse_port: bool,
pub fn with_reuse_port(mut self) -> Self {
self.reuse_port = true;
self
}
}

impl Default for UdpConnectConfig {
Expand All @@ -70,26 +89,45 @@ impl Default for UdpConnectConfig {

#[derive(Clone, PartialEq, Eq, Hash, Debug, Default)]
pub struct UdpListenConfig {
send_broadcasts: bool,
receive_broadcasts: bool,
reuse_address: bool,
reuse_port: bool,
}

impl UdpListenConfig {
/// Enables the socket capabilities to send broadcast messages when the listening socket is
/// also used for sending with
/// [`Endpoint::from_listener`](crate::network::Endpoint::from_listener).
pub send_broadcasts: bool,
pub fn with_send_broadcasts(mut self) -> Self {
self.send_broadcasts = true;
self
}

/// On Windows, when listening on a specific IP address, the sockets also receives
/// corresponding subnet broadcasts and global broadcasts ([`std::net::Ipv4Addr::BROADCAST`])
/// received on the interface matching the IP. When this option is set, message-io mimics this
/// behavior on Linux.
pub receive_broadcasts: bool,
pub fn with_receive_broadcasts(mut self) -> Self {
self.receive_broadcasts = true;
self
}

/// Set value for the `SO_REUSEADDR` option on this socket. This indicates that futher calls to
/// `bind` may allow reuse of local addresses.
pub reuse_address: bool,
pub fn with_reuse_address(mut self) -> Self {
self.reuse_address = true;
self
}

/// Set value for the `SO_REUSEPORT` option on this socket. This indicates that further calls
/// to `bind` may allow reuse of local addresses. For IPv4 sockets this means that a socket may
/// bind even when there’s a socket already listening on this port. This option is always-on
/// on Windows and cannot be configured.
pub reuse_port: bool,
pub fn with_reuse_port(mut self) -> Self {
self.reuse_port = true;
self
}
}

pub(crate) struct UdpAdapter;
Expand Down
4 changes: 2 additions & 2 deletions src/network.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ impl NetworkController {
/// let (handler, listener) = node::split();
/// handler.signals().send_with_timer((), std::time::Duration::from_secs(1));
///
/// let config = UdpConnectConfig { broadcast: true, ..Default::default() };
/// let config = UdpConnectConfig::default().with_broadcast();
/// let addr = "255.255.255.255:7777";
/// let (conn_endpoint, _) = handler.network().connect_with(TransportConnect::Udp(config), addr).unwrap();
/// // The socket could not be able to send yet.
Expand Down Expand Up @@ -226,7 +226,7 @@ impl NetworkController {
/// let (handler, listener) = node::split();
/// handler.signals().send_with_timer((), std::time::Duration::from_secs(1));
///
/// let config = UdpConnectConfig { broadcast: true, ..Default::default() };
/// let config = UdpConnectConfig::default().with_broadcast();
/// let addr = "255.255.255.255:7777";
/// match handler.network().connect_sync_with(TransportConnect::Udp(config), addr) {
/// Ok((endpoint, _)) => {
Expand Down

0 comments on commit a07fde4

Please sign in to comment.