Beispiel #1
0
int dns_resolver(void *log_fp)
{
   DNODEPTR  h_entries;
   DNODEPTR  l_list = NULL;

   int       i;
   int       save_verbose=verbose;

   u_long    listEntries = 0;

   struct sigaction sigPipeAction;
   struct stat dbStat;
   struct tms  mytms;
   /* aligned dnsRecord to prevent Solaris from doing a dump */
   /* (not found in debugger, as it can dereference it :(    */
   struct dnsRecord alignedRecord;

   struct    flock tmp_flock;

   tmp_flock.l_whence=SEEK_SET;    /* default flock fields */
   tmp_flock.l_start=0;
   tmp_flock.l_len=0;
   tmp_flock.l_pid=0;

   time(&runtime);
   start_time = times(&mytms);   /* get start time */

   /* minimal sanity check on it */
   if(stat(dns_cache, &dbStat) < 0)
   {
      if(errno != ENOENT)
      {
         dns_cache=NULL;
         dns_db=NULL; return 0;  /* disable cache */
      }
   }
   else
   {
      if(!dbStat.st_size)  /* bogus file, probably from a crash */
      {
         unlink(dns_cache);  /* remove it so we can recreate... */
      }
   }
  
   /* open cache file */
   if(!(dns_db = dbopen(dns_cache, O_RDWR|O_CREAT, 0664, DB_HASH, NULL)))
   {
      /* Error: Unable to open DNS cache file <filename> */
      if (verbose) fprintf(stderr,"%s %s\n",msg_dns_nodb,dns_cache);
      dns_cache=NULL;
      dns_db=NULL;
      return 0;                  /* disable cache */
   }

   /* get file descriptor */
   dns_fd = dns_db->fd(dns_db);

   tmp_flock.l_type=F_WRLCK;                    /* set read/write lock type */
   if (fcntl(dns_fd,F_SETLK,&tmp_flock) < 0)    /* and barf if we cant lock */
   {
      /* Error: Unable to lock DNS cache file <filename> */
      if (verbose) fprintf(stderr,"%s %s\n",msg_dns_nolk,dns_cache);
      dns_db->close(dns_db);
      dns_cache=NULL;
      dns_db=NULL;
      return 0;                  /* disable cache */
   }

   /* Setup signal handlers */
   sigPipeAction.sa_handler = SIG_IGN;
   sigPipeAction.sa_flags   = SA_RESTART;
   sigemptyset(&sigPipeAction.sa_mask);

   sigaction(SIGPIPE, &sigPipeAction, NULL);

   /* disable warnings/errors for this run... */
   verbose=0;

   /* Main loop to read log records (either regular or zipped) */
   while ( (gz_log)?(our_gzgets((gzFile)log_fp,buffer,BUFSIZE) != Z_NULL):
           (fgets(buffer,BUFSIZE,log_fname?(FILE *)log_fp:stdin) != NULL))
   {
      if (strlen(buffer) == (BUFSIZE-1))
      {
         /* get the rest of the record */
         while ( (gz_log)?(our_gzgets((gzFile)log_fp,buffer,BUFSIZE)!=Z_NULL):
                 (fgets(buffer,BUFSIZE,log_fname?(FILE *)log_fp:stdin)!=NULL))
         {
            if (strlen(buffer) < BUFSIZE-1) break;
         }
         continue;                        /* go get next record if any    */
      }

      memset(tmp_buf, 0, sizeof(tmp_buf));
      strncpy(tmp_buf, buffer, sizeof(tmp_buf)-1);            /* save buffer in case of error */
      if(parse_record(buffer))            /* parse the record             */
      {
         if((log_rec.addr.s_addr = inet_addr(log_rec.hostname)) != INADDR_NONE)
         {
            DBT q, r;
            q.data = log_rec.hostname;
            q.size = strlen(log_rec.hostname);
		
            switch((dns_db->get)(dns_db, &q, &r, 0))
            {
               case -1: break;  /* Error while retrieving .. just ignore     */
               case 1:          /* No record on file, queue up for resolving */
               {
                  put_dnode(log_rec.hostname,
                            &log_rec.addr,
                            host_table);
                  break;
               }

               case 0: /* We have a record for this address */
               {
                  memcpy(&alignedRecord, r.data, sizeof(struct dnsRecord));
                  if((runtime - alignedRecord.timeStamp ) < DNS_CACHE_TTL)
                  {
                     if(!alignedRecord.numeric)  /* It is a name. Do nothing */
                        break;
                     /* otherise, it a number.. fall through */
                  }
                  else
                  {
                     /* queue up stale entry for retrieval */
                     put_dnode(log_rec.hostname,
                               &log_rec.addr,
                               host_table);
                     break;
                  }
               }
            }
         }
      }
   }
   verbose = save_verbose;     /* restore verbosity level... */

   listEntries = 0;
  
   /* build our linked list l_list  */
   for(i=0;i < MAXHASH; i++)
   {
      for(h_entries=host_table[i]; h_entries ; h_entries = h_entries->next)
      {
         h_entries->llist = l_list;
         l_list = h_entries;
         listEntries++;
      }
   }

   if(!l_list)
   {
      /* No valid addresses found... */
      if (verbose>1) printf("%s\n",msg_dns_none);
      tmp_flock.l_type=F_UNLCK;
      fcntl(dns_fd, F_SETLK, &tmp_flock);
      dns_db->close(dns_db);
      return 0;
   }

   /* process our list now... */
   process_list(l_list);

   /* display timing totals ? */
   end_time = times(&mytms);              /* display timing totals?   */
   if (time_me || (verbose>1))
   {
      if (verbose<2 && time_me) printf("DNS: ");
      printf("%lu %s ",listEntries, msg_addresses);

      /* get processing time (end-start) */
      temp_time = (float)(end_time-start_time)/CLK_TCK;
      printf("%s %.2f %s", msg_in, temp_time, msg_seconds);

      /* calculate records per second */
      if (temp_time)
         i=( (int)((float)listEntries/temp_time) );
      else i=0;

      if ( (i>0) && (i<=listEntries) ) printf(", %d/sec\n", i);
         else  printf("\n");
   }

   /* processing done, exit   */
   tmp_flock.l_type=F_UNLCK;
   fcntl(dns_fd, F_SETLK, &tmp_flock);
   dns_db->close(dns_db);
   return 0;

}
Beispiel #2
0
int dns_resolver(void *log_fp)
{
   DNODEPTR  h_entries;
   DNODEPTR  l_list = NULL;

   int       i;
   int       save_verbose=verbose;

   u_int64_t listEntries = 0;

   struct sigaction sigPipeAction;
   struct stat dbStat;
   /* aligned dnsRecord to prevent Solaris from doing a dump */
   /* (not found in debugger, as it can dereference it :(    */
   struct dnsRecord alignedRecord;

   struct    flock tmp_flock;

   tmp_flock.l_whence=SEEK_SET;    /* default flock fields */
   tmp_flock.l_start=0;
   tmp_flock.l_len=0;
   tmp_flock.l_pid=0;

   time(&runtime);

   /* get processing start time */
   start_time = time(NULL);

   /* minimal sanity check on it */
   if(stat(dns_cache, &dbStat) < 0)
   {
      if(errno != ENOENT)
      {
         dns_cache=NULL;
         dns_db=NULL; return 0;  /* disable cache */
      }
   }
   else
   {
      if(!dbStat.st_size)  /* bogus file, probably from a crash */
      {
         unlink(dns_cache);  /* remove it so we can recreate... */
      }
   }
  
   /* open cache file */
   if ( (db_create(&dns_db, NULL, 0) != 0)   ||
        (dns_db->open(dns_db, NULL,
           dns_cache, NULL, DB_HASH,
           DB_CREATE, 0644) != 0) )
   {
      /* Error: Unable to open DNS cache file <filename> */
      if (verbose) fprintf(stderr,"%s %s\n",msg_dns_nodb,dns_cache);
      dns_cache=NULL;
      dns_db=NULL;
      return 0;                  /* disable cache */
   }

   /* get file descriptor */
   dns_db->fd(dns_db, &dns_fd);

   tmp_flock.l_type=F_WRLCK;                    /* set read/write lock type */
   if (fcntl(dns_fd,F_SETLK,&tmp_flock) < 0)    /* and barf if we cant lock */
   {
      /* Error: Unable to lock DNS cache file <filename> */
      if (verbose) fprintf(stderr,"%s %s\n",msg_dns_nolk,dns_cache);
      dns_db->close(dns_db, 0);
      dns_cache=NULL;
      dns_db=NULL;
      return 0;                  /* disable cache */
   }

   /* Setup signal handlers */
   sigPipeAction.sa_handler = SIG_IGN;
   sigPipeAction.sa_flags   = SA_RESTART;
   sigemptyset(&sigPipeAction.sa_mask);

   sigaction(SIGPIPE, &sigPipeAction, NULL);

   /* disable warnings/errors for this run... */
   verbose=0;

   /* Main loop to read log records (either regular or zipped) */
   while ( ourget(buffer,BUFSIZE,our_fp) != NULL)
   {
	  int len = strlen(buffer);
      if (len == (BUFSIZE-1))
      {
         /* get the rest of the record */
         while ( ourget(buffer,BUFSIZE,our_fp) != NULL)
         {
		 	len = strlen(buffer);
            if (len < BUFSIZE-1) break;
         }
         continue;                        /* go get next record if any    */
      }

      strcpy(tmp_buf, buffer);            /* save buffer in case of error */
      if(parse_record(buffer, len))       /* parse the record             */
      {
         struct addrinfo hints, *ares;
         memset(&hints, 0, sizeof(hints));
         hints.ai_family   = AF_UNSPEC;
         hints.ai_socktype = SOCK_STREAM;
         hints.ai_flags    = AI_NUMERICHOST;
         if (0 == getaddrinfo(log_rec.hostname, "0", &hints, &ares))
         {
            DBT q, r;
            memset(&q, 0, sizeof(q));
            memset(&r, 0, sizeof(r));
            q.data = log_rec.hostname;
            q.size = log_rec.hnamelen;

            /* Check if we have it in DB */
            if ( (i=dns_db->get(dns_db, NULL, &q, &r, 0)) == 0 )
            {
               /* have a record for this address */
               memcpy(&alignedRecord, r.data, sizeof(struct dnsRecord));
               if (alignedRecord.timeStamp != 0)
                  /* If it's not permanent, check if it's TTL has expired */
                  if ( (runtime-alignedRecord.timeStamp ) > (86400*cache_ttl) )
                     put_dnode(log_rec.hostname, log_rec.hnamelen, ares->ai_addr,
                               ares->ai_addrlen,  host_table);
            }
            else
            {
               if (i==DB_NOTFOUND)
                   put_dnode(log_rec.hostname, log_rec.hnamelen, ares->ai_addr,
                             ares->ai_addrlen, host_table);
            }
            freeaddrinfo(ares);
         }
      }
   }
   verbose = save_verbose;     /* restore verbosity level... */

   listEntries = 0;
  
   /* build our linked list l_list  */
   for(i=0;i < MAXHASH; i++)
   {
      for(h_entries=host_table[i]; h_entries ; h_entries = h_entries->next)
      {
         h_entries->llist = l_list;
         l_list = h_entries;
         listEntries++;
      }
   }

   if(!l_list)
   {
      /* No valid addresses found... */
      if (verbose>1) printf("%s\n",msg_dns_none);
      tmp_flock.l_type=F_UNLCK;
      fcntl(dns_fd, F_SETLK, &tmp_flock);
      dns_db->close(dns_db, 0);
      return 0;
   }

   /* process our list now... */
   process_list(l_list);

   /* get processing end time */
   end_time = time(NULL);

   /* display DNS processing statistics */
   if (time_me || (verbose>1))
   {
      if (verbose<2 && time_me) printf("DNS: ");
      printf("%llu %s ",listEntries, msg_addresses);

      /* total processing time in seconds */
      temp_time = difftime(end_time,start_time);
      if (temp_time==0) temp_time=1;
      printf("%s %.0f %s", msg_in, temp_time, msg_seconds);

      /* calculate records per second */
      if (temp_time)
         i=( (int)((float)listEntries/temp_time) );
      else i=0;

      if ( (i>0) && (i<=listEntries) ) printf(", %d/sec\n", i);
         else  printf("\n");
   }

   /* processing done, exit   */
   tmp_flock.l_type=F_UNLCK;
   fcntl(dns_fd, F_SETLK, &tmp_flock);
   dns_db->close(dns_db, 0);
   return 0;

}