From 8a030dcf7cce532c59cebc135de2a81189cf6254 Mon Sep 17 00:00:00 2001 From: Bigo <1781140+crisidev@users.noreply.github.com> Date: Mon, 3 Jun 2024 13:46:46 +0100 Subject: [PATCH 01/26] feat: add support for DSCP and TTL / Hop Limit * Support IP_RECVTTL and IPV6_RECVHOPLIMIT socket options and related control messages for recvmsg. * Support setting DSCP in control messages for both sendmsg and recvmsg. Signed-off-by: Bigo <1781140+crisidev@users.noreply.github.com> --- src/sys/socket/mod.rs | 89 +++++++++++++++++++++ src/sys/socket/sockopt.rs | 51 +++++++++++- test/sys/test_socket.rs | 160 ++++++++++++++++++++++++++++++++++++++ test/sys/test_sockopt.rs | 118 ++++++++++++++++++++++++++++ 4 files changed, 415 insertions(+), 3 deletions(-) diff --git a/src/sys/socket/mod.rs b/src/sys/socket/mod.rs index 1f1869e90d..28ee6a08e9 100644 --- a/src/sys/socket/mod.rs +++ b/src/sys/socket/mod.rs @@ -769,6 +769,32 @@ pub enum ControlMessageOwned { #[cfg_attr(docsrs, doc(cfg(feature = "net")))] Ipv6OrigDstAddr(libc::sockaddr_in6), + /// Time-to-Live (TTL) header field of the incoming IPv4 packet. + /// + /// [Further reading](https://www.man7.org/linux/man-pages/man7/ip.7.html) + #[cfg(any(linux_android, target_os = "freebsd"))] + #[cfg(feature = "net")] + #[cfg_attr(docsrs, doc(cfg(feature = "net")))] + Ipv4RecvTtl(u8), + + /// Hop Limit header field of the incoming IPv6 packet. + #[cfg(any(linux_android, target_os = "freebsd"))] + #[cfg(feature = "net")] + #[cfg_attr(docsrs, doc(cfg(feature = "net")))] + Ipv6RecvHopLimit(u8), + + /// Retrieve the DSCP (ToS) header field of the incoming IPv4 packet. + #[cfg(any(linux_android, target_os = "freebsd"))] + #[cfg(feature = "net")] + #[cfg_attr(docsrs, doc(cfg(feature = "net")))] + Ipv4Tos(i32), + + /// Retrieve the DSCP (Traffic Class) header field of the incoming IPv6 packet. + #[cfg(any(linux_android, target_os = "freebsd"))] + #[cfg(feature = "net")] + #[cfg_attr(docsrs, doc(cfg(feature = "net")))] + Ipv6TClass(i32), + /// UDP Generic Receive Offload (GRO) allows receiving multiple UDP /// packets from a single sender. /// Fixed-size payloads are following one by one in a receive buffer. @@ -987,6 +1013,30 @@ impl ControlMessageOwned { let content_type = unsafe { ptr::read_unaligned(p as *const u8) }; ControlMessageOwned::TlsGetRecordType(content_type.into()) }, + #[cfg(any(linux_android, target_os = "freebsd"))] + #[cfg(feature = "net")] + (libc::IPPROTO_IP, libc::IP_TTL) => { + let ttl: u8 = unsafe { ptr::read_unaligned(p as *const u8) }; + ControlMessageOwned::Ipv4RecvTtl(ttl) + }, + #[cfg(any(linux_android, target_os = "freebsd"))] + #[cfg(feature = "net")] + (libc::IPPROTO_IPV6, libc::IPV6_HOPLIMIT) => { + let ttl: u8 = unsafe { ptr::read_unaligned(p as *const u8) }; + ControlMessageOwned::Ipv6RecvHopLimit(ttl) + }, + #[cfg(any(linux_android, target_os = "freebsd"))] + #[cfg(feature = "net")] + (libc::IPPROTO_IP, libc::IP_TOS) => { + let tos = unsafe { ptr::read_unaligned(p as *const i32) }; + ControlMessageOwned::Ipv4Tos(tos) + }, + #[cfg(any(linux_android, target_os = "freebsd"))] + #[cfg(feature = "net")] + (libc::IPPROTO_IPV6, libc::IPV6_TCLASS) => { + let tc = unsafe { ptr::read_unaligned(p as *const i32) }; + ControlMessageOwned::Ipv6TClass(tc) + }, (_, _) => { let sl = unsafe { std::slice::from_raw_parts(p, len) }; let ucmsg = UnknownCmsg(*header, Vec::::from(sl)); @@ -1152,6 +1202,17 @@ pub enum ControlMessage<'a> { /// page. #[cfg(target_os = "linux")] TxTime(&'a u64), + + /// Configure DSCP / IP TOS for outgoing v4 packets. + /// + /// Further information can be found [here](https://en.wikipedia.org/wiki/Differentiated_services). + #[cfg(target_os = "linux")] + IpTos(&'a i32), + /// Configure DSCP / IP TOS for outgoing v6 packets. + /// + /// Further information can be found [here](https://en.wikipedia.org/wiki/Differentiated_services). + #[cfg(target_os = "linux")] + Ipv6TClass(&'a i32), } // An opaque structure used to prevent cmsghdr from being a public type @@ -1256,6 +1317,14 @@ impl<'a> ControlMessage<'a> { ControlMessage::TxTime(tx_time) => { tx_time as *const _ as *const u8 }, + #[cfg(target_os = "linux")] + ControlMessage::IpTos(tos) => { + tos as *const _ as *const u8 + }, + #[cfg(target_os = "linux")] + ControlMessage::Ipv6TClass(tclass) => { + tclass as *const _ as *const u8 + }, }; unsafe { ptr::copy_nonoverlapping( @@ -1320,6 +1389,14 @@ impl<'a> ControlMessage<'a> { ControlMessage::TxTime(tx_time) => { mem::size_of_val(tx_time) }, + #[cfg(target_os = "linux")] + ControlMessage::IpTos(tos) => { + mem::size_of_val(tos) + }, + #[cfg(target_os = "linux")] + ControlMessage::Ipv6TClass(tclass) => { + mem::size_of_val(tclass) + }, } } @@ -1354,6 +1431,10 @@ impl<'a> ControlMessage<'a> { ControlMessage::RxqOvfl(_) => libc::SOL_SOCKET, #[cfg(target_os = "linux")] ControlMessage::TxTime(_) => libc::SOL_SOCKET, + #[cfg(target_os = "linux")] + ControlMessage::IpTos(_) => libc::IPPROTO_IP, + #[cfg(target_os = "linux")] + ControlMessage::Ipv6TClass(_) => libc::IPPROTO_IPV6, } } @@ -1403,6 +1484,14 @@ impl<'a> ControlMessage<'a> { ControlMessage::TxTime(_) => { libc::SCM_TXTIME }, + #[cfg(target_os = "linux")] + ControlMessage::IpTos(_) => { + libc::IP_TOS + }, + #[cfg(target_os = "linux")] + ControlMessage::Ipv6TClass(_) => { + libc::IPV6_TCLASS + }, } } diff --git a/src/sys/socket/sockopt.rs b/src/sys/socket/sockopt.rs index 810340041d..e16e14df0f 100644 --- a/src/sys/socket/sockopt.rs +++ b/src/sys/socket/sockopt.rs @@ -406,7 +406,7 @@ sockopt_impl!( #[cfg(feature = "net")] sockopt_impl!( #[cfg_attr(docsrs, doc(cfg(feature = "net")))] - /// Set or receive the Type-Of-Service (TOS) field that is + /// Set the Type-Of-Service (TOS) field that is /// sent with every IP packet originating from this socket IpTos, Both, @@ -418,13 +418,35 @@ sockopt_impl!( #[cfg(feature = "net")] sockopt_impl!( #[cfg_attr(docsrs, doc(cfg(feature = "net")))] - /// Traffic class associated with outgoing packets + /// Receive the Type-Of-Service (TOS) associated with incoming packets. + IpRecvTos, + Both, + libc::IPPROTO_IP, + libc::IP_RECVTOS, + bool +); +#[cfg(target_os = "linux")] +#[cfg(feature = "net")] +sockopt_impl!( + #[cfg_attr(docsrs, doc(cfg(feature = "net")))] + /// Set the traffic class associated with outgoing packets. Ipv6TClass, Both, libc::IPPROTO_IPV6, libc::IPV6_TCLASS, libc::c_int ); +#[cfg(target_os = "linux")] +#[cfg(feature = "net")] +sockopt_impl!( + #[cfg_attr(docsrs, doc(cfg(feature = "net")))] + /// Receive the traffic class associated with incoming packets. + Ipv6TRecvTClass, + Both, + libc::IPPROTO_IPV6, + libc::IPV6_RECVTCLASS, + bool +); #[cfg(any(linux_android, target_os = "fuchsia"))] #[cfg(feature = "net")] sockopt_impl!( @@ -1045,7 +1067,19 @@ sockopt_impl!( libc::IP_TTL, libc::c_int ); -#[cfg(any(apple_targets, linux_android, target_os = "freebsd"))] +#[cfg(any(linux_android, target_os = "freebsd"))] +#[cfg(feature = "net")] +sockopt_impl!( + /// Enables a receiving socket to retrieve the Time-to-Live (TTL) field + /// from incoming IPv4 packets. + Ipv4RecvTtl, + Both, + libc::IPPROTO_IP, + libc::IP_RECVTTL, + bool +); +#[cfg(any(linux_android, target_os = "freebsd"))] +#[cfg(feature = "net")] sockopt_impl!( /// Set the unicast hop limit for the socket. Ipv6Ttl, @@ -1056,6 +1090,17 @@ sockopt_impl!( ); #[cfg(any(linux_android, target_os = "freebsd"))] #[cfg(feature = "net")] +sockopt_impl!( + /// Enables a receiving socket to retrieve the Hop Limit field + /// (similar to TTL in IPv4) from incoming IPv6 packets. + Ipv6RecvHopLimit, + Both, + libc::IPPROTO_IPV6, + libc::IPV6_RECVHOPLIMIT, + bool +); +#[cfg(any(linux_android, target_os = "freebsd"))] +#[cfg(feature = "net")] sockopt_impl!( #[cfg_attr(docsrs, doc(cfg(feature = "net")))] /// The `recvmsg(2)` call will return the destination IP address for a UDP diff --git a/test/sys/test_socket.rs b/test/sys/test_socket.rs index 79c97c8720..9a57fdb29a 100644 --- a/test/sys/test_socket.rs +++ b/test/sys/test_socket.rs @@ -2544,6 +2544,166 @@ fn test_recvmsg_rxq_ovfl() { assert_eq!(drop_counter, 1); } +#[cfg(target_os = "linux")] +#[cfg(feature = "net")] +#[cfg_attr(qemu, ignore)] +#[test] +pub fn test_ip_tos_udp() { + use nix::sys::socket::ControlMessageOwned; + use nix::sys::socket::{ + bind, recvmsg, sendmsg, setsockopt, socket, sockopt, ControlMessage, + MsgFlags, SockFlag, SockType, SockaddrIn, + }; + + let sock_addr = SockaddrIn::from_str("127.0.0.1:6909").unwrap(); + let rsock = socket( + AddressFamily::Inet, + SockType::Datagram, + SockFlag::empty(), + None, + ) + .unwrap(); + setsockopt(&rsock, sockopt::IpRecvTos, &true).unwrap(); + bind(rsock.as_raw_fd(), &sock_addr).unwrap(); + + let sbuf = [0u8; 2048]; + let iov1 = [std::io::IoSlice::new(&sbuf)]; + + let mut rbuf = [0u8; 2048]; + let mut iov2 = [std::io::IoSliceMut::new(&mut rbuf)]; + let mut rcmsg = cmsg_space!(libc::c_int); + + let ssock = socket( + AddressFamily::Inet, + SockType::Datagram, + SockFlag::empty(), + None, + ) + .expect("send socket failed"); + setsockopt(&ssock, sockopt::IpTos, &20).unwrap(); + + // Test the sendmsg control message and check the received packet has the same TOS. + let scmsg = ControlMessage::IpTos(&20); + sendmsg( + ssock.as_raw_fd(), + &iov1, + &[scmsg], + MsgFlags::empty(), + Some(&sock_addr), + ) + .unwrap(); + + // TODO: this test is weak, but testing for the actual ToS value results in sporadic + // failures in CI where the ToS in the message header is not the one set by the + // sender, so for now the test only checks for the presence of the ToS in the message + // header. + let mut tc = None; + let recv = recvmsg::<()>( + rsock.as_raw_fd(), + &mut iov2, + Some(&mut rcmsg), + MsgFlags::empty(), + ) + .unwrap(); + for c in recv.cmsgs().unwrap() { + println!("CMSG: {c:?}"); + if let ControlMessageOwned::Ipv4Tos(t) = c { + tc = Some(t); + } + } + assert!(tc.is_some()); +} + +#[cfg(target_os = "linux")] +#[cfg(feature = "net")] +#[cfg_attr(qemu, ignore)] +#[test] +pub fn test_ipv6_tclass_udp() { + use nix::sys::socket::ControlMessageOwned; + use nix::sys::socket::{ + bind, recvmsg, sendmsg, setsockopt, socket, sockopt, ControlMessage, + MsgFlags, SockFlag, SockType, SockaddrIn6, + }; + + let std_sa = SocketAddrV6::from_str("[::1]:6902").unwrap(); + let sock_addr: SockaddrIn6 = SockaddrIn6::from(std_sa); + let rsock = socket( + AddressFamily::Inet6, + SockType::Datagram, + SockFlag::empty(), + None, + ) + .unwrap(); + setsockopt(&rsock, sockopt::Ipv6TRecvTClass, &true).unwrap(); + bind(rsock.as_raw_fd(), &sock_addr).unwrap(); + + let sbuf = [0u8; 2048]; + let iov1 = [std::io::IoSlice::new(&sbuf)]; + + let mut rbuf = [0u8; 2048]; + let mut iov2 = [std::io::IoSliceMut::new(&mut rbuf)]; + let mut rcmsg = cmsg_space!(libc::c_int); + + let ssock = socket( + AddressFamily::Inet6, + SockType::Datagram, + SockFlag::empty(), + None, + ) + .expect("send socket failed"); + setsockopt(&ssock, sockopt::Ipv6TClass, &10).unwrap(); + + sendmsg( + ssock.as_raw_fd(), + &iov1, + &[], + MsgFlags::empty(), + Some(&sock_addr), + ) + .unwrap(); + + let mut tc = None; + let recv = recvmsg::<()>( + rsock.as_raw_fd(), + &mut iov2, + Some(&mut rcmsg), + MsgFlags::empty(), + ) + .unwrap(); + for c in recv.cmsgs().unwrap() { + if let ControlMessageOwned::Ipv6TClass(t) = c { + tc = Some(t); + } + } + assert_eq!(tc, Some(10)); + + let scmsg = ControlMessage::Ipv6TClass(&20); + sendmsg( + ssock.as_raw_fd(), + &iov1, + &[scmsg], + MsgFlags::empty(), + Some(&sock_addr), + ) + .unwrap(); + + let mut tc = None; + let recv = recvmsg::<()>( + rsock.as_raw_fd(), + &mut iov2, + Some(&mut rcmsg), + MsgFlags::empty(), + ) + .unwrap(); + for c in recv.cmsgs().unwrap() { + if let ControlMessageOwned::Ipv6TClass(t) = c { + tc = Some(t); + } + } + + assert_eq!(tc, Some(20)); +} + #[cfg(linux_android)] mod linux_errqueue { use super::FromStr; diff --git a/test/sys/test_sockopt.rs b/test/sys/test_sockopt.rs index 1da3f6af38..d9b499063c 100644 --- a/test/sys/test_sockopt.rs +++ b/test/sys/test_sockopt.rs @@ -877,3 +877,121 @@ fn test_reuseport_lb() { setsockopt(&fd, sockopt::ReusePortLb, &true).unwrap(); assert!(getsockopt(&fd, sockopt::ReusePortLb).unwrap()); } + +#[test] +#[cfg(any(linux_android, target_os = "freebsd"))] +fn test_ipv4_recv_ttl_opts() { + let fd = socket( + AddressFamily::Inet, + SockType::Stream, + SockFlag::empty(), + SockProtocol::Tcp, + ) + .unwrap(); + setsockopt(&fd, sockopt::Ipv4RecvTtl, &true) + .expect("setting IP_RECVTTL on an inet stream socket should succeed"); + setsockopt(&fd, sockopt::Ipv4RecvTtl, &false) + .expect("unsetting IP_RECVTTL on an inet stream socket should succeed"); + let fdd = socket( + AddressFamily::Inet, + SockType::Datagram, + SockFlag::empty(), + None, + ) + .unwrap(); + setsockopt(&fdd, sockopt::Ipv4RecvTtl, &true) + .expect("setting IP_RECVTTL on an inet datagram socket should succeed"); + setsockopt(&fdd, sockopt::Ipv4RecvTtl, &false).expect( + "unsetting IP_RECVTTL on an inet datagram socket should succeed", + ); +} + +#[test] +#[cfg(any(linux_android, target_os = "freebsd"))] +fn test_ipv6_recv_hop_limit_opts() { + let fd = socket( + AddressFamily::Inet6, + SockType::Stream, + SockFlag::empty(), + SockProtocol::Tcp, + ) + .unwrap(); + setsockopt(&fd, sockopt::Ipv6RecvHopLimit, &true).expect( + "setting IPV6_RECVHOPLIMIT on an inet6 stream socket should succeed", + ); + setsockopt(&fd, sockopt::Ipv6RecvHopLimit, &false).expect( + "unsetting IPV6_RECVHOPLIMIT on an inet6 stream socket should succeed", + ); + let fdd = socket( + AddressFamily::Inet6, + SockType::Datagram, + SockFlag::empty(), + None, + ) + .unwrap(); + setsockopt(&fdd, sockopt::Ipv6RecvHopLimit, &true).expect( + "setting IPV6_RECVHOPLIMIT on an inet6 datagram socket should succeed", + ); + setsockopt(&fdd, sockopt::Ipv6RecvHopLimit, &false).expect( + "unsetting IPV6_RECVHOPLIMIT on an inet6 datagram socket should succeed", + ); +} + +#[test] +#[cfg(any(linux_android, target_os = "freebsd"))] +fn test_ipv4_recv_tos_opts() { + let fd = socket( + AddressFamily::Inet, + SockType::Stream, + SockFlag::empty(), + SockProtocol::Tcp, + ) + .unwrap(); + setsockopt(&fd, sockopt::IpRecvTos, &true) + .expect("setting IP_RECVTOS on an inet stream socket should succeed"); + setsockopt(&fd, sockopt::IpRecvTos, &false) + .expect("unsetting IP_RECVTOS on an inet stream socket should succeed"); + let fdd = socket( + AddressFamily::Inet, + SockType::Datagram, + SockFlag::empty(), + None, + ) + .unwrap(); + setsockopt(&fdd, sockopt::IpRecvTos, &true) + .expect("setting IP_RECVTOS on an inet datagram socket should succeed"); + setsockopt(&fdd, sockopt::IpRecvTos, &false).expect( + "unsetting IP_RECVTOS on an inet datagram socket should succeed", + ); +} + +#[test] +#[cfg(any(linux_android, target_os = "freebsd"))] +fn test_ipv6_recv_traffic_class_opts() { + let fd = socket( + AddressFamily::Inet6, + SockType::Stream, + SockFlag::empty(), + SockProtocol::Tcp, + ) + .unwrap(); + setsockopt(&fd, sockopt::Ipv6TRecvTClass, &true).expect( + "setting IPV6_RECVTCLASS on an inet6 stream socket should succeed", + ); + setsockopt(&fd, sockopt::Ipv6TRecvTClass, &false).expect( + "unsetting IPV6_RECVTCLASS on an inet6 stream socket should succeed", + ); + let fdd = socket( + AddressFamily::Inet6, + SockType::Datagram, + SockFlag::empty(), + None, + ) + .unwrap(); + setsockopt(&fdd, sockopt::Ipv6TRecvTClass, &true).expect( + "setting IPV6_RECVTCLASS on an inet6 datagram socket should succeed", + ); + setsockopt(&fdd, sockopt::Ipv6TRecvTClass, &false).expect( + "unsetting IPV6_RECVTCLASS on an inet6 datagram socket should succeed", + ); +} From 27cac6054009af17bb32155fcc9a5bfe1bd33619 Mon Sep 17 00:00:00 2001 From: Bigo <1781140+crisidev@users.noreply.github.com> Date: Mon, 3 Jun 2024 18:44:59 +0100 Subject: [PATCH 02/26] Add PR changelog --- changelog/2425.added.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 changelog/2425.added.md diff --git a/changelog/2425.added.md b/changelog/2425.added.md new file mode 100644 index 0000000000..96afad4378 --- /dev/null +++ b/changelog/2425.added.md @@ -0,0 +1,2 @@ +Improve support for extracting the TTL / Hop Limit from incoming packets +and support for DSCP (ToS / Traffic Class). From 4faed1b8ae7e99ee07dc0384bd0ea3aeadb9487f Mon Sep 17 00:00:00 2001 From: Bigo <1781140+crisidev@users.noreply.github.com> Date: Mon, 3 Jun 2024 18:49:23 +0100 Subject: [PATCH 03/26] This is not supported on Freebsd --- src/sys/socket/sockopt.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sys/socket/sockopt.rs b/src/sys/socket/sockopt.rs index e16e14df0f..82d62a49e6 100644 --- a/src/sys/socket/sockopt.rs +++ b/src/sys/socket/sockopt.rs @@ -1067,7 +1067,7 @@ sockopt_impl!( libc::IP_TTL, libc::c_int ); -#[cfg(any(linux_android, target_os = "freebsd"))] +#[cfg(linux_android)] #[cfg(feature = "net")] sockopt_impl!( /// Enables a receiving socket to retrieve the Time-to-Live (TTL) field @@ -1088,7 +1088,7 @@ sockopt_impl!( libc::IPV6_UNICAST_HOPS, libc::c_int ); -#[cfg(any(linux_android, target_os = "freebsd"))] +#[cfg(linux_android)] #[cfg(feature = "net")] sockopt_impl!( /// Enables a receiving socket to retrieve the Hop Limit field From 342aa6bd3e2200da7bf8a20cbf4944fb2ad36b82 Mon Sep 17 00:00:00 2001 From: Bigo <1781140+crisidev@users.noreply.github.com> Date: Mon, 3 Jun 2024 18:55:09 +0100 Subject: [PATCH 04/26] IPV6_RECVTCLASS not supported on freebsd --- src/sys/socket/sockopt.rs | 2 +- test/sys/test_socket.rs | 2 +- test/sys/test_sockopt.rs | 10 +++++----- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/sys/socket/sockopt.rs b/src/sys/socket/sockopt.rs index 82d62a49e6..b154eafd88 100644 --- a/src/sys/socket/sockopt.rs +++ b/src/sys/socket/sockopt.rs @@ -441,7 +441,7 @@ sockopt_impl!( sockopt_impl!( #[cfg_attr(docsrs, doc(cfg(feature = "net")))] /// Receive the traffic class associated with incoming packets. - Ipv6TRecvTClass, + Ipv6RecvTClass, Both, libc::IPPROTO_IPV6, libc::IPV6_RECVTCLASS, diff --git a/test/sys/test_socket.rs b/test/sys/test_socket.rs index 9a57fdb29a..4c5edbc178 100644 --- a/test/sys/test_socket.rs +++ b/test/sys/test_socket.rs @@ -2634,7 +2634,7 @@ pub fn test_ipv6_tclass_udp() { None, ) .unwrap(); - setsockopt(&rsock, sockopt::Ipv6TRecvTClass, &true).unwrap(); + setsockopt(&rsock, sockopt::Ipv6RecvTClass, &true).unwrap(); bind(rsock.as_raw_fd(), &sock_addr).unwrap(); let sbuf = [0u8; 2048]; diff --git a/test/sys/test_sockopt.rs b/test/sys/test_sockopt.rs index d9b499063c..399e27dac0 100644 --- a/test/sys/test_sockopt.rs +++ b/test/sys/test_sockopt.rs @@ -966,7 +966,7 @@ fn test_ipv4_recv_tos_opts() { } #[test] -#[cfg(any(linux_android, target_os = "freebsd"))] +#[cfg(linux_android)] fn test_ipv6_recv_traffic_class_opts() { let fd = socket( AddressFamily::Inet6, @@ -975,10 +975,10 @@ fn test_ipv6_recv_traffic_class_opts() { SockProtocol::Tcp, ) .unwrap(); - setsockopt(&fd, sockopt::Ipv6TRecvTClass, &true).expect( + setsockopt(&fd, sockopt::Ipv6RecvTClass, &true).expect( "setting IPV6_RECVTCLASS on an inet6 stream socket should succeed", ); - setsockopt(&fd, sockopt::Ipv6TRecvTClass, &false).expect( + setsockopt(&fd, sockopt::Ipv6RecvTClass, &false).expect( "unsetting IPV6_RECVTCLASS on an inet6 stream socket should succeed", ); let fdd = socket( @@ -988,10 +988,10 @@ fn test_ipv6_recv_traffic_class_opts() { None, ) .unwrap(); - setsockopt(&fdd, sockopt::Ipv6TRecvTClass, &true).expect( + setsockopt(&fdd, sockopt::Ipv6RecvTClass, &true).expect( "setting IPV6_RECVTCLASS on an inet6 datagram socket should succeed", ); - setsockopt(&fdd, sockopt::Ipv6TRecvTClass, &false).expect( + setsockopt(&fdd, sockopt::Ipv6RecvTClass, &false).expect( "unsetting IPV6_RECVTCLASS on an inet6 datagram socket should succeed", ); } From 84fc5b123e4fb169267ee27375fd306fe597f965 Mon Sep 17 00:00:00 2001 From: Bigo <1781140+crisidev@users.noreply.github.com> Date: Mon, 3 Jun 2024 18:55:49 +0100 Subject: [PATCH 05/26] Properly limit IPV6_RECVTCLASS --- test/sys/test_sockopt.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/sys/test_sockopt.rs b/test/sys/test_sockopt.rs index 399e27dac0..2bbf80d5cd 100644 --- a/test/sys/test_sockopt.rs +++ b/test/sys/test_sockopt.rs @@ -966,7 +966,7 @@ fn test_ipv4_recv_tos_opts() { } #[test] -#[cfg(linux_android)] +#[cfg(target_os = "linux")] fn test_ipv6_recv_traffic_class_opts() { let fd = socket( AddressFamily::Inet6, From 72173b53dcfd8c502a8637c66fb64958d71a697b Mon Sep 17 00:00:00 2001 From: Bigo <1781140+crisidev@users.noreply.github.com> Date: Mon, 3 Jun 2024 18:57:11 +0100 Subject: [PATCH 06/26] Properly limit IP_TOS --- test/sys/test_sockopt.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/sys/test_sockopt.rs b/test/sys/test_sockopt.rs index 2bbf80d5cd..ffc00f18e4 100644 --- a/test/sys/test_sockopt.rs +++ b/test/sys/test_sockopt.rs @@ -938,7 +938,7 @@ fn test_ipv6_recv_hop_limit_opts() { } #[test] -#[cfg(any(linux_android, target_os = "freebsd"))] +#[cfg(target_os = "linux")] fn test_ipv4_recv_tos_opts() { let fd = socket( AddressFamily::Inet, From 64efe4e761e995373735c06e5296d6b34ac294f6 Mon Sep 17 00:00:00 2001 From: Bigo <1781140+crisidev@users.noreply.github.com> Date: Mon, 3 Jun 2024 19:02:16 +0100 Subject: [PATCH 07/26] Restrict everything to target_os linux --- src/sys/socket/sockopt.rs | 4 ++-- test/sys/test_sockopt.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sys/socket/sockopt.rs b/src/sys/socket/sockopt.rs index b154eafd88..5730476303 100644 --- a/src/sys/socket/sockopt.rs +++ b/src/sys/socket/sockopt.rs @@ -1067,7 +1067,7 @@ sockopt_impl!( libc::IP_TTL, libc::c_int ); -#[cfg(linux_android)] +#[cfg(target_os = "linux")] #[cfg(feature = "net")] sockopt_impl!( /// Enables a receiving socket to retrieve the Time-to-Live (TTL) field @@ -1088,7 +1088,7 @@ sockopt_impl!( libc::IPV6_UNICAST_HOPS, libc::c_int ); -#[cfg(linux_android)] +#[cfg(target_os = "linux")] #[cfg(feature = "net")] sockopt_impl!( /// Enables a receiving socket to retrieve the Hop Limit field diff --git a/test/sys/test_sockopt.rs b/test/sys/test_sockopt.rs index ffc00f18e4..9334e68982 100644 --- a/test/sys/test_sockopt.rs +++ b/test/sys/test_sockopt.rs @@ -879,7 +879,7 @@ fn test_reuseport_lb() { } #[test] -#[cfg(any(linux_android, target_os = "freebsd"))] +#[cfg(target_os = "linux")] fn test_ipv4_recv_ttl_opts() { let fd = socket( AddressFamily::Inet, @@ -907,7 +907,7 @@ fn test_ipv4_recv_ttl_opts() { } #[test] -#[cfg(any(linux_android, target_os = "freebsd"))] +#[cfg(target_os = "linux")] fn test_ipv6_recv_hop_limit_opts() { let fd = socket( AddressFamily::Inet6, From ee761a8e545c0d75e0599d7f6ee284c0ee968cf9 Mon Sep 17 00:00:00 2001 From: Bigo <1781140+crisidev@users.noreply.github.com> Date: Tue, 4 Jun 2024 12:17:31 +0100 Subject: [PATCH 08/26] ... --- src/sys/socket/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sys/socket/mod.rs b/src/sys/socket/mod.rs index 28ee6a08e9..9a7b611370 100644 --- a/src/sys/socket/mod.rs +++ b/src/sys/socket/mod.rs @@ -793,7 +793,7 @@ pub enum ControlMessageOwned { #[cfg(any(linux_android, target_os = "freebsd"))] #[cfg(feature = "net")] #[cfg_attr(docsrs, doc(cfg(feature = "net")))] - Ipv6TClass(i32), + Ipv6TClass(i32), /// UDP Generic Receive Offload (GRO) allows receiving multiple UDP /// packets from a single sender. From 8f52422c9e1b65f2c4cab19b2380be1bbc29f455 Mon Sep 17 00:00:00 2001 From: Bigo <1781140+crisidev@users.noreply.github.com> Date: Tue, 4 Jun 2024 15:46:29 +0100 Subject: [PATCH 09/26] Protect bind --- test/sys/test_socket.rs | 116 ++++++++++++++++++++-------------------- 1 file changed, 58 insertions(+), 58 deletions(-) diff --git a/test/sys/test_socket.rs b/test/sys/test_socket.rs index 4c5edbc178..62cd47939e 100644 --- a/test/sys/test_socket.rs +++ b/test/sys/test_socket.rs @@ -2635,73 +2635,73 @@ pub fn test_ipv6_tclass_udp() { ) .unwrap(); setsockopt(&rsock, sockopt::Ipv6RecvTClass, &true).unwrap(); - bind(rsock.as_raw_fd(), &sock_addr).unwrap(); + if bind(rsock.as_raw_fd(), &sock_addr).is_ok() { + let sbuf = [0u8; 2048]; + let iov1 = [std::io::IoSlice::new(&sbuf)]; - let sbuf = [0u8; 2048]; - let iov1 = [std::io::IoSlice::new(&sbuf)]; - - let mut rbuf = [0u8; 2048]; - let mut iov2 = [std::io::IoSliceMut::new(&mut rbuf)]; - let mut rcmsg = cmsg_space!(libc::c_int); + let mut rbuf = [0u8; 2048]; + let mut iov2 = [std::io::IoSliceMut::new(&mut rbuf)]; + let mut rcmsg = cmsg_space!(libc::c_int); - let ssock = socket( - AddressFamily::Inet6, - SockType::Datagram, - SockFlag::empty(), - None, - ) - .expect("send socket failed"); - setsockopt(&ssock, sockopt::Ipv6TClass, &10).unwrap(); + let ssock = socket( + AddressFamily::Inet6, + SockType::Datagram, + SockFlag::empty(), + None, + ) + .expect("send socket failed"); + setsockopt(&ssock, sockopt::Ipv6TClass, &10).unwrap(); - sendmsg( - ssock.as_raw_fd(), - &iov1, - &[], - MsgFlags::empty(), - Some(&sock_addr), - ) - .unwrap(); + sendmsg( + ssock.as_raw_fd(), + &iov1, + &[], + MsgFlags::empty(), + Some(&sock_addr), + ) + .unwrap(); - let mut tc = None; - let recv = recvmsg::<()>( - rsock.as_raw_fd(), - &mut iov2, - Some(&mut rcmsg), - MsgFlags::empty(), - ) - .unwrap(); - for c in recv.cmsgs().unwrap() { - if let ControlMessageOwned::Ipv6TClass(t) = c { - tc = Some(t); + let mut tc = None; + let recv = recvmsg::<()>( + rsock.as_raw_fd(), + &mut iov2, + Some(&mut rcmsg), + MsgFlags::empty(), + ) + .unwrap(); + for c in recv.cmsgs().unwrap() { + if let ControlMessageOwned::Ipv6TClass(t) = c { + tc = Some(t); + } } - } - assert_eq!(tc, Some(10)); + assert_eq!(tc, Some(10)); - let scmsg = ControlMessage::Ipv6TClass(&20); - sendmsg( - ssock.as_raw_fd(), - &iov1, - &[scmsg], - MsgFlags::empty(), - Some(&sock_addr), - ) - .unwrap(); + let scmsg = ControlMessage::Ipv6TClass(&20); + sendmsg( + ssock.as_raw_fd(), + &iov1, + &[scmsg], + MsgFlags::empty(), + Some(&sock_addr), + ) + .unwrap(); - let mut tc = None; - let recv = recvmsg::<()>( - rsock.as_raw_fd(), - &mut iov2, - Some(&mut rcmsg), - MsgFlags::empty(), - ) - .unwrap(); - for c in recv.cmsgs().unwrap() { - if let ControlMessageOwned::Ipv6TClass(t) = c { - tc = Some(t); + let mut tc = None; + let recv = recvmsg::<()>( + rsock.as_raw_fd(), + &mut iov2, + Some(&mut rcmsg), + MsgFlags::empty(), + ) + .unwrap(); + for c in recv.cmsgs().unwrap() { + if let ControlMessageOwned::Ipv6TClass(t) = c { + tc = Some(t); + } } - } - assert_eq!(tc, Some(20)); + assert_eq!(tc, Some(20)); + } } #[cfg(linux_android)] From be4a2de55548aad3e7ef5b5da2a9c0f13913e8dc Mon Sep 17 00:00:00 2001 From: Matteo Bigoi <1781140+crisidev@users.noreply.github.com> Date: Fri, 14 Jun 2024 12:54:39 +0100 Subject: [PATCH 10/26] Apply suggestions from code review Co-authored-by: SteveLauC --- src/sys/socket/mod.rs | 2 +- src/sys/socket/sockopt.rs | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/sys/socket/mod.rs b/src/sys/socket/mod.rs index 9a7b611370..13549c229f 100644 --- a/src/sys/socket/mod.rs +++ b/src/sys/socket/mod.rs @@ -1015,7 +1015,7 @@ impl ControlMessageOwned { }, #[cfg(any(linux_android, target_os = "freebsd"))] #[cfg(feature = "net")] - (libc::IPPROTO_IP, libc::IP_TTL) => { + (libc::IPPROTO_IP, libc::IP_RECVTTL) => { let ttl: u8 = unsafe { ptr::read_unaligned(p as *const u8) }; ControlMessageOwned::Ipv4RecvTtl(ttl) }, diff --git a/src/sys/socket/sockopt.rs b/src/sys/socket/sockopt.rs index 5730476303..89e863373d 100644 --- a/src/sys/socket/sockopt.rs +++ b/src/sys/socket/sockopt.rs @@ -1078,8 +1078,7 @@ sockopt_impl!( libc::IP_RECVTTL, bool ); -#[cfg(any(linux_android, target_os = "freebsd"))] -#[cfg(feature = "net")] +#[cfg(any(apple_targets, linux_android, target_os = "freebsd"))] sockopt_impl!( /// Set the unicast hop limit for the socket. Ipv6Ttl, From 6e34f9253f4548f312b24fc616cb679ce0a63c0e Mon Sep 17 00:00:00 2001 From: Bigo <1781140+crisidev@users.noreply.github.com> Date: Fri, 14 Jun 2024 14:39:21 +0100 Subject: [PATCH 11/26] Address PR comments --- src/sys/socket/mod.rs | 32 ++++++++++++++++++++++++++------ src/sys/socket/sockopt.rs | 6 +++--- test/sys/test_socket.rs | 2 ++ 3 files changed, 31 insertions(+), 9 deletions(-) diff --git a/src/sys/socket/mod.rs b/src/sys/socket/mod.rs index 13549c229f..b3ab651180 100644 --- a/src/sys/socket/mod.rs +++ b/src/sys/socket/mod.rs @@ -775,13 +775,13 @@ pub enum ControlMessageOwned { #[cfg(any(linux_android, target_os = "freebsd"))] #[cfg(feature = "net")] #[cfg_attr(docsrs, doc(cfg(feature = "net")))] - Ipv4RecvTtl(u8), + Ipv4Ttl(u8), /// Hop Limit header field of the incoming IPv6 packet. #[cfg(any(linux_android, target_os = "freebsd"))] #[cfg(feature = "net")] #[cfg_attr(docsrs, doc(cfg(feature = "net")))] - Ipv6RecvHopLimit(u8), + Ipv6HopLimit(u8), /// Retrieve the DSCP (ToS) header field of the incoming IPv4 packet. #[cfg(any(linux_android, target_os = "freebsd"))] @@ -1017,17 +1017,17 @@ impl ControlMessageOwned { #[cfg(feature = "net")] (libc::IPPROTO_IP, libc::IP_RECVTTL) => { let ttl: u8 = unsafe { ptr::read_unaligned(p as *const u8) }; - ControlMessageOwned::Ipv4RecvTtl(ttl) + ControlMessageOwned::Ipv4Ttl(ttl) }, #[cfg(any(linux_android, target_os = "freebsd"))] #[cfg(feature = "net")] (libc::IPPROTO_IPV6, libc::IPV6_HOPLIMIT) => { let ttl: u8 = unsafe { ptr::read_unaligned(p as *const u8) }; - ControlMessageOwned::Ipv6RecvHopLimit(ttl) + ControlMessageOwned::Ipv6HopLimit(ttl) }, #[cfg(any(linux_android, target_os = "freebsd"))] #[cfg(feature = "net")] - (libc::IPPROTO_IP, libc::IP_TOS) => { + (libc::IPPROTO_IP, libc::IP_RECVTOS) => { let tos = unsafe { ptr::read_unaligned(p as *const i32) }; ControlMessageOwned::Ipv4Tos(tos) }, @@ -1174,6 +1174,12 @@ pub enum ControlMessage<'a> { #[cfg_attr(docsrs, doc(cfg(feature = "net")))] Ipv4SendSrcAddr(&'a libc::in_addr), + /// Configure the Time-to-Live for v4 traffic traffic. + #[cfg(any(linux_android, freebsdlike, apple_targets, target_os = "haiku"))] + #[cfg(feature = "net")] + #[cfg_attr(docsrs, doc(cfg(feature = "net")))] + Ipv4Ttl(&'a libc::c_int), + /// Configure the hop limit for v6 multicast traffic. /// /// Set the IPv6 hop limit for this message. The argument is an integer @@ -1187,7 +1193,7 @@ pub enum ControlMessage<'a> { #[cfg_attr(docsrs, doc(cfg(feature = "net")))] Ipv6HopLimit(&'a libc::c_int), - /// SO_RXQ_OVFL indicates that an unsigned 32 bit value + /// 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 /// socket between the last recieved packet and this @@ -1308,6 +1314,9 @@ impl<'a> ControlMessage<'a> { ControlMessage::Ipv4SendSrcAddr(addr) => addr as *const _ as *const u8, #[cfg(any(linux_android, freebsdlike, apple_targets, target_os = "haiku"))] #[cfg(feature = "net")] + ControlMessage::Ipv4Ttl(ttl) => ttl as *const _ as *const u8, + #[cfg(any(linux_android, freebsdlike, apple_targets, target_os = "haiku"))] + #[cfg(feature = "net")] ControlMessage::Ipv6HopLimit(limit) => limit as *const _ as *const u8, #[cfg(any(linux_android, target_os = "fuchsia"))] ControlMessage::RxqOvfl(drop_count) => { @@ -1378,6 +1387,11 @@ impl<'a> ControlMessage<'a> { ControlMessage::Ipv4SendSrcAddr(addr) => mem::size_of_val(addr), #[cfg(any(linux_android, freebsdlike, apple_targets, target_os = "haiku"))] #[cfg(feature = "net")] + ControlMessage::Ipv4Ttl(ttl) => { + mem::size_of_val(ttl) + }, + #[cfg(any(linux_android, freebsdlike, apple_targets, target_os = "haiku"))] + #[cfg(feature = "net")] ControlMessage::Ipv6HopLimit(limit) => { mem::size_of_val(limit) }, @@ -1426,6 +1440,9 @@ impl<'a> ControlMessage<'a> { ControlMessage::Ipv4SendSrcAddr(_) => libc::IPPROTO_IP, #[cfg(any(linux_android, freebsdlike, apple_targets, target_os = "haiku"))] #[cfg(feature = "net")] + ControlMessage::Ipv4Ttl(_) => libc::IPPROTO_IP, + #[cfg(any(linux_android, freebsdlike, apple_targets, target_os = "haiku"))] + #[cfg(feature = "net")] ControlMessage::Ipv6HopLimit(_) => libc::IPPROTO_IPV6, #[cfg(any(linux_android, target_os = "fuchsia"))] ControlMessage::RxqOvfl(_) => libc::SOL_SOCKET, @@ -1475,6 +1492,9 @@ impl<'a> ControlMessage<'a> { ControlMessage::Ipv4SendSrcAddr(_) => libc::IP_SENDSRCADDR, #[cfg(any(linux_android, freebsdlike, apple_targets, target_os = "haiku"))] #[cfg(feature = "net")] + ControlMessage::Ipv4Ttl(_) => libc::IP_TTL, + #[cfg(any(linux_android, freebsdlike, apple_targets, target_os = "haiku"))] + #[cfg(feature = "net")] ControlMessage::Ipv6HopLimit(_) => libc::IPV6_HOPLIMIT, #[cfg(any(linux_android, target_os = "fuchsia"))] ControlMessage::RxqOvfl(_) => { diff --git a/src/sys/socket/sockopt.rs b/src/sys/socket/sockopt.rs index 89e863373d..257f849c26 100644 --- a/src/sys/socket/sockopt.rs +++ b/src/sys/socket/sockopt.rs @@ -406,7 +406,7 @@ sockopt_impl!( #[cfg(feature = "net")] sockopt_impl!( #[cfg_attr(docsrs, doc(cfg(feature = "net")))] - /// Set the Type-Of-Service (TOS) field that is + /// Set or receivethe Type-Of-Service (TOS) field that is /// sent with every IP packet originating from this socket IpTos, Both, @@ -418,7 +418,7 @@ sockopt_impl!( #[cfg(feature = "net")] sockopt_impl!( #[cfg_attr(docsrs, doc(cfg(feature = "net")))] - /// Receive the Type-Of-Service (TOS) associated with incoming packets. + /// If enabled, the IP_TOS ancillary message is passed with incoming packets. IpRecvTos, Both, libc::IPPROTO_IP, @@ -440,7 +440,7 @@ sockopt_impl!( #[cfg(feature = "net")] sockopt_impl!( #[cfg_attr(docsrs, doc(cfg(feature = "net")))] - /// Receive the traffic class associated with incoming packets. + /// If enabled, the IPV6_TCLASS ancillary message is passed with incoming packets. Ipv6RecvTClass, Both, libc::IPPROTO_IPV6, diff --git a/test/sys/test_socket.rs b/test/sys/test_socket.rs index 62cd47939e..bd7148e75d 100644 --- a/test/sys/test_socket.rs +++ b/test/sys/test_socket.rs @@ -2635,6 +2635,8 @@ pub fn test_ipv6_tclass_udp() { ) .unwrap(); setsockopt(&rsock, sockopt::Ipv6RecvTClass, &true).unwrap(); + // This bind call with IPV6_RECVTCLASS fails on the Linux aarch64 target with EADDRNOTAVAIL, + // so the test will only run if `bind` does not return an error.. if bind(rsock.as_raw_fd(), &sock_addr).is_ok() { let sbuf = [0u8; 2048]; let iov1 = [std::io::IoSlice::new(&sbuf)]; From 13b2107a1d12ee5228cc30ec5cc29f0958db0715 Mon Sep 17 00:00:00 2001 From: Bigo <1781140+crisidev@users.noreply.github.com> Date: Fri, 14 Jun 2024 14:40:26 +0100 Subject: [PATCH 12/26] Run cargo fmt --- test/sys/test_socket.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/sys/test_socket.rs b/test/sys/test_socket.rs index bd7148e75d..69a319c7fd 100644 --- a/test/sys/test_socket.rs +++ b/test/sys/test_socket.rs @@ -2635,7 +2635,7 @@ pub fn test_ipv6_tclass_udp() { ) .unwrap(); setsockopt(&rsock, sockopt::Ipv6RecvTClass, &true).unwrap(); - // This bind call with IPV6_RECVTCLASS fails on the Linux aarch64 target with EADDRNOTAVAIL, + // This bind call with IPV6_RECVTCLASS fails on the Linux aarch64 target with EADDRNOTAVAIL, // so the test will only run if `bind` does not return an error.. if bind(rsock.as_raw_fd(), &sock_addr).is_ok() { let sbuf = [0u8; 2048]; From efeac24bfa6301d61489220043b2117e7b50ba10 Mon Sep 17 00:00:00 2001 From: Bigo <1781140+crisidev@users.noreply.github.com> Date: Sun, 21 Jul 2024 17:22:41 +0200 Subject: [PATCH 13/26] Address further comments from PR --- src/sys/socket/mod.rs | 47 ++++++++++++++++++++++++++++++--------- src/sys/socket/sockopt.rs | 2 +- 2 files changed, 38 insertions(+), 11 deletions(-) diff --git a/src/sys/socket/mod.rs b/src/sys/socket/mod.rs index 1997aa7ff3..30d3349725 100644 --- a/src/sys/socket/mod.rs +++ b/src/sys/socket/mod.rs @@ -772,7 +772,15 @@ pub enum ControlMessageOwned { /// Time-to-Live (TTL) header field of the incoming IPv4 packet. /// /// [Further reading](https://www.man7.org/linux/man-pages/man7/ip.7.html) - #[cfg(any(linux_android, target_os = "freebsd"))] + #[cfg(linux_android)] + #[cfg(feature = "net")] + #[cfg_attr(docsrs, doc(cfg(feature = "net")))] + Ipv4Ttl(i32), + + /// Time-to-Live (TTL) header field of the incoming IPv4 packet. + /// + /// [Further reading](https://datatracker.ietf.org/doc/html/rfc3542.html) + #[cfg(target_os = "freebsd")] #[cfg(feature = "net")] #[cfg_attr(docsrs, doc(cfg(feature = "net")))] Ipv4Ttl(u8), @@ -781,14 +789,20 @@ pub enum ControlMessageOwned { #[cfg(any(linux_android, target_os = "freebsd"))] #[cfg(feature = "net")] #[cfg_attr(docsrs, doc(cfg(feature = "net")))] - Ipv6HopLimit(u8), + Ipv6HopLimit(i32), /// Retrieve the DSCP (ToS) header field of the incoming IPv4 packet. - #[cfg(any(linux_android, target_os = "freebsd"))] + #[cfg(linux_android)] #[cfg(feature = "net")] #[cfg_attr(docsrs, doc(cfg(feature = "net")))] Ipv4Tos(i32), + /// Retrieve the DSCP (ToS) header field of the incoming IPv4 packet. + #[cfg(target_os = "freebsd")] + #[cfg(feature = "net")] + #[cfg_attr(docsrs, doc(cfg(feature = "net")))] + Ipv4Tos(u8), + /// Retrieve the DSCP (Traffic Class) header field of the incoming IPv6 packet. #[cfg(any(linux_android, target_os = "freebsd"))] #[cfg(feature = "net")] @@ -1013,7 +1027,13 @@ impl ControlMessageOwned { let content_type = unsafe { ptr::read_unaligned(p as *const u8) }; ControlMessageOwned::TlsGetRecordType(content_type.into()) }, - #[cfg(any(linux_android, target_os = "freebsd"))] + #[cfg(linux_android)] + #[cfg(feature = "net")] + (libc::IPPROTO_IP, libc::IP_TTL) => { + let ttl = unsafe { ptr::read_unaligned(p as *const i32) }; + ControlMessageOwned::Ipv4Ttl(ttl) + }, + #[cfg(target_os = "freebsd")] #[cfg(feature = "net")] (libc::IPPROTO_IP, libc::IP_RECVTTL) => { let ttl: u8 = unsafe { ptr::read_unaligned(p as *const u8) }; @@ -1022,15 +1042,21 @@ impl ControlMessageOwned { #[cfg(any(linux_android, target_os = "freebsd"))] #[cfg(feature = "net")] (libc::IPPROTO_IPV6, libc::IPV6_HOPLIMIT) => { - let ttl: u8 = unsafe { ptr::read_unaligned(p as *const u8) }; + let ttl = unsafe { ptr::read_unaligned(p as *const i32) }; ControlMessageOwned::Ipv6HopLimit(ttl) }, - #[cfg(any(linux_android, target_os = "freebsd"))] + #[cfg(linux_android)] #[cfg(feature = "net")] - (libc::IPPROTO_IP, libc::IP_RECVTOS) => { + (libc::IPPROTO_IP, libc::IP_TOS) => { let tos = unsafe { ptr::read_unaligned(p as *const i32) }; ControlMessageOwned::Ipv4Tos(tos) }, + #[cfg(target_os = "freebsd")] + #[cfg(feature = "net")] + (libc::IPPROTO_IP, libc::IP_RECVTOS) => { + let tos = unsafe { ptr::read_unaligned(p as *const u8) }; + ControlMessageOwned::Ipv4Tos(tos) + }, #[cfg(any(linux_android, target_os = "freebsd"))] #[cfg(feature = "net")] (libc::IPPROTO_IPV6, libc::IPV6_TCLASS) => { @@ -1193,10 +1219,10 @@ pub enum ControlMessage<'a> { #[cfg_attr(docsrs, doc(cfg(feature = "net")))] Ipv6HopLimit(&'a libc::c_int), - /// SO_RXQ_OVFL indicates that an unsigned 32 bit value - /// ancilliary msg (cmsg) should be attached to recieved + /// SO_RXQ_OVFL indicates that an unsigned 32 bit value + /// ancillary msg (cmsg) should be attached to received /// skbs indicating the number of packets dropped by the - /// socket between the last recieved packet and this + /// socket between the last received packet and this /// received packet. #[cfg(any(linux_android, target_os = "fuchsia"))] RxqOvfl(&'a u32), @@ -1214,6 +1240,7 @@ pub enum ControlMessage<'a> { /// Further information can be found [here](https://en.wikipedia.org/wiki/Differentiated_services). #[cfg(target_os = "linux")] IpTos(&'a i32), + /// Configure DSCP / IP TOS for outgoing v6 packets. /// /// Further information can be found [here](https://en.wikipedia.org/wiki/Differentiated_services). diff --git a/src/sys/socket/sockopt.rs b/src/sys/socket/sockopt.rs index 8fda4d7389..ec83eacc7a 100644 --- a/src/sys/socket/sockopt.rs +++ b/src/sys/socket/sockopt.rs @@ -406,7 +406,7 @@ sockopt_impl!( #[cfg(feature = "net")] sockopt_impl!( #[cfg_attr(docsrs, doc(cfg(feature = "net")))] - /// Set or receivethe Type-Of-Service (TOS) field that is + /// Set or receive the Type-Of-Service (TOS) field that is /// sent with every IP packet originating from this socket IpTos, Both, From 3c1eed79e5d2878543dcbf73d300d6566a92c90c Mon Sep 17 00:00:00 2001 From: Bigo <1781140+crisidev@users.noreply.github.com> Date: Sun, 21 Jul 2024 17:31:51 +0200 Subject: [PATCH 14/26] Run tests under qemu --- test/sys/test_socket.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/sys/test_socket.rs b/test/sys/test_socket.rs index 593b224f79..3af6a33c52 100644 --- a/test/sys/test_socket.rs +++ b/test/sys/test_socket.rs @@ -2579,7 +2579,6 @@ fn test_recvmsg_rxq_ovfl() { #[cfg(target_os = "linux")] #[cfg(feature = "net")] -#[cfg_attr(qemu, ignore)] #[test] pub fn test_ip_tos_udp() { use nix::sys::socket::ControlMessageOwned; @@ -2649,7 +2648,6 @@ pub fn test_ip_tos_udp() { #[cfg(target_os = "linux")] #[cfg(feature = "net")] -#[cfg_attr(qemu, ignore)] #[test] pub fn test_ipv6_tclass_udp() { use nix::sys::socket::ControlMessageOwned; From 4946d5f0b0f4a2d0857ad6a195ba8892d508b0e3 Mon Sep 17 00:00:00 2001 From: Bigo <1781140+crisidev@users.noreply.github.com> Date: Sun, 21 Jul 2024 17:41:52 +0200 Subject: [PATCH 15/26] Use libc from git --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 8382b01c3a..0629d095c3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,7 +28,7 @@ targets = [ ] [dependencies] -libc = { version = "0.2.155", features = ["extra_traits"] } +libc = { git = "https://github.com/rust-lang/libc", branch = "libc-0.2", features = ["extra_traits"] } bitflags = "2.3.3" cfg-if = "1.0" pin-utils = { version = "0.1.0", optional = true } From 07691e71275b1eb04283c8f04ebd03ed5deef197 Mon Sep 17 00:00:00 2001 From: Bigo <1781140+crisidev@users.noreply.github.com> Date: Sun, 21 Jul 2024 17:57:24 +0200 Subject: [PATCH 16/26] Disable qemu IPTOS / IPV6TCLASS tests on mips --- test/sys/test_socket.rs | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/test/sys/test_socket.rs b/test/sys/test_socket.rs index 3af6a33c52..cd3be53194 100644 --- a/test/sys/test_socket.rs +++ b/test/sys/test_socket.rs @@ -2579,6 +2579,19 @@ fn test_recvmsg_rxq_ovfl() { #[cfg(target_os = "linux")] #[cfg(feature = "net")] +// qemu doesn't seem to be emulating this correctly in these architectures +#[cfg_attr( + all( + qemu, + any( + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6", + ) + ), + ignore +)] #[test] pub fn test_ip_tos_udp() { use nix::sys::socket::ControlMessageOwned; @@ -2647,6 +2660,19 @@ pub fn test_ip_tos_udp() { } #[cfg(target_os = "linux")] +// qemu doesn't seem to be emulating this correctly in these architectures +#[cfg_attr( + all( + qemu, + any( + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6", + ) + ), + ignore +)] #[cfg(feature = "net")] #[test] pub fn test_ipv6_tclass_udp() { From 0c48b0303bf63422c30d37e6ec37e0d9e46a1fa5 Mon Sep 17 00:00:00 2001 From: Matteo Bigoi <1781140+crisidev@users.noreply.github.com> Date: Mon, 22 Jul 2024 10:34:47 +0200 Subject: [PATCH 17/26] Apply suggestions from code review Co-authored-by: SteveLauC --- src/sys/socket/mod.rs | 36 ++++++++++++++++++------------------ src/sys/socket/sockopt.rs | 8 ++++---- test/sys/test_socket.rs | 2 +- test/sys/test_sockopt.rs | 8 ++++---- 4 files changed, 27 insertions(+), 27 deletions(-) diff --git a/src/sys/socket/mod.rs b/src/sys/socket/mod.rs index 30d3349725..3f00575edc 100644 --- a/src/sys/socket/mod.rs +++ b/src/sys/socket/mod.rs @@ -795,7 +795,7 @@ pub enum ControlMessageOwned { #[cfg(linux_android)] #[cfg(feature = "net")] #[cfg_attr(docsrs, doc(cfg(feature = "net")))] - Ipv4Tos(i32), + Ipv4Tos(u8), /// Retrieve the DSCP (ToS) header field of the incoming IPv4 packet. #[cfg(target_os = "freebsd")] @@ -1048,7 +1048,7 @@ impl ControlMessageOwned { #[cfg(linux_android)] #[cfg(feature = "net")] (libc::IPPROTO_IP, libc::IP_TOS) => { - let tos = unsafe { ptr::read_unaligned(p as *const i32) }; + let tos = unsafe { ptr::read_unaligned(p as *const u8) }; ControlMessageOwned::Ipv4Tos(tos) }, #[cfg(target_os = "freebsd")] @@ -1200,8 +1200,8 @@ pub enum ControlMessage<'a> { #[cfg_attr(docsrs, doc(cfg(feature = "net")))] Ipv4SendSrcAddr(&'a libc::in_addr), - /// Configure the Time-to-Live for v4 traffic traffic. - #[cfg(any(linux_android, freebsdlike, apple_targets, target_os = "haiku"))] + /// Configure the Time-to-Live for v4 traffic. + #[cfg(any(linux_android, target_os = "freebsd"))] #[cfg(feature = "net")] #[cfg_attr(docsrs, doc(cfg(feature = "net")))] Ipv4Ttl(&'a libc::c_int), @@ -1238,13 +1238,13 @@ pub enum ControlMessage<'a> { /// Configure DSCP / IP TOS for outgoing v4 packets. /// /// Further information can be found [here](https://en.wikipedia.org/wiki/Differentiated_services). - #[cfg(target_os = "linux")] - IpTos(&'a i32), + #[cfg(any(linux_android, target_os = "freebsd"))] + IpTos(&'a u8), /// Configure DSCP / IP TOS for outgoing v6 packets. /// /// Further information can be found [here](https://en.wikipedia.org/wiki/Differentiated_services). - #[cfg(target_os = "linux")] + #[cfg(any(linux_android, target_os = "freebsd"))] Ipv6TClass(&'a i32), } @@ -1339,7 +1339,7 @@ impl<'a> ControlMessage<'a> { #[cfg(any(freebsdlike, netbsdlike))] #[cfg(feature = "net")] ControlMessage::Ipv4SendSrcAddr(addr) => addr as *const _ as *const u8, - #[cfg(any(linux_android, freebsdlike, apple_targets, target_os = "haiku"))] + #[cfg(any(linux_android, target_os = "freebsd"))] #[cfg(feature = "net")] ControlMessage::Ipv4Ttl(ttl) => ttl as *const _ as *const u8, #[cfg(any(linux_android, freebsdlike, apple_targets, target_os = "haiku"))] @@ -1353,11 +1353,11 @@ impl<'a> ControlMessage<'a> { ControlMessage::TxTime(tx_time) => { tx_time as *const _ as *const u8 }, - #[cfg(target_os = "linux")] + #[cfg(any(linux_android, target_os = "freebsd"))] ControlMessage::IpTos(tos) => { tos as *const _ as *const u8 }, - #[cfg(target_os = "linux")] + #[cfg(any(linux_android, target_os = "freebsd"))] ControlMessage::Ipv6TClass(tclass) => { tclass as *const _ as *const u8 }, @@ -1412,7 +1412,7 @@ impl<'a> ControlMessage<'a> { #[cfg(any(freebsdlike, netbsdlike))] #[cfg(feature = "net")] ControlMessage::Ipv4SendSrcAddr(addr) => mem::size_of_val(addr), - #[cfg(any(linux_android, freebsdlike, apple_targets, target_os = "haiku"))] + #[cfg(any(linux_android, target_os = "freebsd"))] #[cfg(feature = "net")] ControlMessage::Ipv4Ttl(ttl) => { mem::size_of_val(ttl) @@ -1430,11 +1430,11 @@ impl<'a> ControlMessage<'a> { ControlMessage::TxTime(tx_time) => { mem::size_of_val(tx_time) }, - #[cfg(target_os = "linux")] + #[cfg(any(linux_android, target_os = "freebsd"))] ControlMessage::IpTos(tos) => { mem::size_of_val(tos) }, - #[cfg(target_os = "linux")] + #[cfg(any(linux_android, target_os = "freebsd"))] ControlMessage::Ipv6TClass(tclass) => { mem::size_of_val(tclass) }, @@ -1465,7 +1465,7 @@ impl<'a> ControlMessage<'a> { #[cfg(any(freebsdlike, netbsdlike))] #[cfg(feature = "net")] ControlMessage::Ipv4SendSrcAddr(_) => libc::IPPROTO_IP, - #[cfg(any(linux_android, freebsdlike, apple_targets, target_os = "haiku"))] + #[cfg(any(linux_android, target_os = "freebsd"))] #[cfg(feature = "net")] ControlMessage::Ipv4Ttl(_) => libc::IPPROTO_IP, #[cfg(any(linux_android, freebsdlike, apple_targets, target_os = "haiku"))] @@ -1475,9 +1475,9 @@ impl<'a> ControlMessage<'a> { ControlMessage::RxqOvfl(_) => libc::SOL_SOCKET, #[cfg(target_os = "linux")] ControlMessage::TxTime(_) => libc::SOL_SOCKET, - #[cfg(target_os = "linux")] + #[cfg(any(linux_android, target_os = "freebsd"))] ControlMessage::IpTos(_) => libc::IPPROTO_IP, - #[cfg(target_os = "linux")] + #[cfg(any(linux_android, target_os = "freebsd"))] ControlMessage::Ipv6TClass(_) => libc::IPPROTO_IPV6, } } @@ -1517,7 +1517,7 @@ impl<'a> ControlMessage<'a> { #[cfg(any(freebsdlike, netbsdlike))] #[cfg(feature = "net")] ControlMessage::Ipv4SendSrcAddr(_) => libc::IP_SENDSRCADDR, - #[cfg(any(linux_android, freebsdlike, apple_targets, target_os = "haiku"))] + #[cfg(any(linux_android, target_os = "freebsd"))] #[cfg(feature = "net")] ControlMessage::Ipv4Ttl(_) => libc::IP_TTL, #[cfg(any(linux_android, freebsdlike, apple_targets, target_os = "haiku"))] @@ -1535,7 +1535,7 @@ impl<'a> ControlMessage<'a> { ControlMessage::IpTos(_) => { libc::IP_TOS }, - #[cfg(target_os = "linux")] + #[cfg(any(linux_android, target_os = "freebsd"))] ControlMessage::Ipv6TClass(_) => { libc::IPV6_TCLASS }, diff --git a/src/sys/socket/sockopt.rs b/src/sys/socket/sockopt.rs index ec83eacc7a..a77224674c 100644 --- a/src/sys/socket/sockopt.rs +++ b/src/sys/socket/sockopt.rs @@ -425,7 +425,7 @@ sockopt_impl!( libc::IP_RECVTOS, bool ); -#[cfg(target_os = "linux")] +#[cfg(any(linux_android, target_os = "freebsd"))] #[cfg(feature = "net")] sockopt_impl!( #[cfg_attr(docsrs, doc(cfg(feature = "net")))] @@ -436,7 +436,7 @@ sockopt_impl!( libc::IPV6_TCLASS, libc::c_int ); -#[cfg(target_os = "linux")] +#[cfg(any(linux_android, target_os = "freebsd"))] #[cfg(feature = "net")] sockopt_impl!( #[cfg_attr(docsrs, doc(cfg(feature = "net")))] @@ -1080,7 +1080,7 @@ sockopt_impl!( libc::IP_TTL, libc::c_int ); -#[cfg(target_os = "linux")] +#[cfg(any(linux_android, target_os = "freebsd"))] #[cfg(feature = "net")] sockopt_impl!( /// Enables a receiving socket to retrieve the Time-to-Live (TTL) field @@ -1100,7 +1100,7 @@ sockopt_impl!( libc::IPV6_UNICAST_HOPS, libc::c_int ); -#[cfg(target_os = "linux")] +#[cfg(any(linux_android, target_os = "freebsd"))] #[cfg(feature = "net")] sockopt_impl!( /// Enables a receiving socket to retrieve the Hop Limit field diff --git a/test/sys/test_socket.rs b/test/sys/test_socket.rs index cd3be53194..bb69646ad4 100644 --- a/test/sys/test_socket.rs +++ b/test/sys/test_socket.rs @@ -2577,7 +2577,7 @@ fn test_recvmsg_rxq_ovfl() { assert_eq!(drop_counter, 1); } -#[cfg(target_os = "linux")] +#[cfg(any(linux_android, target_os = "freebsd"))] #[cfg(feature = "net")] // qemu doesn't seem to be emulating this correctly in these architectures #[cfg_attr( diff --git a/test/sys/test_sockopt.rs b/test/sys/test_sockopt.rs index 9334e68982..e678d0f780 100644 --- a/test/sys/test_sockopt.rs +++ b/test/sys/test_sockopt.rs @@ -879,7 +879,7 @@ fn test_reuseport_lb() { } #[test] -#[cfg(target_os = "linux")] +#[cfg(any(linux_android, target_os = "freebsd"))] fn test_ipv4_recv_ttl_opts() { let fd = socket( AddressFamily::Inet, @@ -907,7 +907,7 @@ fn test_ipv4_recv_ttl_opts() { } #[test] -#[cfg(target_os = "linux")] +#[cfg(any(linux_android, target_os = "freebsd"))] fn test_ipv6_recv_hop_limit_opts() { let fd = socket( AddressFamily::Inet6, @@ -938,7 +938,7 @@ fn test_ipv6_recv_hop_limit_opts() { } #[test] -#[cfg(target_os = "linux")] +#[cfg(any(linux_android, target_os = "freebsd"))] fn test_ipv4_recv_tos_opts() { let fd = socket( AddressFamily::Inet, @@ -966,7 +966,7 @@ fn test_ipv4_recv_tos_opts() { } #[test] -#[cfg(target_os = "linux")] +#[cfg(any(linux_android, target_os = "freebsd"))] fn test_ipv6_recv_traffic_class_opts() { let fd = socket( AddressFamily::Inet6, From cfb4fde88fe85595b7afac3891f807ca92d5e913 Mon Sep 17 00:00:00 2001 From: Bigo <1781140+crisidev@users.noreply.github.com> Date: Mon, 22 Jul 2024 13:21:29 +0200 Subject: [PATCH 18/26] Fix more code review suggestions --- src/sys/socket/mod.rs | 41 ++++++++++++++++++++++++++++++--------- src/sys/socket/sockopt.rs | 2 +- test/sys/test_socket.rs | 2 +- 3 files changed, 34 insertions(+), 11 deletions(-) diff --git a/src/sys/socket/mod.rs b/src/sys/socket/mod.rs index 3f00575edc..2de79c4e8e 100644 --- a/src/sys/socket/mod.rs +++ b/src/sys/socket/mod.rs @@ -786,6 +786,9 @@ pub enum ControlMessageOwned { Ipv4Ttl(u8), /// Hop Limit header field of the incoming IPv6 packet. + /// + /// [Further reading for Linux](https://www.man7.org/linux/man-pages/man7/ip.7.html) + /// [Further reading for FreeBSD](https://datatracker.ietf.org/doc/html/rfc3542.html) #[cfg(any(linux_android, target_os = "freebsd"))] #[cfg(feature = "net")] #[cfg_attr(docsrs, doc(cfg(feature = "net")))] @@ -1201,11 +1204,17 @@ pub enum ControlMessage<'a> { Ipv4SendSrcAddr(&'a libc::in_addr), /// Configure the Time-to-Live for v4 traffic. - #[cfg(any(linux_android, target_os = "freebsd"))] + #[cfg(linux_android)] #[cfg(feature = "net")] #[cfg_attr(docsrs, doc(cfg(feature = "net")))] Ipv4Ttl(&'a libc::c_int), + /// Configure the Time-to-Live for v4 traffic. + #[cfg(target_os = "freebsd")] + #[cfg(feature = "net")] + #[cfg_attr(docsrs, doc(cfg(feature = "net")))] + Ipv4Ttl(&'a libc::c_uchar), + /// Configure the hop limit for v6 multicast traffic. /// /// Set the IPv6 hop limit for this message. The argument is an integer @@ -1239,12 +1248,16 @@ pub enum ControlMessage<'a> { /// /// Further information can be found [here](https://en.wikipedia.org/wiki/Differentiated_services). #[cfg(any(linux_android, target_os = "freebsd"))] - IpTos(&'a u8), + #[cfg(feature = "net")] + #[cfg_attr(docsrs, doc(cfg(feature = "net")))] + Ipv4Tos(&'a u8), /// Configure DSCP / IP TOS for outgoing v6 packets. /// /// Further information can be found [here](https://en.wikipedia.org/wiki/Differentiated_services). #[cfg(any(linux_android, target_os = "freebsd"))] + #[cfg(feature = "net")] + #[cfg_attr(docsrs, doc(cfg(feature = "net")))] Ipv6TClass(&'a i32), } @@ -1354,8 +1367,8 @@ impl<'a> ControlMessage<'a> { tx_time as *const _ as *const u8 }, #[cfg(any(linux_android, target_os = "freebsd"))] - ControlMessage::IpTos(tos) => { - tos as *const _ as *const u8 + ControlMessage::Ipv4Tos(tos) => { + tos as *const _ }, #[cfg(any(linux_android, target_os = "freebsd"))] ControlMessage::Ipv6TClass(tclass) => { @@ -1431,7 +1444,7 @@ impl<'a> ControlMessage<'a> { mem::size_of_val(tx_time) }, #[cfg(any(linux_android, target_os = "freebsd"))] - ControlMessage::IpTos(tos) => { + ControlMessage::Ipv4Tos(tos) => { mem::size_of_val(tos) }, #[cfg(any(linux_android, target_os = "freebsd"))] @@ -1476,7 +1489,7 @@ impl<'a> ControlMessage<'a> { #[cfg(target_os = "linux")] ControlMessage::TxTime(_) => libc::SOL_SOCKET, #[cfg(any(linux_android, target_os = "freebsd"))] - ControlMessage::IpTos(_) => libc::IPPROTO_IP, + ControlMessage::Ipv4Tos(_) => libc::IPPROTO_IP, #[cfg(any(linux_android, target_os = "freebsd"))] ControlMessage::Ipv6TClass(_) => libc::IPPROTO_IPV6, } @@ -1517,9 +1530,12 @@ impl<'a> ControlMessage<'a> { #[cfg(any(freebsdlike, netbsdlike))] #[cfg(feature = "net")] ControlMessage::Ipv4SendSrcAddr(_) => libc::IP_SENDSRCADDR, - #[cfg(any(linux_android, target_os = "freebsd"))] + #[cfg(linux_android)] #[cfg(feature = "net")] ControlMessage::Ipv4Ttl(_) => libc::IP_TTL, + #[cfg(target_os = "freebsd")] + #[cfg(feature = "net")] + ControlMessage::Ipv4Ttl(_) => libc::IP_RECVTTL, #[cfg(any(linux_android, freebsdlike, apple_targets, target_os = "haiku"))] #[cfg(feature = "net")] ControlMessage::Ipv6HopLimit(_) => libc::IPV6_HOPLIMIT, @@ -1531,11 +1547,18 @@ impl<'a> ControlMessage<'a> { ControlMessage::TxTime(_) => { libc::SCM_TXTIME }, - #[cfg(target_os = "linux")] - ControlMessage::IpTos(_) => { + #[cfg(linux_android)] + #[cfg(feature = "net")] + ControlMessage::Ipv4Tos(_) => { libc::IP_TOS }, + #[cfg(target_os = "freebsd")] + #[cfg(feature = "net")] + ControlMessage::Ipv4Tos(_) => { + libc::IP_RECVTOS + }, #[cfg(any(linux_android, target_os = "freebsd"))] + #[cfg(feature = "net")] ControlMessage::Ipv6TClass(_) => { libc::IPV6_TCLASS }, diff --git a/src/sys/socket/sockopt.rs b/src/sys/socket/sockopt.rs index a77224674c..93c6a338c8 100644 --- a/src/sys/socket/sockopt.rs +++ b/src/sys/socket/sockopt.rs @@ -414,7 +414,7 @@ sockopt_impl!( libc::IP_TOS, libc::c_int ); -#[cfg(target_os = "linux")] +#[cfg(any(linux_android, target_os = "freebsd"))] #[cfg(feature = "net")] sockopt_impl!( #[cfg_attr(docsrs, doc(cfg(feature = "net")))] diff --git a/test/sys/test_socket.rs b/test/sys/test_socket.rs index bb69646ad4..337a4b311e 100644 --- a/test/sys/test_socket.rs +++ b/test/sys/test_socket.rs @@ -2628,7 +2628,7 @@ pub fn test_ip_tos_udp() { setsockopt(&ssock, sockopt::IpTos, &20).unwrap(); // Test the sendmsg control message and check the received packet has the same TOS. - let scmsg = ControlMessage::IpTos(&20); + let scmsg = ControlMessage::Ipv4Tos(&20); sendmsg( ssock.as_raw_fd(), &iov1, From 1be4b842c43f88f4f3d46e61e423faa985716875 Mon Sep 17 00:00:00 2001 From: Bigo <1781140+crisidev@users.noreply.github.com> Date: Mon, 22 Jul 2024 13:32:02 +0200 Subject: [PATCH 19/26] Fix missing renames in tests --- src/sys/socket/mod.rs | 8 +++++++- src/sys/socket/sockopt.rs | 4 ++-- test/sys/test_socket.rs | 2 +- test/sys/test_sockopt.rs | 4 ++-- 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/sys/socket/mod.rs b/src/sys/socket/mod.rs index 2de79c4e8e..f7e408b21e 100644 --- a/src/sys/socket/mod.rs +++ b/src/sys/socket/mod.rs @@ -1252,7 +1252,7 @@ pub enum ControlMessage<'a> { #[cfg_attr(docsrs, doc(cfg(feature = "net")))] Ipv4Tos(&'a u8), - /// Configure DSCP / IP TOS for outgoing v6 packets. + /// Configure DSCP / IPv6 TCLASS for outgoing v6 packets. /// /// Further information can be found [here](https://en.wikipedia.org/wiki/Differentiated_services). #[cfg(any(linux_android, target_os = "freebsd"))] @@ -1367,10 +1367,12 @@ impl<'a> ControlMessage<'a> { tx_time as *const _ as *const u8 }, #[cfg(any(linux_android, target_os = "freebsd"))] + #[cfg(feature = "net")] ControlMessage::Ipv4Tos(tos) => { tos as *const _ }, #[cfg(any(linux_android, target_os = "freebsd"))] + #[cfg(feature = "net")] ControlMessage::Ipv6TClass(tclass) => { tclass as *const _ as *const u8 }, @@ -1444,10 +1446,12 @@ impl<'a> ControlMessage<'a> { mem::size_of_val(tx_time) }, #[cfg(any(linux_android, target_os = "freebsd"))] + #[cfg(feature = "net")] ControlMessage::Ipv4Tos(tos) => { mem::size_of_val(tos) }, #[cfg(any(linux_android, target_os = "freebsd"))] + #[cfg(feature = "net")] ControlMessage::Ipv6TClass(tclass) => { mem::size_of_val(tclass) }, @@ -1489,8 +1493,10 @@ impl<'a> ControlMessage<'a> { #[cfg(target_os = "linux")] ControlMessage::TxTime(_) => libc::SOL_SOCKET, #[cfg(any(linux_android, target_os = "freebsd"))] + #[cfg(feature = "net")] ControlMessage::Ipv4Tos(_) => libc::IPPROTO_IP, #[cfg(any(linux_android, target_os = "freebsd"))] + #[cfg(feature = "net")] ControlMessage::Ipv6TClass(_) => libc::IPPROTO_IPV6, } } diff --git a/src/sys/socket/sockopt.rs b/src/sys/socket/sockopt.rs index 93c6a338c8..7a88cff2d7 100644 --- a/src/sys/socket/sockopt.rs +++ b/src/sys/socket/sockopt.rs @@ -402,13 +402,13 @@ sockopt_impl!( libc::SO_PRIORITY, libc::c_int ); -#[cfg(target_os = "linux")] +#[cfg(any(linux_android, target_os = "freebsd"))] #[cfg(feature = "net")] sockopt_impl!( #[cfg_attr(docsrs, doc(cfg(feature = "net")))] /// Set or receive the Type-Of-Service (TOS) field that is /// sent with every IP packet originating from this socket - IpTos, + Ipv4Tos, Both, libc::IPPROTO_IP, libc::IP_TOS, diff --git a/test/sys/test_socket.rs b/test/sys/test_socket.rs index 337a4b311e..7b00330d40 100644 --- a/test/sys/test_socket.rs +++ b/test/sys/test_socket.rs @@ -2625,7 +2625,7 @@ pub fn test_ip_tos_udp() { None, ) .expect("send socket failed"); - setsockopt(&ssock, sockopt::IpTos, &20).unwrap(); + setsockopt(&ssock, sockopt::Ipv4Tos, &20).unwrap(); // Test the sendmsg control message and check the received packet has the same TOS. let scmsg = ControlMessage::Ipv4Tos(&20); diff --git a/test/sys/test_sockopt.rs b/test/sys/test_sockopt.rs index e678d0f780..6884674b48 100644 --- a/test/sys/test_sockopt.rs +++ b/test/sys/test_sockopt.rs @@ -479,8 +479,8 @@ fn test_ip_tos() { ) .unwrap(); let tos = 0x80; // CS4 - setsockopt(&fd, sockopt::IpTos, &tos).unwrap(); - assert_eq!(getsockopt(&fd, sockopt::IpTos).unwrap(), tos); + setsockopt(&fd, sockopt::Ipv4Tos, &tos).unwrap(); + assert_eq!(getsockopt(&fd, sockopt::Ipv4Tos).unwrap(), tos); } #[test] From dffe2592fea80ddda72b738eab29defe41ac7ce9 Mon Sep 17 00:00:00 2001 From: Bigo <1781140+crisidev@users.noreply.github.com> Date: Mon, 22 Jul 2024 15:36:04 +0200 Subject: [PATCH 20/26] Testing --- src/sys/socket/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sys/socket/mod.rs b/src/sys/socket/mod.rs index f7e408b21e..1fea9c8305 100644 --- a/src/sys/socket/mod.rs +++ b/src/sys/socket/mod.rs @@ -1561,7 +1561,7 @@ impl<'a> ControlMessage<'a> { #[cfg(target_os = "freebsd")] #[cfg(feature = "net")] ControlMessage::Ipv4Tos(_) => { - libc::IP_RECVTOS + libc::IP_TOS }, #[cfg(any(linux_android, target_os = "freebsd"))] #[cfg(feature = "net")] From 133795301567cabb1deb72442bf24062f83dfeaf Mon Sep 17 00:00:00 2001 From: Bigo <1781140+crisidev@users.noreply.github.com> Date: Mon, 22 Jul 2024 15:48:13 +0200 Subject: [PATCH 21/26] Fixes --- src/sys/socket/mod.rs | 23 +++-------------------- 1 file changed, 3 insertions(+), 20 deletions(-) diff --git a/src/sys/socket/mod.rs b/src/sys/socket/mod.rs index 1fea9c8305..b167f959c9 100644 --- a/src/sys/socket/mod.rs +++ b/src/sys/socket/mod.rs @@ -795,13 +795,7 @@ pub enum ControlMessageOwned { Ipv6HopLimit(i32), /// Retrieve the DSCP (ToS) header field of the incoming IPv4 packet. - #[cfg(linux_android)] - #[cfg(feature = "net")] - #[cfg_attr(docsrs, doc(cfg(feature = "net")))] - Ipv4Tos(u8), - - /// Retrieve the DSCP (ToS) header field of the incoming IPv4 packet. - #[cfg(target_os = "freebsd")] + #[cfg(any(linux_android, target_os = "freebsd"))] #[cfg(feature = "net")] #[cfg_attr(docsrs, doc(cfg(feature = "net")))] Ipv4Tos(u8), @@ -1048,18 +1042,12 @@ impl ControlMessageOwned { let ttl = unsafe { ptr::read_unaligned(p as *const i32) }; ControlMessageOwned::Ipv6HopLimit(ttl) }, - #[cfg(linux_android)] + #[cfg(any(linux_android, target_os = "freebsd"))] #[cfg(feature = "net")] (libc::IPPROTO_IP, libc::IP_TOS) => { let tos = unsafe { ptr::read_unaligned(p as *const u8) }; ControlMessageOwned::Ipv4Tos(tos) }, - #[cfg(target_os = "freebsd")] - #[cfg(feature = "net")] - (libc::IPPROTO_IP, libc::IP_RECVTOS) => { - let tos = unsafe { ptr::read_unaligned(p as *const u8) }; - ControlMessageOwned::Ipv4Tos(tos) - }, #[cfg(any(linux_android, target_os = "freebsd"))] #[cfg(feature = "net")] (libc::IPPROTO_IPV6, libc::IPV6_TCLASS) => { @@ -1553,12 +1541,7 @@ impl<'a> ControlMessage<'a> { ControlMessage::TxTime(_) => { libc::SCM_TXTIME }, - #[cfg(linux_android)] - #[cfg(feature = "net")] - ControlMessage::Ipv4Tos(_) => { - libc::IP_TOS - }, - #[cfg(target_os = "freebsd")] + #[cfg(any(linux_android, target_os = "freebsd"))] #[cfg(feature = "net")] ControlMessage::Ipv4Tos(_) => { libc::IP_TOS From 72c00ee722aa1ee378975ca34ba8e271159e2a0f Mon Sep 17 00:00:00 2001 From: Bigo <1781140+crisidev@users.noreply.github.com> Date: Mon, 22 Jul 2024 16:27:45 +0200 Subject: [PATCH 22/26] Fix freebsd --- src/sys/socket/mod.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/sys/socket/mod.rs b/src/sys/socket/mod.rs index b167f959c9..ac42f7dfcd 100644 --- a/src/sys/socket/mod.rs +++ b/src/sys/socket/mod.rs @@ -1042,12 +1042,18 @@ impl ControlMessageOwned { let ttl = unsafe { ptr::read_unaligned(p as *const i32) }; ControlMessageOwned::Ipv6HopLimit(ttl) }, - #[cfg(any(linux_android, target_os = "freebsd"))] + #[cfg(linux_android)] #[cfg(feature = "net")] (libc::IPPROTO_IP, libc::IP_TOS) => { let tos = unsafe { ptr::read_unaligned(p as *const u8) }; ControlMessageOwned::Ipv4Tos(tos) }, + #[cfg(target_os = "freebsd")] + #[cfg(feature = "net")] + (libc::IPPROTO_IP, libc::IP_RECVTOS) => { + let tos = unsafe { ptr::read_unaligned(p as *const u8) }; + ControlMessageOwned::Ipv4Tos(tos) + }, #[cfg(any(linux_android, target_os = "freebsd"))] #[cfg(feature = "net")] (libc::IPPROTO_IPV6, libc::IPV6_TCLASS) => { From 684e6b232f88a4967f82579043cbc8a21aed566d Mon Sep 17 00:00:00 2001 From: Bigo <1781140+crisidev@users.noreply.github.com> Date: Mon, 22 Jul 2024 17:06:00 +0200 Subject: [PATCH 23/26] Trigger CI again --- src/sys/socket/mod.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/sys/socket/mod.rs b/src/sys/socket/mod.rs index ac42f7dfcd..802bf46c6a 100644 --- a/src/sys/socket/mod.rs +++ b/src/sys/socket/mod.rs @@ -2456,4 +2456,3 @@ pub fn shutdown(df: RawFd, how: Shutdown) -> Result<()> { Errno::result(shutdown(df, how)).map(drop) } } - From 349613c25d8eabeb5f51e64d739e5fc5eb8eafc4 Mon Sep 17 00:00:00 2001 From: Bigo <1781140+crisidev@users.noreply.github.com> Date: Mon, 22 Jul 2024 17:10:42 +0200 Subject: [PATCH 24/26] Trigger CI again --- src/sys/socket/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sys/socket/mod.rs b/src/sys/socket/mod.rs index 802bf46c6a..ac42f7dfcd 100644 --- a/src/sys/socket/mod.rs +++ b/src/sys/socket/mod.rs @@ -2456,3 +2456,4 @@ pub fn shutdown(df: RawFd, how: Shutdown) -> Result<()> { Errno::result(shutdown(df, how)).map(drop) } } + From c842aa72668f1fe4de3208077fd1a2ad931f15d3 Mon Sep 17 00:00:00 2001 From: Bigo <1781140+crisidev@users.noreply.github.com> Date: Mon, 22 Jul 2024 17:33:18 +0200 Subject: [PATCH 25/26] Use the same control message in linux and freebsd for ipv4ttl --- src/sys/socket/mod.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/sys/socket/mod.rs b/src/sys/socket/mod.rs index ac42f7dfcd..bc49f7897a 100644 --- a/src/sys/socket/mod.rs +++ b/src/sys/socket/mod.rs @@ -1530,12 +1530,9 @@ impl<'a> ControlMessage<'a> { #[cfg(any(freebsdlike, netbsdlike))] #[cfg(feature = "net")] ControlMessage::Ipv4SendSrcAddr(_) => libc::IP_SENDSRCADDR, - #[cfg(linux_android)] + #[cfg(any(linux_android, target_os = "freebsd"))] #[cfg(feature = "net")] ControlMessage::Ipv4Ttl(_) => libc::IP_TTL, - #[cfg(target_os = "freebsd")] - #[cfg(feature = "net")] - ControlMessage::Ipv4Ttl(_) => libc::IP_RECVTTL, #[cfg(any(linux_android, freebsdlike, apple_targets, target_os = "haiku"))] #[cfg(feature = "net")] ControlMessage::Ipv6HopLimit(_) => libc::IPV6_HOPLIMIT, From 7fd1b3d89aa4c187f36fc61281caf3c2f93a900b Mon Sep 17 00:00:00 2001 From: SteveLauC Date: Tue, 23 Jul 2024 07:25:29 +0800 Subject: [PATCH 26/26] test: remove a println --- test/sys/test_socket.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/test/sys/test_socket.rs b/test/sys/test_socket.rs index 7b00330d40..afe5629142 100644 --- a/test/sys/test_socket.rs +++ b/test/sys/test_socket.rs @@ -2651,7 +2651,6 @@ pub fn test_ip_tos_udp() { ) .unwrap(); for c in recv.cmsgs().unwrap() { - println!("CMSG: {c:?}"); if let ControlMessageOwned::Ipv4Tos(t) = c { tc = Some(t); }