I have a server implementation where I need 2 separate sockets - 1 IPv4 socket socket listening on a particular IPv4 address and server port X, and an IPv6 socket listening on a particular IPv6 address and same server port X. The IPv4 and IPv6 addresses are on the same interface.
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = htonl(v4addr);
sin.sin_port = htons(tcp_port);
I am using evconnlistener_new_bind to create ipv4 socket and bind to it. For IPv6 listener, the code is as below.
memset(&sin6, 0, sizeof(sin6));
sin6.sin6_family = AF_INET6;
memcpy(sin6.sin6_addr.s6_addr, v6addr_bytes, IPV6_ADDR_LEN);
sin6.sin6_port = htons(tcp_port);
fd = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
evutil_make_socket_nonblocking(fd)
setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (void*)&on, sizeof(on))
setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (void*)&on, sizeof(on))
evutil_make_listen_socket_reuseable(fd) /* Libevent call to set SO_REUSEADDR */
evutil_make_socket_nonblocking(fd) /* Libevent call to set fd non-blocking */
bind(fd, (const struct sockaddr *)&sin6, sizeof(sin6))
As I bind my fd to the particular ipv6 address, I see a bind failure intermittently.
bind v6 failed sin6 3ffe::a00:513 - errno 99 - Cannot assign requested address
I tried to gdb in, but every time I gdb in, the bind succeeds.
I am not sure why I am seeing this problem. Can someone please help?
By default, after a socket is bound to a TCP port, the port remains reserved for one minute when the socket is closed — this is called the TCP TIME_WAIT
state. TIME_WAIT
avoids some race conditions that could cause data corruption, but it is usually safe to ignore TIME_WAIT
on the server side.
This is done by setting the SO_REUSEADDR
socket option:
int one = 1;
rc = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With