On 04/24/2015 04:25 AM, Peter Krempa wrote: > On Thu, Apr 23, 2015 at 16:12:16 -0400, John Ferlan wrote: >> 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@xxxxxxxxxx> >> --- >> 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)) { > > I'm still failing to see why the host address check portion of > virSocketAddrEqual() isn't good for this job and you have to format the > address as string. > Because I was more focused on the implementation that I had in my mind that did the getaddrinfo/getnameinfo loops. Many times the mind is a very difficult thing to convince to do something a different way - about to send an adjustment, >> + ret = 1; >> + goto cleanup; >> + } >> + } > > Next iteration leaks host2rslv. > >> + } > > Next iteration leaks host1rslv. > Oh yeah ... right, but they won't matter with the adjustment. John >> + >> + ret = 0; >> + >> + cleanup: >> + if (reshost1) >> + freeaddrinfo(reshost1); >> + if (reshost2) >> + freeaddrinfo(reshost2); >> + VIR_FREE(host1rslv); >> + VIR_FREE(host2rslv); >> + return ret; >> +} > > Peter > -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list