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

📄 dns_client_cache.c

📁 DNS 的实现代码
💻 C
📖 第 1 页 / 共 5 页
字号:
            dns_free_rrlist(rrlist);            continue;        }        rcnt += cnt;        mrec.name =(char*) crec->r_data;        mrec.num = rcnt;        mrec.RR = rrlist;        mrec.ttl = crec->r_ttl;        mrec.auth = auth;        mrec.ns = 0;        install_matching_records(&mrec, type);        dns_free_rrlist(rrlist);    } }   /* end add_cname2cache() *//* * add_ptr2cache() * * a PTR query is where we have an IP address and request the host name for * that address.  the IP address is in a format used for the query and is * in the r_dname, domain name, section of the record, the host name is in * the r_data, or resource data section.  we first see if the host name * already exists in the list, if so we only replace it if the new data is * from an authority and the current is not. */static voidadd_ptr2cache(DnsRRec *record, int auth){    int    slot;    int    qtype;    struct sockaddr_storage ipaddr;    /*      * first we determine the family of the address and hence the type of     * the request we'll assign to the cache record      */    convert_addr_arpa(record->r_dname, &ipaddr);    if (ipaddr.__ss_family != AF_INET &&        ipaddr.__ss_family != AF_INET6)    {#ifdef DNS_DEBUG        dprintf("add_ptr2cache: queer reverse domain");#endif        return;    }    if (ipaddr.__ss_family == AF_INET)    {        qtype = QT_A;    }    else    {        qtype = QT_AAAA;    }    /*      * see if the host name is already in the list. if so, we only replace     * it if the new data is from an authority and you current data is not.     */    if ((slot = search_bynametype((char*)record->r_data, qtype)) >= 0) {        if ( !(auth && !hostRR[slot]->authoritive) )             return;    }    else         slot = get_slot();    if( slot == -1 )        return;    lowercase_copy(hostRR[slot]->ptr_name[0], record->r_dname);    lowercase_copy(hostRR[slot]->hostname, (char*)record->r_data);    hostRR[slot]->ipaddr[0] = ipaddr;    hostRR[slot]->used = hostRR[slot]->naddr = 1;    hostRR[slot]->nsflag = hostRR[slot]->cflag = hostRR[slot]->recursion = 0;    hostRR[slot]->authoritive = auth;    hostRR[slot]->ttl = record->r_ttl;    hostRR[slot]->init_time = timer_secs();    hostRR[slot]->type = qtype;}   /* end add_ptr2cache() *//*  * dns_add_AA2cache() * * here we look at the authority, or NS records, from the DNS reply.  most of * the time, probably always, a DNS reply that gives NS records will also give * address records for them in the additional records.  we look through the * NS records and see if there is an address record for it in the additional * records, if so we attempt to add it to our list.  we have to see if the  * data is currently in the cache, if so, then only replace it if this reply * is from an authoritive NS and the current data is not. */voiddns_add_AA2cache(DnsMsg *dmsg, int auth){    DnsRRec  *nsrec;    DnsRRec  *addrec;    int      num;    MatchRec mrec;    nsrec = dmsg->m_authoritys;    addrec = dmsg->m_additionals;    num = dmsg->m_dnshdr.naddrr;    while ( nsrec != NULL )     {        int type;                for (type = QT_A; type > 0;             type = (type == QT_A ? QT_AAAA : (type == QT_AAAA ? QT_A6 : -1)))        {                         mrec.match = find_num_match((char*)nsrec->r_data, addrec,  type);            if (mrec.match != 0)            {            /* if there is, see if the data is already in our list, if so             * we only replace the data if we are the authority and the current             * data is not.             */                if ((mrec.slot = search_bynametype((char*)nsrec->r_data,                                                    type)) >= 0)                 {                    if ( !(auth && !hostRR[mrec.slot]->authoritive) )                         continue;                                   }                else                    mrec.slot = get_slot();                                if( mrec.slot == -1 )                    return;                mrec.name = (char*)nsrec->r_data;                mrec.num = num;                mrec.RR = addrec;                mrec.ttl = nsrec->r_ttl;                mrec.auth = auth;                mrec.ns = 1;                if (install_matching_records(&mrec, type) < 0)                    continue;            }        }         nsrec = nsrec->r_next;    } }   /* end dns_add_AA2cache() */  /*  * search_bynametype -- *     This routine looks for a cache record of a particular type. *     Note, type of returned record will not necessarily match *     the requested type: the only restriction is that IPv4 and *     IPv6 types are not mixed. * * PARAMETERS *     name    - domain name to find *     type    - type of record (see above note) * * RETURNS  index of the position with a matching hostname, or *         -1 to indicate there wasn't one. */static intsearch_bynametype(IN const char *name, IN int type){    int   i;    char  copy[NAMEMAX+1];    BITS  now;    lowercase_copy(copy, name);    for (i = 0; i < DNS_RRMAXENTRYS; i++)     {        /*          * Skip records that don't contain a host name. This is possible     	 * if we cached a name error record for a PTR query.	     */        if (!hostRR[i] || hostRR[i]->hostname[0] == '\0')            continue;        /*         * About type: asking for address type (A, AAAA, A6) does         * not imply exact matching of types. Rather, we only require         * that IPv6 records not override IPv4 records.         * However, other record types, (CNAME), require exact         * type match.         */        switch (type)        {            case QT_A:                if (hostRR[i]->type == QT_AAAA ||                    hostRR[i]->type == QT_A6)                    continue;                break;            case QT_AAAA:            case QT_A6:                if (hostRR[i]->type == QT_A)                    continue;                break;            default:                if (hostRR[i]->type != type)                    continue;                break;        }                /*         * If we find a match, then great, but first we need to make         * sure the record is not past its time to live.  If the          * record is outdated, we free it and continue the search.         */        if (strcmp(hostRR[i]->hostname, copy) == 0)         {            now = timer_secs();            if ((now - hostRR[i]->init_time) > hostRR[i]->ttl)             {                free_slot(i);                continue;            }                return i;        }    }    return -1;}   /* end search_bynametype() *//*  * search_byname() * * this routine will just loop through the elements in the list.  we compare * the hostname to the name given.  all hostnames, and cnames, should be in * lower case in the list.  we force the input string to be so. * * return:  index of the position with a matching hostname, or *         -1 to indicate there wasn't one. */static intsearch_byname(const char *name){    int   i;    char  copy[NAMEMAX+1];    BITS  now;    lowercase_copy(copy, name);    for ( i = 0; i < DNS_RRMAXENTRYS; i++ ) {        /* skip records that don't contain a host name. this is possible	 * if we cached a name error record for a PTR query.	 */        if ( !hostRR[i] || hostRR[i]->hostname[0] == '\0' )            continue;        /*         * if we find a match, then great, but first we need to make         * sure the record is not past its time to live.  if the          * record is outdated, we free it, quit the search and return         * that we didn't find it.         */        if ( strcmp(hostRR[i]->hostname, copy) == 0 ) {            now = timer_secs();            if ((now - hostRR[i]->init_time) > hostRR[i]->ttl) {                free_slot(i);                break;            }                return i;        }    }    return -1;}   /* end search_byname() *//* * search_byaddr() *  * this routine will search the list for an IP address.  we get the address as * an inverted string, in the format used for DNS queries, for example: * IP = 12.23.34.55 would look like "55.34.23.12.in-addr.arpa". * we convert it back for the search.   * if there is more that one IP address with an entry we * search the list.  note that we need to verify that the record is not outdated * before we return it.  if its outdated we free that record and quit the search. * pab note: convertion of IPv6 ".ip6.int" and ".ip6.arpa" is also included. * * return:  index of the matching HostRecord, or *         -1 to indicate not found. */static intsearch_byaddr(const char *addr){    int    i, j;    struct sockaddr_storage ip;    BITS   now;    convert_addr_arpa(addr, &ip);    for ( i = 0; i < DNS_RRMAXENTRYS; i++ ) {        if ( !hostRR[i] )            continue;        /*          * search the list of IP addresses.  if we find a match, that's the         * one we're looking for.  first determine if its outdated and if         * so, free it and return we didn't find the information we were         * looking for.         */        for ( j = 0; j < hostRR[i]->naddr; j++ ) {            if ( SOCKEQUAL(&ip, &hostRR[i]->ipaddr[j]) ) {                now = timer_secs();                if ((now - hostRR[i]->init_time) > hostRR[i]->ttl) {                    free_slot(i);                    return -1;                }                    return i;            }        }    }    return -1;}   /* end search_byaddr() *//* * dns_flush_resolver_cache() * * this routine will release all entries in the cache. */voiddns_flush_resolver_cache(){    int i;    for ( i = 0; i < DNS_RRMAXENTRYS; i++ ) {        if ( !hostRR[i] )            continue;        else             free_slot(i);    }}   /* end dns_flush_resolver_cache() *//*  dns_flush_resolver_entry6 -- *     This routine searches for the entry with hostname matching name.   *     If an IPv6 entry is found the entry is freed. * * PARAMETERS *     name   - domain name of to flush *  * RETURNS *     n/a */voiddns_flush_resolver_entry6(IN const char *name){    int  index;    if ((index = search_bynametype(name, QT_AAAA)) >= 0)        free_slot(index);} /* end dns_flush_resolver_entry6() *//* * dns_flush_resolver_entry() * * this routine searches for the entry with hostname matching name.  if  * found the entry is freed. *  * pab note: this routine will not flush an IPv6 entry */voiddns_flush_resolver_entry(const char *name){    int  index;    if ((index = search_byname(name)) >= 0 &&         hostRR[index]->type != QT_AAAA &&        hostRR[index]->type != QT_A6)        free_slot(index);}   /* end dns_flush_resolver_entry() *//* * dns_flush_resolver_entry_ip() * * this routine searches for an entry by using an IP address.  if the entry * is found it is freed.  to use search_byaddr() it is necessary to invert the * IP address as would be done in a PTR query. */voiddns_flush_resolver_entry_ip(U32 ip){    char ipaddr[NAMEMAX+1];    int  index;    reverse_ip_addr(ip, ipaddr);    if ((index = search_byaddr(ipaddr)) >= 0)        free_slot(index);}   /* end dns_flush_resolver_entry_ip() *//* * dns_flush_resolver_entry_ip6 -- *     This routine searches for an entry by using an IPv6 address.   *     If the entry is found it is freed.  To use search_byaddr() it  *     is necessary to invert the IP address as would be done in a PTR query. * * PARAMETERS *     ip  - IPv6 address of entry to be flushed * * RETURNS *     n/a */voiddns_flush_resolver_entry_ip6(IN struct in6_addr *ip){    char                    ipaddr[NAMEMAX+1];    int                     index;    struct sockaddr_storage tmp;    data2sock(&tmp, ip);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -