]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: tcp/udp/unix: make use of proto->addrcmp() to compare addresses
authorWilly Tarreau <w@1wt.eu>
Fri, 28 Aug 2020 13:30:11 +0000 (15:30 +0200)
committerWilly Tarreau <w@1wt.eu>
Fri, 28 Aug 2020 16:51:36 +0000 (18:51 +0200)
The new addrcmp() protocol member points to the function to be used to
compare two addresses of the same family.

When picking an FD from a previous process, we can now use the address
specific address comparison functions instead of having to rely on a
local implementation. This will help move that code to a more central
place.

include/haproxy/protocol-t.h
src/proto_tcp.c
src/proto_udp.c
src/proto_uxst.c

index c490d798f8a3da7a7b3d249d5f67d945669203cf..247ba58f5bf8adb50837d670b0928d6bf1ceb8e6 100644 (file)
@@ -83,6 +83,7 @@ struct protocol {
        int (*drain)(int fd);                           /* indicates whether we can safely close the fd */
        int (*pause)(struct listener *l);               /* temporarily pause this listener for a soft restart */
        void (*add)(struct listener *l, int port);      /* add a listener for this protocol and port */
+       int (*addrcmp)(const struct sockaddr_storage *, const struct sockaddr_storage *); /* compare addresses (like memcmp) */
 
        struct list listeners;                          /* list of listeners using this protocol (under proto_lock) */
        int nb_listeners;                               /* number of listeners (under proto_lock) */
index 5d1bc1ec7808ae11554aed60876fc5bb9272882e..17da4033d484f747c40e84a38435995d8e0879b7 100644 (file)
@@ -40,6 +40,7 @@
 #include <haproxy/protocol.h>
 #include <haproxy/proxy-t.h>
 #include <haproxy/sock.h>
+#include <haproxy/sock_inet.h>
 #include <haproxy/tools.h>
 
 
@@ -67,6 +68,7 @@ static struct protocol proto_tcpv4 = {
        .get_dst = tcp_get_dst,
        .pause = tcp_pause_listener,
        .add = tcpv4_add_listener,
+       .addrcmp = sock_inet4_addrcmp,
        .listeners = LIST_HEAD_INIT(proto_tcpv4.listeners),
        .nb_listeners = 0,
 };
@@ -92,6 +94,7 @@ static struct protocol proto_tcpv6 = {
        .get_dst = tcp_get_dst,
        .pause = tcp_pause_listener,
        .add = tcpv6_add_listener,
+       .addrcmp = sock_inet6_addrcmp,
        .listeners = LIST_HEAD_INIT(proto_tcpv6.listeners),
        .nb_listeners = 0,
 };
@@ -610,35 +613,6 @@ int tcp_get_dst(int fd, struct sockaddr *sa, socklen_t salen, int dir)
        }
 }
 
