The address will be specific to the receiver so let's move it there.
/* 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
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 */
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;
}
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;
}
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;
}
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;
}
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;
}
}
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;
}
}
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;
}
goto out;
}
}
- newpeer->addr = l->addr;
+ newpeer->addr = l->rx.addr;
newpeer->proto = protocol_by_family(newpeer->addr.ss_family);
cur_arg++;
}
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);
}
}
}
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 ");
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;
}
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");
}
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);
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;
}
/* 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 */
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;
#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";
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;
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;
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;
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++;
}
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++;
}
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;
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++;
}
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++;
}
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));
*/
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
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);
}
/* 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) {
/* 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.
#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;
}
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);