network: add socket interface#11278
Conversation
Move socket calls that involve raw fds from address to socket. Signed-off-by: Florin Coras <fcoras@cisco.com>
Signed-off-by: Florin Coras <fcoras@cisco.com>
mattklein123
left a comment
There was a problem hiding this comment.
Epic thanks, I can see the tech debt evaporating in front of me. :)
A few high level comments. Thank you!
/wait
| return {getVersionFromAddress(socket.localAddress())}; | ||
| } else { | ||
| return {getVersionFromAddress(Address::addressFromFd(socket.ioHandle().fd()))}; | ||
| return {getVersionFromAddress(SocketInterface::addressFromFd(socket.ioHandle().fd()))}; |
There was a problem hiding this comment.
Do you want to fix this fd indirection in this PR or a follow up?
There was a problem hiding this comment.
I was planning on doing it in a subsequent PR (after the last in this series). Obviously, if that's fine with you :-)
| /** | ||
| * @return true if address is Ipv6 and Ipv4 compatibility is disabled, false otherwise | ||
| */ | ||
| virtual bool v6only() const PURE; |
There was a problem hiding this comment.
Can't this just be on the IPv6 interface? Why do we need it on the top level IP interface?
There was a problem hiding this comment.
At a high level, I didn't want to change the semantics of one of the existing socket functions which looks at "v6only()" property of the address to setsockopt(,IPV6_V6ONLY,). Not sure if this still makes sense after we finish moving everything to socket, but that's probably for a later time discussion.
So, with respect to the comment above, I did things this way because I didn't know how else to extract the field from the private IpHelper struct. Note though that I am somewhat C++ challenged :-(
I guess that one alternative would be to move the field to the Ipv6Helper struct and that should be then retrievable via a new function, e.g., address.ip().ipv6().v6only(). I didn't do this because I couldn't tell if somebody else relies on Ipv6Helper being nothing more than sockaddr_in6.
There was a problem hiding this comment.
I guess that one alternative would be to move the field to the Ipv6Helper struct and that should be then retrievable via a new function, e.g., address.ip().ipv6().v6only(). I didn't do this because I couldn't tell if somebody else relies on Ipv6Helper being nothing more than sockaddr_in6.
Right this is what I would do. The helper is just an implementation of an interface and I think this can live on the IPv6 interface?
| namespace Envoy { | ||
| namespace Network { | ||
|
|
||
| namespace SocketInterface { |
There was a problem hiding this comment.
Do you want this to be an actual abstract class that you can inject later? Or you want to do that as a follow up? Ultimately I suspect you want this to hang off of the Api interface where we can handle platform injection more easily. Not sure if it's better to do it now or wait until later. I don't feel strongly about it.
There was a problem hiding this comment.
I was planning on leaving it for later, especially because I'm not entirely sure about the best approach.
Originally, I was hoping I could hide all of the "raw" socket calls behind the SocketImpl constructors, but then I stumbled upon some places that only care about the IoHandles (and rely on syscalls to retrieve addresses and whatnot). So, I decided to postpone the decision until I completely migrate everything to SocketImpl.
There was a problem hiding this comment.
OK we can do the injection later.
| return io_handle; | ||
| } | ||
|
|
||
| bool SocketInterface::ipFamilySupported(int domain) { |
There was a problem hiding this comment.
This is a dup of the function in the address file, right? Can we collapse this?
There was a problem hiding this comment.
Yup, it tries to reproduce what Ipv6Instance::socket() was doing. I think that the v6 specific logic should eventually be handled with socket->setOption(setv6only) so this could be cleaned up. However, v6only is true by default, so that could mean a lot of changes.
There was a problem hiding this comment.
Sorry what I mean is this is the same function as https://github.com/envoyproxy/envoy/pull/11278/files#diff-3a2eb9279fdb086a43b5b47dcbe278cdR22-R32, right? Can you just have this be a utility function in network::utility or something?
There was a problem hiding this comment.
Sorry, I completely missed that you were pointing at ipFamilySupported.
I was about to mark this as done, but then noticed that the socket functions were built such that they cannot fail (RELEASE_ASSERT on the socket() return value), therefore we can't rely on this logic in the utility function to test if a socket type is usable.
So we're left with three options:
- change SocketInterface::socket() to allow for failures (not sure about the impact in the rest of the codebase ..)
- do the af test in a different way, but that will probably involve introducing a new SocketInterface function, i.e., something like SocketInterface::socket() that can fail.
- keep on using this for now ...
There was a problem hiding this comment.
Sorry I'm really confused. AFAICT the body of this function is exactly the same as the one I pointed to. Why can't they be shared?
There was a problem hiding this comment.
As usual, I'm the one confused (I thought you felt this function didn't belong to SocketInterface).
The duplication is actually a byproduct of how I split the original PR. In the next PR, I'll completely remove the validateIpvXSupported check from the address, together with the remaining socket api calls, and wanted to have that conversation once we get there. If you think we shouldn't remove the validations, I can add a utility function now.
There was a problem hiding this comment.
OK if you are going to deal with this in a follow up it's fine to leave. SGTM. Can you push the other change and I can take a look?
There was a problem hiding this comment.
Here's a draft patch
I can also rebase the patch and push a separate PR if that works better.
There was a problem hiding this comment.
We can just do it as a follow up. Thank you!
There was a problem hiding this comment.
Thank you for the quick replies! And apologies again for the confusion.
- move v6only to the Ipv6 interface Signed-off-by: Florin Coras <fcoras@cisco.com>
Signed-off-by: Florin Coras <fcoras@cisco.com>
|
/retest |
|
🔨 rebuilding |
|
This has failed coverage twice, so might not be a flake. Can you see if any coverage is missing now? The report should be in CI artifacts. /wait |
Signed-off-by: Florin Coras <fcoras@cisco.com>
|
/retest |
|
🔨 rebuilding |
|
Seems to be passing now but not sure if this is just a fluke or not. From the logs, it appears the hot restart tests did not run and because of that the overall code coverage dropped under 97%. I managed to run the coverage script on one of my severs and, the one time I tried it, the hot restart test did fail. Weirdly enough, it does not fail when running it in isolation or as part of the whole test suite (timeouts maybe?). I also tried the coverage script with the next PR and, again only one sample, that one passed. |
|
OK thanks. I think there is a known flake where hot restart coverage is not always being counted. cc @lizan |
|
Thanks a lot, @mattklein123! Pushed last PR in this first series. |
Move socket calls that involve raw fds from address to socket.
Risk Level: Medium
Testing: unit tests
Docs Changes: n/a
Release Notes: n/a