--------------------- PatchSet 1791 Date: 2001/03/29 12:40:02 Author: rvenning Branch: ipv6 Tag: (none) Log: Added support for AAAA records into internal DNS. On the downside, because BIND does not support the DNS Internet Standard and handle multiple queries in a single DNS request packet, this is done by dispatching a separate A and AAAA query for every name request. Reverse IPv6 lookups (0.a.b.2.3.....2.3.4.ip6.int may work, but this hasn't really been tested. A6 chain lookups are not yet supported. This is part of my plot for handling specification of ACLs, in a non-numeric format as well. Remaining items before being "ready" in some sort of priority order: o ACLs o wccp co-existance o remove need to set incoming & outgoing addrs to :: explicitly in conf o make it all work on non-linux platforms (problems will exist in listening to IPv4 & IPv6 on same socket on most platforms other than linux) o add v6 DNS record handling & tie to address ACL specification Members: CONTRIBUTORS:1.4.2.1->1.4.2.2 include/rfc1035.h:1.3.6.2->1.3.6.3 lib/rfc1035.c:1.4.6.2->1.4.6.3 lib/safe_inet_addr.c:1.2.6.3->1.2.6.4 src/comm.c:1.4.6.3->1.4.6.4 src/dns_internal.c:1.5.6.2->1.5.6.3 src/icp_v2.c:1.3.6.2->1.3.6.3 src/ipcache.c:1.4.6.5->1.4.6.6 src/protos.h:1.5.2.4->1.5.2.5 Index: squid/CONTRIBUTORS =================================================================== RCS file: /cvsroot/squid-sf//squid/CONTRIBUTORS,v retrieving revision 1.4.2.1 retrieving revision 1.4.2.2 diff -u -r1.4.2.1 -r1.4.2.2 --- squid/CONTRIBUTORS 23 Mar 2001 16:06:23 -0000 1.4.2.1 +++ squid/CONTRIBUTORS 29 Mar 2001 12:40:02 -0000 1.4.2.2 @@ -82,5 +82,6 @@ Sergio Rabellino Ian Turner Moez Mahfoudh + Roger Venning Duane Wessels Index: squid/include/rfc1035.h =================================================================== RCS file: /cvsroot/squid-sf//squid/include/rfc1035.h,v retrieving revision 1.3.6.2 retrieving revision 1.3.6.3 diff -u -r1.3.6.2 -r1.3.6.3 --- squid/include/rfc1035.h 27 Feb 2001 14:18:26 -0000 1.3.6.2 +++ squid/include/rfc1035.h 29 Mar 2001 12:40:02 -0000 1.3.6.3 @@ -1,5 +1,5 @@ /* - * $Id: rfc1035.h,v 1.3.6.2 2001/02/27 14:18:26 rvenning Exp $ + * $Id: rfc1035.h,v 1.3.6.3 2001/03/29 12:40:02 rvenning Exp $ * * AUTHOR: Duane Wessels * @@ -35,6 +35,7 @@ #define _RFC1035_H_ #include "config.h" +#include "../src/defines.h" #if HAVE_SYS_TYPES_H #include #endif @@ -56,13 +57,11 @@ unsigned short rdlength; char *rdata; }; -extern unsigned short rfc1035BuildAQuery(const char *hostname, +extern unsigned short rfc1035BuildAddrQuery(const char *hostname, char *buf, - size_t * szp); -extern unsigned short rfc1035BuildAAAAQuery(const char *hostname, - char *buf, - size_t * szp); -extern unsigned short rfc1035BuildPTRQuery(const struct in_addr, + size_t * szp, + int family); +extern unsigned short rfc1035BuildPTRQuery(const struct IN_ADDR, char *buf, size_t * szp); extern unsigned short rfc1035RetryQuery(char *); Index: squid/lib/rfc1035.c =================================================================== RCS file: /cvsroot/squid-sf//squid/lib/rfc1035.c,v retrieving revision 1.4.6.2 retrieving revision 1.4.6.3 diff -u -r1.4.6.2 -r1.4.6.3 --- squid/lib/rfc1035.c 27 Feb 2001 14:18:49 -0000 1.4.6.2 +++ squid/lib/rfc1035.c 29 Mar 2001 12:40:02 -0000 1.4.6.3 @@ -1,6 +1,6 @@ /* - * $Id: rfc1035.c,v 1.4.6.2 2001/02/27 14:18:49 rvenning Exp $ + * $Id: rfc1035.c,v 1.4.6.3 2001/03/29 12:40:02 rvenning Exp $ * * Low level DNS protocol routines * AUTHOR: Duane Wessels @@ -469,11 +469,32 @@ return nr; } -int rfc1035BuildAddrQuery(const char *hostname, char * buf, size_t * szp, unsigned short addrType) +/* + * rfc1035BuildAddrQuery() + * + * Builds a message buffer with a QUESTION to lookup records + * for a hostname. Caller must allocate 'buf' which should + * probably be at least 512 octets. The 'szp' initially + * specifies the size of the buffer, on return it contains + * the size of the message (i.e. how much to write). + * Return value is the query ID. + */ + +/* if BIND could handle multiple queries in one packet as per DNS spec + this would handle getting IPv6 & IPv4 addrs simultaneously. But it doesn't... */ +extern unsigned short rfc1035BuildAddrQuery(const char *hostname, char * buf, size_t * szp, int family) { static rfc1035_header h; size_t offset = 0; size_t sz = *szp; + unsigned short addrType = 0; + if (family == AF_INET) + addrType = RFC1035_TYPE_A; +#if INET6 + if (family == AF_INET6) + addrType = RFC1886_TYPE_AAAA; +#endif + assert(addrType != 0); memset(&h, '\0', sizeof(h)); /* the first char of hostname must be alphanmeric */ if (NULL == strchr(Alphanum, *hostname)) { @@ -484,12 +505,12 @@ h.qr = 0; h.rd = 1; h.opcode = 0; /* QUERY */ - h.qdcount = (unsigned int) 1; + h.qdcount = 1; offset += rfc1035HeaderPack(buf + offset, sz - offset, &h); offset += rfc1035QuestionPack(buf + offset, sz - offset, hostname, - addrType, + addrType, RFC1035_CLASS_IN); assert(offset <= sz); *szp = (size_t) offset; @@ -497,34 +518,6 @@ } /* - * rfc1035BuildAQuery() - * - * Builds a message buffer with a QUESTION to lookup A records - * for a hostname. Caller must allocate 'buf' which should - * probably be at least 512 octets. The 'szp' initially - * specifies the size of the buffer, on return it contains - * the size of the message (i.e. how much to write). - * Return value is the query ID. - */ -unsigned short -rfc1035BuildAQuery(const char *hostname, char *buf, size_t * szp) -{ - return rfc1035BuildAddrQuery(hostname, buf, szp, RFC1035_TYPE_A); -} - -/* - * rfc1035BuildAAAAQuery() - * - * exactly as rfc1035BuildAQuery(), but looks for AAAA records - */ -unsigned short -rfc1035BuildAAAAQuery(const char *hostname, char *buf, size_t * szp) -{ - return rfc1035BuildAddrQuery(hostname, buf, szp, RFC1886_TYPE_AAAA); -} - - -/* * rfc1035BuildPTRQuery() * * Builds a message buffer with a QUESTION to lookup PTR records @@ -535,31 +528,63 @@ * Return value is the query ID. */ unsigned short -rfc1035BuildPTRQuery(const struct in_addr addr, char *buf, size_t * szp) +rfc1035BuildPTRQuery(const struct IN_ADDR addr, char *buf, size_t * szp) { static rfc1035_header h; size_t offset = 0; size_t sz = *szp; - static char rev[32]; + static char rev[72]; /* 32 * 2 + ip6.int */ unsigned int i; memset(&h, '\0', sizeof(h)); - i = (unsigned int) ntohl(addr.s_addr); - snprintf(rev, 32, "%u.%u.%u.%u.in-addr.arpa.", - i & 255, - (i >> 8) & 255, - (i >> 16) & 255, - (i >> 24) & 255); + +#if INET6 + if (IN6_IS_ADDR_V4MAPPED(&addr)) { + i = (unsigned int) ntohl(addr.s6_addr[3]); +#else + i = (unsigned int) ntohl(addr.s_addr); +#endif + snprintf(rev, 32, "%u.%u.%u.%u.in-addr.arpa.", + i & 255, + (i >> 8) & 255, + (i >> 16) & 255, + (i >> 24) & 255); +#if INET6 + } else { + /* a real IPv6 address */ + unsigned char * a = (unsigned char *)rev; + snprintf(rev, 72, + "%x.%x.%x.%x.%x.%x.%x.%x." + "%x.%x.%x.%x.%x.%x.%x.%x." + "%x.%x.%x.%x.%x.%x.%x.%x." + "%x.%x.%x.%x.%x.%x.%x.%x.ip6.int", + a[0] & 0x0f, a[0] & 0xf0, + a[1] & 0x0f, a[1] & 0xf0, + a[2] & 0x0f, a[2] & 0xf0, + a[3] & 0x0f, a[3] & 0xf0, + a[4] & 0x0f, a[4] & 0xf0, + a[5] & 0x0f, a[5] & 0xf0, + a[6] & 0x0f, a[6] & 0xf0, + a[7] & 0x0f, a[7] & 0xf0, + a[8] & 0x0f, a[8] & 0xf0, + a[9] & 0x0f, a[9] & 0xf0, + a[10] & 0x0f, a[10] & 0xf0, + a[11] & 0x0f, a[11] & 0xf0, + a[12] & 0x0f, a[12] & 0xf0, + a[13] & 0x0f, a[13] & 0xf0, + a[14] & 0x0f, a[14] & 0xf0, + a[15] & 0x0f, a[15] & 0xf0); + } +#endif h.id = rfc1035Qid(); h.qr = 0; h.rd = 1; h.opcode = 0; /* QUERY */ - h.qdcount = (unsigned int) 1; offset += rfc1035HeaderPack(buf + offset, sz - offset, &h); offset += rfc1035QuestionPack(buf + offset, - sz - offset, - rev, - RFC1035_TYPE_PTR, - RFC1035_CLASS_IN); + sz - offset, + rev, + RFC1035_TYPE_PTR, + RFC1035_CLASS_IN); assert(offset <= sz); *szp = offset; return h.id; Index: squid/lib/safe_inet_addr.c =================================================================== RCS file: /cvsroot/squid-sf//squid/lib/safe_inet_addr.c,v retrieving revision 1.2.6.3 retrieving revision 1.2.6.4 diff -u -r1.2.6.3 -r1.2.6.4 --- squid/lib/safe_inet_addr.c 27 Feb 2001 14:18:49 -0000 1.2.6.3 +++ squid/lib/safe_inet_addr.c 29 Mar 2001 12:40:02 -0000 1.2.6.4 @@ -1,6 +1,6 @@ /* - * $Id: safe_inet_addr.c,v 1.2.6.3 2001/02/27 14:18:49 rvenning Exp $ + * $Id: safe_inet_addr.c,v 1.2.6.4 2001/03/29 12:40:02 rvenning Exp $ */ #include "config.h" @@ -65,6 +65,7 @@ return 1; } +#if INET6 int safe_inet_sockaddr(const char *buf, struct sockaddr_storage *addr) { struct in6_addr inaddr6; @@ -83,7 +84,7 @@ } return 0; } - +#endif #if INET6 int Index: squid/src/comm.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/comm.c,v retrieving revision 1.4.6.3 retrieving revision 1.4.6.4 diff -u -r1.4.6.3 -r1.4.6.4 --- squid/src/comm.c 23 Mar 2001 16:06:27 -0000 1.4.6.3 +++ squid/src/comm.c 29 Mar 2001 12:40:02 -0000 1.4.6.4 @@ -1,6 +1,6 @@ /* - * $Id: comm.c,v 1.4.6.3 2001/03/23 16:06:27 rvenning Exp $ + * $Id: comm.c,v 1.4.6.4 2001/03/29 12:40:02 rvenning Exp $ * * DEBUG: section 5 Socket Functions * AUTHOR: Harvest Derived @@ -417,6 +417,8 @@ socklen_t errlen; assert(ntohs(PORT_FROM_SA(*address)) != 0); /* Establish connection. */ + debug(5, 4) ("comm_connect_addr: Connecting to %s port %d\n", + SA_NTOA(*address), PORT_FROM_SA(*address)); errno = 0; if (!F->flags.called_connect) { F->flags.called_connect = 1; Index: squid/src/dns_internal.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/dns_internal.c,v retrieving revision 1.5.6.2 retrieving revision 1.5.6.3 diff -u -r1.5.6.2 -r1.5.6.3 --- squid/src/dns_internal.c 27 Feb 2001 14:18:51 -0000 1.5.6.2 +++ squid/src/dns_internal.c 29 Mar 2001 12:40:02 -0000 1.5.6.3 @@ -1,6 +1,6 @@ /* - * $Id: dns_internal.c,v 1.5.6.2 2001/02/27 14:18:51 rvenning Exp $ + * $Id: dns_internal.c,v 1.5.6.3 2001/03/29 12:40:02 rvenning Exp $ * * DEBUG: section 78 DNS lookups; interacts with lib/rfc1035.c * AUTHOR: Duane Wessels @@ -98,10 +98,10 @@ debug(78, 0) ("WARNING: rejecting '%s' as a name server, because it is not a numeric IP address\n", buf); return; } - if (A.s_addr == 0) { + if (ADDR_IS_NOADDR(A)) { debug(78, 0) ("WARNING: Squid does not accept 0.0.0.0 in DNS server specifications.\n"); debug(78, 0) ("Will be using 127.0.0.1 instead, assuming you meant that DNS is running on the same machine\n"); - safe_inet_addr("127.0.0.1", &A); + SAFE_INET_ADDR("127.0.0.1", &A); /* won't work on ipv6 only node */ } if (nns == nns_alloc) { int oldalloc = nns_alloc; @@ -310,6 +310,7 @@ } dlinkDelete(&q->lru, &lru_list); idnsRcodeCount(n, q->attempt); + /* FIXME - THIS IS WHERE WE POINT IN LOGIC TO FOLLOW A6 POINTER CHAINS? */ if (n < 0) { debug(78, 3) ("idnsGrokReply: error %d\n", rfc1035_errno); if (-2 == n && ++q->attempt < MAX_ATTEMPT) { @@ -501,18 +502,18 @@ } void -idnsALookup(const char *name, IDNSCB * callback, void *data) +idnsLookup(const char *name, IDNSCB * callback, void *data, int family) { idns_query *q = memAllocate(MEM_IDNS_QUERY); q->sz = sizeof(q->buf); - q->id = rfc1035BuildAQuery(name, q->buf, &q->sz); + q->id = rfc1035BuildAddrQuery(name, q->buf, &q->sz, family); if (0 == q->id) { /* problem with query data -- query not sent */ callback(data, NULL, 0); memFree(q, MEM_IDNS_QUERY); return; } - debug(78, 3) ("idnsALookup: buf is %d bytes for %s, id = %#hx\n", + debug(78, 3) ("idnsLookup: buf is %d bytes for %s, id = %#hx\n", (int) q->sz, name, q->id); q->callback = callback; q->callback_data = data; Index: squid/src/icp_v2.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/icp_v2.c,v retrieving revision 1.3.6.2 retrieving revision 1.3.6.3 diff -u -r1.3.6.2 -r1.3.6.3 --- squid/src/icp_v2.c 27 Feb 2001 14:18:52 -0000 1.3.6.2 +++ squid/src/icp_v2.c 29 Mar 2001 12:40:02 -0000 1.3.6.3 @@ -1,6 +1,6 @@ /* - * $Id: icp_v2.c,v 1.3.6.2 2001/02/27 14:18:52 rvenning Exp $ + * $Id: icp_v2.c,v 1.3.6.3 2001/03/29 12:40:02 rvenning Exp $ * * DEBUG: section 12 Internet Cache Protocol * AUTHOR: Duane Wessels @@ -434,7 +434,11 @@ INET_NTOA(Config.Addrs.udp_incoming), (int) port, theInIcpConnection); addr = Config.Addrs.udp_outgoing; +#if INET6 + if (!ADDR_IS_ANYADDR(addr)) { /* in IPv6, this is ::, which is what we want */ +#else if (!ADDR_IS_NOADDR(addr)) { +#endif enter_suid(); theOutIcpConnection = comm_open(SOCK_DGRAM, 0, Index: squid/src/ipcache.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/ipcache.c,v retrieving revision 1.4.6.5 retrieving revision 1.4.6.6 diff -u -r1.4.6.5 -r1.4.6.6 --- squid/src/ipcache.c 23 Mar 2001 16:06:29 -0000 1.4.6.5 +++ squid/src/ipcache.c 29 Mar 2001 12:40:02 -0000 1.4.6.6 @@ -1,6 +1,6 @@ /* - * $Id: ipcache.c,v 1.4.6.5 2001/03/23 16:06:29 rvenning Exp $ + * $Id: ipcache.c,v 1.4.6.6 2001/03/29 12:40:02 rvenning Exp $ * * DEBUG: section 14 IP Cache * AUTHOR: Harvest Derived @@ -51,6 +51,9 @@ struct { unsigned int negcached:1; unsigned int fromhosts:1; +#if INET6 + unsigned int gotOne:1; +#endif } flags; }; @@ -324,7 +327,11 @@ } assert(answers); for (j = 0, k = 0; k < nr; k++) { - if (answers[k].type != RFC1035_TYPE_A) + if (answers[k].type != RFC1035_TYPE_A +#if INET6 + && answers[k].type != RFC1886_TYPE_AAAA +#endif + ) continue; if (answers[k].class != RFC1035_CLASS_IN) continue; @@ -340,14 +347,33 @@ i.addrs.bad_mask = xcalloc(na, sizeof(unsigned char)); i.addrs.count = (unsigned char) na; for (j = 0, k = 0; k < nr; k++) { - if (answers[k].type != RFC1035_TYPE_A) + if (answers[k].type != RFC1035_TYPE_A +#if INET6 + && answers[k].type != RFC1886_TYPE_AAAA +#endif + ) continue; if (answers[k].class != RFC1035_CLASS_IN) continue; if (j == 0) i.expires = squid_curtime + answers[k].ttl; + +#if INET6 + if (answers[k].type == RFC1035_TYPE_A) { + struct in6_addr * a; + assert(answers[k].rdlength == 4); + /* need to make into a mapped address */ + a = &i.addrs.in_addrs[j++]; + a->s6_addr32[2] = htonl(0x0000ffff); + xmemcpy(&a->s6_addr32[3], answers[k].rdata, 4); + } else if (answers[k].type == RFC1886_TYPE_AAAA) { + assert(answers[k].rdlength == 16); + xmemcpy(&i.addrs.in_addrs[j++], answers[k].rdata, 16); + } +#else assert(answers[k].rdlength == 4); xmemcpy(&i.addrs.in_addrs[j++], answers[k].rdata, 4); +#endif debug(14, 3) ("ipcacheParse: #%d %s\n", j - 1, INET_NTOA(i.addrs.in_addrs[j - 1])); @@ -367,8 +393,17 @@ generic_cbdata *c = data; ipcache_entry *i = c->data; ipcache_entry *x = NULL; +#if INET6 && ! USE_DNSSERVERS + /* we only free cbdata if already got one of A or AAAA */ + /* DANGER, DANGER WILL ROBINSON. Do we have locking / re-entrancy probs? */ + if (i->flags.gotOne) { + cbdataFree(c); + c = NULL; + } +#else cbdataFree(c); c = NULL; +#endif IpcacheStats.replies++; statHistCount(&statCounter.dns.svc_time, tvSubMsec(i->request_time, current_time)); @@ -378,12 +413,75 @@ x = ipcacheParse(answers, na); #endif assert(x); +#if INET6 && ! USE_DNSSERVERS + if (c == NULL) { /* only on the second time through */ + /* allocate space for it all */ + ipcache_addrs allI; + + debug(14, 7) ("ipcacheParse: Merging on second time through\n"); + /* deal with degenerate cases first */ + if (i->addrs.count == 0) { + debug(14, 7) ("ipcacheParse: Degenerate - nothing last time\n"); + i->addrs = x->addrs; + } else if (x->addrs.count == 0) { + debug(14, 7) ("ipcacheParse: Degenerate - nothing this time\n"); + debug(14, 7) ("ipcacheParse: - last time %d addresses\n", i->addrs.count); + /* and let the error run its course if no address previously */ + } else if (i->addrs.count == 0 && x->addrs.count == 0) { + ; /* really degenerate - no addresses */ + } else { + /* we need to merge */ + allI.count = i->addrs.count + x->addrs.count; + allI.in_addrs = xcalloc(allI.count, sizeof(struct IN_ADDR)); + allI.bad_mask = xcalloc(allI.count, sizeof(unsigned char)); + allI.badcount = i->addrs.badcount + x->addrs.badcount; + /* choose cur to point to IPv6 */ + if (!IN6_IS_ADDR_V4MAPPED(i->addrs.in_addrs)) + allI.cur = 0; /* we shove i at the start */ + else + allI.cur = i->addrs.count; /* point at index of x addrs, as they're IPv6 */ + + debug(14, 7) ("ipcacheParse: Merging %d addresses\n", allI.count); + xmemcpy(allI.in_addrs, i->addrs.in_addrs, + sizeof(struct IN_ADDR) * i->addrs.count); + xmemcpy(allI.bad_mask, i->addrs.bad_mask, + sizeof(unsigned char) * i->addrs.count); + xmemcpy(&allI.in_addrs[i->addrs.count], x->addrs.in_addrs, + sizeof(struct IN_ADDR) * x->addrs.count); + xmemcpy(&allI.bad_mask[i->addrs.count], x->addrs.bad_mask, + sizeof(unsigned char) * x->addrs.count); + + /* free & re-assign */ + safe_free(i->addrs.in_addrs); + safe_free(i->addrs.in_addrs); + safe_free(i->addrs.bad_mask); + safe_free(x->addrs.in_addrs); + safe_free(x->addrs.in_addrs); + safe_free(x->addrs.bad_mask); + i->addrs = allI; /* struct assignment */ + } + } else { + /* this is the first time through, save it for later */ + i->addrs = x->addrs; + i->error_message = x->error_message; + i->expires = x->expires; /* dodgy - IPv4 & IPv6 addrs have same expiry... */ + i->flags = x->flags; + } + + i->flags.gotOne = 1; /* we do have one answer now */ + if (c == NULL) { + /* we have received and processed both answers */ + ipcacheAddEntry(i); + ipcacheCallback(i); + } +#else i->addrs = x->addrs; i->error_message = x->error_message; i->expires = x->expires; i->flags = x->flags; ipcacheAddEntry(i); ipcacheCallback(i); +#endif } void @@ -437,7 +535,12 @@ #if USE_DNSSERVERS dnsSubmit(hashKeyStr(&i->hash), ipcacheHandleReply, c); #else - idnsALookup(hashKeyStr(&i->hash), ipcacheHandleReply, c); + idnsLookup(hashKeyStr(&i->hash), ipcacheHandleReply, c, AF_INET); +#if INET6 + /* we have two things using the one call back if IPv6 */ + debug(14, 7) ("ipcache_nbgethostbyname: Name '%s' - getting A & AAAA recs.\n", name); + idnsLookup(hashKeyStr(&i->hash), ipcacheHandleReply, c, AF_INET6); +#endif /* INET6 */ #endif } @@ -620,12 +723,29 @@ return; ia = &i->addrs; } +#ifdef INET6 + /* first favour good IPv6 addresses */ for (k = 0; k < ia->count; k++) { if (++ia->cur == ia->count) ia->cur = 0; - if (!ia->bad_mask[ia->cur]) + if (!ia->bad_mask[ia->cur] && + !IN6_IS_ADDR_V4MAPPED(&ia->in_addrs[ia->cur])) break; } + + /* if this is true, we spun right through without getting an IPv6, + we still need to cycle the IPv4 mapped address */ + if (IN6_IS_ADDR_V4MAPPED(&ia->in_addrs[ia->cur])) { +#endif + for (k = 0; k < ia->count; k++) { + if (++ia->cur == ia->count) + ia->cur = 0; + if (!ia->bad_mask[ia->cur]) + break; + } +#ifdef INET6 + } +#endif if (k == ia->count) { /* All bad, reset to All good */ debug(14, 3) ("ipcacheCycleAddr: Changing ALL %s addrs from BAD to OK\n", Index: squid/src/protos.h =================================================================== RCS file: /cvsroot/squid-sf//squid/src/protos.h,v retrieving revision 1.5.2.4 retrieving revision 1.5.2.5 diff -u -r1.5.2.4 -r1.5.2.5 --- squid/src/protos.h 23 Mar 2001 16:06:30 -0000 1.5.2.4 +++ squid/src/protos.h 29 Mar 2001 12:40:02 -0000 1.5.2.5 @@ -1,6 +1,6 @@ /* - * $Id: protos.h,v 1.5.2.4 2001/03/23 16:06:30 rvenning Exp $ + * $Id: protos.h,v 1.5.2.5 2001/03/29 12:40:02 rvenning Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -238,7 +238,7 @@ /* dns_internal.c */ extern void idnsInit(void); extern void idnsShutdown(void); -extern void idnsALookup(const char *, IDNSCB *, void *); +extern void idnsLookup(const char *, IDNSCB *, void *, int family); extern void idnsPTRLookup(const struct IN_ADDR, IDNSCB *, void *); extern void eventAdd(const char *name, EVH * func, void *arg, double when, int);