From: wessels <> Date: Wed, 4 Sep 1996 00:50:37 +0000 (+0000) Subject: make fqdncache more like ipcache X-Git-Tag: SQUID_3_0_PRE1~5862 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e84703adde7a8d6cc0eadf15e4a55022146403d9;p=thirdparty%2Fsquid.git make fqdncache more like ipcache - new parsebuffer() - use ->expires instead of ->ttl --- diff --git a/src/fqdncache.cc b/src/fqdncache.cc index 16dc8462a2..d1e4614519 100644 --- a/src/fqdncache.cc +++ b/src/fqdncache.cc @@ -1,6 +1,6 @@ /* - * $Id: fqdncache.cc,v 1.13 1996/08/30 23:23:29 wessels Exp $ + * $Id: fqdncache.cc,v 1.14 1996/09/03 18:50:37 wessels Exp $ * * DEBUG: section 35 FQDN Cache * AUTHOR: Harvest Derived @@ -137,20 +137,14 @@ static struct { int ghba_calls; /* # calls to blocking gethostbyaddr() */ } FqdncacheStats; -typedef struct _line_entry { - char *line; - struct _line_entry *next; -} line_entry; - static int fqdncache_compareLastRef _PARAMS((fqdncache_entry **, fqdncache_entry **)); static int fqdncache_dnsHandleRead _PARAMS((int, dnsserver_t *)); -static int fqdncache_parsebuffer _PARAMS((char *buf, unsigned int offset, dnsserver_t *)); +static fqdncache_entry *fqdncache_parsebuffer _PARAMS((char *buf, dnsserver_t *)); static int fqdncache_purgelru _PARAMS((void)); static void fqdncache_release _PARAMS((fqdncache_entry *)); static fqdncache_entry *fqdncache_GetFirst _PARAMS((void)); static fqdncache_entry *fqdncache_GetNext _PARAMS((void)); static fqdncache_entry *fqdncache_create _PARAMS((void)); -static void free_lines _PARAMS((line_entry *)); static void fqdncache_add_to_hash _PARAMS((fqdncache_entry *)); static void fqdncache_call_pending _PARAMS((fqdncache_entry *)); static void fqdncache_call_pending_badname _PARAMS((int fd, FQDNH handler, void *)); @@ -290,7 +284,7 @@ static int fqdncacheExpiredEntry(f) return 0; if (f->status == FQDN_DISPATCHED) return 0; - if (f->ttl + f->timestamp > squid_curtime) + if (f->expires > squid_curtime) return 0; return 1; } @@ -405,13 +399,13 @@ static void fqdncache_add(name, f, hp, cached) if (f->name_count == FQDN_MAX_NAMES) break; } - f->lastref = f->timestamp = squid_curtime; + f->lastref = squid_curtime; f->status = FQDN_CACHED; - f->ttl = Config.positiveDnsTtl; + f->expires = squid_curtime + Config.positiveDnsTtl; } else { - f->lastref = f->timestamp = squid_curtime; + f->lastref = squid_curtime; f->status = FQDN_NEGATIVE_CACHED; - f->ttl = Config.negativeDnsTtl; + f->expires = squid_curtime + Config.negativeDnsTtl; } fqdncache_add_to_hash(f); } @@ -451,234 +445,83 @@ static void fqdncache_call_pending_badname(fd, handler, data) handler(fd, NULL, data); } -/* free all lines in the list */ -static void free_lines(line) - line_entry *line; -{ - line_entry *tmp; - - while (line) { - tmp = line; - line = line->next; - safe_free(tmp->line); - safe_free(tmp); - } -} - -/* scan through buffer and do a conversion if possible - * return number of char used */ -static int fqdncache_parsebuffer(buf, offset, dnsData) - char *buf; - unsigned int offset; +static fqdncache_entry *fqdncache_parsebuffer(inbuf, dnsData) + char *inbuf; dnsserver_t *dnsData; { - char *pos = NULL; - char *tpos = NULL; - char *endpos = NULL; - char *token = NULL; - char *tmp_ptr = NULL; - line_entry *line_head = NULL; - line_entry *line_tail = NULL; - line_entry *line_cur = NULL; + char *buf = xstrdup(inbuf); + char *token; + static fqdncache_entry f; + int k; int ipcount; int aliascount; - fqdncache_entry *f = NULL; - - - pos = buf; - while (pos < (buf + offset)) { - - /* no complete record here */ - if ((endpos = strstr(pos, "$end\n")) == NULL) { - debug(35, 2, "fqdncache_parsebuffer: DNS response incomplete.\n"); + debug(35, 5, "fqdncache_parsebuffer: parsing:\n%s", inbuf); + memset(&f, '\0', sizeof(fqdncache_entry)); + f.expires = squid_curtime + Config.positiveDnsTtl; + f.status = IP_DISPATCHED; + for (token = strtok(buf, w_space); token; token = strtok(NULL, w_space)) { + if (!strcmp(token, "$end")) { break; - } - line_head = line_tail = NULL; - - while (pos < endpos) { - /* add the next line to the end of the list */ - line_cur = xcalloc(1, sizeof(line_entry)); - - if ((tpos = memchr(pos, '\n', 4096)) == NULL) { - debug(35, 2, "fqdncache_parsebuffer: DNS response incomplete.\n"); - return -1; - } - *tpos = '\0'; - line_cur->line = xstrdup(pos); - debug(35, 7, "fqdncache_parsebuffer: %s\n", line_cur->line); - *tpos = '\n'; - - if (line_tail) - line_tail->next = line_cur; - if (line_head == NULL) - line_head = line_cur; - line_tail = line_cur; - line_cur = NULL; - - /* update pointer */ - pos = tpos + 1; - } - pos = endpos + 5; /* strlen("$end\n") */ - - /* - * At this point, the line_head is a linked list with each - * link node containing another line of the DNS response. - * Start parsing... - */ - if (strstr(line_head->line, "$alive")) { + } else if (!strcmp(token, "$alive")) { dnsData->answer = squid_curtime; - free_lines(line_head); - debug(35, 10, "fqdncache_parsebuffer: $alive succeeded.\n"); - } else if (strstr(line_head->line, "$fail")) { - /* - * The $fail messages look like: - * $fail host\n$message msg\n$end\n - */ - token = strtok(line_head->line, w_space); /* skip first token */ - if ((token = strtok(NULL, w_space)) == NULL) { - debug(35, 1, "fqdncache_parsebuffer: Invalid $fail?\n"); - } else { - line_cur = line_head->next; - f = dnsData->data; - f->lastref = f->timestamp = squid_curtime; - f->ttl = Config.negativeDnsTtl; - f->status = FQDN_NEGATIVE_CACHED; - if (line_cur && !strncmp(line_cur->line, "$message", 8)) - f->error_message = xstrdup(line_cur->line + 8); - dns_error_message = f->error_message; - fqdncache_call_pending(f); + } else if (!strcmp(token, "$fail")) { + if ((token = strtok(NULL, w_space)) == NULL) + fatal_dump("Invalid $fail"); + f.expires = squid_curtime + Config.negativeDnsTtl; + f.status = IP_NEGATIVE_CACHED; + } else if (!strcmp(token, "$message")) { + if ((token = strtok(NULL, "\n")) == NULL) + fatal_dump("Invalid $message"); + f.error_message = xstrdup(token); + } else if (!strcmp(token, "$name")) { + if ((token = strtok(NULL, w_space)) == NULL) + fatal_dump("Invalid $name"); + f.status = IP_CACHED; + } else if (!strcmp(token, "$h_name")) { + if ((token = strtok(NULL, w_space)) == NULL) + fatal_dump("Invalid $h_name"); + f.names[0] = xstrdup(token); + f.name_count = 1; + } else if (!strcmp(token, "$h_len")) { + if ((token = strtok(NULL, w_space)) == NULL) + fatal_dump("Invalid $h_len"); + } else if (!strcmp(token, "$ipcount")) { + if ((token = strtok(NULL, w_space)) == NULL) + fatal_dump("Invalid $ipcount"); + ipcount = atoi(token); + for (k = 0; k < ipcount; k++) { + if ((token = strtok(NULL, w_space)) == NULL) + fatal_dump("Invalid IP address"); } - free_lines(line_head); - } else if (strstr(line_head->line, "$name")) { - tmp_ptr = line_head->line; - /* skip the first token */ - token = strtok(tmp_ptr, w_space); - if ((token = strtok(NULL, w_space)) == NULL) { - debug(35, 0, "fqdncache_parsebuffer: Invalid OPCODE?\n"); - } else { - f = dnsData->data; - if (f->status != FQDN_DISPATCHED) { - debug(35, 0, "fqdncache_parsebuffer: DNS record already resolved.\n"); - } else { - f->lastref = f->timestamp = squid_curtime; - f->ttl = Config.positiveDnsTtl; - f->status = FQDN_CACHED; - - line_cur = line_head->next; - - /* get $h_name */ - if (line_cur == NULL || - !strstr(line_cur->line, "$h_name")) { - debug(35, 1, "fqdncache_parsebuffer: DNS record in invalid format? No $h_name.\n"); - /* abandon this record */ - break; - } - tmp_ptr = line_cur->line; - /* skip the first token */ - token = strtok(tmp_ptr, w_space); - tmp_ptr = NULL; - token = strtok(tmp_ptr, w_space); - f->names[0] = xstrdup(token); - f->name_count = 1; - - line_cur = line_cur->next; - - /* get $h_length */ - if (line_cur == NULL || - !strstr(line_cur->line, "$h_len")) { - debug(35, 1, "fqdncache_parsebuffer: DNS record in invalid format? No $h_len.\n"); - /* abandon this record */ - break; - } - tmp_ptr = line_cur->line; - /* skip the first token */ - token = strtok(tmp_ptr, w_space); - tmp_ptr = NULL; - token = strtok(tmp_ptr, w_space); - - line_cur = line_cur->next; - - /* get $ipcount */ - if (line_cur == NULL || - !strstr(line_cur->line, "$ipcount")) { - debug(35, 1, "fqdncache_parsebuffer: DNS record in invalid format? No $ipcount.\n"); - /* abandon this record */ - break; - } - tmp_ptr = line_cur->line; - /* skip the first token */ - token = strtok(tmp_ptr, w_space); - tmp_ptr = NULL; - token = strtok(tmp_ptr, w_space); - ipcount = atoi(token); - - /* get ip addresses */ - { - int k = 0; - line_cur = line_cur->next; - while (k < ipcount) { - if (line_cur == NULL) { - debug(35, 1, "fqdncache_parsebuffer: DNS record in invalid format? No $ipcount data.\n"); - break; - } - line_cur = line_cur->next; - k++; - } - } - - /* get $aliascount */ - if (line_cur == NULL || - !strstr(line_cur->line, "$aliascount")) { - debug(35, 1, "fqdncache_parsebuffer: DNS record in invalid format? No $aliascount.\n"); - /* abandon this record */ - break; - } - tmp_ptr = line_cur->line; - /* skip the first token */ - token = strtok(tmp_ptr, w_space); - tmp_ptr = NULL; - token = strtok(tmp_ptr, w_space); - aliascount = atoi(token); - - /* get aliases */ - { - int k = 0; - line_cur = line_cur->next; - while (k < aliascount) { - if (line_cur == NULL) { - debug(35, 1, "fqdncache_parsebuffer: DNS record in invalid format? No $aliascount data.\n"); - break; - } - if (f->name_count < FQDN_MAX_NAMES) - f->names[f->name_count++] = xstrdup(line_cur->line); - line_cur = line_cur->next; - k++; - } - } - fqdncache_call_pending(f); - debug(35, 10, "fqdncache_parsebuffer: $name succeeded.\n"); - } + } else if (!strcmp(token, "$aliascount")) { + if ((token = strtok(NULL, w_space)) == NULL) + fatal_dump("Invalid $aliascount"); + aliascount = atoi(token); + for (k = 0; k < aliascount; k++) { + if ((token = strtok(NULL, w_space)) == NULL) + fatal_dump("Invalid alias"); } - free_lines(line_head); + } else if (!strcmp(token, "$ttl")) { + if ((token = strtok(NULL, w_space)) == NULL) + fatal_dump("Invalid $ttl"); + f.expires = squid_curtime + atoi(token); } else { - free_lines(line_head); - debug(35, 1, "fqdncache_parsebuffer: Invalid OPCODE for DNS table?\n"); - return -1; + fatal_dump("Invalid dnsserver output"); } } - return (int) (pos - buf); + xfree(buf); + return &f; } - static int fqdncache_dnsHandleRead(fd, dnsData) int fd; dnsserver_t *dnsData; { - int char_scanned; int len; int svc_time; int n; fqdncache_entry *f = NULL; + fqdncache_entry *x = NULL; len = read(fd, dnsData->ip_inbuf + dnsData->offset, @@ -709,16 +552,19 @@ static int fqdncache_dnsHandleRead(fd, dnsData) n = FQDNCACHE_AV_FACTOR; FqdncacheStats.avg_svc_time = (FqdncacheStats.avg_svc_time * (n - 1) + svc_time) / n; - char_scanned = fqdncache_parsebuffer(dnsData->ip_inbuf, - dnsData->offset, - dnsData); - if (char_scanned > 0) { - /* update buffer */ - xmemcpy(dnsData->ip_inbuf, - dnsData->ip_inbuf + char_scanned, - dnsData->offset - char_scanned); - dnsData->offset -= char_scanned; - dnsData->ip_inbuf[dnsData->offset] = '\0'; + if ((x = fqdncache_parsebuffer(dnsData->ip_inbuf, dnsData)) == NULL) { + debug(35, 0, "fqdncache_dnsHandleRead: fqdncache_parsebuffer failed?!\n"); + } else { + dnsData->offset = 0; + dnsData->ip_inbuf[0] = '\0'; + f = dnsData->data; + f->name_count = x->name_count; + for (n = 0; n < f->name_count; n++) + f->names[n] = x->names[n]; + f->error_message = x->error_message; + f->status = x->status; + f->expires = x->expires; + fqdncache_call_pending(f); } } if (dnsData->offset == 0) { @@ -982,7 +828,7 @@ void fqdnStats(sentry) if (f->status == FQDN_PENDING || f->status == FQDN_DISPATCHED) ttl = 0; else - ttl = (f->ttl - squid_curtime + f->timestamp); + ttl = (f->expires - squid_curtime); storeAppendPrintf(sentry, " {%-32.32s %c %6d %d", f->name, fqdncache_status_char[f->status],