Changeset 3344


Ignore:
Timestamp:
Oct 14, 2010 7:22:04 AM (11 years ago)
Author:
bennylp
Message:

Misc (re #1134): fixed failure in resolving DNS A resolution if the answer contains more than one CNAME redirection before an A record is found (thanks Régis Montoya for the report)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjlib-util/src/pjlib-util/resolver.c

    r3298 r3344  
    842842                                            pj_dns_a_record *rec) 
    843843{ 
    844     pj_str_t hostname, alias, *res_name; 
     844    enum { MAX_SEARCH = 20 }; 
     845    pj_str_t hostname, alias = {NULL, 0}; 
    845846    unsigned bufstart = 0; 
    846847    unsigned bufleft = sizeof(rec->buf_); 
    847     unsigned i, ansidx; 
     848    unsigned i, ansidx, search_cnt=0; 
    848849 
    849850    PJ_ASSERT_RETURN(pkt && rec, PJ_EINVAL); 
     
    888889        return PJLIB_UTIL_EDNSNOANSWERREC; 
    889890 
    890     /* If hostname is a CNAME, get the alias. */ 
    891     if (pkt->ans[ansidx].type == PJ_DNS_TYPE_CNAME) { 
    892         alias = pkt->ans[ansidx].rdata.cname.name; 
    893         res_name = &alias; 
    894     } else if (pkt->ans[ansidx].type == PJ_DNS_TYPE_A) { 
    895         alias.ptr = NULL; 
    896         alias.slen = 0; 
    897         res_name = &hostname; 
    898     } else { 
     891    /* Keep following CNAME records. */ 
     892    while (pkt->ans[ansidx].type == PJ_DNS_TYPE_CNAME && 
     893           search_cnt++ < MAX_SEARCH) 
     894    { 
     895        if (!alias.slen) 
     896            alias = pkt->ans[ansidx].rdata.cname.name; 
     897 
     898        for (i=ansidx+1; i < pkt->hdr.anscount; ++i) { 
     899            if (pj_stricmp(&pkt->ans[ansidx].rdata.cname.name, 
     900                           &pkt->ans[i].name)==0) 
     901            { 
     902                break; 
     903            } 
     904        } 
     905 
     906        if (i==pkt->hdr.anscount) 
     907            return PJLIB_UTIL_EDNSINANSWER; 
     908 
     909        ansidx = i; 
     910    } 
     911 
     912    if (search_cnt >= MAX_SEARCH) 
    899913        return PJLIB_UTIL_EDNSINANSWER; 
    900     } 
     914 
     915    if (pkt->ans[ansidx].type != PJ_DNS_TYPE_A) 
     916        return PJLIB_UTIL_EDNSINANSWER; 
    901917 
    902918    /* Copy alias to the record, if present. */ 
     
    913929    } 
    914930 
    915     /* Now scan the answer for all type A RRs where the name matches 
    916      * hostname or alias. 
    917      */ 
    918     for (i=0; i<pkt->hdr.anscount; ++i) { 
    919         if (pkt->ans[i].type == PJ_DNS_TYPE_A && 
    920             pj_stricmp(&pkt->ans[i].name, res_name)==0 && 
    921             rec->addr_count < PJ_DNS_MAX_IP_IN_A_REC) 
    922         { 
    923             rec->addr[rec->addr_count].s_addr =  
    924                 pkt->ans[i].rdata.a.ip_addr.s_addr; 
    925             ++rec->addr_count; 
    926         } 
     931    /* Retrieve the IP address. */ 
     932    if (rec->addr_count < PJ_DNS_MAX_IP_IN_A_REC) { 
     933        rec->addr[rec->addr_count++].s_addr = 
     934            pkt->ans[i].rdata.a.ip_addr.s_addr; 
    927935    } 
    928936 
Note: See TracChangeset for help on using the changeset viewer.