I don’t think the precise code is important. Instead, I’ll give the strace output:
socket(AF_INET, SOCK_STREAM, IPPROTO_IP) = 5 fcntl(5, F_SETFL, O_WRONLY|O_NONBLOCK) = 0 epoll_ctl(3, EPOLL_CTL_ADD, 5, {EPOLLIN|EPOLLOUT|EPOLLRDHUP|EPOLLET, {u32=209357450, u64=94373525752458}}) = 0 setsockopt(5, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 bind(5, {sa_family=AF_INET, sin_port=htons(31337), sin_addr=inet_addr("0.0.0.0")}, 16) = 0 listen(5, 10) = 0 accept(5, 0x7f2a6aade440, [110]) = -1 EAGAIN (Resource temporarily unavailable) stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2265, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2265, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2265, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2265, ...}) = 0 write(1, "33[1;30m09:44:34.62533[0m34222420233[36m0"..., 130) = 130 socket(AF_INET6, SOCK_STREAM, IPPROTO_IP) = 6 fcntl(6, F_SETFL, O_WRONLY|O_NONBLOCK) = 0 epoll_ctl(3, EPOLL_CTL_ADD, 6, {EPOLLIN|EPOLLOUT|EPOLLRDHUP|EPOLLET, {u32=209357482, u64=94373525752490}}) = 0 setsockopt(6, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 bind(6, {sa_family=AF_INET6, sin6_port=htons(31337), inet_pton(AF_INET6, "::", &sin6_addr), sin6_flowinfo=htonl(0), sin6_scope_id=0}, 28) = -1 EADDRINUSE (Address already in use)
We can see that socket 5 (IPv4) successfully bound to port any:31337, but when I try to bind socket 6 (IPv6), it fails with EADDRINUSE
.
You can also see that I did set SO_REUSEADDR
on both sockets, so I believe this problem should not have happened.
$ lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 17.10 Release: 17.10 Codename: artful
Advertisement
Answer
You don’t need to listen to both IPv4 and IPv6, as listening for IPv6 connections is sufficient. Incoming IPv4 connections will be handled by a socket listing for IPv6 connections. The client addresses might show in a format like ::FFFF:192.168.1.1
then.