📄 dns_client_cache.c
字号:
reverse_sockaddr_int(&tmp, ipaddr); if ((index = search_byaddr(ipaddr)) >= 0) free_slot(index);} /* end dns_flush_resolver_entry_ip6() *//* * dns_cache_init() * * set all elements of the host entry array to unused. */voiddns_cache_init(){ int i; for ( i = 0; i < DNS_RRMAXENTRYS; i++ ) { hostRR[i] = 0; }} /* end dns_cache_init() *//* * free_slot() * * this routine frees up a previously allocated RR slot */static voidfree_slot(int slot){ assert(hostRR[slot]); free(hostRR[slot]); hostRR[slot]=0;} /* end free_slot() *//* * convert_addr_arpa -- * This routine converts reversed IPv4 or IPv6 PTR domain into * sockaddr_storage structure. First we find out which family * the address belongs to. If it ends with ".in-addr.arpa" then * this is an IPv4 address. If it ends with ".ip6.int" then this * is an RFC 1886 IPv6 PTR domain. If it ends with ".ip6.arpa" then * this is an RFC 2874 IPv6 PTR domain. Otherwise we set the address * to nil and family to AF_INET. * * Note, in ip6.arpa we only support hexadecimal binary * labels. * * PARAMETERS * ptr - reversed domain address string * ip - storage for IP address * * RETURNS * n/a */void convert_addr_arpa(IN const char *ptr, OUT struct sockaddr_storage *ip){ char *tok, *s_tok; char dup[NAMEMAX + 1]; char suffix[NAMEMAX + 1]; int len; /* first we get two last labels of the domain */ strcpy(dup, ptr); /* suppress the trailing dot if it exists */ len = strlen(dup); if (dup[len - 1] == DOT) dup[len - 1] = '\0'; s_tok = strrchr(dup, DOT); *s_tok = '\0'; tok = strrchr(dup, DOT); tok++; /* skip the dot */ *s_tok = DOT; /* restore the dot */ lowercase_copy(suffix, tok); strcat(suffix, SDOT); if (strcmp(suffix, INADDR_ARPA) == 0) { long2sock(ip, convert_addr_ipv4(ptr)); return; } /* long2sock does memset(), so we do it here */ memset(ip, 0, sizeof(struct sockaddr_storage)); if (strcmp(suffix, IP6_INT) == 0) { int cnt; U8 *bytes = (U8 *)&((struct sockaddr_in6 *)ip)->sin6_addr; s_tok = dup; for(cnt = sizeof(struct in6_addr) - 1; cnt >= 0; cnt--) { int low, high; tok = strchr(s_tok, DOT); *tok++ = '\0'; sscanf(s_tok, "%x",&low); s_tok = tok; tok = strchr(s_tok, DOT); *tok++ = '\0'; sscanf(s_tok, "%x",&high); s_tok = tok; bytes[cnt] = (U8)(low + (high << 4)); } ip->__ss_family = AF_INET6; return; } if (strcmp(suffix, IP6_ARPA) == 0 && dup[0] == '\\' && dup[1] == '[' && dup[2] == 'x') { int cnt; U8 *bytes = (U8 *)&((struct sockaddr_in6 *)ip)->sin6_addr; tok = dup + 3; for (cnt = 0; cnt < (int)sizeof(struct in6_addr); cnt++) { char buf[3]; /* get first two digits */ buf[0] = *tok++; buf[1] = *tok++; buf[2] = '\0'; bytes[cnt] = atoi(buf); } ip->__ss_family = AF_INET6; return; } /* so, just set family to AF_INET */ ip->__ss_family = AF_INET;}/* * convert_addr_ipv4() * * this routine will take a string used for a PTR query, for example * something like "44.33.22.11.in-addr.arpa", and return the IP address * from it, which will be 11.22.33.44 in this case. */U32convert_addr_ipv4(const char *ptr){ U32 ipaddr = 0; char *tmp, *tok; char dup[NAMEMAX+1]; U8 *cptr = (U8 *)&ipaddr; strcpy(dup, ptr); tmp = strchr(dup, DOT); *tmp++ = '\0'; cptr[3] = atoi(dup); tok = strchr(tmp, DOT); *tok++ = '\0'; cptr[2] = atoi(tmp); tmp = strchr(tok, DOT); *tmp++ = '\0'; cptr[1] = atoi(tok); tok = strchr(tmp, DOT); *tok = '\0'; cptr[0] = atoi(tmp); return ipaddr;} /* end convert_addr_ipv4() *//* * copy_RR() * * this routine will copy one resource record structure to the other. */static intcopy_RR(DnsRRec *to, DnsRRec *from){ if ((to->r_data = dns_dalloc(from->r_datalen)) == NULL) { dprintf("%C allocation failure for data\n");#ifdef DNS_DEBUG print_resource_pool();#endif return -1; } memcpy(to->r_data, from->r_data, from->r_datalen); to->r_used = from->r_used; to->r_type = from->r_type; to->r_class = from->r_class; to->r_ttl = from->r_ttl; to->r_datalen = from->r_datalen; strcpy(to->r_dname, from->r_dname); return 0;} /* end copy_RR() *//* * add2listfrommatch() * * this routine will add or create a list of RRs. if the head is NULL it * will create a new list from matching records of the given list, list. * if the head is not NULL it'll add to the existing list. * * return: number RRs added to the list, or * -1 to indicate an error condition. */static intadd2listfrommatch(const char *domain, U16 type, DnsRRec **head, DnsRRec *list){ DnsRRec *save, *start, *rr, *rtmp; int num = 0; /* make sure there's something to do */ if ( find_num_match(domain, list, type) == 0) return num; /* * if head is null there's no list to start with. so we create the head of * the list and copy over the first matching record. the start pointer is * the start of the list we create here in case there is an error and we need * to delete the list we create. */ if ( NULL == *head ) { if ((*head = dns_get_RR()) == NULL) { dprintf("%C resource record allocation failed\n");#ifdef DNS_DEBUG print_resource_pool();#endif return -1; } if ((rr = find_match_rrecord(domain, list, type)) == NULL) { dprintf("%C error no match when there should be\n"); dns_free_RR(*head); *head = NULL; return -1; } if ( copy_RR(*head, rr) < 0 ) { dprintf("%C error copying RR\n"); return -1; } ++num; save = NULL; start = rtmp = *head; } /* * head is not null which means we need to add on to the end of the list. * we first find the end of the list. we set save to the last element of * the list in case there's an error and we remove the list we don't want * the end of the passed in list to be pointing off into space. */ else { rtmp = *head; while ( rtmp->r_next != NULL ) rtmp = rtmp->r_next; save = rtmp; if ((rtmp->r_next = dns_get_RR()) == NULL) { dprintf("%C resource record allocation failed\n");#ifdef DNS_DEBUG print_resource_pool();#endif return -1; } if ((rr = find_match_rrecord(domain, list, type)) == NULL) { dprintf("%C error no match when there should be\n"); return -1; } if ( copy_RR(rtmp->r_next, rr) < 0 ) { dprintf("%C error RR copy failed\n"); dns_free_RR(rtmp->r_next); return -1; } start = rtmp = rtmp->r_next; } while ((rr = find_match_rrecord(domain, rr->r_next, type)) != NULL) { if ((rtmp->r_next = dns_get_RR()) == NULL) { dprintf("%C resource record allocation failed\n");#ifdef DNS_DEBUG print_resource_pool();#endif dns_free_rrlist(start); if ( save != NULL ) save->r_next = NULL; return -1; } if ( copy_RR(rtmp->r_next, rr) < 0 ) { dprintf("%C error copying RR\n"); dns_free_rrlist(start); if ( save != NULL ) save->r_next = NULL; return -1; } ++num; rtmp = rtmp->r_next; } return num;} /* end add2listfrommatch() */ /* * create_RR_list() * * this routine will create a new list of resource records. it allocates the * r_data portion also based on the size passed to it. * * return: pointer to the start of the list or, * NULL if there is an error condition. */static DnsRRec *create_RR_list(int num, int size){ DnsRRec *rr, *head; int cnt; if ( num <= 0 ) /* nothing to do */ return NULL; /* allocate the head of the list and then the data space for the * record. */ if ((head = dns_get_RR()) == NULL) { dprintf("%C error allocating resource record\n");#ifdef DNS_DEBUG print_resource_pool();#endif return NULL; } if ((head->r_data = dns_dalloc(size)) == NULL) { dns_free_RR(head); dprintf("%C error allocating data memory\n");#ifdef DNS_DEBUG print_resource_pool();#endif return NULL; } /* okay now do the rest of the list, note that dns_get_RR() set the r_next * pointer to NULL so we don't have to do that for the last element. */ rr = head; for ( cnt = 1; cnt < num; cnt++ ) { if ((rr->r_next = dns_get_RR()) == NULL) { dns_free_rrlist(head); dprintf("%C error allocating RR memory\n");#ifdef DNS_DEBUG print_resource_pool();#endif return NULL; } if ((rr->r_next->r_data = dns_dalloc(size)) == NULL) { dns_free_rrlist(head); dprintf("%C error allocating data memory\n");#ifdef DNS_DEBUG print_resource_pool();#endif return NULL; } rr = rr->r_next; } return head;} /* end create_RR_list() *//* * print_hostrecord() * * this routine is used by list_cache() to print out elements of the host * record entry. */static voidprint_hostrecord(HostRecord *hr){ int i; BITS now, hlong; char ipaddr[INET6_ADDRSTRLEN]; printf("\n"); printf("Hostname %s\n", hr->hostname); if ( hr->cflag ) { printf("Name is an alias.\n"); printf("%s is the canonical name.\n", hr->cname); } now = timer_secs(); hlong = now - hr->init_time; if ( hlong > hr->ttl ) printf("Entry outdated.\n"); else printf("Entry has %d seconds to live.\n", hr->ttl - hlong); if ( hr->nsflag ) printf("This entry is for a Name Server.\n"); if ( hr->recursion ) printf("Recursion available.\n"); if ( hr->authoritive ) printf("Information received from an authoritive server.\n"); if ( hr->nerrflag ) printf("Negative Entry [type %s].\n", (hr->type == QT_A ? "A" : (hr->type == QT_AAAA ? "AAAA" : (hr->type == QT_A6 ? "A6" : "<unknown
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -