diff options
Diffstat (limited to 'src/utils')
-rw-r--r-- | src/utils/common/params.c | 11 | ||||
-rw-r--r-- | src/utils/common/quic.c | 12 | ||||
-rw-r--r-- | src/utils/kdig/kdig_params.c | 2 | ||||
-rw-r--r-- | src/utils/knotc/commands.c | 38 | ||||
-rw-r--r-- | src/utils/knotd/main.c | 3 | ||||
-rw-r--r-- | src/utils/kxdpgun/main.c | 58 |
6 files changed, 97 insertions, 27 deletions
diff --git a/src/utils/common/params.c b/src/utils/common/params.c index 4db4b9e..d16af4c 100644 --- a/src/utils/common/params.c +++ b/src/utils/common/params.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2022 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> +/* Copyright (C) 2024 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 @@ -47,7 +47,12 @@ char *name_from_idn(const char *idn_name) { return NULL; } - return name; + if (strcasecmp(idn_name, name) == 0) { + free(name); + return strdup(idn_name); + } else { + return name; + } #endif return strdup(idn_name); } @@ -212,7 +217,7 @@ char *get_fqd_name(const char *name) size_t name_len = strlen(name); // If the name is FQDN, make a copy. - if (name[name_len - 1] == '.') { + if (name_len > 0 && name[name_len - 1] == '.') { fqd_name = strdup(name); // Else make a copy and append a trailing dot. } else { diff --git a/src/utils/common/quic.c b/src/utils/common/quic.c index 55e5408..704f3b1 100644 --- a/src/utils/common/quic.c +++ b/src/utils/common/quic.c @@ -564,6 +564,10 @@ int quic_ctx_connect(quic_ctx_t *ctx, int sockfd, struct addrinfo *dst_addr) ret = poll(&pfd, 1, timeout); if (ret == 0) { ret = ngtcp2_conn_handle_expiry(ctx->conn, quic_timestamp()); + if (ret != 0) { + WARN("QUIC, failed to send"); + return KNOT_ECONNABORTED; + } } else if (ret < 0) { return knot_map_errno(); } @@ -658,6 +662,10 @@ int quic_send_dns_query(quic_ctx_t *ctx, int sockfd, struct addrinfo *srv, return knot_map_errno(); } else if (ret == 0) { ret = ngtcp2_conn_handle_expiry(ctx->conn, quic_timestamp()); + if (ret != 0) { + WARN("QUIC, failed to send"); + return KNOT_ECONNABORTED; + } continue; } ret = quic_recv(ctx, sockfd); @@ -701,6 +709,10 @@ int quic_recv_dns_response(quic_ctx_t *ctx, uint8_t *buf, const size_t buf_len, return knot_map_errno(); } else if (ret == 0) { ret = ngtcp2_conn_handle_expiry(ctx->conn, quic_timestamp()); + if (ret != 0) { + WARN("QUIC, failed to send"); + return KNOT_ECONNABORTED; + } WARN("QUIC, peer took too long to respond"); goto send; } diff --git a/src/utils/kdig/kdig_params.c b/src/utils/kdig/kdig_params.c index 310e890..c8fd83f 100644 --- a/src/utils/kdig/kdig_params.c +++ b/src/utils/kdig/kdig_params.c @@ -1982,7 +1982,7 @@ static int parse_name(const char *value, list_t *queries, const query_t *conf) char *ascii_name = (char *)value; char *fqd_name = NULL; - if (value != NULL) { + if (value != NULL && value[0] != '\0') { if (conf->idn) { ascii_name = name_from_idn(value); if (ascii_name == NULL) { diff --git a/src/utils/knotc/commands.c b/src/utils/knotc/commands.c index e5cb455..c2c25a2 100644 --- a/src/utils/knotc/commands.c +++ b/src/utils/knotc/commands.c @@ -688,6 +688,7 @@ static int cmd_zone_ctl(cmd_args_t *args) } #define FILTER_IMPORT_NOPURGE "+nopurge" +#define FILTER_EXPORT_SCHEMA "+schema" typedef struct { const char *name; @@ -1173,22 +1174,45 @@ static int cmd_conf_import(cmd_args_t *args) static int cmd_conf_export(cmd_args_t *args) { - int ret = check_args(args, 0, 1); + int ret = check_args(args, 0, 2); if (ret != KNOT_EOK) { return ret; } // Stdout is the default output file. const char *file_name = NULL; - if (args->argc > 0) { - file_name = args->argv[0]; - log_debug("exporting confdb into file '%s'", file_name); + bool export_schema = false; + for (int i = 0; i < args->argc; i++) { + if (args->argv[i][0] == '+') { + if (strcmp(args->argv[i], FILTER_EXPORT_SCHEMA) == 0) { + export_schema = true; + } else { + log_error("unknown filter: %s", args->argv[i]); + return KNOT_EINVAL; + } + } else if (file_name == NULL) { + file_name = args->argv[i]; + } else { + log_error("command does not take 2 arguments"); + return KNOT_EINVAL; + } } - ret = conf_export(conf(), file_name, YP_SNONE); + if (file_name != NULL) { + if (export_schema) { + log_debug("exporting JSON schema into file '%s'", file_name); + } else { + log_debug("exporting confdb into file '%s'", file_name); + } + } + if (export_schema) { + ret = conf_export_schema(conf(), file_name); + } else { + ret = conf_export(conf(), file_name, YP_SNONE); + } if (ret == KNOT_EOK) { - if (args->argc > 0) { + if (file_name != NULL) { log_info("OK"); } } else { @@ -1345,7 +1369,7 @@ static const cmd_help_t cmd_help_table[] = { { CMD_CONF_INIT, "", "Initialize the confdb. (*)" }, { CMD_CONF_CHECK, "", "Check the server configuration. (*)" }, { CMD_CONF_IMPORT, " <filename> [+nopurge]", "Import a config file into the confdb. (*)" }, - { CMD_CONF_EXPORT, "[<filename>]", "Export the confdb into a config file or stdout. (*)" }, + { CMD_CONF_EXPORT, "[<filename>] [+schema]", "Export the confdb (or JSON schema) into a file or stdout. (*)" }, { CMD_CONF_LIST, "[<item>...]", "List the confdb sections or section items." }, { CMD_CONF_READ, "[<item>...]", "Get the item from the active confdb." }, { CMD_CONF_BEGIN, "", "Begin a writing confdb transaction." }, diff --git a/src/utils/knotd/main.c b/src/utils/knotd/main.c index 2355d9e..d4ebd53 100644 --- a/src/utils/knotd/main.c +++ b/src/utils/knotd/main.c @@ -273,7 +273,8 @@ static void event_loop(server_t *server, const char *socket, bool daemonize, log_info("control, binding to '%s'", listen); /* Bind the control socket. */ - int ret = knot_ctl_bind(ctl, listen); + uint16_t backlog = conf_get_int(conf(), C_CTL, C_BACKLOG); + int ret = knot_ctl_bind2(ctl, listen, backlog); if (ret != KNOT_EOK) { knot_ctl_free(ctl); log_fatal("control, failed to bind socket '%s' (%s)", diff --git a/src/utils/kxdpgun/main.c b/src/utils/kxdpgun/main.c index c9db312..8f4d402 100644 --- a/src/utils/kxdpgun/main.c +++ b/src/utils/kxdpgun/main.c @@ -30,6 +30,7 @@ #include <string.h> #include <time.h> #include <unistd.h> +#include <netdb.h> #include <arpa/inet.h> #include <netinet/in.h> @@ -205,12 +206,12 @@ static void print_stats(kxdpgun_stats_t *st, bool tcp, bool quic, bool recv, uin { pthread_mutex_lock(&st->mutex); -#define ps(counter) ((counter) * 1000 / (st->duration / 1000)) +#define ps(counter) ((typeof(counter))((counter) * 1000 / ((float)st->duration / 1000))) #define pct(counter) ((counter) * 100.0 / st->qry_sent) const char *name = tcp ? "SYNs: " : quic ? "initials:" : "queries: "; - printf("total %s %"PRIu64" (%"PRIu64" pps) (%f%%)\n", name, - st->qry_sent, ps(st->qry_sent), 100.0 * st->qry_sent / (st->duration / 1000000.0 * qps)); + printf("total %s %"PRIu64" (%"PRIu64" pps) (%f%%)\n", name, st->qry_sent, + ps(st->qry_sent), 100.0 * st->qry_sent / (st->duration / 1000000.0 * qps)); if (st->qry_sent > 0 && recv) { if (tcp || quic) { name = tcp ? "established:" : "handshakes: "; @@ -534,8 +535,8 @@ void *xdp_gun_thread(void *_ctx) } if (ctx->thread_id == 0) { - INFO2("using interface %s, XDP threads %u, %s%s%s, %s mode", - ctx->dev, ctx->n_threads, + INFO2("using interface %s, XDP threads %u, IPv%c/%s%s%s, %s mode", + ctx->dev, ctx->n_threads, (ctx->ipv6 ? '6' : '4'), (ctx->tcp ? "TCP" : ctx->quic ? "QUIC" : "UDP"), (ctx->sending_mode[0] != '\0' ? " mode " : ""), (ctx->sending_mode[0] != '\0' ? ctx->sending_mode : ""), @@ -989,6 +990,41 @@ static int mac_sscan(const char *src, uint8_t *dst) return KNOT_EOK; } +static bool resolve_name(char *target_str, xdp_gun_ctx_t *ctx) +{ + struct addrinfo *res = NULL, hints = { + .ai_family = AF_UNSPEC, + .ai_socktype = 0, // any socket type + .ai_protocol = 0, // any protocol + }; + + int err = 0; + if ((err = getaddrinfo(target_str, NULL, &hints, &res)) != 0) { + ERR2("failed to resolve '%s' (%s)", target_str, gai_strerror(err)); + goto cleanup; + } + + for (struct addrinfo *i = res; i != NULL; i = i->ai_next) { + switch (i->ai_family) { + case AF_INET: + case AF_INET6: + ctx->ipv6 = (i->ai_family == AF_INET6); + assert(sizeof(ctx->target_ip_ss) >= i->ai_addrlen); + memcpy(&ctx->target_ip_ss, i->ai_addr, i->ai_addrlen); + goto cleanup; + default: + break; + }; + } + err = 1; + +cleanup: + if (res != NULL) { + freeaddrinfo(res); + } + return (err == 0); +} + static bool configure_target(char *target_str, char *local_ip, xdp_gun_ctx_t *ctx) { int val; @@ -998,16 +1034,8 @@ static bool configure_target(char *target_str, char *local_ip, xdp_gun_ctx_t *ct *at = '\0'; } - ctx->ipv6 = false; - if (inet_pton(AF_INET, target_str, &ctx->target_ip4.sin_addr) <= 0) { - ctx->ipv6 = true; - ctx->target_ip.sin6_family = AF_INET6; - if (inet_pton(AF_INET6, target_str, &ctx->target_ip.sin6_addr) <= 0) { - ERR2("invalid target IP"); - return false; - } - } else { - ctx->target_ip.sin6_family = AF_INET; + if (!resolve_name(target_str, ctx)) { + return false; } struct sockaddr_storage via = { 0 }; |