Fossil User Forum

fossil ui only listens on IPv6 afer checkin 7ce8400d02223bad7b38c672ed493a292c938b9c
Login

fossil ui only listens on IPv6 afer checkin 7ce8400d02223bad7b38c672ed493a292c938b9c

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:

  1. 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.

  2. Go to a different machine (maybe a completely different OS) and then using the latest Fossil, run:

    fossil ui openbsd:/
    Where "openbsd:" is the hostname for your OpenBSD machine.

  3. 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.

(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.

(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);

(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?

(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.

(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

(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.

(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?

(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

(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.

(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

(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.

(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