4

I'm somewhat new to socket programming, and am confused about the concept of binding a socket to the address INADDR_LOOPBACK, or 127.0.0.1.

If I'm writing server code to listen for messages on a specific port, and I bind a socket to an address as in the following code exerpt...

int sd = socket( PF_INET, SOCK_DGRAM, 0 );
sockaddr_in si;
si.sin_family = AF_INET;
si.sin_addr.s_addr = inet_addr( "127.0.0.1" );
si.sin_port = htons( 9090 );
bind( sd, (sockaddr*)&si, sizeof si )

...my question is: who is able to send to this socket?

I know that other processes running on the same PC as the server process can reach the above socket, by doing a sendto() with a dest_addr argument specifying 127.0.0.1.

But can clients on other PCs on the same network also send to that socket if they know the server's "actual" address? What I mean is: if I run ifconfig on a Linux PC, I'll see an inet address, e.g. 10.138.19.27. Does this mean a client process on a different PC than the server, but on the same network, can send to the server's socket - which was bound to 127.0.0.1 - if the client specifies an address of 10.138.19.27?

StoneThrow
  • 5,314
  • 4
  • 44
  • 86
  • Also see [Understanding INADDR_ANY for socket programming](https://stackoverflow.com/q/16508685/608639) and [Loopback example using INADDR_LOOPBACK does not work](https://stackoverflow.com/q/16787812/608639) on Stack Overflow. – jww Jul 11 '17 at 00:43
  • @jww - Thanks, but I must be dense because I didn't understand from that post whether _other PCs on the same network_ can reach the LOOPBACK-binded socket. One answerer uses the phrase "If you wish to bind your socket to localhost *only* ". The "only" implies some kind of limited visibility, but I don't want to rely on my speculation. The second post appears to be demonstrating server + client on same PC. – StoneThrow Jul 11 '17 at 00:48
  • 2
    Yes, that's what it means. Whenever you send to 127.0.0.1 it goes to the loopback interface on the same machine. So there's no way to use that address to send something over the network. – Barmar Jul 11 '17 at 00:50
  • *"But can clients on other PCs on the same network also send to that socket"* - The loopback context is different for each host. While each host can send to `localhost`, `127.0.0.1` or `INADDR_LOOPBACK`, its ***their*** local host, and not another's local host. In fact, `127` addresses all designate local host and are not supposed to be routed or forwarded to a gateway by way of a default route. Now, on the network and using a non-local address, its a different story. It works as you would expect. Other hosts can connect to a listener. – jww Jul 11 '17 at 00:52
  • @Barmar - "there's no way to use that address to send something over the network" - forgive my denseness: do you mean that a client cannot reach the server's socket by using `127.0.0.1`? If so, I understand and agree with that. But could that client reach the server if it sent to `10.138.19.27` ? – StoneThrow Jul 11 '17 at 00:53
  • 3
    When you bind a socket to a specific address, it will only listen for connections coming to that address. So if it's bound to `127.0.0.1`, it won't accept connections to `10.138.19.27`, and vice versa. Only the special address `INADDR_ANY` will accept connections to any interface's address. – Barmar Jul 11 '17 at 00:55
  • @Barmar - I got you at last, thank you. In other words `127.0.0.1` is not automagically "aliased" to `10.138.19.27` - it is literally only `127.0.0.1`. I'm happy to give upvotes and answer points if you'd like to post as an answer. – StoneThrow Jul 11 '17 at 00:58
  • 1
    `127.0.0.1` never leaves the local machine. Its is not routed, and its not sent to the default route or to the default gateway. `10.138.19.27` can be either (1) ***this*** host, or (2) ***remote*** host. If its *this* host, then it is *not* routed by way of the default route, and it is *not* sent to the default gateway. It never leaves your machine. If its a *remote* host, then the segment is either (a) broadcast on the Local LAN based on the network mask; or (b) forwarded to the default gateway by way of the default route. – jww Jul 11 '17 at 00:58
  • 1
    This may help as well. It discusses networking and local host in the networking context, and not the programming context. [What is the difference between 127.0.0.1 and my assigned IPv4 address?](https://superuser.com/q/897699/173513) and [Can my default gateway of router be 127.0.0.1?](https://networkengineering.stackexchange.com/q/40153/8368) – jww Jul 11 '17 at 01:10

1 Answers1

5

Only connections to the loopback adapter (127.0.0.1), and those can only originate from the same machine as the listener since the other interfaces intentionally avoid rounding to that one.


When you don't bind or when you bind to INADDR_ANY (0.0.0.0), you accept connections from all interfaces.

Window 1                                    Window 2
------------------------------------------  ------------------------------------------
                                            $ nc -l 5678
$ echo test-ip | nc 69.163.162.155 5678     test-ip

$ echo $?
0
                                            $ nc -l 5678
$ echo test-localhost | nc localhost 5678   test-localhost

$ echo $?
0

When you bind to an IP address, you only accept connections directed to that IP address.

Window 1                                    Window 2
------------------------------------------  ------------------------------------------
                                            $ nc -l 69.163.162.155 5678
$ echo test-localhost | nc localhost 5678

$ echo $?
1

$ echo test-ip | nc 69.163.162.155 5678     test-ip

$ echo $?
0

The same goes for addresses in 127.x.x.x.

Window 1                                    Window 2
------------------------------------------  ------------------------------------------
                                            $ nc -l localhost 5678
$ echo test-ip | nc 69.163.162.155 5678

$ echo $?
1

$ echo test-localhost | nc localhost 5678   test-localhost

$ echo $?
0

The special thing about 127.x.x.x is that only your own machine can reach 127.x.x.x addresses.

ikegami
  • 367,544
  • 15
  • 269
  • 518
  • I was unfamiliar with `nc` so let me check that I understand what it demonstrates: in block 1, you bind `nc` to `INADDR_ANY` and prove that it receives dgrams to localhost as well as an "externally-facing" address (e.g. what I see when I type `ifconfig` ). In block 2, you bind `nc` to the "externally-facing" address only and prove that it doesn't receive dgrams to localhost. In block 3, you bind `nc` to localhost and prove that it doesn't receive dgrams to the "externally-facing" address. Is that correct? – StoneThrow Jul 11 '17 at 03:21
  • 1
    I guess my original confusion was that I thought "127.0.0.1" was some sort of "alias" for a "real" or "externally-facing" address. The superuser Q&A that @jww pointed me to was helpful because it explained that IP addresses bind to network interfaces. So the IP address "127.x.x.x" are actually bound to the loopback adapter. I think I have that right. – StoneThrow Jul 11 '17 at 03:24
  • 1
    Confirm the first comment, but the second is not quite right. Addresses are *assigned* to network interfaces. You *bind* a socket to a interface/address to only get the traffic addressed to that interface, as I demonstrated. – ikegami Jul 11 '17 at 04:43
  • Note that interfaces can route to each other, but 127.x.x.x is an exception to that. You should not create routes from other interfaces to 127.x.x.x. – ikegami Jul 11 '17 at 04:44