From: Willy Tarreau Date: Thu, 27 Aug 2020 05:48:42 +0000 (+0200) Subject: REORG: listener: move the listening address to a struct receiver X-Git-Tag: v2.3-dev5~69 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=371590661e66ba21380bd1a8c0b4dd9659ba8999;p=thirdparty%2Fhaproxy.git REORG: listener: move the listening address to a struct receiver The address will be specific to the receiver so let's move it there. --- diff --git a/include/haproxy/listener-t.h b/include/haproxy/listener-t.h index 245436d08b..7a07e3f2e0 100644 --- a/include/haproxy/listener-t.h +++ b/include/haproxy/listener-t.h @@ -193,7 +193,10 @@ struct bind_conf { /* This describes a receiver with all its characteristics (address, status, etc) */ struct receiver { - unsigned int flags; /* receiver options (RX_F_*) */ + unsigned int flags; /* receiver options (RX_F_*) */ + + /* warning: this struct is huge, keep it at the bottom */ + struct sockaddr_storage addr; /* the address the socket is bound to */ }; /* The listener will be directly referenced by the fdtab[] which holds its @@ -235,9 +238,6 @@ struct listener { struct bind_conf *bind_conf; /* "bind" line settings, include SSL settings among other things */ struct list proto_list; /* list in the protocol header */ struct receiver rx; /* network receiver parts */ - - /* warning: this struct is huge, keep it at the bottom */ - struct sockaddr_storage addr; /* the address we listen to */ struct { struct eb32_node id; /* place in the tree of used IDs */ } conf; /* config information */ diff --git a/src/cfgparse-tcp.c b/src/cfgparse-tcp.c index 961a726a5b..7346d652b9 100644 --- a/src/cfgparse-tcp.c +++ b/src/cfgparse-tcp.c @@ -43,7 +43,7 @@ static int bind_parse_v4v6(char **args, int cur_arg, struct proxy *px, struct bi struct listener *l; list_for_each_entry(l, &conf->listeners, by_bind) { - if (l->addr.ss_family == AF_INET6) + if (l->rx.addr.ss_family == AF_INET6) l->options |= LI_O_V4V6; } @@ -56,7 +56,7 @@ static int bind_parse_v6only(char **args, int cur_arg, struct proxy *px, struct struct listener *l; list_for_each_entry(l, &conf->listeners, by_bind) { - if (l->addr.ss_family == AF_INET6) + if (l->rx.addr.ss_family == AF_INET6) l->options |= LI_O_V6ONLY; } @@ -71,7 +71,7 @@ static int bind_parse_transparent(char **args, int cur_arg, struct proxy *px, st struct listener *l; list_for_each_entry(l, &conf->listeners, by_bind) { - if (l->addr.ss_family == AF_INET || l->addr.ss_family == AF_INET6) + if (l->rx.addr.ss_family == AF_INET || l->rx.addr.ss_family == AF_INET6) l->options |= LI_O_FOREIGN; } @@ -86,7 +86,7 @@ static int bind_parse_defer_accept(char **args, int cur_arg, struct proxy *px, s struct listener *l; list_for_each_entry(l, &conf->listeners, by_bind) { - if (l->addr.ss_family == AF_INET || l->addr.ss_family == AF_INET6) + if (l->rx.addr.ss_family == AF_INET || l->rx.addr.ss_family == AF_INET6) l->options |= LI_O_DEF_ACCEPT; } @@ -101,7 +101,7 @@ static int bind_parse_tfo(char **args, int cur_arg, struct proxy *px, struct bin struct listener *l; list_for_each_entry(l, &conf->listeners, by_bind) { - if (l->addr.ss_family == AF_INET || l->addr.ss_family == AF_INET6) + if (l->rx.addr.ss_family == AF_INET || l->rx.addr.ss_family == AF_INET6) l->options |= LI_O_TCP_FO; } @@ -128,7 +128,7 @@ static int bind_parse_mss(char **args, int cur_arg, struct proxy *px, struct bin } list_for_each_entry(l, &conf->listeners, by_bind) { - if (l->addr.ss_family == AF_INET || l->addr.ss_family == AF_INET6) + if (l->rx.addr.ss_family == AF_INET || l->rx.addr.ss_family == AF_INET6) l->maxseg = mss; } @@ -166,7 +166,7 @@ static int bind_parse_tcp_ut(char **args, int cur_arg, struct proxy *px, struct } list_for_each_entry(l, &conf->listeners, by_bind) { - if (l->addr.ss_family == AF_INET || l->addr.ss_family == AF_INET6) + if (l->rx.addr.ss_family == AF_INET || l->rx.addr.ss_family == AF_INET6) l->tcp_ut = timeout; } diff --git a/src/cfgparse.c b/src/cfgparse.c index cc787b2dee..cc5f9f76ec 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -635,7 +635,7 @@ int cfg_parse_peers(const char *file, int linenum, char **args, int kwm) goto out; } } - newpeer->addr = l->addr; + newpeer->addr = l->rx.addr; newpeer->proto = protocol_by_family(newpeer->addr.ss_family); cur_arg++; } diff --git a/src/cli.c b/src/cli.c index 5a2c5c67b2..0d826aa3df 100644 --- a/src/cli.c +++ b/src/cli.c @@ -401,25 +401,25 @@ int listeners_setenv(struct proxy *frontend, const char *varname) if (trash->data) chunk_appendf(trash, ";"); - if (l->addr.ss_family == AF_UNIX) { + if (l->rx.addr.ss_family == AF_UNIX) { const struct sockaddr_un *un; - un = (struct sockaddr_un *)&l->addr; + un = (struct sockaddr_un *)&l->rx.addr; if (un->sun_path[0] == '\0') { chunk_appendf(trash, "abns@%s", un->sun_path+1); } else { chunk_appendf(trash, "unix@%s", un->sun_path); } - } else if (l->addr.ss_family == AF_INET) { - addr_to_str(&l->addr, addr, sizeof(addr)); - port_to_str(&l->addr, port, sizeof(port)); + } else if (l->rx.addr.ss_family == AF_INET) { + addr_to_str(&l->rx.addr, addr, sizeof(addr)); + port_to_str(&l->rx.addr, port, sizeof(port)); chunk_appendf(trash, "ipv4@%s:%s", addr, port); - } else if (l->addr.ss_family == AF_INET6) { - addr_to_str(&l->addr, addr, sizeof(addr)); - port_to_str(&l->addr, port, sizeof(port)); + } else if (l->rx.addr.ss_family == AF_INET6) { + addr_to_str(&l->rx.addr, addr, sizeof(addr)); + port_to_str(&l->rx.addr, port, sizeof(port)); chunk_appendf(trash, "ipv6@[%s]:%s", addr, port); - } else if (l->addr.ss_family == AF_CUST_SOCKPAIR) { - chunk_appendf(trash, "sockpair@%d", ((struct sockaddr_in *)&l->addr)->sin_addr.s_addr); + } else if (l->rx.addr.ss_family == AF_CUST_SOCKPAIR) { + chunk_appendf(trash, "sockpair@%d", ((struct sockaddr_in *)&l->rx.addr)->sin_addr.s_addr); } } } @@ -1239,25 +1239,25 @@ static int cli_io_handler_show_cli_sock(struct appctx *appctx) char addr[46]; char port[6]; - if (l->addr.ss_family == AF_UNIX) { + if (l->rx.addr.ss_family == AF_UNIX) { const struct sockaddr_un *un; - un = (struct sockaddr_un *)&l->addr; + un = (struct sockaddr_un *)&l->rx.addr; if (un->sun_path[0] == '\0') { chunk_appendf(&trash, "abns@%s ", un->sun_path+1); } else { chunk_appendf(&trash, "unix@%s ", un->sun_path); } - } else if (l->addr.ss_family == AF_INET) { - addr_to_str(&l->addr, addr, sizeof(addr)); - port_to_str(&l->addr, port, sizeof(port)); + } else if (l->rx.addr.ss_family == AF_INET) { + addr_to_str(&l->rx.addr, addr, sizeof(addr)); + port_to_str(&l->rx.addr, port, sizeof(port)); chunk_appendf(&trash, "ipv4@%s:%s ", addr, port); - } else if (l->addr.ss_family == AF_INET6) { - addr_to_str(&l->addr, addr, sizeof(addr)); - port_to_str(&l->addr, port, sizeof(port)); + } else if (l->rx.addr.ss_family == AF_INET6) { + addr_to_str(&l->rx.addr, addr, sizeof(addr)); + port_to_str(&l->rx.addr, port, sizeof(port)); chunk_appendf(&trash, "ipv6@[%s]:%s ", addr, port); - } else if (l->addr.ss_family == AF_CUST_SOCKPAIR) { - chunk_appendf(&trash, "sockpair@%d ", ((struct sockaddr_in *)&l->addr)->sin_addr.s_addr); + } else if (l->rx.addr.ss_family == AF_CUST_SOCKPAIR) { + chunk_appendf(&trash, "sockpair@%d ", ((struct sockaddr_in *)&l->rx.addr)->sin_addr.s_addr); } else chunk_appendf(&trash, "unknown "); diff --git a/src/extcheck.c b/src/extcheck.c index e6b30ff9e5..dd7c942404 100644 --- a/src/extcheck.c +++ b/src/extcheck.c @@ -266,9 +266,9 @@ int prepare_external_check(struct check *check) list_for_each_entry(l, &px->conf.listeners, by_fe) /* Use the first INET, INET6 or UNIX listener */ - if (l->addr.ss_family == AF_INET || - l->addr.ss_family == AF_INET6 || - l->addr.ss_family == AF_UNIX) { + if (l->rx.addr.ss_family == AF_INET || + l->rx.addr.ss_family == AF_INET6 || + l->rx.addr.ss_family == AF_UNIX) { listener = l; break; } @@ -292,17 +292,17 @@ int prepare_external_check(struct check *check) check->argv[1] = strdup("NOT_USED"); check->argv[2] = strdup("NOT_USED"); } - else if (listener->addr.ss_family == AF_INET || - listener->addr.ss_family == AF_INET6) { - addr_to_str(&listener->addr, buf, sizeof(buf)); + else if (listener->rx.addr.ss_family == AF_INET || + listener->rx.addr.ss_family == AF_INET6) { + addr_to_str(&listener->rx.addr, buf, sizeof(buf)); check->argv[1] = strdup(buf); - port_to_str(&listener->addr, buf, sizeof(buf)); + port_to_str(&listener->rx.addr, buf, sizeof(buf)); check->argv[2] = strdup(buf); } - else if (listener->addr.ss_family == AF_UNIX) { + else if (listener->rx.addr.ss_family == AF_UNIX) { const struct sockaddr_un *un; - un = (struct sockaddr_un *)&listener->addr; + un = (struct sockaddr_un *)&listener->rx.addr; check->argv[1] = strdup(un->sun_path); check->argv[2] = strdup("NOT_USED"); } diff --git a/src/haproxy.c b/src/haproxy.c index 0f72d5ad8f..12a5992d8b 100644 --- a/src/haproxy.c +++ b/src/haproxy.c @@ -719,11 +719,11 @@ static void get_cur_unixsocket() list_for_each_entry(l, &bind_conf->listeners, by_bind) { - if (l->addr.ss_family == AF_UNIX && + if (l->rx.addr.ss_family == AF_UNIX && (bind_conf->level & ACCESS_FD_LISTENERS)) { const struct sockaddr_un *un; - un = (struct sockaddr_un *)&l->addr; + un = (struct sockaddr_un *)&l->rx.addr; /* priority to old_unixsocket */ if (!cur_unixsocket) { cur_unixsocket = strdup(un->sun_path); diff --git a/src/listener.c b/src/listener.c index b0efa93813..eac95e2da8 100644 --- a/src/listener.c +++ b/src/listener.c @@ -565,7 +565,7 @@ int create_listeners(struct bind_conf *bc, const struct sockaddr_storage *ss, l->bind_conf = bc; l->fd = fd; - memcpy(&l->addr, ss, sizeof(*ss)); + memcpy(&l->rx.addr, ss, sizeof(*ss)); MT_LIST_INIT(&l->wait_queue); l->state = LI_INIT; @@ -765,7 +765,7 @@ void listener_accept(int fd) } /* with sockpair@ we don't want to do an accept */ - if (unlikely(l->addr.ss_family == AF_CUST_SOCKPAIR)) { + if (unlikely(l->rx.addr.ss_family == AF_CUST_SOCKPAIR)) { if ((cfd = recv_fd_uxst(fd)) != -1) fcntl(cfd, F_SETFL, O_NONBLOCK); /* just like with UNIX sockets, only the family is filled */ diff --git a/src/proto_tcp.c b/src/proto_tcp.c index 7bb31b29b3..a338ad83ca 100644 --- a/src/proto_tcp.c +++ b/src/proto_tcp.c @@ -581,7 +581,7 @@ int tcp_bind_listener(struct listener *listener, char *errmsg, int errlen) ext = (fd >= 0); if (!ext) { - fd = my_socketat(listener->bind_conf->settings.netns, listener->addr.ss_family, SOCK_STREAM, IPPROTO_TCP); + fd = my_socketat(listener->bind_conf->settings.netns, listener->rx.addr.ss_family, SOCK_STREAM, IPPROTO_TCP); if (fd == -1) { err |= ERR_RETRYABLE | ERR_ALERT; @@ -631,7 +631,7 @@ int tcp_bind_listener(struct listener *listener, char *errmsg, int errlen) #endif if (!ext && (listener->options & LI_O_FOREIGN)) { - switch (listener->addr.ss_family) { + switch (listener->rx.addr.ss_family) { case AF_INET: if (!sock_inet4_make_foreign(fd)) { msg = "cannot make listening socket transparent"; @@ -670,7 +670,7 @@ int tcp_bind_listener(struct listener *listener, char *errmsg, int errlen) int defaultmss; socklen_t len = sizeof(tmpmaxseg); - if (listener->addr.ss_family == AF_INET) + if (listener->rx.addr.ss_family == AF_INET) defaultmss = sock_inet_tcp_maxseg_default; else defaultmss = sock_inet6_tcp_maxseg_default; @@ -739,7 +739,7 @@ int tcp_bind_listener(struct listener *listener, char *errmsg, int errlen) setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &zero, sizeof(zero)); #endif - if (!ext && bind(fd, (struct sockaddr *)&listener->addr, listener->proto->sock_addrlen) == -1) { + if (!ext && bind(fd, (struct sockaddr *)&listener->rx.addr, listener->proto->sock_addrlen) == -1) { err |= ERR_RETRYABLE | ERR_ALERT; msg = "cannot bind socket"; goto tcp_close_return; @@ -779,8 +779,8 @@ int tcp_bind_listener(struct listener *listener, char *errmsg, int errlen) if (msg && errlen) { char pn[INET6_ADDRSTRLEN]; - addr_to_str(&listener->addr, pn, sizeof(pn)); - snprintf(errmsg, errlen, "%s [%s:%d]", msg, pn, get_host_port(&listener->addr)); + addr_to_str(&listener->rx.addr, pn, sizeof(pn)); + snprintf(errmsg, errlen, "%s [%s:%d]", msg, pn, get_host_port(&listener->rx.addr)); } return err; @@ -802,7 +802,7 @@ static void tcpv4_add_listener(struct listener *listener, int port) return; listener->state = LI_ASSIGNED; listener->proto = &proto_tcpv4; - ((struct sockaddr_in *)(&listener->addr))->sin_port = htons(port); + ((struct sockaddr_in *)(&listener->rx.addr))->sin_port = htons(port); LIST_ADDQ(&proto_tcpv4.listeners, &listener->proto_list); proto_tcpv4.nb_listeners++; } @@ -820,7 +820,7 @@ static void tcpv6_add_listener(struct listener *listener, int port) return; listener->state = LI_ASSIGNED; listener->proto = &proto_tcpv6; - ((struct sockaddr_in *)(&listener->addr))->sin_port = htons(port); + ((struct sockaddr_in *)(&listener->rx.addr))->sin_port = htons(port); LIST_ADDQ(&proto_tcpv6.listeners, &listener->proto_list); proto_tcpv6.nb_listeners++; } diff --git a/src/proto_udp.c b/src/proto_udp.c index 92dad6afb1..7d190a1718 100644 --- a/src/proto_udp.c +++ b/src/proto_udp.c @@ -181,7 +181,7 @@ int udp_bind_listener(struct listener *listener, char *errmsg, int errlen) int fd, err; const char *msg = NULL; /* copy listener addr because sometimes we need to switch family */ - struct sockaddr_storage addr_inet = listener->addr; + struct sockaddr_storage addr_inet = listener->rx.addr; /* force to classic sock family */ addr_inet.ss_family = listener->proto->sock_family; @@ -311,7 +311,7 @@ static void udp4_add_listener(struct listener *listener, int port) return; listener->state = LI_ASSIGNED; listener->proto = &proto_udp4; - ((struct sockaddr_in *)(&listener->addr))->sin_port = htons(port); + ((struct sockaddr_in *)(&listener->rx.addr))->sin_port = htons(port); LIST_ADDQ(&proto_udp4.listeners, &listener->proto_list); proto_udp4.nb_listeners++; } @@ -326,7 +326,7 @@ static void udp6_add_listener(struct listener *listener, int port) return; listener->state = LI_ASSIGNED; listener->proto = &proto_udp6; - ((struct sockaddr_in *)(&listener->addr))->sin_port = htons(port); + ((struct sockaddr_in *)(&listener->rx.addr))->sin_port = htons(port); LIST_ADDQ(&proto_udp6.listeners, &listener->proto_list); proto_udp6.nb_listeners++; } diff --git a/src/proto_uxst.c b/src/proto_uxst.c index ac2fb536eb..33768a1d5b 100644 --- a/src/proto_uxst.c +++ b/src/proto_uxst.c @@ -112,7 +112,7 @@ static int uxst_bind_listener(struct listener *listener, char *errmsg, int errle if (listener->fd == -1) listener->fd = sock_find_compatible_fd(listener); - path = ((struct sockaddr_un *)&listener->addr)->sun_path; + path = ((struct sockaddr_un *)&listener->rx.addr)->sun_path; maxpathlen = MIN(MAXPATHLEN, sizeof(addr.sun_path)); @@ -316,7 +316,7 @@ static void uxst_add_listener(struct listener *listener, int port) */ static int uxst_pause_listener(struct listener *l) { - if (((struct sockaddr_un *)&l->addr)->sun_path[0]) + if (((struct sockaddr_un *)&l->rx.addr)->sun_path[0]) return 1; /* Listener's lock already held. Call lockless version of diff --git a/src/proxy.c b/src/proxy.c index 8fbb8171df..dda701cee4 100644 --- a/src/proxy.c +++ b/src/proxy.c @@ -1405,7 +1405,7 @@ int resume_proxy(struct proxy *p) if (!resume_listener(l)) { int port; - port = get_host_port(&l->addr); + port = get_host_port(&l->rx.addr); if (port) { ha_warning("Port %d busy while trying to enable %s %s.\n", port, proxy_cap_str(p->cap), p->id); diff --git a/src/session.c b/src/session.c index c303585410..871a6acedf 100644 --- a/src/session.c +++ b/src/session.c @@ -220,7 +220,7 @@ int session_accept_fd(struct listener *l, int cfd, struct sockaddr_storage *addr } /* Adjust some socket options */ - if (l->addr.ss_family == AF_INET || l->addr.ss_family == AF_INET6) { + if (l->rx.addr.ss_family == AF_INET || l->rx.addr.ss_family == AF_INET6) { setsockopt(cfd, IPPROTO_TCP, TCP_NODELAY, (char *) &one, sizeof(one)); if (p->options & PR_O_TCP_CLI_KA) { diff --git a/src/sock.c b/src/sock.c index a9dd5f2ff9..161e7238dc 100644 --- a/src/sock.c +++ b/src/sock.c @@ -369,13 +369,13 @@ int sock_find_compatible_fd(const struct listener *l) /* WT: this is not the right way to do it, it is temporary for the * transition to receivers. */ - if (l->addr.ss_family == AF_CUST_UDP4 || l->addr.ss_family == AF_CUST_UDP6) + if (l->rx.addr.ss_family == AF_CUST_UDP4 || l->rx.addr.ss_family == AF_CUST_UDP6) options |= SOCK_XFER_OPT_DGRAM; if (l->options & LI_O_FOREIGN) options |= SOCK_XFER_OPT_FOREIGN; - if (l->addr.ss_family == AF_INET6) { + if (l->rx.addr.ss_family == AF_INET6) { /* Prepare to match the v6only option against what we really want. Note * that sadly the two options are not exclusive to each other and that * v6only is stronger than v4v6. @@ -400,7 +400,7 @@ int sock_find_compatible_fd(const struct listener *l) #ifdef USE_NS (!ns_namelen || strcmp(l->bind_conf->settings.netns->node.key, xfer_sock->namespace) == 0) && #endif - l->proto->addrcmp(&xfer_sock->addr, &l->addr) == 0) + l->proto->addrcmp(&xfer_sock->addr, &l->rx.addr) == 0) break; xfer_sock = xfer_sock->next; } diff --git a/src/stats.c b/src/stats.c index 36aee99f9a..38cac0cb93 100644 --- a/src/stats.c +++ b/src/stats.c @@ -1535,8 +1535,8 @@ int stats_fill_li_stats(struct proxy *px, struct listener *l, int flags, char str[INET6_ADDRSTRLEN]; int port; - port = get_host_port(&l->addr); - switch (addr_to_str(&l->addr, str, sizeof(str))) { + port = get_host_port(&l->rx.addr); + switch (addr_to_str(&l->rx.addr, str, sizeof(str))) { case AF_INET: stats[ST_F_ADDR] = mkf_str(FO_CONFIG|FS_SERVICE, chunk_newstr(out)); chunk_appendf(out, "%s:%d", str, port);