|
|
6cf099 |
From 856cb96e313c164aa80915410ba758ad21cb6173 Mon Sep 17 00:00:00 2001
|
|
|
6cf099 |
From: Pavel Reichl <preichl@redhat.com>
|
|
|
6cf099 |
Date: Tue, 14 Jul 2015 09:56:59 -0400
|
|
|
6cf099 |
Subject: [PATCH 19/19] DYNDNS: support for dualstack
|
|
|
6cf099 |
|
|
|
6cf099 |
When dyndns_iface option was not used, address of connection to LDAP
|
|
|
6cf099 |
was used. This patch proposes following change:
|
|
|
6cf099 |
* Interface containing address of connection is found.
|
|
|
6cf099 |
* All A and AAAA addresses of this interface are collected.
|
|
|
6cf099 |
* Collected addresses are sent during DDNS update.
|
|
|
6cf099 |
* Function sss_iface_addr_add() is removed.
|
|
|
6cf099 |
|
|
|
6cf099 |
Resolves:
|
|
|
6cf099 |
https://fedorahosted.org/sssd/ticket/2558
|
|
|
6cf099 |
---
|
|
|
6cf099 |
src/providers/dp_dyndns.c | 135 +++++++++++++++++++++++------
|
|
|
6cf099 |
src/providers/dp_dyndns.h | 8 +-
|
|
|
6cf099 |
src/providers/ldap/sdap_dyndns.c | 20 ++---
|
|
|
6cf099 |
src/tests/cmocka/test_dyndns.c | 178 +++++++++++++++++++++++++++++++++++++++
|
|
|
6cf099 |
4 files changed, 302 insertions(+), 39 deletions(-)
|
|
|
6cf099 |
|
|
|
6cf099 |
diff --git a/src/providers/dp_dyndns.c b/src/providers/dp_dyndns.c
|
|
|
6cf099 |
index 03389acfba13e566540ca8b0570c0d009173575f..c254d78936f412626db0533f559350de57017618 100644
|
|
|
6cf099 |
--- a/src/providers/dp_dyndns.c
|
|
|
6cf099 |
+++ b/src/providers/dp_dyndns.c
|
|
|
6cf099 |
@@ -58,31 +58,6 @@ void sss_iface_addr_concatenate(struct sss_iface_addr **list,
|
|
|
6cf099 |
DLIST_CONCATENATE((*list), list2, struct sss_iface_addr*);
|
|
|
6cf099 |
}
|
|
|
6cf099 |
|
|
|
6cf099 |
-struct sss_iface_addr *
|
|
|
6cf099 |
-sss_iface_addr_add(TALLOC_CTX *mem_ctx, struct sss_iface_addr **list,
|
|
|
6cf099 |
- struct sockaddr_storage *ss)
|
|
|
6cf099 |
-{
|
|
|
6cf099 |
- struct sss_iface_addr *address;
|
|
|
6cf099 |
-
|
|
|
6cf099 |
- address = talloc(mem_ctx, struct sss_iface_addr);
|
|
|
6cf099 |
- if (address == NULL) {
|
|
|
6cf099 |
- return NULL;
|
|
|
6cf099 |
- }
|
|
|
6cf099 |
-
|
|
|
6cf099 |
- address->addr = talloc_memdup(address, ss,
|
|
|
6cf099 |
- sizeof(struct sockaddr_storage));
|
|
|
6cf099 |
- if(address->addr == NULL) {
|
|
|
6cf099 |
- talloc_zfree(address);
|
|
|
6cf099 |
- return NULL;
|
|
|
6cf099 |
- }
|
|
|
6cf099 |
-
|
|
|
6cf099 |
- /* steal old dlist to the new head */
|
|
|
6cf099 |
- talloc_steal(address, *list);
|
|
|
6cf099 |
- DLIST_ADD(*list, address);
|
|
|
6cf099 |
-
|
|
|
6cf099 |
- return address;
|
|
|
6cf099 |
-}
|
|
|
6cf099 |
-
|
|
|
6cf099 |
errno_t
|
|
|
6cf099 |
sss_iface_addr_list_as_str_list(TALLOC_CTX *mem_ctx,
|
|
|
6cf099 |
struct sss_iface_addr *ifaddr_list,
|
|
|
6cf099 |
@@ -1258,3 +1233,113 @@ errno_t be_nsupdate_init_timer(struct be_nsupdate_ctx *ctx,
|
|
|
6cf099 |
|
|
|
6cf099 |
return ERR_OK;
|
|
|
6cf099 |
}
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+static bool match_ip(const struct sockaddr *sa,
|
|
|
6cf099 |
+ const struct sockaddr *sb)
|
|
|
6cf099 |
+{
|
|
|
6cf099 |
+ size_t addrsize;
|
|
|
6cf099 |
+ bool res;
|
|
|
6cf099 |
+ const void *addr_a;
|
|
|
6cf099 |
+ const void *addr_b;
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ if (sa->sa_family == AF_INET) {
|
|
|
6cf099 |
+ addrsize = sizeof(struct in_addr);
|
|
|
6cf099 |
+ addr_a = (const void *) &((const struct sockaddr_in *) sa)->sin_addr;
|
|
|
6cf099 |
+ addr_b = (const void *) &((const struct sockaddr_in *) sb)->sin_addr;
|
|
|
6cf099 |
+ } else if (sa->sa_family == AF_INET6) {
|
|
|
6cf099 |
+ addrsize = sizeof(struct in6_addr);
|
|
|
6cf099 |
+ addr_a = (const void *) &((const struct sockaddr_in6 *) sa)->sin6_addr;
|
|
|
6cf099 |
+ addr_b = (const void *) &((const struct sockaddr_in6 *) sb)->sin6_addr;
|
|
|
6cf099 |
+ } else {
|
|
|
6cf099 |
+ res = false;
|
|
|
6cf099 |
+ goto done;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ if (sa->sa_family != sb->sa_family) {
|
|
|
6cf099 |
+ res = false;
|
|
|
6cf099 |
+ goto done;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ res = memcmp(addr_a, addr_b, addrsize) == 0;
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+done:
|
|
|
6cf099 |
+ return res;
|
|
|
6cf099 |
+}
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+static errno_t find_iface_by_addr(TALLOC_CTX *mem_ctx,
|
|
|
6cf099 |
+ const struct sockaddr *ss,
|
|
|
6cf099 |
+ const char **_iface_name)
|
|
|
6cf099 |
+{
|
|
|
6cf099 |
+ struct ifaddrs *ifaces = NULL;
|
|
|
6cf099 |
+ struct ifaddrs *ifa;
|
|
|
6cf099 |
+ errno_t ret;
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ ret = getifaddrs(&ifaces);
|
|
|
6cf099 |
+ if (ret == -1) {
|
|
|
6cf099 |
+ ret = errno;
|
|
|
6cf099 |
+ DEBUG(SSSDBG_OP_FAILURE,
|
|
|
6cf099 |
+ "Could not read interfaces [%d][%s]\n", ret, sss_strerror(ret));
|
|
|
6cf099 |
+ goto done;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ for (ifa = ifaces; ifa != NULL; ifa = ifa->ifa_next) {
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ /* Some interfaces don't have an ifa_addr */
|
|
|
6cf099 |
+ if (!ifa->ifa_addr) continue;
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ if (match_ip(ss, ifa->ifa_addr)) {
|
|
|
6cf099 |
+ const char *iface_name;
|
|
|
6cf099 |
+ iface_name = talloc_strdup(mem_ctx, ifa->ifa_name);
|
|
|
6cf099 |
+ if (iface_name == NULL) {
|
|
|
6cf099 |
+ ret = ENOMEM;
|
|
|
6cf099 |
+ } else {
|
|
|
6cf099 |
+ *_iface_name = iface_name;
|
|
|
6cf099 |
+ ret = EOK;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+ goto done;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+ ret = ENOENT;
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+done:
|
|
|
6cf099 |
+ freeifaddrs(ifaces);
|
|
|
6cf099 |
+ return ret;
|
|
|
6cf099 |
+}
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+errno_t sss_get_dualstack_addresses(TALLOC_CTX *mem_ctx,
|
|
|
6cf099 |
+ struct sockaddr *ss,
|
|
|
6cf099 |
+ struct sss_iface_addr **_iface_addrs)
|
|
|
6cf099 |
+{
|
|
|
6cf099 |
+ struct sss_iface_addr *iface_addrs;
|
|
|
6cf099 |
+ const char *iface_name = NULL;
|
|
|
6cf099 |
+ TALLOC_CTX *tmp_ctx;
|
|
|
6cf099 |
+ errno_t ret;
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ tmp_ctx = talloc_new(NULL);
|
|
|
6cf099 |
+ if (tmp_ctx == NULL) {
|
|
|
6cf099 |
+ ret = ENOMEM;
|
|
|
6cf099 |
+ goto done;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ ret = find_iface_by_addr(tmp_ctx, ss, &iface_name);
|
|
|
6cf099 |
+ if (ret != EOK) {
|
|
|
6cf099 |
+ DEBUG(SSSDBG_MINOR_FAILURE, "find_iface_by_addr failed: %d:[%s]\n",
|
|
|
6cf099 |
+ ret, sss_strerror(ret));
|
|
|
6cf099 |
+ goto done;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ ret = sss_iface_addr_list_get(tmp_ctx, iface_name, &iface_addrs);
|
|
|
6cf099 |
+ if (ret != EOK) {
|
|
|
6cf099 |
+ DEBUG(SSSDBG_MINOR_FAILURE,
|
|
|
6cf099 |
+ "sss_iface_addr_list_get failed: %d:[%s]\n",
|
|
|
6cf099 |
+ ret, sss_strerror(ret));
|
|
|
6cf099 |
+ goto done;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ ret = EOK;
|
|
|
6cf099 |
+ *_iface_addrs = talloc_steal(mem_ctx, iface_addrs);
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+done:
|
|
|
6cf099 |
+ talloc_free(tmp_ctx);
|
|
|
6cf099 |
+ return ret;
|
|
|
6cf099 |
+}
|
|
|
6cf099 |
diff --git a/src/providers/dp_dyndns.h b/src/providers/dp_dyndns.h
|
|
|
6cf099 |
index deba112538ad22cd7f59be07934778ee9d4361e7..a8a20ec6f8a1a63cd8c85aaec3f54f9fddb42049 100644
|
|
|
6cf099 |
--- a/src/providers/dp_dyndns.h
|
|
|
6cf099 |
+++ b/src/providers/dp_dyndns.h
|
|
|
6cf099 |
@@ -81,10 +81,6 @@ errno_t
|
|
|
6cf099 |
sss_iface_addr_list_get(TALLOC_CTX *mem_ctx, const char *ifname,
|
|
|
6cf099 |
struct sss_iface_addr **_addrlist);
|
|
|
6cf099 |
|
|
|
6cf099 |
-struct sss_iface_addr *
|
|
|
6cf099 |
-sss_iface_addr_add(TALLOC_CTX *mem_ctx, struct sss_iface_addr **list,
|
|
|
6cf099 |
- struct sockaddr_storage *ss);
|
|
|
6cf099 |
-
|
|
|
6cf099 |
errno_t
|
|
|
6cf099 |
sss_iface_addr_list_as_str_list(TALLOC_CTX *mem_ctx,
|
|
|
6cf099 |
struct sss_iface_addr *ifaddr_list,
|
|
|
6cf099 |
@@ -132,4 +128,8 @@ void
|
|
|
6cf099 |
sss_iface_addr_concatenate(struct sss_iface_addr **list,
|
|
|
6cf099 |
struct sss_iface_addr *list2);
|
|
|
6cf099 |
|
|
|
6cf099 |
+errno_t
|
|
|
6cf099 |
+sss_get_dualstack_addresses(TALLOC_CTX *mem_ctx,
|
|
|
6cf099 |
+ struct sockaddr *ss,
|
|
|
6cf099 |
+ struct sss_iface_addr **_iface_addrs);
|
|
|
6cf099 |
#endif /* DP_DYNDNS_H_ */
|
|
|
6cf099 |
diff --git a/src/providers/ldap/sdap_dyndns.c b/src/providers/ldap/sdap_dyndns.c
|
|
|
6cf099 |
index f5929cff3db6f724efcedeb963e3a12d04f6e1d3..a463a2fce08f42b325010cd37c501ef23aee173f 100644
|
|
|
6cf099 |
--- a/src/providers/ldap/sdap_dyndns.c
|
|
|
6cf099 |
+++ b/src/providers/ldap/sdap_dyndns.c
|
|
|
6cf099 |
@@ -644,7 +644,6 @@ sdap_dyndns_add_ldap_conn(struct sdap_dyndns_get_addrs_state *state,
|
|
|
6cf099 |
{
|
|
|
6cf099 |
int ret;
|
|
|
6cf099 |
int fd;
|
|
|
6cf099 |
- struct sss_iface_addr *address;
|
|
|
6cf099 |
struct sockaddr_storage ss;
|
|
|
6cf099 |
socklen_t ss_len = sizeof(ss);
|
|
|
6cf099 |
|
|
|
6cf099 |
@@ -666,20 +665,21 @@ sdap_dyndns_add_ldap_conn(struct sdap_dyndns_get_addrs_state *state,
|
|
|
6cf099 |
return ret;
|
|
|
6cf099 |
}
|
|
|
6cf099 |
|
|
|
6cf099 |
- switch(ss.ss_family) {
|
|
|
6cf099 |
- case AF_INET:
|
|
|
6cf099 |
- case AF_INET6:
|
|
|
6cf099 |
- address = sss_iface_addr_add(state, &state->addresses, &ss);
|
|
|
6cf099 |
- if (address == NULL) {
|
|
|
6cf099 |
- return ENOMEM;
|
|
|
6cf099 |
- }
|
|
|
6cf099 |
- break;
|
|
|
6cf099 |
- default:
|
|
|
6cf099 |
+ if (ss.ss_family != AF_INET && ss.ss_family != AF_INET6) {
|
|
|
6cf099 |
DEBUG(SSSDBG_CRIT_FAILURE,
|
|
|
6cf099 |
"Connection to LDAP is neither IPv4 nor IPv6\n");
|
|
|
6cf099 |
return EIO;
|
|
|
6cf099 |
}
|
|
|
6cf099 |
|
|
|
6cf099 |
+ ret = sss_get_dualstack_addresses(state, (struct sockaddr *) &ss,
|
|
|
6cf099 |
+ &state->addresses);
|
|
|
6cf099 |
+ if (ret != EOK) {
|
|
|
6cf099 |
+ DEBUG(SSSDBG_MINOR_FAILURE,
|
|
|
6cf099 |
+ "sss_get_dualstack_addresses failed: %d:[%s]\n",
|
|
|
6cf099 |
+ ret, sss_strerror(ret));
|
|
|
6cf099 |
+ return ret;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
return EOK;
|
|
|
6cf099 |
}
|
|
|
6cf099 |
|
|
|
6cf099 |
diff --git a/src/tests/cmocka/test_dyndns.c b/src/tests/cmocka/test_dyndns.c
|
|
|
6cf099 |
index e9d42cea37472b38ae2eb900368f2ce3f409fefc..8118e9438e89465674155c11f4523d2313f6a59c 100644
|
|
|
6cf099 |
--- a/src/tests/cmocka/test_dyndns.c
|
|
|
6cf099 |
+++ b/src/tests/cmocka/test_dyndns.c
|
|
|
6cf099 |
@@ -289,6 +289,173 @@ void dyndns_test_get_ifaddr_enoent(void **state)
|
|
|
6cf099 |
assert_true(check_leaks_pop(dyndns_test_ctx) == true);
|
|
|
6cf099 |
}
|
|
|
6cf099 |
|
|
|
6cf099 |
+void dyndns_test_dualstack(void **state)
|
|
|
6cf099 |
+{
|
|
|
6cf099 |
+ errno_t ret;
|
|
|
6cf099 |
+ struct sss_iface_addr *addrlist;
|
|
|
6cf099 |
+ struct sss_iface_addr *sss_if_addrs;
|
|
|
6cf099 |
+ char straddr[128];
|
|
|
6cf099 |
+ int i;
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ check_leaks_push(dyndns_test_ctx);
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ /* getifaddrs is called twice in sss_get_dualstack_addresses() */
|
|
|
6cf099 |
+ for (i = 0; i < 2; i++) {
|
|
|
6cf099 |
+ will_return_getifaddrs("eth0", "192.168.0.2", AF_INET);
|
|
|
6cf099 |
+ will_return_getifaddrs("eth1", "192.168.0.1", AF_INET);
|
|
|
6cf099 |
+ will_return_getifaddrs("eth0", "2001:cdba::555", AF_INET6);
|
|
|
6cf099 |
+ will_return_getifaddrs("eth1", "2001:cdba::444", AF_INET6);
|
|
|
6cf099 |
+ will_return_getifaddrs(NULL, NULL, 0); /* sentinel */
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ struct sockaddr_in sin;
|
|
|
6cf099 |
+ memset (&sin, 0, sizeof (sin));
|
|
|
6cf099 |
+ sin.sin_family = AF_INET;
|
|
|
6cf099 |
+ sin.sin_addr.s_addr = inet_addr ("192.168.0.2");
|
|
|
6cf099 |
+ ret = sss_get_dualstack_addresses(dyndns_test_ctx,
|
|
|
6cf099 |
+ (struct sockaddr *) &sin,
|
|
|
6cf099 |
+ &addrlist);
|
|
|
6cf099 |
+ assert_int_equal(ret, EOK);
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ sss_if_addrs = addrlist;
|
|
|
6cf099 |
+ assert_non_null(sss_if_addrs);
|
|
|
6cf099 |
+ assert_non_null(sss_if_addrs->addr);
|
|
|
6cf099 |
+ assert_non_null(sss_if_addrs->next);
|
|
|
6cf099 |
+ assert_null(sss_if_addrs->prev);
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ assert_non_null(inet_ntop(AF_INET6,
|
|
|
6cf099 |
+ &((struct sockaddr_in6 *) sss_if_addrs->addr)->sin6_addr,
|
|
|
6cf099 |
+ straddr, INET6_ADDRSTRLEN));
|
|
|
6cf099 |
+ /* ip addresses are returned in different order */
|
|
|
6cf099 |
+ assert_string_equal(straddr, "2001:cdba::555");
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ sss_if_addrs = addrlist->next;
|
|
|
6cf099 |
+ assert_non_null(sss_if_addrs);
|
|
|
6cf099 |
+ assert_non_null(sss_if_addrs->addr);
|
|
|
6cf099 |
+ assert_null(sss_if_addrs->next);
|
|
|
6cf099 |
+ assert_non_null(sss_if_addrs->prev);
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ assert_non_null(inet_ntop(AF_INET,
|
|
|
6cf099 |
+ &((struct sockaddr_in *) sss_if_addrs->addr)->sin_addr,
|
|
|
6cf099 |
+ straddr, INET_ADDRSTRLEN));
|
|
|
6cf099 |
+ /* ip addresses are returned in different order */
|
|
|
6cf099 |
+ assert_string_equal(straddr, "192.168.0.2");
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ talloc_free(addrlist);
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ assert_true(check_leaks_pop(dyndns_test_ctx) == true);
|
|
|
6cf099 |
+}
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+void dyndns_test_dualstack_multiple_addresses(void **state)
|
|
|
6cf099 |
+{
|
|
|
6cf099 |
+ errno_t ret;
|
|
|
6cf099 |
+ struct sss_iface_addr *addrlist;
|
|
|
6cf099 |
+ struct sss_iface_addr *sss_if_addrs;
|
|
|
6cf099 |
+ char straddr[128];
|
|
|
6cf099 |
+ int i;
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ check_leaks_push(dyndns_test_ctx);
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ /* getifaddrs is called twice in sss_get_dualstack_addresses() */
|
|
|
6cf099 |
+ for (i = 0; i < 2; i++) {
|
|
|
6cf099 |
+ will_return_getifaddrs("eth0", "192.168.0.2", AF_INET);
|
|
|
6cf099 |
+ will_return_getifaddrs("eth0", "192.168.0.1", AF_INET);
|
|
|
6cf099 |
+ /* loopback - invalid for dns (should be skipped) */
|
|
|
6cf099 |
+ will_return_getifaddrs("eth0", "::1", AF_INET6);
|
|
|
6cf099 |
+ /* linklocal - invalid for dns (should be skipped) */
|
|
|
6cf099 |
+ will_return_getifaddrs("eth0", "fe80::5054:ff:fe4a:65ae", AF_INET6);
|
|
|
6cf099 |
+ will_return_getifaddrs("eth0", "2001:cdba::555", AF_INET6);
|
|
|
6cf099 |
+ will_return_getifaddrs("eth0", "2001:cdba::444", AF_INET6);
|
|
|
6cf099 |
+ will_return_getifaddrs(NULL, NULL, 0); /* sentinel */
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ struct sockaddr_in sin;
|
|
|
6cf099 |
+ memset (&sin, 0, sizeof (sin));
|
|
|
6cf099 |
+ sin.sin_family = AF_INET;
|
|
|
6cf099 |
+ sin.sin_addr.s_addr = inet_addr ("192.168.0.2");
|
|
|
6cf099 |
+ ret = sss_get_dualstack_addresses(dyndns_test_ctx,
|
|
|
6cf099 |
+ (struct sockaddr *) &sin,
|
|
|
6cf099 |
+ &addrlist);
|
|
|
6cf099 |
+ assert_int_equal(ret, EOK);
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ sss_if_addrs = addrlist;
|
|
|
6cf099 |
+ assert_non_null(sss_if_addrs);
|
|
|
6cf099 |
+ assert_non_null(sss_if_addrs->addr);
|
|
|
6cf099 |
+ assert_non_null(sss_if_addrs->next);
|
|
|
6cf099 |
+ assert_null(sss_if_addrs->prev);
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ assert_non_null(inet_ntop(AF_INET6,
|
|
|
6cf099 |
+ &((struct sockaddr_in6 *) sss_if_addrs->addr)->sin6_addr,
|
|
|
6cf099 |
+ straddr, INET6_ADDRSTRLEN));
|
|
|
6cf099 |
+ /* ip addresses are returned in different order */
|
|
|
6cf099 |
+ assert_string_equal(straddr, "2001:cdba::444");
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ sss_if_addrs = sss_if_addrs->next;
|
|
|
6cf099 |
+ assert_non_null(sss_if_addrs);
|
|
|
6cf099 |
+ assert_non_null(sss_if_addrs->addr);
|
|
|
6cf099 |
+ assert_non_null(sss_if_addrs->prev);
|
|
|
6cf099 |
+ assert_non_null(sss_if_addrs->next);
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ assert_non_null(inet_ntop(AF_INET6,
|
|
|
6cf099 |
+ &((struct sockaddr_in6 *) sss_if_addrs->addr)->sin6_addr,
|
|
|
6cf099 |
+ straddr, INET6_ADDRSTRLEN));
|
|
|
6cf099 |
+ /* ip addresses are returned in different order */
|
|
|
6cf099 |
+ assert_string_equal(straddr, "2001:cdba::555");
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ sss_if_addrs = sss_if_addrs->next;
|
|
|
6cf099 |
+ assert_non_null(sss_if_addrs);
|
|
|
6cf099 |
+ assert_non_null(sss_if_addrs->addr);
|
|
|
6cf099 |
+ assert_non_null(sss_if_addrs->next);
|
|
|
6cf099 |
+ assert_non_null(sss_if_addrs->prev);
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ assert_non_null(inet_ntop(AF_INET,
|
|
|
6cf099 |
+ &((struct sockaddr_in *) sss_if_addrs->addr)->sin_addr,
|
|
|
6cf099 |
+ straddr, INET_ADDRSTRLEN));
|
|
|
6cf099 |
+ /* ip addresses are returned in different order */
|
|
|
6cf099 |
+ assert_string_equal(straddr, "192.168.0.1");
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ sss_if_addrs = sss_if_addrs->next;
|
|
|
6cf099 |
+ assert_non_null(sss_if_addrs);
|
|
|
6cf099 |
+ assert_non_null(sss_if_addrs->addr);
|
|
|
6cf099 |
+ assert_null(sss_if_addrs->next);
|
|
|
6cf099 |
+ assert_non_null(sss_if_addrs->prev);
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ assert_non_null(inet_ntop(AF_INET,
|
|
|
6cf099 |
+ &((struct sockaddr_in *) sss_if_addrs->addr)->sin_addr,
|
|
|
6cf099 |
+ straddr, INET_ADDRSTRLEN));
|
|
|
6cf099 |
+ /* ip addresses are returned in different order */
|
|
|
6cf099 |
+ assert_string_equal(straddr, "192.168.0.2");
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ talloc_free(addrlist);
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ assert_true(check_leaks_pop(dyndns_test_ctx) == true);
|
|
|
6cf099 |
+}
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+void dyndns_test_dualstack_no_iface(void **state)
|
|
|
6cf099 |
+{
|
|
|
6cf099 |
+ errno_t ret;
|
|
|
6cf099 |
+ struct sss_iface_addr *addrlist;
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ check_leaks_push(dyndns_test_ctx);
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ will_return_getifaddrs("eth0", "192.168.0.2", AF_INET);
|
|
|
6cf099 |
+ will_return_getifaddrs("eth1", "192.168.0.1", AF_INET);
|
|
|
6cf099 |
+ will_return_getifaddrs("eth0", "2001:cdba::555", AF_INET6);
|
|
|
6cf099 |
+ will_return_getifaddrs("eth1", "2001:cdba::444", AF_INET6);
|
|
|
6cf099 |
+ will_return_getifaddrs(NULL, NULL, 0); /* sentinel */
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ struct sockaddr_in sin;
|
|
|
6cf099 |
+ memset (&sin, 0, sizeof (sin));
|
|
|
6cf099 |
+ sin.sin_family = AF_INET;
|
|
|
6cf099 |
+ sin.sin_addr.s_addr = inet_addr ("192.168.0.3");
|
|
|
6cf099 |
+ ret = sss_get_dualstack_addresses(dyndns_test_ctx,
|
|
|
6cf099 |
+ (struct sockaddr *) &sin,
|
|
|
6cf099 |
+ &addrlist);
|
|
|
6cf099 |
+ assert_int_equal(ret, ENOENT);
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ assert_true(check_leaks_pop(dyndns_test_ctx) == true);
|
|
|
6cf099 |
+}
|
|
|
6cf099 |
+
|
|
|
6cf099 |
void dyndns_test_ok(void **state)
|
|
|
6cf099 |
{
|
|
|
6cf099 |
struct tevent_req *req;
|
|
|
6cf099 |
@@ -519,6 +686,17 @@ int main(int argc, const char *argv[])
|
|
|
6cf099 |
cmocka_unit_test_setup_teardown(dyndns_test_interval,
|
|
|
6cf099 |
dyndns_test_setup,
|
|
|
6cf099 |
dyndns_test_teardown),
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ /* Dynamic DNS dualstack unit tests*/
|
|
|
6cf099 |
+ cmocka_unit_test_setup_teardown(dyndns_test_dualstack,
|
|
|
6cf099 |
+ dyndns_test_simple_setup,
|
|
|
6cf099 |
+ dyndns_test_teardown),
|
|
|
6cf099 |
+ cmocka_unit_test_setup_teardown(dyndns_test_dualstack_multiple_addresses,
|
|
|
6cf099 |
+ dyndns_test_simple_setup,
|
|
|
6cf099 |
+ dyndns_test_teardown),
|
|
|
6cf099 |
+ cmocka_unit_test_setup_teardown(dyndns_test_dualstack_no_iface,
|
|
|
6cf099 |
+ dyndns_test_simple_setup,
|
|
|
6cf099 |
+ dyndns_test_teardown),
|
|
|
6cf099 |
};
|
|
|
6cf099 |
|
|
|
6cf099 |
/* Set debug level to invalid value so we can deside if -d 0 was used. */
|
|
|
6cf099 |
--
|
|
|
6cf099 |
2.4.3
|
|
|
6cf099 |
|