IPv6 client issue on OpenBSD.
(1) By Michael Price (spheno) on 2025-12-17 19:28:58 [source]
I have a strange issue I'm experiencing that I wanted to toss out to the group. On an OpenBSD box with only an IPv6 address I can't clone any https fossil repo. Even the official fossil server here. I have tried the binary from the ports as well as compiling my own. I've tried on my own machines as well as IPv6 only OpenBSD VPS servers. I initially noticed the issue on a dual stack box where every connection was on IPv4. This confused me as all other connections were properly preferring IPv6. Dropping the IPv4 address exposed the issue. In every case you can run the OpenBSD version of chrome on the same box and hit the server just fine.
Can someone with an IPv6 only OpenBSD box try this so I can finally know if I'm crazy? Thanks.
Michael
(2) By Andy Bradford (andybradford) on 2025-12-18 02:31:04 in reply to 1 [link] [source]
I don't have a remote using HTTPS over IPv6, but HTTP is working for me: $ ping6 -c 1 remote PING remote (fe80::baae:edff:fe7f:f5ff%em0): 56 data bytes 64 bytes from fe80::baae:edff:fe7f:f5ff%em0: icmp_seq=0 hlim=64 time=0.663 ms --- remote ping statistics --- 1 packets transmitted, 1 packets received, 0.0% packet loss round-trip min/avg/max/std-dev = 0.663/0.663/0.663/0.000 ms I had to add an entry to /etc/hosts for this because apparently there's some error handling [] notation for IPv6: $ fossil clone http://[fe80::baae:edff:fe7f:f5ff%em0]:8080/ clone.fossil getaddrinfo() fails: non-recoverable failure in name resolution Clone done, wire bytes sent: 0 received: 0 remote: server returned an error - clone aborted Rerun using --httptrace for more detail But it clones over IPv6 as long as I'm using DNS: $ fossil clone http://remote:8080/ clone.fossil Round-trips: 23 Artifacts sent: 0 received: 65834 Clone done, wire bytes sent: 5935 received: 119547898 remote: fe80::baae:edff:fe7f:f5ff%em0 Rebuilding repository meta-data... 100.3% complete... Extra delta compression... 455 deltas save 20,900,100 bytes Vacuuming the database... project-id: CE59BB9F186226D80E49D1FA2DB29F935CCA0333 server-id: b8e87060e5d21feb5f51bbe90a0c8a38191babe3 admin-user: amb (password is "DzRjNmHxb5")
(3) By Kirill M (Kirill) on 2025-12-18 08:57:25 in reply to 1 [link] [source]
IPv6-only VM running OpenBSD with fossil package installed:
km@ams ~ $ uname -prs
OpenBSD 7.8 amd64
km@ams ~ $ fossil clone https://fossil-scm.org/
SSL: cannot connect to host fossil-scm.org:443 (Can't assign requested address)
Clone done, wire bytes sent: 0 received: 0 remote:
server returned an error - clone aborted
Rerun using --httptrace for more detail
km@ams ~ $ fossil clone --httptrace https://fossil-scm.org/
SSL: cannot connect to host fossil-scm.org:443 (Can't assign requested address)
Clone done, wire bytes sent: 0 received: 0 remote:
no such file: http-reply-0.txt
/***** Subprocess 16570 exit(1) *****/
(4.1) By Andy Bradford (andybradford) on 2025-12-18 15:07:39 edited from 4.0 in reply to 3 [link] [source]
> SSL: cannot connect to host fossil-scm.org:443 (Can't assign requested address) Can you connect at all using telnet or some other mechanism? telnet -6 fossil-scm.org 443 openssl s_client -6 -connect fossil-scm.org:443
(5) By Michael Price (spheno) on 2025-12-18 15:29:23 in reply to 4.1 [link] [source]
I’m the original poster and get that same error. You can start chrome on the box and hit the same url without incident.
(6) By Richard Hipp (drh) on 2025-12-18 15:34:47 in reply to 1 [link] [source]
Are you saying that you are running Fossil on the IPv6-only box and trying to clone from a server on the internet? Or are you running a Fossil server on the IPv6-only box and trying to clone from the IPv6-oly server to some other platform?
Please show us the clone command you are using with its output. Maybe add the --xverbose option before capturing the output.
(7) By Michael Price (spheno) on 2025-12-18 17:15:45 in reply to 6 [link] [source]
I am getting the same output as Kirill above when running "fossil clone https://fossil-scm.org/" on an OpenBSD box with only an IPv6 address. I can use google chrome from the same machine to access the url. I can post verbose output from the command when I'm home later today.
(10) By Kirill M (Kirill) on 2025-12-19 10:30:15 in reply to 6 [link] [source]
Now I got curios and tried various things (such as specifying family inet6 in /etc/resolv.conf and even adding an ipv6-only entry for fossil-scm.org in /etc/hosts). Nothing have helped. For DNS fossil uses IPv6, but for connection, it's stuck with IPv4.
$ kdump | grep -E "(socket|connect|getaddrinfo)"
92315 fossil CALL socket(AF_INET6,0x5002<SOCK_DGRAM|SOCK_NONBLOCK|SOCK_DNS>,0)
92315 fossil RET socket 6
92315 fossil CALL connect(6,0xdab35081da0,28)
92315 fossil RET connect 0
92315 fossil CALL socket(AF_INET,0x1<SOCK_STREAM>,0x6)
92315 fossil RET socket 6
92315 fossil CALL connect(6,0xdab13542aa4,16)
92315 fossil RET connect -1 errno 49 Can't assign requested address
"SSL: cannot connect to host fossil-scm.org:443 (Can't assign requested address)
Could the marked line be causing this?
int
BIO_get_host_ip(const char *str, unsigned char *ip)
{
struct addrinfo *res = NULL;
struct addrinfo hints = {
.ai_family = AF_INET,
^^^^^^^^^^^^^^^^^^^^^
.ai_socktype = SOCK_STREAM,
.ai_flags = AI_PASSIVE,
};
uint32_t *iap = (in_addr_t *)ip;
int error;
(11) By Richard Hipp (drh) on 2025-12-19 12:35:13 in reply to 10 [link] [source]
The marked line is in OpenSSL, not in Fossil.
I don't know what is going wrong for you, and I don't have an BSD system to experiment
with. I did add a new command-line option "--ipv6" which attempts to force the use
of IPv6 for everything. Maybe rebuild the Fossil binary using the latest trunk code
and then run:
fossil clone --ipv6 --xverbose https://sqlite.org/althttpd dummy.db
Let us know if that makes any difference. The command above clones a small repository just to avoid using excess time and bandwidth for this test.
(12) By Kirill M (Kirill) on 2025-12-19 13:05:00 in reply to 11 [link] [source]
The marked line is in OpenSSL, not in Fossil.
LibreSSL even… I'll check!
(13) By Kirill M (Kirill) on 2025-12-19 13:24:51 in reply to 11 [link] [source]
$ fossil clone --ipv6 --xverbose https://sqlite.org/althttpd dummy.db
The --ipv6 option is not supported in this build
SSL: cannot connect to host sqlite.org:443 (Can't assign requested address)
Clone done, wire bytes sent: 0 received: 0 remote:
server returned an error - clone aborted
Rerun using --httptrace for more detail
(14) By Richard Hipp (drh) on 2025-12-19 13:34:27 in reply to 13 [link] [source]
Please download and build the latest version of OpenSSL, then link Fossil against that newer OpenSSL. That might clear the problem.
See the Notes on how Fossil deliverables are built document for hints on how to do the above.
Just to confirm that my hunch above is correct, what is the output
of "fossil version -v" and/or "fossil tls-config"?
In particular, what version of OpenSSL were you running?
(15) By Kirill M (Kirill) on 2025-12-19 14:48:24 in reply to 14 [link] [source]
I'm not the OP, but I got curious enough to dig this hole…
I have tried with this setup so far:
$ ./fossil version -v
This is fossil version 2.28 [5ef8ac82c3] 2025-12-19 13:01:53 UTC
Compiled on Dec 19 2025 14:19:08 using clang-19.1.7 (64-bit)
SQLite 3.52.0 2025-12-11 23:24:05 01409738af
SSL (LibreSSL 4.2.0)
zlib 1.3.1.1-motley, loaded 1.3.1.1-motley
$ fossil tls-config
OpenSSL-version: LibreSSL 4.2.0 (0x020000000)
Trust store location
SSL_CERT_FILE:
SSL_CERT_DIR:
ssl-ca-location:
OpenSSL-cert-file: /etc/ssl/cert.pem
OpenSSL-cert-dir: /etc/ssl/certs
Trust store used: /etc/ssl/cert.pem
ssl-identity:
By default OpenBSD uses LibreSSL, which has been forked from OpenSSL, but uh-oh I will go ahead and give it a try with OpenSSL 3.5, as I happen to have it available om machine with fossil trunk checked out. Now trying with 3.5 and static build on IPv6-only machine:
$ ./fossil version -v
This is fossil version 2.28 [5ef8ac82c3] 2025-12-19 13:01:53 UTC
Compiled on Dec 19 2025 15:28:53 using clang-19.1.7 (64-bit)
SQLite 3.52.0 2025-12-11 23:24:05 01409738af
SSL (OpenSSL 3.5.4 30 Sep 2025)
zlib 1.3.1.1-motley, loaded 1.3.1.1-motley
~ $ fossil tls-config
OpenSSL-version: LibreSSL 4.2.0 (0x020000000)
Trust store location
SSL_CERT_FILE:
SSL_CERT_DIR:
ssl-ca-location:
OpenSSL-cert-file: /etc/ssl/cert.pem
OpenSSL-cert-dir: /etc/ssl/certs
Trust store used: /etc/ssl/cert.pem
ssl-identity:
With this setup even original command worked:
~ $ ./fossil clone https://fossil-scm.org/ foo
Round-trips: 12 Artifacts sent: 0 received: 65809
Clone done, wire bytes sent: 3125 received: 51921158 remote: 2600:3c02::f03c:95ff:fe07:695
Rebuilding repository meta-data...
100.1% complete...
Extra delta compression... 84 deltas save 6,398,780 bytes
Vacuuming the database...
Hm, it says 100.1% complete there?
and --ipv6 also worked:
$ ./fossil clone --ipv6 https://sqlite.org/src bar
Round-trips: 23 Artifacts sent: 0 received: 127647
Clone done, wire bytes sent: 5992 received: 109521302 remote: 2600:3c02::f03c:95ff:fe07:695
Rebuilding repository meta-data...
100.0% complete...
Extra delta compression... 729 deltas save 13,006,958 bytes
Vacuuming the database...
Rebuilding of repository meta-data took ages on that machine! I didn't need it, but wanted to see if I got >100% the second time.
(16) By spindrift on 2025-12-19 15:14:12 in reply to 15 [link] [source]
Hm, it says 100.1% complete there?
Ah. You fixed it too comprehensively?
(18) By Michael Price (spheno) on 2025-12-19 20:11:23 in reply to 15 [link] [source]
Also works for me if I compile with OpenSSL.
(19) By Kirill M (Kirill) on 2025-12-20 12:15:18 in reply to 18 [link] [source]
I raised the issue on the libressl@ mailing list.
(20) By Kirill M (Kirill) on 2025-12-20 16:01:04 in reply to 19 [link] [source]
and we have a response by one of the devs:
Looks like that's because it uses BIO_new_connect() which has only ever supported IPv4 in LibreSSL's libcrypto (since that's what 1.0.1 had). [...] OpenSSL 1.1 extended this interface to support IPv6.
(21) By Richard Hipp (drh) on 2025-12-20 16:06:05 in reply to 20 [link] [source]
Please ask them if there is some other interface that we ought to be using instead
(22) By Andy Bradford (andybradford) on 2025-12-20 17:01:21 in reply to 21 [link] [source]
I think we could use the BIO_new_socket() interface. Basically call Fossil's socket_open() (which supports IPv6) and then use the existing socket with BIO_new_socket() to "upgrade" the connection to TLS. I've actually been experimenting with these changes already, but SSL code is quite messy and the documentation spartan.
(24) By Kirill M (Kirill) on 2025-12-21 12:10:40 in reply to 22 [link] [source]
or some simple helper function in http_ssl.c, which just mirrors the logic from socket_open()? it might look like socket_open() manages iSocket, which is declared as static and thus private to the file where socket_open lives. a helper function in http_socket.c which exposes iSocket could be used too, I guess.
(25) By Andy Bradford (andybradford) on 2025-12-21 15:30:14 in reply to 24 [link] [source]
That's precisely what we're testing in this branch: https://fossil-scm.org/home/timeline?r=ssl-with-socket Also, I didn't mean that Fossil's code was messy, but rather it seems that SSL cannot help but be messy. At any rate, if you want to help in testing the proposed changes, please build and try it out.
(26) By Kirill M (Kirill) on 2025-12-21 17:47:08 in reply to 25 [link] [source]
At any rate, if you want to help in testing the proposed changes, please build and try it out.
works for me
~ $ ./fossil version -v
This is fossil version 2.28 [fa63c94422] 2025-12-21 00:49:43 UTC
Compiled on Dec 21 2025 18:40:00 using clang-19.1.7 (64-bit)
SQLite 3.52.0 2025-12-11 23:24:05 01409738af
SSL (LibreSSL 4.2.0)
zlib 1.3.1.1-motley, loaded 1.3.1.1-motley
~ $ ./fossil clone https://fossil-scm.org/ foo.fossil
Round-trips: 11 Artifacts sent: 0 received: 65821
Clone done, wire bytes sent: 2848 received: 51931988 remote: 2600:3c02::f03c:95ff:fe07:695
Rebuilding repository meta-data...
100.1% complete...
Extra delta compression... 84 deltas save 6,400,871 bytes
Vacuuming the database...
project-id: CE59BB9F186226D80E49D1FA2DB29F935CCA0333
but 100.1% again!
(27) By Richard Hipp (drh) on 2025-12-21 18:10:29 in reply to 26 [link] [source]
Is there any reason to delay landing this change on trunk?
(28) By Kirill M (Kirill) on 2025-12-21 19:12:54 in reply to 27 [link] [source]
LGTM logic-wise, and it works too FWIW.
I'm not a C programmer, though, so beware: I can follow the flow and logic, but not verify the details. The logic seems better, simpler and with some duplication removed.
(30) By Andy Bradford (andybradford) on 2025-12-21 22:20:55 in reply to 27 [link] [source]
At this point, I don't think there's any reason to delay.
(29) By spindrift on 2025-12-21 21:18:45 in reply to 26 [link] [source]
100.1% again!
Floating point precision for the win!
Just be grateful that it's not 99.9% complete. That would really really really annoy people.
I'm sure one day someone will decide to cap the displayed variable.
(23) By Andy Bradford (andybradford) on 2025-12-20 21:00:14 in reply to 21 [link] [source]
Internally, OpenBSD tends to prefer using libtls: https://www.openbsd.org/papers/linuxconfau2017-libtls/ I don't think we need to go so far as to rewrite all the code to use that model, even if it might be a cleaner interface.
(17) By Andy Bradford (andybradford) on 2025-12-19 16:16:36 in reply to 14 [link] [source]
Just for the sake of comparison, I too am running on OpenBSD and have a Fossil server behind an IPv6 relayd configuration. I can hit it with my Firefox browser. I can hit it with Curl. But not with Fossil. Curl's configuration is using LibreSSL: ------------------------------------------------------------------------ $ curl --version curl 8.13.0 (x86_64-unknown-openbsd7.7) libcurl/8.13.0 LibreSSL/4.1.0 zlib/1.3.1.1-motley nghttp2/1.65.0 ngtcp2/1.11.0 nghttp3/1.8.0 Release-Date: 2025-04-02 Protocols: dict file ftp ftps gopher gophers http https imap imaps ipfs ipns mqtt pop3 pop3s rtsp smb smbs smtp smtps telnet tftp ws wss Features: alt-svc AsynchDNS HSTS HTTP2 HTTP3 HTTPS-proxy IPv6 Largefile libz NTLM SSL threadsafe UnixSockets ------------------------------------------------------------------------ Fossil is also using LibreSSL: ------------------------------------------------------------------------ $ fossil version -v This is fossil version 2.28 [5ef8ac82c3] 2025-12-19 13:01:53 UTC Compiled on Dec 19 2025 08:36:58 using clang-16.0.6 (64-bit) SQLite 3.52.0 2025-12-11 23:24:05 01409738af SSL (LibreSSL 4.1.0) zlib 1.3.1.1-motley, loaded 1.3.1.1-motley libfuse 2.6, loaded unknown ------------------------------------------------------------------------ Curl works: ------------------------------------------------------------------------ $ curl -6 -i -k https://remote/project HTTP/1.0 302 Moved Temporarily Cache-control: no-cache Connection: close Content-Length: 75 Content-Type: text/html; charset=utf-8 Date: Fri, 19 Dec 2025 16:10:06 +0000 Location: https://remote/project/index X-Frame-Options: SAMEORIGIN X-UA-Compatible: IE=edge <html> <p>Redirect to Location: https://remote/project/index </p> </html> ------------------------------------------------------------------------ Fossil does not work. ------------------------------------------------------------------------ $ fossil clone https://remote/project project.fossil SSL: cannot connect to host remote:443 (bad hostname lookup) Clone done, wire bytes sent: 0 received: 0 remote: server returned an error - clone aborted Rerun using --httptrace for more detail ------------------------------------------------------------------------ Does this suggest that the problem is actually somewhere in the BIO routines that Fossil uses? Perhaps the BIO routines that Curl uses are different... time to look at Curl sources I guess.
(8) By absc (abiscuola) on 2025-12-18 17:43:08 in reply to 1 [link] [source]
I was going to open a thread for the exact same issue. The server is exposed to the internet through IPv6, with a tunnel reaching it with IPv4 for IPv4 only clients:
dick$ dig -t AAAA lab.abiscuola.com
; <<>> dig 9.10.8-P1 <<>> -t AAAA lab.abiscuola.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 8315
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;lab.abiscuola.com. IN AAAA
;; ANSWER SECTION:
lab.abiscuola.com. 85777 IN CNAME f1.ch.abiscuola.com.
f1.ch.abiscuola.com. 69223 IN AAAA 2a04:ee41:8:6055::14
;; Query time: 2 msec
;; SERVER: fd0f:ee:b0::1#53(fd0f:ee:b0::1)
;; WHEN: Thu Dec 18 18:34:50 CET 2025
;; MSG SIZE rcvd: 107
My laptop is IPv6 only:
trunk0: flags=248843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST,AUTOCONF6TEMP,AUTOCONF6> mtu 1500
lladdr 68:f7:28:fe:8e:b2
index 5 priority 0 llprio 3
trunk: trunkproto failover
iwm0 port active
em0 port master
groups: trunk egress
media: Ethernet autoselect
status: active
inet6 fe80::6af7:28ff:fefe:8eb2%trunk0 prefixlen 64 scopeid 0x5
inet6 2a01:e11:6450:a900:2895:d572:ac16:ac58 prefixlen 64 autoconf temporary pltime 52257 vltime 86362
inet6 2a01:e11:6450:a900:50f5:752f:a774:59de prefixlen 64 autoconf pltime 86362 vltime 86362
Trying to clone one of my repositories doesn't work:
dick$ fossil clone --httptrace https://lab.abiscuola.com/irctk
SSL: cannot connect to host lab.abiscuola.com:443 (Can't assign requested address)
Clone done, wire bytes sent: 0 received: 0 remote:
no such file: http-reply-0.txt
/***** Subprocess 58243 exit(1) *****/
However, connecting to the server with netcat works:
dick$ nc -vc6 lab.abiscuola.com 443
Connection to lab.abiscuola.com (2a04:ee41:8:6055::14) 443 port [tcp/https] succeeded!
TLS handshake negotiated TLSv1.3/TLS_CHACHA20_POLY1305_SHA256 with host lab.abiscuola.com
Peer name: lab.abiscuola.com
Subject: /CN=f1.ch.abiscuola.com
Issuer: /C=US/O=Let's Encrypt/CN=R13
Valid From: Sat Dec 6 15:32:10 2025
Valid Until: Fri Mar 6 15:32:09 2026
Cert Hash: SHA256:ffe2f108fd1a6935bc23e2568fec3d072b5e9fd2222eaa310f94ea1243df0617
My DNS servers are configured to properly resolve IPv6 addresses and even prefer those to IPv4 using the latter only as a fallback:
nameserver 2a01:4f9:c010:3f02::1
nameserver 2a00:1098:2b::1
nameserver 2a01:4f8:c2c:123f::1
family inet6 inet4
lookup file bind
I did some tests and it appears, but I don't have a final word for it, that on OpenBSD fossil while resolving a DNS name, always prefers IPv4 addresses, while ignoring IPv6 ones, even if you are on a IPv6-only machine.
If you need more informations, please let me know.
-- absc
(9) By Michael Price (spheno) on 2025-12-18 22:41:30 in reply to 8 [link] [source]
I have similar results here: michael@wg ~> fossil clone --xverbose --httptrace https://fossil-scm.org/ SSL: cannot connect to host fossil-scm.org:443 (Can't assign requested address) Clone done, wire bytes sent: 0 received: 0 remote: no such file: http-reply-0.txt /***** Subprocess 84594 exit(1) *****/ michael@wg ~> curl -v https://fossil-scm.org/ * Host fossil-scm.org:443 was resolved. * IPv6: 2600:3c02::f03c:95ff:fe07:695 * IPv4: (none) * Trying [2600:3c02::f03c:95ff:fe07:695]:443... * ALPN: curl offers h2,http/1.1 * TLSv1.3 (OUT), TLS handshake, Client hello (1): * CAfile: /etc/ssl/cert.pem * CApath: none * TLSv1.3 (IN), TLS handshake, Server hello (2): * TLSv1.3 (IN), TLS handshake, Unknown (8): * TLSv1.3 (IN), TLS handshake, Certificate (11): * TLSv1.3 (IN), TLS handshake, CERT verify (15): * TLSv1.3 (IN), TLS handshake, Finished (20): * TLSv1.3 (OUT), TLS handshake, Finished (20): * SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384 / [blank] / UNDEF * ALPN: server did not agree on a protocol. Uses default. * Server certificate: * subject: CN=a1.sqlite.org * start date: Dec 3 01:07:25 2025 GMT * expire date: Mar 3 01:07:24 2026 GMT * subjectAltName: host "fossil-scm.org" matched cert's "fossil-scm.org" * issuer: C=US; O=Let's Encrypt; CN=E8 * SSL certificate verify ok. * Certificate level 0: Public key type ? (256/128 Bits/secBits), signed using ecdsa-with-SHA384 * Certificate level 1: Public key type ? (384/192 Bits/secBits), signed using sha256WithRSAEncryption * Certificate level 2: Public key type ? (4096/128 Bits/secBits), signed using sha256WithRSAEncryption * Established connection to fossil-scm.org (2600:3c02::f03c:95ff:fe07:695 port 443) from <redacted> port 16558 * using HTTP/1.x > GET / HTTP/1.1 > Host: fossil-scm.org > User-Agent: curl/8.16.0 > Accept: */* > * Request completely sent off < HTTP/1.1 302 Moved Temporarily < Location: https://fossil-scm.org/home/doc/trunk/www/index.wiki < Cache-control: no-cache < X-Frame-Options: SAMEORIGIN < Content-Type: text/html; charset=utf-8 < Content-length: 99 < <html> <p>Redirect to Location: https://fossil-scm.org/home/doc/trunk/www/index.wiki </p> </html> * Connection #0 to host fossil-scm.org:443 left intact