fossil ui only listens on IPv6 afer checkin 7ce8400d02223bad7b38c672ed493a292c938b9c
(1) By anonymous on 2025-04-16 16:34:37 [source]
Only [::1}:8080 responds to requests. 127.0.0.1:8080 is not active
checkout: 7ce8400d02223bad7b38c672ed493a292c938b9c 2025-04-11 13:01:17 UTC
parent: e546a2b4573159e74a10d9c7046247e552d51c4a 2025-04-11 13:00:46 UTC
child: e3eb83997b9dfbabac425310184596efe11b78fc 2025-04-11 15:30:09 UTC
tags: trunk
comment: Fix "fossil server" so that it listens on both IPv4 and IPv6 on Unix. (user: drh)
Reverting back to e546a2b4573159e74a10d9c7046247e552d51c4a (the immediate parent), or anything before, fixes the error.
Firefox browser will try both IPv4 and IPv6 when asked to open localhost, but other browsers like Palemoon only try IPv4 and cannot connect to localhost.
(2) By Andy Bradford (andybradford) on 2025-04-17 03:13:14 in reply to 1 [link] [source]
I see the same issue here on OpenBSD 7.6: $ fossil version This is fossil version 2.26 [264250d670] 2025-04-16 16:47:24 UTC $ fossil server Listening for HTTP requests on TCP port 8080 $ netstat -na | grep 8080 tcp6 0 0 *.8080 *.* LISTEN So it only LISTENs on IPv6. I looked at the changes introduced for IPv6 and I'm not sure yet how to make it work with IPv4. Here's an example of using getaddrinfo() with the addrinfo struct to provide "hints" for which families are wanted to be used: https://github.com/openbsd/src/blob/96fb1b485f5f95c3ef2e24833649b403b27f679a/usr.sbin/identd/identd.c#L660 And then on line 664, it iterates over each addr found matching the "hints" and sets up a socket listener for each. Perhaps this is how it should be done also with Fossil? I've had little experience writing code for IPv6 so I'm not sure which approach is recommended. According to the man page for getaddrinfo, getting both AF_INET and AF_INET6 to work is accomplished by specifying AF_UNSPEC as the family: ai_family The address family that should be used. When ai_family is set to AF_UNSPEC, it means the caller will accept any address family supported by the operating system. Andy
(3.1) By ravbc on 2025-04-17 09:03:06 edited from 3.0 in reply to 2 [link] [source]
AFAIK OpenBSD (and some other BSDs) don't have dual-stack sockets, so listening simultaneously on inet4 and inet6 requires creating 2 listening sockets.
Putting it other way: OpenBSD always behaves as if IPV6_V6ONLY is set and it cannot be disabled.
(4) By Richard Hipp (drh) on 2025-04-17 09:59:28 in reply to 3.1 [link] [source]
The current code (check-in 2025-04-16T16:47 or later) works fine on Linux and MacOS. If some BSDs need separate sockets in order to listen simultaneously on IPv4 and IPv6, then I think BSD-using contributors need to suggest appropriate patches.
(5) By ravbc on 2025-04-17 10:44:24 in reply to 4 [link] [source]
Well, I don't care about IPv6. For me it's enough that fossil listen on inet4 socket. But current trunk build on OpenBSD listens only on inet6 socket, and in effect connection to localhost-ed fossil do not work if not made over IPv6 (so http://localhost:8080/ returns "Unable to connect", but http://[::1]:8080/ works as expected).
(6) By Richard Hipp (drh) on 2025-04-17 10:48:17 in reply to 5 [link] [source]
What happens if you do "fossil ui -P 127.0.0.1:8080
"? Does your BSD give you an IPv4 listening socket then?
(7) By ravbc on 2025-04-17 10:57:18 in reply to 6 [link] [source]
Yes, it does.
(8) By Richard Hipp (drh) on 2025-04-17 11:05:40 in reply to 7 [link] [source]
So if you hack your local copy of Fossil such that the "::ffff." is removed from cgi.c:2637, does that then solve your problem?
What OS and version are you using? How can we identify your OS using #ifdef?
(9) By Daniel Dumitriu (danield) on 2025-04-17 11:35:34 in reply to 8 [link] [source]
This seems to be a detailed list, if only correct.
(10) By ravbc on 2025-04-17 12:28:53 in reply to 8 [link] [source]
So if you hack your local copy of Fossil such that the "::ffff." is removed from cgi.c:2637, does that then solve your problem?
Now it listens on inet4 socket, and localhost connection works. So yes, this resolve my problem. Thank you.
What OS and version are you using?
I'm testing it on OpenBSD.
(11) By Richard Hipp (drh) on 2025-04-17 13:12:39 in reply to 10 [link] [source]
Please also try this test, ravbc:
Install the latest Fossil on your OpenBSD box in a place where ssh can find it. Perhaps /usr/local/bin. Make sure the first Fossil on the PATH used by ssh is indeed the latest build of Fossil.
Go to a different machine (maybe a completely different OS) and then using the latest Fossil, run:
Where "fossil ui openbsd:/
openbsd:
" is the hostname for your OpenBSD machine.Surf about some. Please confirm to us that this still works for you.
(12) By Martin Gagnon (mgagnon) on 2025-04-17 13:42:13 in reply to 11 [link] [source]
I just tried on our old OpenBSD server which is 6.8 and it doesn't works..
Also, nothing works on the server itself in cgi mode using the OpenBSD httpd webserver.
(13) By Andy Bradford (andybradford) on 2025-04-17 13:52:51 in reply to 6 [link] [source]
> What happens if you do "fossil ui -P 127.0.0.1:8080"? $ fossil ui -P 127.0.0.1:8080 unable to open listening socket on port 8080
(14) By Andy Bradford (andybradford) on 2025-04-17 13:54:34 in reply to 4 [link] [source]
> I think BSD-using contributors need to suggest appropriate patches. If it doesn't get resolved before I have a chance to look at it, I may take a stab at it. Andy
(15) By Richard Hipp (drh) on 2025-04-17 13:56:54 in reply to 13 [link] [source]
Context, please? What OS (including the version number!) are you running on? Which check-in of Fossil are you running? Are you sure that you are running the version of Fossil that you think you are running, and have not picked up some other random version off of your $PATH?
(16) By ravbc on 2025-04-17 14:03:38 in reply to 15 [link] [source]
Andy is right. I made a mistake when testing - used older system-wide installed version of fossil (from $PATH), not the freshly built one.
(17) By ravbc on 2025-04-17 14:07:43 in reply to 10 [link] [source]
This test was also wrongly made - sorry for the confusion. The change in cgi.c does not make a difference - fossil still listens on inet6 socket only.
(18) By Richard Hipp (drh) on 2025-04-17 14:12:32 in reply to 16 [link] [source]
OK, so I infer from this that the IPv6 stack on OpenBSD is broken in that it is unable to handle IPv4 traffic. Any application that wants to receive IPv4 traffic using OpenBSD has to open an IPv4 socket?
What if run "fossil server -P 192.168.1.123:8080
" (substituting your actual
IPv4 IP address). Does that also not work on OpenBSD?
Do the OpenBSD developers know about this limitation in their system and just expect application developers to work around it?
(19.1) By Andy Bradford (andybradford) on 2025-04-17 14:52:41 edited from 19.0 in reply to 8 [link] [source]
> So if you hack your local copy of Fossil such that the "::ffff." is > removed from cgi.c:2637 I removed the string and it still fails on OpenBSD 7.6 using [264250d670] and this suggested local modification: $ fossil ui -P 127.0.0.1:8080 unable to open listening socket on port 8080 But netcat works just fine: $ nc -l 127.0.0.1 8080 HELLO WORLD! If I leave off the specific request to use 127.0.0.1:8080 it launches: $ fossil ui Listening for HTTP requests on TCP port 8080 But my browser fails to connect because it tries to connect to IPv4 and gets a connection refused. Again, not surprising because it isn't listening: $ netstat -na | grep 8080 tcp6 0 0 *.8080 *.* LISTEN Just to be sure, this is what I've modified and tested with above: $ fossil diff Index: src/cgi.c ================================================================== --- src/cgi.c +++ src/cgi.c @@ -2632,11 +2632,11 @@ ){ fossil_fatal("not a valid IP address: %s", zIpAddr); } }else if( flags & HTTP_SERVER_LOCALHOST ){ /* Bind to the loop-back IP address */ - inet_pton(AF_INET6, "::ffff.127.0.0.1", &inaddr.sin6_addr); + inet_pton(AF_INET6, "127.0.0.1", &inaddr.sin6_addr); }else{ /* Bind to any and all available IP addresses */ inaddr.sin6_addr = in6addr_any; } inaddr.sin6_port = htons(iPort);
(20) By Andy Bradford (andybradford) on 2025-04-17 14:22:13 in reply to 15 [link] [source]
> What OS (including the version number!) are you running on? Sorry, I mentioned that earlier in the thread, but I'm running on OpenBSD 7.6. I'm absolutely certain that the path is correct. The check-in that I'm running is: $ fossil version This is fossil version 2.26 [264250d670] 2025-04-16 16:47:24 UTC With the slight modification that you requested to remove "::ffff." from the address. If I try your other suggestion: $ fossil ui localhost:/tmp ssh -e none -t -L 127.0.0.1:20908:127.0.0.1:20908 localhost fossil ui --nobrowser --localauth --port 127.0.0.1:20908 /tmp First attempt to run "fossil" on localhost failed Retry: ssh -e none -t -L 127.0.0.1:20908:127.0.0.1:20908 localhost 'PATH=$HOME/bin:/usr/local/bin:/opt/homebrew/bin:$PATH' fossil ui --nobrowser --localauth --port 127.0.0.1:20908 /tmp unable to open listening socket on port 20908 Connection to localhost closed.
(21) By Andy Bradford (andybradford) on 2025-04-17 14:36:00 in reply to 18 [link] [source]
> OK, so I infer from this that the IPv6 stack on OpenBSD is broken Broken is a subjective thing. That it behaves differently than Linux doesn't necessarily make it broken, any more than the lack of "rebase" in Fossil makes it broken. :-) OpenSSH, OpenSMTPD, and other "standard" servers are developed on and work just fine with OpenBSD with IPv4 and IPv6 support without "dual-stack" trickery. As for them being aware, sure, they know: https://marc.info/?t=174372025100001&r=1&w=2 Their answer is to use two sockets. Is there a "standard" way to use both IPv4 and IPv6 in a server process? Is iterating over the addrinfo list that is setup by getaddrinfo() with "hints" the "standard"? https://en.wikipedia.org/wiki/Getaddrinfo
(22) By Andy Bradford (andybradford) on 2025-04-17 14:59:21 in reply to 8 [link] [source]
> How can we identify your OS using #ifdef? This might suffice: #if defined(__OpenBSD__) But I wonder if there are others. Does Windows do it differently?
(23) By Richard Hipp (drh) on 2025-04-17 15:20:07 in reply to 14 [link] [source]
Check-in 2025-04-17T15:08z works around the OpenBSD socket limitations without adding too much complication to the code as follows:
If you specify an IP address (ex:
-P 192.168.1.192:8080
) then it will only listen for either IPv4 or IPv6, according to the format of that IP address. If the IP address contains a ':' it is assumed to be an IPv6 address, otherwise IPv4.Loopback is always "127.0.0.1". The ::1 loopback is not bound for "fossil ui" any more by default. If you need to use ::1 for loopback, then you have to say so explicitly using something like
-P ::1:8080
.If you do not specify an IP address and you are running on Linux or Mac, then you can connect on any IPv4 or IPv6 address, including 127.0.0.1 and ::1.
If you do not specify an IP address and you are running on OpenBSD, then you can only connect via IPv6 (I'm guessing - I don't have an OpenBSD machine at hand to test with.) If you want to provide service on an IPv4 address using OpenBSD, then you must specify that IPv4 address using the -P option. It is not currently possible for the "
fossil server
" command to listen for both IPv4 and IPv6 at the same time on OpenBSD.
This seems like a reasonable compromise.
(24) By Richard Hipp (drh) on 2025-04-17 15:48:31 in reply to 22 [link] [source]
Does Windows do it differently?
(Snicker) Microsoft always does things different. There is a completely separate source code file just to implement sockets on Windows, which is utterly and completely incompatible with everything else in the world. This thread is only about Unix.
(25) By Andy Bradford (andybradford) on 2025-04-17 16:17:49 in reply to 23 [link] [source]
> If you do not specify an IP address and you are running on OpenBSD, > then you can only connect via IPv6 This should work (for fossil ui) for those who haven't intentionally disabled IPv6 support in their browser (or their OS). I have gotten in the habit of disabling IPv6 because I find that it improves the browsing experience because I don't have IPv6 on the network. > This seems like a reasonable compromise. It will buy some time. I can look at improving the "fossil server" experience on OpenBSD this weekend (unless I'm able to find time sooner). Also, I believe that the behavior on Linux depends on the value of the net.ipv6.bindv6only sysctl setting: sysctl net.ipv6.bindv6only=1 When that is set to 1 I believe Linux will behave like OpenBSD in that if you request IPv6 you will not also get IPv4. (untested) Andy
(26) By anonymous on 2025-04-17 23:38:57 in reply to 23 [link] [source]
Check-in 2025-04-17T15:08z
If you do not specify an IP address and you are running on Linux or Mac, then you can connect on any IPv4 or IPv6 address, including 127.0.0.1 and ::1
I don't see that outcome on Linux Mint
$ fossil ui &
[1] 2829592
$ Listening for HTTP requests on TCP port 8080
$ curl 127.0.0.1:8080
<html>
<p>Redirect to Location: http://127.0.0.1:8080/timeline?c=current
</p>
</html>
$ curl [::1]:8080
curl: (7) Failed to connect to ::1 port 8080 after 0 ms: Couldn't connect to server
$
(27) By Andy Bradford (andybradford) on 2025-04-18 05:02:00 in reply to 26 [link] [source]
> $ fossil ui & What does "fossil version" show?
(28) By anonymous on 2025-04-18 05:25:28 in reply to 27 [link] [source]
What does "fossil version" show?
I used the version I showed above.
Check-in 2025-04-17T15:08z
https://fossil-scm.org/home/info/2025-04-17T15:08z
I have since reverted back to the version before that the listens on both v4 and v6.
(29) By Richard Hipp (drh) on 2025-04-18 12:31:55 in reply to 1 [link] [source]
The cgi_http_server() routine that implements the server function of "fossil ui" and "fossil server" has now been rewritten so that it uses separate sockets for IPv4 and IPv6. Seems to be working on Linux, Mac, and Windows but untested on OpenBSD as I don't have a platform for testing. New rules:
"fossil ui" listens on both 127.0.0.1 and on [::1], using separate sockets so that it ought to work even on OpenBSD.
"fossil server -P PORT" listens on all available IP addresses. There are separate sockets for IPv4 and IPv6 addresses, so this ought to work on OpenBSD.
"fossil server -P IPADDR:PORT" listens on the specified IP address. There is only one socket in this case, which will be either IPv4 or IPv6 depending on the format of IPADDR.
"fossil server --socket-name NAME" continues to listen on unix-domain socket NAME. This part is unchanged from the user perspective (though I did have to rewrite it internally.)
Please experiment with the new code on diverse platforms and report any issues.
(30) By Andy Bradford (andybradford) on 2025-04-18 14:14:40 in reply to 29 [link] [source]
> Please experiment with the new code on diverse platforms So far it seems to be working better on OpenBSD. I don't yet have a way to test the --socket-name parameter so I cannot comment on that. Thanks for looking at this sooner than I was able. Andy