Commit 791d0da8 authored by Marek Vavrusa's avatar Marek Vavrusa

zone-contents: removed contents->zone pointer (used for saving zonefile)

parent 2d4e430d
......@@ -229,8 +229,6 @@ int knot_ns_switch_zone(knot_nameserver_t *nameserver,
free(name);
return KNOT_ENOZONE;
} else {
zone->zone = z;
}
rcu_read_unlock();
......
......@@ -209,7 +209,6 @@ static zone_t *preserve_zone(conf_zone_t *conf, const zone_t *old_zone)
}
new_zone->contents = old_zone->contents;
new_zone->contents->zone = new_zone; // hopefully temporary
return new_zone;
}
......@@ -368,7 +367,6 @@ fail:
} else {
// recycled zone content (bind back to old zone)
if (!new_content) {
old_zone->contents->zone = old_zone;
new_zone->contents = NULL;
}
......@@ -433,7 +431,6 @@ static int zone_loader_thread(dthread_t *thread)
// recycled zone content (bind back to old zone)
if (old_zone && old_zone->contents == zone->contents) {
old_zone->contents->zone = old_zone;
zone->contents = NULL;
}
......
......@@ -45,9 +45,6 @@
#include "knot/zone/zone.h"
#include "knot/zone/zonedb.h"
/* Forward declarations. */
static int zones_dump_zone_text(knot_zone_contents_t *zone, const char *zf);
/*!
* \brief Apply jitter to time interval.
*
......@@ -906,7 +903,6 @@ static zone_t *create_fake_zone(zone_t *zone)
// steal the zone content
fake->contents = zone->contents;
fake->contents->zone = fake;
return fake;
}
......@@ -1042,7 +1038,6 @@ int zones_process_update_auth(zone_t *zone, knot_pkt_t *query,
knot_changesets_free(&sec_chs);
free(msg);
zone_free(&fake_zone);
zone->contents->zone = zone;
return ret;
}
......@@ -1062,7 +1057,6 @@ int zones_process_update_auth(zone_t *zone, knot_pkt_t *query,
zones_free_merged_changesets(chgsets, sec_chs);
free(msg);
zone_free(&fake_zone);
zone->contents->zone = zone;
return ret;
}
......@@ -1108,7 +1102,6 @@ int zones_process_update_auth(zone_t *zone, knot_pkt_t *query,
}
zone_free(&fake_zone);
zone->contents->zone = zone;
dbg_zones_verb("%s: DNSSEC changes applied\n", msg);
......@@ -1175,6 +1168,79 @@ int zones_process_update_auth(zone_t *zone, knot_pkt_t *query,
return ret;
}
/*----------------------------------------------------------------------------*/
static int zones_open_free_filename(const char *old_name, char **new_name)
{
/* find zone name not present on the disk */
size_t name_size = strlen(old_name);
*new_name = malloc(name_size + 7 + 1);
if (*new_name == NULL) {
return -1;
}
memcpy(*new_name, old_name, name_size + 1);
strncat(*new_name, ".XXXXXX", 7);
dbg_zones_verb("zones: creating temporary zone file\n");
mode_t old_mode = umask(077);
int fd = mkstemp(*new_name);
UNUSED(umask(old_mode));
if (fd < 0) {
dbg_zones_verb("zones: couldn't create temporary zone file\n");
free(*new_name);
*new_name = NULL;
}
return fd;
}
/*----------------------------------------------------------------------------*/
static int save_transferred_zone(knot_zone_contents_t *zone, const sockaddr_t *from, const char *fname)
{
assert(zone != NULL && fname != NULL);
char *new_fname = NULL;
int fd = zones_open_free_filename(fname, &new_fname);
if (fd < 0) {
return KNOT_EWRITABLE;
}
FILE *f = fdopen(fd, "w");
if (f == NULL) {
log_zone_warning("Failed to open file descriptor for text zone.\n");
unlink(new_fname);
free(new_fname);
return KNOT_ERROR;
}
if (zone_dump_text(zone, from, f) != KNOT_EOK) {
log_zone_warning("Failed to save the transferred zone to '%s'.\n",
new_fname);
fclose(f);
unlink(new_fname);
free(new_fname);
return KNOT_ERROR;
}
/* Set zone file rights to 0640. */
fchmod(fd, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP);
/* Swap temporary zonefile and new zonefile. */
fclose(f);
int ret = rename(new_fname, fname);
if (ret < 0 && ret != EEXIST) {
log_zone_warning("Failed to replace old zone file '%s'' with a "
"new zone file '%s'.\n", fname, new_fname);
unlink(new_fname);
free(new_fname);
return KNOT_ERROR;
}
free(new_fname);
return KNOT_EOK;
}
/*----------------------------------------------------------------------------*/
/* API functions */
/*----------------------------------------------------------------------------*/
......@@ -1224,7 +1290,7 @@ int zones_zonefile_sync(zone_t *zone, journal_t *journal)
dbg_zones("zones: syncing '%s' differences to '%s' "
"(SOA serial %u)\n",
zone->conf->name, zone->conf->file, serial_to);
ret = zones_dump_zone_text(contents, zone->conf->file);
ret = save_transferred_zone(zone->contents, &zone->xfr_in.master, zone->conf->file);
if (ret != KNOT_EOK) {
log_zone_warning("Failed to apply differences "
"'%s' to '%s (%s)'\n",
......@@ -1388,79 +1454,6 @@ knot_ns_xfr_type_t zones_transfer_to_use(zone_t *zone)
/*----------------------------------------------------------------------------*/
static int zones_open_free_filename(const char *old_name, char **new_name)
{
/* find zone name not present on the disk */
size_t name_size = strlen(old_name);
*new_name = malloc(name_size + 7 + 1);
if (*new_name == NULL) {
return -1;
}
memcpy(*new_name, old_name, name_size + 1);
strncat(*new_name, ".XXXXXX", 7);
dbg_zones_verb("zones: creating temporary zone file\n");
mode_t old_mode = umask(077);
int fd = mkstemp(*new_name);
UNUSED(umask(old_mode));
if (fd < 0) {
dbg_zones_verb("zones: couldn't create temporary zone file\n");
free(*new_name);
*new_name = NULL;
}
return fd;
}
/*----------------------------------------------------------------------------*/
static int zones_dump_zone_text(knot_zone_contents_t *zone, const char *fname)
{
assert(zone != NULL && fname != NULL);
char *new_fname = NULL;
int fd = zones_open_free_filename(fname, &new_fname);
if (fd < 0) {
return KNOT_EWRITABLE;
}
FILE *f = fdopen(fd, "w");
if (f == NULL) {
log_zone_warning("Failed to open file descriptor for text zone.\n");
unlink(new_fname);
free(new_fname);
return KNOT_ERROR;
}
if (zone_dump_text(zone, f) != KNOT_EOK) {
log_zone_warning("Failed to save the transferred zone to '%s'.\n",
new_fname);
fclose(f);
unlink(new_fname);
free(new_fname);
return KNOT_ERROR;
}
/* Set zone file rights to 0640. */
fchmod(fd, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP);
/* Swap temporary zonefile and new zonefile. */
fclose(f);
int ret = rename(new_fname, fname);
if (ret < 0 && ret != EEXIST) {
log_zone_warning("Failed to replace old zone file '%s'' with a "
"new zone file '%s'.\n", fname, new_fname);
unlink(new_fname);
free(new_fname);
return KNOT_ERROR;
}
free(new_fname);
return KNOT_EOK;
}
/*----------------------------------------------------------------------------*/
int zones_save_zone(const knot_ns_xfr_t *xfr)
{
/* Zone is already referenced, no need for RCU locking. */
......@@ -1491,7 +1484,7 @@ int zones_save_zone(const knot_ns_xfr_t *xfr)
assert(zonefile != NULL);
/* dump the zone into text zone file */
int ret = zones_dump_zone_text(new_zone, zonefile);
int ret = save_transferred_zone(new_zone, &xfr->addr, zonefile);
rcu_read_unlock();
return ret;
}
......
......@@ -428,7 +428,6 @@ knot_zone_contents_t *knot_zone_contents_new(knot_node_t *apex,
}
contents->apex = apex;
contents->zone = zone;
contents->node_count = 1;
dbg_zone_verb("Creating tree for normal nodes.\n");
......@@ -1537,8 +1536,6 @@ int knot_zone_contents_shallow_copy(const knot_zone_contents_t *from,
// set the 'new' flag
knot_zone_contents_set_gen_new(contents);
contents->zone = from->zone;
if ((ret = knot_zone_tree_deep_copy(from->nodes,
&contents->nodes)) != KNOT_EOK
|| (ret = knot_zone_tree_deep_copy(from->nsec3_nodes,
......
......@@ -48,8 +48,6 @@ typedef struct knot_zone_contents_t {
knot_zone_tree_t *nodes;
knot_zone_tree_t *nsec3_nodes;
struct zone_t *zone;
knot_nsec3_params_t nsec3_params;
/*!
......
......@@ -148,7 +148,7 @@ static int node_dump_text(knot_node_t *node, void *data)
return KNOT_EOK;
}
int zone_dump_text(knot_zone_contents_t *zone, FILE *file)
int zone_dump_text(knot_zone_contents_t *zone, const sockaddr_t *from, FILE *file)
{
if (zone == NULL || file == NULL) {
return KNOT_EINVAL;
......@@ -164,12 +164,13 @@ int zone_dump_text(knot_zone_contents_t *zone, FILE *file)
fprintf(file, ";; Zone dump (Knot DNS %s)\n", PACKAGE_VERSION);
// Set structure with parameters.
knot_node_t *apex = zone->apex;
dump_params_t params;
params.file = file;
params.buf = buf;
params.buflen = DUMP_BUF_LEN;
params.rr_count = 0;
params.origin = knot_node_owner(knot_zone_contents_apex(zone));
params.origin = knot_node_owner(apex);
params.style = &KNOT_DUMP_STYLE_DEFAULT;
int ret;
......@@ -184,8 +185,7 @@ int zone_dump_text(knot_zone_contents_t *zone, FILE *file)
}
// Dump DNSSEC signatures if secured.
const knot_rrset_t *soa = knot_node_rrset(knot_zone_contents_apex(zone),
KNOT_RRTYPE_SOA);
const knot_rrset_t *soa = knot_node_rrset(apex, KNOT_RRTYPE_SOA);
if (soa && soa->rrsigs) {
fprintf(file, ";; DNSSEC signatures\n");
......@@ -239,14 +239,12 @@ int zone_dump_text(knot_zone_contents_t *zone, FILE *file)
params.rr_count, date);
// Get master information.
sockaddr_t *master = &zone->zone->xfr_in.master;
int port = sockaddr_portnum(master);
int port = sockaddr_portnum(from);
// If a master server is configured, dump info about it.
if (port >= 0) {
char addr[INET6_ADDRSTRLEN] = "NULL";
sockaddr_tostr(master, addr, sizeof(addr));
sockaddr_tostr(from, addr, sizeof(addr));
fprintf(file, ";; Transfered from %s#%i\n", addr, port);
}
......
......@@ -33,12 +33,13 @@
* \brief Dumps given zone to text file.
*
* \param zone Zone to be saved.
* \param from From where the zone originated.
* \param file File to write to.
*
* \retval KNOT_EOK on success.
* \retval < 0 if error.
*/
int zone_dump_text(knot_zone_contents_t *zone, FILE *file);
int zone_dump_text(knot_zone_contents_t *zone, const sockaddr_t *from, FILE *file);
#endif // _KNOTD_ZONEDUMP_H_
......
......@@ -239,7 +239,7 @@ static void process_rr(const scanner_t *scanner)
return;
}
knot_zone_contents_t *contents = parser->current_zone;
knot_zone_contents_t *contents = parser->current_zone->contents;
/*!
* \todo Node/RRSet compression at this level? To avoid duplicate
......@@ -473,10 +473,10 @@ static void process_rr(const scanner_t *scanner)
} else if (ret > 0) {
knot_rrset_deep_free(&current_rrset, 1);
}
assert(parser->current_zone && node);
assert(contents && node);
/* Do mandatory semantic checks. */
bool sem_fatal_error = false;
ret = sem_check_node_plain(parser->current_zone, node,
ret = sem_check_node_plain(parser->current_zone->contents, node,
parser->err_handler, true,
&sem_fatal_error);
if (ret != KNOT_EOK) {
......@@ -536,7 +536,7 @@ int knot_zload_open(zloader_t **dst, const conf_zone_t *conf)
/* As it's a first node, no need for compression yet. */
context->origin_from_config = knot_dname_copy(zone->name);
context->current_zone = zone->contents;
context->current_zone = zone;
context->last_node = zone->contents->apex;
context->node_rrsigs = NULL;
context->ret = KNOT_EOK;
......@@ -585,6 +585,7 @@ zone_t *knot_zload_load(zloader_t *loader)
}
parser_context_t *c = loader->context;
knot_node_t *apex = c->current_zone->contents->apex;
assert(c);
int ret = file_loader_process(loader->file_loader);
if (ret != ZSCANNER_OK) {
......@@ -593,15 +594,14 @@ zone_t *knot_zload_load(zloader_t *loader)
}
if (c->last_node && c->node_rrsigs) {
process_rrsigs_in_node(c, c->current_zone, c->last_node);
process_rrsigs_in_node(c, c->current_zone->contents, c->last_node);
}
if (c->ret != KNOT_EOK) {
log_zone_error("%s: zone file could not be loaded (%s).\n",
loader->source, zscanner_strerror(c->ret));
rrset_list_delete(&c->node_rrsigs);
zone_t *zone_to_free = c->current_zone->zone;
zone_deep_free(&zone_to_free);
zone_deep_free(&c->current_zone);
return NULL;
}
......@@ -611,52 +611,43 @@ zone_t *knot_zload_load(zloader_t *loader)
loader->source,
loader->file_loader->scanner->error_counter);
rrset_list_delete(&c->node_rrsigs);
zone_t *zone_to_free = c->current_zone->zone;
zone_deep_free(&zone_to_free);
zone_deep_free(&c->current_zone);
return NULL;
}
if (knot_zone_contents_apex(c->current_zone) == NULL ||
knot_node_rrset(knot_zone_contents_apex(c->current_zone),
KNOT_RRTYPE_SOA) == NULL) {
if (knot_node_rrset(apex, KNOT_RRTYPE_SOA) == NULL) {
log_zone_error("%s: no SOA record in the zone file.\n",
loader->source);
rrset_list_delete(&c->node_rrsigs);
zone_t *zone_to_free = c->current_zone->zone;
zone_deep_free(&zone_to_free);
zone_deep_free(&c->current_zone);
return NULL;
}
knot_node_t *first_nsec3_node = NULL;
knot_node_t *last_nsec3_node = NULL;
rrset_list_delete(&c->node_rrsigs);
int kret = knot_zone_contents_adjust_full(c->current_zone, &first_nsec3_node,
int kret = knot_zone_contents_adjust_full(c->current_zone->contents, &first_nsec3_node,
&last_nsec3_node);
if (kret != KNOT_EOK) {
log_zone_error("%s: Failed to finalize zone contents: %s\n",
loader->source, knot_strerror(kret));
rrset_list_delete(&c->node_rrsigs);
zone_t *zone_to_free = c->current_zone->zone;
zone_deep_free(&zone_to_free);
zone_deep_free(&c->current_zone);
return NULL;
}
if (loader->semantic_checks) {
int check_level = 1;
const knot_rrset_t *soa_rr =
knot_node_rrset(knot_zone_contents_apex(c->current_zone),
KNOT_RRTYPE_SOA);
const knot_rrset_t *soa_rr = knot_node_rrset(apex, KNOT_RRTYPE_SOA);
assert(soa_rr); // In this point, SOA has to exist
const knot_rrset_t *nsec3param_rr =
knot_node_rrset(knot_zone_contents_apex(c->current_zone),
KNOT_RRTYPE_NSEC3PARAM);
const knot_rrset_t *nsec3param_rr = knot_node_rrset(apex, KNOT_RRTYPE_NSEC3PARAM);
if (soa_rr->rrsigs && nsec3param_rr == NULL) {
/* Set check level to DNSSEC. */
check_level = 2;
} else if (soa_rr->rrsigs && nsec3param_rr) {
check_level = 3;
}
zone_do_sem_checks(c->current_zone, check_level,
zone_do_sem_checks(c->current_zone->contents, check_level,
loader->err_handler, first_nsec3_node,
last_nsec3_node);
char *zname = knot_dname_to_str(knot_rrset_owner(soa_rr));
......@@ -664,7 +655,7 @@ zone_t *knot_zload_load(zloader_t *loader)
free(zname);
}
return c->current_zone->zone;
return c->current_zone;
}
void knot_zload_close(zloader_t *loader)
......
......@@ -46,7 +46,7 @@ typedef struct rrset_list rrset_list_t;
struct parser_context {
rrset_list_t *node_rrsigs;
knot_zone_contents_t *current_zone;
zone_t *current_zone;
knot_rrset_t *current_rrset;
knot_dname_t *origin_from_config;
knot_node_t *last_node;
......
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