57

We are serving a port on localhost and want to check in another process if the port is available. Due to a bug in our code, it is actually trying to connect to the IP 0.0.0.0:<port>, and for some reason it succeeds -- as strace proves:

[...]
connect(3, {sa_family=AF_INET, sin_port=htons(10002), sin_addr=inet_addr("0.0.0.0")}, 16) = 0
[...]

What does it mean? Why does it work?

GAD3R
  • 63,407
  • 31
  • 131
  • 192
erikbstack
  • 940
  • 2
  • 9
  • 16

1 Answers1

84

0.0.0.0 as a target address refers variously to a non-routable host or to “this host” (RFC 5735 section 3). In practice connecting to 0.0.0.0 is, in most scenarios, equivalent to connecting to localhost. Strictly speaking it isn’t valid as a destination address, on the wire (RFC 1122 section 3.2.1.3), only as a source address, so the operating system has to ensure that a packet with destination address of 0.0.0.0 doesn’t leave the system as-is. In practice, when the Linux kernel sees a packet with a destination address of 0.0.0.0 (i.e. no destination address), it copies the source address to the destination address, and if the packet doesn’t have a source address either, it sets both to the loopback address. In both cases the packet is “sent out” over the loopback interface, so it never leaves the system.

When binding, “this host” expands to “any address on this host” — so applications commonly accept connections by binding to 0.0.0.0, which means they’ll receive packets addressed to any IPv4 address on the system.

Stephen Kitt
  • 411,918
  • 54
  • 1,065
  • 1,164
  • 10
    To extend this answer a little - it means "any IP address on this system, including IPs that have been added after the listening process started" – Criggie Jan 27 '18 at 09:23
  • 6
    localhost is a single address, mostly 127.0.0.1, while 0.0.0.0 means all addresses on this host. – rexkogitans Jan 27 '18 at 11:21
  • @rexkogitans localhost is not a single address, but any address in the range 127.0.0.0/8 - i.e. any address from 127.0.0.0 to 127.255.255.255 – Dezza Jan 27 '18 at 15:05
  • 7
    @Dezza No, localhost is 127.0.0.1. 127.0.0.0/8 (as you say, a.k.a. 127.0.0.0 through 127.255.255.255) is loopback with most equipment, e.g. documented by [RFC 5735 page 4](https://tools.ietf.org/html/rfc5735#page-4). (Interestingly, some Cisco equipment can assign loopback to any address, but defaults to not supporting loopback at all. Not that this is likely to affect other equipment on the network.) However, localhost is a name, typically pointing to just to a single address which is 127.0.0.1, and commonly implemented by using a "hosts" file. So I disagree with your attempted correction. – TOOGAM Jan 27 '18 at 19:11
  • Could you clarify what you mean by "it isn’t valid as a destination address, only as a source address"? When mysql server listens at 0.0.0.0, is the address destination or source? Is it not the destination of a request sent from a mysql client? – Tim Mar 22 '19 at 20:08
  • I’m not sure how to clarify. When MySQL listens on 0.0.0.0, that corresponds to the second paragraph of my answer. A client can connect to the server using any valid address for the server, reachable by the client; but not using 0.0.0.0, unless the server is on the same system as the client. – Stephen Kitt Mar 22 '19 at 20:31
  • So you mean a client can't use 0.0.0.0 as destination. How can it be used as a source? – Tim Mar 22 '19 at 20:48
  • Where did I say a client *can’t* use 0.0.0.0? I’ve explained what happens when a client connects to 0.0.0.0, which implies that it is possible (even though theory says it isn’t). 0.0.0.0 is used as a source address when the real source address isn’t known, *e.g.* for DHCP requests. – Stephen Kitt Mar 23 '19 at 09:08
  • Does 0.0.0.0 have two completely different meanings? A process specifies its own unknown address to another process not in the same host. A process specifies that it is listening on all the addresses on the local host? – Tim Mar 23 '19 at 15:45
  • 1
    Please forgive my OCD, maybe I missed something: `Strictly speaking it isn’t valid as a destination address` This doesn't appear to be defined in RFC 5735; if it is then using 0.0.0.0 to mean "non-routable" is equally invalid as it uses an address reserved for a different purpose. RFC 1122 section 3.2.1.3 (a) states 0.0.0.0 is only valid as a source address but RFC 1122 only applies to transmission over the wire. So in terms of OS behaviour and sockets, a 0.0.0.0 destination address appears valid as long as it never results in an IP packet transmitted thus. AFAIK Linux doesn't. – Philip Couling Nov 18 '22 at 20:22
  • @Philip you’re right, it only matters on the wire; I’ve updated the answer (thanks for insisting!). – Stephen Kitt Nov 19 '22 at 13:46