1
votes

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.625\33[0m\342\224\202\33[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
1
Are you trying to listen on the same port twice, once with IPv4 and once with IPv6? This shouldn't be necessary, as listening to IPv6 should also listen for IPv4, with addresses showing like ::FFFF:192.168.1.1 - Karsten Koop
Yes, that was it. Please phrase as an answer if you want me to accept. - Shachar Shemesh

1 Answers

2
votes

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.