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 */
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) */
int nb_listeners; /* number of listeners (under proto_lock) */
#include <haproxy/protocol.h>
#include <haproxy/proxy-t.h>
#include <haproxy/sock.h>
+#include <haproxy/sock_inet.h>
#include <haproxy/tools.h>
.get_dst = tcp_get_dst,
.pause = tcp_pause_listener,
.add = tcpv4_add_listener,
+ .addrcmp = sock_inet4_addrcmp,
.listeners = LIST_HEAD_INIT(proto_tcpv4.listeners),
.nb_listeners = 0,
};
.get_dst = tcp_get_dst,
.pause = tcp_pause_listener,
.add = tcpv6_add_listener,
+ .addrcmp = sock_inet6_addrcmp,
.listeners = LIST_HEAD_INIT(proto_tcpv6.listeners),
.nb_listeners = 0,
};
}
}
-/* 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
* according to the various supported socket options. The socket's address family
* must be passed in <family>.
options &= ~LI_O_V4V6;
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) ||
(l->interface != NULL && xfer_sock->iface != NULL &&
!strcmp(l->interface, xfer_sock->iface))) {
#include <haproxy/proxy.h>
#include <haproxy/server.h>
#include <haproxy/sock.h>
+#include <haproxy/sock_inet.h>
#include <haproxy/task.h>
static int udp_bind_listeners(struct protocol *proto, char *errmsg, int errlen);
.get_dst = udp_get_dst,
.pause = udp_pause_listener,
.add = udp4_add_listener,
+ .addrcmp = sock_inet4_addrcmp,
.listeners = LIST_HEAD_INIT(proto_udp4.listeners),
.nb_listeners = 0,
};
.get_dst = udp_get_dst,
.pause = udp_pause_listener,
.add = udp6_add_listener,
+ .addrcmp = sock_inet6_addrcmp,
.listeners = LIST_HEAD_INIT(proto_udp6.listeners),
.nb_listeners = 0,
};
#include <haproxy/log.h>
#include <haproxy/protocol.h>
#include <haproxy/sock.h>
+#include <haproxy/sock_unix.h>
#include <haproxy/time.h>
#include <haproxy/tools.h>
#include <haproxy/version.h>
.get_dst = sock_get_dst,
.pause = uxst_pause_listener,
.add = uxst_add_listener,
+ .addrcmp = sock_unix_addrcmp,
.listeners = LIST_HEAD_INIT(proto_unix.listeners),
.nb_listeners = 0,
};
int ret = -1;
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
* will be the temporary name <sockname>.XXXXX.tmp,
* so we can't just compare the two names
*/
- if (xfer_sock->addr.ss_family == AF_UNIX &&
- 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))
+ if (!l->proto->addrcmp(&xfer_sock->addr, &l->addr))
break;
- }
xfer_sock = xfer_sock->next;
}
if (xfer_sock != NULL) {