How to make COOL listen to both IPv4 and IPv6?

Hi,

I’m building COOL (24.04) on Ubuntu 24.04, and in coolwsd.xml.in there is a comment:

  <!-- On systems where localhost resolves to IPv6 [::1] address first, when net.proto is all and net.listen is loopback, coolwsd unexpectedly listens on [::1] only.
       You need to change net.proto to IPv4, if you want to use 127.0.0.1. -->

However, in the default settings, net.proto is all and net.listen is any instead of loopback, and after make run it still listen to IPv6 only. I had to change net.proto to IPv4 to make it listen to IPv4. How could I get it to listen both IPv4 and IPv6? Either to change in the settings or the code, or the OS?

hii @lodev welcome

Check Your System’s Default Bind Preference

On some systems, when an application binds to [::], it only listens for IPv6 connections. Check your system’s behavior using:

sysctl net.ipv6.bindv6only
  • If the value is 1, it means your system is restricting [::] to IPv6 only.

Thanks
Darshan

Thanks for answering, but no, in my (fresh) ubuntu 24.04 this is not 1.

$ sysctl net.ipv6.bindv6only
net.ipv6.bindv6only = 0

First, confirm what COOL is actually binding to:

  1. Run sudo netstat -tuln | grep 9980 (assuming COOL uses the default port 9980).
  2. Look at the output:
  • tcp6 0 0 :::9980 :::* LISTEN: Indicates IPv6 only.
  • tcp 0 0 0.0.0.0:9980 0.0.0.0:* LISTEN: Indicates IPv4 only.
  • Two lines (tcp and tcp6) would indicate both.

Adjust OS Network Settings

OS might prioritize IPv6 in a way that affects COOL’s binding:

  1. Check IPv6 Preference:
  • Run cat /etc/gai.conf and look for precedence or label directives. If IPv6 is strongly preferred, it might influence the socket behavior.
  • Temporarily disable IPv6 to test: sudo sysctl -w net.ipv6.conf.all.disable_ipv6=1. Then run COOL and check if it switches to IPv4. Re-enable with 0 afterward.

In my ubuntu 24.04:

$ netstat -tuln | grep 9980
tcp6       0      0 :::9980                 :::*                    LISTEN   

In my coolwsd.xml:

    <net desc="Network settings">
      <!-- On systems where localhost resolves to IPv6 [::1] address first, when net.proto is all and net.listen is loopback, coolwsd unexpectedly listens on [::1] only.
           You need to change net.proto to IPv4, if you want to use 127.0.0.1. -->
      <proto type="string" default="all" desc="Protocol to use IPv4, IPv6 or all for both">all</proto>
      <listen type="string" default="any" desc="Listen address that coolwsd binds to. Can be 'any' or 'loopback'.">any</listen>

All the lines in /etc/gai.conf are commented out.

After disabling ipv6, netstat -tuln still shows tcp6 only.

$ netstat -tuln | grep 9980
tcp6       0      0 :::9980                 :::*                    LISTEN   

hii @lodev

As there is discussion on matrix about this issue Michael suggested

  1. Could you grab an strace of coolwsd to check what parameters are being passed to the listen system call? That should help clarify whether it’s binding as expected or if something else is interfering.

  2. Also, running lsof -p <pid-of-coolwsd> might reveal useful details about what addresses and ports it’s actually listening on

And yes, you can join the public discussion channel—or as we call it, the Matrix channel—here: COOL Dev Matrix Channel!

Thanks
Darshan

Not sure how to do it and what to look. I ran strace ./coolwsd and got a lot of output. It was a lot, so I paste something I think it may be helpful here:

socket(AF_INET6, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, IPPROTO_IP) = 14
setsockopt(14, SOL_TCP, TCP_NODELAY, [1], 4) = 0
getpid()                                = 139547
gettid()                                = 139547
setsockopt(14, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
setsockopt(14, SOL_IPV6, IPV6_V6ONLY, [0], 4) = 0
bind(14, {sa_family=AF_INET6, sin6_port=htons(9980), sin6_flowinfo=htonl(0), inet_pton(AF_INET6, "::", &sin6_addr), sin6_scope_id=0}, 28) = 0
getpid()                                = 139547
gettid()                                = 139547
listen(14, 64)                          = 0
getpid()                                = 139547
gettid()                                = 139547
getpid()                                = 139547
gettid()                                = 139547
write(2, "wsd-139547-139547 2025-03-26 14:"..., 536wsd-139547-139547 2025-03-26 14:26:58.728116 +0800 [ coolwsd ] DBG  #14: Created socket. Thread affinity set to 0x7ec9f5a99880, Socket[#14, All @ :0]| net/Socket.hpp:474
wsd-139547-139547 2025-03-26 14:26:58.728645 +0800 [ coolwsd ] TRC  #14: Bind to: IPv6 port: 9980| net/Socket.cpp:1149
wsd-139547-139547 2025-03-26 14:26:58.728869 +0800 [ coolwsd ] TRC  #14: Listening| net/ServerSocket.hpp:81
wsd-139547-139547 2025-03-26 14:26:58.728999 +0800 [ coolwsd ] INF  #14 Listening to client connections on port 9980| wsd/COOLWSD.cpp:3510
) = 536
getpid()                                = 139547

I’m sure in coolwsd.xml(.in) the proto is all and listen is any. It still looks like only bound to IPv6.
(There is a setsockopt setting the socket option as 'IPV6_V6only`. I’m not sure if it is the cause or not, or where it comes from.

The only place mentioning IPv4 in this strace log is

read(4, "IPv4-mapped IPv6 addresses\">::ff"..., 4092) = 4092

Here is the output of lsof when I ran strace ./coolwsd above:

COMMAND    PID  USER   FD   TYPE             DEVICE SIZE/OFF    NODE NAME
coolwsd 139547 lodev  cwd    DIR              252,0     4096 1842768 /home/lodev/git/COOL
coolwsd 139547 lodev  rtd    DIR              252,0     4096       2 /
coolwsd 139547 lodev  txt    REG              252,0 79997992 1884790 /home/lodev/git/COOL/coolwsd
coolwsd 139547 lodev  mem    REG              252,0  5866528 2892100 /usr/lib/locale/locale-archive
coolwsd 139547 lodev  mem    REG              252,0   360460 2884339 /usr/lib/locale/C.utf8/LC_CTYPE
coolwsd 139547 lodev  mem    REG              252,0  2125328 2903539 /usr/lib/x86_64-linux-gnu/libc.so.6
coolwsd 139547 lodev  mem    REG              252,0   129256 2884837 /usr/lib/x86_64-linux-gnu/ossl-modules/legacy.so
coolwsd 139547 lodev  mem    REG              252,0   625344 2890413 /usr/lib/x86_64-linux-gnu/libpcre2-8.so.0.11.2
coolwsd 139547 lodev  mem    REG              252,0   952616 2903542 /usr/lib/x86_64-linux-gnu/libm.so.6
coolwsd 139547 lodev  mem    REG              252,0  2592224 2903090 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.33
coolwsd 139547 lodev  mem    REG              252,0    26848 2899003 /usr/lib/x86_64-linux-gnu/libcap-ng.so.0.0.0
coolwsd 139547 lodev  mem    REG              252,0   170240 2884608 /usr/lib/x86_64-linux-gnu/libexpat.so.1.9.1
coolwsd 139547 lodev  mem    REG              252,0   133200 2886113 /usr/lib/x86_64-linux-gnu/libaudit.so.1.0.0
coolwsd 139547 lodev  mem    REG              252,0   183024 2897496 /usr/lib/x86_64-linux-gnu/libgcc_s.so.1
coolwsd 139547 lodev  mem    REG              252,0   293040 2896886 /usr/lib/x86_64-linux-gnu/libPocoCrypto.so.103
coolwsd 139547 lodev  mem    REG              252,0  2017952 2896883 /usr/lib/x86_64-linux-gnu/libPocoFoundation.so.103
coolwsd 139547 lodev  mem    REG              252,0   514240 2896897 /usr/lib/x86_64-linux-gnu/libPocoXML.so.103
coolwsd 139547 lodev  mem    REG              252,0   321720 2896889 /usr/lib/x86_64-linux-gnu/libPocoJSON.so.103
coolwsd 139547 lodev  mem    REG              252,0   448696 2896898 /usr/lib/x86_64-linux-gnu/libPocoUtil.so.103
coolwsd 139547 lodev  mem    REG              252,0  1366288 2896895 /usr/lib/x86_64-linux-gnu/libPocoNet.so.103
coolwsd 139547 lodev  mem    REG              252,0    67888 2899439 /usr/lib/x86_64-linux-gnu/libpam.so.0.85.1
coolwsd 139547 lodev  mem    REG              252,0  5305304 2884762 /usr/lib/x86_64-linux-gnu/libcrypto.so.3
coolwsd 139547 lodev  mem    REG              252,0       50 2884545 /usr/lib/locale/C.utf8/LC_NUMERIC
coolwsd 139547 lodev  mem    REG              252,0   113000 2899721 /usr/lib/x86_64-linux-gnu/libz.so.1.3
coolwsd 139547 lodev  mem    REG              252,0     3360 2884635 /usr/lib/locale/C.utf8/LC_TIME
coolwsd 139547 lodev  mem    REG              252,0     1406 2884322 /usr/lib/locale/C.utf8/LC_COLLATE
coolwsd 139547 lodev  mem    REG              252,0      270 2884541 /usr/lib/locale/C.utf8/LC_MONETARY
coolwsd 139547 lodev  mem    REG              252,0       48 2884504 /usr/lib/locale/C.utf8/LC_MESSAGES/SYS_LC_MESSAGES
coolwsd 139547 lodev  mem    REG              252,0       34 2884546 /usr/lib/locale/C.utf8/LC_PAPER
coolwsd 139547 lodev  mem    REG              252,0       62 2884544 /usr/lib/locale/C.utf8/LC_NAME
coolwsd 139547 lodev  mem    REG              252,0      127 2884281 /usr/lib/locale/C.utf8/LC_ADDRESS
coolwsd 139547 lodev  mem    REG              252,0       47 2884576 /usr/lib/locale/C.utf8/LC_TELEPHONE
coolwsd 139547 lodev  mem    REG              252,0       23 2884398 /usr/lib/locale/C.utf8/LC_MEASUREMENT
coolwsd 139547 lodev  mem    REG              252,0    27028 2903528 /usr/lib/x86_64-linux-gnu/gconv/gconv-modules.cache
coolwsd 139547 lodev  mem    REG              252,0      258 2884341 /usr/lib/locale/C.utf8/LC_IDENTIFICATION
coolwsd 139547 lodev  mem    REG              252,0   236616 2903536 /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
coolwsd 139547 lodev    0u   CHR              136,1      0t0       4 /dev/pts/1
coolwsd 139547 lodev    1w   REG              252,0  1568428 1861625 /home/lodev/git/COOL/strace.log
coolwsd 139547 lodev    2w   REG              252,0  1568428 1861625 /home/lodev/git/COOL/strace.log
coolwsd 139547 lodev    3r   CHR                1,9      0t0      10 /dev/urandom
coolwsd 139547 lodev    4r  FIFO               0,15      0t0  146612 pipe
coolwsd 139547 lodev    5w  FIFO               0,15      0t0  146612 pipe
coolwsd 139547 lodev    6r  FIFO               0,15      0t0  146613 pipe
coolwsd 139547 lodev    7w  FIFO               0,15      0t0  146613 pipe
coolwsd 139547 lodev    8r  FIFO               0,15      0t0  146614 pipe
coolwsd 139547 lodev    9w  FIFO               0,15      0t0  146614 pipe
coolwsd 139547 lodev   10r  FIFO               0,15      0t0  146615 pipe
coolwsd 139547 lodev   11w  FIFO               0,15      0t0  146615 pipe
coolwsd 139547 lodev   12r  FIFO               0,15      0t0  146618 pipe
coolwsd 139547 lodev   13w  FIFO               0,15      0t0  146618 pipe
coolwsd 139547 lodev   14u  IPv6             146619      0t0     TCP *:9980 (LISTEN)
coolwsd 139547 lodev   15u  unix 0x0000000000000000      0t0  146620 @coolwsd-aJqZVnv6@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ type=STREAM (LISTEN)

Looks like it only listen to IPv6 as well.