]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
daemon/worker.c: replace asserts
authorTomas Krizek <tomas.krizek@nic.cz>
Wed, 24 Mar 2021 16:44:43 +0000 (17:44 +0100)
committerTomas Krizek <tomas.krizek@nic.cz>
Tue, 25 May 2021 12:39:37 +0000 (14:39 +0200)
daemon/worker.c

index a070ee78210517d8131e41e26b1a6734a707ef2a..9f2bc2426c7ec78113090a87dacb2b2344e9ca0e 100644 (file)
@@ -16,7 +16,6 @@
 #if defined(__GLIBC__) && defined(_GNU_SOURCE)
 #include <malloc.h>
 #endif
-#include <assert.h>
 #include <sys/types.h>
 #include <unistd.h>
 #include <gnutls/gnutls.h>
@@ -100,7 +99,7 @@ struct qr_task
 #define qr_task_unref(task) \
        do { \
                if (task) \
-                       assert((task)->refs > 0); \
+                       kr_require((task)->refs > 0); \
                if ((task) && --(task)->refs == 0) \
                        qr_task_free((task)); \
        } while (0)
@@ -142,8 +141,7 @@ static uv_handle_t *ioreq_spawn(struct worker_ctx *worker,
 {
        bool precond = (socktype == SOCK_DGRAM || socktype == SOCK_STREAM)
                        && (family == AF_INET  || family == AF_INET6);
-       if (!precond) {
-               assert(false);
+       if (!kr_assume(precond)) {
                kr_log_verbose("[work] ioreq_spawn: pre-condition failed\n");
                return NULL;
        }
@@ -172,7 +170,10 @@ static uv_handle_t *ioreq_spawn(struct worker_ctx *worker,
                addr = (union inaddr *)&worker->out_addr6;
        }
        if (addr->ip.sa_family != AF_UNSPEC) {
-               assert(addr->ip.sa_family == family);
+               if (!kr_assume(addr->ip.sa_family == family)) {
+                       io_free(handle);
+                       return NULL;
+               }
                if (socktype == SOCK_DGRAM) {
                        uv_udp_t *udp = (uv_udp_t *)handle;
                        ret = uv_udp_bind(udp, &addr->ip, 0);
@@ -259,7 +260,7 @@ static inline void pool_release(struct worker_ctx *worker, struct mempool *mp)
 static const size_t SUBREQ_KEY_LEN = KR_RRKEY_LEN;
 static int subreq_key(char *dst, knot_pkt_t *pkt)
 {
-       assert(pkt);
+       kr_require(pkt);
        return kr_rrkey(dst, knot_pkt_qclass(pkt), knot_pkt_qname(pkt),
                        knot_pkt_qtype(pkt), knot_pkt_qtype(pkt));
 }
@@ -267,11 +268,13 @@ static int subreq_key(char *dst, knot_pkt_t *pkt)
 #if ENABLE_XDP
 static uint8_t *alloc_wire_cb(struct kr_request *req, uint16_t *maxlen)
 {
-       assert(maxlen);
+       if (!kr_assume(maxlen))
+               return NULL;
        struct request_ctx *ctx = (struct request_ctx *)req;
        /* We know it's an AF_XDP socket; otherwise this CB isn't assigned. */
        uv_handle_t *handle = session_get_handle(ctx->source.session);
-       assert(handle->type == UV_POLL);
+       if (!kr_assume(handle->type == UV_POLL))
+               return NULL;
        xdp_handle_data_t *xhd = handle->data;
        knot_xdp_msg_t out;
        bool ipv6 = ctx->source.addr.ip.sa_family == AF_INET6;
@@ -282,7 +285,7 @@ static uint8_t *alloc_wire_cb(struct kr_request *req, uint16_t *maxlen)
                                        ipv6, &out, NULL);
                        #endif
        if (ret != KNOT_EOK) {
-               assert(ret == KNOT_ENOMEM);
+               (void)!kr_assume(ret == KNOT_ENOMEM);
                *maxlen = 0;
                return NULL;
        }
@@ -294,7 +297,8 @@ static uint8_t *alloc_wire_cb(struct kr_request *req, uint16_t *maxlen)
 }
 static void free_wire(const struct request_ctx *ctx)
 {
-       assert(ctx->req.alloc_wire_cb == alloc_wire_cb);
+       if (!kr_assume(ctx->req.alloc_wire_cb == alloc_wire_cb))
+               return;
        knot_pkt_t *ans = ctx->req.answer;
        if (unlikely(ans == NULL)) /* dropped */
                return;
@@ -302,7 +306,8 @@ static void free_wire(const struct request_ctx *ctx)
                return;
        /* We know it's an AF_XDP socket; otherwise alloc_wire_cb isn't assigned. */
        uv_handle_t *handle = session_get_handle(ctx->source.session);
-       assert(handle->type == UV_POLL);
+       if (!kr_assume(handle->type == UV_POLL))
+               return;
        xdp_handle_data_t *xhd = handle->data;
        /* Freeing is done by sending an empty packet (the API won't really send it). */
        knot_xdp_msg_t out;
@@ -310,7 +315,7 @@ static void free_wire(const struct request_ctx *ctx)
        out.payload.iov_len = 0;
        uint32_t sent;
        int ret = knot_xdp_send(xhd->socket, &out, 1, &sent);
-       assert(ret == KNOT_EOK && sent == 0); (void)ret;
+       (void)!kr_assume(ret == KNOT_EOK && sent == 0);
        kr_log_verbose("[xdp] freed unsent buffer, ret = %d\n", ret);
 }
 #endif
@@ -355,20 +360,28 @@ static struct request_ctx *request_create(struct worker_ctx *worker,
 
        /* TODO Relocate pool to struct request */
        ctx->worker = worker;
-       if (session) {
-               assert(session_flags(session)->outgoing == false);
+       if (session && !kr_assume(session_flags(session)->outgoing == false)) {
+               pool_release(worker, pool.ctx);
+               return NULL;
        }
        ctx->source.session = session;
-       assert(!!eth_to == !!eth_from);
+       if (!kr_assume(!!eth_to == !!eth_from)) {
+               pool_release(worker, pool.ctx);
+               return NULL;
+       }
        const bool is_xdp = eth_to != NULL;
        if (is_xdp) {
        #if ENABLE_XDP
-               assert(session);
+               if (!kr_assume(session)) {
+                       pool_release(worker, pool.ctx);
+                       return NULL;
+               }
                memcpy(&ctx->source.eth_addrs[0], eth_to,   sizeof(ctx->source.eth_addrs[0]));
                memcpy(&ctx->source.eth_addrs[1], eth_from, sizeof(ctx->source.eth_addrs[1]));
                ctx->req.alloc_wire_cb = alloc_wire_cb;
        #else
-               assert(!EINVAL);
+               (void)!kr_assume(!EINVAL);
+               pool_release(worker, pool.ctx);
                return NULL;
        #endif
        }
@@ -419,7 +432,8 @@ static struct request_ctx *request_create(struct worker_ctx *worker,
 /** More initialization, related to the particular incoming query/packet. */
 static int request_start(struct request_ctx *ctx, knot_pkt_t *query)
 {
-       assert(query && ctx);
+       if (!kr_assume(query && ctx))
+               return kr_error(EINVAL);
 
        struct kr_request *req = &ctx->req;
        req->qsource.size = query->size;
@@ -475,7 +489,7 @@ static void request_free(struct request_ctx *ctx)
        #if ENABLE_XDP
                free_wire(ctx);
        #else
-               assert(!EINVAL);
+               (void)!kr_assume(!EINVAL);
        #endif
        }
        /* Return mempool to ring or free it if it's full */
@@ -513,7 +527,7 @@ static struct qr_task *qr_task_create(struct request_ctx *ctx)
        task->pktbuf = pktbuf;
        array_init(task->waiting);
        task->refs = 0;
-       assert(ctx->task == NULL);
+       (void)!kr_assume(ctx->task == NULL);
        ctx->task = task;
        /* Make the primary reference to task. */
        qr_task_ref(task);
@@ -527,7 +541,8 @@ static void qr_task_free(struct qr_task *task)
 {
        struct request_ctx *ctx = task->ctx;
 
-       assert(ctx);
+       if (!kr_assume(ctx))
+               return;
 
        struct worker_ctx *worker = ctx->worker;
 
@@ -542,12 +557,14 @@ static void qr_task_free(struct qr_task *task)
 /*@ Register new qr_task within session. */
 static int qr_task_register(struct qr_task *task, struct session *session)
 {
-       assert(!session_flags(session)->outgoing && session_get_handle(session)->type == UV_TCP);
+       if (!kr_assume(!session_flags(session)->outgoing && session_get_handle(session)->type == UV_TCP))
+               return kr_error(EINVAL);
 
        session_tasklist_add(session, task);
 
        struct request_ctx *ctx = task->ctx;
-       assert(ctx && (ctx->source.session == NULL || ctx->source.session == session));
+       if (!kr_assume(ctx && (ctx->source.session == NULL || ctx->source.session == session)))
+               return kr_error(EINVAL);
        ctx->source.session = session;
        /* Soft-limit on parallel queries, there is no "slow down" RCODE
         * that we could use to signalize to client, but we can stop reading,
@@ -569,12 +586,12 @@ static void qr_task_complete(struct qr_task *task)
 
        /* Kill pending I/O requests */
        ioreq_kill_pending(task);
-       assert(task->waiting.len == 0);
-       assert(task->leading == false);
+       kr_require(task->waiting.len == 0);
+       kr_require(task->leading == false);
 
        struct session *s = ctx->source.session;
        if (s) {
-               assert(!session_flags(s)->outgoing && session_waitinglist_is_empty(s));
+               kr_require(!session_flags(s)->outgoing && session_waitinglist_is_empty(s));
                ctx->source.session = NULL;
                session_tasklist_del(s, task);
        }
@@ -590,23 +607,22 @@ static void qr_task_complete(struct qr_task *task)
 int qr_task_on_send(struct qr_task *task, const uv_handle_t *handle, int status)
 {
        if (task->finished) {
-               assert(task->leading == false);
+               kr_require(task->leading == false);
                qr_task_complete(task);
        }
 
-       if (!handle)
+       if (!handle || !kr_assume(handle->data))
                return status;
-
        struct session* s = handle->data;
-       assert(s);
 
        if (handle->type == UV_UDP && session_flags(s)->outgoing) {
                // This should ensure that we are only dealing with our question to upstream
-               assert(!knot_wire_get_qr(task->pktbuf->wire));
+               if (!kr_assume(!knot_wire_get_qr(task->pktbuf->wire)))
+                       return status;
                // start the timer
                struct kr_query *qry = array_tail(task->ctx->req.rplan.pending);
-               assert(qry != NULL);
-               (void)qry;
+               if (!kr_assume(qry))
+                       return status;
                size_t timeout = task->transport->timeout;
                int ret = session_timer_start(s, on_udp_timeout, timeout, 0);
                /* Start next step with timeout, fatal if can't start a timer. */
@@ -657,25 +673,23 @@ static void on_write(uv_write_t *req, int status)
 static int qr_task_send(struct qr_task *task, struct session *session,
                        const struct sockaddr *addr, knot_pkt_t *pkt)
 {
-       if (!session) {
+       if (!session)
                return qr_task_on_send(task, NULL, kr_error(EIO));
-       }
 
        int ret = 0;
        struct request_ctx *ctx = task->ctx;
 
        uv_handle_t *handle = session_get_handle(session);
-       assert(handle && handle->data == session);
+       if (!kr_assume(handle && handle->data == session))
+               return qr_task_on_send(task, NULL, kr_error(EINVAL));
        const bool is_stream = handle->type == UV_TCP;
        if (!is_stream && handle->type != UV_UDP) abort();
 
-       if (addr == NULL) {
+       if (addr == NULL)
                addr = session_get_peer(session);
-       }
 
-       if (pkt == NULL) {
+       if (pkt == NULL)
                pkt = worker_task_get_pktbuf(task);
-       }
 
        if (session_flags(session)->outgoing && handle->type == UV_TCP) {
                size_t try_limit = session_tasklist_get_len(session) + 1;
@@ -686,16 +700,14 @@ static int qr_task_send(struct qr_task *task, struct session *session,
                        ++msg_id;
                        ++try_count;
                }
-               if (try_count > try_limit) {
+               if (try_count > try_limit)
                        return kr_error(ENOENT);
-               }
                worker_task_pkt_set_msgid(task, msg_id);
        }
 
        uv_handle_t *ioreq = malloc(is_stream ? sizeof(uv_write_t) : sizeof(uv_udp_send_t));
-       if (!ioreq) {
+       if (!ioreq)
                return qr_task_on_send(task, handle, kr_error(ENOMEM));
-       }
 
        /* Pending ioreq on current task */
        qr_task_ref(task);
@@ -705,7 +717,8 @@ static int qr_task_send(struct qr_task *task, struct session *session,
        task->send_time = kr_now();
        task->recv_time = 0; // task structure is being reused so we have to zero this out here
        /* Send using given protocol */
-       assert(!session_flags(session)->closing);
+       if (!kr_assume(!session_flags(session)->closing))
+               return qr_task_on_send(task, NULL, kr_error(EIO));
        if (session_flags(session)->has_http) {
 #if ENABLE_DOH2
                uv_write_t *write_req = (uv_write_t *)ioreq;
@@ -748,7 +761,7 @@ static int qr_task_send(struct qr_task *task, struct session *session,
                write_req->data = task;
                ret = uv_write(write_req, (uv_stream_t *)handle, buf, 3, &on_write);
        } else {
-               assert(false);
+               (void)!kr_assume(false);
        }
 
        if (ret == 0) {
@@ -808,7 +821,8 @@ static struct kr_query *task_get_last_pending_query(struct qr_task *task)
 
 static int session_tls_hs_cb(struct session *session, int status)
 {
-       assert(session_flags(session)->outgoing);
+       if (!kr_assume(session_flags(session)->outgoing))
+               return kr_error(EINVAL);
        struct sockaddr *peer = session_get_peer(session);
        int deletion_res = worker_del_tcp_waiting(the_worker, peer);
        int ret = kr_ok();
@@ -826,10 +840,10 @@ static int session_tls_hs_cb(struct session *session, int status)
                         * waiting for connection to upstream.
                         * So that it MUST be unsuccessful rehandshake.
                         * Check it. */
-                       assert(deletion_res != 0);
+                       kr_require(deletion_res != 0);
                        const char *key = tcpsess_key(peer);
-                       assert(key);
-                       assert(map_contains(&the_worker->tcp_connected, key) != 0);
+                       kr_require(key);
+                       kr_require(map_contains(&the_worker->tcp_connected, key) != 0);
                }
 #endif
                return ret;
@@ -933,17 +947,18 @@ static int send_waiting(struct session *session)
 static void on_connect(uv_connect_t *req, int status)
 {
        struct worker_ctx *worker = the_worker;
-       assert(worker);
+       kr_require(worker);
        uv_stream_t *handle = req->handle;
        struct session *session = handle->data;
        struct sockaddr *peer = session_get_peer(session);
        free(req);
 
-       assert(session_flags(session)->outgoing);
+       if (!kr_assume(session_flags(session)->outgoing))
+               return;
 
        if (session_flags(session)->closing) {
                worker_del_tcp_waiting(worker, peer);
-               assert(session_is_empty(session));
+               (void)!kr_assume(session_is_empty(session));
                return;
        }
 
@@ -961,7 +976,7 @@ static void on_connect(uv_connect_t *req, int status)
                                        "is already timeouted, close\n",
                                        peer_str ? peer_str : "");
                }
-               assert(session_tasklist_is_empty(session));
+               (void)!kr_assume(session_tasklist_is_empty(session));
                session_waitinglist_retry(session, false);
                session_close(session);
                return;
@@ -978,7 +993,7 @@ static void on_connect(uv_connect_t *req, int status)
                                        "is already connected, close\n",
                                        peer_str ? peer_str : "");
                }
-               assert(session_tasklist_is_empty(session));
+               (void)!kr_assume(session_tasklist_is_empty(session));
                session_waitinglist_retry(session, false);
                session_close(session);
                return;
@@ -999,7 +1014,7 @@ static void on_connect(uv_connect_t *req, int status)
                        struct kr_query *qry = array_tail(task->ctx->req.rplan.pending);
                        qry->server_selection.error(qry, task->transport, KR_SELECTION_TCP_CONNECT_FAILED);
                }
-               assert(session_tasklist_is_empty(session));
+               (void)!kr_assume(session_tasklist_is_empty(session));
                session_waitinglist_retry(session, false);
                session_close(session);
                return;
@@ -1012,7 +1027,7 @@ static void on_connect(uv_connect_t *req, int status)
                        /* session isn't in list of waiting queries, *
                         * something gone wrong */
                        session_waitinglist_finalize(session, KR_STATE_FAIL);
-                       assert(session_tasklist_is_empty(session));
+                       (void)!kr_assume(session_tasklist_is_empty(session));
                        session_close(session);
                        return;
                }
@@ -1056,9 +1071,9 @@ static void on_tcp_connect_timeout(uv_timer_t *timer)
 
        uv_timer_stop(timer);
        struct worker_ctx *worker = the_worker;
-       assert(worker);
+       kr_require(worker);
 
-       assert (session_tasklist_is_empty(session));
+       (void)!kr_assume(session_tasklist_is_empty(session));
 
        struct sockaddr *peer = session_get_peer(session);
        worker_del_tcp_waiting(worker, peer);
@@ -1083,7 +1098,7 @@ static void on_tcp_connect_timeout(uv_timer_t *timer)
 
        worker->stats.timeout += session_waitinglist_get_len(session);
        session_waitinglist_retry(session, true);
-       assert (session_tasklist_is_empty(session));
+       (void)!kr_assume(session_tasklist_is_empty(session));
        /* uv_cancel() doesn't support uv_connect_t request,
         * so that we can't cancel it.
         * There still exists possibility of successful connection
@@ -1098,13 +1113,15 @@ static void on_tcp_connect_timeout(uv_timer_t *timer)
 static void on_udp_timeout(uv_timer_t *timer)
 {
        struct session *session = timer->data;
-       assert(session_get_handle(session)->data == session);
-       assert(session_tasklist_get_len(session) == 1);
-       assert(session_waitinglist_is_empty(session));
+       (void)!kr_assume(session_get_handle(session)->data == session);
+       (void)!kr_assume(session_tasklist_get_len(session) == 1);
+       (void)!kr_assume(session_waitinglist_is_empty(session));
 
        uv_timer_stop(timer);
 
        struct qr_task *task = session_tasklist_get_first(session);
+       if (!task)
+               return;
        struct worker_ctx *worker = task->ctx->worker;
 
        if (task->leading && task->pending_count > 0) {
@@ -1144,7 +1161,7 @@ static uv_handle_t *transmit(struct qr_task *task)
                struct sockaddr *addr = (struct sockaddr *)choice;
                struct session *session = ret->data;
                struct sockaddr *peer = session_get_peer(session);
-               assert (peer->sa_family == AF_UNSPEC && session_flags(session)->outgoing);
+               (void)!kr_assume(peer->sa_family == AF_UNSPEC && session_flags(session)->outgoing);
                memcpy(peer, addr, kr_sockaddr_len(addr));
                if (qr_task_send(task, session, (struct sockaddr *)choice,
                                 task->pktbuf) != 0) {
@@ -1175,7 +1192,7 @@ static void subreq_finalize(struct qr_task *task, const struct sockaddr *packet_
        if (klen > 0) {
                void *val_deleted;
                int ret = trie_del(task->ctx->worker->subreq_out, key, klen, &val_deleted);
-               assert(ret == KNOT_EOK && val_deleted == task); (void)ret;
+               (void)!kr_assume(ret == KNOT_EOK && val_deleted == task);
        }
        /* Notify waiting tasks. */
        struct kr_query *leader_qry = array_tail(task->ctx->req.rplan.pending);
@@ -1203,7 +1220,8 @@ static void subreq_finalize(struct qr_task *task, const struct sockaddr *packet_
 
 static void subreq_lead(struct qr_task *task)
 {
-       assert(task);
+       if (!kr_assume(task))
+               return;
        char key[SUBREQ_KEY_LEN];
        const int klen = subreq_key(key, task->pktbuf);
        if (klen < 0)
@@ -1212,17 +1230,16 @@ static void subreq_lead(struct qr_task *task)
                trie_get_ins(task->ctx->worker->subreq_out, key, klen);
        if (unlikely(!tvp))
                return; /*ENOMEM*/
-       if (unlikely(*tvp != NULL)) {
-               assert(false);
+       if (!kr_assume(*tvp == NULL))
                return;
-       }
        *tvp = task;
        task->leading = true;
 }
 
 static bool subreq_enqueue(struct qr_task *task)
 {
-       assert(task);
+       if (!kr_assume(task))
+               return false;
        char key[SUBREQ_KEY_LEN];
        const int klen = subreq_key(key, task->pktbuf);
        if (klen < 0)
@@ -1260,6 +1277,10 @@ static int xdp_push(struct qr_task *task, const uv_handle_t *src_handle)
 {
 #if ENABLE_XDP
        struct request_ctx *ctx = task->ctx;
+       xdp_handle_data_t *xhd = src_handle->data;
+       if (!kr_assume(xhd && xhd->socket && xhd->session == ctx->source.session))
+               return qr_task_on_send(task, src_handle, kr_error(EINVAL));
+
        knot_xdp_msg_t msg;
        const struct sockaddr *ip_from = &ctx->source.dst_addr.ip;
        const struct sockaddr *ip_to   = &ctx->source.addr.ip;
@@ -1268,8 +1289,6 @@ static int xdp_push(struct qr_task *task, const uv_handle_t *src_handle)
        msg.payload.iov_base = ctx->req.answer->wire;
        msg.payload.iov_len  = ctx->req.answer->size;
 
-       xdp_handle_data_t *xhd = src_handle->data;
-       assert(xhd && xhd->socket && xhd->session == ctx->source.session);
        uint32_t sent;
        int ret = knot_xdp_send(xhd->socket, &msg, 1, &sent);
        ctx->req.answer->wire = NULL; /* it's been freed */
@@ -1279,14 +1298,14 @@ static int xdp_push(struct qr_task *task, const uv_handle_t *src_handle)
 
        return qr_task_on_send(task, src_handle, ret);
 #else
-       assert(!EINVAL);
+       (void)!kr_assume(!EINVAL);
        return kr_error(EINVAL);
 #endif
 }
 
 static int qr_task_finalize(struct qr_task *task, int state)
 {
-       assert(task && task->leading == false);
+       kr_require(task && task->leading == false);
        if (task->finished) {
                return kr_ok();
        }
@@ -1315,21 +1334,16 @@ static int qr_task_finalize(struct qr_task *task, int state)
        /* Send back answer */
        int ret;
        const uv_handle_t *src_handle = session_get_handle(source_session);
-       if (src_handle->type != UV_UDP && src_handle->type != UV_TCP
-                                      && src_handle->type != UV_POLL) {
-               assert(false);
+       if (!kr_assume(src_handle->type == UV_UDP || src_handle->type == UV_TCP
+                      || src_handle->type == UV_POLL)) {
                ret = kr_error(EINVAL);
-
        } else if (src_handle->type == UV_POLL) {
                ret = xdp_push(task, src_handle);
-
        } else if (src_handle->type == UV_UDP && ENABLE_SENDMMSG) {
                int fd;
                ret = uv_fileno(src_handle, &fd);
-               assert(!ret);
-               if (ret == 0) {
+               if (kr_assume(ret == 0))
                        udp_queue_push(fd, &ctx->req, task);
-               }
        } else {
                ret = qr_task_send(task, source_session, &ctx->source.addr.ip, ctx->req.answer);
        }
@@ -1340,7 +1354,7 @@ static int qr_task_finalize(struct qr_task *task, int state)
                while (!session_tasklist_is_empty(source_session)) {
                        struct qr_task *t = session_tasklist_del_first(source_session, false);
                        struct request_ctx *c = t->ctx;
-                       assert(c->source.session == source_session);
+                       (void)!kr_assume(c->source.session == source_session);
                        c->source.session = NULL;
                        /* Don't finalize them as there can be other tasks
                         * waiting for answer to this particular task.
@@ -1381,14 +1395,8 @@ static int udp_task_step(struct qr_task *task,
 
 static int tcp_task_waiting_connection(struct session *session, struct qr_task *task)
 {
-       assert(session_flags(session)->outgoing);
-       if (session_flags(session)->closing) {
-               /* Something went wrong. Better answer with KR_STATE_FAIL.
-                * TODO: normally should not happen,
-                * consider possibility to transform this into
-                * assert(!session_flags(session)->closing). */
+       if (!kr_assume(session_flags(session)->outgoing && !session_flags(session)->closing))
                return kr_error(EINVAL);
-       }
        /* Add task to the end of list of waiting tasks.
         * It will be notified in on_connect() or qr_task_on_send(). */
        int ret = session_waitinglist_push(session, task);
@@ -1400,18 +1408,11 @@ static int tcp_task_waiting_connection(struct session *session, struct qr_task *
 
 static int tcp_task_existing_connection(struct session *session, struct qr_task *task)
 {
-       assert(session_flags(session)->outgoing);
+       if (!kr_assume(session_flags(session)->outgoing && !session_flags(session)->closing))
+               return kr_error(EINVAL);
        struct request_ctx *ctx = task->ctx;
        struct worker_ctx *worker = ctx->worker;
 
-       if (session_flags(session)->closing) {
-               /* Something went wrong. Better answer with KR_STATE_FAIL.
-                * TODO: normally should not happen,
-                * consider possibility to transform this into
-                * assert(!session_flags(session)->closing). */
-               return kr_error(EINVAL);
-       }
-
        /* If there are any unsent queries, send it first. */
        int ret = send_waiting(session);
        if (ret != 0) {
@@ -1470,7 +1471,11 @@ static int tcp_task_make_connection(struct qr_task *task, const struct sockaddr
                return kr_error(EINVAL);
        }
        struct session *session = client->data;
-       assert(session_flags(session)->has_tls == has_tls);
+       if (!kr_assume(session_flags(session)->has_tls == has_tls)) {
+               tls_client_ctx_free(tls_ctx);
+               free(conn);
+               return kr_error(EINVAL);
+       }
        if (has_tls) {
                tls_client_ctx_set_session(tls_ctx, session);
                session_tls_set_client_ctx(session, tls_ctx);
@@ -1534,7 +1539,10 @@ static int tcp_task_make_connection(struct qr_task *task, const struct sockaddr
 static int tcp_task_step(struct qr_task *task,
                         const struct sockaddr *packet_source, knot_pkt_t *packet)
 {
-       assert(task->pending_count == 0);
+       if (!kr_assume(task->pending_count == 0)) {
+               subreq_finalize(task, packet_source, packet);
+               return qr_task_finalize(task, KR_STATE_FAIL);
+       }
 
        /* target */
        const struct sockaddr *addr = &task->transport->address.ip;
@@ -1593,7 +1601,8 @@ static int qr_task_step(struct qr_task *task,
 
        /* Consume input and produce next query */
        struct request_ctx *ctx = task->ctx;
-       assert(ctx);
+       if (!kr_assume(ctx))
+               return qr_task_finalize(task, KR_STATE_FAIL);
        struct kr_request *req = &ctx->req;
        struct worker_ctx *worker = ctx->worker;
 
@@ -1656,7 +1665,7 @@ static int qr_task_step(struct qr_task *task,
        case KR_TRANSPORT_TLS:
                return tcp_task_step(task, packet_source, packet);
        default:
-               assert(0);
+               (void)!kr_assume(!EINVAL);
                return kr_error(EINVAL);
        }
 }
@@ -1753,12 +1762,14 @@ int worker_submit(struct session *session,
                                        (int)id);
                        return kr_error(ENOENT);
                }
-               assert(!session_flags(session)->closing);
+               if (!kr_assume(!session_flags(session)->closing))
+                       return kr_error(EINVAL);
                addr = peer;
                /* Note recieve time for RTT calculation */
                task->recv_time = kr_now();
        }
-       assert(uv_is_closing(session_get_handle(session)) == false);
+       if (!kr_assume(!uv_is_closing(session_get_handle(session))))
+               return kr_error(EINVAL);
 
        /* Packet was successfully parsed.
         * Task was created (found). */
@@ -1771,19 +1782,22 @@ int worker_submit(struct session *session,
 static int map_add_tcp_session(map_t *map, const struct sockaddr* addr,
                               struct session *session)
 {
-       assert(map && addr);
+       if (!kr_assume(map && addr))
+               return kr_error(EINVAL);
        const char *key = tcpsess_key(addr);
-       assert(key);
-       assert(map_contains(map, key) == 0);
+       if (!kr_assume(key && map_contains(map, key) == 0))
+               return kr_error(EINVAL);
        int ret = map_set(map, key, session);
        return ret ? kr_error(EINVAL) : kr_ok();
 }
 
 static int map_del_tcp_session(map_t *map, const struct sockaddr* addr)
 {
-       assert(map && addr);
+       if (!kr_assume(map && addr))
+               return kr_error(EINVAL);
        const char *key = tcpsess_key(addr);
-       assert(key);
+       if (!kr_assume(key))
+               return kr_error(EINVAL);
        int ret = map_del(map, key);
        return ret ? kr_error(ENOENT) : kr_ok();
 }
@@ -1791,9 +1805,11 @@ static int map_del_tcp_session(map_t *map, const struct sockaddr* addr)
 static struct session* map_find_tcp_session(map_t *map,
                                            const struct sockaddr *addr)
 {
-       assert(map && addr);
+       if (!kr_assume(map && addr))
+               return NULL;
        const char *key = tcpsess_key(addr);
-       assert(key);
+       if (!kr_assume(key))
+               return NULL;
        struct session* ret = map_get(map, key);
        return ret;
 }
@@ -1802,19 +1818,12 @@ int worker_add_tcp_connected(struct worker_ctx *worker,
                                    const struct sockaddr* addr,
                                    struct session *session)
 {
-#ifndef NDEBUG
-       assert(addr);
-       const char *key = tcpsess_key(addr);
-       assert(key);
-       assert(map_contains(&worker->tcp_connected, key) == 0);
-#endif
        return map_add_tcp_session(&worker->tcp_connected, addr, session);
 }
 
 int worker_del_tcp_connected(struct worker_ctx *worker,
                                    const struct sockaddr* addr)
 {
-       assert(addr && tcpsess_key(addr));
        return map_del_tcp_session(&worker->tcp_connected, addr);
 }
 
@@ -1828,19 +1837,12 @@ static int worker_add_tcp_waiting(struct worker_ctx *worker,
                                  const struct sockaddr* addr,
                                  struct session *session)
 {
-#ifndef NDEBUG
-       assert(addr);
-       const char *key = tcpsess_key(addr);
-       assert(key);
-       assert(map_contains(&worker->tcp_waiting, key) == 0);
-#endif
        return map_add_tcp_session(&worker->tcp_waiting, addr, session);
 }
 
 int worker_del_tcp_waiting(struct worker_ctx *worker,
                           const struct sockaddr* addr)
 {
-       assert(addr && tcpsess_key(addr));
        return map_del_tcp_session(&worker->tcp_waiting, addr);
 }
 
@@ -1852,9 +1854,8 @@ struct session* worker_find_tcp_waiting(struct worker_ctx *worker,
 
 int worker_end_tcp(struct session *session)
 {
-       if (!session) {
+       if (!session)
                return kr_error(EINVAL);
-       }
 
        session_timer_stop(session);
 
@@ -1878,7 +1879,7 @@ int worker_end_tcp(struct session *session)
 
        while (!session_waitinglist_is_empty(session)) {
                struct qr_task *task = session_waitinglist_pop(session, false);
-               assert(task->refs > 1);
+               (void)!kr_assume(task->refs > 1);
                session_tasklist_del(session, task);
                if (session_flags(session)->outgoing) {
                        if (task->ctx->req.options.FORWARD) {
@@ -1893,7 +1894,7 @@ int worker_end_tcp(struct session *session)
                        }
                        qr_task_step(task, NULL, NULL);
                } else {
-                       assert(task->ctx->source.session == session);
+                       (void)!kr_assume(task->ctx->source.session == session);
                        task->ctx->source.session = NULL;
                }
                worker_task_unref(task);
@@ -1909,7 +1910,7 @@ int worker_end_tcp(struct session *session)
                        }
                        qr_task_step(task, NULL, NULL);
                } else {
-                       assert(task->ctx->source.session == session);
+                       (void)!kr_assume(task->ctx->source.session == session);
                        task->ctx->source.session = NULL;
                }
                worker_task_unref(task);
@@ -1967,17 +1968,14 @@ knot_pkt_t *worker_resolve_mk_pkt(const char *qname_str, uint16_t qtype, uint16_
 struct qr_task *worker_resolve_start(knot_pkt_t *query, struct kr_qflags options)
 {
        struct worker_ctx *worker = the_worker;
-       if (!worker || !query) {
-               assert(!EINVAL);
+       if (!kr_assume(worker && query))
                return NULL;
-       }
 
 
        struct request_ctx *ctx = request_create(worker, NULL, NULL, NULL, NULL, NULL,
                                                 worker->next_request_uid);
-       if (!ctx) {
+       if (!ctx)
                return NULL;
-       }
 
        /* Create task */
        struct qr_task *task = qr_task_create(ctx);
@@ -1998,9 +1996,8 @@ struct qr_task *worker_resolve_start(knot_pkt_t *query, struct kr_qflags options
        }
 
        worker->next_request_uid += 1;
-       if (worker->next_request_uid == 0) {
+       if (worker->next_request_uid == 0)
                worker->next_request_uid = UINT16_MAX + 1;
-       }
 
        /* Set options late, as qr_task_start() -> kr_resolve_begin() rewrite it. */
        kr_qflags_set(&task->ctx->req.options, options);
@@ -2009,9 +2006,8 @@ struct qr_task *worker_resolve_start(knot_pkt_t *query, struct kr_qflags options
 
 int worker_resolve_exec(struct qr_task *task, knot_pkt_t *query)
 {
-       if (!task) {
+       if (!task)
                return kr_error(EINVAL);
-       }
        return qr_task_step(task, NULL, query);
 }
 
@@ -2022,9 +2018,8 @@ int worker_task_numrefs(const struct qr_task *task)
 
 struct kr_request *worker_task_request(struct qr_task *task)
 {
-       if (!task || !task->ctx) {
+       if (!task || !task->ctx)
                return NULL;
-       }
 
        return &task->ctx->req;
 }
@@ -2137,7 +2132,8 @@ static inline void reclaim_mp_freelist(mp_freelist_t *list)
 void worker_deinit(void)
 {
        struct worker_ctx *worker = the_worker;
-       assert(worker);
+       if (!kr_assume(worker))
+               return;
        if (worker->z_import != NULL) {
                zi_free(worker->z_import);
                worker->z_import = NULL;
@@ -2160,8 +2156,8 @@ void worker_deinit(void)
 
 int worker_init(struct engine *engine, int worker_count)
 {
-       assert(engine && engine->L);
-       assert(the_worker == NULL);
+       if (!kr_assume(engine && engine->L && the_worker == NULL))
+               return kr_error(EINVAL);
        kr_bindings_register(engine->L);
 
        /* Create main worker. */
@@ -2201,7 +2197,7 @@ int worker_init(struct engine *engine, int worker_count)
                lua_pushstring(engine->L, inst_name);
        } else {
                ret = asprintf(&pid_str, "%ld", (long)pid);
-               assert(ret > 0);
+               (void)!kr_assume(ret > 0);
                lua_pushstring(engine->L, pid_str);
        }
        lua_setfield(engine->L, -2, "id");