?? resolv.c
字號(hào):
dns_caught_signal = 0;#if USE_UCIP_DIRECT timerTempSeconds(10,dns_timeout,(void*)fd); i=udpRead(fd,UNCACHED(packet),PACKETSZ);#else oldalarm = alarm(REPLY_TIMEOUT); oldhandler = signal(SIGALRM, dns_catch_signal); i=read(fd, packet, PACKETSZ); alarm(0); signal(SIGALRM, oldhandler); alarm(oldalarm);#endif if (dns_caught_signal) { /* timed out, so retry send and receive, to next nameserver on queue */ RESOLVDEBUG(("query timed out, retrying\n")); goto again; }#if USE_UCIP_DIRECT else timerCancel(dns_timeout,(void*)fd);#endif if (i < HFIXEDSZ) { /* too short ! */ goto again; } decode_header(packet, &h); RESOLVDEBUG(("id = %d, qr = %d\n", h.id, h.qr)); if ((h.id != id) || (!h.qr)) { /* unsolicited */ goto again; } RESOLVDEBUG(("Got response %s\n", "(i think)!")); RESOLVDEBUG(("qrcount=%d,ancount=%d,nscount=%d,arcount=%d\n", h.qdcount, h.ancount, h.nscount, h.arcount)); RESOLVDEBUG(("opcode=%d,aa=%d,tc=%d,rd=%d,ra=%d,rcode=%d\n", h.opcode, h.aa, h.tc, h.rd, h.ra, h.rcode)); if ((h.rcode) || (h.ancount < 1)) { /* negative result, not present */ goto again; } pos = HFIXEDSZ; for (j = 0; j < h.qdcount; j++) { RESOLVDEBUG(("Skipping question %d at %d\n", j, pos)); i = length_question(packet, pos); RESOLVDEBUG(("Length of question %d is %d\n", j, i)); if (i < 0) goto again; pos += i; } RESOLVDEBUG(("Decoding answer at pos %d\n", pos)); for (j=0;j<h.ancount;j++) { i = decode_answer(packet, pos, &tmpA); printf("dns_lookup:tmpA.dotted=%p\n",tmpA.dotted); if (i<0) { RESOLVDEBUG(("failed decode %d\n", i)); goto again; } /* For all but T_SIG, accept first answer */// if (a->atype != T_SIG)// break; //++cg[6/2/2001]: better search of the answers - prefer host address (type 1) // answers over other answers if possible. if(a->atype==0) { *a=tmpA; }else if(tmpA.atype==T_A){ free(a->dotted); *a=tmpA; } if(tmpA.atype==T_A) break; if(tmpA.atype==T_SIG) free(a->dotted); pos += i; } RESOLVDEBUG(("Answer name = |%s|\n", a->dotted)); RESOLVDEBUG(("Answer type = |%d|\n", a->atype));#if USE_UCIP_DIRECT udpClose(fd);#else close(fd);#endif if (outpacket) *outpacket = packet; else free(packet); printf("dns_lookup (end):a->dotted=%p\n",a->dotted); return (0); /* success! */tryall: /* if there are other nameservers, give them a go, otherwise return with error */ variant = 0; if (retries >= nscount*(searchdomains+1)) goto fail;again: /* if there are searchdomains, try them or fallback as passed */ if (variant < searchdomains) { /* next search */ variant++; } else { /* next server, first search */ ns = (ns + 1) % nscount; variant = 0; }}fail: if (fd != -1)#if USE_UCIP_DIRECT udpClose(fd);#else close(fd);#endif if (lookup) free(lookup); if (packet) free(packet); return -1;}#endif#ifdef L_resolveaddressint resolve_address(const char *address, int nscount, char **nsip, struct in_addr *in){ unsigned char *packet; struct resolv_answer a; char temp[256]; int i; int nest = 0; if (!address || !in) return -1; strncpy(temp, address, sizeof(temp)); for (;;) { i = dns_lookup(temp, T_A, nscount, nsip, &packet, &a); printf("resolve_address: a.dotted=%p\n",a.dotted); if (i < 0) return -1; free(a.dotted); if (a.atype == T_CNAME) { /* CNAME */ i = decode_dotted(packet, a.rdoffset, temp, sizeof(temp)); free(packet); if (i < 0) return -1; if (++nest > MAX_RECURSE) return -1; continue; } else if (a.atype == T_A) { /* ADDRESS */ free(packet); break; } else { free(packet); return -1; } } if (in) memcpy(in, a.rdata, INADDRSZ); /* IPv4 T_A */ return 0;}#endif#ifdef L_resolvemailboxint resolve_mailbox(const char *address, int nscount, char **nsip, struct in_addr *in){ struct resolv_answer a; unsigned char *packet; char temp[256]; int nest = 0; int i; if (!address || !in) return -1; /* look up mail exchange */ i = dns_lookup(address, T_MX, nscount, nsip, &packet, &a); strncpy(temp, address, sizeof(temp)); if (i >= 0) { i = decode_dotted(packet, a.rdoffset+2, temp, sizeof(temp)); free(packet); } for (;;) { i = dns_lookup(temp, T_A, nscount, nsip, &packet, &a); if (i < 0) return -1; free(a.dotted); if (a.atype == T_CNAME) { /* CNAME */ i = decode_dotted(packet, a.rdoffset, temp, sizeof(temp)); free(packet); if (i < 0) return i; if (++nest > MAX_RECURSE) return -1; continue; } else if (a.atype == T_A) { /* ADDRESS */ free(packet); break; } else { free(packet); return -1; } } if (in) memcpy(in, a.rdata, INADDRSZ); /* IPv4 */ return 0;}#endifextern int nameservers;extern char * nameserver[MAX_SERVERS];extern int searchdomains;extern const char * searchdomain[MAX_SEARCH];#ifdef L_opennameservers#if (USE_RESOLV_CONF==0)/** Number of nameservers to search */int nameservers=2;/** Array of nameserver address's */char * nameserverList[]={ "195.184.228.6", "195.184.228.7"};char *nameserver[MAX_SERVERS];/** Number of search domains */int searchdomains=1;/** Array of search domains */const char *searchdomain[]={ "data-uncertain.co.uk"};#elseint nameservers=0;const char * nameserver[MAX_SERVERS];int searchdomains=0;const char * searchdomain[MAX_SEARCH];#endif#if USE_RESOLV_CONF#error "Reading the nameservers from /etc/resolv.conf doesn't work as I've not included cfgfind() in the build yet."int open_nameservers(){ FILE *fp; int i; if (nameservers > 0) return 0; RESOLVDEBUG(("open_nameservers() [using /etc/resolv.conf]\n")); // Nameservers from configuration file if ((fp = fopen("/etc/resolv.conf", "r"))) { if (0 != (arg = cfgfind(fp, "nameserver"))) { for (i=1; arg[i] && nameservers <= MAX_SERVERS; i++) { nameserver[nameservers++] = strdup(arg[i]); RESOLVDEBUG(("adding nameserver %s\n",arg[i])); } } if (0 != (arg = cfgfind(fp, "search"))) { for (i=1; arg[i] && searchdomains <= MAX_SEARCH; i++) { searchdomain[searchdomains++] = strdup(arg[i]); RESOLVDEBUG(("adding search %s\n",arg[i])); } } fclose(fp); } else { RESOLVDEBUG(("failed to open %s\n", "resolv.conf")); } RESOLVDEBUG(("nameservers = %d\n", nameservers)); return 0;}#endif#endif#ifdef L_closenameserversvoid close_nameservers(void){ while (nameservers > 0) free((void*)nameserver[--nameservers]);}#endif#ifdef L_resolvenameconst char *resolve_name(const char *name, int mailbox){ struct in_addr in; int i; /* shortcut: is it a valid IP address to begin with? */ if (inet_aton(name, &in)) return name;#if USE_RESOLV_CONF open_nameservers();#endif RESOLVDEBUG(("looking up '%s', mailbox=%d, nameservers=%d\n", name, mailbox, nameservers)); if (mailbox) i = resolve_mailbox(name, nameservers, nameserver, &in); else i = resolve_address(name, nameservers, nameserver, &in); if (i < 0) return 0; RESOLVDEBUG(("success = '%s'\n", inet_ntoa(in))); return inet_ntoa(in);}#endif#include <pthread.h>pthread_mutex_t resolvLock;void resolvInit(void){ pthread_mutex_init(&resolvLock,NULL); nameservers=2; nameserver[0]=strdup(nameserverList[0]); nameserver[1]=strdup(nameserverList[1]);}/** * set nameservers * @param ns1 IP of primary nameserver * @param ns2 IP of secondary nameserver (or NULL if none) */void setNameServer(const char *ns1, const char *ns2){ if(nameserver[0]) free(nameserver[0]); if(nameserver[1]) free(nameserver[1]); nameservers=0; if(ns1) { nameserver[nameservers]=strdup(ns1); nameservers++; } if(ns2) { nameserver[nameservers]=strdup(ns2); nameservers++; }}#ifdef L_gethostbynametypedef struct { char *name; struct in_addr in; struct in_addr *addr_list[2]; struct hostent h;} DNS_CACHE;#define DNS_CACHE_MAX 10static int cachePtr=0;static DNS_CACHE cache[DNS_CACHE_MAX]={ {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}};struct hostent *gethostbyname(const char *name){ char namebuf[512]; struct hostent *rtn=NULL; unsigned char *packet; struct resolv_answer a; int i; int nest = 0; // do dns cache lookup... for(i=0; i<DNS_CACHE_MAX; i++) { if((cache[i].name)&&(!strcmp(name,cache[i].name))) { printf("gethostbyname(%s): got cached address in slot %d\n",name,i); return &cache[i].h; } } printf("gethostbyname(%s): uncached, requesting from DNS\n",name);#ifdef ISS_OS pthread_mutex_lock(&resolvLock);#endif RESOLVDEBUG(("gethostbyname()\n"));#if USE_RESOLV_CONF open_nameservers();#endif if (!name) { RESOLVDEBUG(("no name\n"));#ifdef ISS_OS pthread_mutex_unlock(&resolvLock);#endif return 0; } memset(&cache[cachePtr].h, 0, sizeof(cache[cachePtr].h)); cache[cachePtr].addr_list[0] = &cache[cachePtr].in; cache[cachePtr].addr_list[1] = 0; strcpy(namebuf, name); for (;;) { i = dns_lookup(namebuf, 1, nameservers, nameserver, &packet, &a); if (i < 0) {#ifdef ISS_OS pthread_mutex_unlock(&resolvLock);#endif return 0; } strncpy(namebuf, a.dotted, strlen(a.dotted)); printf("gethostbyname: a.dotted=%p\n",a); free(a.dotted); if (a.atype == T_CNAME) /* CNAME */ { i = decode_dotted(packet, a.rdoffset, namebuf, sizeof(namebuf)); free(packet); if (i < 0) {#ifdef ISS_OS pthread_mutex_unlock(&resolvLock);#endif return 0; } if (++nest > MAX_RECURSE) {#ifdef ISS_OS pthread_mutex_unlock(&resolvLock);#endif return 0; } continue; } else if (a.atype == T_A) { /* ADDRESS */ memcpy(&cache[cachePtr].in, a.rdata, sizeof(cache[cachePtr].in)); printf("dns lookup, got addres for %s, caching in slot %d\n",name,cachePtr); if(cache[cachePtr].name) free(cache[cachePtr].name); cache[cachePtr].name=strdup(name); cache[cachePtr].h.h_name = cache[cachePtr].name; cache[cachePtr].h.h_addrtype = AF_INET; cache[cachePtr].h.h_length = sizeof(cache[cachePtr].in); cache[cachePtr].h.h_addr_list = (char **) cache[cachePtr].addr_list; rtn=&cache[cachePtr].h; free(packet); if(++cachePtr==DNS_CACHE_MAX) cachePtr=0; break; } else { free(packet);#ifdef ISS_OS pthread_mutex_unlock(&resolvLock);#endif return 0; } }#ifdef ISS_OS pthread_mutex_unlock(&resolvLock);#endif return rtn;}#endif#ifdef L_gethostbyaddrstruct hostent *gethostbyaddr(const char *addr, size_t len, int type){ static struct hostent h; static char namebuf[256]; static struct in_addr in; static struct in_addr *addr_list[2]; unsigned char *packet; struct resolv_answer a; int i; int nest = 0; if (!addr || (len != sizeof(in)) || (type != AF_INET)) return 0; memcpy(&in.s_addr, addr, len);#if USE_RESOLV_CONF open_nameservers();#endif memset(&h, 0, sizeof(h)); addr_list[0] = ∈ addr_list[1] = 0; sprintf(namebuf, "%d.%d.%d.%d.in-addr.arpa", (in.s_addr >> 24) & 0xff, (in.s_addr >> 16) & 0xff, (in.s_addr >> 8) & 0xff, (in.s_addr >> 0) & 0xff); for (;;) { i = dns_lookup(namebuf, T_PTR, nameservers, nameserver, &packet, &a); if (i < 0) return 0; strncpy(namebuf, a.dotted, sizeof(namebuf)); free(a.dotted); if (a.atype == T_CNAME) { /* CNAME */ i = decode_dotted(packet, a.rdoffset, namebuf, sizeof(namebuf)); free(packet); if (i < 0) return 0; if (++nest > MAX_RECURSE) return 0; continue; } else if (a.atype == T_PTR) { /* ADDRESS */ i = decode_dotted(packet, a.rdoffset, namebuf, sizeof(namebuf)); free(packet); h.h_name = namebuf; h.h_addrtype = AF_INET; h.h_length = sizeof(in); h.h_addr_list = (char **) addr_list; break; } else { free(packet); return 0; } } return &h;}#endif
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -