int main(int argc, char *argv[]) { plan(TESTS_COUNT + 1); mm_ctx_t mm; mm_ctx_mempool(&mm, MM_DEFAULT_BLKSIZE); conf_remote_t remote; memset(&remote, 0, sizeof(conf_remote_t)); sockaddr_set(&remote.addr, AF_INET, "127.0.0.1", 0); sockaddr_set(&remote.via, AF_INET, "127.0.0.1", 0); /* Create fake server environment. */ server_t server; int ret = create_fake_server(&server, &mm); ok(ret == KNOT_EOK, "requestor: initialize fake server"); /* Initialize requestor. */ struct knot_requestor requestor; knot_requestor_init(&requestor, &mm); knot_requestor_overlay(&requestor, &dummy_module, NULL); /* Test requestor in disconnected environment. */ test_disconnected(&requestor, &remote); /* Bind to random port. */ int origin_fd = net_bound_socket(SOCK_STREAM, &remote.addr, 0); assert(origin_fd > 0); socklen_t addr_len = sockaddr_len((struct sockaddr *)&remote.addr); getsockname(origin_fd, (struct sockaddr *)&remote.addr, &addr_len); ret = listen(origin_fd, 10); assert(ret == 0); /* Responder thread. */ pthread_t thread; pthread_create(&thread, 0, responder_thread, &origin_fd); /* Test requestor in connected environment. */ test_connected(&requestor, &remote); /*! \todo #243 TSIG secured requests test should be implemented. */ /* Terminate responder. */ int responder = net_connected_socket(SOCK_STREAM, &remote.addr, NULL, 0); assert(responder > 0); tcp_send_msg(responder, (const uint8_t *)"", 1, NULL); (void) pthread_join(thread, 0); close(responder); /* Close requestor. */ knot_requestor_clear(&requestor); close(origin_fd); /* Cleanup. */ mp_delete((struct mempool *)mm.ctx); server_deinit(&server); conf_free(conf(), false); return 0; }
struct sockaddr_storage conf_addr( conf_val_t *val, const char *sock_base_dir) { assert(val != NULL && val->item != NULL); assert(val->item->type == YP_TADDR || (val->item->type == YP_TREF && val->item->var.r.ref->var.g.id->type == YP_TADDR)); struct sockaddr_storage out = { AF_UNSPEC }; if (val->code == KNOT_EOK) { bool no_port; conf_val(val); out = yp_addr(val->data, &no_port); if (out.ss_family == AF_UNIX) { // val->data[0] is socket type identifier! if (val->data[1] != '/' && sock_base_dir != NULL) { char *tmp = sprintf_alloc("%s/%s", sock_base_dir, val->data + 1); val->code = sockaddr_set(&out, AF_UNIX, tmp, 0); free(tmp); } } else if (no_port) { sockaddr_port_set(&out, val->item->var.a.dflt_port); } } else { const char *dflt_socket = val->item->var.a.dflt_socket; if (dflt_socket != NULL) { if (dflt_socket[0] == '/' || sock_base_dir == NULL) { val->code = sockaddr_set(&out, AF_UNIX, dflt_socket, 0); } else { char *tmp = sprintf_alloc("%s/%s", sock_base_dir, dflt_socket); val->code = sockaddr_set(&out, AF_UNIX, tmp, 0); free(tmp); } } } return out; }
/*! \brief Check if query fits the template requirements. */ static int template_match(int state, synth_template_t *tpl, knot_pkt_t *pkt, struct query_data *qdata) { /* Parse address from query name. */ char addr_str[SOCKADDR_STRLEN] = { '\0' }; int ret = addr_parse(qdata, tpl, addr_str); if (ret != KNOT_EOK) { return state; /* Can't identify addr in QNAME, not applicable. */ } /* Match against template netblock. */ struct sockaddr_storage query_addr = { '\0' }; int provided_af = tpl->subnet.ss.ss_family; ret = sockaddr_set(&query_addr, provided_af, addr_str, 0); if (ret == KNOT_EOK) { ret = netblock_match(&tpl->subnet, &query_addr); } if (ret != 0) { return state; /* Out of our netblock, not applicable. */ } /* Check if the request is for an available query type. */ uint16_t qtype = knot_pkt_qtype(qdata->query); switch (tpl->type) { case SYNTH_FORWARD: if (!query_satisfied_by_family(qtype, provided_af)) { qdata->rcode = KNOT_RCODE_NOERROR; return NODATA; } break; case SYNTH_REVERSE: if (qtype != KNOT_RRTYPE_PTR && qtype != KNOT_RRTYPE_ANY) { qdata->rcode = KNOT_RCODE_NOERROR; return NODATA; } break; default: break; } /* Synthetise record from template. */ knot_rrset_t *rr = synth_rr(addr_str, tpl, pkt, qdata); if (rr == NULL) { qdata->rcode = KNOT_RCODE_SERVFAIL; return ERROR; } /* Insert synthetic response into packet. */ if (knot_pkt_put(pkt, 0, rr, KNOT_PF_FREE) != KNOT_EOK) { return ERROR; } /* Authoritative response. */ knot_wire_set_aa(pkt->wire); return HIT; }
static int rosedb_synth(knot_pkt_t *pkt, const knot_dname_t *key, struct iter *it, struct query_data *qdata) { struct entry entry; int ret = KNOT_EOK; uint16_t qtype = knot_pkt_qtype(qdata->query); /* Answer section. */ while (ret == KNOT_EOK) { if (cache_iter_val(it, &entry) == 0) { ret = rosedb_synth_rr(pkt, &entry, qtype); } if (cache_iter_next(it) != 0) { break; } } /* Authority section. */ knot_pkt_begin(pkt, KNOT_AUTHORITY); /* Not found (zone cut if records exist). */ ret = cache_iter_begin(it, key); while (ret == KNOT_EOK) { if (cache_iter_val(it, &entry) == 0) { ret = rosedb_synth_rr(pkt, &entry, KNOT_RRTYPE_NS); ret = rosedb_synth_rr(pkt, &entry, KNOT_RRTYPE_SOA); } if (cache_iter_next(it) != 0) { break; } } /* Our response is authoritative. */ if (knot_wire_get_nscount(pkt->wire) > 0) { knot_wire_set_aa(pkt->wire); if (knot_wire_get_ancount(pkt->wire) == 0) { qdata->rcode = KNOT_RCODE_NXDOMAIN; } } /* Send message to syslog. */ struct sockaddr_storage syslog_addr; if (sockaddr_set(&syslog_addr, AF_INET, entry.syslog_ip, DEFAULT_PORT) == KNOT_EOK) { int sock = net_unbound_socket(AF_INET, &syslog_addr); if (sock > 0) { rosedb_send_log(sock, (struct sockaddr *)&syslog_addr, pkt, entry.threat_code, qdata); close(sock); } } return ret; }
static int forward_rr(char *addr_str, synth_template_t *tpl, knot_pkt_t *pkt, knot_rrset_t *rr) { struct sockaddr_storage query_addr = {'\0'}; sockaddr_set(&query_addr, tpl->subnet.ss.ss_family, addr_str, 0); /* Specify address type and data. */ if (tpl->subnet.ss.ss_family == AF_INET6) { rr->type = KNOT_RRTYPE_AAAA; const struct sockaddr_in6* ip = (const struct sockaddr_in6*)&query_addr; knot_rrset_add_rdata(rr, (const uint8_t *)&ip->sin6_addr, sizeof(struct in6_addr), tpl->ttl, &pkt->mm); } else if (tpl->subnet.ss.ss_family == AF_INET) { rr->type = KNOT_RRTYPE_A; const struct sockaddr_in* ip = (const struct sockaddr_in*)&query_addr; knot_rrset_add_rdata(rr, (const uint8_t *)&ip->sin_addr, sizeof(struct in_addr), tpl->ttl, &pkt->mm); } else { return KNOT_EINVAL; } return KNOT_EOK; }
int dnsproxy_load(struct query_plan *plan, struct query_module *self) { struct dnsproxy *proxy = mm_alloc(self->mm, sizeof(struct dnsproxy)); if (proxy == NULL) { MODULE_ERR("not enough memory"); return KNOT_ENOMEM; } memset(proxy, 0, sizeof(struct dnsproxy)); /* Determine IPv4/IPv6 */ int family = AF_INET; if (strchr(self->param, ':')) { family = AF_INET6; } int ret = sockaddr_set(&proxy->remote.addr, family, self->param, 53); if (ret != KNOT_EOK) { MODULE_ERR("invalid proxy address: '%s'", self->param); mm_free(self->mm, proxy); return KNOT_EINVAL; } return query_plan_step(plan, QPLAN_BEGIN, dnsproxy_fwd, proxy); }
int main(int argc, char *argv[]) { plan(10); /* Prepare query. */ knot_pkt_t *query = knot_pkt_new(NULL, 512, NULL); if (query == NULL) { return KNOT_ERROR; /* Fatal */ } knot_dname_t *qname = knot_dname_from_str("beef."); int ret = knot_pkt_put_question(query, qname, KNOT_CLASS_IN, KNOT_RRTYPE_A); knot_dname_free(&qname, NULL); if (ret != KNOT_EOK) { knot_pkt_free(&query); return KNOT_ERROR; /* Fatal */ } /* Prepare response */ uint8_t rbuf[65535]; size_t rlen = sizeof(rbuf); memcpy(rbuf, query->wire, query->size); knot_wire_flags_set_qr(rbuf); rrl_req_t rq; rq.w = rbuf; rq.len = rlen; rq.query = query; rq.flags = 0; /* 1. create rrl table */ rrl_table_t *rrl = rrl_create(RRL_SIZE); ok(rrl != NULL, "rrl: create"); /* 2. set rate limit */ uint32_t rate = 10; rrl_setrate(rrl, rate); is_int(rate, rrl_rate(rrl), "rrl: setrate"); /* 3. setlocks */ ret = rrl_setlocks(rrl, RRL_LOCKS); is_int(KNOT_EOK, ret, "rrl: setlocks"); /* 4. N unlimited requests. */ conf_zone_t *zone_conf = malloc(sizeof(conf_zone_t)); conf_init_zone(zone_conf); zone_conf->name = strdup("rrl."); zone_t *zone = zone_new(zone_conf); struct sockaddr_storage addr; struct sockaddr_storage addr6; sockaddr_set(&addr, AF_INET, "1.2.3.4", 0); sockaddr_set(&addr6, AF_INET6, "1122:3344:5566:7788::aabb", 0); ret = 0; for (unsigned i = 0; i < rate; ++i) { if (rrl_query(rrl, &addr, &rq, zone) != KNOT_EOK || rrl_query(rrl, &addr6, &rq, zone) != KNOT_EOK) { ret = KNOT_ELIMIT; break; } } is_int(0, ret, "rrl: unlimited IPv4/v6 requests"); #ifdef ENABLE_TIMED_TESTS /* 5. limited request */ ret = rrl_query(rrl, &addr, &rq, zone); is_int(0, ret, "rrl: throttled IPv4 request"); /* 6. limited IPv6 request */ ret = rrl_query(rrl, &addr6, &rq, zone); is_int(0, ret, "rrl: throttled IPv6 request"); #else skip_block(2, "Timed tests not enabled"); #endif /* 7. invalid values. */ ret = 0; rrl_create(0); // NULL ret += rrl_setrate(0, 0); // 0 ret += rrl_rate(0); // 0 ret += rrl_setlocks(0,0); // -1 ret += rrl_query(0, 0, 0, 0); // -1 ret += rrl_query(rrl, 0, 0, 0); // -1 ret += rrl_query(rrl, (void*)0x1, 0, 0); // -1 ret += rrl_destroy(0); // -1 is_int(-488, ret, "rrl: not crashed while executing functions on NULL context"); #ifdef ENABLE_TIMED_TESTS /* 8. hopscotch test */ struct runnable_data rd = { 1, rrl, &addr, &rq, zone }; rrl_hopscotch(&rd); ok(rd.passed, "rrl: hashtable is ~ consistent"); /* 9. reseed */ is_int(0, rrl_reseed(rrl), "rrl: reseed"); /* 10. hopscotch after reseed. */ rrl_hopscotch(&rd); ok(rd.passed, "rrl: hashtable is ~ consistent"); #else skip_block(3, "Timed tests not enabled"); #endif zone_free(&zone); knot_pkt_free(&query); rrl_destroy(rrl); return 0; }
int main(int argc, char *argv[]) { plan(8*6 + 3); /* exec_query = 6 TAP tests */ /* Create processing context. */ knot_process_t query_ctx; memset(&query_ctx, 0, sizeof(knot_process_t)); mm_ctx_mempool(&query_ctx.mm, sizeof(knot_pkt_t)); /* Create name server. */ server_t server; server_init(&server); server.opt_rr = knot_edns_new(); knot_edns_set_version(server.opt_rr, EDNS_VERSION); knot_edns_set_payload(server.opt_rr, 4096); conf()->identity = strdup("bogus.ns"); conf()->version = strdup("0.11"); /* Insert root zone. */ create_root_zone(&server, &query_ctx.mm); zone_t *zone = knot_zonedb_find(server.zone_db, ROOT_DNAME); /* Prepare. */ int state = NS_PROC_FAIL; uint8_t query_wire[KNOT_WIRE_MAX_PKTSIZE]; uint16_t query_len = KNOT_WIRE_MAX_PKTSIZE; knot_pkt_t *query = knot_pkt_new(query_wire, query_len, &query_ctx.mm); /* Create query processing parameter. */ struct sockaddr_storage ss; memset(&ss, 0, sizeof(struct sockaddr_storage)); sockaddr_set(&ss, AF_INET, "127.0.0.1", 53); struct process_query_param param = {0}; param.query_source = &ss; param.server = &server; /* Query processor (CH zone) */ state = knot_process_begin(&query_ctx, ¶m, NS_PROC_QUERY); const uint8_t chaos_dname[] = "\2""id""\6""server"; /* id.server */ knot_pkt_clear(query); knot_pkt_put_question(query, chaos_dname, KNOT_CLASS_CH, KNOT_RRTYPE_TXT); exec_query(&query_ctx, "CH TXT", query->wire, query->size, KNOT_RCODE_NOERROR); /* Query processor (valid input). */ state = knot_process_reset(&query_ctx); knot_pkt_clear(query); knot_pkt_put_question(query, ROOT_DNAME, KNOT_CLASS_IN, KNOT_RRTYPE_SOA); exec_query(&query_ctx, "IN/root", query->wire, query->size, KNOT_RCODE_NOERROR); /* Query processor (-1 bytes, not enough data). */ state = knot_process_reset(&query_ctx); exec_query(&query_ctx, "IN/few-data", query->wire, query->size - 1, KNOT_RCODE_FORMERR); /* Query processor (+1 bytes trailing). */ state = knot_process_reset(&query_ctx); query->wire[query->size] = '\1'; /* Initialize the "garbage" value. */ exec_query(&query_ctx, "IN/trail-garbage", query->wire, query->size + 1, KNOT_RCODE_FORMERR); /* Forge NOTIFY query from SOA query. */ state = knot_process_reset(&query_ctx); knot_wire_set_opcode(query->wire, KNOT_OPCODE_NOTIFY); exec_query(&query_ctx, "IN/notify", query->wire, query->size, KNOT_RCODE_NOTAUTH); /* Forge AXFR query. */ knot_process_reset(&query_ctx); knot_pkt_clear(query); knot_pkt_put_question(query, ROOT_DNAME, KNOT_CLASS_IN, KNOT_RRTYPE_AXFR); exec_query(&query_ctx, "IN/axfr", query->wire, query->size, KNOT_RCODE_NOTAUTH); /* Forge IXFR query (badly formed, no SOA in AUTHORITY section). */ knot_process_reset(&query_ctx); knot_pkt_clear(query); knot_pkt_put_question(query, ROOT_DNAME, KNOT_CLASS_IN, KNOT_RRTYPE_IXFR); exec_query(&query_ctx, "IN/ixfr-formerr", query->wire, query->size, KNOT_RCODE_FORMERR); /* Forge IXFR query (well formed). */ knot_process_reset(&query_ctx); /* Append SOA RR. */ knot_rrset_t soa_rr = node_rrset(zone->contents->apex, KNOT_RRTYPE_SOA); knot_pkt_begin(query, KNOT_AUTHORITY); knot_pkt_put(query, COMPR_HINT_NONE, &soa_rr, 0); exec_query(&query_ctx, "IN/ixfr", query->wire, query->size, KNOT_RCODE_NOTAUTH); /* \note Tests below are not possible without proper zone and zone data. */ /* #189 Process UPDATE query. */ /* #189 Process AXFR client. */ /* #189 Process IXFR client. */ /* Query processor (smaller than DNS header, ignore). */ state = knot_process_reset(&query_ctx); knot_pkt_clear(query); knot_pkt_put_question(query, ROOT_DNAME, KNOT_CLASS_IN, KNOT_RRTYPE_SOA); state = knot_process_in(query->wire, KNOT_WIRE_HEADER_SIZE - 1, &query_ctx); ok(state == NS_PROC_NOOP, "ns: IN/less-than-header query ignored"); /* Query processor (response, ignore). */ state = knot_process_reset(&query_ctx); knot_wire_set_qr(query->wire); state = knot_process_in(query->wire, query->size, &query_ctx); ok(state == NS_PROC_NOOP, "ns: IN/less-than-header query ignored"); /* Finish. */ state = knot_process_finish(&query_ctx); ok(state == NS_PROC_NOOP, "ns: processing end" ); /* Cleanup. */ mp_delete((struct mempool *)query_ctx.mm.ctx); server_deinit(&server); return 0; }
int synth_record_load(struct query_plan *plan, struct query_module *self) { /* Parse first token. */ char *saveptr = NULL; char *token = strtok_r(self->param, " ", &saveptr); if (token == NULL) { return KNOT_EFEWDATA; } /* Create synthesis template. */ struct synth_template *tpl = mm_alloc(self->mm, sizeof(struct synth_template)); if (tpl == NULL) { return KNOT_ENOMEM; } /* Save in query module, it takes ownership from now on. */ self->ctx = tpl; /* Supported types: reverse, forward */ if (strcmp(token, "reverse") == 0) { tpl->type = SYNTH_REVERSE; } else if (strcmp(token, "forward") == 0) { tpl->type = SYNTH_FORWARD; } else { MODULE_ERR("invalid type '%s'.\n", token); return KNOT_ENOTSUP; } /* Parse format string. */ tpl->prefix = strtok_r(NULL, " ", &saveptr); if (strchr(tpl->prefix, '.') != NULL) { MODULE_ERR("dots '.' are not allowed in the prefix.\n"); return KNOT_EMALF; } /* Parse zone if generating reverse record. */ if (tpl->type == SYNTH_REVERSE) { tpl->zone = strtok_r(NULL, " ", &saveptr); knot_dname_t *check_name = knot_dname_from_str(tpl->zone); if (check_name == NULL) { MODULE_ERR("invalid zone '%s'.\n", tpl->zone); return KNOT_EMALF; } knot_dname_free(&check_name, NULL); } /* Parse TTL. */ tpl->ttl = strtol(strtok_r(NULL, " ", &saveptr), NULL, 10); /* Parse address. */ token = strtok_r(NULL, " ", &saveptr); char *subnet = strchr(token, '/'); if (subnet) { subnet[0] = '\0'; tpl->subnet.prefix = strtol(subnet + 1, NULL, 10); } /* Estimate family. */ int family = AF_INET; int prefix_max = IPV4_PREFIXLEN; if (strchr(token, ':') != NULL) { family = AF_INET6; prefix_max = IPV6_PREFIXLEN; } /* Check subnet. */ if (tpl->subnet.prefix > prefix_max) { MODULE_ERR("invalid address prefix '%s'.\n", subnet); return KNOT_EMALF; } int ret = sockaddr_set(&tpl->subnet.ss, family, token, 0); if (ret != KNOT_EOK) { MODULE_ERR("invalid address '%s'.\n", token); return KNOT_EMALF; } return query_plan_step(plan, QPLAN_ANSWER, solve_synth_record, tpl); }
/*! Run all scheduled tests for given parameters. */ int main(int argc, char *argv[]) { plan(19); // Test 1: Allocate new config const char *config_fn = "rc:/sample_conf"; conf_t *conf = conf_new(strdup(config_fn)); ok(conf != 0, "config_new()"); // Test 2: Parse config int ret = conf_parse_str(conf, sample_conf_rc); is_int(0, ret, "parsing configuration file %s", config_fn); if (ret != 0) { skip_block(19, "Parse err"); goto skip_all; } // Test 3: Test server version (0-level depth) is_string("Infinitesimal", conf->version, "server version loaded ok"); // Test 4: Test interfaces (1-level depth) ok(!EMPTY_LIST(conf->ifaces), "configured interfaces exist"); // Test 5,6: Interfaces content (2-level depth) struct node *n = HEAD(conf->ifaces); conf_iface_t *iface = (conf_iface_t*)n; struct sockaddr_storage addr_ref; sockaddr_set(&addr_ref, AF_INET, "10.10.1.1", 53531); is_int(0, sockaddr_cmp(&iface->addr, &addr_ref), "interface0 address check"); n = n->next; iface = (conf_iface_t*)n; sockaddr_set(&addr_ref, AF_INET6, "::0", 53); is_int(0, sockaddr_cmp(&iface->addr, &addr_ref), "interface1 address check"); // Test 9,10: Check server key if (EMPTY_LIST(conf->keys)) { ok(0, "TSIG key algorithm check - NO KEY FOUND"); ok(0, "TSIG key secret check - NO KEY FOUND"); } else { knot_tsig_key_t *k = &((conf_key_t *)HEAD(conf->keys))->k; uint8_t decoded_secret[] = { 0x5a }; ok(k->algorithm == KNOT_TSIG_ALG_HMAC_MD5, "TSIG key algorithm check"); ok(k->secret.size == sizeof(decoded_secret) && memcmp(k->secret.data, decoded_secret, sizeof(decoded_secret)) == 0, "TSIG key secret check"); } // Test 11,12,13,14,15,16,17,18: Check logging facilities ok(list_size(&conf->logs) == 4, "log facilites count check"); n = HEAD(conf->logs); ok(!EMPTY_LIST(conf->logs), "log facilities not empty"); conf_log_t *log = (conf_log_t*)n; node_t *nm = HEAD(log->map); conf_log_map_t *m = (conf_log_map_t*)nm; ok(log->type == LOGT_SYSLOG, "log0 is syslog"); if (EMPTY_LIST(log->map)) { skip_block(5, "Empty list"); } else { ok(m->source == LOG_ANY, "syslog first rule is ANY"); int mask = LOG_UPTO(LOG_NOTICE); ok(m->prios == mask, "syslog mask is equal"); nm = nm->next; m = (conf_log_map_t*)nm; ok(m != 0, "syslog has more than 1 rule"); if (m == 0) { skip_block(2, "No mapping"); } else { ok(m->source == LOG_ZONE, "syslog next rule is for zone"); ok(m->prios == LOG_UPTO(LOG_INFO), "rule for zone is: info level"); } } // Test 19,20: File facility checks n = n->next; log = (conf_log_t*)n; ok(n != 0, "log has next facility"); if (n == 0) { skip("No mapping"); } else { is_string("/var/log/knot/server.err", log->file, "log file matches"); } // Test 21: Load key dname const char *sample_str = "key0.example.net"; knot_dname_t *sample = knot_dname_from_str_alloc(sample_str); if (list_size(&conf->keys) > 0) { knot_tsig_key_t *k = &((conf_key_t *)HEAD(conf->keys))->k; ok(knot_dname_cmp(sample, k->name) == 0, "TSIG key dname check"); } else { ok(0, "TSIG key dname check - NO KEY FOUND"); } knot_dname_free(&sample, NULL); skip_all: // Deallocating config conf_free(conf); return 0; }
static int parse_addr_str(struct sockaddr_storage *sa, const char *addr) { int family = strchr(addr, ':') ? AF_INET6 : AF_INET; return sockaddr_set(sa, family, addr, 0); }
int main(int argc, char *argv[]) { plan(8*6 + 4); /* exec_query = 6 TAP tests */ knot_mm_t mm; mm_ctx_mempool(&mm, MM_DEFAULT_BLKSIZE); /* Create processing context. */ knot_layer_t proc; memset(&proc, 0, sizeof(knot_layer_t)); proc.mm = &mm; /* Create fake server environment. */ server_t server; int ret = create_fake_server(&server, proc.mm); ok(ret == KNOT_EOK, "ns: fake server initialization"); zone_t *zone = knot_zonedb_find(server.zone_db, ROOT_DNAME); /* Prepare. */ knot_pkt_t *query = knot_pkt_new(NULL, KNOT_WIRE_MAX_PKTSIZE, proc.mm); /* Create query processing parameter. */ struct sockaddr_storage ss; memset(&ss, 0, sizeof(struct sockaddr_storage)); sockaddr_set(&ss, AF_INET, "127.0.0.1", 53); struct process_query_param param = {0}; param.remote = &ss; param.server = &server; /* Query processor (CH zone) */ knot_layer_begin(&proc, NS_PROC_QUERY, ¶m); knot_pkt_clear(query); knot_pkt_put_question(query, IDSERVER_DNAME, KNOT_CLASS_CH, KNOT_RRTYPE_TXT); exec_query(&proc, "CH TXT", query, KNOT_RCODE_NOERROR); /* Query processor (valid input). */ knot_layer_reset(&proc); knot_pkt_clear(query); knot_pkt_put_question(query, ROOT_DNAME, KNOT_CLASS_IN, KNOT_RRTYPE_SOA); exec_query(&proc, "IN/root", query, KNOT_RCODE_NOERROR); /* Query processor (-1 bytes, not enough data). */ knot_layer_reset(&proc); query->size -= 1; exec_query(&proc, "IN/few-data", query, KNOT_RCODE_FORMERR); query->size += 1; /* Query processor (+1 bytes trailing). */ knot_layer_reset(&proc); query->wire[query->size] = '\1'; /* Initialize the "garbage" value. */ query->size += 1; exec_query(&proc, "IN/trail-garbage", query, KNOT_RCODE_FORMERR); query->size -= 1; /* Forge NOTIFY query from SOA query. */ knot_layer_reset(&proc); knot_wire_set_opcode(query->wire, KNOT_OPCODE_NOTIFY); exec_query(&proc, "IN/notify", query, KNOT_RCODE_NOTAUTH); /* Forge AXFR query. */ knot_layer_reset(&proc); knot_pkt_clear(query); knot_pkt_put_question(query, ROOT_DNAME, KNOT_CLASS_IN, KNOT_RRTYPE_AXFR); exec_query(&proc, "IN/axfr", query, KNOT_RCODE_NOTAUTH); /* Forge IXFR query (badly formed, no SOA in AUTHORITY section). */ knot_layer_reset(&proc); knot_pkt_clear(query); knot_pkt_put_question(query, ROOT_DNAME, KNOT_CLASS_IN, KNOT_RRTYPE_IXFR); exec_query(&proc, "IN/ixfr-formerr", query, KNOT_RCODE_FORMERR); /* Forge IXFR query (well formed). */ knot_layer_reset(&proc); knot_pkt_clear(query); knot_pkt_put_question(query, ROOT_DNAME, KNOT_CLASS_IN, KNOT_RRTYPE_IXFR); /* Append SOA RR. */ knot_rrset_t soa_rr = node_rrset(zone->contents->apex, KNOT_RRTYPE_SOA); knot_pkt_begin(query, KNOT_AUTHORITY); knot_pkt_put(query, KNOT_COMPR_HINT_NONE, &soa_rr, 0); exec_query(&proc, "IN/ixfr", query, KNOT_RCODE_NOTAUTH); /* \note Tests below are not possible without proper zone and zone data. */ /* #189 Process UPDATE query. */ /* #189 Process AXFR client. */ /* #189 Process IXFR client. */ /* Query processor (smaller than DNS header, ignore). */ knot_layer_reset(&proc); knot_pkt_clear(query); knot_pkt_put_question(query, ROOT_DNAME, KNOT_CLASS_IN, KNOT_RRTYPE_SOA); size_t orig_query_size = query->size; query->size = KNOT_WIRE_HEADER_SIZE - 1; int state = knot_layer_consume(&proc, query); ok(state == KNOT_STATE_NOOP, "ns: IN/less-than-header query ignored"); query->size = orig_query_size; /* Query processor (response, ignore). */ knot_layer_reset(&proc); knot_wire_set_qr(query->wire); state = knot_layer_consume(&proc, query); ok(state == KNOT_STATE_NOOP, "ns: IN/less-than-header query ignored"); /* Finish. */ state = knot_layer_finish(&proc); ok(state == KNOT_STATE_NOOP, "ns: processing end" ); /* Cleanup. */ mp_delete((struct mempool *)mm.ctx); server_deinit(&server); conf_free(conf()); return 0; }