[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