[tarantool-patches] [PATCH 3/7] swim: do not rebind when new 'port' is 0

Vladislav Shpilevoy v.shpilevoy at tarantool.org
Wed May 15 02:06:21 MSK 2019


SWIM internally tries to avoid unnecessary close+socket+bind
calls on reconfiguration if a new URI is the same as an old one.
SWIM transport compares <IP, port> couples and if they are
equal, does nothing.

But if a port is 0, it is not a real port, but a sign to the
kernel to find any free port on the IP address. In such a case
SWIM transport after bind() retrieves and saves a real port.

When the same URI is specified again, the transport compares two
addresses: old <IP, auto found port>, new <IP, 0>, sees they are
'different', and rebinds. It is not necessary, obviously, because
the new URI covers the old one.

This commit avoids rebind, when new IP == old IP, and new port is
0.

Part of #3234
---
 src/lib/swim/swim_transport_udp.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/src/lib/swim/swim_transport_udp.c b/src/lib/swim/swim_transport_udp.c
index f017eeaf0..c0317a20b 100644
--- a/src/lib/swim/swim_transport_udp.c
+++ b/src/lib/swim/swim_transport_udp.c
@@ -64,11 +64,21 @@ swim_transport_bind(struct swim_transport *transport,
 	const struct sockaddr_in *new_addr = (const struct sockaddr_in *) addr;
 	const struct sockaddr_in *old_addr = &transport->addr;
 	assert(addr_len == sizeof(*new_addr));
+	bool is_new_port_any = new_addr->sin_port == 0;
 
 	if (transport->fd != -1 &&
 	    new_addr->sin_addr.s_addr == old_addr->sin_addr.s_addr &&
-	    new_addr->sin_port == old_addr->sin_port)
+	    (new_addr->sin_port == old_addr->sin_port || is_new_port_any)) {
+		/*
+		 * Note, that new port == 0 means that any port is
+		 * ok. If at the same time old and new IP
+		 * addresses are the same and the socket is
+		 * already bound (fd != -1), then the existing
+		 * socket 'matches' the new URI and rebind is not
+		 * needed.
+		 */
 		return 0;
+	}
 
 	int fd = sio_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
 	if (fd < 0)
@@ -81,7 +91,7 @@ swim_transport_bind(struct swim_transport *transport,
 		return -1;
 	}
 	int real_port = new_addr->sin_port;
-	if (new_addr->sin_port == 0) {
+	if (is_new_port_any) {
 		struct sockaddr_in real_addr;
 		addr_len = sizeof(real_addr);
 		if (sio_getsockname(fd, (struct sockaddr *) &real_addr,
-- 
2.20.1 (Apple Git-117)





More information about the Tarantool-patches mailing list