Skip to content
Snippets Groups Projects
Commit 89ad4954 authored by Marek Vavruša's avatar Marek Vavruša
Browse files

requestor: changed API to allow multiple requests with different endpoints

no TSIG yet
parent 9871b35f
No related branches found
No related tags found
1 merge request!232Zone events queue
......@@ -125,6 +125,8 @@ src/knot/nameserver/process_query.c
src/knot/nameserver/process_query.h
src/knot/nameserver/query_module.c
src/knot/nameserver/query_module.h
src/knot/nameserver/requestor.c
src/knot/nameserver/requestor.h
src/knot/nameserver/update.c
src/knot/nameserver/update.h
src/knot/other/debug.h
......@@ -308,6 +310,7 @@ tests/pkt.c
tests/process_answer.c
tests/process_query.c
tests/query_module.c
tests/requestor.c
tests/rrl.c
tests/rrset.c
tests/sample_conf.h
......
......@@ -23,6 +23,7 @@ struct request {
node_t node;
int fd;
int state;
const struct sockaddr_storage *remote, *origin;
knot_pkt_t *query;
knot_process_t process;
uint8_t *pkt_buf;
......@@ -118,12 +119,13 @@ static int request_recv(struct request *request, struct timeval *timeout)
return NS_PROC_FAIL;
}
return KNOT_EOK;
return ret;
}
void requestor_init(struct requestor *requestor, mm_ctx_t *mm)
void requestor_init(struct requestor *requestor, const knot_process_module_t *module, mm_ctx_t *mm)
{
memset(requestor, 0, sizeof(struct requestor));
requestor->module = module;
requestor->mm = mm;
init_list(&requestor->pending);
}
......@@ -139,33 +141,47 @@ bool requestor_finished(struct requestor *requestor)
return requestor == NULL || EMPTY_LIST(requestor->pending);
}
int requestor_enqueue(struct requestor *requestor, knot_pkt_t *query,
const knot_process_module_t *module, void *param)
struct request *requestor_make(struct requestor *requestor,
const struct sockaddr_storage *from,
const struct sockaddr_storage *to,
knot_pkt_t *query)
{
if (requestor == NULL || query == NULL || to == NULL) {
return NULL;
}
/* Form a pending request. */
struct request *request = request_make(requestor->mm);
if (request == NULL) {
return NULL;
}
request->origin = from;
request->remote = to;
request->fd = -1;
request->query = query;
return request;
}
int requestor_enqueue(struct requestor *requestor, struct request * request, void *param)
{
if (requestor == NULL || query == NULL) {
if (requestor == NULL || request == NULL) {
return KNOT_EINVAL;
}
/* Fetch a bound socket. */
int fd = net_connected_socket(SOCK_STREAM, requestor->remote,
requestor->origin, O_NONBLOCK);
int fd = net_connected_socket(SOCK_STREAM, request->remote,
request->origin, O_NONBLOCK);
if (fd < 0) {
return KNOT_ECONN;
}
/* Form a pending request. */
struct request *request = request_make(requestor->mm);
if (request == NULL) {
close(fd);
return KNOT_ENOMEM;
}
request->fd = fd;
request->query = query;
request->state = NS_PROC_FULL; /* We have a query to be sent. */
memcpy(&request->process.mm, requestor->mm, sizeof(mm_ctx_t));
knot_process_begin(&request->process, param, module);
knot_process_begin(&request->process, param, requestor->module);
add_tail(&requestor->pending, &request->node);
......@@ -198,15 +214,18 @@ static int exec_request(struct request *last, struct timeval *timeout)
/* Receive and process expected answers. */
while(last->state == NS_PROC_MORE) {
ret = request_recv(last, timeout);
if (ret != KNOT_EOK) {
return ret;
int rcvd = request_recv(last, timeout);
if (rcvd <= 0) {
return rcvd;
}
last->state = knot_process_in(last->pkt_buf, ret, &last->process);
last->state = knot_process_in(last->pkt_buf, rcvd, &last->process);
if (last->state == NS_PROC_FAIL) {
return KNOT_ERROR;
}
}
return ret;
return KNOT_EOK;
}
int requestor_exec(struct requestor *requestor, struct timeval *timeout)
......
......@@ -20,13 +20,15 @@
#include "knot/nameserver/process_answer.h"
#include "common/lists.h"
struct request;
/*! \brief Requestor structure.
*
* Requestor holds a FIFO of pending queries with given remote.
*/
struct requestor {
/* Requestor target and source address. */
const struct sockaddr_storage *remote, *origin;
const knot_process_module_t *module;
//knot_sign_context_t tsig; /* @note not implemented */
......@@ -37,7 +39,7 @@ struct requestor {
/*!
* \brief Initialize requestor structure.
*/
void requestor_init(struct requestor *requestor, mm_ctx_t *mm);
void requestor_init(struct requestor *requestor, const knot_process_module_t *module, mm_ctx_t *mm);
/*!
* \brief Clear the requestor structure and close pending queries.
......@@ -47,6 +49,13 @@ void requestor_clear(struct requestor *requestor);
/*! \brief Return true if there are no pending queries. */
bool requestor_finished(struct requestor *requestor);
/*! \brief Make request out of endpoints and query. */
struct request *requestor_make(struct requestor *requestor,
const struct sockaddr_storage *from,
const struct sockaddr_storage *to,
knot_pkt_t *query);
/*!
* \brief Enqueue a query for processing.
*
......@@ -60,8 +69,7 @@ bool requestor_finished(struct requestor *requestor);
*
* \return KNOT_EOK or error
*/
int requestor_enqueue(struct requestor *requestor, knot_pkt_t *query,
const knot_process_module_t *module, void *param);
int requestor_enqueue(struct requestor *requestor, struct request *request, void *param);
/*!
* \brief Close first pending request.
......
......@@ -64,18 +64,19 @@ static void* responder_thread(void *arg)
#define CONNECTED_TESTS 4
#define TESTS_COUNT DISCONNECTED_TESTS + CONNECTED_TESTS
static knot_pkt_t *make_query(mm_ctx_t *mm)
static struct request *make_query(struct requestor *requestor, struct sockaddr_storage *remote)
{
knot_pkt_t *pkt = knot_pkt_new(NULL, KNOT_WIRE_MAX_PKTSIZE, mm);
knot_pkt_t *pkt = knot_pkt_new(NULL, KNOT_WIRE_MAX_PKTSIZE, requestor->mm);
assert(pkt);
knot_pkt_put_question(pkt, ROOT_DNAME, KNOT_CLASS_IN, KNOT_RRTYPE_SOA);
return pkt;
return requestor_make(requestor, NULL, remote, pkt);
}
static void test_disconnected(struct requestor *requestor)
static void test_disconnected(struct requestor *requestor, struct sockaddr_storage *remote)
{
/* Enqueue packet. */
int ret = requestor_enqueue(requestor, make_query(requestor->mm), &dummy_module, NULL);
int ret = requestor_enqueue(requestor, make_query(requestor, remote), NULL);
is_int(KNOT_EOK, ret, "requestor: disconnected/enqueue");
/* Wait for completion. */
......@@ -84,10 +85,10 @@ static void test_disconnected(struct requestor *requestor)
is_int(KNOT_ECONNREFUSED, ret, "requestor: disconnected/wait");
}
static void test_connected(struct requestor *requestor)
static void test_connected(struct requestor *requestor, struct sockaddr_storage *remote)
{
/* Enqueue packet. */
int ret = requestor_enqueue(requestor, make_query(requestor->mm), &dummy_module, NULL);
int ret = requestor_enqueue(requestor, make_query(requestor, remote), NULL);;
is_int(KNOT_EOK, ret, "requestor: connected/enqueue");
/* Wait for completion. */
......@@ -98,7 +99,7 @@ static void test_connected(struct requestor *requestor)
/* Enqueue multiple queries. */
ret = KNOT_EOK;
for (unsigned i = 0; i < 10; ++i) {
ret |= requestor_enqueue(requestor, make_query(requestor->mm), &dummy_module, NULL);
ret |= requestor_enqueue(requestor, make_query(requestor, remote), NULL);;
}
is_int(KNOT_EOK, ret, "requestor: multiple enqueue");
......@@ -127,12 +128,10 @@ int main(int argc, char *argv[])
/* Initialize requestor. */
struct requestor requestor;
requestor_init(&requestor, &mm);
requestor.remote = &remote;
requestor.origin = NULL;
requestor_init(&requestor, &dummy_module, &mm);
/* Test requestor in disconnected environment. */
test_disconnected(&requestor);
test_disconnected(&requestor, &remote);
/* Bind to random port. */
int origin_fd = net_bound_socket(SOCK_STREAM, &remote);
......@@ -147,7 +146,7 @@ int main(int argc, char *argv[])
pthread_create(&thread, 0, responder_thread, &origin_fd);
/* Test requestor in connected environment. */
test_connected(&requestor);
test_connected(&requestor, &remote);
/* TSIG secured. */
#warning TODO: when ported sign_packet/verify_packet
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment