Conversation
cc0b3f4 to
b25c9af
Compare
|
Both This was already an existing issue with the previous code (I think?) which used the "does it contain a I think that the following approaches would fix it, if we decide that it is worth fixing:
|
I probably wasn't clear enough in the PR description (and I discovered I think I see the problem this way: almost anything can be a path, but there are things that are clearly not pairs of (host, port), if they contain directory separators and square brackets. I think it's better to deal with the obvious cases, let
Yes. Non-implicit paths are well recognized as such.
Possible refinements, but a bit more annoying to implement, include checking whether the address contains a directory separator, and whether the segment after the last colon parses as an integer.
That would be the clearest option, but what should we do about the |
|
My main goal was to update the network code. I found out while hacking that I could add IPv6 and Unix domain sockets support too (on Windows). If this feature is too complicated to sort out, I could remove it (the last commit!) from this PR and re-submit later. |
debugger/unix_tools.ml
Outdated
| match String.rindex address ':' with | ||
| | exception Not_found -> un_addr | ||
| | n -> | ||
| let is_ipv6 = is_ipv6 address (n - 1) in |
There was a problem hiding this comment.
There is no guarantee that n - 1 is >= 0 here (and same with the n - 2 computation further down).
There was a problem hiding this comment.
I'm now checking that there's a least 4 bytes in the address ([::]) before accessing it.
b25c9af to
ef45ba6
Compare
ef45ba6 to
372faa3
Compare
|
My general impression:
|
But you have no proof that I am not @MisterDA's sock puppet! |
gasche
left a comment
There was a problem hiding this comment.
I find the logic to select the socket type not clear enough. The code should be clearer. Maybe we also want a comment that explains what the logic is (it is not documented anywhere so far?), but this might not be necessary if the code is readable enough as its own specification.
debugger/unix_tools.ml
Outdated
| | exception Not_found -> un_addr | ||
| | n -> | ||
| let likely_ipv6 = is_likely_ipv6 address (n - 1) in | ||
| if not (Filename.is_implicit address) && not likely_ipv6 then |
There was a problem hiding this comment.
I find the logic in this block of code too hard to follow. Before your change the idea was rather clear: either there is a : and we handle this as an IP (V4) address, or there isn't and we assume a unix socket path. Now what is the logic, and is it apparent in the code?
For example I think that it is not clear what not (Filename.is_implicit ...) is testing for, and maybe this could be helped with variable naming: let is_an_explicit_path = not (Filename.is_implicit address) in ....
There was a problem hiding this comment.
Well a path like C:\TMP\my.sock or ./my:sock is obviously not a host:port. not (Filename.is_implicit ...) caches paths that are rooted or (syntactically) relative to the current directory (they begin with ./ or ../).
If we only look at whether the address contains a : to decide whether it's an Unix domain socket or an inet address, then we'll miss absolute paths on Windows.
I'll look for a simpler compromise.
There was a problem hiding this comment.
I'm not saying that the previous logic was better -- I agree it was worse, especially on Windows. I am asking for a clear description of what the new logic is, and code that matches this clear description.
gethostbyname is deprecated. Windows doesn't support EAI_SYSTEM, and its gai_strerror is not thread-safe.
9641368 to
3fef800
Compare
I hope to have made it simpler and clearer.
I hope that the code is self-sufficient, although it does not justify the choices made. I now consider that the string is a Unix domain socket path if:
Sorry for the back and forth, I tried to be too clever without achieving a satisfying result. Are the code and the explanations satisfying now? Do you think that the code covers reasonable use-cases and has sane failure conditions? |
gasche
left a comment
There was a problem hiding this comment.
Yes, I think this is reasonable now. Thanks! (See minor comments.)
Failure messages were silently dropped. Also print the quoted address and port number.
Also use offsetof to simplify an expression.
3fef800 to
31c2f4b
Compare
Support IPv6 on all platforms in ocamldebug CAML_DEBUG_SOCKET. Passing an IPv6 address (e.g., `[::1]:8080`), or a hostname resolving to an IPv6 address, is supported. Support Unix domain sockets on Windows. Detecting the type of the address is on done on a best-effort basis. `[:` is a valid DOS drive and counts as an absolute path. We chose to ignore that and recognize the string as an IPv6 address.
31c2f4b to
2697622
Compare
The OCaml debugger sets up a socket between the debugger and the runtime of the process being debugged. The user has some control over the socket: she can specify an IPv4 address or host, or a path to a Unix domain socket. They are selected with
ocamldebug -s [address]option, or interactively withset socket [address], and with theCAML_DEBUG_SOCKETenvironment variable to the remotely debugged process.With some warnings enabled, C compilers now complain that some network functions are deprecated (e.g.,
gethostbynameis replaced bygetaddrinfo), because the functions don't support IPv6.This PR:
gethostbynamewithgetaddrinfoin the runtime and inocamldebug;[::1]:8080, and IPv6 hosts;My code tries to detect whether a colon:separating an IP address and a port has been specified; if not it considers that the user has specified an Unix domain socket (a path in the filesystem). Then, if the user has specified an implicit path or something that doesn't look like an IPv6 address, my code also picks an Unix domain socket. All the remaining cases (IPv4 address, IPv6 address, hostname; followed by a port) are handled bygetaddrinfoafter some little processing.I've tested this code on macOS and Windows, with IPv4, IPv6 addresses and hosts, and absolute and relative paths for Unix domain sockets.