From: wessels <> Date: Wed, 14 Apr 1999 11:16:12 +0000 (+0000) Subject: initial working implementation of internal DNS! X-Git-Tag: SQUID_3_0_PRE1~2289 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=7b724b86a8a2f18bb51f87e968de315a0ecddeb6;p=thirdparty%2Fsquid.git initial working implementation of internal DNS! --- diff --git a/include/rfc1035.h b/include/rfc1035.h new file mode 100644 index 0000000000..b261280ed6 --- /dev/null +++ b/include/rfc1035.h @@ -0,0 +1,69 @@ +/* + * $Id: rfc1035.h,v 1.1 1999/04/14 05:16:12 wessels Exp $ + * + * AUTHOR: Harvest Derived + * + * SQUID Internet Object Cache http://squid.nlanr.net/Squid/ + * -------------------------------------------------------- + * + * Squid is the result of efforts by numerous individuals from the + * Internet community. Development is led by Duane Wessels of the + * National Laboratory for Applied Network Research and funded by + * the National Science Foundation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. + * + */ + +#ifndef _RFC1035_H_ +#define _RFC1035_H_ + +#include "config.h" +#if HAVE_SYS_TYPES_H +#include +#endif +#if HAVE_NETINET_IN_H +#include +#endif +#if HAVE_ARPA_INET_H +#include +#endif + +/* rfc1035 - DNS */ +#define RFC1035_MAXHOSTNAMESZ 128 +typedef struct _rfc1035_rr rfc1035_rr; +struct _rfc1035_rr { + char name[RFC1035_MAXHOSTNAMESZ]; + unsigned short type; + unsigned short class; + unsigned int ttl; + unsigned short rdlength; + char *rdata; +}; +extern unsigned short rfc1035BuildAQuery(const char *hostname, + char *buf, + size_t * szp); +extern int rfc1035AnswersUnpack(const char *buf, + size_t sz, + rfc1035_rr ** records, + unsigned short *id); +extern void rfc1035RRDestroy(rfc1035_rr * rr, int n); +extern int rfc1035_errno; +extern const char *rfc1035_error_message; + +#define RFC1035_TYPE_A 1 +#define RFC1035_CLASS_IN 1 + +#endif /* ndef _RFC1035_H_ */ diff --git a/lib/rfc1035.c b/lib/rfc1035.c index bf5e99541d..70ca2762f9 100644 --- a/lib/rfc1035.c +++ b/lib/rfc1035.c @@ -1,5 +1,5 @@ /* - * $Id: rfc1035.c,v 1.2 1999/04/13 21:25:56 wessels Exp $ + * $Id: rfc1035.c,v 1.3 1999/04/14 05:16:13 wessels Exp $ * * Low level DNS protocol routines * AUTHOR: Duane Wessels @@ -62,18 +62,15 @@ #include #endif -#define RFC1035_TYPE_A 1 -#define RFC1035_CLASS_IN 1 +#include "rfc1035.h" #define RFC1035_MAXLABELSZ 63 -#define RFC1035_MAXHOSTNAMESZ 128 -typedef struct _rfc1305_header rfc1305_header; -typedef struct _rfc1305_rr rfc1305_rr; +typedef struct _rfc1035_header rfc1035_header; int rfc1035_errno; - -struct _rfc1305_header { +const char *rfc1035_error_message; +struct _rfc1035_header { unsigned short id; unsigned int qr:1; unsigned int opcode:4; @@ -88,23 +85,14 @@ struct _rfc1305_header { unsigned short arcount; }; -struct _rfc1305_rr { - char name[RFC1035_MAXHOSTNAMESZ]; - unsigned short type; - unsigned short class; - unsigned int ttl; - unsigned short rdlength; - char *rdata; -}; - /* * rfc1035HeaderPack() * - * Packs a rfc1305_header structure into a buffer. + * Packs a rfc1035_header structure into a buffer. * Returns number of octets packed (should always be 12) */ static off_t -rfc1035HeaderPack(char *buf, size_t sz, rfc1305_header * hdr) +rfc1035HeaderPack(char *buf, size_t sz, rfc1035_header * hdr) { off_t off = 0; unsigned short s; @@ -216,13 +204,13 @@ rfc1035QuestionPack(char *buf, /* * rfc1035HeaderUnpack() * - * Unpacks a RFC1035 message header buffer into a rfc1305_header + * Unpacks a RFC1035 message header buffer into a rfc1035_header * structure. * Returns the new buffer offset, which is the same as number of * octects unpacked since the header starts at offset 0. */ static off_t -rfc1035HeaderUnpack(const char *buf, size_t sz, rfc1305_header * h) +rfc1035HeaderUnpack(const char *buf, size_t sz, rfc1035_header * h) { unsigned short s; unsigned short t; @@ -294,8 +282,8 @@ rfc1035NameUnpack(const char *buf, size_t sz, off_t off, char *name, size_t ns) len = (size_t) c; if (len == 0) break; - if (len > (ns-1)) - len = ns-1; + if (len > (ns - 1)) + len = ns - 1; memcpy(name + no, buf + off, len); off += len; no += len; @@ -315,7 +303,7 @@ rfc1035NameUnpack(const char *buf, size_t sz, off_t off, char *name, size_t ns) * Returns the new message buffer offset. */ static off_t -rfc1035RRUnpack(const char *buf, size_t sz, off_t off, rfc1305_rr * RR) +rfc1035RRUnpack(const char *buf, size_t sz, off_t off, rfc1035_rr * RR) { unsigned short s; unsigned int i; @@ -339,26 +327,75 @@ rfc1035RRUnpack(const char *buf, size_t sz, off_t off, rfc1305_rr * RR) return off; } +static unsigned short +rfc1035Qid(void) +{ + static unsigned short qid = 0x0001; + if (++qid == 0xFFFF) + qid = 0x0001; + return qid; +} + +void +rfc1035RRDestroy(rfc1035_rr * rr, int n) +{ + if (rr == NULL) + return; + assert(n > 0); + while (n--) { + if (rr[n].rdata) + free(rr[n].rdata); + } + free(rr); +} + int -rfc1035ARecordsUnpack(const char *buf, - size_t sz, - struct in_addr *addrs, - int naddrs, - char *name, - size_t namelen, - unsigned short *id, - time_t * ttl) +rfc1035AnswersUnpack(const char *buf, + size_t sz, + rfc1035_rr ** records, + unsigned short *id) { off_t off = 0; int l; int i; - int na = 0; - rfc1305_header hdr; + int nr = 0; + rfc1035_header hdr; + rfc1035_rr *recs; memset(&hdr, '\0', sizeof(hdr)); off = rfc1035HeaderUnpack(buf + off, sz - off, &hdr); *id = hdr.id; + rfc1035_errno = 0; + rfc1035_error_message = NULL; if (hdr.rcode) { rfc1035_errno = (int) hdr.rcode; + switch (rfc1035_errno) { + case 0: + rfc1035_error_message = "No error condition"; + break; + case 1: + rfc1035_error_message = "Format Error: The name server was " + "unable to interpret the query."; + break; + case 2: + rfc1035_error_message = "Server Failure: The name server was " + "unable to process this query."; + break; + case 3: + rfc1035_error_message = "Name Error: The domain name does " + "not exist."; + break; + case 4: + rfc1035_error_message = "Not Implemented: The name server does " + "not support the requested kind of query."; + break; + case 5: + rfc1035_error_message = "Refused: The name server refuses to " + "perform the specified operation."; + break; + default: + rfc1035_error_message = "Unknown Error"; + break; + } return -rfc1035_errno; } i = (int) hdr.qdcount; @@ -378,27 +415,14 @@ rfc1035ARecordsUnpack(const char *buf, assert(off <= sz); } i = (int) hdr.ancount; + recs = calloc(i, sizeof(*recs)); while (i--) { - rfc1305_rr RR; - memset(&RR, '\0', sizeof(RR)); - off = rfc1035RRUnpack(buf, sz, off, &RR); - if (RR.type != RFC1035_TYPE_A) { - free(RR.rdata); - RR.rdata = NULL; - continue; - } - if (na == 0) { - strncpy(name, RR.name, namelen); - *ttl = (time_t) RR.ttl; - } - memcpy(&addrs[na].s_addr, RR.rdata, 4); - free(RR.rdata); - RR.rdata = NULL; + off = rfc1035RRUnpack(buf, sz, off, &recs[i]); assert(off <= sz); - if (++na == naddrs) - break; + nr++; } - return na; + *records = recs; + return nr; } /* @@ -412,14 +436,13 @@ rfc1035ARecordsUnpack(const char *buf, * Return value is the query ID. */ unsigned short -rfc1035BuildQuery(const char *hostname, char *buf, size_t * szp) +rfc1035BuildAQuery(const char *hostname, char *buf, size_t * szp) { - static unsigned short id = 0x0001; - static rfc1305_header h; + static rfc1035_header h; off_t offset = 0; size_t sz = *szp; memset(&h, '\0', sizeof(h)); - h.id = id; + h.id = rfc1035Qid(); h.qr = 0; h.rd = 1; h.opcode = 0; /* QUERY */ @@ -432,14 +455,14 @@ rfc1035BuildQuery(const char *hostname, char *buf, size_t * szp) RFC1035_CLASS_IN); assert(offset <= sz); *szp = (size_t) offset; - return id++; + return h.id; } #if DRIVER int main(int argc, char *argv[]) { - rfc1305_header h; + rfc1035_header h; char input[512]; char buf[512]; char rbuf[512]; @@ -478,18 +501,18 @@ main(int argc, char *argv[]) S.sin_addr.s_addr = inet_addr("128.117.28.219"); sendto(s, buf, (size_t) offset, 0, (struct sockaddr *) &S, sizeof(S)); do { - fd_set R; - struct timeval to; + fd_set R; + struct timeval to; FD_ZERO(&R); FD_SET(s, &R); to.tv_sec = 10; to.tv_usec = 0; - rl = select(s+1, &R, NULL, NULL, &to); - } while(0); - if (rl < 1) { - printf("TIMEOUT\n"); - continue; - } + rl = select(s + 1, &R, NULL, NULL, &to); + } while (0); + if (rl < 1) { + printf("TIMEOUT\n"); + continue; + } memset(rbuf, '\0', 512); rl = recv(s, rbuf, 512, 0); { diff --git a/src/Makefile.in b/src/Makefile.in index c182b1ea1b..764ba77761 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -1,7 +1,7 @@ # # Makefile for the Squid Object Cache server # -# $Id: Makefile.in,v 1.168 1999/01/22 19:07:01 glenn Exp $ +# $Id: Makefile.in,v 1.169 1999/04/14 05:16:14 wessels Exp $ # # Uncomment and customize the following to suit your needs: # @@ -97,6 +97,7 @@ OBJS = \ @DELAY_OBJS@ \ disk.o \ dns.o \ + dns_internal.o \ errorpage.o \ ETag.o \ event.o \ diff --git a/src/dns.cc b/src/dns.cc index 792b772f62..eaf1968274 100644 --- a/src/dns.cc +++ b/src/dns.cc @@ -1,6 +1,6 @@ /* - * $Id: dns.cc,v 1.74 1999/01/17 19:46:28 wessels Exp $ + * $Id: dns.cc,v 1.75 1999/04/14 05:16:14 wessels Exp $ * * DEBUG: section 34 Dnsserver interface * AUTHOR: Harvest Derived @@ -47,6 +47,7 @@ dnsStats(StoreEntry * sentry) void dnsInit(void) { +#if USE_DNSSERVERS static int init = 0; wordlist *w; if (!Config.Program.dnsserver) @@ -70,6 +71,7 @@ dnsInit(void) dnsStats, 0, 1); } init++; +#endif } void diff --git a/src/dns_internal.cc b/src/dns_internal.cc new file mode 100644 index 0000000000..f2e332fdf3 --- /dev/null +++ b/src/dns_internal.cc @@ -0,0 +1,299 @@ + +/* + * $Id: dns_internal.cc,v 1.1 1999/04/14 05:16:15 wessels Exp $ + * + * DEBUG: section 78 DNS lookups; interacts with lib/rfc1035.c + * AUTHOR: Duane Wessels + * + * SQUID Internet Object Cache http://squid.nlanr.net/Squid/ + * ---------------------------------------------------------- + * + * Squid is the result of efforts by numerous individuals from the + * Internet community. Development is led by Duane Wessels of the + * National Laboratory for Applied Network Research and funded by the + * National Science Foundation. Squid is Copyrighted (C) 1998 by + * Duane Wessels and the University of California San Diego. Please + * see the COPYRIGHT file for full details. Squid incorporates + * software developed and/or copyrighted by other sources. Please see + * the CREDITS file for full details. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. + * + */ + +#include "squid.h" + +#ifndef _PATH_RESOLV_CONF +#define _PATH_RESOLV_CONF "/etc/resolv.conf" +#endif +#ifndef DOMAIN_PORT +#define DOMAIN_PORT 53 +#endif + +typedef struct _ns ns; +struct _ns { + struct sockaddr_in S; + int nqueries; + int nreplies; +}; +static ns *nameservers = NULL; +static int nns = 0; +static int nns_alloc = 0; +static int domain_socket = -1; +static dlink_list lru_list; + +static OBJH idnsStats; +static void idnsAddNameserver(const char *buf); +static void idnsFreeNameservers(void); +static void idnsParseResolvConf(void); +static void idnsSendQuery(idns_query * q); +static int idnsFromKnownNameserver(struct sockaddr_in *from); +static idns_query *idnsFindQuery(unsigned short id); +static void idnsGrokReply(const char *buf, size_t sz); +static PF idnsRead; + +static void +idnsAddNameserver(const char *buf) +{ + if (nns == nns_alloc) { + int oldalloc = nns_alloc; + ns *oldptr = nameservers; + if (nns_alloc == 0) + nns_alloc = 2; + else + nns_alloc <<= 1; + nameservers = xcalloc(nns_alloc, sizeof(*nameservers)); + if (oldptr && oldalloc) + xmemcpy(nameservers, oldptr, oldalloc * sizeof(*nameservers)); + if (oldptr) + safe_free(oldptr); + } + assert(nns < nns_alloc); + nameservers[nns].S.sin_family = AF_INET; + nameservers[nns].S.sin_port = htons(DOMAIN_PORT); + nameservers[nns].S.sin_addr.s_addr = inet_addr(buf); + debug(78, 1) ("idnsAddNameserver: Added nameserver #%d: %s\n", + nns, inet_ntoa(nameservers[nns].S.sin_addr)); + nns++; +} + +static void +idnsFreeNameservers(void) +{ + safe_free(nameservers); + nns = nns_alloc = 0; +} + +static void +idnsParseResolvConf(void) +{ + FILE *fp; + char buf[512]; + char *t; + fp = fopen(_PATH_RESOLV_CONF, "r"); + if (fp == NULL) { + debug(78, 1) ("%s: %s\n", _PATH_RESOLV_CONF, xstrerror()); + return; + } + idnsFreeNameservers(); + while (fgets(buf, 512, fp)) { + t = strtok(buf, w_space); + if (strcasecmp(t, "nameserver")) + continue; + t = strtok(NULL, w_space); + if (t == NULL) + continue;; + debug(78, 1) ("idnsParseResolvConf: nameserver %s\n", t); + idnsAddNameserver(t); + } + fclose(fp); +} + +static void +idnsStats(StoreEntry * sentry) +{ + storeAppendPrintf(sentry, "Internal DNS Statistics:\n"); +} + +static void +idnsSendQuery(idns_query * q) +{ + int x; + int ns = 0; + /* XXX Select nameserver */ + assert(nns > 0); + assert(q->lru.next == NULL); + assert(q->lru.prev == NULL); + x = comm_udp_sendto(domain_socket, + &nameservers[ns].S, + sizeof(nameservers[ns].S), + q->buf, + q->sz); + dlinkAdd(q, &q->lru, &lru_list); +} + +static int +idnsFromKnownNameserver(struct sockaddr_in *from) +{ + int i; + for (i = 0; i < nns; i++) { + if (nameservers[i].S.sin_addr.s_addr != from->sin_addr.s_addr) + continue; + if (nameservers[i].S.sin_port != from->sin_port) + continue; + return 1; + } + return 0; +} + +static idns_query * +idnsFindQuery(unsigned short id) +{ + dlink_node *n; + idns_query *q; + for (n = lru_list.tail; n; n = n->prev) { + q = n->data; + if (q->id == id) + return q; + } + return NULL; +} + +static void +idnsGrokReply(const char *buf, size_t sz) +{ + int n; + int valid; + rfc1035_rr *answers = NULL; + unsigned short rid = 0xFFFF; + idns_query *q; + n = rfc1035AnswersUnpack(buf, + sz, + &answers, + &rid); + debug(78, 1) ("idnsGrokReply: ID %#hx, %d answers\n", rid, n); + if (rid == 0xFFFF) { + debug(78, 1) ("idnsGrokReply: Unknown error\n"); + /* XXX leak answers? */ + return; + } + q = idnsFindQuery(rid); + if (q == NULL) { + debug(78, 1) ("idnsGrokReply: Didn't find query!\n"); + rfc1035RRDestroy(answers, n); + return; + } + if (n < 0) + debug(78, 1) ("idnsGrokReply: error %d\n", rfc1035_errno); + valid = cbdataValid(q->callback_data); + cbdataUnlock(q->callback_data); + if (valid) + q->callback(q->callback_data, answers, n); + rfc1035RRDestroy(answers, n); +} + +static void +idnsRead(int fd, void *data) +{ + ssize_t len; + struct sockaddr_in from; + socklen_t from_len; + int max = 10; + static char rbuf[512]; + commSetSelect(fd, COMM_SELECT_READ, idnsRead, NULL, 0); + while (max--) { + from_len = sizeof(from); + memset(&from, '\0', from_len); + Counter.syscalls.sock.recvfroms++; + len = recvfrom(fd, rbuf, 512, 0, (struct sockaddr *) &from, &from_len); + if (len == 0) + break; + if (len < 0) { + if (ignoreErrno(errno)) + break; +#ifdef _SQUID_LINUX_ + /* Some Linux systems seem to set the FD for reading and then + * return ECONNREFUSED when sendto() fails and generates an ICMP + * port unreachable message. */ + /* or maybe an EHOSTUNREACH "No route to host" message */ + if (errno != ECONNREFUSED && errno != EHOSTUNREACH) +#endif + debug(50, 1) ("idnsRead: FD %d recvfrom: %s\n", + fd, xstrerror()); + break; + } + debug(78, 1) ("idnsRead: FD %d: received %d bytes from %s.\n", + fd, + len, + inet_ntoa(from.sin_addr)); + if (!idnsFromKnownNameserver(&from)) { + debug(78, 1) ("idnsRead: Reply from unknown nameserver [%s]\n", + inet_ntoa(from.sin_addr)); + continue; + } + idnsGrokReply(rbuf, len); + } +} + +/* ====================================================================== */ + +void +idnsInit(void) +{ + static int init = 0; + if (domain_socket < 0) { + domain_socket = comm_open(SOCK_DGRAM, + 0, + Config.Addrs.udp_outgoing, + 0, + COMM_NONBLOCKING, + "DNS Socket"); + if (domain_socket < 0) + fatal("Could not create a DNS socket"); + debug(78, 1) ("DNS Socket created on FD %d\n", domain_socket); + commSetSelect(domain_socket, COMM_SELECT_READ, idnsRead, NULL, 0); + } + if (nns == 0) + idnsParseResolvConf(); + if (!init) { + cachemgrRegister("idns", + "Internal DNS Statistics", + idnsStats, 0, 1); + } + init++; +} + +void +idnsShutdown(void) +{ + if (domain_socket < 0) + return; + comm_close(domain_socket); + domain_socket = -1; +} + +void +idnsALookup(const char *name, IDNSCB * callback, void *data) +{ + idns_query *q = memAllocate(MEM_IDNS_QUERY); + q->sz = sizeof(q->buf); + q->id = rfc1035BuildAQuery(name, q->buf, &q->sz); + debug(78, 1) ("idnsSubmit: buf is %d bytes for %s, id = %#hx\n", + (int) q->sz, name, q->id); + q->callback = callback; + q->callback_data = data; + cbdataLock(q->callback_data); + idnsSendQuery(q); +} diff --git a/src/enums.h b/src/enums.h index 001748d32d..2bd92f2bca 100644 --- a/src/enums.h +++ b/src/enums.h @@ -1,6 +1,6 @@ /* - * $Id: enums.h,v 1.146 1999/03/29 16:52:04 wessels Exp $ + * $Id: enums.h,v 1.147 1999/04/14 05:16:15 wessels Exp $ * * * SQUID Internet Object Cache http://squid.nlanr.net/Squid/ @@ -553,6 +553,7 @@ typedef enum { MEM_SWAPDIR, MEM_USHORTLIST, MEM_WORDLIST, + MEM_IDNS_QUERY, MEM_MAX } mem_type; diff --git a/src/ipcache.cc b/src/ipcache.cc index 01dc789757..b0f08a82b6 100644 --- a/src/ipcache.cc +++ b/src/ipcache.cc @@ -1,6 +1,6 @@ /* - * $Id: ipcache.cc,v 1.210 1998/12/05 00:54:30 wessels Exp $ + * $Id: ipcache.cc,v 1.211 1999/04/14 05:16:16 wessels Exp $ * * DEBUG: section 14 IP Cache * AUTHOR: Harvest Derived @@ -50,12 +50,20 @@ static struct { static dlink_list lru_list; static FREE ipcacheFreeEntry; +#if USE_DNSSERVERS static HLPCB ipcacheHandleReply; +#else +static IDNSCB ipcacheHandleReply; +#endif static IPH dummy_handler; static int ipcacheExpiredEntry(ipcache_entry *); static int ipcache_testname(void); static ipcache_entry *ipcacheAddNew(const char *, const struct hostent *, ipcache_status_t); +#if USE_DNSSERVERS static ipcache_entry *ipcacheParse(const char *buf); +#else +static ipcache_entry *ipcacheParse(rfc1035_rr *, int); +#endif static ipcache_entry *ipcache_create(const char *name); static ipcache_entry *ipcache_get(const char *); static void ipcacheAddHostent(ipcache_entry *, const struct hostent *); @@ -254,6 +262,7 @@ ipcache_call_pending(ipcache_entry * i) ipcacheUnlockEntry(i); } +#if USE_DNSSERVERS static ipcache_entry * ipcacheParse(const char *inbuf) { @@ -323,9 +332,53 @@ ipcacheParse(const char *inbuf) i.addrs.count = (unsigned char) j; return &i; } +#else +static ipcache_entry * +ipcacheParse(rfc1035_rr * answers, int na) +{ + static ipcache_entry i; + memset(&i, '\0', sizeof(i)); + i.expires = squid_curtime; + i.status = IP_NEGATIVE_CACHED; + if (na < 0) { + debug(14, 1) ("ipcacheParse: Lookup failed\n"); + debug(14, 1) ("\trfc1035_errno = %d\n", rfc1035_errno); + assert(rfc1035_error_message); + i.error_message = xstrdup(rfc1035_error_message); + } else if (na == 0) { + debug(14, 1) ("ipcacheParse: No Address records\n"); + i.error_message = xstrdup("No Address records"); + } else { + int k; + int j; + assert(answers); + i.status = IP_CACHED; + i.expires = squid_curtime + answers->ttl; + i.addrs.in_addrs = xcalloc(na, sizeof(struct in_addr)); + i.addrs.bad_mask = xcalloc(na, sizeof(unsigned char)); + for (j = 0, k = 0; k < na; k++) { + if (answers[k].type != RFC1035_TYPE_A) + continue; + if (answers[k].class != RFC1035_CLASS_IN) + continue; + assert(answers[k].rdlength == 4); + xmemcpy(&i.addrs.in_addrs[j++], answers[k].rdata, 4); + debug(14, 1) ("ipcacheParse: #%d %s\n", + j - 1, + inet_ntoa(i.addrs.in_addrs[j - 1])); + } + i.addrs.count = (unsigned char) j; + } + return &i; +} +#endif static void +#if USE_DNSSERVERS ipcacheHandleReply(void *data, char *reply) +#else +ipcacheHandleReply(void *data, rfc1035_rr * answers, int na) +#endif { int n; generic_cbdata *c = data; @@ -337,7 +390,11 @@ ipcacheHandleReply(void *data, char *reply) c = NULL; n = ++IpcacheStats.replies; statHistCount(&Counter.dns.svc_time, tvSubMsec(i->request_time, current_time)); +#if USE_DNSSERVERS x = ipcacheParse(reply); +#else + x = ipcacheParse(answers, na); +#endif assert(x); i->status = x->status; i->addrs = x->addrs; @@ -420,7 +477,11 @@ ipcache_nbgethostbyname(const char *name, IPH * handler, void *handlerData) cbdataAdd(c, cbdataXfree, 0); i->status = IP_DISPATCHED; ipcacheLockEntry(i); +#if USE_DNSSERVERS dnsSubmit(i->name, ipcacheHandleReply, c); +#else + idnsALookup(i->name, ipcacheHandleReply, c); +#endif } /* initialize the ipcache */ diff --git a/src/main.cc b/src/main.cc index 98fca89944..a654cdafb5 100644 --- a/src/main.cc +++ b/src/main.cc @@ -1,6 +1,6 @@ /* - * $Id: main.cc,v 1.290 1999/01/24 04:03:52 wessels Exp $ + * $Id: main.cc,v 1.291 1999/04/14 05:16:17 wessels Exp $ * * DEBUG: section 1 Startup and Main Loop * AUTHOR: Harvest Derived @@ -320,6 +320,7 @@ mainReconfigure(void) snmpConnectionClose(); #endif dnsShutdown(); + idnsShutdown(); redirectShutdown(); authenticateShutdown(); storeDirCloseSwapLogs(); @@ -330,6 +331,7 @@ mainReconfigure(void) fqdncache_restart(); /* sigh, fqdncache too */ errorInitialize(); /* reload error pages */ dnsInit(); + idnsInit(); redirectInit(); authenticateInit(); serverConnectionsOpen(); @@ -406,6 +408,7 @@ mainInitialize(void) ipcache_init(); fqdncache_init(); dnsInit(); + idnsInit(); redirectInit(); authenticateInit(); useragentOpenLog(); @@ -594,6 +597,7 @@ main(int argc, char **argv) shutting_down = 1; serverConnectionsClose(); dnsShutdown(); + idnsShutdown(); redirectShutdown(); authenticateShutdown(); eventAdd("SquidShutdown", SquidShutdown, NULL, (double) (wait + 1), 1); diff --git a/src/mem.cc b/src/mem.cc index 690a51f137..953f279804 100644 --- a/src/mem.cc +++ b/src/mem.cc @@ -1,6 +1,6 @@ /* - * $Id: mem.cc,v 1.39 1999/01/21 23:15:37 wessels Exp $ + * $Id: mem.cc,v 1.40 1999/04/14 05:16:17 wessels Exp $ * * DEBUG: section 13 High Level Memory Pool Management * AUTHOR: Harvest Derived @@ -291,6 +291,8 @@ memInit(void) sizeof(helper_request), 0); memDataInit(MEM_HELPER_SERVER, "helper_server", sizeof(helper_server), 0); + memDataInit(MEM_IDNS_QUERY, "idns_query", + sizeof(idns_query), 0); /* test that all entries are initialized */ for (t = MEM_NONE, t++; t < MEM_MAX; t++) { if (MEM_DONTFREE == t) diff --git a/src/protos.h b/src/protos.h index 3ee9ae8534..09568f2b63 100644 --- a/src/protos.h +++ b/src/protos.h @@ -1,6 +1,6 @@ /* - * $Id: protos.h,v 1.315 1999/04/08 07:16:40 wessels Exp $ + * $Id: protos.h,v 1.316 1999/04/14 05:16:18 wessels Exp $ * * * SQUID Internet Object Cache http://squid.nlanr.net/Squid/ @@ -213,6 +213,11 @@ extern void dnsShutdown(void); extern void dnsInit(void); extern void dnsSubmit(const char *lookup, HLPCB * callback, void *data); +/* dns_internal.c */ +extern void idnsInit(void); +extern void idnsShutdown(void); +extern void idnsALookup(const char *, IDNSCB *, void *); + extern void eventAdd(const char *name, EVH * func, void *arg, double when, int); extern void eventAddIsh(const char *name, EVH * func, void *arg, double delta_ish, int); extern void eventRun(void); diff --git a/src/squid.h b/src/squid.h index d10383a553..bfbfcdb42d 100644 --- a/src/squid.h +++ b/src/squid.h @@ -1,6 +1,6 @@ /* - * $Id: squid.h,v 1.185 1999/01/19 17:41:04 wessels Exp $ + * $Id: squid.h,v 1.186 1999/04/14 05:16:19 wessels Exp $ * * AUTHOR: Duane Wessels * @@ -344,6 +344,7 @@ struct rusage { #endif #include "hash.h" +#include "rfc1035.h" #include "defines.h" #include "enums.h" diff --git a/src/structs.h b/src/structs.h index 875f7fd5c7..26d03bb2ca 100644 --- a/src/structs.h +++ b/src/structs.h @@ -1,6 +1,6 @@ /* - * $Id: structs.h,v 1.277 1999/04/07 21:39:06 wessels Exp $ + * $Id: structs.h,v 1.278 1999/04/14 05:16:20 wessels Exp $ * * * SQUID Internet Object Cache http://squid.nlanr.net/Squid/ @@ -1672,3 +1672,14 @@ struct _helper_server { struct _generic_cbdata { void *data; }; + +struct _idns_query { + char buf[512]; + size_t sz; + unsigned short id; + int nsends; + struct timeval start; + dlink_node lru; + IDNSCB *callback; + void *callback_data; +}; diff --git a/src/typedefs.h b/src/typedefs.h index 872c907a10..5fa163f975 100644 --- a/src/typedefs.h +++ b/src/typedefs.h @@ -1,6 +1,6 @@ /* - * $Id: typedefs.h,v 1.86 1999/01/29 23:39:25 wessels Exp $ + * $Id: typedefs.h,v 1.87 1999/04/14 05:16:20 wessels Exp $ * * * SQUID Internet Object Cache http://squid.nlanr.net/Squid/ @@ -161,6 +161,7 @@ typedef struct _helper helper; typedef struct _helper_server helper_server; typedef struct _helper_request helper_request; typedef struct _generic_cbdata generic_cbdata; +typedef struct _idns_query idns_query; #if SQUID_SNMP typedef variable_list *(oid_ParseFn) (variable_list *, snint *); @@ -204,6 +205,7 @@ typedef void SIGHDLR(int sig); typedef void STVLDCB(void *, int, int); typedef void HLPCB(void *, char *buf); typedef void HLPCMDOPTS(int *argc, char **argv); +typedef void IDNSCB(void *, rfc1035_rr *, int); typedef double hbase_f(double); typedef void StatHistBinDumper(StoreEntry *, int idx, double val, double size, int count);