/** * QUERY. * */ static query_state query_process_query(query_type* q, ldns_rr_type qtype, engine_type* engine) { dnsout_type* dnsout = NULL; if (!q || !q->zone) { return QUERY_DISCARDED; } ods_log_assert(q->zone->name); ods_log_debug("[%s] incoming query qtype=%s for zone %s", query_str, rrset_type2str(qtype), q->zone->name); /* sanity checks */ if (buffer_pkt_qdcount(q->buffer) != 1 || buffer_pkt_tc(q->buffer)) { buffer_pkt_set_flags(q->buffer, 0); return query_formerr(q); } if (buffer_pkt_ancount(q->buffer) != 0 || (qtype != LDNS_RR_TYPE_IXFR && buffer_pkt_nscount(q->buffer) != 0)) { buffer_pkt_set_flags(q->buffer, 0); return query_formerr(q); } /* acl */ if (!q->zone->adoutbound || q->zone->adoutbound->type != ADAPTER_DNS) { ods_log_error("[%s] zone %s is not configured to have output dns " "adapter", query_str, q->zone->name); return query_refused(q); } ods_log_assert(q->zone->adoutbound->config); dnsout = (dnsout_type*) q->zone->adoutbound->config; /* acl also in use for soa and other queries */ if (!acl_find(dnsout->provide_xfr, &q->addr, q->tsig_rr)) { return query_refused(q); } /* ixfr? */ if (qtype == LDNS_RR_TYPE_IXFR) { if (query_process_ixfr(q) != QUERY_PROCESSED) { buffer_pkt_set_flags(q->buffer, 0); return query_formerr(q); } query_prepare(q); ods_log_assert(q->zone->name); ods_log_debug("[%s] incoming ixfr request serial=%u for zone %s", query_str, q->serial, q->zone->name); return ixfr(q, engine); } query_prepare(q); /* axfr? */ if (qtype == LDNS_RR_TYPE_AXFR) { ods_log_assert(q->zone->name); ods_log_debug("[%s] incoming axfr request for zone %s", query_str, q->zone->name); return axfr(q, engine); } /* (soa) query */ return query_response(q, qtype); }
void request_answer(int sock) { int start, end; struct timeval t1, t2; query q; gettimeofday(&t1, 0); query_init(&q); socket_set_timeout(sock, 5, 5); /* read query, read interval start, read interval end */ if(!request_read_query(sock, &q) || !request_read_integer(sock, &start) || !request_read_integer(sock, &end)) { query_delete(&q); close(sock); return; } query_prepare(&q); request_send_result(sock, &q, start, end); query_delete(&q); close(sock); gettimeofday(&t2, 0); /* printf("%i milliseconds\n", ((t2.tv_sec - t1.tv_sec) * 1000000 + t2.tv_usec - t1.tv_usec) / 1000); */ return; }
int query_first_result(struct query *q, uint8_t **tal_data, size_t *n, int *raw, int *id) { int result; query_prepare(q); result = query_next(q, tal_data, n, raw, id); query_finalize(q); return result; }
int query_foreach_result(struct query *q, int (*fn)(uint8_t *data, size_t n, int raw, int id, int i, void *user), void *user) { uint8_t *data; size_t n; int raw, id, i, status; query_prepare(q); i = 0; while(query_next(q, &data, &n, &raw, &id) == 0) { status = (*fn)(data, n, raw, id, i++, user); talloc_free(data); if(status != 0) break; } query_finalize(q); return i; }