]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: tools: add port for ipcmp as optional criteria
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Thu, 1 Dec 2022 16:46:45 +0000 (17:46 +0100)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Fri, 2 Dec 2022 13:45:43 +0000 (14:45 +0100)
Complete ipcmp() function with a new argument <check_port>. If this
argument is true, the function will compare port values besides IP
addresses and return true only if both are identical.

This commit will simplify QUIC connection migration detection. As such,
it should be backported to 2.7.

include/haproxy/tools.h
src/server.c
src/tools.c

index c3549918cb8fed7108470eff5e41b48af421c369..b2133b827c465efedfbf983b2158ceb474b9418f 100644 (file)
@@ -775,11 +775,13 @@ extern void v4tov6(struct in6_addr *sin6_addr, struct in_addr *sin_addr);
  */
 extern int v6tov4(struct in_addr *sin_addr, struct in6_addr *sin6_addr);
 
-/* compare two struct sockaddr_storage and return:
+/* compare two struct sockaddr_storage, including port if <check_port> is true,
+ * and return:
  *  0 (true)  if the addr is the same in both
  *  1 (false) if the addr is not the same in both
+ *  -1 (unable) if one of the addr is not AF_INET*
  */
-int ipcmp(struct sockaddr_storage *ss1, struct sockaddr_storage *ss2);
+int ipcmp(struct sockaddr_storage *ss1, struct sockaddr_storage *ss2, int check_port);
 
 /* compare a struct sockaddr_storage to a struct net_addr and return :
  *  0 (true)  if <addr> is matching <net>
index 51ca0cdf3b9dd9447f8486db1984e1dc8aef09e1..5938e3547304532da44f3d56f48b00c659508eec 100644 (file)
@@ -3314,7 +3314,7 @@ const char *srv_update_addr_port(struct server *s, const char *addr, const char
                /* applying ADDR changes if required and allowed
                 * ipcmp returns 0 when both ADDR are the same
                 */
-               if (ipcmp(&s->addr, &sa) == 0) {
+               if (ipcmp(&s->addr, &sa, 0) == 0) {
                        chunk_appendf(msg, "no need to change the addr");
                        goto port;
                }
index a392fe573b78b5c7a66eea704e28496fb2761c11..1f4fedaaaaf483bbec5e689cb212261734b44d3e 100644 (file)
@@ -3323,12 +3323,13 @@ int v6tov4(struct in_addr *sin_addr, struct in6_addr *sin6_addr)
        return 0;
 }
 
-/* compare two struct sockaddr_storage and return:
+/* compare two struct sockaddr_storage, including port if <check_port> is true,
+ * and return:
  *  0 (true)  if the addr is the same in both
  *  1 (false) if the addr is not the same in both
  *  -1 (unable) if one of the addr is not AF_INET*
  */
-int ipcmp(struct sockaddr_storage *ss1, struct sockaddr_storage *ss2)
+int ipcmp(struct sockaddr_storage *ss1, struct sockaddr_storage *ss2, int check_port)
 {
        if ((ss1->ss_family != AF_INET) && (ss1->ss_family != AF_INET6))
                return -1;
@@ -3341,13 +3342,15 @@ int ipcmp(struct sockaddr_storage *ss1, struct sockaddr_storage *ss2)
 
        switch (ss1->ss_family) {
                case AF_INET:
-                       return memcmp(&((struct sockaddr_in *)ss1)->sin_addr,
+                       return (memcmp(&((struct sockaddr_in *)ss1)->sin_addr,
                                      &((struct sockaddr_in *)ss2)->sin_addr,
-                                     sizeof(struct in_addr)) != 0;
+                                     sizeof(struct in_addr)) != 0) ||
+                              (check_port && get_net_port(ss1) != get_net_port(ss2));
                case AF_INET6:
-                       return memcmp(&((struct sockaddr_in6 *)ss1)->sin6_addr,
+                       return (memcmp(&((struct sockaddr_in6 *)ss1)->sin6_addr,
                                      &((struct sockaddr_in6 *)ss2)->sin6_addr,
-                                     sizeof(struct in6_addr)) != 0;
+                                     sizeof(struct in6_addr)) != 0) ||
+                              (check_port && get_net_port(ss1) != get_net_port(ss2));
        }
 
        return 1;