summaryrefslogtreecommitdiffstats
path: root/lib/layer/iterate.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/layer/iterate.c')
-rw-r--r--lib/layer/iterate.c128
1 files changed, 128 insertions, 0 deletions
diff --git a/lib/layer/iterate.c b/lib/layer/iterate.c
new file mode 100644
index 00000000..5662099b
--- /dev/null
+++ b/lib/layer/iterate.c
@@ -0,0 +1,128 @@
+/* Copyright 2014 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+#include <libknot/descriptor.h>
+#include <libknot/rrtype/rdname.h>
+#include <libknot/rrtype/aaaa.h>
+
+#include "lib/layer/iterate.h"
+
+/* State-less single resolution iteration step, not needed. */
+static int reset(knot_process_t *ctx) { return NS_PROC_MORE; }
+static int finish(knot_process_t *ctx) { return NS_PROC_NOOP; }
+
+/* Set resolution context and parameters. */
+static int begin(knot_process_t *ctx, void *module_param)
+{
+ ctx->data = module_param;
+ return NS_PROC_MORE;
+}
+
+/* Resolve input query or continue resolution with followups. */
+static int resolve(knot_pkt_t *pkt, knot_process_t *ctx)
+{
+ assert(pkt && ctx);
+ struct layer_iterate_param *param = ctx->data;
+
+ struct kresolve_ctx *resolution = param->ctx;
+ struct kresolve_result *result = param->result;
+
+ /* Is the answer authoritative? */
+ bool is_aa = knot_wire_get_aa(pkt->wire);
+ printf("got packet: AA? %d RRs %d RCODE %d\n", is_aa, pkt->rrset_count, knot_wire_get_rcode(pkt->wire));
+ if (is_aa) {
+ /* Add results to the answer section. */
+ const knot_pktsection_t *an = knot_pkt_section(pkt, KNOT_ANSWER);
+ for (unsigned i = 0; i < an->count; ++i) {
+ knot_rrset_t *copy = knot_rrset_copy(an->rr + i, resolution->mm);
+ result->data[result->count] = copy;
+ result->count += 1;
+ }
+ /* Store canonical name. */
+ result->cname = knot_dname_copy(knot_pkt_qname(pkt), resolution->mm);
+ /* TODO: store flags */
+ /* Finished. */
+ resolution->state = NS_PROC_DONE;
+ } else {
+ /* Is there a NS to add into SLIST? */
+ knot_pktsection_t *ns = knot_pkt_section(pkt, KNOT_AUTHORITY);
+ result->ns.name = NULL;
+ memset(&result->ns.addr, 0, sizeof(result->ns.addr));
+ for (unsigned i = 0; i < ns->count; ++i) {
+ if (ns->rr[i].type == KNOT_RRTYPE_NS) {
+ result->ns.name = knot_ns_name(&ns->rr[i].rrs, 0);
+ /* TODO: fill SLIST */
+ printf("next nameserver: %s\n", knot_dname_to_str(result->ns.name));
+ break;
+ }
+ }
+
+ /* No next nameserver? */
+ if (result->ns.name == NULL) {
+ printf("no next nameserver\n");
+ resolution->state = NS_PROC_FAIL;
+ return NS_PROC_FAIL;
+ }
+
+ /* Is the address in additional records? */
+ knot_pktsection_t *ar = knot_pkt_section(pkt, KNOT_ADDITIONAL);
+ for (unsigned i = 0; i < ar->count; ++i) {
+ printf("checking additional: %s type %d\n", knot_dname_to_str(ar->rr[i].owner), ar->rr[i].type);
+ if (knot_dname_is_equal(result->ns.name, ar->rr[i].owner)) {
+
+ /* Fill next server address. */
+ switch(ar->rr[i].type) {
+ case KNOT_RRTYPE_A:
+ knot_a_addr(&ar->rr[i].rrs, 0, &result->ns.addr);
+ break;
+ case KNOT_RRTYPE_AAAA:
+ knot_aaaa_addr(&ar->rr[i].rrs, 0, &result->ns.addr);
+ break;
+ default:
+ resolution->state = NS_PROC_FAIL;
+ return NS_PROC_FAIL;
+ }
+
+ /* Fill port. */
+ sockaddr_port_set(&result->ns.addr, 53);
+
+ break;
+ }
+ }
+
+ char tmpbuf[512];
+ sockaddr_tostr(&result->ns.addr, tmpbuf, 512);
+ printf("next addr: %s\n", tmpbuf);
+ }
+
+ printf("done\n");
+
+ return NS_PROC_DONE;
+}
+
+/*! \brief Module implementation. */
+static const knot_process_module_t LAYER_ITERATE_MODULE = {
+ &begin,
+ &reset,
+ &finish,
+ &resolve,
+ &knot_process_noop, /* No output. */
+ &knot_process_noop /* No error processing. */
+};
+
+const knot_process_module_t *layer_iterate_module(void)
+{
+ return &LAYER_ITERATE_MODULE;
+}