Add new API to be able to compare two TCP host name strings or numeric IP
Addresses in order to determine if the resolved and translated names match.
Signed-off-by: John Ferlan <jferlan(a)redhat.com>
---
src/libvirt_private.syms | 1 +
src/util/virsocketaddr.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++
src/util/virsocketaddr.h | 2 ++
3 files changed, 65 insertions(+)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 848b44a..34cb871 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2058,6 +2058,7 @@ virSocketAddrGetRange;
virSocketAddrIsNetmask;
virSocketAddrIsNumericLocalhost;
virSocketAddrIsPrivate;
+virSocketAddrIsSameTCPHost;
virSocketAddrIsWildcard;
virSocketAddrMask;
virSocketAddrMaskByPrefix;
diff --git a/src/util/virsocketaddr.c b/src/util/virsocketaddr.c
index 993d460..c602604 100644
--- a/src/util/virsocketaddr.c
+++ b/src/util/virsocketaddr.c
@@ -23,6 +23,7 @@
#include <config.h>
+#include "viralloc.h"
#include "virsocketaddr.h"
#include "virerror.h"
#include "virstring.h"
@@ -980,3 +981,64 @@ virSocketAddrIsNumericLocalhost(const char *addr)
return false;
}
+
+
+/**
+ * virSocketAddrIsSameTCPHost:
+ * @host1: either a numeric network address IPv4 or IPv6 or a network hostname
+ * @host2: either a numeric network address IPv4 or IPv6 or a network hostname
+ *
+ * For each hostname, get the array of resolved addresses and in a loop make
+ * compare the translated host IP Address looking for duplicates.
+ *
+ * Returns 1 if the hosts match, 0 if there is no match, and -1 on error
+ */
+int
+virSocketAddrIsSameTCPHost(const char *host1,
+ const char *host2)
+{
+ int ret = -1;
+ struct addrinfo *reshost1 = NULL, *reshost2 = NULL;
+ struct addrinfo *curhost1, *curhost2;
+ char *host1rslv = NULL, *host2rslv = NULL;
+
+ if (virSocketAddrParseInternal(&reshost1, host1, AF_UNSPEC, IPPROTO_TCP,
+ false, true) < 0)
+ goto cleanup;
+
+ if (virSocketAddrParseInternal(&reshost2, host2, AF_UNSPEC, IPPROTO_TCP,
+ false, true) < 0)
+ goto cleanup;
+
+ for (curhost1 = reshost1; curhost1; curhost1 = curhost1->ai_next) {
+ if (!(host1rslv = virSocketAddrGetNumericHost(curhost1->ai_addr,
+ curhost1->ai_addrlen,
+ false, NULL)))
+ goto cleanup;
+ for (curhost2 = reshost2; curhost2; curhost2 = curhost2->ai_next) {
+ if (curhost1->ai_family != curhost2->ai_family)
+ continue;
+
+ if (!(host2rslv = virSocketAddrGetNumericHost(curhost2->ai_addr,
+ curhost2->ai_addrlen,
+ false, NULL)))
+ goto cleanup;
+
+ if (STREQ(host1rslv, host2rslv)) {
+ ret = 1;
+ goto cleanup;
+ }
+ }
+ }
+
+ ret = 0;
+
+ cleanup:
+ if (reshost1)
+ freeaddrinfo(reshost1);
+ if (reshost2)
+ freeaddrinfo(reshost2);
+ VIR_FREE(host1rslv);
+ VIR_FREE(host2rslv);
+ return ret;
+}
diff --git a/src/util/virsocketaddr.h b/src/util/virsocketaddr.h
index 3bbf119..2f9f358 100644
--- a/src/util/virsocketaddr.h
+++ b/src/util/virsocketaddr.h
@@ -137,4 +137,6 @@ bool virSocketAddrIsWildcard(const virSocketAddr *addr);
int virSocketAddrNumericFamily(const char *address);
bool virSocketAddrIsNumericLocalhost(const char *addr);
+
+int virSocketAddrIsSameTCPHost(const char *host1, const char *host2);
#endif /* __VIR_SOCKETADDR_H__ */
--
2.1.0