static int request_recv(struct knot_request *request, const struct timeval *timeout) { knot_pkt_t *resp = request->resp; knot_pkt_clear(resp); /* Each request has unique timeout. */ struct timeval tv = { timeout->tv_sec, timeout->tv_usec }; /* Wait for readability */ int ret = request_ensure_connected(request); if (ret != KNOT_EOK) { return ret; } /* Receive it */ if (use_tcp(request)) { ret = tcp_recv_msg(request->fd, resp->wire, resp->max_size, &tv); } else { ret = udp_recv_msg(request->fd, resp->wire, resp->max_size, &tv); } if (ret <= 0) { resp->size = 0; if (ret == 0) { return KNOT_ECONN; } return ret; } resp->size = ret; return ret; }
/*! \brief Allocate new wireformat of given length. */ static int pkt_wire_alloc(knot_pkt_t *pkt, uint16_t len) { assert(pkt); assert(len >= KNOT_WIRE_HEADER_SIZE); pkt->wire = pkt->mm.alloc(pkt->mm.ctx, len); if (pkt->wire == NULL) { return KNOT_ENOMEM; } pkt->flags |= KNOT_PF_FREE; pkt->max_size = len; knot_pkt_clear(pkt); return KNOT_EOK; }
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 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; }