1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-10 01:18:15 +03:00

ctdb-protocol: Add generalised socket address comparison

Add new function ctdb_sock_addr_cmp(), which returns a 3-way result
useful for qsort(3).  Reimplent ctdb_sock_addr_same() using this.

In the process, make arguments const so that ctdb_sock_addr_cmp() can
be used with qsort().

BUG: https://bugzilla.samba.org/show_bug.cgi?id=12470

Signed-off-by: Martin Schwenke <martin@meltin.net>
Reviewed-by: Amitay Isaacs <amitay@gmail.com>
This commit is contained in:
Martin Schwenke 2016-05-23 10:35:10 +10:00 committed by Amitay Isaacs
parent 25aad0df06
commit 362f066d61
2 changed files with 55 additions and 23 deletions

View File

@ -658,7 +658,13 @@ const char *ctdb_event_to_string(enum ctdb_event event);
enum ctdb_event ctdb_event_from_string(const char *event_str);
const char *ctdb_sock_addr_to_string(TALLOC_CTX *mem_ctx, ctdb_sock_addr *addr);
bool ctdb_sock_addr_same_ip(ctdb_sock_addr *addr1, ctdb_sock_addr *addr2);
bool ctdb_sock_addr_same(ctdb_sock_addr *addr1, ctdb_sock_addr *addr2);
int ctdb_sock_addr_cmp_ip(const ctdb_sock_addr *addr1,
const ctdb_sock_addr *addr2);
int ctdb_sock_addr_cmp(const ctdb_sock_addr *addr1,
const ctdb_sock_addr *addr2);
bool ctdb_sock_addr_same_ip(const ctdb_sock_addr *addr1,
const ctdb_sock_addr *addr2);
bool ctdb_sock_addr_same(const ctdb_sock_addr *addr1,
const ctdb_sock_addr *addr2);
#endif /* __CTDB_PROTOCOL_API_H__ */

View File

@ -141,55 +141,81 @@ const char *ctdb_sock_addr_to_string(TALLOC_CTX *mem_ctx, ctdb_sock_addr *addr)
return cip;
}
bool ctdb_sock_addr_same_ip(ctdb_sock_addr *addr1, ctdb_sock_addr *addr2)
int ctdb_sock_addr_cmp_ip(const ctdb_sock_addr *addr1,
const ctdb_sock_addr *addr2)
{
if (addr1->sa.sa_family != addr2->sa.sa_family) {
return false;
int ret = 0;
/* This is somewhat arbitrary. However, when used for sorting
* it just needs to be consistent.
*/
if (addr1->sa.sa_family < addr2->sa.sa_family) {
return -1;
}
if (addr1->sa.sa_family > addr2->sa.sa_family) {
return 1;
}
switch (addr1->sa.sa_family) {
case AF_INET:
if (addr1->ip.sin_addr.s_addr != addr2->ip.sin_addr.s_addr) {
return false;
}
ret = memcmp(&addr1->ip.sin_addr.s_addr,
&addr2->ip.sin_addr.s_addr, 4);
break;
case AF_INET6:
if (memcmp(addr1->ip6.sin6_addr.s6_addr,
addr2->ip6.sin6_addr.s6_addr, 16) != 0) {
return false;
}
ret = memcmp(addr1->ip6.sin6_addr.s6_addr,
addr2->ip6.sin6_addr.s6_addr, 16);
break;
default:
return false;
ret = -1;
}
return true;
return ret;
}
bool ctdb_sock_addr_same(ctdb_sock_addr *addr1, ctdb_sock_addr *addr2)
int ctdb_sock_addr_cmp(const ctdb_sock_addr *addr1,
const ctdb_sock_addr *addr2)
{
if (! ctdb_sock_addr_same_ip(addr1, addr2)) {
return false;
int ret = 0;
ret = ctdb_sock_addr_cmp_ip(addr1, addr2);
if (ret != 0) {
return ret;
}
switch (addr1->sa.sa_family) {
case AF_INET:
if (addr1->ip.sin_port != addr2->ip.sin_port) {
return false;
if (addr1->ip.sin_port < addr2->ip.sin_port) {
ret = -1;
} else if (addr1->ip.sin_port > addr2->ip.sin_port) {
ret = 1;
}
break;
case AF_INET6:
if (addr1->ip6.sin6_port != addr2->ip6.sin6_port) {
return false;
if (addr1->ip6.sin6_port < addr2->ip6.sin6_port) {
ret = -1;
} else if (addr1->ip6.sin6_port > addr2->ip6.sin6_port) {
ret = 1;
}
break;
default:
return false;
ret = -1;
}
return true;
return ret;
}
bool ctdb_sock_addr_same_ip(const ctdb_sock_addr *addr1,
const ctdb_sock_addr *addr2)
{
return (ctdb_sock_addr_cmp_ip(addr1, addr2) == 0);
}
bool ctdb_sock_addr_same(const ctdb_sock_addr *addr1,
const ctdb_sock_addr *addr2)
{
return (ctdb_sock_addr_cmp(addr1, addr2) == 0);
}