mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-05-07 02:08:04 +00:00
MINOR: tcp/udp/unix: make use of proto->addrcmp() to compare addresses
The new addrcmp() protocol member points to the function to be used to compare two addresses of the same family. When picking an FD from a previous process, we can now use the address specific address comparison functions instead of having to rely on a local implementation. This will help move that code to a more central place.
This commit is contained in:
parent
0d06df6448
commit
f172558b27
@ -83,6 +83,7 @@ struct protocol {
|
|||||||
int (*drain)(int fd); /* indicates whether we can safely close the fd */
|
int (*drain)(int fd); /* indicates whether we can safely close the fd */
|
||||||
int (*pause)(struct listener *l); /* temporarily pause this listener for a soft restart */
|
int (*pause)(struct listener *l); /* temporarily pause this listener for a soft restart */
|
||||||
void (*add)(struct listener *l, int port); /* add a listener for this protocol and port */
|
void (*add)(struct listener *l, int port); /* add a listener for this protocol and port */
|
||||||
|
int (*addrcmp)(const struct sockaddr_storage *, const struct sockaddr_storage *); /* compare addresses (like memcmp) */
|
||||||
|
|
||||||
struct list listeners; /* list of listeners using this protocol (under proto_lock) */
|
struct list listeners; /* list of listeners using this protocol (under proto_lock) */
|
||||||
int nb_listeners; /* number of listeners (under proto_lock) */
|
int nb_listeners; /* number of listeners (under proto_lock) */
|
||||||
|
@ -40,6 +40,7 @@
|
|||||||
#include <haproxy/protocol.h>
|
#include <haproxy/protocol.h>
|
||||||
#include <haproxy/proxy-t.h>
|
#include <haproxy/proxy-t.h>
|
||||||
#include <haproxy/sock.h>
|
#include <haproxy/sock.h>
|
||||||
|
#include <haproxy/sock_inet.h>
|
||||||
#include <haproxy/tools.h>
|
#include <haproxy/tools.h>
|
||||||
|
|
||||||
|
|
||||||
@ -67,6 +68,7 @@ static struct protocol proto_tcpv4 = {
|
|||||||
.get_dst = tcp_get_dst,
|
.get_dst = tcp_get_dst,
|
||||||
.pause = tcp_pause_listener,
|
.pause = tcp_pause_listener,
|
||||||
.add = tcpv4_add_listener,
|
.add = tcpv4_add_listener,
|
||||||
|
.addrcmp = sock_inet4_addrcmp,
|
||||||
.listeners = LIST_HEAD_INIT(proto_tcpv4.listeners),
|
.listeners = LIST_HEAD_INIT(proto_tcpv4.listeners),
|
||||||
.nb_listeners = 0,
|
.nb_listeners = 0,
|
||||||
};
|
};
|
||||||
@ -92,6 +94,7 @@ static struct protocol proto_tcpv6 = {
|
|||||||
.get_dst = tcp_get_dst,
|
.get_dst = tcp_get_dst,
|
||||||
.pause = tcp_pause_listener,
|
.pause = tcp_pause_listener,
|
||||||
.add = tcpv6_add_listener,
|
.add = tcpv6_add_listener,
|
||||||
|
.addrcmp = sock_inet6_addrcmp,
|
||||||
.listeners = LIST_HEAD_INIT(proto_tcpv6.listeners),
|
.listeners = LIST_HEAD_INIT(proto_tcpv6.listeners),
|
||||||
.nb_listeners = 0,
|
.nb_listeners = 0,
|
||||||
};
|
};
|
||||||
@ -610,35 +613,6 @@ int tcp_get_dst(int fd, struct sockaddr *sa, socklen_t salen, int dir)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* XXX: Should probably be elsewhere */
|
|
||||||
static int compare_sockaddr(struct sockaddr_storage *a, struct sockaddr_storage *b)
|
|
||||||
{
|
|
||||||
if (a->ss_family != b->ss_family) {
|
|
||||||
return (-1);
|
|
||||||
}
|
|
||||||
switch (a->ss_family) {
|
|
||||||
case AF_INET:
|
|
||||||
{
|
|
||||||
struct sockaddr_in *a4 = (void *)a, *b4 = (void *)b;
|
|
||||||
if (a4->sin_port != b4->sin_port)
|
|
||||||
return (-1);
|
|
||||||
return (memcmp(&a4->sin_addr, &b4->sin_addr,
|
|
||||||
sizeof(a4->sin_addr)));
|
|
||||||
}
|
|
||||||
case AF_INET6:
|
|
||||||
{
|
|
||||||
struct sockaddr_in6 *a6 = (void *)a, *b6 = (void *)b;
|
|
||||||
if (a6->sin6_port != b6->sin6_port)
|
|
||||||
return (-1);
|
|
||||||
return (memcmp(&a6->sin6_addr, &b6->sin6_addr,
|
|
||||||
sizeof(a6->sin6_addr)));
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return (-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Returns true if the passed FD corresponds to a socket bound with LI_O_FOREIGN
|
/* Returns true if the passed FD corresponds to a socket bound with LI_O_FOREIGN
|
||||||
* according to the various supported socket options. The socket's address family
|
* according to the various supported socket options. The socket's address family
|
||||||
* must be passed in <family>.
|
* must be passed in <family>.
|
||||||
@ -747,7 +721,7 @@ static int tcp_find_compatible_fd(struct listener *l)
|
|||||||
options &= ~LI_O_V4V6;
|
options &= ~LI_O_V4V6;
|
||||||
|
|
||||||
while (xfer_sock) {
|
while (xfer_sock) {
|
||||||
if (!compare_sockaddr(&xfer_sock->addr, &l->addr)) {
|
if (!l->proto->addrcmp(&xfer_sock->addr, &l->addr)) {
|
||||||
if ((l->interface == NULL && xfer_sock->iface == NULL) ||
|
if ((l->interface == NULL && xfer_sock->iface == NULL) ||
|
||||||
(l->interface != NULL && xfer_sock->iface != NULL &&
|
(l->interface != NULL && xfer_sock->iface != NULL &&
|
||||||
!strcmp(l->interface, xfer_sock->iface))) {
|
!strcmp(l->interface, xfer_sock->iface))) {
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
#include <haproxy/proxy.h>
|
#include <haproxy/proxy.h>
|
||||||
#include <haproxy/server.h>
|
#include <haproxy/server.h>
|
||||||
#include <haproxy/sock.h>
|
#include <haproxy/sock.h>
|
||||||
|
#include <haproxy/sock_inet.h>
|
||||||
#include <haproxy/task.h>
|
#include <haproxy/task.h>
|
||||||
|
|
||||||
static int udp_bind_listeners(struct protocol *proto, char *errmsg, int errlen);
|
static int udp_bind_listeners(struct protocol *proto, char *errmsg, int errlen);
|
||||||
@ -63,6 +64,7 @@ static struct protocol proto_udp4 = {
|
|||||||
.get_dst = udp_get_dst,
|
.get_dst = udp_get_dst,
|
||||||
.pause = udp_pause_listener,
|
.pause = udp_pause_listener,
|
||||||
.add = udp4_add_listener,
|
.add = udp4_add_listener,
|
||||||
|
.addrcmp = sock_inet4_addrcmp,
|
||||||
.listeners = LIST_HEAD_INIT(proto_udp4.listeners),
|
.listeners = LIST_HEAD_INIT(proto_udp4.listeners),
|
||||||
.nb_listeners = 0,
|
.nb_listeners = 0,
|
||||||
};
|
};
|
||||||
@ -88,6 +90,7 @@ static struct protocol proto_udp6 = {
|
|||||||
.get_dst = udp_get_dst,
|
.get_dst = udp_get_dst,
|
||||||
.pause = udp_pause_listener,
|
.pause = udp_pause_listener,
|
||||||
.add = udp6_add_listener,
|
.add = udp6_add_listener,
|
||||||
|
.addrcmp = sock_inet6_addrcmp,
|
||||||
.listeners = LIST_HEAD_INIT(proto_udp6.listeners),
|
.listeners = LIST_HEAD_INIT(proto_udp6.listeners),
|
||||||
.nb_listeners = 0,
|
.nb_listeners = 0,
|
||||||
};
|
};
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
#include <haproxy/log.h>
|
#include <haproxy/log.h>
|
||||||
#include <haproxy/protocol.h>
|
#include <haproxy/protocol.h>
|
||||||
#include <haproxy/sock.h>
|
#include <haproxy/sock.h>
|
||||||
|
#include <haproxy/sock_unix.h>
|
||||||
#include <haproxy/time.h>
|
#include <haproxy/time.h>
|
||||||
#include <haproxy/tools.h>
|
#include <haproxy/tools.h>
|
||||||
#include <haproxy/version.h>
|
#include <haproxy/version.h>
|
||||||
@ -66,6 +67,7 @@ static struct protocol proto_unix = {
|
|||||||
.get_dst = sock_get_dst,
|
.get_dst = sock_get_dst,
|
||||||
.pause = uxst_pause_listener,
|
.pause = uxst_pause_listener,
|
||||||
.add = uxst_add_listener,
|
.add = uxst_add_listener,
|
||||||
|
.addrcmp = sock_unix_addrcmp,
|
||||||
.listeners = LIST_HEAD_INIT(proto_unix.listeners),
|
.listeners = LIST_HEAD_INIT(proto_unix.listeners),
|
||||||
.nb_listeners = 0,
|
.nb_listeners = 0,
|
||||||
};
|
};
|
||||||
@ -88,37 +90,13 @@ static int uxst_find_compatible_fd(struct listener *l)
|
|||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
|
||||||
while (xfer_sock) {
|
while (xfer_sock) {
|
||||||
struct sockaddr_un *un1 = (void *)&l->addr;
|
|
||||||
struct sockaddr_un *un2 = (void *)&xfer_sock->addr;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The bound socket's path as returned by getsockaddr
|
* The bound socket's path as returned by getsockaddr
|
||||||
* will be the temporary name <sockname>.XXXXX.tmp,
|
* will be the temporary name <sockname>.XXXXX.tmp,
|
||||||
* so we can't just compare the two names
|
* so we can't just compare the two names
|
||||||
*/
|
*/
|
||||||
if (xfer_sock->addr.ss_family == AF_UNIX &&
|
if (!l->proto->addrcmp(&xfer_sock->addr, &l->addr))
|
||||||
strncmp(un1->sun_path, un2->sun_path,
|
|
||||||
strlen(un1->sun_path)) == 0) {
|
|
||||||
char *after_sockname = un2->sun_path +
|
|
||||||
strlen(un1->sun_path);
|
|
||||||
/* Make a reasonable effort to check that
|
|
||||||
* it is indeed a haproxy-generated temporary
|
|
||||||
* name, it's not perfect, but probably good enough.
|
|
||||||
*/
|
|
||||||
if (after_sockname[0] == '.') {
|
|
||||||
after_sockname++;
|
|
||||||
while (after_sockname[0] >= '0' &&
|
|
||||||
after_sockname[0] <= '9')
|
|
||||||
after_sockname++;
|
|
||||||
if (!strcmp(after_sockname, ".tmp"))
|
|
||||||
break;
|
|
||||||
/* abns sockets sun_path starts with a \0 */
|
|
||||||
} else if (un1->sun_path[0] == 0
|
|
||||||
&& un2->sun_path[0] == 0
|
|
||||||
&& !memcmp(&un1->sun_path[1], &un2->sun_path[1],
|
|
||||||
sizeof(un1->sun_path) - 1))
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
xfer_sock = xfer_sock->next;
|
xfer_sock = xfer_sock->next;
|
||||||
}
|
}
|
||||||
if (xfer_sock != NULL) {
|
if (xfer_sock != NULL) {
|
||||||
|
Loading…
Reference in New Issue
Block a user