static void idnsSendQuery(idns_query * q) { int x; int ns; if (DnsSocket < 0) { debug(78, 1) ("idnsSendQuery: Can't send query, no DNS socket!\n"); return; } /* XXX Select nameserver */ assert(nns > 0); assert(q->lru.next == NULL); assert(q->lru.prev == NULL); ns = q->nsends % nns; x = comm_udp_sendto(DnsSocket, &nameservers[ns].S, sizeof(nameservers[ns].S), q->buf, q->sz); if (x < 0) { debug(50, 1) ("idnsSendQuery: FD %d: sendto: %s\n", DnsSocket, xstrerror()); } else { fd_bytes(DnsSocket, x, FD_WRITE); commSetSelect(DnsSocket, COMM_SELECT_READ, idnsRead, NULL, 0); } q->nsends++; q->sent_t = current_time; nameservers[ns].nqueries++; dlinkAdd(q, &q->lru, &lru_list); idnsTickleQueue(); }
static void idnsCheckQueue(void *unused) { dlink_node *n; dlink_node *p = NULL; idns_query *q; event_queued = 0; for (n = lru_list.tail; n; n = p) { q = n->data; if (tvSubDsec(q->sent_t, current_time) < 5.0) break; debug(78, 3) ("idnsCheckQueue: ID %#04x timeout\n", q->id); p = n->prev; dlinkDelete(&q->lru, &lru_list); if (q->nsends < IDNS_MAX_TRIES) { idnsSendQuery(q); } else { int v = cbdataValid(q->callback_data); debug(78, 1) ("idnsCheckQueue: ID %x: giving up after %d tries and %5.1f seconds\n", (int) q->id, q->nsends, tvSubDsec(q->start_t, current_time)); cbdataUnlock(q->callback_data); if (v) q->callback(q->callback_data, NULL, 0); memFree(q, MEM_IDNS_QUERY); } } idnsTickleQueue(); }
static void idnsCheckQueue(void *unused) { dlink_node *n; dlink_node *p = NULL; idns_query *q; event_queued = 0; if (0 == nns) /* name servers went away; reconfiguring or shutting down */ return; for (n = lru_list.tail; n; n = p) { p = n->prev; q = n->data; /* Anything to process in the queue? */ if (tvSubDsec(q->queue_t, current_time) < Config.Timeout.idns_retransmit) break; /* Query timer expired? */ if (tvSubDsec(q->sent_t, current_time) < Config.Timeout.idns_retransmit * 1 << ((q->nsends - 1) / nns)) { dlinkDelete(&q->lru, &lru_list); q->queue_t = current_time; dlinkAdd(q, &q->lru, &lru_list); continue; } debug(78, 3) ("idnsCheckQueue: ID %#04x timeout\n", q->id); dlinkDelete(&q->lru, &lru_list); if (tvSubDsec(q->start_t, current_time) < Config.Timeout.idns_query) { idnsSendQuery(q); } else { debug(78, 2) ("idnsCheckQueue: ID %x: giving up after %d tries and %5.1f seconds\n", (int) q->id, q->nsends, tvSubDsec(q->start_t, current_time)); if (q->rcode != 0) idnsCallback(q, NULL, -q->rcode, q->error); else idnsCallback(q, NULL, -16, "Timeout"); idnsTcpCleanup(q); cbdataFree(q); } } idnsTickleQueue(); }