0

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;
}
progquester
  • 1,228
  • 14
  • 23
  • *"I test it by following codes and tcpdump."* - please show your interfaces (`ip a`), your routes (`ip r`) and how you run the above program along with the output, otherwise this sentence doesn't mean anything. – Marco Bonelli Nov 07 '20 at 14:06
  • bind has no effect on packet routing. It sets what port and optionally what interface can receive connections. If you aren't listening and don't care about port, you don't need to call bind. – stark Nov 09 '20 at 14:37
  • @stark bind has two arguments, one is address, the other is port. You can bind to an address without specifying a port (port=0). Here we are not talking about the need for calling bind. We are just talking about how the calling take effect on routing. Thank you. – progquester Nov 12 '20 at 01:25

0 Answers0