From: Willy Tarreau Date: Fri, 28 Aug 2020 17:51:44 +0000 (+0200) Subject: REORG: listener: move the listener's proto to the receiver X-Git-Tag: v2.3-dev5~67 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=b743661f0495247528d74b618301f989ebec46b3;p=thirdparty%2Fhaproxy.git REORG: listener: move the listener's proto to the receiver The receiver is the one which depends on the protocol while the listener relies on the receiver. Let's move the protocol there. Since there's also a list element to get back to the listener from the proto list, this list element (proto_list) was moved as well. For now when scanning protos, we still see listeners which are linked by their rx.proto_list part. --- diff --git a/include/haproxy/listener-t.h b/include/haproxy/listener-t.h index 2bc0d0cac3..d7c45d5fa3 100644 --- a/include/haproxy/listener-t.h +++ b/include/haproxy/listener-t.h @@ -195,6 +195,8 @@ struct bind_conf { struct receiver { int fd; /* handle we receive from (fd only for now) */ unsigned int flags; /* receiver options (RX_F_*) */ + struct protocol *proto; /* protocol this receiver belongs to */ + struct list proto_list; /* list in the protocol header */ /* warning: this struct is huge, keep it at the bottom */ struct sockaddr_storage addr; /* the address the socket is bound to */ }; @@ -210,7 +212,6 @@ struct listener { int luid; /* listener universally unique ID, used for SNMP */ int options; /* socket options : LI_O_* */ struct fe_counters *counters; /* statistics counters */ - struct protocol *proto; /* protocol this listener belongs to */ int nbconn; /* current number of connections on this listener */ int maxconn; /* maximum connections allowed on this listener */ unsigned int backlog; /* if set, listen backlog */ @@ -235,7 +236,6 @@ struct listener { struct list by_fe; /* chaining in frontend's list of listeners */ struct list by_bind; /* chaining in bind_conf's list of listeners */ 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 */ struct { struct eb32_node id; /* place in the tree of used IDs */ diff --git a/src/listener.c b/src/listener.c index b62d6fd9f4..1a8b5ad659 100644 --- a/src/listener.c +++ b/src/listener.c @@ -296,11 +296,11 @@ int pause_listener(struct listener *l) if (l->state <= LI_ZOMBIE) goto end; - if (l->proto->pause) { + if (l->rx.proto->pause) { /* Returns < 0 in case of failure, 0 if the listener * was totally stopped, or > 0 if correctly paused. */ - int ret = l->proto->pause(l); + int ret = l->rx.proto->pause(l); if (ret < 0) { ret = 0; @@ -349,7 +349,7 @@ int resume_listener(struct listener *l) char msg[100]; int err; - err = l->proto->bind(l, msg, sizeof(msg)); + err = l->rx.proto->bind(l, msg, sizeof(msg)); if (err & ERR_ALERT) ha_alert("Resuming listener: %s\n", msg); else if (err & ERR_WARN) @@ -366,7 +366,7 @@ int resume_listener(struct listener *l) goto end; } - if (l->proto->sock_prot == IPPROTO_TCP && + if (l->rx.proto->sock_prot == IPPROTO_TCP && l->state == LI_PAUSED && listen(l->rx.fd, listener_backlog(l)) != 0) { ret = 0; @@ -442,7 +442,7 @@ int enable_all_listeners(struct protocol *proto) { struct listener *listener; - list_for_each_entry(listener, &proto->listeners, proto_list) + list_for_each_entry(listener, &proto->listeners, rx.proto_list) enable_listener(listener); return ERR_NONE; } @@ -459,7 +459,7 @@ int disable_all_listeners(struct protocol *proto) { struct listener *listener; - list_for_each_entry(listener, &proto->listeners, proto_list) + list_for_each_entry(listener, &proto->listeners, rx.proto_list) disable_listener(listener); return ERR_NONE; } @@ -596,8 +596,8 @@ void delete_listener(struct listener *listener) HA_SPIN_LOCK(LISTENER_LOCK, &listener->lock); if (listener->state == LI_ASSIGNED) { listener->state = LI_INIT; - LIST_DEL(&listener->proto_list); - listener->proto->nb_listeners--; + LIST_DEL(&listener->rx.proto_list); + listener->rx.proto->nb_listeners--; _HA_ATOMIC_SUB(&jobs, 1); _HA_ATOMIC_SUB(&listeners, 1); } diff --git a/src/log.c b/src/log.c index c1c6eda3cd..702f443d97 100644 --- a/src/log.c +++ b/src/log.c @@ -3642,7 +3642,7 @@ int cfg_parse_log_forward(const char *file, int linenum, char **args, int kwm) } list_for_each_entry(l, &bind_conf->listeners, by_bind) { /* Currently, only UDP handlers are allowed */ - if (l->proto->sock_domain != AF_CUST_UDP4 && l->proto->sock_domain != AF_CUST_UDP6) { + if (l->rx.proto->sock_domain != AF_CUST_UDP4 && l->rx.proto->sock_domain != AF_CUST_UDP6) { ha_alert("parsing [%s:%d] : '%s %s' : error, listening address must be prefixed using 'udp@', 'udp4@' or 'udp6@' %s.\n", file, linenum, args[0], args[1], args[2]); err_code |= ERR_ALERT | ERR_FATAL; diff --git a/src/proto_sockpair.c b/src/proto_sockpair.c index c73699511a..4030c33a2c 100644 --- a/src/proto_sockpair.c +++ b/src/proto_sockpair.c @@ -80,8 +80,8 @@ static void sockpair_add_listener(struct listener *listener, int port) if (listener->state != LI_INIT) return; listener->state = LI_ASSIGNED; - listener->proto = &proto_sockpair; - LIST_ADDQ(&proto_sockpair.listeners, &listener->proto_list); + listener->rx.proto = &proto_sockpair; + LIST_ADDQ(&proto_sockpair.listeners, &listener->rx.proto_list); proto_sockpair.nb_listeners++; } @@ -125,7 +125,7 @@ static int sockpair_bind_listener(struct listener *listener, char *errmsg, int e listener->state = LI_LISTEN; - fd_insert(fd, listener, listener->proto->accept, + fd_insert(fd, listener, listener->rx.proto->accept, thread_mask(listener->bind_conf->settings.bind_thread) & all_threads_mask); return err; diff --git a/src/proto_tcp.c b/src/proto_tcp.c index a97cdc31c6..79b68b4485 100644 --- a/src/proto_tcp.c +++ b/src/proto_tcp.c @@ -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->rx.addr, listener->proto->sock_addrlen) == -1) { + if (!ext && bind(fd, (struct sockaddr *)&listener->rx.addr, listener->rx.proto->sock_addrlen) == -1) { err |= ERR_RETRYABLE | ERR_ALERT; msg = "cannot bind socket"; goto tcp_close_return; @@ -768,7 +768,7 @@ int tcp_bind_listener(struct listener *listener, char *errmsg, int errlen) listener->rx.fd = fd; listener->state = LI_LISTEN; - fd_insert(fd, listener, listener->proto->accept, + fd_insert(fd, listener, listener->rx.proto->accept, thread_mask(listener->bind_conf->settings.bind_thread) & all_threads_mask); /* for now, all regularly bound TCP listeners are exportable */ @@ -801,9 +801,9 @@ static void tcpv4_add_listener(struct listener *listener, int port) if (listener->state != LI_INIT) return; listener->state = LI_ASSIGNED; - listener->proto = &proto_tcpv4; + listener->rx.proto = &proto_tcpv4; ((struct sockaddr_in *)(&listener->rx.addr))->sin_port = htons(port); - LIST_ADDQ(&proto_tcpv4.listeners, &listener->proto_list); + LIST_ADDQ(&proto_tcpv4.listeners, &listener->rx.proto_list); proto_tcpv4.nb_listeners++; } @@ -819,9 +819,9 @@ static void tcpv6_add_listener(struct listener *listener, int port) if (listener->state != LI_INIT) return; listener->state = LI_ASSIGNED; - listener->proto = &proto_tcpv6; + listener->rx.proto = &proto_tcpv6; ((struct sockaddr_in *)(&listener->rx.addr))->sin_port = htons(port); - LIST_ADDQ(&proto_tcpv6.listeners, &listener->proto_list); + LIST_ADDQ(&proto_tcpv6.listeners, &listener->rx.proto_list); proto_tcpv6.nb_listeners++; } diff --git a/src/proto_udp.c b/src/proto_udp.c index 38be905c59..5cd7b73652 100644 --- a/src/proto_udp.c +++ b/src/proto_udp.c @@ -184,7 +184,7 @@ int udp_bind_listener(struct listener *listener, char *errmsg, int errlen) struct sockaddr_storage addr_inet = listener->rx.addr; /* force to classic sock family */ - addr_inet.ss_family = listener->proto->sock_family; + addr_inet.ss_family = listener->rx.proto->sock_family; /* ensure we never return garbage */ if (errlen) @@ -200,7 +200,10 @@ int udp_bind_listener(struct listener *listener, char *errmsg, int errlen) * IPPROTO (sockaddr is not enough) */ - fd = my_socketat(listener->bind_conf->settings.netns, listener->proto->sock_family, listener->proto->sock_type, listener->proto->sock_prot); + fd = my_socketat(listener->bind_conf->settings.netns, + listener->rx.proto->sock_family, + listener->rx.proto->sock_type, + listener->rx.proto->sock_prot); if (fd == -1) { err |= ERR_RETRYABLE | ERR_ALERT; msg = "cannot create listening socket"; @@ -268,7 +271,7 @@ int udp_bind_listener(struct listener *listener, char *errmsg, int errlen) setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &zero, sizeof(zero)); #endif - if (bind(fd, (struct sockaddr *)&addr_inet, listener->proto->sock_addrlen) < 0) { + if (bind(fd, (struct sockaddr *)&addr_inet, listener->rx.proto->sock_addrlen) < 0) { err |= ERR_RETRYABLE | ERR_ALERT; msg = "cannot bind socket"; goto udp_close_return; @@ -310,9 +313,9 @@ static void udp4_add_listener(struct listener *listener, int port) if (listener->state != LI_INIT) return; listener->state = LI_ASSIGNED; - listener->proto = &proto_udp4; + listener->rx.proto = &proto_udp4; ((struct sockaddr_in *)(&listener->rx.addr))->sin_port = htons(port); - LIST_ADDQ(&proto_udp4.listeners, &listener->proto_list); + LIST_ADDQ(&proto_udp4.listeners, &listener->rx.proto_list); proto_udp4.nb_listeners++; } @@ -325,9 +328,9 @@ static void udp6_add_listener(struct listener *listener, int port) if (listener->state != LI_INIT) return; listener->state = LI_ASSIGNED; - listener->proto = &proto_udp6; + listener->rx.proto = &proto_udp6; ((struct sockaddr_in *)(&listener->rx.addr))->sin_port = htons(port); - LIST_ADDQ(&proto_udp6.listeners, &listener->proto_list); + LIST_ADDQ(&proto_udp6.listeners, &listener->rx.proto_list); proto_udp6.nb_listeners++; } diff --git a/src/proto_uxst.c b/src/proto_uxst.c index 9b5a28d1f0..a63f183c9e 100644 --- a/src/proto_uxst.c +++ b/src/proto_uxst.c @@ -261,7 +261,7 @@ static int uxst_bind_listener(struct listener *listener, char *errmsg, int errle listener->rx.fd = fd; listener->state = LI_LISTEN; - fd_insert(fd, listener, listener->proto->accept, + fd_insert(fd, listener, listener->rx.proto->accept, thread_mask(listener->bind_conf->settings.bind_thread) & all_threads_mask); /* for now, all regularly bound UNIX listeners are exportable */ @@ -303,8 +303,8 @@ static void uxst_add_listener(struct listener *listener, int port) if (listener->state != LI_INIT) return; listener->state = LI_ASSIGNED; - listener->proto = &proto_unix; - LIST_ADDQ(&proto_unix.listeners, &listener->proto_list); + listener->rx.proto = &proto_unix; + LIST_ADDQ(&proto_unix.listeners, &listener->rx.proto_list); proto_unix.nb_listeners++; } diff --git a/src/protocol.c b/src/protocol.c index a942e44930..bf1b1c5cbd 100644 --- a/src/protocol.c +++ b/src/protocol.c @@ -66,7 +66,7 @@ int protocol_bind_all(int verbose) err = 0; HA_SPIN_LOCK(PROTO_LOCK, &proto_lock); list_for_each_entry(proto, &protocols, list) { - list_for_each_entry(listener, &proto->listeners, proto_list) { + list_for_each_entry(listener, &proto->listeners, rx.proto_list) { lerr = proto->bind(listener, msg, sizeof(msg)); /* errors are reported if is set or if they are fatal */ @@ -106,7 +106,7 @@ int protocol_unbind_all(void) err = 0; HA_SPIN_LOCK(PROTO_LOCK, &proto_lock); list_for_each_entry(proto, &protocols, list) { - list_for_each_entry(listener, &proto->listeners, proto_list) + list_for_each_entry(listener, &proto->listeners, rx.proto_list) unbind_listener(listener); } HA_SPIN_UNLOCK(PROTO_LOCK, &proto_lock); diff --git a/src/session.c b/src/session.c index 871a6acedf..58eacd41a4 100644 --- a/src/session.c +++ b/src/session.c @@ -155,7 +155,7 @@ int session_accept_fd(struct listener *l, int cfd, struct sockaddr_storage *addr cli_conn->flags |= CO_FL_ADDR_FROM_SET; cli_conn->proxy_netns = l->bind_conf->settings.netns; - conn_prepare(cli_conn, l->proto, l->bind_conf->xprt); + conn_prepare(cli_conn, l->rx.proto, l->bind_conf->xprt); conn_ctrl_init(cli_conn); /* wait for a PROXY protocol header */ @@ -207,8 +207,8 @@ int session_accept_fd(struct listener *l, int cfd, struct sockaddr_storage *addr * - HEALTH mode without HTTP check => just send "OK" * - TCP mode from monitoring address => just close */ - if (l->proto->drain) - l->proto->drain(cfd); + if (l->rx.proto->drain) + l->rx.proto->drain(cfd); if (p->mode == PR_MODE_HTTP || (p->mode == PR_MODE_HEALTH && (p->options2 & PR_O2_CHK_ANY) == PR_O2_TCPCHK_CHK && (p->tcpcheck_rules.flags & TCPCHK_RULES_PROTO_CHK) == TCPCHK_RULES_HTTP_CHK)) diff --git a/src/sock.c b/src/sock.c index 161e7238dc..8bdc3eaffa 100644 --- a/src/sock.c +++ b/src/sock.c @@ -363,7 +363,7 @@ int sock_find_compatible_fd(const struct listener *l) int ns_namelen = 0; int ret = -1; - if (!l->proto->addrcmp) + if (!l->rx.proto->addrcmp) return -1; /* WT: this is not the right way to do it, it is temporary for the @@ -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->rx.addr) == 0) + l->rx.proto->addrcmp(&xfer_sock->addr, &l->rx.addr) == 0) break; xfer_sock = xfer_sock->next; } diff --git a/src/stream.c b/src/stream.c index f2826651ec..b298d7b79e 100644 --- a/src/stream.c +++ b/src/stream.c @@ -2823,7 +2823,7 @@ static int stats_dump_full_strm_to_buffer(struct stream_interface *si, struct st tm.tm_mday, monthname[tm.tm_mon], tm.tm_year+1900, tm.tm_hour, tm.tm_min, tm.tm_sec, (int)(strm->logs.accept_date.tv_usec), strm->uniq_id, - strm_li(strm) ? strm_li(strm)->proto->name : "?"); + strm_li(strm) ? strm_li(strm)->rx.proto->name : "?"); conn = objt_conn(strm_orig(strm)); switch (conn && conn_get_src(conn) ? addr_to_str(conn->src, pn, sizeof(pn)) : AF_UNSPEC) { @@ -3232,7 +3232,7 @@ static int cli_io_handler_dump_sess(struct appctx *appctx) chunk_appendf(&trash, "%p: proto=%s", curr_strm, - strm_li(curr_strm) ? strm_li(curr_strm)->proto->name : "?"); + strm_li(curr_strm) ? strm_li(curr_strm)->rx.proto->name : "?"); conn = objt_conn(strm_orig(curr_strm)); switch (conn && conn_get_src(conn) ? addr_to_str(conn->src, pn, sizeof(pn)) : AF_UNSPEC) {