*/
static inline void lua_pushpointer(lua_State *L, void *p)
{
- void *addr = lua_newuserdata(L, sizeof(void *));
+ void **addr = lua_newuserdata(L, sizeof(void *));
kr_require(addr);
memcpy(addr, &p, sizeof(void *));
}
char *beg = strstr(path, key);
char *end;
size_t remaining;
- ssize_t ret;
uint8_t *dest;
if (!beg) /* No dns variable in path. */
remaining = ctx->buf_size - ctx->submitted - ctx->buf_pos;
dest = ctx->buf + ctx->buf_pos;
- ret = kr_base64url_decode((uint8_t*)beg, end - beg, dest, remaining);
+ int ret = kr_base64url_decode((uint8_t*)beg, end - beg, dest, remaining);
if (ret < 0) {
ctx->buf_pos = 0;
- kr_log_debug(DOH, "[%p] base64url decode failed %s\n", (void *)ctx->h2, strerror(ret));
+ kr_log_debug(DOH, "[%p] base64url decode failed %s\n", (void *)ctx->h2, kr_strerror(ret));
return ret;
}
int yes = 1;
if (addr->sa_family == AF_INET || addr->sa_family == AF_INET6) {
- if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)))
+ if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes))) {
+ close(fd);
return kr_error(errno);
+ }
#ifdef SO_REUSEPORT_LB
- if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT_LB, &yes, sizeof(yes)))
+ if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT_LB, &yes, sizeof(yes))) {
+ close(fd);
return kr_error(errno);
+ }
#elif defined(SO_REUSEPORT) && defined(__linux__) /* different meaning on (Free)BSD */
- if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &yes, sizeof(yes)))
+ if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &yes, sizeof(yes))) {
+ close(fd);
return kr_error(errno);
+ }
#endif
#ifdef IPV6_V6ONLY
if (addr->sa_family == AF_INET6
- && setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &yes, sizeof(yes)))
+ && setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &yes, sizeof(yes))) {
+ close(fd);
return kr_error(errno);
+ }
#endif
if (flags != NULL && flags->freebind) {
int optlevel;
int optname;
int ret = family_to_freebind_option(addr->sa_family, &optlevel, &optname);
- if (ret) return kr_error(ret);
- if (setsockopt(fd, optlevel, optname, &yes, sizeof(yes)))
+ if (ret) {
+ close(fd);
+ return kr_error(ret);
+ }
+ if (setsockopt(fd, optlevel, optname, &yes, sizeof(yes))) {
+ close(fd);
return kr_error(errno);
+ }
}
/* Linux 3.15 has IP_PMTUDISC_OMIT which makes sockets
#endif
}
- if (bind(fd, addr, kr_sockaddr_len(addr)))
+ if (bind(fd, addr, kr_sockaddr_len(addr))) {
+ close(fd);
return kr_error(errno);
+ }
return fd;
}
char *cmd, *cmd_next = NULL;
bool incomplete_cmd = false;
- if (!(stream && commands && nread > 0)) {
+ if (!commands || nread <= 0) {
goto finish;
}
- /* Execute */
+ /* Execute */
if (commands[nread - 1] != '\n') {
incomplete_cmd = true;
}
void io_tty_accept(uv_stream_t *master, int status)
{
- struct io_stream_data *data = io_tty_alloc_data();
/* We can't use any allocations after mp_start() and it's easier anyway. */
uv_pipe_t *client = malloc(sizeof(*client));
+ if (!client)
+ return;
+
+ struct io_stream_data *data = io_tty_alloc_data();
+ if (!data) {
+ free(client);
+ return;
+ }
client->data = data;
struct args *args = the_args;
- if (client && client->data) {
- uv_pipe_init(master->loop, client, 0);
- if (uv_accept(master, (uv_stream_t *)client) != 0) {
- mp_delete(data->pool->ctx);
- return;
- }
- uv_read_start((uv_stream_t *)client, io_tty_alloc, io_tty_process_input);
- /* Write command line */
- if (!args->quiet) {
- uv_buf_t buf = { "> ", 2 };
- uv_try_write((uv_stream_t *)client, &buf, 1);
- }
+ uv_pipe_init(master->loop, client, 0);
+ if (uv_accept(master, (uv_stream_t *)client) != 0) {
+ mp_delete(data->pool->ctx);
+ return;
+ }
+ uv_read_start((uv_stream_t *)client, io_tty_alloc, io_tty_process_input);
+
+ /* Write command line */
+ if (!args->quiet) {
+ uv_buf_t buf = { "> ", 2 };
+ uv_try_write((uv_stream_t *)client, &buf, 1);
}
}
/* Control sockets or TTY */
uv_pipe_t *pipe = malloc(sizeof(*pipe));
+ if (!pipe)
+ return EXIT_FAILURE;
uv_pipe_init(loop, pipe, 0);
if (args->interactive) {
if (!args->quiet)
static udp_queue_t * udp_queue_create()
{
udp_queue_t *q = calloc(1, sizeof(*q));
+ kr_require(q != NULL);
+
for (int i = 0; i < UDP_QUEUE_LEN; ++i) {
struct msghdr *mhi = &q->msgvec[i].msg_hdr;
/* These shall remain always the same. */
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)
- return qr_task_on_send(task, handle, kr_error(ENOMEM));
-
- /* Pending ioreq on current task */
- qr_task_ref(task);
-
struct worker_ctx *worker = ctx->worker;
/* Note time for upstream RTT */
task->send_time = kr_now();
/* Send using given protocol */
if (kr_fails_assert(!session_flags(session)->closing))
return qr_task_on_send(task, NULL, kr_error(EIO));
+
+ uv_handle_t *ioreq = malloc(is_stream ? sizeof(uv_write_t) : sizeof(uv_udp_send_t));
+ if (!ioreq)
+ return qr_task_on_send(task, handle, kr_error(ENOMEM));
+
+ /* Pending ioreq on current task */
+ qr_task_ref(task);
+
if (session_flags(session)->has_http) {
#if ENABLE_DOH2
uv_write_t *write_req = (uv_write_t *)ioreq;
if (ns->type != KNOT_RRTYPE_NS)
continue;
- int flags = 0;
bool nsec3_found = false;
for (unsigned j = 0; j < sec->count; ++j) {
const knot_rrset_t *nsec3 = knot_pkt_rr(sec, j);
}
if (!nsec3_found)
return kr_error(DNSSEC_NOT_FOUND);
- if (flags & FLG_NAME_MATCHED) {
- /* nsec3 which owner matches
- * the delegation name was found,
- * but nsec3 type bitmap contains wrong types
- */
- return kr_error(EINVAL);
- }
/* nsec3 that matches the delegation was not found.
* Check rfc5155, 8.9. paragraph 4.
* Find closest provable encloser.
static struct queue_chunk * queue_chunk_new(const struct queue *q)
{
+ /* size_t cast is to avoid unintended sign-extension */
struct queue_chunk *c = malloc(offsetof(struct queue_chunk, data)
- + q->chunk_cap * q->item_size);
+ + (size_t) q->chunk_cap * (size_t) q->item_size);
if (unlikely(!c)) abort(); // simplify stuff
memset(c, 0, offsetof(struct queue_chunk, data));
c->cap = q->chunk_cap;
} else
if (t->end == t->cap) {
if (t->begin * 2 >= t->cap) {
- /* Utilization is below 50%, so let's shift (no overlap). */
+ /* Utilization is below 50%, so let's shift (no overlap).
+ * (size_t cast is to avoid unintended sign-extension) */
memcpy(t->data, t->data + t->begin * q->item_size,
- (t->end - t->begin) * q->item_size);
+ (size_t) (t->end - t->begin) * (size_t) q->item_size);
t->end -= t->begin;
t->begin = 0;
} else {
if (h->begin == 0) {
if (h->end * 2 <= h->cap) {
/* Utilization is below 50%, so let's shift (no overlap).
- * Computations here are simplified due to h->begin == 0. */
+ * Computations here are simplified due to h->begin == 0.
+ * (size_t cast is to avoid unintended sign-extension) */
const int cnt = h->end;
memcpy(h->data + (h->cap - cnt) * q->item_size, h->data,
- cnt * q->item_size);
+ (size_t) cnt * (size_t) q->item_size);
h->begin = h->cap - cnt;
h->end = h->cap;
} else {
/* Iterate */
uint8_t *it = pack_head(pack);
assert_non_null(it);
- unsigned count = 0;
while (it != pack_tail(pack)) {
assert_int_equal(pack_obj_len(it), 2);
assert_true(memcmp(pack_obj_val(it), "de", 2) == 0);
it = pack_obj_next(it);
- count += 1;
}
/* Find */
/* AD flag. We can only change `secure` from true to false.
* Be conservative. Primary approach: check ranks of all RRs in wire.
* Only "negative answers" need special handling. */
- bool secure = last != NULL && request->state == KR_STATE_DONE /*< suspicious otherwise */
+ bool secure = request->state == KR_STATE_DONE /*< suspicious otherwise */
&& knot_pkt_qtype(answer) != KNOT_RRTYPE_RRSIG;
- if (last && (last->flags.STUB)) {
+ if (last->flags.STUB) {
secure = false; /* don't trust forwarding for now */
}
- if (last && (last->flags.DNSSEC_OPTOUT)) {
+ if (last->flags.DNSSEC_OPTOUT) {
VERBOSE_MSG(last, "insecure because of opt-out\n");
secure = false; /* the last answer is insecure due to opt-out */
}
/* Write all RRsets meant for the answer. */
- const uint16_t reorder = last ? last->reorder : 0;
bool answ_all_cnames = false/*arbitrary*/;
if (knot_pkt_begin(answer, KNOT_ANSWER)
- || write_extra_ranked_records(&request->answ_selected, reorder,
+ || write_extra_ranked_records(&request->answ_selected, last->reorder,
answer, &secure, &answ_all_cnames)
|| knot_pkt_begin(answer, KNOT_AUTHORITY)
- || write_extra_ranked_records(&request->auth_selected, reorder,
+ || write_extra_ranked_records(&request->auth_selected, last->reorder,
answer, &secure, NULL)
|| knot_pkt_begin(answer, KNOT_ADDITIONAL)
- || write_extra_ranked_records(&request->add_selected, reorder,
+ || write_extra_ranked_records(&request->add_selected, last->reorder,
answer, NULL/*not relevant to AD*/, NULL)
|| answer_append_edns(request)
)
return;
}
- if (!last) secure = false; /*< should be no-op, mostly documentation */
/* AD: "negative answers" need more handling. */
if (kr_response_classify(answer) != PKT_NOERROR
/* Additionally check for CNAME chains that "end in NODATA",
return KR_STATE_FAIL;
}
bool tried_tcp = (qry->flags.TCP);
- if (!packet || packet->size == 0) {
+ if (!packet || packet->size == 0)
return KR_STATE_PRODUCE;
+
+ /* Packet cleared, derandomize QNAME. */
+ knot_dname_t *qname_raw = knot_pkt_qname(packet);
+ if (qname_raw && qry->secret != 0) {
+ randomized_qname_case(qname_raw, qry->secret);
+ }
+ request->state = KR_STATE_CONSUME;
+ if (qry->flags.CACHED) {
+ ITERATE_LAYERS(request, qry, consume, packet);
} else {
- /* Packet cleared, derandomize QNAME. */
- knot_dname_t *qname_raw = knot_pkt_qname(packet);
- if (qname_raw && qry->secret != 0) {
- randomized_qname_case(qname_raw, qry->secret);
- }
- request->state = KR_STATE_CONSUME;
- if (qry->flags.CACHED) {
- ITERATE_LAYERS(request, qry, consume, packet);
- } else {
- /* Fill in source and latency information. */
- request->upstream.rtt = kr_now() - qry->timestamp_mono;
- request->upstream.transport = transport ? *transport : NULL;
- ITERATE_LAYERS(request, qry, consume, packet);
- /* Clear temporary information */
- request->upstream.transport = NULL;
- request->upstream.rtt = 0;
- }
+ /* Fill in source and latency information. */
+ request->upstream.rtt = kr_now() - qry->timestamp_mono;
+ request->upstream.transport = transport ? *transport : NULL;
+ ITERATE_LAYERS(request, qry, consume, packet);
+ /* Clear temporary information */
+ request->upstream.transport = NULL;
+ request->upstream.rtt = 0;
}
if (transport && !qry->flags.CACHED) {
if (!(request->state & KR_STATE_FAIL)) {
/* Do not complete NS address resolution on soft-fail. */
- const int rcode = packet ? knot_wire_get_rcode(packet->wire) : 0;
+ const int rcode = knot_wire_get_rcode(packet->wire);
if (rcode != KNOT_RCODE_SERVFAIL && rcode != KNOT_RCODE_REFUSED) {
qry->flags.AWAIT_IPV6 = false;
qry->flags.AWAIT_IPV4 = false;
static void test_module_params(void **state)
{
- struct kr_module module;
+ struct kr_module module = { 0 };
assert_int_equal(kr_module_load(NULL, NULL, NULL), kr_error(EINVAL));
assert_int_equal(kr_module_load(&module, NULL, NULL), kr_error(EINVAL));
kr_module_unload(NULL);
static void test_module_builtin(void **state)
{
- struct kr_module module;
+ struct kr_module module = { 0 };
assert_int_equal(kr_module_load(&module, "iterate", NULL), 0);
kr_module_unload(&module);
}
static void test_module_c(void **state)
{
- struct kr_module module;
+ struct kr_module module = { 0 };
assert_int_equal(kr_module_load(&module, "mock_cmodule", "tests/unit"), 0);
kr_module_unload(&module);
}
static void test_rplan_push(void **state)
{
- knot_mm_t mm;
+ knot_mm_t mm = { 0 };
test_mm_ctx_init(&mm);
struct kr_request request = {
.pool = mm,
/* Allocate result and fill */
char *result = NULL;
if (total_len > 0) {
- if (unlikely(total_len + 1 == 0)) return NULL;
+ if (unlikely(total_len == SIZE_MAX)) return NULL;
result = malloc(total_len + 1);
}
if (result) {
return;
}
switch (addr->sa_family) {
- case AF_INET: ((struct sockaddr_in *)addr)->sin_port = htons(port);
- case AF_INET6: ((struct sockaddr_in6 *)addr)->sin6_port = htons(port);
- default: break;
+ case AF_INET:
+ ((struct sockaddr_in *)addr)->sin_port = htons(port);
+ break;
+ case AF_INET6:
+ ((struct sockaddr_in6 *)addr)->sin6_port = htons(port);
+ break;
+ default:
+ break;
}
}
return kr_error(ENOMEM);
}
rr_new->rrs = rr->rrs;
- if (kr_fails_assert(rr_new->additional == NULL)) return kr_error(EINVAL);
+ if (kr_fails_assert(rr_new->additional == NULL)) {
+ mm_free(pool, entry);
+ return kr_error(EINVAL);
+ }
entry->qry_uid = qry_uid;
entry->rr = rr_new;
info.entry_size = key.len + val.len;
info.valid = false;
- const int entry_type = ret == KNOT_EOK ? kr_gc_key_consistent(key) : -1;
+ const int entry_type = kr_gc_key_consistent(key);
const struct entry_h *entry = NULL;
if (entry_type >= 0) {
counter_gc_consistent++;
if ((ctx->cfg_temp_keys_space > 0 &&
used > ctx->cfg_temp_keys_space) || todelete == NULL) {
ctx->oversize_records++;
+ free(todelete);
} else {
entry_dynarray_add(&ctx->to_delete, &todelete);
ctx->used_space = used;
}
//! Returns Lua name of type of value, NULL on error. Puts length of type in name_len;
-const char *get_type_name(const char *value)
+char *get_type_name(const char *value)
{
if (value == NULL) {
return NULL;
}
char *cmd = afmt("type(%s)", value);
-
if (!cmd) {
perror("While tab-completing.");
return NULL;
char *type = run_cmd(cmd, &name_len);
if (!type) {
return NULL;
- } else {
- free(cmd);
}
+ free(cmd);
if (starts_with(type, "[")) {
//Return "nil" on non-valid name.
free(type);
- return "nil";
+ return strdup("nil");
} else {
- type[(strlen(type)) - 1] = '\0';
+ type[strlen(type) - 1] = '\0';
return type;
}
}
} else {
//Print members matching the current line.
while (token) {
- if (str && starts_with(token, dot + 1)) {
+ if (starts_with(token, dot + 1)) {
const char *member_type =
get_type_name(afmt
("%s.%s", table,
char *lastmatch = NULL;
while (token) {
if (str && starts_with(token, str)) {
- printf("\n%s (%s)", token, get_type_name(token));
+ char *name = get_type_name(token);
+ printf("\n%s (%s)", token, name);
+ free(name);
lastmatch = token;
matches++;
}
if (!fread(&len, sizeof(len), 1, g_tty))
return NULL;
len = ntohl(len);
+ if (!len)
+ return NULL;
char *msg = malloc(1 + (size_t) len);
if (!msg)
return NULL;