Before connecting to the remote server, the socket has called bind()
to bind one of the host's ip address. How does kernel route for address bound socket?
Answer from Does routing affect a socket with a bound source address? said kernel should not route for this socket, because it has been bound to a specific address.
But answer from Choosing socket output interface: SO_BINDTODEVICE vs bind before connect said the source address take no effect on routing, just destination address does.
I wonder which is right?
I test it by following codes and tcpdump. In my PC, Linux tuntest 4.15.0-122-generic #124-Ubuntu SMP Thu Oct 15 13:03:05 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
, the first answer is right: always sent by the bound interface. Could someone show me the related source code in Linux kernel?
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
int main(int argc, char* argv[])
{
int sock;
in_addr_t cip, sip;
struct sockaddr_in caddr, saddr;
cip = inet_addr(argv[1]);
if (cip == INADDR_NONE) {
fprintf(stderr, "bound address %s is invalid\n", argv[1]);
return -1;
}
sip = inet_addr(argv[2]);
if (sip == INADDR_NONE) {
fprintf(stderr, "server address %s is invalid\n", argv[2]);
return -1;
}
caddr.sin_family = AF_INET;
caddr.sin_addr.s_addr = cip;
caddr.sin_port = 0;
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock == -1) {
perror("failed to create socket:");
return -1;
}
printf("Bind to %s ... ", argv[1]);
if (bind(sock, (const struct sockaddr *)&caddr, sizeof(caddr)) != 0) {
perror("failed to bind to local.");
return -1;
}
printf("done.\n");
saddr.sin_family=AF_INET;
saddr.sin_addr.s_addr = sip;
saddr.sin_port = htons(443);
printf("Start to connect to server %s ... ", argv[2]);
if (connect(sock, (const struct sockaddr *)&saddr, sizeof(saddr)) != 0) {
perror("failed to connect to server.");
return -1;
}
printf("done.\n");
return 0;
}