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; }
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; }