/** Set UDP maximum payload size. */ static int net_bufsize(lua_State *L) { struct engine *engine = engine_luaget(L); knot_rrset_t *opt_rr = engine->resolver.opt_rr; if (!lua_isnumber(L, 1)) { lua_pushnumber(L, knot_edns_get_payload(opt_rr)); return 1; } int bufsize = lua_tointeger(L, 1); if (bufsize < KNOT_EDNS_MIN_DNSSEC_PAYLOAD || bufsize > UINT16_MAX) { format_error(L, "bufsize must be within <1220, 65535>"); lua_error(L); } knot_edns_set_payload(opt_rr, (uint16_t) bufsize); 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; }
static bool test_setters(knot_rrset_t *opt_rr, int *done) { assert(opt_rr != NULL); assert(done != NULL); /* Header-related setters. */ knot_edns_set_payload(opt_rr, E_MAX_PLD2); knot_edns_set_ext_rcode(opt_rr, E_RCODE2); knot_edns_set_version(opt_rr, E_VERSION2); knot_edns_set_do(opt_rr); bool success = true; bool check = check_header(opt_rr, E_MAX_PLD2, E_VERSION2, DO_FLAG, E_RCODE2, "OPT RR setters", done); success &= check; /* OPTION(RDATA)-related setters. */ /* Proper option. */ int ret = knot_edns_add_option(opt_rr, KNOT_EDNS_OPTION_NSID, E_NSID_LEN, (uint8_t *)E_NSID_STR, NULL); ok(ret == KNOT_EOK, "OPT RR setters: add option with data (ret = %s)", knot_strerror(ret)); (*done)++; /* Wrong argument: no OPT RR. */ ret = knot_edns_add_option(NULL, E_OPT3_CODE, E_OPT3_FAKE_LEN, (uint8_t *)E_OPT3_FAKE_DATA, NULL); ok(ret == KNOT_EINVAL, "OPT RR setters: add option (rr == NULL) " "(ret = %s)", knot_strerror(ret)); (*done)++; /* Wrong argument: option length != 0 && data == NULL. */ ret = knot_edns_add_option(opt_rr, E_OPT3_CODE, E_OPT3_FAKE_LEN, NULL, NULL); ok(ret == KNOT_EINVAL, "OPT RR setters: add option (data == NULL, " "len != 0) (ret = %s)", knot_strerror(ret)); (*done)++; /* Empty OPTION (length 0, data != NULL). */ ret = knot_edns_add_option(opt_rr, E_OPT3_CODE, E_OPT3_LEN, (uint8_t *)E_OPT3_FAKE_DATA, NULL); ok(ret == KNOT_EOK, "OPT RR setters: add empty option 1 (ret = %s)", knot_strerror(ret)); (*done)++; /* Empty OPTION (length 0, data == NULL). */ ret = knot_edns_add_option(opt_rr, E_OPT4_CODE, E_OPT4_LEN, (uint8_t *)E_OPT4_DATA, NULL); ok(ret == KNOT_EOK, "OPT RR setters: add empty option 2 (ret = %s)", knot_strerror(ret)); (*done)++; knot_rdata_t *rdata = knot_rdataset_at(&opt_rr->rrs, 0); if (rdata == NULL) { skip_block(2, "No RDATA in OPT RR."); return false; } /* Check proper option */ check = check_option(rdata, KNOT_EDNS_OPTION_NSID, E_NSID_LEN, (uint8_t *)E_NSID_STR, "OPT RR setters (proper option)", done); success &= check; /* Check empty option 1 */ check = check_option(rdata, E_OPT3_CODE, E_OPT3_LEN, (uint8_t *)E_OPT3_DATA, "OPT RR setters (empty option 1)", done); success &= check; /* Check empty option 2 */ check = check_option(rdata, E_OPT4_CODE, E_OPT4_LEN, (uint8_t *)E_OPT4_DATA, "OPT RR setters (empty option 2)", done); success &= check; return success; }