]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: protocol: create abnsz socket address family
authorWilly Tarreau <w@1wt.eu>
Fri, 9 Aug 2024 19:12:23 +0000 (21:12 +0200)
committerAurelien DARRAGON <adarragon@haproxy.com>
Tue, 29 Oct 2024 11:14:50 +0000 (12:14 +0100)
For now it's the same as abns. We'll need to modify sock_unix_addrcmp(),
and a few other ones to support effective path length when dealing with
the \0. Let's check with Tristan's patch for this (upcoming patch).

Co-authored-by: Aurelien DARRAGON <adarragon@haproxy.com>
14 files changed:
include/haproxy/protocol-t.h
include/haproxy/sock_unix.h
include/haproxy/tools.h
src/cli.c
src/connection.c
src/extcheck.c
src/frontend.c
src/peers.c
src/proto_uxdg.c
src/proto_uxst.c
src/sock_unix.c
src/stats-proxy.c
src/stream.c
src/tools.c

index 9b3b7f5593220aa5e827e1f004f0a6a2a72ea562..2a44e1471bc380e39a46264b34be100f9439b78f 100644 (file)
@@ -41,7 +41,8 @@ struct connection;
 #define AF_CUST_SOCKPAIR     (AF_MAX + 2)
 #define AF_CUST_RHTTP_SRV    (AF_MAX + 3)
 #define AF_CUST_ABNS         (AF_MAX + 4)
-#define AF_CUST_MAX          (AF_MAX + 5)
+#define AF_CUST_ABNSZ        (AF_MAX + 5)
+#define AF_CUST_MAX          (AF_MAX + 6)
 
 /*
  * Test in case AF_CUST_MAX overflows the sa_family_t (unsigned int)
index 641fd823f302184fa8b2f4054ed3375cdeeab319..39583e9f9bf5dfe52660169c04b12c46bd791ea4 100644 (file)
@@ -30,6 +30,7 @@
 
 extern struct proto_fam proto_fam_unix;
 extern struct proto_fam proto_fam_abns;
+extern struct proto_fam proto_fam_abnsz;
 
 int sock_unix_addrcmp(const struct sockaddr_storage *a, const struct sockaddr_storage *b);
 int sock_unix_bind_receiver(struct receiver *rx, char **errmsg);
index a8d289e129ae527b4d44baac30472129a0759fe3..c47e5cd1feee61fa38571754e55f138634c4d09b 100644 (file)
@@ -744,7 +744,8 @@ static inline int is_addr(const struct sockaddr_storage *addr)
        /* WT: ideally we should use real_family(addr->ss_family) here, but we
         * have so few custom addresses that it's simple enough to test them all.
         */
-       if (addr->ss_family == AF_UNIX || addr->ss_family == AF_CUST_ABNS || addr->ss_family == AF_CUST_SOCKPAIR)
+       if (addr->ss_family == AF_UNIX || addr->ss_family == AF_CUST_ABNS ||
+           addr->ss_family == AF_CUST_ABNSZ || addr->ss_family == AF_CUST_SOCKPAIR)
                return 1;
        else
                return is_inet_addr(addr);
@@ -784,6 +785,7 @@ static inline int get_addr_len(const struct sockaddr_storage *addr)
                return sizeof(struct sockaddr_in6);
        case AF_UNIX:
        case AF_CUST_ABNS:
+       case AF_CUST_ABNSZ:
                return sizeof(struct sockaddr_un);
        }
        return 0;
index 556be111b07944757af2a063afb0f1b42cfe5a89..e63ba93642843d0d7dfa89486af3b8119e1aa647 100644 (file)
--- a/src/cli.c
+++ b/src/cli.c
@@ -655,11 +655,14 @@ int listeners_setenv(struct proxy *frontend, const char *varname)
                                if (trash->data)
                                        chunk_appendf(trash, ";");
 
-                               if (l->rx.addr.ss_family == AF_UNIX || l->rx.addr.ss_family == AF_CUST_ABNS) {
+                               if (l->rx.addr.ss_family == AF_UNIX ||
+                                   l->rx.addr.ss_family == AF_CUST_ABNS ||
+                                   l->rx.addr.ss_family == AF_CUST_ABNSZ) {
                                        const struct sockaddr_un *un;
 
                                        un = (struct sockaddr_un *)&l->rx.addr;
-                                       if (l->rx.addr.ss_family == AF_CUST_ABNS) {
+                                       if (l->rx.addr.ss_family == AF_CUST_ABNS ||
+                                           l->rx.addr.ss_family == AF_CUST_ABNSZ) {
                                                chunk_appendf(trash, "abns@%s", un->sun_path+1);
                                        } else {
                                                chunk_appendf(trash, "unix@%s", un->sun_path);
@@ -1584,11 +1587,14 @@ static int cli_io_handler_show_cli_sock(struct appctx *appctx)
                        char addr[46];
                        char port[6];
 
-                       if (l->rx.addr.ss_family == AF_UNIX || l->rx.addr.ss_family == AF_CUST_ABNS) {
+                       if (l->rx.addr.ss_family == AF_UNIX ||
+                           l->rx.addr.ss_family == AF_CUST_ABNS ||
+                           l->rx.addr.ss_family == AF_CUST_ABNSZ) {
                                const struct sockaddr_un *un;
 
                                un = (struct sockaddr_un *)&l->rx.addr;
-                               if (l->rx.addr.ss_family == AF_CUST_ABNS) {
+                               if (l->rx.addr.ss_family == AF_CUST_ABNS ||
+                                   l->rx.addr.ss_family == AF_CUST_ABNSZ) {
                                        chunk_appendf(&trash, "abns@%s ", un->sun_path+1);
                                } else {
                                        chunk_appendf(&trash, "unix@%s ", un->sun_path);
index 9c1d4a013394b43af70ad68f28da4d698155955c..07655934b5eafafd1bc00deb9fbd7daa9ff7e154 100644 (file)
@@ -2684,6 +2684,7 @@ static void conn_calculate_hash_sockaddr(const struct sockaddr_storage *ss,
                break;
 
        case AF_CUST_ABNS:
+       case AF_CUST_ABNSZ:
                conn_hash_update(hash,
                                 &((struct sockaddr_un *)ss)->sun_path,
                                 sizeof(((struct sockaddr_un *)ss)->sun_path),
index 20e9fa8f942453ca09f89cf835f599fbf564a36b..c71639cd5f37bb2766b2e2248d4dda31ec8e8d7c 100644 (file)
@@ -306,7 +306,8 @@ int prepare_external_check(struct check *check)
                check->argv[2] = strdup(buf);
        }
        else if (listener->rx.addr.ss_family == AF_UNIX ||
-                listener->rx.addr.ss_family == AF_CUST_ABNS) {
+                listener->rx.addr.ss_family == AF_CUST_ABNS ||
+                listener->rx.addr.ss_family == AF_CUST_ABNSZ) {
                const struct sockaddr_un *un;
 
                un = (struct sockaddr_un *)&listener->rx.addr;
index 690ca1413b600c093f3446ef1321f65cc2adb7b2..5e3821d76b6748e4d0275abfc1f98491d7b082a0 100644 (file)
@@ -92,6 +92,7 @@ int frontend_accept(struct stream *s)
                                        break;
                                case AF_UNIX:
                                case AF_CUST_ABNS:
+                               case AF_CUST_ABNSZ:
                                        /* UNIX socket, only the destination is known */
                                        send_log(fe, LOG_INFO, "Connect to unix:%d (%s/%s)\n",
                                                 l->luid,
@@ -133,6 +134,7 @@ int frontend_accept(struct stream *s)
                        break;
                case AF_UNIX:
                case AF_CUST_ABNS:
+               case AF_CUST_ABNSZ:
                        /* UNIX socket, only the destination is known */
                        chunk_printf(&trash, "%08x:%s.accept(%04x)=%04x from [unix:%d] ALPN=%s\n",
                                     s->uniq_id, fe->id, (unsigned short)l->rx.fd, (unsigned short)conn->handle.fd,
index 5b9390cbca6ccbd80438bed6a29de07897b58d4c..5094002b1c2171b24b18a372c96f79b17ff5934f 100644 (file)
@@ -4068,6 +4068,7 @@ static int peers_dump_peer(struct buffer *msg, struct appctx *appctx, struct pee
                break;
        case AF_UNIX:
        case AF_CUST_ABNS:
+       case AF_CUST_ABNSZ:
                chunk_appendf(&trash, " src=unix:%d", strm_li(peer_s)->luid);
                break;
        }
@@ -4079,6 +4080,7 @@ static int peers_dump_peer(struct buffer *msg, struct appctx *appctx, struct pee
                break;
        case AF_UNIX:
        case AF_CUST_ABNS:
+       case AF_CUST_ABNSZ:
                chunk_appendf(&trash, " addr=unix:%d", strm_li(peer_s)->luid);
                break;
        }
index 32c9e45e92cca20fb4136cae1b9c3ac4b8c8126b..b0a538340d857cc9a00525e1c8a268aabbb36efd 100644 (file)
@@ -96,8 +96,40 @@ struct protocol proto_abns_dgram = {
        .nb_receivers   = 0,
 };
 
+/* Note: must not be declared <const> as its list will be overwritten */
+struct protocol proto_abnsz_dgram = {
+       .name           = "abnsz_dgram",
+
+       /* connection layer */
+       .xprt_type      = PROTO_TYPE_DGRAM,
+       .listen         = uxdg_bind_listener,
+       .enable         = uxdg_enable_listener,
+       .disable        = uxdg_disable_listener,
+       .add            = default_add_listener,
+       .unbind         = default_unbind_listener,
+       .suspend        = default_suspend_listener,
+       .resume         = default_resume_listener,
+
+       /* binding layer */
+       .rx_suspend     = uxdg_suspend_receiver,
+
+       /* address family */
+       .fam            = &proto_fam_abnsz,
+
+       /* socket layer */
+       .proto_type     = PROTO_TYPE_DGRAM,
+       .sock_type      = SOCK_DGRAM,
+       .sock_prot      = 0,
+       .rx_enable      = sock_enable,
+       .rx_disable     = sock_disable,
+       .rx_unbind      = sock_unbind,
+       .receivers      = LIST_HEAD_INIT(proto_abnsz_dgram.receivers),
+       .nb_receivers   = 0,
+};
+
 INITCALL1(STG_REGISTER, protocol_register, &proto_uxdg);
 INITCALL1(STG_REGISTER, protocol_register, &proto_abns_dgram);
+INITCALL1(STG_REGISTER, protocol_register, &proto_abnsz_dgram);
 
 /* This function tries to bind dgram unix socket listener. It may return a warning or
  * an error message in <errmsg> if the message is at most <errlen> bytes long
index 0ae2569b36056728c90fe45de08880819e8b0f32..f8b6958091b28fc126a7f0064e990106c5994efb 100644 (file)
@@ -123,8 +123,49 @@ struct protocol proto_abns_stream = {
        .nb_receivers   = 0,
 };
 
+/* Note: must not be declared <const> as its list will be overwritten */
+struct protocol proto_abnsz_stream = {
+       .name           = "abnsz_stream",
+
+       /* connection layer */
+       .xprt_type      = PROTO_TYPE_STREAM,
+       .listen         = uxst_bind_listener,
+       .enable         = uxst_enable_listener,
+       .disable        = uxst_disable_listener,
+       .add            = default_add_listener,
+       .unbind         = default_unbind_listener,
+       .suspend        = default_suspend_listener,
+       .resume         = default_resume_listener,
+       .accept_conn    = sock_accept_conn,
+       .ctrl_init      = sock_conn_ctrl_init,
+       .ctrl_close     = sock_conn_ctrl_close,
+       .connect        = uxst_connect_server,
+       .drain          = sock_drain,
+       .check_events   = sock_check_events,
+       .ignore_events  = sock_ignore_events,
+
+       /* binding layer */
+       .rx_suspend     = uxst_suspend_receiver,
+
+       /* address family */
+       .fam            = &proto_fam_abnsz,
+
+       /* socket layer */
+       .proto_type     = PROTO_TYPE_STREAM,
+       .sock_type      = SOCK_STREAM,
+       .sock_prot      = 0,
+       .rx_enable      = sock_enable,
+       .rx_disable     = sock_disable,
+       .rx_unbind      = sock_unbind,
+       .rx_listening   = sock_accepting_conn,
+       .default_iocb   = sock_accept_iocb,
+
+       .nb_receivers   = 0,
+};
+
 INITCALL1(STG_REGISTER, protocol_register, &proto_uxst);
 INITCALL1(STG_REGISTER, protocol_register, &proto_abns_stream);
+INITCALL1(STG_REGISTER, protocol_register, &proto_abnsz_stream);
 
 /********************************
  * 1) low-level socket functions
index 13e0c9146d703aff58e21b76d77f4c883e69d913..8785845b317d7f6794045486fe5c30c9074220dc 100644 (file)
@@ -63,6 +63,19 @@ struct proto_fam proto_fam_abns = {
        .get_dst = sock_get_dst,
 };
 
+struct proto_fam proto_fam_abnsz = {
+       .name = "abnsz",
+       .sock_domain = AF_UNIX,
+       .sock_family = AF_CUST_ABNSZ,
+       .real_family = AF_UNIX,
+       .sock_addrlen = sizeof(struct sockaddr_un),
+       .l3_addrlen = sizeof(((struct sockaddr_un*)0)->sun_path),
+       .addrcmp = sock_unix_addrcmp,
+       .bind = sock_unix_bind_receiver,
+       .get_src = sock_get_src,
+       .get_dst = sock_get_dst,
+};
+
 /* PLEASE NOTE for functions below:
  *
  * The address family SHOULD always be checked. In some cases a function will
index de14e299c83118df699c41daaa1f701d761430d1..5fc1f5c5ed3f6bb7cc2667805eabd5cd9573d895 100644 (file)
@@ -571,6 +571,7 @@ int stats_fill_li_line(struct proxy *px, struct listener *l, int flags,
                                                break;
                                        case AF_UNIX:
                                        case AF_CUST_ABNS:
+                                       case AF_CUST_ABNSZ:
                                                field = mkf_str(FO_CONFIG|FS_SERVICE, "unix");
                                                break;
                                        case -1:
@@ -1004,6 +1005,7 @@ int stats_fill_sv_line(struct proxy *px, struct server *sv, int flags,
                                                        break;
                                                case AF_UNIX:
                                                case AF_CUST_ABNS:
+                                               case AF_CUST_ABNSZ:
                                                        field = mkf_str(FO_CONFIG|FS_SERVICE, "unix");
                                                        break;
                                                case -1:
index 0e84fab12d5549e8e102a3cdd68425865bb2b5aa..34696bd2c7a451715641708cd84c5b085a19f6a7 100644 (file)
@@ -3295,6 +3295,7 @@ void strm_dump_to_buffer(struct buffer *buf, const struct stream *strm, const ch
                break;
        case AF_UNIX:
        case AF_CUST_ABNS:
+       case AF_CUST_ABNSZ:
                chunk_appendf(buf, " source=unix:%d\n", strm_li(strm)->luid);
                break;
        default:
@@ -3330,6 +3331,7 @@ void strm_dump_to_buffer(struct buffer *buf, const struct stream *strm, const ch
                break;
        case AF_UNIX:
        case AF_CUST_ABNS:
+       case AF_CUST_ABNSZ:
                chunk_appendf(buf, " addr=unix:%d\n", strm_li(strm)->luid);
                break;
        default:
@@ -3355,6 +3357,7 @@ void strm_dump_to_buffer(struct buffer *buf, const struct stream *strm, const ch
                break;
        case AF_UNIX:
        case AF_CUST_ABNS:
+       case AF_CUST_ABNSZ:
                chunk_appendf(buf, " addr=unix\n");
                break;
        default:
@@ -3379,6 +3382,7 @@ void strm_dump_to_buffer(struct buffer *buf, const struct stream *strm, const ch
                break;
        case AF_UNIX:
        case AF_CUST_ABNS:
+       case AF_CUST_ABNSZ:
                chunk_appendf(buf, " addr=unix\n");
                break;
        default:
@@ -3814,6 +3818,7 @@ static int cli_io_handler_dump_sess(struct appctx *appctx)
                        break;
                case AF_UNIX:
                case AF_CUST_ABNS:
+               case AF_CUST_ABNSZ:
                        chunk_appendf(&trash,
                                     " src=unix:%d fe=%s be=%s srv=%s",
                                     strm_li(curr_strm)->luid,
index ec36a9d94203605f03b50d45bdcccbf9fe6b8016..d2decb69beabe4c73aba3f0ea7507836574bdc01 100644 (file)
@@ -1053,6 +1053,10 @@ struct sockaddr_storage *str2sa_range(const char *str, int *port, int *low, int
                str2 += 5;
                ss.ss_family = AF_CUST_ABNS;
        }
+       else if (strncmp(str2, "abnsz@", 5) == 0) {
+               str2 += 6;
+               ss.ss_family = AF_CUST_ABNSZ;
+       }
        else if (strncmp(str2, "ip@", 3) == 0) {
                str2 += 3;
                ss.ss_family = AF_UNSPEC;
@@ -1218,14 +1222,14 @@ struct sockaddr_storage *str2sa_range(const char *str, int *port, int *low, int
                        goto out;
                }
        }
-       else if (ss.ss_family == AF_UNIX || ss.ss_family == AF_CUST_ABNS) {
+       else if (ss.ss_family == AF_UNIX || ss.ss_family == AF_CUST_ABNS || ss.ss_family == AF_CUST_ABNSZ) {
                struct sockaddr_un *un = (struct sockaddr_un *)&ss;
                int prefix_path_len;
                int max_path_len;
                int adr_len;
                int abstract = 0;
 
-               if (ss.ss_family == AF_CUST_ABNS)
+               if (ss.ss_family == AF_CUST_ABNS || ss.ss_family == AF_CUST_ABNSZ)
                        abstract = 1;
 
                /* complete unix socket path name during startup or soft-restart is
@@ -1474,8 +1478,10 @@ char * sa2str(const struct sockaddr_storage *addr, int port, int map_ports)
                break;
        case AF_UNIX:
        case AF_CUST_ABNS:
+       case AF_CUST_ABNSZ:
                path = ((struct sockaddr_un *)addr)->sun_path;
-               if (addr->ss_family == AF_CUST_ABNS) {
+               if (addr->ss_family == AF_CUST_ABNS ||
+                   addr->ss_family == AF_CUST_ABNSZ) {
                        const int max_length = sizeof(struct sockaddr_un) - offsetof(struct sockaddr_un, sun_path) - 1;
                        return memprintf(&out, "abns@%.*s", max_length, path+1);
                } else {
@@ -1922,6 +1928,7 @@ int addr_to_str(const struct sockaddr_storage *addr, char *str, int size)
                break;
        case AF_UNIX:
        case AF_CUST_ABNS:
+       case AF_CUST_ABNSZ:
                memcpy(str, "unix", 5);
                return addr->ss_family;
        default:
@@ -1960,6 +1967,7 @@ int port_to_str(const struct sockaddr_storage *addr, char *str, int size)
                break;
        case AF_UNIX:
        case AF_CUST_ABNS:
+       case AF_CUST_ABNSZ:
                memcpy(str, "unix", 5);
                return addr->ss_family;
        default:
@@ -6421,6 +6429,7 @@ const char *hash_ipanon(uint32_t scramble, char *ipstring, int hasport)
 
                        case AF_UNIX:
                        case AF_CUST_ABNS:
+                       case AF_CUST_ABNSZ:
                                return HA_ANON_STR(scramble, ipstring);
                                break;