]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: receiver: add a receiver-specific flag to indicate the socket is bound
authorWilly Tarreau <w@1wt.eu>
Tue, 1 Sep 2020 08:47:07 +0000 (10:47 +0200)
committerWilly Tarreau <w@1wt.eu>
Wed, 16 Sep 2020 20:08:07 +0000 (22:08 +0200)
In order to split the receiver from the listener, we'll need to know that
a socket is already bound and ready to receive. We used to do that via
tha LI_O_ASSIGNED state but that's not sufficient anymore since the
receiver might not belong to a listener anymore. The new RX_F_BOUND flag
is used for this.

include/haproxy/receiver-t.h
src/listener.c
src/proto_sockpair.c
src/proto_tcp.c
src/proto_udp.c
src/proto_uxst.c

index 5b45dc2692115b32ad785550ff0220c16a8a248f..5537d5ab555578b3553318a9e9fb263bee9f79a9 100644 (file)
@@ -29,6 +29,9 @@
 #include <haproxy/namespace-t.h>
 #include <haproxy/thread.h>
 
+/* Bit values for receiver->options */
+#define RX_F_BOUND              0x00000001  /* receiver already bound */
+
 /* All the settings that are used to configure a receiver */
 struct rx_settings {
        unsigned long bind_proc;          /* bitmask of processes allowed to use these listeners */
index 4026ea233359dd8ff7813231dd20b5d4dda4b4bc..27476cd7ac2f2cdc5653615ba0f789e764e8ccfe 100644 (file)
@@ -505,6 +505,7 @@ void do_unbind_listener(struct listener *listener, int do_close)
                fd_stop_both(listener->rx.fd);
                if (do_close) {
                        fd_delete(listener->rx.fd);
+                       listener->rx.flags &= ~RX_F_BOUND;
                        listener->rx.fd = -1;
                }
        }
index 90300cc22cf6ad3e94af7cf1c47d7651eacd609c..d25ab5a4248d38f8eecd885d847bd56cc40813c9 100644 (file)
@@ -106,6 +106,9 @@ static int sockpair_bind_listener(struct listener *listener, char *errmsg, int e
        if (listener->state != LI_ASSIGNED)
                return ERR_NONE; /* already bound */
 
+       if (listener->rx.flags & RX_F_BOUND)
+               goto bound;
+
        if (listener->rx.fd == -1) {
                err |= ERR_FATAL | ERR_ALERT;
                msg = "sockpair can be only used with inherited FDs";
@@ -122,7 +125,9 @@ static int sockpair_bind_listener(struct listener *listener, char *errmsg, int e
                msg = "cannot make sockpair non-blocking";
                goto err_return;
        }
+       listener->rx.flags |= RX_F_BOUND;
 
+ bound:
        listener->state = LI_LISTEN;
 
        fd_insert(fd, listener, listener->rx.proto->accept,
index 62f86117dc13c8dc66ac0f0fa006b8e25ac39f54..84b3635f958d201ceffbfb39aef06fe19f55ab51 100644 (file)
@@ -569,6 +569,9 @@ int tcp_bind_listener(struct listener *listener, char *errmsg, int errlen)
 
        err = ERR_NONE;
 
+       if (listener->rx.flags & RX_F_BOUND)
+               goto bound;
+
        if (listener->rx.fd == -1)
                listener->rx.fd = sock_find_compatible_fd(listener);
 
@@ -744,7 +747,9 @@ int tcp_bind_listener(struct listener *listener, char *errmsg, int errlen)
                msg = "cannot bind socket";
                goto tcp_close_return;
        }
+       listener->rx.flags |= RX_F_BOUND;
 
+ bound:
        ready = 0;
        ready_len = sizeof(ready);
        if (getsockopt(fd, SOL_SOCKET, SO_ACCEPTCONN, &ready, &ready_len) == -1)
index 9325ba8f4672612622f30a8fe24fc522dabe6cec..64ea63931895cc38e808d86973064f0ecb89f533 100644 (file)
@@ -195,6 +195,9 @@ int udp_bind_listener(struct listener *listener, char *errmsg, int errlen)
 
        err = ERR_NONE;
 
+       if (listener->rx.flags & RX_F_BOUND)
+               goto bound;
+
        /* TODO: Implement reuse fd. Take care that to identify fd to reuse
         * listeners uses a special AF_CUST_ family and we MUST consider
         * IPPROTO (sockaddr is not enough)
@@ -276,7 +279,9 @@ int udp_bind_listener(struct listener *listener, char *errmsg, int errlen)
                msg = "cannot bind socket";
                goto udp_close_return;
        }
+       listener->rx.flags |= RX_F_BOUND;
 
+ bound:
        /* the socket is ready */
        listener->rx.fd = fd;
        listener->state = LI_LISTEN;
index 55d02be8d0a3b07879adbdd8ea9878f9c3e4926e..4378db3ad9e11ac2828d69462eddd1cb5173e8b4 100644 (file)
@@ -109,6 +109,9 @@ static int uxst_bind_listener(struct listener *listener, char *errmsg, int errle
        if (listener->state != LI_ASSIGNED)
                return ERR_NONE; /* already bound */
                
+       if (listener->rx.flags & RX_F_BOUND)
+               goto bound;
+
        if (listener->rx.fd == -1)
                listener->rx.fd = sock_find_compatible_fd(listener);
        path = ((struct sockaddr_un *)&listener->rx.addr)->sun_path;
@@ -230,7 +233,9 @@ static int uxst_bind_listener(struct listener *listener, char *errmsg, int errle
                msg = "cannot change UNIX socket ownership";
                goto err_unlink_temp;
        }
+       listener->rx.flags |= RX_F_BOUND;
 
+ bound:
        ready = 0;
        ready_len = sizeof(ready);
        if (getsockopt(fd, SOL_SOCKET, SO_ACCEPTCONN, &ready, &ready_len) == -1)