Ignore:
File:
1 edited

Legend:

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

    r5826 r4649  
    2020#include <pjlib-util/resolver.h> 
    2121#include <pjlib-util/errno.h> 
    22 #include <pj/compat/socket.h> 
    2322#include <pj/assert.h> 
    2423#include <pj/ctype.h> 
     
    8180struct nameserver 
    8281{ 
    83     pj_sockaddr     addr;               /**< Server address.                */ 
     82    pj_sockaddr_in  addr;               /**< Server address.                */ 
    8483 
    8584    enum ns_state   state;              /**< Nameserver state.              */ 
     
    170169    /* Internals */ 
    171170    pj_pool_t           *pool;          /**< Internal pool.                 */ 
    172     pj_grp_lock_t       *grp_lock;      /**< Group lock protection.         */ 
     171    pj_mutex_t          *mutex;         /**< Mutex protection.              */ 
    173172    pj_bool_t            own_timer;     /**< Do we own timer?               */ 
    174173    pj_timer_heap_t     *timer;         /**< Timer instance.                */ 
     
    181180    pj_ioqueue_key_t    *udp_key;       /**< UDP socket ioqueue key.        */ 
    182181    unsigned char        udp_rx_pkt[UDPSZ];/**< UDP receive buffer.         */ 
    183     unsigned char        udp_tx_pkt[UDPSZ];/**< UDP transmit buffer.        */ 
     182    unsigned char        udp_tx_pkt[UDPSZ];/**< UDP receive buffer.         */ 
     183    pj_ssize_t           udp_len;       /**< Length of received packet.     */ 
    184184    pj_ioqueue_op_key_t  udp_op_rx_key; /**< UDP read operation key.        */ 
    185185    pj_ioqueue_op_key_t  udp_op_tx_key; /**< UDP write operation key.       */ 
    186     pj_sockaddr          udp_src_addr;  /**< Source address of packet       */ 
     186    pj_sockaddr_in       udp_src_addr;  /**< Source address of packet       */ 
    187187    int                  udp_addr_len;  /**< Source address length.         */ 
    188  
    189 #if PJ_HAS_IPV6 
    190     /* IPv6 socket */ 
    191     pj_sock_t            udp6_sock;     /**< UDP socket.                    */ 
    192     pj_ioqueue_key_t    *udp6_key;      /**< UDP socket ioqueue key.        */ 
    193     unsigned char        udp6_rx_pkt[UDPSZ];/**< UDP receive buffer.        */ 
    194     //unsigned char      udp6_tx_pkt[UDPSZ];/**< UDP transmit buffer.       */ 
    195     pj_ioqueue_op_key_t  udp6_op_rx_key;/**< UDP read operation key.        */ 
    196     pj_ioqueue_op_key_t  udp6_op_tx_key;/**< UDP write operation key.       */ 
    197     pj_sockaddr          udp6_src_addr; /**< Source address of packet       */ 
    198     int                  udp6_addr_len; /**< Source address length.         */ 
    199 #endif 
    200188 
    201189    /* Settings */ 
     
    237225                                      unsigned servers[]); 
    238226 
    239 /* Destructor */ 
    240 static void dns_resolver_on_destroy(void *member); 
    241227 
    242228/* Close UDP socket */ 
     
    252238        resv->udp_sock = PJ_INVALID_SOCKET; 
    253239    } 
    254  
    255 #if PJ_HAS_IPV6 
    256     if (resv->udp6_key != NULL) { 
    257         pj_ioqueue_unregister(resv->udp6_key); 
    258         resv->udp6_key = NULL; 
    259         resv->udp6_sock = PJ_INVALID_SOCKET; 
    260     } else if (resv->udp6_sock != PJ_INVALID_SOCKET) { 
    261         pj_sock_close(resv->udp6_sock); 
    262         resv->udp6_sock = PJ_INVALID_SOCKET; 
    263     } 
    264 #endif 
    265240} 
    266241 
     
    270245{ 
    271246    pj_ioqueue_callback socket_cb; 
    272     pj_sockaddr bound_addr; 
    273     pj_ssize_t rx_pkt_size; 
    274247    pj_status_t status; 
    275248 
     
    287260    pj_bzero(&socket_cb, sizeof(socket_cb)); 
    288261    socket_cb.on_read_complete = &on_read_complete; 
    289     status = pj_ioqueue_register_sock2(resv->pool, resv->ioqueue, 
    290                                        resv->udp_sock, resv->grp_lock, 
    291                                        resv, &socket_cb, &resv->udp_key); 
     262    status = pj_ioqueue_register_sock(resv->pool, resv->ioqueue, 
     263                                      resv->udp_sock, resv, &socket_cb, 
     264                                      &resv->udp_key); 
    292265    if (status != PJ_SUCCESS) 
    293266        return status; 
     
    297270 
    298271    /* Start asynchronous read to the UDP socket */ 
    299     rx_pkt_size = sizeof(resv->udp_rx_pkt); 
     272    resv->udp_len = sizeof(resv->udp_rx_pkt); 
    300273    resv->udp_addr_len = sizeof(resv->udp_src_addr); 
    301274    status = pj_ioqueue_recvfrom(resv->udp_key, &resv->udp_op_rx_key, 
    302                                  resv->udp_rx_pkt, &rx_pkt_size, 
     275                                 resv->udp_rx_pkt, &resv->udp_len, 
    303276                                 PJ_IOQUEUE_ALWAYS_ASYNC, 
    304277                                 &resv->udp_src_addr, &resv->udp_addr_len); 
    305278    if (status != PJ_EPENDING) 
    306279        return status; 
    307  
    308  
    309 #if PJ_HAS_IPV6 
    310     /* Also setup IPv6 socket */ 
    311  
    312     /* Create the UDP socket */ 
    313     status = pj_sock_socket(pj_AF_INET6(), pj_SOCK_DGRAM(), 0, 
    314                             &resv->udp6_sock); 
    315     if (status != PJ_SUCCESS) { 
    316         /* Skip IPv6 socket on system without IPv6 (see ticket #1953) */ 
    317         if (status == PJ_STATUS_FROM_OS(OSERR_EAFNOSUPPORT)) { 
    318             PJ_LOG(3,(resv->name.ptr, 
    319                       "System does not support IPv6, resolver will " 
    320                       "ignore any IPv6 nameservers")); 
    321             return PJ_SUCCESS; 
    322         } 
    323         return status; 
    324     } 
    325  
    326     /* Bind to any address/port */ 
    327     pj_sockaddr_init(pj_AF_INET6(), &bound_addr, NULL, 0); 
    328     status = pj_sock_bind(resv->udp6_sock, &bound_addr, 
    329                           pj_sockaddr_get_len(&bound_addr)); 
    330     if (status != PJ_SUCCESS) 
    331         return status; 
    332  
    333     /* Register to ioqueue */ 
    334     pj_bzero(&socket_cb, sizeof(socket_cb)); 
    335     socket_cb.on_read_complete = &on_read_complete; 
    336     status = pj_ioqueue_register_sock2(resv->pool, resv->ioqueue, 
    337                                        resv->udp6_sock, resv->grp_lock, 
    338                                        resv, &socket_cb, &resv->udp6_key); 
    339     if (status != PJ_SUCCESS) 
    340         return status; 
    341  
    342     pj_ioqueue_op_key_init(&resv->udp6_op_rx_key, 
    343                            sizeof(resv->udp6_op_rx_key)); 
    344     pj_ioqueue_op_key_init(&resv->udp6_op_tx_key, 
    345                            sizeof(resv->udp6_op_tx_key)); 
    346  
    347     /* Start asynchronous read to the UDP socket */ 
    348     rx_pkt_size = sizeof(resv->udp6_rx_pkt); 
    349     resv->udp6_addr_len = sizeof(resv->udp6_src_addr); 
    350     status = pj_ioqueue_recvfrom(resv->udp6_key, &resv->udp6_op_rx_key, 
    351                                  resv->udp6_rx_pkt, &rx_pkt_size, 
    352                                  PJ_IOQUEUE_ALWAYS_ASYNC, 
    353                                  &resv->udp6_src_addr, &resv->udp6_addr_len); 
    354     if (status != PJ_EPENDING) 
    355         return status; 
    356 #else 
    357     PJ_UNUSED_ARG(bound_addr); 
    358 #endif 
    359280 
    360281    return PJ_SUCCESS; 
     
    405326    pj_strdup2_with_null(pool, &resv->name, name); 
    406327     
    407     /* Create group lock */ 
    408     status = pj_grp_lock_create_w_handler(pool, NULL, resv, 
    409                                           &dns_resolver_on_destroy, 
    410                                           &resv->grp_lock);  
     328    /* Create the mutex */ 
     329    status = pj_mutex_create_recursive(pool, name, &resv->mutex); 
    411330    if (status != PJ_SUCCESS) 
    412331        goto on_error; 
    413  
    414     pj_grp_lock_add_ref(resv->grp_lock); 
    415332 
    416333    /* Timer, ioqueue, and settings */ 
     
    424341    /* Create the timer heap if one is not specified */ 
    425342    if (resv->timer == NULL) { 
    426         resv->own_timer = PJ_TRUE; 
    427343        status = pj_timer_heap_create(pool, TIMER_SIZE, &resv->timer); 
    428344        if (status != PJ_SUCCESS) 
     
    432348    /* Create the ioqueue if one is not specified */ 
    433349    if (resv->ioqueue == NULL) { 
    434         resv->own_ioqueue = PJ_TRUE; 
    435350        status = pj_ioqueue_create(pool, MAX_FD, &resv->ioqueue); 
    436351        if (status != PJ_SUCCESS) 
     
    458373    pj_dns_resolver_destroy(resv, PJ_FALSE); 
    459374    return status; 
    460 } 
    461  
    462  
    463 void dns_resolver_on_destroy(void *member) 
    464 { 
    465     pj_dns_resolver *resolver = (pj_dns_resolver*)member; 
    466     pj_pool_safe_release(&resolver->pool); 
    467375} 
    468376 
     
    524432    } 
    525433 
    526     pj_grp_lock_dec_ref(resolver->grp_lock); 
    527  
     434    if (resolver->mutex) { 
     435        pj_mutex_destroy(resolver->mutex); 
     436        resolver->mutex = NULL; 
     437    } 
     438 
     439    if (resolver->pool) { 
     440        pj_pool_t *pool = resolver->pool; 
     441        resolver->pool = NULL; 
     442        pj_pool_release(pool); 
     443    } 
    528444    return PJ_SUCCESS; 
    529445} 
     
    546462    PJ_ASSERT_RETURN(count < PJ_DNS_RESOLVER_MAX_NS, PJ_EINVAL); 
    547463 
    548     pj_grp_lock_acquire(resolver->grp_lock); 
     464    pj_mutex_lock(resolver->mutex); 
    549465 
    550466    if (count > PJ_DNS_RESOLVER_MAX_NS) 
     
    559475        struct nameserver *ns = &resolver->ns[i]; 
    560476 
    561         status = pj_sockaddr_init(pj_AF_INET(), &ns->addr, &servers[i],  
    562                                   (pj_uint16_t)(ports ? ports[i] : PORT)); 
    563         if (status != PJ_SUCCESS) 
    564             status = pj_sockaddr_init(pj_AF_INET6(), &ns->addr, &servers[i],  
    565                                       (pj_uint16_t)(ports ? ports[i] : PORT)); 
     477        status = pj_sockaddr_in_init(&ns->addr, &servers[i],  
     478                                     (pj_uint16_t)(ports ? ports[i] : PORT)); 
    566479        if (status != PJ_SUCCESS) { 
    567             pj_grp_lock_release(resolver->grp_lock); 
     480            pj_mutex_unlock(resolver->mutex); 
    568481            return PJLIB_UTIL_EDNSINNSADDR; 
    569482        } 
     
    576489    resolver->ns_count = count; 
    577490 
    578     pj_grp_lock_release(resolver->grp_lock); 
     491    pj_mutex_unlock(resolver->mutex); 
    579492    return PJ_SUCCESS; 
    580493} 
     
    590503    PJ_ASSERT_RETURN(resolver && st, PJ_EINVAL); 
    591504 
    592     pj_grp_lock_acquire(resolver->grp_lock); 
     505    pj_mutex_lock(resolver->mutex); 
    593506    pj_memcpy(&resolver->settings, st, sizeof(*st)); 
    594     pj_grp_lock_release(resolver->grp_lock); 
     507    pj_mutex_unlock(resolver->mutex); 
    595508    return PJ_SUCCESS; 
    596509} 
     
    605518    PJ_ASSERT_RETURN(resolver && st, PJ_EINVAL); 
    606519 
    607     pj_grp_lock_acquire(resolver->grp_lock); 
     520    pj_mutex_lock(resolver->mutex); 
    608521    pj_memcpy(st, &resolver->settings, sizeof(*st)); 
    609     pj_grp_lock_release(resolver->grp_lock); 
     522    pj_mutex_unlock(resolver->mutex); 
    610523    return PJ_SUCCESS; 
    611524} 
     
    620533    PJ_ASSERT_ON_FAIL(resolver, return); 
    621534 
    622     pj_grp_lock_acquire(resolver->grp_lock); 
     535    pj_mutex_lock(resolver->mutex); 
    623536    pj_timer_heap_poll(resolver->timer, NULL); 
    624     pj_grp_lock_release(resolver->grp_lock); 
     537    pj_mutex_unlock(resolver->mutex); 
    625538 
    626539    pj_ioqueue_poll(resolver->ioqueue, timeout); 
     
    667580{ 
    668581    unsigned pkt_size; 
    669     unsigned i, server_cnt, send_cnt; 
     582    unsigned i, server_cnt; 
    670583    unsigned servers[PJ_DNS_RESOLVER_MAX_NS]; 
    671584    pj_time_val now; 
     
    694607    delay.msec = resolver->settings.qretr_delay; 
    695608    pj_time_val_normalize(&delay); 
    696     status = pj_timer_heap_schedule_w_grp_lock(resolver->timer, 
    697                                                &q->timer_entry, 
    698                                                &delay, 1, 
    699                                                resolver->grp_lock); 
     609    status = pj_timer_heap_schedule(resolver->timer, &q->timer_entry, &delay); 
    700610    if (status != PJ_SUCCESS) { 
    701611        return status; 
     
    703613 
    704614    /* Check if the socket is available for sending */ 
    705     if (pj_ioqueue_is_pending(resolver->udp_key, &resolver->udp_op_tx_key) 
    706 #if PJ_HAS_IPV6 
    707         || (resolver->udp6_key && 
    708             pj_ioqueue_is_pending(resolver->udp6_key, 
    709                                   &resolver->udp6_op_tx_key)) 
    710 #endif 
    711         ) 
    712     { 
     615    if (pj_ioqueue_is_pending(resolver->udp_key, &resolver->udp_op_tx_key)) { 
    713616        ++q->transmit_cnt; 
    714617        PJ_LOG(4,(resolver->name.ptr, 
     
    735638 
    736639    /* Send the packet to name servers */ 
    737     send_cnt = 0; 
    738640    for (i=0; i<server_cnt; ++i) { 
    739         char addr[PJ_INET6_ADDRSTRLEN]; 
    740641        pj_ssize_t sent  = (pj_ssize_t) pkt_size; 
    741642        struct nameserver *ns = &resolver->ns[servers[i]]; 
    742643 
    743         if (ns->addr.addr.sa_family == pj_AF_INET()) { 
    744             status = pj_ioqueue_sendto(resolver->udp_key, 
    745                                        &resolver->udp_op_tx_key, 
    746                                        resolver->udp_tx_pkt, &sent, 0, 
    747                                        &ns->addr, 
    748                                        pj_sockaddr_get_len(&ns->addr)); 
    749             if (status == PJ_SUCCESS || status == PJ_EPENDING) 
    750                 send_cnt++; 
    751         } 
    752 #if PJ_HAS_IPV6 
    753         else if (resolver->udp6_key) { 
    754             status = pj_ioqueue_sendto(resolver->udp6_key, 
    755                                        &resolver->udp6_op_tx_key, 
    756                                        resolver->udp_tx_pkt, &sent, 0, 
    757                                        &ns->addr, 
    758                                        pj_sockaddr_get_len(&ns->addr)); 
    759             if (status == PJ_SUCCESS || status == PJ_EPENDING) 
    760                 send_cnt++; 
    761         } 
    762 #endif 
    763         else { 
    764             continue; 
    765         } 
     644        status = pj_ioqueue_sendto(resolver->udp_key, 
     645                                   &resolver->udp_op_tx_key, 
     646                                   resolver->udp_tx_pkt, &sent, 0, 
     647                                   &resolver->ns[servers[i]].addr, 
     648                                   sizeof(pj_sockaddr_in)); 
    766649 
    767650        PJ_PERROR(4,(resolver->name.ptr, status, 
     
    769652                  (q->transmit_cnt==0? "Transmitting":"Re-transmitting"), 
    770653                  (int)pkt_size, servers[i], 
    771                   pj_sockaddr_print(&ns->addr, addr, sizeof(addr), 2), 
    772                   pj_sockaddr_get_port(&ns->addr), 
     654                  pj_inet_ntoa(ns->addr.sin_addr),  
     655                  (int)pj_ntohs(ns->addr.sin_port), 
    773656                  pj_dns_get_type_name(q->key.qtype),  
    774657                  q->key.name)); 
     
    778661            ns->sent_time = now; 
    779662        } 
    780     } 
    781  
    782     if (send_cnt == 0) { 
    783         pj_timer_heap_cancel(resolver->timer, &q->timer_entry); 
    784         return PJLIB_UTIL_EDNSNOWORKINGNS; 
    785663    } 
    786664 
     
    869747    struct res_key key; 
    870748    struct cached_res *cache; 
    871     pj_dns_async_query *q, *p_q = NULL; 
     749    pj_dns_async_query *q; 
    872750    pj_uint32_t hval; 
    873751    pj_status_t status = PJ_SUCCESS; 
     
    883761    PJ_ASSERT_RETURN(type > 0 && type < 0xFFFF, PJ_EINVAL); 
    884762 
     763    if (p_query) 
     764        *p_query = NULL; 
     765 
    885766    /* Build resource key for looking up hash tables */ 
    886767    init_res_key(&key, type, name); 
    887768 
    888769    /* Start working with the resolver */ 
    889     pj_grp_lock_acquire(resolver->grp_lock); 
     770    pj_mutex_lock(resolver->mutex); 
    890771 
    891772    /* Get current time. */ 
     
    920801             */ 
    921802            cache->ref_cnt++; 
    922             pj_grp_lock_release(resolver->grp_lock); 
     803            pj_mutex_unlock(resolver->mutex); 
    923804 
    924805            /* This cached response is still valid. Just return this 
     
    930811 
    931812            /* Done. No host resolution is necessary */ 
    932             pj_grp_lock_acquire(resolver->grp_lock); 
     813            pj_mutex_lock(resolver->mutex); 
    933814 
    934815            /* Decrement the ref counter. Also check if it is time to free 
     
    942823            status = PJ_SUCCESS; 
    943824 
    944             /* 
    945              * We cannot write to *p_query after calling cb because what 
    946              * p_query points to may have been freed by cb. 
    947              * Refer to ticket #1974. 
    948              */ 
    949             pj_grp_lock_release(resolver->grp_lock); 
    950             return status; 
     825            goto on_return; 
    951826        } 
    952827 
     
    980855         * query completes. 
    981856         */ 
    982         p_q = nq; 
    983857        status = PJ_SUCCESS; 
    984858        goto on_return; 
     
    1008882                   0, q->hbufkey, q); 
    1009883 
    1010     p_q = q; 
     884    if (p_query) 
     885        *p_query = q; 
    1011886 
    1012887on_return: 
    1013     if (p_query) 
    1014         *p_query = p_q; 
    1015  
    1016     pj_grp_lock_release(resolver->grp_lock); 
     888    pj_mutex_unlock(resolver->mutex); 
    1017889    return status; 
    1018890} 
     
    1029901    PJ_ASSERT_RETURN(query, PJ_EINVAL); 
    1030902 
    1031     pj_grp_lock_acquire(query->resolver->grp_lock); 
    1032  
    1033     if (query->timer_entry.id == 1) { 
    1034         pj_timer_heap_cancel_if_active(query->resolver->timer, 
    1035                                        &query->timer_entry, 0); 
    1036     } 
     903    pj_mutex_lock(query->resolver->mutex); 
    1037904 
    1038905    cb = query->cb; 
     
    1042909        (*cb)(query->user_data, PJ_ECANCELLED, NULL); 
    1043910 
    1044     pj_grp_lock_release(query->resolver->grp_lock); 
     911    pj_mutex_unlock(query->resolver->mutex); 
    1045912    return PJ_SUCCESS; 
    1046913} 
     
    11601027 
    11611028 
    1162 /*  
    1163  * DNS response containing A and/or AAAA packet.  
    1164  */ 
    1165 PJ_DEF(pj_status_t) pj_dns_parse_addr_response( 
    1166                                             const pj_dns_parsed_packet *pkt, 
    1167                                             pj_dns_addr_record *rec) 
    1168 { 
    1169     enum { MAX_SEARCH = 20 }; 
    1170     pj_str_t hostname, alias = {NULL, 0}, *resname; 
    1171     pj_size_t bufstart = 0; 
    1172     pj_size_t bufleft; 
    1173     unsigned i, ansidx, cnt=0; 
    1174  
    1175     PJ_ASSERT_RETURN(pkt && rec, PJ_EINVAL); 
    1176  
    1177     /* Init the record */ 
    1178     pj_bzero(rec, sizeof(*rec)); 
    1179  
    1180     bufleft = sizeof(rec->buf_); 
    1181  
    1182     /* Return error if there's error in the packet. */ 
    1183     if (PJ_DNS_GET_RCODE(pkt->hdr.flags)) 
    1184         return PJ_STATUS_FROM_DNS_RCODE(PJ_DNS_GET_RCODE(pkt->hdr.flags)); 
    1185  
    1186     /* Return error if there's no query section */ 
    1187     if (pkt->hdr.qdcount == 0) 
    1188         return PJLIB_UTIL_EDNSINANSWER; 
    1189  
    1190     /* Return error if there's no answer */ 
    1191     if (pkt->hdr.anscount == 0) 
    1192         return PJLIB_UTIL_EDNSNOANSWERREC; 
    1193  
    1194     /* Get the hostname from the query. */ 
    1195     hostname = pkt->q[0].name; 
    1196  
    1197     /* Copy hostname to the record */ 
    1198     if (hostname.slen > (int)bufleft) { 
    1199         return PJ_ENAMETOOLONG; 
    1200     } 
    1201  
    1202     pj_memcpy(&rec->buf_[bufstart], hostname.ptr, hostname.slen); 
    1203     rec->name.ptr = &rec->buf_[bufstart]; 
    1204     rec->name.slen = hostname.slen; 
    1205  
    1206     bufstart += hostname.slen; 
    1207     bufleft -= hostname.slen; 
    1208  
    1209     /* Find the first RR which name matches the hostname. */ 
    1210     for (ansidx=0; ansidx < pkt->hdr.anscount; ++ansidx) { 
    1211         if (pj_stricmp(&pkt->ans[ansidx].name, &hostname)==0) 
    1212             break; 
    1213     } 
    1214  
    1215     if (ansidx == pkt->hdr.anscount) 
    1216         return PJLIB_UTIL_EDNSNOANSWERREC; 
    1217  
    1218     resname = &hostname; 
    1219  
    1220     /* Keep following CNAME records. */ 
    1221     while (pkt->ans[ansidx].type == PJ_DNS_TYPE_CNAME && 
    1222            cnt++ < MAX_SEARCH) 
    1223     { 
    1224         resname = &pkt->ans[ansidx].rdata.cname.name; 
    1225  
    1226         if (!alias.slen) 
    1227             alias = *resname; 
    1228  
    1229         for (i=0; i < pkt->hdr.anscount; ++i) { 
    1230             if (pj_stricmp(resname, &pkt->ans[i].name)==0) 
    1231                 break; 
    1232         } 
    1233  
    1234         if (i==pkt->hdr.anscount) 
    1235             return PJLIB_UTIL_EDNSNOANSWERREC; 
    1236  
    1237         ansidx = i; 
    1238     } 
    1239  
    1240     if (cnt >= MAX_SEARCH) 
    1241         return PJLIB_UTIL_EDNSINANSWER; 
    1242  
    1243     if (pkt->ans[ansidx].type != PJ_DNS_TYPE_A && 
    1244         pkt->ans[ansidx].type != PJ_DNS_TYPE_AAAA) 
    1245     { 
    1246         return PJLIB_UTIL_EDNSINANSWER; 
    1247     } 
    1248  
    1249     /* Copy alias to the record, if present. */ 
    1250     if (alias.slen) { 
    1251         if (alias.slen > (int)bufleft) 
    1252             return PJ_ENAMETOOLONG; 
    1253  
    1254         pj_memcpy(&rec->buf_[bufstart], alias.ptr, alias.slen); 
    1255         rec->alias.ptr = &rec->buf_[bufstart]; 
    1256         rec->alias.slen = alias.slen; 
    1257  
    1258         bufstart += alias.slen; 
    1259         bufleft -= alias.slen; 
    1260     } 
    1261  
    1262     /* Get the IP addresses. */ 
    1263     cnt = 0; 
    1264     for (i=0; i < pkt->hdr.anscount && cnt < PJ_DNS_MAX_IP_IN_A_REC ; ++i) { 
    1265         if ((pkt->ans[i].type == PJ_DNS_TYPE_A || 
    1266              pkt->ans[i].type == PJ_DNS_TYPE_AAAA) && 
    1267             pj_stricmp(&pkt->ans[i].name, resname)==0) 
    1268         { 
    1269             if (pkt->ans[i].type == PJ_DNS_TYPE_A) { 
    1270                 rec->addr[cnt].af = pj_AF_INET(); 
    1271                 rec->addr[cnt].ip.v4 = pkt->ans[i].rdata.a.ip_addr; 
    1272             } else { 
    1273                 rec->addr[cnt].af = pj_AF_INET6(); 
    1274                 rec->addr[cnt].ip.v6 = pkt->ans[i].rdata.aaaa.ip_addr; 
    1275             } 
    1276             ++cnt; 
    1277         } 
    1278     } 
    1279     rec->addr_count = cnt; 
    1280  
    1281     if (cnt == 0) 
    1282         return PJLIB_UTIL_EDNSNOANSWERREC; 
    1283  
    1284     return PJ_SUCCESS; 
    1285 } 
    1286  
    1287  
    12881029/* Set nameserver state */ 
    12891030static void set_nameserver_state(pj_dns_resolver *resolver, 
     
    12941035    struct nameserver *ns = &resolver->ns[index]; 
    12951036    enum ns_state old_state = ns->state; 
    1296     char addr[PJ_INET6_ADDRSTRLEN]; 
    12971037 
    12981038    ns->state = state; 
     
    13081048 
    13091049    PJ_LOG(5, (resolver->name.ptr, "Nameserver %s:%d state changed %s --> %s", 
    1310                pj_sockaddr_print(&ns->addr, addr, sizeof(addr), 2), 
    1311                pj_sockaddr_get_port(&ns->addr), 
     1050               pj_inet_ntoa(ns->addr.sin_addr), 
     1051               (int)pj_ntohs(ns->addr.sin_port), 
    13121052               state_names[old_state], state_names[state])); 
    13131053} 
     
    13881128/* Update name server status */ 
    13891129static void report_nameserver_status(pj_dns_resolver *resolver, 
    1390                                      const pj_sockaddr *ns_addr, 
     1130                                     const pj_sockaddr_in *ns_addr, 
    13911131                                     const pj_dns_parsed_packet *pkt) 
    13921132{ 
     
    14081148    } 
    14091149 
    1410     /* Some nameserver is reported to respond with PJ_DNS_RCODE_SERVFAIL for 
    1411      * missing AAAA record, and the standard doesn't seem to specify that 
    1412      * SERVFAIL should prevent the server to be contacted again for other 
    1413      * queries. So let's not mark nameserver as bad for SERVFAIL response. 
    1414      */ 
    1415     if (!pkt || /* rcode == PJ_DNS_RCODE_SERVFAIL || */ 
     1150    if (!pkt || rcode == PJ_DNS_RCODE_SERVFAIL || 
    14161151                rcode == PJ_DNS_RCODE_REFUSED || 
    14171152                rcode == PJ_DNS_RCODE_NOTAUTH)  
     
    14301165        struct nameserver *ns = &resolver->ns[i]; 
    14311166 
    1432         if (pj_sockaddr_cmp(&ns->addr, ns_addr) == 0) { 
     1167        if (ns->addr.sin_addr.s_addr == ns_addr->sin_addr.s_addr && 
     1168            ns->addr.sin_port == ns_addr->sin_port && 
     1169            ns->addr.sin_family == ns_addr->sin_family) 
     1170        { 
    14331171            if (q_id == ns->q_id) { 
    14341172                /* Calculate response time */ 
     
    14951233        ttl = resolver->settings.cache_max_ttl; 
    14961234 
    1497     /* Get a cache response entry */ 
    1498     cache = (struct cached_res *) pj_hash_get(resolver->hrescache, key, 
    1499                                               sizeof(*key), &hval); 
    1500  
    15011235    /* If TTL is zero, clear the same entry in the hash table */ 
    15021236    if (ttl == 0) { 
     1237        cache = (struct cached_res *) pj_hash_get(resolver->hrescache, key,  
     1238                                                  sizeof(*key), &hval); 
    15031239        /* Remove the entry before releasing its pool (see ticket #1710) */ 
    15041240        pj_hash_set(NULL, resolver->hrescache, key, sizeof(*key), hval, NULL); 
     
    15101246    } 
    15111247 
     1248    /* Get a cache response entry */ 
     1249    cache = (struct cached_res *) pj_hash_get(resolver->hrescache, key,  
     1250                                              sizeof(*key), &hval); 
    15121251    if (cache == NULL) { 
     1252        cache = alloc_entry(resolver); 
     1253    } else if (cache->ref_cnt > 1) { 
     1254        /* When cache entry is being used by callback (to app), just decrement 
     1255         * ref_cnt so it will be freed after the callback returns and allocate 
     1256         * new entry. 
     1257         */ 
     1258        cache->ref_cnt--; 
    15131259        cache = alloc_entry(resolver); 
    15141260    } else { 
     
    15161262        pj_hash_set(NULL, resolver->hrescache, key, sizeof(*key), hval, NULL); 
    15171263 
    1518         if (cache->ref_cnt > 1) { 
    1519             /* When cache entry is being used by callback (to app), 
    1520              * just decrement ref_cnt so it will be freed after 
    1521              * the callback returns and allocate new entry. 
    1522              */ 
    1523             cache->ref_cnt--; 
    1524             cache = alloc_entry(resolver); 
    1525         } else { 
    1526             /* Reset cache to avoid bloated cache pool */ 
    1527             reset_entry(&cache); 
    1528         } 
     1264        /* Reset cache to avoid bloated cache pool */ 
     1265        reset_entry(&cache); 
    15291266    } 
    15301267 
     
    15711308    resolver = q->resolver; 
    15721309 
    1573     pj_grp_lock_acquire(resolver->grp_lock); 
     1310    pj_mutex_lock(resolver->mutex); 
    15741311 
    15751312    /* Recheck that this query is still pending, since there is a slight 
     
    15791316    if (pj_hash_get(resolver->hquerybyid, &q->id, sizeof(q->id), NULL)==NULL) { 
    15801317        /* Yeah, this query is done. */ 
    1581         pj_grp_lock_release(resolver->grp_lock); 
     1318        pj_mutex_unlock(resolver->mutex); 
    15821319        return; 
    15831320    } 
     
    15901327        status = transmit_query(resolver, q); 
    15911328        if (status == PJ_SUCCESS) { 
    1592             pj_grp_lock_release(resolver->grp_lock); 
     1329            pj_mutex_unlock(resolver->mutex); 
    15931330            return; 
    15941331        } else { 
     
    16091346 
    16101347    /* Workaround for deadlock problem in #1565 (similar to #1108) */ 
    1611     pj_grp_lock_release(resolver->grp_lock); 
     1348    pj_mutex_unlock(resolver->mutex); 
    16121349 
    16131350    /* Call application callback, if any. */ 
     
    16241361 
    16251362    /* Workaround for deadlock problem in #1565 (similar to #1108) */ 
    1626     pj_grp_lock_acquire(resolver->grp_lock); 
     1363    pj_mutex_lock(resolver->mutex); 
    16271364 
    16281365    /* Clear data */ 
     
    16411378    pj_list_push_back(&resolver->query_free_nodes, q); 
    16421379 
    1643     pj_grp_lock_release(resolver->grp_lock); 
     1380    pj_mutex_unlock(resolver->mutex); 
    16441381} 
    16451382 
     
    16541391    pj_dns_parsed_packet *dns_pkt; 
    16551392    pj_dns_async_query *q; 
    1656     char addr[PJ_INET6_ADDRSTRLEN]; 
    1657     pj_sockaddr *src_addr; 
    1658     int *src_addr_len; 
    1659     unsigned char *rx_pkt; 
    1660     pj_ssize_t rx_pkt_size; 
    16611393    pj_status_t status; 
    16621394    PJ_USE_EXCEPTION; 
     
    16641396 
    16651397    resolver = (pj_dns_resolver *) pj_ioqueue_get_user_data(key); 
    1666     pj_assert(resolver); 
    1667  
    1668 #if PJ_HAS_IPV6 
    1669     if (key == resolver->udp6_key) { 
    1670         src_addr = &resolver->udp6_src_addr; 
    1671         src_addr_len = &resolver->udp6_addr_len; 
    1672         rx_pkt = resolver->udp6_rx_pkt; 
    1673         rx_pkt_size = sizeof(resolver->udp6_rx_pkt); 
    1674     } else  
    1675 #endif 
    1676     { 
    1677         src_addr = &resolver->udp_src_addr; 
    1678         src_addr_len = &resolver->udp_addr_len; 
    1679         rx_pkt = resolver->udp_rx_pkt; 
    1680         rx_pkt_size = sizeof(resolver->udp_rx_pkt); 
    1681     } 
    1682  
    1683     pj_grp_lock_acquire(resolver->grp_lock); 
     1398    pj_mutex_lock(resolver->mutex); 
    16841399 
    16851400 
     
    16901405        status = (pj_status_t)-bytes_read; 
    16911406        pj_strerror(status, errmsg, sizeof(errmsg)); 
    1692         PJ_LOG(4,(resolver->name.ptr, "DNS resolver read error: %s", errmsg)); 
     1407        PJ_LOG(4,(resolver->name.ptr,  
     1408                  "DNS resolver read error from %s:%d: %s",  
     1409                  pj_inet_ntoa(resolver->udp_src_addr.sin_addr), 
     1410                  pj_ntohs(resolver->udp_src_addr.sin_port), 
     1411                  errmsg)); 
    16931412 
    16941413        goto read_next_packet; 
     
    16981417              "Received %d bytes DNS response from %s:%d", 
    16991418              (int)bytes_read,  
    1700               pj_sockaddr_print(src_addr, addr, sizeof(addr), 2), 
    1701               pj_sockaddr_get_port(src_addr))); 
     1419              pj_inet_ntoa(resolver->udp_src_addr.sin_addr), 
     1420              pj_ntohs(resolver->udp_src_addr.sin_port))); 
    17021421 
    17031422 
     
    17141433    dns_pkt = NULL; 
    17151434    PJ_TRY { 
    1716         status = pj_dns_parse_packet(pool, rx_pkt,  
     1435        status = pj_dns_parse_packet(pool, resolver->udp_rx_pkt,  
    17171436                                     (unsigned)bytes_read, &dns_pkt); 
    17181437    } 
     
    17231442 
    17241443    /* Update nameserver status */ 
    1725     report_nameserver_status(resolver, src_addr, dns_pkt); 
     1444    report_nameserver_status(resolver, &resolver->udp_src_addr, dns_pkt); 
    17261445 
    17271446    /* Handle parse error */ 
     
    17321451        PJ_LOG(3,(resolver->name.ptr,  
    17331452                  "Error parsing DNS response from %s:%d: %s",  
    1734                   pj_sockaddr_print(src_addr, addr, sizeof(addr), 2), 
    1735                   pj_sockaddr_get_port(src_addr), 
     1453                  pj_inet_ntoa(resolver->udp_src_addr.sin_addr),  
     1454                  pj_ntohs(resolver->udp_src_addr.sin_port),  
    17361455                  errmsg)); 
    17371456        goto read_next_packet; 
     
    17451464        PJ_LOG(5,(resolver->name.ptr,  
    17461465                  "DNS response from %s:%d id=%d discarded", 
    1747                   pj_sockaddr_print(src_addr, addr, sizeof(addr), 2), 
    1748                   pj_sockaddr_get_port(src_addr), 
     1466                  pj_inet_ntoa(resolver->udp_src_addr.sin_addr),  
     1467                  pj_ntohs(resolver->udp_src_addr.sin_port), 
    17491468                  (unsigned)dns_pkt->hdr.id)); 
    17501469        goto read_next_packet; 
     
    17641483 
    17651484    /* Workaround for deadlock problem in #1108 */ 
    1766     pj_grp_lock_release(resolver->grp_lock); 
     1485    pj_mutex_unlock(resolver->mutex); 
    17671486 
    17681487    /* Notify applications first, to allow application to modify the  
     
    17851504 
    17861505    /* Workaround for deadlock problem in #1108 */ 
    1787     pj_grp_lock_acquire(resolver->grp_lock); 
     1506    pj_mutex_lock(resolver->mutex); 
    17881507 
    17891508    /* Save/update response cache. */ 
     
    18091528        pj_pool_release(pool); 
    18101529    } 
    1811  
    1812     status = pj_ioqueue_recvfrom(key, op_key, rx_pkt, &rx_pkt_size, 
    1813                                  PJ_IOQUEUE_ALWAYS_ASYNC, 
    1814                                  src_addr, src_addr_len); 
    1815  
    1816     if (status != PJ_EPENDING && status != PJ_ECANCELLED) { 
     1530    bytes_read = sizeof(resolver->udp_rx_pkt); 
     1531    resolver->udp_addr_len = sizeof(resolver->udp_src_addr); 
     1532    status = pj_ioqueue_recvfrom(resolver->udp_key, op_key,  
     1533                                 resolver->udp_rx_pkt, 
     1534                                 &bytes_read, PJ_IOQUEUE_ALWAYS_ASYNC, 
     1535                                 &resolver->udp_src_addr,  
     1536                                 &resolver->udp_addr_len); 
     1537    if (status != PJ_EPENDING) { 
    18171538        char errmsg[PJ_ERR_MSG_SIZE]; 
    18181539 
     
    18241545    } 
    18251546 
    1826     pj_grp_lock_release(resolver->grp_lock); 
     1547    pj_mutex_unlock(resolver->mutex); 
    18271548} 
    18281549 
     
    18501571                     PJLIB_UTIL_EDNSNOANSWERREC); 
    18511572 
    1852     pj_grp_lock_acquire(resolver->grp_lock); 
     1573    pj_mutex_lock(resolver->mutex); 
    18531574 
    18541575    /* Build resource key for looking up hash tables */ 
     
    18721593    update_res_cache(resolver, &key, PJ_SUCCESS, set_ttl, pkt); 
    18731594 
    1874     pj_grp_lock_release(resolver->grp_lock); 
     1595    pj_mutex_unlock(resolver->mutex); 
    18751596 
    18761597    return PJ_SUCCESS; 
     
    18871608    PJ_ASSERT_RETURN(resolver, 0); 
    18881609 
    1889     pj_grp_lock_acquire(resolver->grp_lock); 
     1610    pj_mutex_lock(resolver->mutex); 
    18901611    count = pj_hash_count(resolver->hrescache); 
    1891     pj_grp_lock_release(resolver->grp_lock); 
     1612    pj_mutex_unlock(resolver->mutex); 
    18921613 
    18931614    return count; 
     
    19051626    pj_time_val now; 
    19061627 
    1907     pj_grp_lock_acquire(resolver->grp_lock); 
     1628    pj_mutex_lock(resolver->mutex); 
    19081629 
    19091630    pj_gettimeofday(&now); 
     
    19131634    PJ_LOG(3,(resolver->name.ptr, "  Name servers:")); 
    19141635    for (i=0; i<resolver->ns_count; ++i) { 
    1915         char addr[PJ_INET6_ADDRSTRLEN]; 
     1636        const char *state_names[] = { "probing", "active", "bad"}; 
    19161637        struct nameserver *ns = &resolver->ns[i]; 
    19171638 
    19181639        PJ_LOG(3,(resolver->name.ptr, 
    19191640                  "   NS %d: %s:%d (state=%s until %ds, rtt=%d ms)", 
    1920                   i, 
    1921                   pj_sockaddr_print(&ns->addr, addr, sizeof(addr), 2), 
    1922                   pj_sockaddr_get_port(&ns->addr), 
     1641                  i, pj_inet_ntoa(ns->addr.sin_addr), 
     1642                  pj_ntohs(ns->addr.sin_port), 
    19231643                  state_names[ns->state], 
    19241644                  ns->state_expiry.sec - now.sec, 
     
    19651685              pj_pool_get_used_size(resolver->pool))); 
    19661686 
    1967     pj_grp_lock_release(resolver->grp_lock); 
     1687    pj_mutex_unlock(resolver->mutex); 
    19681688#endif 
    19691689} 
Note: See TracChangeset for help on using the changeset viewer.