mirror of
https://gitee.com/openharmony/third_party_rust_nix
synced 2025-02-17 06:27:44 +00:00
Add support for the IP_SENDSRCADDR control message
This control message (actually just an alias for IP_RECVDSTADDR) sets the IPv4 source address when used with sendmsg. It is available on FreeBSD, NetBSD, OpenBSD, and DragonFlyBSD.
This commit is contained in:
parent
67329c593f
commit
6bf07fdbb9
@ -38,6 +38,8 @@ This project adheres to [Semantic Versioning](https://semver.org/).
|
||||
(#[1772](https://github.com/nix-rust/nix/pull/1772))
|
||||
- Added IPV6_ORIGDSTADDR using Ipv6OrigDstAddr in setsockopt and recvmsg.
|
||||
(#[1772](https://github.com/nix-rust/nix/pull/1772))
|
||||
- Added `IP_SENDSRCADDR` using `Ipv4SendSrcAddr` in `sendmsg`.
|
||||
(#[1776](https://github.com/nix-rust/nix/pull/1776))
|
||||
|
||||
### Changed
|
||||
|
||||
|
@ -1117,6 +1117,17 @@ pub enum ControlMessage<'a> {
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
|
||||
Ipv6PacketInfo(&'a libc::in6_pktinfo),
|
||||
|
||||
/// Configure the IPv4 source address with `IP_SENDSRCADDR`.
|
||||
#[cfg(any(
|
||||
target_os = "netbsd",
|
||||
target_os = "freebsd",
|
||||
target_os = "openbsd",
|
||||
target_os = "dragonfly",
|
||||
))]
|
||||
#[cfg(feature = "net")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
|
||||
Ipv4SendSrcAddr(&'a libc::in_addr),
|
||||
|
||||
/// SO_RXQ_OVFL indicates that an unsigned 32 bit value
|
||||
/// ancilliary msg (cmsg) should be attached to recieved
|
||||
/// skbs indicating the number of packets dropped by the
|
||||
@ -1226,6 +1237,10 @@ impl<'a> ControlMessage<'a> {
|
||||
target_os = "android", target_os = "ios",))]
|
||||
#[cfg(feature = "net")]
|
||||
ControlMessage::Ipv6PacketInfo(info) => info as *const _ as *const u8,
|
||||
#[cfg(any(target_os = "netbsd", target_os = "freebsd",
|
||||
target_os = "openbsd", target_os = "dragonfly"))]
|
||||
#[cfg(feature = "net")]
|
||||
ControlMessage::Ipv4SendSrcAddr(addr) => addr as *const _ as *const u8,
|
||||
#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
|
||||
ControlMessage::RxqOvfl(drop_count) => {
|
||||
drop_count as *const _ as *const u8
|
||||
@ -1285,6 +1300,10 @@ impl<'a> ControlMessage<'a> {
|
||||
target_os = "android", target_os = "ios",))]
|
||||
#[cfg(feature = "net")]
|
||||
ControlMessage::Ipv6PacketInfo(info) => mem::size_of_val(info),
|
||||
#[cfg(any(target_os = "netbsd", target_os = "freebsd",
|
||||
target_os = "openbsd", target_os = "dragonfly"))]
|
||||
#[cfg(feature = "net")]
|
||||
ControlMessage::Ipv4SendSrcAddr(addr) => mem::size_of_val(addr),
|
||||
#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
|
||||
ControlMessage::RxqOvfl(drop_count) => {
|
||||
mem::size_of_val(drop_count)
|
||||
@ -1320,6 +1339,10 @@ impl<'a> ControlMessage<'a> {
|
||||
target_os = "android", target_os = "ios",))]
|
||||
#[cfg(feature = "net")]
|
||||
ControlMessage::Ipv6PacketInfo(_) => libc::IPPROTO_IPV6,
|
||||
#[cfg(any(target_os = "netbsd", target_os = "freebsd",
|
||||
target_os = "openbsd", target_os = "dragonfly"))]
|
||||
#[cfg(feature = "net")]
|
||||
ControlMessage::Ipv4SendSrcAddr(_) => libc::IPPROTO_IP,
|
||||
#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
|
||||
ControlMessage::RxqOvfl(_) => libc::SOL_SOCKET,
|
||||
#[cfg(target_os = "linux")]
|
||||
@ -1362,6 +1385,10 @@ impl<'a> ControlMessage<'a> {
|
||||
target_os = "android", target_os = "ios",))]
|
||||
#[cfg(feature = "net")]
|
||||
ControlMessage::Ipv6PacketInfo(_) => libc::IPV6_PKTINFO,
|
||||
#[cfg(any(target_os = "netbsd", target_os = "freebsd",
|
||||
target_os = "openbsd", target_os = "dragonfly"))]
|
||||
#[cfg(feature = "net")]
|
||||
ControlMessage::Ipv4SendSrcAddr(_) => libc::IP_SENDSRCADDR,
|
||||
#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
|
||||
ControlMessage::RxqOvfl(_) => {
|
||||
libc::SO_RXQ_OVFL
|
||||
|
@ -1122,6 +1122,58 @@ pub fn test_sendmsg_ipv6packetinfo() {
|
||||
.expect("sendmsg");
|
||||
}
|
||||
|
||||
// Verify that ControlMessage::Ipv4SendSrcAddr works for sendmsg. This
|
||||
// creates a UDP socket bound to all local interfaces (0.0.0.0). It then
|
||||
// sends message to itself at 127.0.0.1 while explicitly specifying
|
||||
// 127.0.0.1 as the source address through an Ipv4SendSrcAddr
|
||||
// (IP_SENDSRCADDR) control message.
|
||||
//
|
||||
// Note that binding to 0.0.0.0 is *required* on FreeBSD; sendmsg
|
||||
// returns EINVAL otherwise. (See FreeBSD's ip(4) man page.)
|
||||
#[cfg(any(
|
||||
target_os = "netbsd",
|
||||
target_os = "freebsd",
|
||||
target_os = "openbsd",
|
||||
target_os = "dragonfly",
|
||||
))]
|
||||
#[test]
|
||||
pub fn test_sendmsg_ipv4sendsrcaddr() {
|
||||
use nix::sys::socket::{
|
||||
bind, sendmsg, socket, AddressFamily, ControlMessage, MsgFlags,
|
||||
SockFlag, SockType, SockaddrIn,
|
||||
};
|
||||
use std::io::IoSlice;
|
||||
|
||||
let sock = socket(
|
||||
AddressFamily::Inet,
|
||||
SockType::Datagram,
|
||||
SockFlag::empty(),
|
||||
None,
|
||||
)
|
||||
.expect("socket failed");
|
||||
|
||||
let unspec_sock_addr = SockaddrIn::new(0, 0, 0, 0, 0);
|
||||
bind(sock, &unspec_sock_addr).expect("bind failed");
|
||||
let bound_sock_addr: SockaddrIn = getsockname(sock).unwrap();
|
||||
let localhost_sock_addr: SockaddrIn =
|
||||
SockaddrIn::new(127, 0, 0, 1, bound_sock_addr.port());
|
||||
|
||||
let slice = [1u8, 2, 3, 4, 5, 6, 7, 8];
|
||||
let iov = [IoSlice::new(&slice)];
|
||||
let cmsg = [ControlMessage::Ipv4SendSrcAddr(
|
||||
&localhost_sock_addr.as_ref().sin_addr,
|
||||
)];
|
||||
|
||||
sendmsg(
|
||||
sock,
|
||||
&iov,
|
||||
&cmsg,
|
||||
MsgFlags::empty(),
|
||||
Some(&localhost_sock_addr),
|
||||
)
|
||||
.expect("sendmsg");
|
||||
}
|
||||
|
||||
/// Tests that passing multiple fds using a single `ControlMessage` works.
|
||||
// Disable the test on emulated platforms due to a bug in QEMU versions <
|
||||
// 2.12.0. https://bugs.launchpad.net/qemu/+bug/1701808
|
||||
|
Loading…
x
Reference in New Issue
Block a user