⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dns_client_cache.c

📁 DNS 的实现代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    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 + -