Skip to content

Commit

Permalink
Added IpBindAddressNoPort sockopt
Browse files Browse the repository at this point in the history
From [man page](https://man7.org/linux/man-pages/man7/ip.7.html):
```
IP_BIND_ADDRESS_NO_PORT (since Linux 4.2)
       Inform the kernel to not reserve an ephemeral port when
       using bind(2) with a port number of 0.  The port will
       later be automatically chosen at connect(2) time, in a way
       that allows sharing a source port as long as the 4-tuple
       is unique.
```
  • Loading branch information
xonatius committed Dec 2, 2023
1 parent 83dfd90 commit 0b6bb15
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 0 deletions.
1 change: 1 addition & 0 deletions changelog/2244.added.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Added `IpBindAddressNoPort` sockopt to support `IP_BIND_ADDRESS_NO_PORT` available on linux.
14 changes: 14 additions & 0 deletions src/sys/socket/sockopt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,20 @@ sockopt_impl!(
libc::IP_FREEBIND,
bool
);
#[cfg(linux_android)]
#[cfg(feature = "net")]
sockopt_impl!(
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
/// If enabled, the kernel will not reserve an ephemeral port when binding
/// socket with a port number of 0. The port will later be automatically
/// chosen at connect time, in a way that allows sharing a source port as
/// long as the 4-tuple is unique.
IpBindAddressNoPort,
Both,
libc::IPPROTO_IP,
libc::IP_BIND_ADDRESS_NO_PORT,
bool
);
sockopt_impl!(
/// Specify the receiving timeout until reporting an error.
ReceiveTimeout,
Expand Down
27 changes: 27 additions & 0 deletions test/sys/test_sockopt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -549,3 +549,30 @@ fn test_ts_clock_monotonic() {
SocketTimestamp::SO_TS_MONOTONIC
);
}

#[test]
#[cfg(linux_android)]
// Disable the test under emulation because it failsi with ENOPROTOOPT in CI
// on cross target. Lack of QEMU support is suspected.
#[cfg_attr(qemu, ignore)]
fn test_ip_bind_address_no_port() {
let fd = socket(
AddressFamily::Inet,
SockType::Stream,
SockFlag::empty(),
SockProtocol::Tcp,
)
.unwrap();
setsockopt(&fd, sockopt::IpBindAddressNoPort, &true).expect(
"setting IP_BIND_ADDRESS_NO_PORT on an inet stream socket should succeed",
);
assert!(getsockopt(&fd, sockopt::IpBindAddressNoPort).expect(
"getting IP_BIND_ADDRESS_NO_PORT on an inet stream socket should succeed",
));
setsockopt(&fd, sockopt::IpBindAddressNoPort, &false).expect(
"unsetting IP_BIND_ADDRESS_NO_PORT on an inet stream socket should succeed",
);
assert!(!getsockopt(&fd, sockopt::IpBindAddressNoPort).expect(
"getting IP_BIND_ADDRESS_NO_PORT on an inet stream socket should succeed",
));
}

0 comments on commit 0b6bb15

Please sign in to comment.