]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: protocol: add a real family for existing FDs
authorWilly Tarreau <w@1wt.eu>
Fri, 4 Sep 2020 14:44:20 +0000 (16:44 +0200)
committerWilly Tarreau <w@1wt.eu>
Wed, 16 Sep 2020 20:08:07 +0000 (22:08 +0200)
At some places (log fd@XXX, bind fd@XXX) we support using an explicit
file descriptor number, that is placed into the sockaddr for later use.
The problem is that till now it was done with an AF_UNSPEC family, which
is also used for other situations like missing info or rings (for logs).

Let's create an "official" family AF_CUST_EXISTING_FD for this case so
that we are certain the FD can be found in the address when it is set.

include/haproxy/protocol-t.h
src/cfgparse.c
src/log.c
src/tools.c

index 4f5aac221e0d545911996b539bf43c6260742378..cacd3fc316a17b42131085810efdb6cda03032c6 100644 (file)
@@ -37,10 +37,11 @@ struct connection;
  * Custom network family for str2sa parsing.  Should be ok to do this since
  * sa_family_t is standardized as an unsigned integer
  */
-#define AF_CUST_SOCKPAIR     (AF_MAX + 1)
-#define AF_CUST_UDP4         (AF_MAX + 2)
-#define AF_CUST_UDP6         (AF_MAX + 3)
-#define AF_CUST_MAX          (AF_MAX + 4)
+#define AF_CUST_EXISTING_FD  (AF_MAX + 1)
+#define AF_CUST_SOCKPAIR     (AF_MAX + 2)
+#define AF_CUST_UDP4         (AF_MAX + 3)
+#define AF_CUST_UDP6         (AF_MAX + 4)
+#define AF_CUST_MAX          (AF_MAX + 5)
 
 /*
  * Test in case AF_CUST_MAX overflows the sa_family_t (unsigned int)
index cc5f9f76ece304369b744fb811168c5c605003a7..8effc8311056496846331861df42bec5259febcf 100644 (file)
@@ -156,7 +156,7 @@ int str2listener(char *str, struct proxy *curproxy, struct bind_conf *bind_conf,
                                goto fail;
                        }
                }
-               else if (ss2->ss_family == AF_UNSPEC) {
+               else if (ss2->ss_family == AF_CUST_EXISTING_FD) {
                        socklen_t addr_len;
                        inherited = 1;
 
index 702f443d9728a902c596fad6614bab4fb4ee8736..e1257132aaf9d4b5369d76151a3d9d531d8a2943 100644 (file)
--- a/src/log.c
+++ b/src/log.c
@@ -1754,14 +1754,14 @@ static inline void __do_send_log(struct logsrv *logsrv, int nblogger, int level,
        while (size && (message[size-1] == '\n' || (message[size-1] == 0)))
                size--;
 
-       if (logsrv->type == LOG_TARGET_FD) {
-               /* the socket's address is a file descriptor */
-               plogfd = (int *)&((struct sockaddr_in *)&logsrv->addr)->sin_addr.s_addr;
-       }
-       else if (logsrv->type == LOG_TARGET_BUFFER) {
+       if (logsrv->type == LOG_TARGET_BUFFER) {
                plogfd = NULL;
                goto send;
        }
+       else if (logsrv->addr.ss_family == AF_CUST_EXISTING_FD) {
+               /* the socket's address is a file descriptor */
+               plogfd = (int *)&((struct sockaddr_in *)&logsrv->addr)->sin_addr.s_addr;
+       }
        else if (logsrv->addr.ss_family == AF_UNIX)
                plogfd = &logfdunix;
        else
@@ -1790,18 +1790,23 @@ static inline void __do_send_log(struct logsrv *logsrv, int nblogger, int level,
 
        msg_header = build_log_header(logsrv->format, level, facility, metadata, &nbelem);
  send:
-       if (logsrv->addr.ss_family == AF_UNSPEC) {
+       if (logsrv->type == LOG_TARGET_BUFFER) {
                struct ist msg;
 
                msg = ist2(message, size);
                if (msg.len > logsrv->maxlen)
                        msg.len = logsrv->maxlen;
 
-               if (logsrv->type == LOG_TARGET_BUFFER) {
-                       sent = sink_write(logsrv->sink, &msg, 1, level, logsrv->facility, metadata);
-               }
-               else /* LOG_TARGET_FD */
-                       sent = fd_write_frag_line(*plogfd, logsrv->maxlen, msg_header, nbelem, &msg, 1, 1);
+               sent = sink_write(logsrv->sink, &msg, 1, level, logsrv->facility, metadata);
+       }
+       else if (logsrv->addr.ss_family == AF_CUST_EXISTING_FD) {
+               struct ist msg;
+
+               msg = ist2(message, size);
+               if (msg.len > logsrv->maxlen)
+                       msg.len = logsrv->maxlen;
+
+               sent = fd_write_frag_line(*plogfd, logsrv->maxlen, msg_header, nbelem, &msg, 1, 1);
        }
        else {
                int i = 0;
index 803afab9e9f30ca3258cdd0a4742d2510d008d6a..d948993b254256d97fe185dfb012aceceb5a2212 100644 (file)
@@ -861,7 +861,8 @@ struct sockaddr_storage *str2ip2(const char *str, struct sockaddr_storage *sa, i
  * <fqdn> was filled, indicating the need for a resolution.
  *
  * When a file descriptor is passed, its value is put into the s_addr part of
- * the address when cast to sockaddr_in and the address family is AF_UNSPEC.
+ * the address when cast to sockaddr_in and the address family is
+ * AF_CUST_EXISTING_FD.
  */
 struct sockaddr_storage *str2sa_range(const char *str, int *port, int *low, int *high, char **err, const char *pfx, char **fqdn, int resolve)
 {
@@ -957,8 +958,8 @@ struct sockaddr_storage *str2sa_range(const char *str, int *port, int *low, int
                        goto out;
                }
 
-               /* we return AF_UNSPEC if we use a file descriptor number */
-               ss.ss_family = AF_UNSPEC;
+               /* we return AF_CUST_EXISTING_FD if we use a file descriptor number */
+               ss.ss_family = AF_CUST_EXISTING_FD;
        }
        else if (ss.ss_family == AF_UNIX) {
                struct sockaddr_un *un = (struct sockaddr_un *)&ss;