From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from localhost (localhost [127.0.0.1]) by turing.freelists.org (Avenir Technologies Mail Multiplex) with ESMTP id 0EDC42EA42 for ; Tue, 14 May 2019 19:06:30 -0400 (EDT) Received: from turing.freelists.org ([127.0.0.1]) by localhost (turing.freelists.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 6Bu-TjZPclx3 for ; Tue, 14 May 2019 19:06:29 -0400 (EDT) Received: from smtpng3.m.smailru.net (smtpng3.m.smailru.net [94.100.177.149]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by turing.freelists.org (Avenir Technologies Mail Multiplex) with ESMTPS id 8B0032EA45 for ; Tue, 14 May 2019 19:06:29 -0400 (EDT) From: Vladislav Shpilevoy Subject: [tarantool-patches] [PATCH 3/7] swim: do not rebind when new 'port' is 0 Date: Wed, 15 May 2019 02:06:21 +0300 Message-Id: <22d5641734c11687a5adf489d7e49dc1de544239.1557875116.git.v.shpilevoy@tarantool.org> In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: tarantool-patches-bounce@freelists.org Errors-to: tarantool-patches-bounce@freelists.org Reply-To: tarantool-patches@freelists.org List-Help: List-Unsubscribe: List-software: Ecartis version 1.0.0 List-Id: tarantool-patches List-Subscribe: List-Owner: List-post: List-Archive: To: tarantool-patches@freelists.org Cc: kostja@tarantool.org 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 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 , new , 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)