I'm developing a server application on Linux and have a question about socket binding behavior when using INADDR_ANY
and specific IP addresses. My test setup involves two sockets:
INADDR_ANY
, meaning it listens on all available IP addresses.192.168.1.4
.My question is:
If a client attempts to connect to 192.168.1.4
on port 80, is there any possibility that the connection could be handled by the socket bound to INADDR_ANY
instead of the one explicitly bound to 192.168.1.4
?
I am also using the SO_REUSEPORT
socket option on both sockets. Could this affect how the connections are routed, or is it purely related to allowing both sockets to bind to the same port without error?
Here is the relevant snippet of how I'm binding the sockets:
// Test Program //
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <arpa/inet.h>
int main() {
int sock1 = socket(AF_INET, SOCK_STREAM, 0);
int sock2 = socket(AF_INET, SOCK_STREAM, 0);
int optval = 1;
setsockopt(sock1, SOL_SOCKET, SO_REUSEPORT, &optval, sizeof(optval));
setsockopt(sock2, SOL_SOCKET, SO_REUSEPORT, &optval, sizeof(optval));
// Socket 1: Bind to INADDR_ANY (all interfaces)
struct sockaddr_in addr1;
addr1.sin_family = AF_INET;
addr1.sin_addr.s_addr = htonl(INADDR_ANY);
addr1.sin_port = htons(80);
if (bind(sock1, (struct sockaddr*)&addr1, sizeof(addr1)) < 0) {
perror("bind failed for sock1");
exit(1);
}
// Socket 2: Bind to specific IP address
struct sockaddr_in addr2;
addr2.sin_family = AF_INET;
addr2.sin_addr.s_addr = inet_addr("192.168.1.4");
addr2.sin_port = htons(80);
if (bind(sock2, (struct sockaddr*)&addr2, sizeof(addr2)) < 0) {
perror("bind failed for sock2");
exit(1);
}
int rval1 = listen(sock1, 5);
if (rval1 == -1) {
perror("listen failed for sock1");
exit(1);
}
int rval2 = listen(sock2, 5);
if (rval2 == -1) {
perror("listen failed for sock2");
exit(1);
}
printf("%s\n", "Exiting test program");
}
INADDR_ANY
listens on all available IPs, while the other socket only listens on 192.168.1.4
.SO_REUSEPORT
option allows both sockets to bind to the same port without errors, but as far as I understand, it doesn’t control which socket handles incoming connections.192.168.1.4:80
could be handled by the INADDR_ANY
socket?SO_REUSEPORT
play here? Does it impact which socket handles incoming connections, or is it only relevant during the binding process?I want to ensure that any connections targeting 192.168.1.4:80
are always handled by the second socket (the one explicitly bound to that address), and connections to other IPs (e.g., 127.0.0.1:80
) are handled by the INADDR_ANY
socket.
Any clarification or confirmation of how Linux handles this would be greatly appreciated!
The SO_REUSEADDR
option on TCP sockets only allows you to listen/bind a port if there's an outstanding connection from a prior run of the program that hasn't yet fully closed. It doesn't actually allow you to have multiple listening sockets open on the same IP/port.
The code above binds the sockets, but you haven't yet attempted to listen on either one. If you attempt to do so:
rval = listen(sock1, 5);
if (rval==-1) {
perror("listen failed for sock1");
exit(1);
}
rval = listen(sock2, 5);
if (rval==-1) {
perror("listen failed for sock2");
exit(1);
}
One of them will fail:
listen failed for sock2: Address already in use
You should only have one listening socket bound to INADDR_ANY
, as that will handle any incoming connection on port 80, regardless of the interface.
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