]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: reload: stop passing listener options along with FDs
authorWilly Tarreau <w@1wt.eu>
Wed, 26 Aug 2020 08:30:09 +0000 (10:30 +0200)
committerWilly Tarreau <w@1wt.eu>
Wed, 26 Aug 2020 09:04:33 +0000 (11:04 +0200)
During a reload operation, we used to send listener options associated
with each passed file descriptor. These were passed as binary contents
for the size of the "options" field in the struct listener. This means
that any flag value change or field size change would be problematic,
the former failing to properly grab certain options, the latter possibly
causing permanent failures during this operation.

Since these two previous commits:
  MINOR: reload: determine the foreing binding status from the socket
  BUG/MINOR: reload: detect the OS's v6only status before choosing an old socket

we don't need this anymore as the values are determined from the file
descriptor itself.

Let's just turn the previous 32 bits to vestigal space, send them as
zeroes and ignore them on receipt. The only possible side effect is if
someone would want to roll back from a 2.3 to 2.2 or earlier, such options
might be ignored during this reload. But other forthcoming changes might
make this fail as well anyway so that's not a reason for keeping this
behavior.

src/cli.c
src/haproxy.c

index da6932f1383955cb27e5115b661d8b061cc10dfb..3783bd6eae1ff3f807543ae8e67be9039d856f85 100644 (file)
--- a/src/cli.c
+++ b/src/cli.c
@@ -1639,9 +1639,10 @@ inline static int _getsocks_gen_send(struct proxy *px, int sendfd, int *tmpfd, s
                                curoff += len;
                        } else
                                tmpbuf[curoff++] = 0;
-                       memcpy(tmpbuf + curoff, &l->options,
-                              sizeof(l->options));
-                       curoff += sizeof(l->options);
+
+                       /* we used to send the listener options here before 2.3 */
+                       memset(tmpbuf + curoff, 0, sizeof(int));
+                       curoff += sizeof(int);
 
                        i++;
                } else
@@ -1785,7 +1786,7 @@ static int _getsocks(char **args, char *payload, struct appctx *appctx, void *pr
         *  The namespace name, if any
         *  Size of the interface name (or 0 if none), as an unsigned char
         *  The interface name, if any
-        *  Listener options, as an int.
+        *  32 bits of zeroes (used to be listener options).
         */
        /* We will send sockets MAX_SEND_FD per MAX_SEND_FD, allocate a
         * buffer big enough to store the socket information.
index 5b3252256c4f7f72840b005917f17adb8e542537..a8d27f84e1a0f405403014c3ed7b3aaeb9701438 100644 (file)
@@ -1295,34 +1295,30 @@ static int get_old_sockets(const char *unixsocket)
                        ha_warning("Inconsistency while transferring sockets\n");
                        goto out;
                }
-               memcpy(&xfer_sock->options, &tmpbuf[curoff],
-                   sizeof(xfer_sock->options));
-               curoff += sizeof(xfer_sock->options);
+
+               /* we used to have 32 bits of listener options here but we don't
+                * use them anymore.
+                */
+               curoff += sizeof(int);
 
                /* determine the foreign status directly from the socket itself */
-               xfer_sock->options &= ~LI_O_FOREIGN;
                if (tcp_is_foreign(fd, xfer_sock->addr.ss_family))
                        xfer_sock->options |= LI_O_FOREIGN;
 
                /* keep only the v6only flag depending on what's currently
                 * active on the socket, and always drop the v4v6 one.
                 */
+#if defined(IPV6_V6ONLY)
                {
                        int val = 0;
-#if defined(IPV6_V6ONLY)
                        socklen_t len = sizeof(val);
 
                        if (xfer_sock->addr.ss_family == AF_INET6 &&
-                           getsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &val, &len) != 0)
-                               val = 0;
-#endif
-
-                       if (val)
+                           getsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &val, &len) == 0 &&
+                           val > 0)
                                xfer_sock->options |= LI_O_V6ONLY;
-                       else
-                               xfer_sock->options &= ~LI_O_V6ONLY;
-                       xfer_sock->options &= ~LI_O_V4V6;
                }
+#endif
 
                xfer_sock->fd = fd;
                if (xfer_sock_list)