Skip to content
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

Add support for SO_TIMESTAMP #663

Merged
merged 1 commit into from
Sep 7, 2017
Merged

Conversation

Wolvereness
Copy link
Contributor

This was implemented as part of my employment, and I have received permission to submit it upstream under my own name.

I implemented this with a bit of copy+pasting from the SCM_RIGHTS implementation, and it appeared to be functional when originally implemented on top of 13deb61 (tagged v0.8.0).

@@ -109,6 +109,7 @@ mod os {

// Ancillary message types
pub const SCM_RIGHTS: c_int = libc::SCM_RIGHTS;
pub const SCM_TIMESTAMP: c_int = SO_TIMESTAMP;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This constant is declared in libc, so it should reference that constant instead of defining it directly.

@@ -235,6 +236,7 @@ mod os {

// Ancillary message types
pub const SCM_RIGHTS: c_int = 1;
pub const SCM_TIMESTAMP: c_int = SO_TIMESTAMP;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above.

@@ -182,6 +187,7 @@ pub enum ControlMessage<'a> {
/// "Ancillary messages" section of the
/// [unix(7) man page](http://man7.org/linux/man-pages/man7/unix.7.html).
ScmRights(&'a [RawFd]),
ScmTimestamp(&'a TimeVal),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs a doc comment.

@Susurrus
Copy link
Contributor

Susurrus commented Jul 9, 2017

Awesome, thanks for your contribution! I've added a few minor comments. Please also add a changelog entry under the Added section.

@Wolvereness
Copy link
Contributor Author

Wolvereness commented Jul 9, 2017

Added changelog entry, documentation blurb, and used the SCM_TIMESTAMP declaration.

However, that appears to have broken the build; SCM_TIMESTAMP is at minimum inconsistently declared.

Here's a breakdown of where libc::SCM_TIMESTAMP is defined, based on a travis-ci build:

STATUS TARGET
aarch64-linux-android
arm-linux-androideabi
armv7-linux-androideabi
i686-linux-android
x86_64-linux-android
✔️ aarch64-unknown-linux-gnu
arm-unknown-linux-gnueabi
armv7-unknown-linux-gnueabihf
i686-unknown-linux-gnu
i686-unknown-linux-musl
✔️ mips-unknown-linux-gnu
✔️ mipsel-unknown-linux-gnu
powerpc-unknown-linux-gnu
✔️ powerpc64-unknown-linux-gnu
✔️ powerpc64le-unknown-linux-gnu
✔️ x86_64-unknown-linux-gnu
x86_64-unknown-linux-musl
✔️ i686-apple-darwin
✔️ x86_64-apple-darwin
i686-unknown-freebsd
✔️ x86_64-unknown-netbsd
✔️ x86_64-unknown-linux-gnu
✔️ x86_64-apple-darwin

It appears that for many of these, it might be a bug for libc's crate for not defining them. I can't confirm any target where it shouldn't be found; every c-header researched has had it defined. Some of them do not alias it (or share the value) as SO_TIMESTAMP though, so assigning it to libc::SO_TIMESTAMP will fail on those targets.

However, I can say that I can't personally pursue fixing this upstream, other than opening an issue: rust-lang/libc#655

@ndusart
Copy link
Contributor

ndusart commented Jul 9, 2017

I will include it in my PR as I'm trying to add missing sockets constants (rust-lang/libc#656).

@Susurrus
Copy link
Contributor

Susurrus commented Jul 9, 2017

@Wolvereness Yes, most of our issues end up being libc issues unfortunately as that crate is going through puberty and many things are undefined or defined incorrectly. But it's the path of least maintenance for us moving forward so we try to power through it.

Can you change Cargo.toml in this PR to reference the PR @ndusart filed so we can make sure CI will pass for all platforms when that PR lands? We can change Cargo.toml back before we merge this.

Could you please update this PR to use the libc types directly as @ndusart has volunteered to get this constant upstreamed for you. Thanks @ndusart!

@Wolvereness
Copy link
Contributor Author

@ndusart I'm appreciative that you can take that on; thanks!

@Susurrus I'll do that as soon as I'm able, which I'd expect in the next day or so.

@Wolvereness
Copy link
Contributor Author

@Susurrus I reverted to the libc::SCM_TIMESTAMP commit, and added a commit that changes the Cargo.toml libc to point to master in their repo. Based on a preliminary travis-ci, it appears to compile properly now. The upstream commit that matters is rust-lang/libc@472ffbb.

@Susurrus
Copy link
Contributor

The whole consts module is going to go away with #647, so instead of adding SCM_TIMESTAMP, just refer to libc directly for it. That way this shouldn't need much of a rebase once #647 lands.

@Wolvereness
Copy link
Contributor Author

@Susurrus Either way one of them will require a merge conflict resolution. If the plan was to include this one sooner, and have #647 rebase, I can go ahead and fix this one up to the new style. But, I'm under the assumption that both are still waiting on libc to hit a release cycle.

The least amount of effort will be fixing this one up to a certain style when it's intended to be merged. Let me know what the plan is, and I can put in the work when stuff is ready.

@Wolvereness
Copy link
Contributor Author

I went ahead and prepared it with the new style of using libc instead of the consts. Upstream has already put the constants into a release cycle, so as long as the version in the toml doesn't get set back down to an earlier release, that wont be an issue either.

@asomers
Copy link
Member

asomers commented Jul 26, 2017

I'm not familiar with the api, but it looks ok to me. I think the test failure on rust=beta will go away if you rebase. @Susurrus do you want to look too?

@Wolvereness
Copy link
Contributor Author

Wolvereness commented Jul 26, 2017

@asomers The commit is up-to-date with master; there's nothing to rebase other than to retry the build.

There's a problem in travis-ci, as beta should actually be an allowed failure at the moment, but it's using an old one for this PR. All of the current builds are failing in beta, but they are correctly marked as allowed failure.

Copy link
Contributor

@Susurrus Susurrus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some documentation changes are needed. And is there anyway to write tests for this? I'd really like to get some testing this functionality if possible.

@@ -182,6 +188,11 @@ pub enum ControlMessage<'a> {
/// "Ancillary messages" section of the
/// [unix(7) man page](http://man7.org/linux/man-pages/man7/unix.7.html).
ScmRights(&'a [RawFd]),
/// A message of type SCM_TIMESTAMP, containing the time the packet
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment is too long so it looks terrible in the generated docs. You should generate the docs on your end to check (cargo doc --no-deps --open) and search for ScmTimestamp and you'll see what I'm talking about.

All docs should have a short descriptive sentence at the start, followed by an empty comment line, then a more descriptive text. Please see the Rust book for some more details on writing effective documentation.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can touch that up with the other changes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image

CHANGELOG.md Outdated
@@ -5,6 +5,10 @@ This project adheres to [Semantic Versioning](http://semver.org/).

## [Unreleased]

### Added
- Added `nix::sys::socket::ControlMessage::ScmTimestamp`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does this mean for the user? Adding an enum variant, so what? Is there some new functionality we can describe here. If you were someone who wanted to use nix and you saw this, would you know what it meant? I think this needs a little more description here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could add nix::sys::socket::sockopt::ReceiveTimestamp was added, otherwise a binding for a particular socket control message should be straightforward to someone looking for the functionality of the same name.

I didn't see any other added changelog entries that added more than the shared name of the new binding, so I'm not sure what level of detail is appropriate.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really understand this subsystem as it's missing pretty much all relevant documentation, but you added a new ControlMessage variant to handle SCM_TIMESTAMP messages. You also added ReceiveTimestamp as something, that I think is user-facing, but I don't understand what it is and how it's used, but it should probably be documented under "Added" as well if it's a public API addition.

@Wolvereness
Copy link
Contributor Author

@Susurrus Technically speaking, testing the availability of UDP packets isn't deterministic. From a practical perspective, I'm not prepared to write tests for it, nor am I even sure it's supported on all targets (though they do have the constants apparently).

@Susurrus
Copy link
Contributor

Susurrus commented Aug 3, 2017

@Wolvereness This needs a rebase and some clarify for the CHANGELOG. Also some tests are failing which should be investigated.

@Wolvereness
Copy link
Contributor Author

Wolvereness commented Aug 8, 2017

Added a test. Two UDP packets are sent to the same socket, 250 ms apart. The test fails if timestamps are >10ms apart from expected delay, there are no timestamps, the packets are incorrect, or not both packets were received.

@Wolvereness Wolvereness force-pushed the SO_TIMESTAMP branch 7 times, most recently from 54d4a37 to 8a7c977 Compare August 9, 2017 22:30
@Wolvereness
Copy link
Contributor Author

Wolvereness commented Aug 9, 2017

@Susurrus The x86-freebsd (at least on buildbot) doesn't seem to give back the control messages, so I've disabled the API for that target. I also changed the measurement to compare the difference between the time taken within 5ms accuracy (which, from observation, it tends to be abs((sent2 - sent1) - (received2 - received1)) <40μs). That appears to have fixed the x64-freebsd system.

@asomers
Copy link
Member

asomers commented Aug 9, 2017

Before we accept this we need to figure out why your test fails on i386-freebsd. Simply disabling the API on that architecture is probably not correct.

@Wolvereness
Copy link
Contributor Author

@asomers It's a tier-2 target. I don't have access to a machine running that target either, other than spamming PRs to see what sticks on buildbot.

A volunteer could run it an look at what CmsgSpace ends up containing; maybe it's a mismatched constant. If there's nothing, even with an excessively sized buffer, then that's an issue for the developers of that C-API implementation.

@asomers
Copy link
Member

asomers commented Aug 9, 2017

@Wolvereness I'm just such a volunteer. I'll try it out tonight.

@asomers
Copy link
Member

asomers commented Aug 10, 2017

I grabbed @Wolvereness's branch, removed the restrictions for FreeBSD x86, and the tests all passed in my 32 bit VM. Next I need to try to replicate the Buildbot's setup. That system is actually a 32-bit userland with a 64-bit kernel.

Copy link
Contributor

@Susurrus Susurrus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a couple of last doc comment edits, then I think I'm done here.

/// [unix(7) man page](http://man7.org/linux/man-pages/man7/unix.7.html).
ScmRights(&'a [RawFd]),
/// A message of type SCM_TIMESTAMP, containing the time the packet
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Backticks around "SO_TIMESTAMP" here and on 290.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The later usage of "SO_TIMESTAMP" is not referring to the identifier, it's referring to the section name, as is the earlier "Ancillary messages".

@@ -274,10 +279,77 @@ impl<'a> Iterator for CmsgIterator<'a> {
/// [Further reading](http://man7.org/linux/man-pages/man3/cmsg.3.html)
pub enum ControlMessage<'a> {
/// A message of type SCM_RIGHTS, containing an array of file
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since you're here, can you also put SCM_RIGHTS in backticks?

@Wolvereness
Copy link
Contributor Author

@Susurrus I can take care of that just after @asomers has an update on the FreeBSD target.

@Susurrus
Copy link
Contributor

Susurrus commented Sep 1, 2017

@asomers Any update on the FreeBSD target issues?

@asomers
Copy link
Member

asomers commented Sep 1, 2017

I'll try to do the 32-bit on 64-bit test this weekend.

@asomers
Copy link
Member

asomers commented Sep 4, 2017

I've tracked it down to a FreeBSD kernel bug. Only 32-bit emulation is affected. The test works fine with a native i386 kernel. So you should enable all relevant functionality for FreeBSD i386, but disable the test like this. We will reenable the test whenever I update Buildbot to a version that fixes this bug.

    /// # Examples
    ///
    // Disable this test on FreeBSD i386
    // https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=222039
#[cfg_attr(not(all(target_os = "freebsd", target_arch = "x86")), doc = " ```")]
#[cfg_attr(all(target_os = "freebsd", target_arch = "x86"), doc = " ```no_run")]
    /// use nix::sys::socket::*;
    /// use nix::sys::uio::IoVec;
    /// use nix::sys::time::*;
    /// use std::time::*;

@Wolvereness
Copy link
Contributor Author

@asomers That's an unbelievably nifty trick for having a rust doc test excluded for certain targets.

And, I'm trying to throw in keywords to this message in hopes it comes up in a search for someone in the future, as I couldn't find how to do that myself.

@asomers
Copy link
Member

asomers commented Sep 7, 2017

FYI the bug is now fixed. But we must still leave that test disabled for now, because I'm not going to update the worker's image until 11.2 is released.
https://svnweb.freebsd.org/base?view=revision&revision=323254

bors r+

bors bot added a commit that referenced this pull request Sep 7, 2017
663: Add support for SO_TIMESTAMP r=asomers a=Wolvereness

This was implemented as part of my employment, and I have received permission to submit it upstream under my own name.

I implemented this with a bit of copy+pasting from the SCM_RIGHTS implementation, and it appeared to be functional when originally implemented on top of 13deb61 (tagged v0.8.0).
@bors
Copy link
Contributor

bors bot commented Sep 7, 2017

@bors bors bot merged commit dba1bb7 into nix-rust:master Sep 7, 2017
@WiSaGaN WiSaGaN mentioned this pull request Mar 20, 2021
bors bot added a commit that referenced this pull request Apr 8, 2021
1402: Support TIMESTAMPNS r=asomers a=WiSaGaN

This adds support of linux TIMESTAMPNS.
The code is mostly copied paste from #663

Co-authored-by: Lu, Wangshan <wisagan@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants