]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: socket: always properly use the sock_domain for requested families
authorWilly Tarreau <w@1wt.eu>
Fri, 9 Aug 2024 17:37:44 +0000 (19:37 +0200)
committerWilly Tarreau <w@1wt.eu>
Wed, 21 Aug 2024 15:36:58 +0000 (17:36 +0200)
Now we make sure to always look up the protocol's domain for an address
family. Previously we would use it as-is, which prevented from properly
using custom addresses (which is when they differ).

This removes some hard-coded tests such as in log.c where UNIX vs UDP
was explicitly checked for example. It requires a bit of care, however,
so as to properly pass value 1 in the 3rd arg of the protocol_lookup()
for DGRAM stuff. Maybe one day we'll change these for defines or enums
to limit mistakes.

src/dns.c
src/log.c
src/resolvers.c
src/sock.c
src/tools.c

index 2a4c4650fd58f0be63e54bfc0de5c28736f9ef5f..14c811a10860c51820cf460517011f84612f9952 100644 (file)
--- a/src/dns.c
+++ b/src/dns.c
@@ -31,6 +31,7 @@
 #include <haproxy/errors.h>
 #include <haproxy/fd.h>
 #include <haproxy/log.h>
+#include <haproxy/protocol.h>
 #include <haproxy/sc_strm.h>
 #include <haproxy/stconn.h>
 #include <haproxy/stream.h>
@@ -48,6 +49,7 @@ DECLARE_STATIC_POOL(dns_msg_buf, "dns_msg_buf", DNS_TCP_MSG_RING_MAX_SIZE);
 static int dns_connect_nameserver(struct dns_nameserver *ns)
 {
        struct dgram_conn *dgram = &ns->dgram->conn;
+       const struct protocol *proto;
        int fd;
 
        /* Already connected */
@@ -55,7 +57,9 @@ static int dns_connect_nameserver(struct dns_nameserver *ns)
                return 0;
 
        /* Create an UDP socket and connect it on the nameserver's IP/Port */
-       if ((fd = socket(dgram->addr.to.ss_family, SOCK_DGRAM, IPPROTO_UDP)) == -1) {
+       proto = protocol_lookup(dgram->addr.to.ss_family, PROTO_TYPE_DGRAM, 1);
+       BUG_ON(!proto);
+       if ((fd = socket(proto->fam->sock_domain, proto->sock_type, proto->sock_prot)) == -1) {
                send_log(NULL, LOG_WARNING,
                         "DNS : section '%s': can't create socket for nameserver '%s'.\n",
                         ns->counters->pid, ns->id);
index 4b9573cdb78e280e6e125670ab15bd1a26395817..d1f285a396387b2179a5bdb0f87756750bf79a28 100644 (file)
--- a/src/log.c
+++ b/src/log.c
@@ -38,6 +38,7 @@
 #include <haproxy/lb_map.h>
 #include <haproxy/lb_ss.h>
 #include <haproxy/log.h>
+#include <haproxy/protocol.h>
 #include <haproxy/proxy.h>
 #include <haproxy/sample.h>
 #include <haproxy/sc_strm.h>
@@ -2670,6 +2671,7 @@ static inline void __do_send_log(struct log_target *target, struct log_header hd
        };
        static THREAD_LOCAL int logfdunix = -1; /* syslog to AF_UNIX socket */
        static THREAD_LOCAL int logfdinet = -1; /* syslog to AF_INET socket */
+       const struct protocol *proto;
        int *plogfd;
        int sent;
        size_t nbelem;
@@ -2698,8 +2700,13 @@ static inline void __do_send_log(struct log_target *target, struct log_header hd
 
        if (plogfd && unlikely(*plogfd < 0)) {
                /* socket not successfully initialized yet */
-               if ((*plogfd = socket(target->addr->ss_family, SOCK_DGRAM,
-                                     (target->addr->ss_family == AF_UNIX) ? 0 : IPPROTO_UDP)) < 0) {
+
+               /* WT: this is not compliant with AF_CUST_* usage but we don't use that
+                * with DNS at the moment.
+                */
+               proto = protocol_lookup(target->addr->ss_family, PROTO_TYPE_DGRAM, 1);
+               BUG_ON(!proto);
+               if ((*plogfd = socket(proto->fam->sock_domain, proto->sock_type, proto->sock_prot)) < 0) {
                        static char once;
 
                        if (!once) {
index d01a30717ccad2e4adb17d770b9ecee8a7fe6fbf..33a9bbd7927a97b8bf2b2c0e23485e18de484be7 100644 (file)
@@ -2633,6 +2633,7 @@ static void resolvers_deinit(void)
  */
 static int resolvers_finalize_config(void)
 {
+       const struct protocol *proto;
        struct resolvers *resolvers;
        struct proxy         *px;
        int err_code = 0;
@@ -2650,7 +2651,9 @@ static int resolvers_finalize_config(void)
 
                        if (ns->dgram) {
                                /* Check nameserver info */
-                               if ((fd = socket(ns->dgram->conn.addr.to.ss_family, SOCK_DGRAM, IPPROTO_UDP)) == -1) {
+                               proto = protocol_lookup(ns->dgram->conn.addr.to.ss_family, PROTO_TYPE_DGRAM, 1);
+                               BUG_ON(!proto);
+                               if ((fd = socket(proto->fam->sock_domain, proto->sock_type, proto->sock_prot)) == -1) {
                                        if (!resolvers->conf.implicit) {  /* emit a warning only if it was configured manually */
                                                ha_alert("resolvers '%s': can't create socket for nameserver '%s'.\n",
                                                         resolvers->id, ns->id);
index 61ebf4a929e8e8ed79d62c3efbab18aca95867bb..867a0ed76e7d499bc0820158de8ba94cb6299b17 100644 (file)
@@ -30,7 +30,7 @@
 #include <haproxy/listener.h>
 #include <haproxy/log.h>
 #include <haproxy/namespace.h>
-#include <haproxy/protocol-t.h>
+#include <haproxy/protocol.h>
 #include <haproxy/proto_sockpair.h>
 #include <haproxy/sock.h>
 #include <haproxy/sock_inet.h>
@@ -268,6 +268,7 @@ static int sock_handle_system_err(struct connection *conn, struct proxy *be)
 int sock_create_server_socket(struct connection *conn, struct proxy *be, int *stream_err)
 {
        const struct netns_entry *ns = NULL;
+       const struct protocol *proto;
        int sock_fd;
 
 #ifdef USE_NS
@@ -278,7 +279,9 @@ int sock_create_server_socket(struct connection *conn, struct proxy *be, int *st
                        ns = __objt_server(conn->target)->netns;
        }
 #endif
-       sock_fd = my_socketat(ns, conn->dst->ss_family, SOCK_STREAM, 0);
+       proto = protocol_lookup(conn->dst->ss_family, PROTO_TYPE_STREAM, 0);
+       BUG_ON(!proto);
+       sock_fd = my_socketat(ns, proto->fam->sock_domain, SOCK_STREAM, 0);
 
        /* at first, handle common to all proto families system limits and permission related errors */
        if (sock_fd == -1) {
index 15756c880bd4afa19ccefdcd74bf9d833ef93d75..c1acea3341ef5ad48d7dc7283fce314a5d45e52e 100644 (file)
@@ -1941,6 +1941,7 @@ int addr_is_local(const struct netns_entry *ns,
                   const struct sockaddr_storage *orig)
 {
        struct sockaddr_storage addr;
+       const struct proto_fam *fam;
        int result;
        int fd;
 
@@ -1950,7 +1951,10 @@ int addr_is_local(const struct netns_entry *ns,
        memcpy(&addr, orig, sizeof(addr));
        set_host_port(&addr, 0);
 
-       fd = my_socketat(ns, addr.ss_family, SOCK_DGRAM, IPPROTO_UDP);
+       fam = proto_fam_lookup(addr.ss_family);
+       BUG_ON(!fam);
+
+       fd = my_socketat(ns, fam->sock_domain, SOCK_DGRAM, IPPROTO_UDP);
        if (fd < 0)
                return -1;