]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
make fqdncache more like ipcache
authorwessels <>
Wed, 4 Sep 1996 00:50:37 +0000 (00:50 +0000)
committerwessels <>
Wed, 4 Sep 1996 00:50:37 +0000 (00:50 +0000)
- new parsebuffer()
- use ->expires instead of ->ttl

src/fqdncache.cc

index 16dc8462a2fa5bcca2b5ad6771bb0a97a374a503..d1e4614519b6a6b05135806016d8c023eae0d726 100644 (file)
@@ -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],