diff --git a/include/haproxy/listener-t.h b/include/haproxy/listener-t.h index 2bc0d0cac..d7c45d5fa 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 b62d6fd9f..1a8b5ad65 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 c1c6eda3c..702f443d9 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 c73699511..4030c33a2 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 a97cdc31c..79b68b448 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 38be905c5..5cd7b7365 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 9b5a28d1f..a63f183c9 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 a942e4493..bf1b1c5cb 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 871a6aced..58eacd41a 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 161e7238d..8bdc3eaff 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 f2826651e..b298d7b79 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) {