Consider the case of a redis instance which is acting as a slave of a remote instance, for read by local processes.

That is:

redis-server --bind 127.0.0.1 --slaveof 1.2.3.4 10345

In src/replication.c, connectWithMaster() passes NET_FIRST_BIND_ADDR, a macro which extends to (server.bindaddr_count ? server.bindaddr[0] : NULL). This is not documented in the redis.conf config example/documentation for bind, neither for slaveof.

In consequence, the outbound connection in the case above tries to bind to 127.0.0.1 before connecting to 1.2.3.4, preventing the connection from ever completing. (Moreover, in order to connect to 1.2.3.4 as a client, this requires a Redis instance to have also be listening as a server on an interface that can route to that address; this is a significant restriction on the set of possible configurations).

Similar issues occur if the first bind address is an IPv4 address and the master connection is to an IPv6 address.


If NET_FIRST_BIND_ADDR is going to be used at all (rather than letting the operating system select an bind interface for the client socket itself), the importance of the ordering between bind addresses (lack of parity between initial and subsequent) should be clearly documented.

Comment From: danielkucera

I just met this now:

13:12:57.381666 IP 127.0.0.1.44018 > 10.10.121.103.6379: Flags [S], seq 1133304429, win 29200, options [mss 1460,sackOK,TS val 1053178304 ecr 0,nop,wscale 7], length 0

which of course cannot be ACKed and results in

# Timeout connecting to the MASTER...

Comment From: jstangroome

The introduction of the bind-source-addr configuration option in redis 7.x should allow the source IP used for connections to the remote redis to be different from the listening IP.

See #9142.