add Eio_unix.Sockopt for setting/getting socket options#575
Conversation
talex5
left a comment
There was a problem hiding this comment.
Seems like socket options could be useful on non-Unix systems too. We could define the type in Eio.Net as an extensible variant and put the common ones there, adding Unix specific ones in Eio_unix.Net, etc. Would have to decide what to do about unsupported options.
SGTM. Right now, if a given sockopt isn't defined, it becomes (-1) and a call to it raises EINVAL (similar behaviour to the OCaml Unix module). I'll move the common definitions that work on Windows as well to Eio.Net, and then put the remaining ones in Eio_unix. |
52c2ac8 to
65fa53b
Compare
|
In #322, @create2000 is asking about helping to finish this. Are we happy with the current design? What needs to happen beyond rebasing it? It looks to me like some of the options (those not specific to Unix) should move to Possibly Might need a way to pass a list of options when connecting or binding (since we do that in one step, and maybe it's too late to set some options by then?). Might want some fancy heterogeneous list to hold them, since they have various types. @create2000 I don't know if it's a good first issue or not. It uses some fancy types and involves C code. On the other hand, it's mostly done! |
|
Re:design -- my impression is that we should definitely move parts to Perhaps a follow up PR can work to support options being set at the point of connecting/binding (as you mentioned, this seems very related to #713)? |
|
I've pushed a rebase with all the suggestions here. There are loads of Linux and Windows specific ones to add, but I wanted to check if this is version is heading in the right direction first @talex5 @patricoferris |
talex5
left a comment
There was a problem hiding this comment.
This approach looks good to me.
|
I've added a bunch of Linux specific calls now (skipping multicast for now, and some of the more exotic fast connect and tcp_info ones), and also dropped SO_ACCEPTCON as it's not portable to macOS with no reasonable alternative (have to do a listen and wait for an EINVAL). It can still be passed directly via the Unix passthrough, but it's not much use in Eio where you know the state of your sockets anyway. |
|
Tests should be fixed now as I've pushed a fix to ignore ENOPROTOOPT errors for IP_LOCAL IP sockopts that only work on Linux >6.3 |
|
Squashed commits, should be ready for merge. |
talex5
left a comment
There was a problem hiding this comment.
(only reviewed the mock bit so far)
|
Rebased to trunk, and some minor fixes also added while re-reviewing it. |
|
@talex5 @patricoferris I'm happy with the low-level implementation here, but I'm not sure if the Pi integration is right. We've got a new SOCKET module type now, and I think it won't be too onerous to mock, but I'm not sure... |
|
Need to ensure this is compatible with whatever approach we pick for #713 as well |
7dfdf32 to
149ee4f
Compare
f66325d to
fbd9544
Compare
| int ret = getsockopt(Int_val(v_fd), Int_val(v_level), Int_val(v_option), | ||
| buffer, &len); | ||
| if (ret == -1) uerror("getsockopt", Nothing); | ||
| v_result = caml_alloc_initialized_string(strnlen(buffer, len), buffer); |
There was a problem hiding this comment.
Nothing good comes from returning a truncated string; the caller wont be able to use it meaningully. Instead of strnlen, why not check len after the getsockopt and raise an exception if it's the same as sizeof(buffer)?
There was a problem hiding this comment.
Yes, could do. Not sure what exception to raise, though.
There was a problem hiding this comment.
Invalid_argument is reasonable here. It's a rare violation that indicates something's quite wrong, and not something expected to be caught and handled.
Co-authored-by: Thomas Leonard <talex5@gmail.com>
There are some socket options that are Linux-specific which are quite handy to have. This adds a Eio_unix.Sockopt module which works on Eio_unix.Fd.t values.
This is a draft PR to check on the interface: the current PR replaces the need for Unix.setsockopt and has a single simple GADT for the socket options. Alternatively we could just expose the extended ones in the same style as upstream OCaml as a separate set of types, too. Opinions welcome.