-/* XXX: Should probably be elsewhere */
-static int compare_sockaddr(struct sockaddr_storage *a, struct sockaddr_storage *b)
-{
-       if (a->ss_family != b->ss_family) {
-               return (-1);
-       }
-       switch (a->ss_family) {
-       case AF_INET:
-               {
-                       struct sockaddr_in *a4 = (void *)a, *b4 = (void *)b;
-                       if (a4->sin_port != b4->sin_port)
-                               return (-1);
-                       return (memcmp(&a4->sin_addr, &b4->sin_addr,
-                           sizeof(a4->sin_addr)));
-               }
-       case AF_INET6:
-               {
-                       struct sockaddr_in6 *a6 = (void *)a, *b6 = (void *)b;
-                       if (a6->sin6_port != b6->sin6_port)
-                               return (-1);
-                       return (memcmp(&a6->sin6_addr, &b6->sin6_addr,
-                           sizeof(a6->sin6_addr)));
-               }
-       default:
-               return (-1);
-       }
-
-}
-
 /* Returns true if the passed FD corresponds to a socket bound with LI_O_FOREIGN
  * according to the various supported socket options. The socket's address family
  * must be passed in <family>.
@@ -747,7 +721,7 @@ static int tcp_find_compatible_fd(struct listener *l)
        options &= ~LI_O_V4V6;
 
        while (xfer_sock) {
-               if (!compare_sockaddr(&xfer_sock->addr, &l->addr)) {
+               if (!l->proto->addrcmp(&xfer_sock->addr, &l->addr)) {
                        if ((l->interface == NULL && xfer_sock->iface == NULL) ||
                            (l->interface != NULL && xfer_sock->iface != NULL &&
                             !strcmp(l->interface, xfer_sock->iface))) {
index 0c14817f5d7aa8db257ae808e3e3cb8515130245..0bd903fb5b35051e0861e1b4b4a528cace167221 100644 (file)
@@ -37,6 +37,7 @@
 #include <haproxy/proxy.h>
 #include <haproxy/server.h>
 #include <haproxy/sock.h>
+#include <haproxy/sock_inet.h>
 #include <haproxy/task.h>
 
 static int udp_bind_listeners(struct protocol *proto, char *errmsg, int errlen);
@@ -63,6 +64,7 @@ static struct protocol proto_udp4 = {
        .get_dst = udp_get_dst,
        .pause = udp_pause_listener,
        .add = udp4_add_listener,
+       .addrcmp = sock_inet4_addrcmp,
        .listeners = LIST_HEAD_INIT(proto_udp4.listeners),
        .nb_listeners = 0,
 };
@@ -88,6 +90,7 @@ static struct protocol proto_udp6 = {
        .get_dst = udp_get_dst,
        .pause = udp_pause_listener,
        .add = udp6_add_listener,
+       .addrcmp = sock_inet6_addrcmp,
        .listeners = LIST_HEAD_INIT(proto_udp6.listeners),
        .nb_listeners = 0,
 };
index 0e1cfc62a25b5b69d41207af8827a9e51eb8b9ad..f0cf99988a5e3a19820457bb5aea51f132378e71 100644 (file)
@@ -34,6 +34,7 @@
 #include <haproxy/log.h>
 #include <haproxy/protocol.h>
 #include <haproxy/sock.h>
+#include <haproxy/sock_unix.h>
 #include <haproxy/time.h>
 #include <haproxy/tools.h>
 #include <haproxy/version.h>
@@ -66,6 +67,7 @@ static struct protocol proto_unix = {
        .get_dst = sock_get_dst,
        .pause = uxst_pause_listener,
        .add = uxst_add_listener,
+       .addrcmp = sock_unix_addrcmp,
        .listeners = LIST_HEAD_INIT(proto_unix.listeners),
        .nb_listeners = 0,
 };
@@ -88,37 +90,13 @@ static int uxst_find_compatible_fd(struct listener *l)
        int ret = -1;
 
        while (xfer_sock) {
-               struct sockaddr_un *un1 = (void *)&l->addr;
-               struct sockaddr_un *un2 = (void *)&xfer_sock->addr;
-
                /*
                 * The bound socket's path as returned by getsockaddr
                 * will be the temporary name <sockname>.XXXXX.tmp,
                 * so we can't just compare the two names
                 */
-               if (xfer_sock->addr.ss_family == AF_UNIX &&
-                   strncmp(un1->sun_path, un2->sun_path,
-                   strlen(un1->sun_path)) == 0) {
-                       char *after_sockname = un2->sun_path +
-                           strlen(un1->sun_path);
-                       /* Make a reasonable effort to check that
-                        * it is indeed a haproxy-generated temporary
-                        * name, it's not perfect, but probably good enough.
-                        */
-                       if (after_sockname[0] == '.') {
-                               after_sockname++;
-                               while (after_sockname[0] >= '0' &&
-                                   after_sockname[0] <= '9')
-                                       after_sockname++;
-                               if (!strcmp(after_sockname, ".tmp"))
-                                       break;
-                       /* abns sockets sun_path starts with a \0 */
-                       } else if (un1->sun_path[0] == 0
-                           && un2->sun_path[0] == 0
-                           && !memcmp(&un1->sun_path[1], &un2->sun_path[1],
-                           sizeof(un1->sun_path) - 1))
+               if (!l->proto->addrcmp(&xfer_sock->addr, &l->addr))
                                break;
-               }
                xfer_sock = xfer_sock->next;
        }
        if (xfer_sock != NULL) {