📄 dns_resolv.c
字号:
close(child[i].inpipe[0]); close(child[i].outpipe[1]); /* get struct in_addr here */ while((size = read(child[i].outpipe[0], child_buf, MAXHOST))) { if(size < 0) { perror("read error"); exit(1); } else { if(debug_mode) printf("Child got work: %lx(%d)\n", *((unsigned long *)child_buf), size); if((res_ent = gethostbyaddr(child_buf, size, AF_INET))) { /* must be at least 4 chars */ if (strlen(res_ent->h_name)>3) { if(debug_mode) printf("Child got %s for %lx(%d), %d bytes\n", res_ent->h_name, *((unsigned long *)child_buf), size,strlen(res_ent->h_name)); /* If long hostname, take max domain name part */ if ((size = strlen(res_ent->h_name)) > MAXHOST-2) strcpy(child_buf,(res_ent->h_name+(size-MAXHOST+1))); else strcpy(child_buf, res_ent->h_name); size = strlen(child_buf); } else { if (debug_mode) printf("gethostbyaddr returned bad h_name!\n"); } } else { if(debug_mode) printf("gethostbyaddr returned NULL! (%d)\n",h_errno); } if (write(child[i].inpipe[1], child_buf, size) == -1) { perror("write error"); exit(1); } } } close(child[i].inpipe[1]); close(child[i].outpipe[0]); if(debug_mode) printf( "Child %d got closed input, shutting down\n", i); fflush(stdout); exit(0); } /* case 0 */ default: { child[i].pid = pid; child[i].flags = DNS_CHILD_READY|DNS_CHILD_RUNNING; nof_children++; close(child[i].inpipe[1]); close(child[i].outpipe[0]); set_fl(child[i].inpipe[0], O_NONBLOCK); } } } trav = l_list; while(nof_children) { static struct timeval selectTimeval; int res; int max_fd; FD_ZERO(&rd_set); max_fd = 0; if(raiseSigChild) { int pid; while((pid = waitpid(-1, NULL, WNOHANG)) > 0) { for(i=0;i<dns_children;i++) { if(child[i].pid == pid) { child[i].pid = 0; child[i].flags &= ~(DNS_CHILD_READY|DNS_CHILD_RUNNING); nof_children--; if(debug_mode) printf("Reaped Child %d\n", pid); break; } } } raiseSigChild--; continue; /* while, nof children has just changed */ } for(i=0;i<dns_children;i++) { if(child[i].flags & DNS_CHILD_RUNNING) /* Child is running */ { if(child[i].flags & DNS_CHILD_READY) { child[i].flags &= ~DNS_CHILD_READY; if(trav) /* something to resolve */ { if (write(child[i].outpipe[1], &(trav->addr.s_addr), sizeof(trav->addr.s_addr)) != -1) { /* We will watch this child */ child[i].cur = trav; FD_SET(child[i].inpipe[0], &rd_set); max_fd = MAX(max_fd, child[i].inpipe[0]); if(debug_mode) printf("Giving %s (%lx) to Child %d for resolving\n", child[i].cur->string, (unsigned long)child[i].cur->addr.s_addr, i); trav = trav->llist; } else /* write error */ { if(errno != EINTR) /* Could be a signal */ { perror("Could not write to pipe"); close(child[i].outpipe[1]); /* kill */ child[i].flags &= ~DNS_CHILD_RUNNING; /* child */ } } } else /* List is complete */ { close(child[i].outpipe[1]); /* Go away */ child[i].flags &= ~DNS_CHILD_RUNNING; /* Child is dead */ } } else { /* Look, the busy child... */ FD_SET(child[i].inpipe[0], &rd_set); max_fd = MAX(max_fd, child[i].inpipe[0]); } } } selectTimeval.tv_sec = 5; /* This stuff ticks in 5 second intervals */ selectTimeval.tv_usec = 0; switch(res = select(max_fd+1, &rd_set, NULL, NULL, &selectTimeval)) { case -1: { if(errno != EINTR) /* Could be a signal */ perror("Error in select"); break; } case 0: /* Timeout, just fall once through the child loop */ { if(debug_mode) printf("tick\n"); break; } default: { for(i=0; i< dns_children;i++) { if(!res) /* All file descriptors done */ break; if(FD_ISSET(child[i].inpipe[0], &rd_set)) { int size; res--; /* One less... */ if(debug_mode) printf("Work requested from Child %d\n", i); switch (size=read(child[i].inpipe[0], dns_buf, MAXHOST)) { case -1: { if(errno != EINTR) perror("Could not read from pipe"); break; } case 0: { /* EOF. Child has closed Pipe. It shouldn't have */ /* done that, could be an error or something. */ /* Reap it */ close(child[i].outpipe[1]); child[i].flags &= ~DNS_CHILD_RUNNING; if(debug_mode) printf("Child %d wants to be reaped\n", i); break; } default: { dns_buf[size] = '\0'; if(memcmp(dns_buf, &(child[i].cur->addr.s_addr), sizeof(child[i].cur->addr.s_addr))) { if(debug_mode) printf("Got a result (%d): %s -> %s\n", i, child[i].cur->string, dns_buf); db_put(child[i].cur->string, dns_buf, 0); } else { if(debug_mode) printf("Could not resolve (%d): %s\n", i, child[i].cur->string); /* db_put(child[i].cur->string,child[i].cur->string,1); */ } if(debug_mode) printf("Child %d back in task pool\n", i); /* Child is back in the task pool */ child[i].flags |= DNS_CHILD_READY; break; } } } } break; } } } return;}/*********************************************//* SET_FL - set flag on pipe FD *//*********************************************/void set_fl(int fd, int flags){ int val; /* get current flags */ if ((val=fcntl(fd, F_GETFL, 0)) < 0) if (verbose) fprintf(stderr,"set_fl F_GETFL error\n"); /* set them */ val |= flags; /* and write them back */ if ((val=fcntl(fd, F_SETFL, val)) < 0) if (verbose) fprintf(stderr,"set_fl F_SETFL error\n");}/*********************************************//* CLR_FL - clear flag on pipe FD *//*********************************************/void clr_fl(int fd, int flags){ int val; /* Get current flags */ if ((val=fcntl(fd, F_GETFL, 0)) < 0) if (verbose) fprintf(stderr,"clr_fl F_GETFL error\n"); /* set them */ val &= ~flags; /* and write them back */ if ((val=fcntl(fd, F_SETFL, val)) < 0) if (verbose) fprintf(stderr,"clr_fl F_SETFL error\n");}/*********************************************//* DB_PUT - put key/val in the cache db *//*********************************************/static void db_put(char *key, char *value, int numeric){ DBT k, v; struct dnsRecord *recPtr = NULL; int nameLen = strlen(value)+1; /* Align to multiple of eight bytes */ int recSize = (sizeof(struct dnsRecord)+nameLen+7) & ~0x7; /* make sure we have a db ;) */ if(dns_db) { if((recPtr = calloc(1, recSize))) { recPtr->timeStamp = runtime; recPtr->numeric = numeric; memcpy(&recPtr->hostName, value, nameLen); k.data = key; k.size = strlen(key); v.size = recSize; v.data = recPtr; if((dns_db->put)(dns_db, &k, &v, 0) < 0) if (verbose>1) fprintf(stderr,"db_put fail!\n"); free(recPtr); } }}/*********************************************//* SIGCHILD - raise our signal *//*********************************************/static void sigChild(int signum){ raiseSigChild++;}/*********************************************//* OPEN_CACHE - open our cache file RDONLY *//*********************************************/int open_cache(){ struct stat dbStat; 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; tmp_flock.l_type=F_RDLCK; /* double check filename was specified */ if(!dns_cache) { dns_db=NULL; return 0; } /* minimal sanity check on it */ if(stat(dns_cache, &dbStat) < 0) { if(errno != ENOENT) return 0; } 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_RDONLY, 0664, DB_HASH, NULL))) { /* Error: Unable to open DNS cache file <filename> */ if (verbose) fprintf(stderr,"%s %s\n",msg_dns_nodb,dns_cache); return 0; /* disable cache */ } /* get file descriptor */ dns_fd = dns_db->fd(dns_db); /* Get shared lock on cache file */ if (fcntl(dns_fd, F_SETLK, &tmp_flock) < 0) { if (verbose) fprintf(stderr,"%s %s\n",msg_dns_nolk,dns_cache); dns_db->close(dns_db); return 0; } return 1;}/*********************************************//* CLOSE_CACHE - close our RDONLY cache *//*********************************************/int close_cache(){ 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; tmp_flock.l_type=F_UNLCK; /* clear lock and close cache file */ fcntl(dns_fd, F_SETLK, &tmp_flock); dns_db->close(dns_db); return 1;}#endif /* USE_DNS */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -