From 82ae109eba3901127fcd5267872b0afd64af4a7c Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Sat, 12 Jul 2014 12:56:46 +0100 Subject: [PATCH 1/1] addrfam: New arrangements for protocol address types Abolish union gen_addr and struct af_addr. It is not legitimate to up-cast to a union (since the alignment might be wrong), and the profusion of additonal address types is confusing. The new arrangements are: * Use adns_sockaddr wherever we can. That includes situations where the port (or v6 scope, etc.) is not relevant. * Where that's not possible, use a struct sockaddr if we can. * Where we need to deal with an IP address of unspecified family (we use the phrase `protocol address') we must use a void*. Other changes we make here: * Reorganise the set of functions provided by addrfam.c. Previously there was a comprehensive set of manipulators. Now, we have precisely the set of functions we need. The new functions are called adns__addr_* when they deal with adns_sockaddrs, and adns_sockaddr_* when dealing with struct sockaddrs. The new functions normally no longer need to take an explicit af parameter, since they can use the af field in the sockaddr. * adns__sockaddrs_equal (previously, adns__sockaddr_equal_p) now uses the generic protocol address comparison function; consequently remove the IN6_ADDR_EQUALP macro since it now has only one use site. * Remove the Lispy "-p" suffix from predicate function names. And of course the very formulaic changes to code which accesses addresses of various kinds. Signed-off-by: Ian Jackson --- src/addrfam.c | 129 +++++++++++++++++++++++++------------------------ src/check.c | 4 +- src/event.c | 4 +- src/internal.h | 82 +++++++++++++------------------ src/setup.c | 35 +++++++------- src/types.c | 30 ++++++------ 6 files changed, 136 insertions(+), 148 deletions(-) diff --git a/src/addrfam.c b/src/addrfam.c index b03b6ab..0f6bc18 100644 --- a/src/addrfam.c +++ b/src/addrfam.c @@ -62,39 +62,43 @@ static void unknown_af(int af) { abort(); } -#define IN6_ADDR_EQUALP(a, b) \ - (!memcmp((a).s6_addr, (b).s6_addr, sizeof((a).s6_addr))) - -int adns__genaddr_equal_p(int af, const union gen_addr *a, - int bf, const void *b) { - const union gen_addr *bb= b; - if (af != bf) return 0; - switch (af) { +int adns__addrs_equal_raw(const struct sockaddr *a, + int bf, const void *b) { + if (a->sa_family != bf) return 0; + switch (a->sa_family) { AF_CASES(af); - af_inet: return a->v4.s_addr == bb->v4.s_addr; - af_inet6: return IN6_ADDR_EQUALP(a->v6, bb->v6); - default: unknown_af(af); return -1; + af_inet: + return ((const struct sockaddr_in*)a)->sin_addr.s_addr == + ((const struct in_addr*)b)->s_addr; + af_inet6: + return !memcmp(&((const struct sockaddr_in6*)a)->sin6_addr, + b, sizeof(struct in6_addr)); + default: unknown_af(a->sa_family); return -1; } } -int adns__sockaddr_equal_p(const struct sockaddr *sa, - const struct sockaddr *sb) { - if (sa->sa_family != sb->sa_family) return 0; +int adns__addrs_equal(const adns_sockaddr *a, const adns_sockaddr *b) { + return adns__addrs_equal_raw(&a->sa, b->sa.sa_family, + adns__sockaddr_addr(&b->sa)); +} + +int adns__sockaddrs_equal(const struct sockaddr *sa, + const struct sockaddr *sb) { + if (!adns__addrs_equal_raw(sa, sb->sa_family, adns__sockaddr_addr(sb))) + return 0; switch (sa->sa_family) { AF_CASES(af); af_inet: { const struct sockaddr_in *sina= CSIN(sa), *sinb= CSIN(sb); - return (sina->sin_addr.s_addr == sinb->sin_addr.s_addr && - sina->sin_port == sinb->sin_port); + return sina->sin_port == sinb->sin_port; } af_inet6: { /* Don't check the flowlabel. That's apparently useful for routing * performance, but doesn't affect the address in any important * respect. */ const struct sockaddr_in6 *sin6a= CSIN6(sa), *sin6b= CSIN6(sb); - return (IN6_ADDR_EQUALP(sin6a->sin6_addr, sin6b->sin6_addr) && - sin6a->sin6_port == sin6b->sin6_port && - sin6a->sin6_scope_id == sin6b->sin6_scope_id); + return sin6a->sin6_port == sin6b->sin6_port && + sin6a->sin6_scope_id == sin6b->sin6_scope_id; } default: unknown_af(sa->sa_family); @@ -111,16 +115,17 @@ int adns__addr_width(int af) { } } -void adns__prefix_mask(int af, int len, union gen_addr *mask_r) { +void adns__prefix_mask(adns_sockaddr *sa, int len) { + int af= sa->sa.sa_family; switch (af) { AF_CASES(af); af_inet: assert(len <= 32); - mask_r->v4.s_addr= htonl(!len ? 0 : 0xffffffff << (32-len)); + sa->inet.sin_addr.s_addr= htonl(!len ? 0 : 0xffffffff << (32-len)); break; af_inet6: { int i= len/8, j= len%8; - unsigned char *m= mask_r->v6.s6_addr; + unsigned char *m= sa->inet6.sin6_addr.s6_addr; assert(len <= 128); memset(m, 0xff, i); if (j) m[i++]= (0xff << (8-j)) & 0xff; @@ -132,11 +137,12 @@ void adns__prefix_mask(int af, int len, union gen_addr *mask_r) { } } -int adns__guess_prefix_length(int af, const union gen_addr *addr) { +int adns__guess_prefix_length(const adns_sockaddr *sa) { + int af= sa->sa.sa_family; switch (af) { AF_CASES(af); af_inet: { - unsigned a= (ntohl(addr->v4.s_addr) >> 24) & 0xff; + unsigned a= (ntohl(sa->inet.sin_addr.s_addr) >> 24) & 0xff; if (a < 128) return 8; else if (a < 192) return 16; else if (a < 224) return 24; @@ -150,69 +156,64 @@ int adns__guess_prefix_length(int af, const union gen_addr *addr) { } } -int adns__addr_match_p(int addraf, const union gen_addr *addr, - int netaf, const union gen_addr *base, - const union gen_addr *mask) +int adns__addr_matches(int af, const void *addr, + const adns_sockaddr *base, const adns_sockaddr *mask) { - if (addraf != netaf) return 0; - switch (addraf) { + assert(base->sa.sa_family == mask->sa.sa_family); + if (af != base->sa.sa_family) return 0; + switch (af) { AF_CASES(af); - af_inet: - return (addr->v4.s_addr & mask->v4.s_addr) == base->v4.s_addr; + af_inet: { + const struct in_addr *v4 = addr; + return (v4->s_addr & mask->inet.sin_addr.s_addr) + == base->inet.sin_addr.s_addr; + } af_inet6: { int i; - const char *a= addr->v6.s6_addr; - const char *b= base->v6.s6_addr; - const char *m= mask->v6.s6_addr; + const char *a= addr; + const char *b= base->inet6.sin6_addr.s6_addr; + const char *m= mask->inet6.sin6_addr.s6_addr; for (i = 0; i < 16; i++) if ((a[i] & m[i]) != b[i]) return 0; return 1; } break; default: - unknown_af(addraf); + unknown_af(af); return -1; } } -void adns__sockaddr_extract(const struct sockaddr *sa, - union gen_addr *a_r, int *port_r) { +const void *adns__sockaddr_addr(const struct sockaddr *sa) { switch (sa->sa_family) { AF_CASES(af); af_inet: { const struct sockaddr_in *sin = CSIN(sa); - if (port_r) *port_r= ntohs(sin->sin_port); - if (a_r) a_r->v4= sin->sin_addr; - break; + return &sin->sin_addr; } af_inet6: { const struct sockaddr_in6 *sin6 = CSIN6(sa); - if (port_r) *port_r= ntohs(sin6->sin6_port); - if (a_r) a_r->v6= sin6->sin6_addr; - break; + return &sin6->sin6_addr; } default: unknown_af(sa->sa_family); } } -void adns__sockaddr_inject(const union gen_addr *a, int port, - struct sockaddr *sa) { - switch (sa->sa_family) { +void adns__addr_inject(const void *a, adns_sockaddr *sa) { + switch (sa->sa.sa_family) { AF_CASES(af); af_inet: { - struct sockaddr_in *sin = SIN(sa); - if (port != -1) sin->sin_port= htons(port); - if (a) sin->sin_addr= a->v4; + struct sockaddr_in *sin = &sa->inet; + memcpy(&sin->sin_addr, a, sizeof(sin->sin_addr)); break; } af_inet6: { - struct sockaddr_in6 *sin6 = SIN6(sa); - if (port != -1) sin6->sin6_port= htons(port); - if (a) sin6->sin6_addr= a->v6; + struct sockaddr_in6 *sin6 = &sa->inet6; + memcpy(&sin6->sin6_addr, a, sizeof(sin6->sin6_addr)); break; } default: - unknown_af(sa->sa_family); + unknown_af(sa->sa.sa_family); } } @@ -536,9 +537,10 @@ static int inet_rev_parsecomp(const char *p, size_t n) { return i; } -static void inet_rev_mkaddr(union gen_addr *addr, const byte *ipv) { - addr->v4.s_addr= htonl((ipv[3]<<24) | (ipv[2]<<16) | - (ipv[1]<<8) | (ipv[0])); +static void inet_rev_mkaddr(adns_sockaddr *addr, const byte *ipv) { + struct in_addr *v4 = &addr->inet.sin_addr; + v4->s_addr= htonl((ipv[3]<<24) | (ipv[2]<<16) | + (ipv[1]<<8) | (ipv[0])); } static int inet6_rev_parsecomp(const char *p, size_t n) { @@ -549,8 +551,9 @@ static int inet6_rev_parsecomp(const char *p, size_t n) { else return -1; } -static void inet6_rev_mkaddr(union gen_addr *addr, const byte *ipv) { - unsigned char *a= addr->v6.s6_addr; +static void inet6_rev_mkaddr(adns_sockaddr *addr, const byte *ipv) { + struct in6_addr *v6 = &addr->inet6.sin6_addr; + unsigned char *a= v6->s6_addr; int i; for (i=0; i<16; i++) @@ -567,8 +570,8 @@ static const struct revparse_domain { * if it was unintelligible. */ - void (*rev_mkaddr)(union gen_addr *addr, const byte *ipv); - /* write out the parsed address from a vector of parsed components */ + void (*rev_mkaddr)(adns_sockaddr *addr, const byte *ipv); + /* write out the parsed protocol address from a vector of parsed components */ const char *const tail[3]; /* tail label names */ } revparse_domains[NREVDOMAINS] = { @@ -613,7 +616,7 @@ int adns__revparse_label(struct revparse_state *rps, int labnum, } int adns__revparse_done(struct revparse_state *rps, int nlabels, - adns_rrtype *rrtype_r, struct af_addr *addr_r) { + adns_rrtype *rrtype_r, adns_sockaddr *addr_r) { unsigned f= REVDOMAIN_MAP(rps, nlabels); const struct revparse_domain *rpd; unsigned d; @@ -630,7 +633,7 @@ int adns__revparse_done(struct revparse_state *rps, int nlabels, rpd= &revparse_domains[found]; *rrtype_r= rpd->rrtype; - addr_r->af= rpd->af; - rpd->rev_mkaddr(&addr_r->addr, rps->ipv[found]); + addr_r->sa.sa_family= rpd->af; + rpd->rev_mkaddr(addr_r, rps->ipv[found]); return 0; } diff --git a/src/check.c b/src/check.c index 21dca70..c26dbdc 100644 --- a/src/check.c +++ b/src/check.c @@ -82,7 +82,9 @@ static void checkc_global(adns_state ads) { for (i=0; insortlist; i++) { sl= &ads->sortlist[i]; - assert(adns__addr_match_p(sl->af,&sl->base, sl->af,&sl->base,&sl->mask)); + assert(adns__addr_matches(sl->base.sa.sa_family, + adns__sockaddr_addr(&sl->base.sa), + &sl->base,&sl->mask)); } assert(ads->tcpserver >= 0 && ads->tcpserver < ads->nservers); diff --git a/src/event.c b/src/event.c index 5b2b42d..ce5276f 100644 --- a/src/event.c +++ b/src/event.c @@ -411,8 +411,8 @@ int adns_processreadable(adns_state ads, int fd, const struct timeval *now) { } for (serv= 0; serv < ads->nservers && - !adns__sockaddr_equal_p(&udpaddr.sa, - &ads->servers[serv].addr.sa); + !adns__sockaddrs_equal(&udpaddr.sa, + &ads->servers[serv].addr.sa); serv++); if (serv >= ads->nservers) { adns__warn(ads,-1,0,"datagram received from unknown nameserver %s", diff --git a/src/internal.h b/src/internal.h index 4144ec1..0b39418 100644 --- a/src/internal.h +++ b/src/internal.h @@ -131,13 +131,6 @@ typedef struct { struct timeval now; } parseinfo; -union gen_addr { - struct in_addr v4; - struct in6_addr v6; -}; - -struct af_addr { int af; union gen_addr addr; }; - #define NREVDOMAINS 2 /* keep in sync with addrfam! */ struct revparse_state { unsigned map; /* which domains are still live */ @@ -155,7 +148,7 @@ typedef struct { union { struct { adns_rrtype rev_rrtype; - struct af_addr addr; + adns_sockaddr addr; } ptr; struct { unsigned want, have; @@ -399,8 +392,7 @@ struct adns__state { struct pollfd pollfds_buf[MAX_POLLFDS]; adns_rr_addr servers[MAXSERVERS]; struct sortlist { - int af; - union gen_addr base, mask; + adns_sockaddr base, mask; } sortlist[MAXSORTLIST]; char **searchlist; unsigned short rand48xsubi[3]; @@ -408,21 +400,20 @@ struct adns__state { /* From addrfam.c: */ -extern int adns__af_supported_p(int af); -/* Return nonzero if the address family af known to the library and supported - * by the other addrfam operations. Note that the other operations will - * abort on an unrecognized address family rather than returning an error - * code. +extern int adns__addrs_equal_raw(const struct sockaddr *a, + int bf, const void *b); +/* Returns nonzero a's family is bf and a's protocol address field + * refers to the same protocol address as that stored at ba. */ -extern int adns__genaddr_equal_p(int af, const union gen_addr *a, - int bf, const void *b); -/* b should point to a `struct in_addr' or equivalent for the address family - * bf. Returns nonzero if the two addresses are equal. +extern int adns__addrs_equal(const adns_sockaddr *a, + const adns_sockaddr *b); +/* Returns nonzero if the two refer to the same protocol address + * (disregarding port, IPv6 scope, etc). */ -extern int adns__sockaddr_equal_p(const struct sockaddr *sa, - const struct sockaddr *sb); +extern int adns__sockaddrs_equal(const struct sockaddr *sa, + const struct sockaddr *sb); /* Return nonzero if the two socket addresses are equal (in all significant * respects). */ @@ -430,39 +421,33 @@ extern int adns__sockaddr_equal_p(const struct sockaddr *sa, extern int adns__addr_width(int af); /* Return the width of addresses of family af, in bits. */ -extern void adns__prefix_mask(int af, int len, union gen_addr *mask_r); -/* Store in mask_r an address mask for address family af, whose first len - * bits are set and the remainder are clear. This is what you want for - * converting a prefix length into a netmask. +extern void adns__prefix_mask(adns_sockaddr *sa, int len); +/* Stores in sa's protocol address field an address mask for address + * family af, whose first len bits are set and the remainder are + * clear. On entry, sa's af field must be set. This is what you want + * for converting a prefix length into a netmask. */ -extern int adns__guess_prefix_length(int af, const union gen_addr *addr); +extern int adns__guess_prefix_length(const adns_sockaddr *addr); /* Given a network base address, guess the appropriate prefix length based on * the appropriate rules for the address family (e.g., for IPv4, this uses * the old address classes). */ -extern int adns__addr_match_p(int addraf, const union gen_addr *addr, - int netaf, const union gen_addr *base, - const union gen_addr *mask); -/* Given an address af (with family addraf) and a network (with family netaf, - * base address base, and netmask mask), return nonzero if the address lies - * within the network. +extern int adns__addr_matches(int af, const void *addr, + const adns_sockaddr *base, + const adns_sockaddr *mask); +/* Return nonzero if the protocol address specified by af and addr + * lies within the network specified by base and mask. */ -extern void adns__sockaddr_extract(const struct sockaddr *sa, - union gen_addr *a_r, int *port_r); -/* Extract fields from the socket address, filling in *a_r and *port_r with - * the address and (integer, host byte-order) port number, respectively. - * Either (or, pointlessly, both) of a_r and port_r may be null to mean - * `don't care'. +extern void adns__addr_inject(const void *a, adns_sockaddr *sa); +/* Injects the protocol address *a into the socket adress sa. Assumes + * that sa->sa_family is already set correctly. */ -extern void adns__sockaddr_inject(const union gen_addr *a, int port, - struct sockaddr *sa); -/* Inject fields into the socket adress sa. If a is not null, copy the - * address in; if port is not -1, then copy the port (converting from host - * byte-order). Assumes that sa->sa_family is already set correctly. +extern const void *adns__sockaddr_addr(const struct sockaddr *sa); +/* Returns the address of the protocol address field in sa. */ char *adns__sockaddr_ntoa(const struct sockaddr *sa, char *buf); @@ -497,11 +482,12 @@ extern int adns__revparse_label(struct revparse_state *rps, int labnum, */ extern int adns__revparse_done(struct revparse_state *rps, int nlabels, - adns_rrtype *rrtype_r, struct af_addr *addr_r); -/* Finishes parsing a reverse-domain name, given the total number of labels - * in the name. On success, fills in the address in *addr_r, and the forward - * query type in *rrtype_r (because that turns out to be useful). Returns - * nonzero if the parse must be abandoned. + adns_rrtype *rrtype_r, adns_sockaddr *addr_r); +/* Finishes parsing a reverse-domain name, given the total number of + * labels in the name. On success, fills in the af and protocol + * address in *addr_r, and the forward query type in *rrtype_r + * (because that turns out to be useful). Returns nonzero if the + * parse must be abandoned. */ /* From setup.c: */ diff --git a/src/setup.c b/src/setup.c index a082870..79e00e1 100644 --- a/src/setup.c +++ b/src/setup.c @@ -47,7 +47,7 @@ static void addserver(adns_state ads, const struct sockaddr *sa, int n) { char buf[ADNS_ADDR2TEXT_BUFLEN]; for (i=0; inservers; i++) { - if (adns__sockaddr_equal_p(sa, &ads->servers[i].addr.sa)) { + if (adns__sockaddrs_equal(sa, &ads->servers[i].addr.sa)) { adns__debug(ads,-1,0,"duplicate nameserver %s ignored", adns__sockaddr_ntoa(sa, buf)); return; @@ -165,17 +165,15 @@ static void ccf_search(adns_state ads, const char *fn, ads->searchlist= newptrs; } -static int gen_pton(const char *text, int *af_io, union gen_addr *a) { - adns_rr_addr addr; +static int gen_pton(const char *text, int want_af, adns_sockaddr *a) { int err; + int len; - addr.len= sizeof(addr.addr); + len= sizeof(*a); err= adns_text2addr(text,0, adns_qf_addrlit_scope_forbid, - &addr.addr.sa, &addr.len); + &a->sa, &len); if (err) { assert(err == EINVAL); return 0; } - if (*af_io == AF_UNSPEC) *af_io= addr.addr.sa.sa_family; - else if (*af_io != addr.addr.sa.sa_family) return 0; - adns__sockaddr_extract(&addr.addr.sa, a, 0); + if (want_af != AF_UNSPEC && a->sa.sa_family != want_af) return 0; return 1; } @@ -186,7 +184,6 @@ static void ccf_sortlist(adns_state ads, const char *fn, const char *maskwhat; struct sortlist *sl; int l; - int af; int initial= -1; if (!buf) return; @@ -209,8 +206,7 @@ static void ccf_sortlist(adns_state ads, const char *fn, if (slash) *slash++= 0; sl= &ads->sortlist[ads->nsortlist]; - af= AF_UNSPEC; - if (!gen_pton(tbuf, &af, &sl->base)) { + if (!gen_pton(tbuf, AF_UNSPEC, &sl->base)) { configparseerr(ads,fn,lno,"invalid address `%s' in sortlist",tbuf); continue; } @@ -218,32 +214,36 @@ static void ccf_sortlist(adns_state ads, const char *fn, if (slash) { if (slash[strspn(slash, "0123456789")]) { maskwhat = "mask"; - if (!gen_pton(slash,&af,&sl->mask)) { + if (!gen_pton(slash, sl->base.sa.sa_family, &sl->mask)) { configparseerr(ads,fn,lno,"invalid mask `%s' in sortlist",slash); continue; } } else { maskwhat = "prefix length"; initial= strtoul(slash,&ep,10); - if (*ep || initial>adns__addr_width(af)) { + if (*ep || initial>adns__addr_width(sl->base.sa.sa_family)) { configparseerr(ads,fn,lno,"mask length `%s' invalid",slash); continue; } - adns__prefix_mask(af, initial, &sl->mask); + sl->mask.sa.sa_family= sl->base.sa.sa_family; + adns__prefix_mask(&sl->mask, initial); } } else { maskwhat = "implied prefix length"; - initial= adns__guess_prefix_length(af, &sl->base); + initial= adns__guess_prefix_length(&sl->base); if (initial < 0) { configparseerr(ads,fn,lno, "network address `%s'" " in sortlist is not in classed ranges," " must specify mask explicitly", tbuf); continue; } - adns__prefix_mask(af, initial, &sl->mask); + sl->mask.sa.sa_family= sl->base.sa.sa_family; + adns__prefix_mask(&sl->mask, initial); } - if (!adns__addr_match_p(af,&sl->base, af,&sl->base,&sl->mask)) { + if (!adns__addr_matches(sl->base.sa.sa_family, + adns__sockaddr_addr(&sl->base.sa), + &sl->base,&sl->mask)) { if (initial >= 0) { configparseerr(ads,fn,lno, "%s %d in sortlist" " overlaps address `%s'",maskwhat,initial,tbuf); @@ -254,7 +254,6 @@ static void ccf_sortlist(adns_state ads, const char *fn, continue; } - sl->af= af; ads->nsortlist++; } } diff --git a/src/types.c b/src/types.c index d53fe3e..8b9723e 100644 --- a/src/types.c +++ b/src/types.c @@ -263,27 +263,26 @@ static adns_status pa_inaddr(const parseinfo *pai, int cbyte, static int search_sortlist(adns_state ads, int af, const void *ad) { const struct sortlist *slp; - const struct in6_addr *a6; - union gen_addr a; + struct in_addr a4; int i; int v6mappedp= 0; if (af == AF_INET6) { - a6= ad; + const struct in6_addr *a6= ad; if (IN6_IS_ADDR_V4MAPPED(a6)) { - a.v4.s_addr= htonl(((unsigned long)a6->s6_addr[12] << 24) | - ((unsigned long)a6->s6_addr[13] << 16) | - ((unsigned long)a6->s6_addr[14] << 8) | - ((unsigned long)a6->s6_addr[15] << 0)); + a4.s_addr= htonl(((unsigned long)a6->s6_addr[12] << 24) | + ((unsigned long)a6->s6_addr[13] << 16) | + ((unsigned long)a6->s6_addr[14] << 8) | + ((unsigned long)a6->s6_addr[15] << 0)); v6mappedp= 1; } } for (i=0, slp=ads->sortlist; insortlist && - !adns__addr_match_p(af,ad, slp->af,&slp->base,&slp->mask) && + !adns__addr_matches(af,ad, &slp->base,&slp->mask) && !(v6mappedp && - adns__addr_match_p(AF_INET,&a, slp->af,&slp->base,&slp->mask)); + adns__addr_matches(AF_INET,&a4, &slp->base,&slp->mask)); i++, slp++); return i; } @@ -311,7 +310,7 @@ static adns_status csp_genaddr(vbuf *vb, int af, const void *p) { memset(&a, 0, sizeof(a)); a.addr.sa.sa_family= af; - adns__sockaddr_inject(p, 0, &a.addr.sa); + adns__addr_inject(p, &a.addr); err= adns_addr2text(&a.addr.sa,0, buf,&len, 0); assert(!err); CSP_ADDSTR(buf); return adns_s_ok; @@ -456,9 +455,8 @@ static adns_status pa_addr(const parseinfo *pai, int cbyte, } static int search_sortlist_sa(adns_state ads, const struct sockaddr *sa) { - union gen_addr a; - adns__sockaddr_extract(sa, &a, 0); - return search_sortlist(ads, sa->sa_family, &a); + const void *pa = adns__sockaddr_addr(sa); + return search_sortlist(ads, sa->sa_family, pa); } static int dip_sockaddr(adns_state ads, @@ -1152,7 +1150,7 @@ static adns_status ckl_ptr(adns_state ads, adns_queryflags flags, static void icb_ptr(adns_query parent, adns_query child) { adns_answer *cans= child->answer; - const struct af_addr *queried; + const adns_sockaddr *queried; const unsigned char *found; adns_state ads= parent->ads; int i; @@ -1167,8 +1165,8 @@ static void icb_ptr(adns_query parent, adns_query child) { queried= &parent->ctx.tinfo.ptr.addr; for (i=0, found=cans->rrs.bytes; inrrs; i++, found+=cans->rrsz) { - if (adns__genaddr_equal_p(queried->af,&queried->addr, - parent->ctx.tinfo.ptr.addr.af,found)) { + if (adns__addrs_equal_raw(&queried->sa, + parent->ctx.tinfo.ptr.addr.sa.sa_family,found)) { if (!parent->children.head) { adns__query_done(parent); return; -- 2.30.2