-
Notifications
You must be signed in to change notification settings - Fork 649
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: add support for DSCP and TTL / Hop Limit #2425
base: master
Are you sure you want to change the base?
Conversation
* 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 <[email protected]>
src/sys/socket/mod.rs
Outdated
@@ -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) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On FreeBSD (and other BSDs, maybe), this should be:
(libc::IPPROTO_IP, libc::IP_TTL) => { | |
(libc::IPPROTO_IP, libc::IP_RECVTTL) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for being unclear, on FreeBSD, this should check IP_RECVTTL
, on Linux, IP_TTL
should be used.
Is the suggestion to have 2 different blocks, one for Linux and one for FreeBSD?
Yes
This is documented in man 7 ip:
Some BSD sockets implementations also provide an IP_RECVTTL option, but an ancillary message with type IP_RECVTTL is passed with the incoming packet. This is different from the IP_TTL option used in Linux.
also in the FreeBSD manual:
If the IP_RECVTTL option is enabled on a SOCK_DGRAM socket, the
recvmsg(2) call will return the IP TTL (time to live) field for a UDP
datagram. The msg_control field in the msghdr structure points to a
buffer that contains a cmsghdr structure followed by the TTL. The cms-
ghdr fields have the following values:
cmsg_len = CMSG_LEN(sizeof(u_char)) cmsg_level = IPPROTO_IP cmsg_type = IP_RECVTTL
@@ -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)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So these tests do not work under QEMU? Nix's cross CI tests use qemu under the hood
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think some of them (maybe all) will probably work.. I'll validate once I am done with addressing your comments. If they do not work, I'll try to document why.
Hi, thanks for the PR! Sorry for the late response!
For the cfg for targets (OSes), see Lines 20 to 27 in 5fde28e
|
Thanks a lot for the review and don't worry about the timing :) I'll address the comments and publish a new version!
|
Co-authored-by: SteveLauC <[email protected]>
The code we have right now does not build on freebsd 14 because
I think we need to enable RECVTTL only on linux. |
On FreeBSD, Update: PR filed rust-lang/libc#3750 Update: PR merged, we can use the libc from git now: libc = { git = "https://github.com/rust-lang/libc", branch = "libc-0.2", features = ["extra_traits"] } |
@@ -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 or receivethe Type-Of-Service (TOS) field that is |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need a blank space here:
/// Set or receivethe Type-Of-Service (TOS) field that is | |
/// Set or receive the Type-Of-Service (TOS) field that is |
src/sys/socket/mod.rs
Outdated
@@ -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) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for being unclear, on FreeBSD, this should check IP_RECVTTL
, on Linux, IP_TTL
should be used.
Is the suggestion to have 2 different blocks, one for Linux and one for FreeBSD?
Yes
This is documented in man 7 ip:
Some BSD sockets implementations also provide an IP_RECVTTL option, but an ancillary message with type IP_RECVTTL is passed with the incoming packet. This is different from the IP_TTL option used in Linux.
also in the FreeBSD manual:
If the IP_RECVTTL option is enabled on a SOCK_DGRAM socket, the
recvmsg(2) call will return the IP TTL (time to live) field for a UDP
datagram. The msg_control field in the msghdr structure points to a
buffer that contains a cmsghdr structure followed by the TTL. The cms-
ghdr fields have the following values:
cmsg_len = CMSG_LEN(sizeof(u_char)) cmsg_level = IPPROTO_IP cmsg_type = IP_RECVTTL
src/sys/socket/mod.rs
Outdated
}, | ||
#[cfg(any(linux_android, target_os = "freebsd"))] | ||
#[cfg(feature = "net")] | ||
(libc::IPPROTO_IP, libc::IP_TOS) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's right, sorry for being unclear.
@@ -1137,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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A change made by accident:)
I am moving this back to draft, while I find some time to finish to implement the changes and fix all the tests. |
What does this PR do
This PR improves the support for setting and retrieving of IP headers values for
It includes the socket options and the appropriate control messages for
sendmsg
andrecvmsg
.Note: I am not 100% sure I understand correctly the
cfg
values and feature flags ofnix
, so they could be set wrongly in the PR.Checklist:
CONTRIBUTING.md