-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
unix: Extend UpdSocket to send and receive TTL for a specific packet #82858
Conversation
r? @KodrAus (rust-highfive has picked a reviewer for you, use r? to override) |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
062c56f
to
1447222
Compare
Can you force-push to fix the typo in the commit message ( |
I posted comments with a few very minor issues. With those fixed, this LGTM. |
☔ The latest upstream changes (presumably #83664) made this pull request unmergeable. Please resolve the merge conflicts. |
☔ The latest upstream changes (presumably #84200) made this pull request unmergeable. Please resolve the merge conflicts. |
Hi @joshtriplett, could you approve this PR? |
Does somebody know how to fix this tidy error? |
Afaik platform-specific code should be in the |
This comment has been minimized.
This comment has been minimized.
Did not know that, thanks. |
8d9d6b4
to
605bf81
Compare
Hi @joshtriplett, |
Since josh seems busy and this concerns unstable stuff which will need some more revisions anyway I hope it's ok if I take over review. I'll go over it on the weekend. r? @the8472 |
Add the function recv_vectored_with_ancillary_from, recv_vectored_with_ancillary, send_vectored_with_ancillary_to and send_vectored_with_ancillary to UdpSocket for Unix platforms. Also add set_recvttl and recvttl to UdpSocket to tell the kernel to receive the TTL. Therefore, rename the Ancillary(Data) to UnixAncillary(Data) for the UnixDatagram and UnixStream and also add the IpAncillary(Data) for UdpSocket.
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.
First pass, haven't reviewed everything yet.
Overall I am a bit concerned that the split into IpAncillary
and UnixAncillary
will lead to some duplication especially if we want to expose raw ancillary messages (parsed into header + raw data) so that other libraries can do their own decoding. Although that discussion belongs in #76915 i'm just noting that the changes here may need to be revised.
/// and type `IPV6_HOPLIMIT`. | ||
/// | ||
/// # Example | ||
/// ```no_run |
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.
Any reason why the doc test is no_run
? Obviously the receiving parts would hang if they never received data but the sending ones could send the data into a black hole.
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.
But it would fail because of the expect("send_vectored_with_ancillary function failed")
.
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.
Why would sending fail though? UDP is fire-and-forget so you can still send even if nothing is listening on the other side.
If it's failing due to the lack of ipv6 you could try 127.0.0.1
instead.
/// | ||
/// The function returns `true` if there was enough space in the buffer. | ||
/// If there was not enough space then no file descriptors was appended. | ||
/// Technically, that means this operation adds a control message with the level `IPPROTO_IPV6` |
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.
"Technically" seems like an odd choice here (and in the comment below too). The following would probably do
This adds a control message [...]
Since this is standardized maybe link to the relevant section in RFC 3542
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.
Where and how to add the RFC 3542 link?
target_os = "linux", | ||
target_os = "netbsd", | ||
target_os = "openbsd", | ||
))] |
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.
these additions run afoul of this rule:
rust/src/tools/tidy/src/pal.rs
Line 27 in 4d90635
//! `std/sys_common` should _not_ contain platform-specific code. |
It currently isn't fully enforced by tidy, but the goal is to reduce that amount, not add more. Instead the module-reuse trick used a few times by hermit might help.
https://github.com/rust-lang/rust/blob/master/library/std/src/sys/hermit/mod.rs#L33-L38
sys_common::AsInner, | ||
}; | ||
|
||
impl UdpSocket { |
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.
Unless I missed a policy change simply adding platform-specific methods to a cross-platform struct isn't allowed and sealed extension traits should be used instead.
self.as_inner().recvttl() | ||
} | ||
|
||
/// Receives data and ancillary data from socket. |
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.
ancilliary data should link to IpAncillary
's docs.
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.
How do I add this link?
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.
Check the Ipv4Addr
doc comments for an example.
} | ||
} | ||
|
||
/// A net IP Ancillary data struct. |
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.
This needs several paragraphs of text and links to external documentation (e.g. RFC 3542, cmsg manpages or posix specs)
This was suggested here. I think we should keep If other libraries should use their own decoding, then we have to define the interface. |
Extend UdpSocket to send and receive hop-limit.
Having separate enums makes sense. But do we need separate ancillary types and all those setters too? Imo it would make more sense to align more closely with native concept of arbitrary messages. Some of those happen to be of types known to the standard library but not all of them. I think it could look roughly look like this: trait AncillaryMessage {
fn to_raw(&self) -> (c_int, c_int, &[u8]);
// and some unsafe helper methods do the memcpy to custom types properly
}
struct RawAncillaryMessage {
// I'm not 100% sure, but I think for raw accessors to platform-specific values using `c_int` should be fine.
fn from_raw(level: c_int, type: c_int, body: &[u8]) -> Self;
}
impl AncillaryMessage for RawAncillaryMessage {
...
}
impl AncillaryMessage for IpAncillaryData {
...
}
impl TryFrom<RawAncillaryMessage> for IpAncillaryData {
...
}
impl SocketAncillary {
pub fn addMessage(&mut self, impl AncillaryMessage) {
...
}
pub fn getMessages(&self) -> impl Iterator<Item = RawAncillaryMessage> {
...
}
} Then you could add any kind of message and iterator over any kind of message and then If you pass in a |
#[doc(cfg(any(target_os = "android", target_os = "linux",)))] | ||
#[cfg(any(doc, target_os = "android", target_os = "linux",))] | ||
#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] | ||
pub struct ScmCredentials<'a>(AncillaryDataIter<'a, libc::ucred>); |
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.
If these structs are linux-specific they should be moved to os::linux
, or are there any other unix platforms that support this too and they're just not implemented yet? There's #88025 which looks similar and yet different, I haven't checked if they can be unified.
☔ The latest upstream changes (presumably #88265) made this pull request unmergeable. Please resolve the merge conflicts. |
@LinkTed |
Add the function
recv_vectored_with_ancillary_from
,recv_vectored_with_ancillary
,send_vectored_with_ancillary_to
andsend_vectored_with_ancillary
toUdpSocket
for Unix platforms. Also addset_recvttl
andrecvttl
toUdpSocket
to tell the kernel to receive theTTL. Therefore, the
AncillaryData
enum had to be extended.