-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Raw socket support #11410
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
Raw socket support #11410
Conversation
fcntl() is a vararg function allowing many options to be passed. This commit adds support for a single argument, as well as adding some options which may be passed to it.
Adds a new IoFactory method for creating a raw socket. Native/blocking implementation is stubbed out. Adds a RawSocketWatcher which creates a non-blocking raw socket using berkeley sockets. It registers the socket with libuv to handle reading and writing. When the socket is ready the sendto/recvfrom calls are used to handle sending. Note that Windows does not support raw sockets.
This is a small weapper around the functionality provided by IoFactory and very similar to std::io::net::udp.
Can you add native support? green isn't destined to be the default, and keeping feature parity is important. |
I will work on that now. |
This is pretty awesome, nice work! @cmr is right in that sadly we should not be merging this unless there's both native and green support. It looks like it's trivial to add native support though as you've already done the bulk of the work in green! |
Hm, now that I've actually read the PR description, there's a few things that I'm a little concerned about.
Is there really no way for us to add tests? This is a fairly large chunk of code and it's like to regress without tests.
Documenting the green/native impls isn't so important, but documenting libstd code is paramount.
I'm unhappy that we have |
This is what I'm hoping. I'm working on this now.
Tests can be added by linking to a dummy library which emulates the functionality of the C functions which are being used. That way no root access is required. I don't know what would be the best way to achieve this with the build system you are using. I agree there should be test cases.
I'll add documentation for the bits of libstd that I have changed.
That was there when I got here! I can't test on Windows right now, I'd be happy to remove the |
If you'd like, anyone with r+ access can push to try for you which will run most of the tests on windows and you can see if it builds, feel free to ask in IRC (or pm me directly) |
I have now added native backend support. How would I go about creating/linking with another library in the test suite? Where in the source tree should I put it? I should be able to put together some tests if I can do this. |
let proto = if domain == libc::AF_INET { libc::IPPROTO_IP } else { libc::IPPROTO_IPV6 }; | ||
let res = unsafe { libc::setsockopt(socket, proto, libc::IP_HDRINCL, (&one as *libc::c_int) as *libc::c_void, intrinsics::size_of::<libc::c_int>() as u32) }; | ||
if res == -1 { | ||
return Err(super::last_error()); |
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 doesn't close the socket on error, I'd recommend creating the RawSocket
as soon as possible to let the destructor kick in.
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.
Is leaving it to the destructor the best way to do this? I seem to recall that there's no guarantee that they will be called?
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 destructor is guaranteed to be called when a value goes out of scope. Perhaps you're thinking of another language with a focus on garbage collection. A close
method doesn't make much sense in Rust.
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 probably it, thanks. I'll fix it.
Conflicts: mk/crates.mk src/libstd/libc.rs
I've made a ton of changes:
I'd like to get this in fairly soon (despite some missing platform support), since it's quite difficult to keep merging the latest changes. |
…t expected to pass.
Conflicts: mk/crates.mk src/libnative/io/mod.rs src/libstd/lib.rs
New since the pull was re-opened:
Are you happy with the API? If so I'll get some documentation written up for it. |
This has reached the point that I fear that this no longer belongs in the standard library. The new module is quite extensive, and the new
I would tend to lean towards 2 before 1 because I would think that it would be generally useful, but it also may be difficult. |
What would you do instead of In order to do this in a separate library there either needs:
I agree that there is a lot of content in this pull, and there's also a lot of scope to extend it, for example:
Perhaps a subset of these things could be added to the standard library? The trouble is where to draw the line, since quite a few of the things here would not be required for basic support but are required for testing. |
Maybe it could be reduced to the minimal code that needs to be in the core libraries? For example, there's a lot of code that gets put in libstd to encode and decode Ethernet, IP, UDP, TCP packets as well as constants like IpNextHeaderProtocols which seem unnecessary in libstd and could be moved to another crate. Also, there's a lot of code that attempts to lookup network interface in libnetsupport, and that also seems unnecessary since the raw socket code could just translate sockaddr_ll fields more directly without needing to do get_network_interfaces and so on (which could be done in another crate if necessary). |
Closing due to inactivity. I like the idea of adding a little support to the green/native implementations if necessary, but leaving most of this outside of the standard library for a more proper and well defined library. Depending on the extent of this library, I would also recommend an RFC for adding a new library. |
Since someone on reddit linked to here in search of raw sockets with Rust: libpnet is what this pull request became, and the project you're looking for if you want to use raw sockets in Rust, without using the C APIs directly. To everyone else, sorry for the noise... |
This pull request adds raw socket support to rust using libuv.
Some notes:
It only supports the libuv backend - the native backend is stubbed out.Using raw sockets requires root access on the machine, which I assume the test suite does not have (and will not have) access to. The way around this would be to create a dummy library which exposes all the C functions used without actually implementing the functionality - I don't know how best to go about this or how to integrate it with the test-suite, guidance would be helpful.
I can add support for the native backend if required - there's no reason it can't be there, it just didn't exist while I was writing support. I have tested this on all the platforms I have available to me under various scenarios (transport layer/ipv4/ipv6 and network layer).