Skip to content

Commit 3b1ae36

Browse files
authored
Added IpBindAddressNoPort sockopt (#2244)
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. ```
1 parent a4e0c95 commit 3b1ae36

File tree

3 files changed

+42
-0
lines changed

3 files changed

+42
-0
lines changed

changelog/2244.added.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Added `IpBindAddressNoPort` sockopt to support `IP_BIND_ADDRESS_NO_PORT` available on linux.

src/sys/socket/sockopt.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,20 @@ sockopt_impl!(
412412
libc::IP_FREEBIND,
413413
bool
414414
);
415+
#[cfg(linux_android)]
416+
#[cfg(feature = "net")]
417+
sockopt_impl!(
418+
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
419+
/// If enabled, the kernel will not reserve an ephemeral port when binding
420+
/// socket with a port number of 0. The port will later be automatically
421+
/// chosen at connect time, in a way that allows sharing a source port as
422+
/// long as the 4-tuple is unique.
423+
IpBindAddressNoPort,
424+
Both,
425+
libc::IPPROTO_IP,
426+
libc::IP_BIND_ADDRESS_NO_PORT,
427+
bool
428+
);
415429
sockopt_impl!(
416430
/// Specify the receiving timeout until reporting an error.
417431
ReceiveTimeout,

test/sys/test_sockopt.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -549,3 +549,30 @@ fn test_ts_clock_monotonic() {
549549
SocketTimestamp::SO_TS_MONOTONIC
550550
);
551551
}
552+
553+
#[test]
554+
#[cfg(linux_android)]
555+
// Disable the test under emulation because it failsi with ENOPROTOOPT in CI
556+
// on cross target. Lack of QEMU support is suspected.
557+
#[cfg_attr(qemu, ignore)]
558+
fn test_ip_bind_address_no_port() {
559+
let fd = socket(
560+
AddressFamily::Inet,
561+
SockType::Stream,
562+
SockFlag::empty(),
563+
SockProtocol::Tcp,
564+
)
565+
.unwrap();
566+
setsockopt(&fd, sockopt::IpBindAddressNoPort, &true).expect(
567+
"setting IP_BIND_ADDRESS_NO_PORT on an inet stream socket should succeed",
568+
);
569+
assert!(getsockopt(&fd, sockopt::IpBindAddressNoPort).expect(
570+
"getting IP_BIND_ADDRESS_NO_PORT on an inet stream socket should succeed",
571+
));
572+
setsockopt(&fd, sockopt::IpBindAddressNoPort, &false).expect(
573+
"unsetting IP_BIND_ADDRESS_NO_PORT on an inet stream socket should succeed",
574+
);
575+
assert!(!getsockopt(&fd, sockopt::IpBindAddressNoPort).expect(
576+
"getting IP_BIND_ADDRESS_NO_PORT on an inet stream socket should succeed",
577+
));
578+
}

0 commit comments

Comments
 (0)