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.
This commit is contained in:
Willy Tarreau 2020-08-28 19:51:44 +02:00
parent 38ba647f9f
commit b743661f04
11 changed files with 42 additions and 39 deletions

View File

@ -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 */

View File

@ -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);
}

View File

@ -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;

View File

@ -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;

View File

@ -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++;
}

View File

@ -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++;
}

View File

@ -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++;
}

View File

@ -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 <verbose> 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);

View File

@ -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))

View File

@ -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;
}

View File

@ -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) {