This is an archive of the discontinued LLVM Phabricator instance.

[test] Use either `127.0.0.1` or `[::1]` to run in ipv6-only environments.
ClosedPublic

Authored by rupprecht on Sep 6 2022, 6:56 PM.

Details

Summary

Test for both IPv4 and IPv6 support to determine if either 127.0.0.1 or [::1] are appropriate IP addresses to attempt to connect to. In an IPv6-only environment, 127.0.0.1 is not available.

Using localhost is problematic because we might not be able to get the same port on each IP flavor, and later try to connect to the wrong thing.

Diff Detail

Event Timeline

rupprecht created this revision.Sep 6 2022, 6:56 PM
Herald added a project: Restricted Project. · View Herald TranscriptSep 6 2022, 6:56 PM
rupprecht requested review of this revision.Sep 6 2022, 6:56 PM
Herald added a project: Restricted Project. · View Herald TranscriptSep 6 2022, 6:56 PM

I previously converted some tests to support running in ipv6-only environments in D87333, but we weren't running these tests so I missed them. Looking at history, I see D58131 specifically changed this from localhost to 127.0.0.1. Do the reasons there still apply today? I could make this more complicated and probe to see if 127.0.0.1 is supported, and fallback to ::1 if that doesn't work, like I did in parts of D87333, although this would be preferred IMO.

I believe the reasons are still relevant. Basically the problem is that listening on localhost:x creates two sockets (one for 127.0.0.1, one for ::1), and there's no way to guarantee that we'll be able to grab the same port for both (one could be taken by some other application). Our listening code will succeed if it opens at least one socket, but then if we again try to connect using the localhost name, we may end up connecting to the wrong thing. I think the correct fix is to take the address (ip+port) that we've *actually* started listening on, and then pass *that* as the argument to the connect command, but I'm not sure if our current Socket APIs allow you to get that information.

rupprecht updated this revision to Diff 458609.Sep 7 2022, 4:56 PM
  • Add a GetLocalhostIp helper to socket host utilities

I believe the reasons are still relevant. Basically the problem is that listening on localhost:x creates two sockets (one for 127.0.0.1, one for ::1), and there's no way to guarantee that we'll be able to grab the same port for both (one could be taken by some other application). Our listening code will succeed if it opens at least one socket, but then if we again try to connect using the localhost name, we may end up connecting to the wrong thing. I think the correct fix is to take the address (ip+port) that we've *actually* started listening on, and then pass *that* as the argument to the connect command, but I'm not sure if our current Socket APIs allow you to get that information.

There's listen_socket.GetLocalIPAddress(), but that returns an empty string here.

Anyway, I just changed to use the HostSupportsIPv4()/HostSupportsIPv6() helper methods and pick an appropriate scheme. PTAL.

rupprecht retitled this revision from [test] Use localhost in place of 127.0.0.1 to run in ipv6-only environments. to [test] Use either `127.0.0.1` or `[::1]` to run in ipv6-only environments..Sep 7 2022, 5:03 PM
rupprecht edited the summary of this revision. (Show Details)
JDevlieghere added inline comments.Sep 7 2022, 5:17 PM
lldb/unittests/TestingSupport/Host/SocketTestUtilities.h
50

nit

rupprecht updated this revision to Diff 458611.Sep 7 2022, 5:20 PM
  • Ip -> IP casing
rupprecht marked an inline comment as done.Sep 7 2022, 5:21 PM
labath accepted this revision.Sep 9 2022, 2:37 AM

I believe the reasons are still relevant. Basically the problem is that listening on localhost:x creates two sockets (one for 127.0.0.1, one for ::1), and there's no way to guarantee that we'll be able to grab the same port for both (one could be taken by some other application). Our listening code will succeed if it opens at least one socket, but then if we again try to connect using the localhost name, we may end up connecting to the wrong thing. I think the correct fix is to take the address (ip+port) that we've *actually* started listening on, and then pass *that* as the argument to the connect command, but I'm not sure if our current Socket APIs allow you to get that information.

There's listen_socket.GetLocalIPAddress(), but that returns an empty string here.

Yeah, that probably only works on connected sockets.

This revision is now accepted and ready to land.Sep 9 2022, 2:37 AM