Commit 3d2796c5 authored by Daniel Salzman's avatar Daniel Salzman

knotc: split into main, remote and commands

parent 9613d8fe
......@@ -489,9 +489,13 @@ src/utils/knot1to2/includes.c
src/utils/knot1to2/includes.h
src/utils/knot1to2/main.c
src/utils/knot1to2/scheme.h
src/utils/knotc/commands.c
src/utils/knotc/commands.h
src/utils/knotc/estimator.c
src/utils/knotc/estimator.h
src/utils/knotc/main.c
src/utils/knotc/remote.c
src/utils/knotc/remote.h
src/utils/knsupdate/knsupdate_exec.c
src/utils/knsupdate/knsupdate_exec.h
src/utils/knsupdate/knsupdate_main.c
......
......@@ -203,8 +203,12 @@ EXTRA_DIST += \
utils/knot1to2/cf-parse.y
knotc_SOURCES = \
utils/knotc/commands.c \
utils/knotc/commands.h \
utils/knotc/estimator.c \
utils/knotc/estimator.h \
utils/knotc/remote.c \
utils/knotc/remote.h \
utils/knotc/main.c
knotd_SOURCES = \
......
This diff is collapsed.
/* Copyright (C) 2015 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 <http://www.gnu.org/licenses/>.
*/
/*!
* \file
*
* \brief Knot control commands.
*
* \addtogroup knot_utils
* @{
*/
#pragma once
/*! \brief Command parameter flags. */
typedef enum {
CMD_FNONE = 0, /*!< Empty flag. */
CMD_FFORCE = 1 << 0 /*!< Forced operation. */
} cmd_flag_t;
/*! \brief Command condition flags. */
typedef enum {
CMD_CONF_FNONE = 0, /*!< Empty flag. */
CMD_CONF_FREAD = 1 << 0, /*!< Required read access to config or confdb. */
CMD_CONF_FWRITE = 1 << 1 /*!< Required write access to confdb. */
} cmd_conf_flag_t;
/*! \brief Command callback arguments. */
typedef struct {
char *socket;
int argc;
char **argv;
cmd_flag_t flags;
} cmd_args_t;
/*! \brief Command callback prototype. */
typedef int (*cmd_t)(cmd_args_t *args);
/*! \brief Command callback description. */
typedef struct {
const char *name;
cmd_t cmd;
cmd_conf_flag_t flags;
} cmd_desc_t;
/*! \brief Old command name translation. */
typedef struct {
const char *old_name;
const char *new_name;
} cmd_desc_old_t;
/*! \brief Command description. */
typedef struct {
const char *name;
const char *params;
const char *desc;
} cmd_help_t;
/*! \brief Table of commands. */
extern const cmd_desc_t cmd_table[];
/*! \brief Table of command translations. */
extern const cmd_desc_old_t cmd_table_old[];
/*! \brief Table of command descriptions. */
extern const cmd_help_t cmd_help_table[];
/*! @} */
This diff is collapsed.
/* Copyright (C) 2015 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 <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include "libknot/libknot.h"
#include "knot/common/log.h"
#include "knot/conf/conf.h"
#include "knot/ctl/remote.h"
#include "contrib/net.h"
#include "contrib/sockaddr.h"
#include "contrib/string.h"
#include "utils/knotc/remote.h"
static int cmd_remote_print_reply(const knot_rrset_t *rr)
{
if (rr->type != KNOT_RRTYPE_TXT) {
return KNOT_EMALF;
}
uint16_t rr_count = rr->rrs.rr_count;
for (uint16_t i = 0; i < rr_count; i++) {
/* Parse TXT. */
remote_print_txt(rr, i);
}
return KNOT_EOK;
}
static int cmd_remote_reply(int c, struct timeval *timeout)
{
knot_pkt_t *pkt = knot_pkt_new(NULL, KNOT_WIRE_MAX_PKTSIZE, NULL);
if (!pkt) {
return KNOT_ENOMEM;
}
/* Read response packet. */
int n = net_dns_tcp_recv(c, pkt->wire, pkt->max_size, timeout);
if (n <= 0) {
knot_pkt_free(&pkt);
return KNOT_ECONN;
} else {
pkt->size = n;
}
/* Parse packet and check response. */
int ret = remote_parse(pkt);
if (ret != KNOT_EOK) {
knot_pkt_free(&pkt);
return ret;
}
/* Check RCODE */
const knot_pktsection_t *authority = knot_pkt_section(pkt, KNOT_AUTHORITY);
ret = knot_wire_get_rcode(pkt->wire);
switch(ret) {
case KNOT_RCODE_NOERROR:
if (authority->count > 0) {
ret = cmd_remote_print_reply(knot_pkt_rr(authority, 0));
}
break;
case KNOT_RCODE_REFUSED:
ret = KNOT_EDENIED;
break;
default:
ret = KNOT_ERROR;
break;
}
knot_pkt_free(&pkt);
return ret;
}
int cmd_remote(const char *socket, const char *cmd, uint16_t rrt,
int argc, char *argv[])
{
int rc = 0;
/* Make query. */
knot_pkt_t *pkt = remote_query(cmd);
if (!pkt) {
log_error("failed to prepare query for '%s'", cmd);
return 1;
}
/* Build query data. */
knot_pkt_begin(pkt, KNOT_AUTHORITY);
if (argc > 0) {
knot_rrset_t rr;
int res = remote_build_rr(&rr, "data.", rrt);
if (res != KNOT_EOK) {
log_error("failed to create the query");
knot_pkt_free(&pkt);
return 1;
}
for (uint16_t i = 0; i < argc; ++i) {
switch(rrt) {
case KNOT_RRTYPE_NS:
remote_create_ns(&rr, argv[i]);
break;
case KNOT_RRTYPE_TXT:
default:
remote_create_txt(&rr, argv[i], strlen(argv[i]), i);
break;
}
}
res = knot_pkt_put(pkt, 0, &rr, KNOT_PF_FREE);
if (res != KNOT_EOK) {
log_error("failed to create the query");
knot_rrset_clear(&rr, NULL);
knot_pkt_free(&pkt);
return 1;
}
}
/* Default timeout. */
conf_val_t *val = &conf()->cache.srv_tcp_reply_timeout;
const struct timeval tv_reply = { conf_int(val), 0 };
/* Prepare socket address. */
struct sockaddr_storage addr;
int ret = sockaddr_set(&addr, AF_UNIX, socket, 0);
if (ret != KNOT_EOK) {
log_error("failed to connect to socket '%s' (%s)", socket,
knot_strerror(ret));
knot_pkt_free(&pkt);
return 1;
}
/* Connect to socket. */
int s = net_connected_socket(SOCK_STREAM, &addr, NULL);
if (s < 0) {
log_error("failed to connect to socket '%s' (%s)", socket,
knot_strerror(s));
knot_pkt_free(&pkt);
return 1;
}
/* Send and free packet. */
struct timeval tv = tv_reply;
ret = net_dns_tcp_send(s, pkt->wire, pkt->size, &tv);
knot_pkt_free(&pkt);
/* Evaluate and wait for reply. */
if (ret <= 0) {
log_error("failed to connect to socket '%s' (%s)", socket,
knot_strerror(ret));
close(s);
return 1;
}
/* Wait for reply. */
ret = KNOT_EOK;
while (ret == KNOT_EOK) {
tv = tv_reply;
ret = cmd_remote_reply(s, &tv);
if (ret != KNOT_EOK) {
if (ret != KNOT_ECONN) {
log_error("remote command reply: %s",
knot_strerror(ret));
rc = 1;
}
break;
}
}
/* Cleanup. */
if (rc == 0) {
printf("\n");
}
/* Close connection. */
close(s);
return rc;
}
/* Copyright (C) 2015 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 <http://www.gnu.org/licenses/>.
*/
#pragma once
int cmd_remote(const char *socket, const char *cmd, uint16_t rrt,
int argc, char *argv[]);
......@@ -25,10 +25,10 @@ serial_slave = slave.zone_wait(zone)
assert serial_master <= serial_slave
# Force refresh
slave.ctl("-f refresh example.com.")
slave.ctl("zone-retransfer example.com.")
t.sleep(2)
serial_slave = slave.zone_wait(zone)
compare(serial_slave, serial_master, "Forced refresh")
compare(serial_slave, serial_master, "Serial after retransfer")
t.end()
......@@ -226,10 +226,6 @@ class Server(object):
self.ctl("reload")
time.sleep(Server.START_WAIT)
def flush(self):
self.ctl("flush")
time.sleep(Server.START_WAIT)
def running(self):
proc = psutil.Process(self.proc.pid)
status = proc.status
......@@ -668,6 +664,10 @@ class Bind(Server):
ctltcp = super()._check_socket("tcp", self.ctlport)
return (tcp and udp and ctltcp)
def flush(self):
self.ctl("flush")
time.sleep(Server.START_WAIT)
def _str(self, conf, name, value):
if value and value != True:
conf.item_str(name, value)
......@@ -832,6 +832,10 @@ class Knot(Server):
udp = super()._check_socket("udp", self.port)
return (tcp and udp)
def flush(self):
self.ctl("zone-flush")
time.sleep(Server.START_WAIT)
def _on_str_hex(self, conf, name, value):
if value == True:
return
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment