diff options
Diffstat (limited to 'daemon/worker.h')
-rw-r--r-- | daemon/worker.h | 171 |
1 files changed, 171 insertions, 0 deletions
diff --git a/daemon/worker.h b/daemon/worker.h new file mode 100644 index 0000000..f56e10d --- /dev/null +++ b/daemon/worker.h @@ -0,0 +1,171 @@ +/* Copyright (C) 2014-2017 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +#pragma once + +#include "daemon/engine.h" +#include "lib/generic/array.h" +#include "lib/generic/map.h" + + +/** Query resolution task (opaque). */ +struct qr_task; +/** Worker state (opaque). */ +struct worker_ctx; +/** Transport session (opaque). */ +struct session; +/** Zone import context (opaque). */ +struct zone_import_ctx; + +/** Create and initialize the worker. */ +struct worker_ctx *worker_create(struct engine *engine, knot_mm_t *pool, + int worker_id, int worker_count); + +/** + * Process an incoming packet (query from a client or answer from upstream). + * + * @param session session the where packet came from + * @param query the packet, or NULL on an error from the transport layer + * @return 0 or an error code + */ +int worker_submit(struct session *session, knot_pkt_t *query); + +/** + * End current DNS/TCP session, this disassociates pending tasks from this session + * which may be freely closed afterwards. + */ +int worker_end_tcp(struct session *session); + +/** + * Start query resolution with given query. + * + * @return task or NULL + */ +struct qr_task *worker_resolve_start(struct worker_ctx *worker, knot_pkt_t *query, struct kr_qflags options); + +/** + * Execute a request with given query. + * It expects task to be created with \fn worker_resolve_start. + * + * @return 0 or an error code + */ +int worker_resolve_exec(struct qr_task *task, knot_pkt_t *query); + +/** @return struct kr_request associated with opaque task */ +struct kr_request *worker_task_request(struct qr_task *task); + +/** Collect worker mempools */ +void worker_reclaim(struct worker_ctx *worker); + +int worker_task_step(struct qr_task *task, const struct sockaddr *packet_source, + knot_pkt_t *packet); + +int worker_task_numrefs(const struct qr_task *task); + +/** Finalize given task */ +int worker_task_finalize(struct qr_task *task, int state); + +void worker_task_complete(struct qr_task *task); + +void worker_task_ref(struct qr_task *task); + +void worker_task_unref(struct qr_task *task); + +void worker_task_timeout_inc(struct qr_task *task); + +int worker_add_tcp_connected(struct worker_ctx *worker, + const struct sockaddr *addr, + struct session *session); +int worker_del_tcp_connected(struct worker_ctx *worker, + const struct sockaddr *addr); +int worker_del_tcp_waiting(struct worker_ctx *worker, + const struct sockaddr* addr); +knot_pkt_t *worker_task_get_pktbuf(const struct qr_task *task); + +struct request_ctx *worker_task_get_request(struct qr_task *task); + +struct session *worker_request_get_source_session(struct request_ctx *); + +void worker_request_set_source_session(struct request_ctx *, struct session *session); + +uint16_t worker_task_pkt_get_msgid(struct qr_task *task); +void worker_task_pkt_set_msgid(struct qr_task *task, uint16_t msgid); +uint64_t worker_task_creation_time(struct qr_task *task); +void worker_task_subreq_finalize(struct qr_task *task); +bool worker_task_finished(struct qr_task *task); + +/** @cond internal */ + +/** Number of request within timeout window. */ +#define MAX_PENDING KR_NSREP_MAXADDR + +/** Maximum response time from TCP upstream, milliseconds */ +#define MAX_TCP_INACTIVITY (KR_RESOLVE_TIME_LIMIT + KR_CONN_RTT_MAX) + +#ifndef RECVMMSG_BATCH /* see check_bufsize() */ +#define RECVMMSG_BATCH 1 +#endif + +/** Freelist of available mempools. */ +typedef array_t(struct mempool *) mp_freelist_t; + +/** List of query resolution tasks. */ +typedef array_t(struct qr_task *) qr_tasklist_t; + +/** \details Worker state is meant to persist during the whole life of daemon. */ +struct worker_ctx { + struct engine *engine; + uv_loop_t *loop; + int id; + int count; + int vars_table_ref; + unsigned tcp_pipeline_max; + + /** Addresses to bind for outgoing connections or AF_UNSPEC. */ + struct sockaddr_in out_addr4; + struct sockaddr_in6 out_addr6; + + uint8_t wire_buf[RECVMMSG_BATCH * KNOT_WIRE_MAX_PKTSIZE]; + + struct { + size_t concurrent; + size_t rconcurrent; + size_t udp; + size_t tcp; + size_t tls; + size_t ipv4; + size_t ipv6; + size_t queries; + size_t dropped; + size_t timeout; + } stats; + + struct zone_import_ctx* z_import; + bool too_many_open; + size_t rconcurrent_highwatermark; + /** List of active outbound TCP sessions */ + map_t tcp_connected; + /** List of outbound TCP sessions waiting to be accepted */ + map_t tcp_waiting; + /** Subrequest leaders (struct qr_task*), indexed by qname+qtype+qclass. */ + trie_t *subreq_out; + mp_freelist_t pool_mp; + knot_mm_t pkt_pool; + unsigned int next_request_uid; +}; + +/** @endcond */ + |