Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Knot DNS
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
22
Issues
22
List
Boards
Labels
Service Desk
Milestones
Merge Requests
18
Merge Requests
18
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Incidents
Environments
Packages & Registries
Packages & Registries
Container Registry
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Knot projects
Knot DNS
Commits
6148338b
Commit
6148338b
authored
Feb 04, 2016
by
Dominik Taborsky
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
zone contents: cleanup of changeset-related functions, comments
parent
c449adcd
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
191 additions
and
137 deletions
+191
-137
src/knot/updates/changesets.c
src/knot/updates/changesets.c
+2
-2
src/knot/zone/contents.c
src/knot/zone/contents.c
+120
-125
src/knot/zone/contents.h
src/knot/zone/contents.h
+49
-10
src/libknot/rrset.c
src/libknot/rrset.c
+14
-0
src/libknot/rrset.h
src/libknot/rrset.h
+6
-0
No files found.
src/knot/updates/changesets.c
View file @
6148338b
...
...
@@ -178,8 +178,8 @@ static bool need_to_insert(zone_contents_t *counterpart, const knot_rrset_t *rr)
if
(
node
->
rrset_count
==
0
)
{
// Remove empty node.
zone_tree_t
*
t
=
zone_contents_rrset_is_nsec3rel
(
rr
)
?
counterpart
->
nsec3_nodes
:
counterpart
->
nodes
;
zone_tree_t
*
t
=
knot_rrset_is_nsec3rel
(
rr
)
?
counterpart
->
nsec3_nodes
:
counterpart
->
nodes
;
zone_contents_delete_empty_node
(
counterpart
,
t
,
node
);
}
...
...
src/knot/zone/contents.c
View file @
6148338b
...
...
@@ -643,18 +643,61 @@ static int recreate_nsec3_tree(const zone_contents_t *z, zone_contents_t *out)
return
KNOT_EOK
;
}
bool
zone_contents_rrset_is_nsec3rel
(
const
knot_rrset_t
*
rr
)
static
zone_node_t
*
get_previous
(
const
zone_contents_t
*
zone
,
const
knot_dname_t
*
name
)
{
if
(
rr
==
NULL
)
{
return
false
;
if
(
zone
==
NULL
||
name
==
NULL
)
{
return
NULL
;
}
zone_node_t
*
found
=
NULL
,
*
prev
=
NULL
;
int
exact_match
=
find_in_tree
(
zone
->
nodes
,
name
,
&
found
,
&
prev
);
assert
(
exact_match
>=
0
);
//assert(prev != NULL);
return
prev
;
}
static
zone_node_t
*
zone_contents_get_greatest_child
(
const
zone_contents_t
*
zone
,
const
knot_dname_t
*
parent
)
{
if
(
knot_dname_size
(
parent
)
+
2
>
KNOT_DNAME_MAXLEN
)
{
// Not enough space for children.
return
NULL
;
}
knot_dname_t
dn
[
KNOT_DNAME_MAXLEN
]
=
{
0x01
,
0xff
};
knot_dname_to_wire
(
dn
+
2
,
parent
,
KNOT_DNAME_MAXLEN
);
zone_node_t
*
child
=
get_node
(
zone
,
dn
);
if
(
child
)
{
return
child
;
}
/* Is NSEC3 or non-empty RRSIG covering NSEC3. */
return
((
rr
->
type
==
KNOT_RRTYPE_NSEC3
)
||
(
rr
->
type
==
KNOT_RRTYPE_RRSIG
&&
knot_rrsig_type_covered
(
&
rr
->
rrs
,
0
)
==
KNOT_RRTYPE_NSEC3
));
child
=
get_previous
(
zone
,
dn
);
if
(
!
child
)
{
return
NULL
;
}
//assert(child);
const
int
parent_labels
=
knot_dname_labels
(
parent
,
NULL
);
const
int
child_labels
=
knot_dname_labels
(
child
->
owner
,
NULL
);
if
(
child_labels
<=
parent_labels
)
{
return
NULL
;
}
if
(
knot_dname_matched_labels
(
parent
,
child
->
owner
)
!=
parent_labels
)
{
return
NULL
;
}
return
child
;
}
static
bool
contents_has_children
(
const
zone_contents_t
*
zone
,
const
knot_dname_t
*
owner
)
{
return
zone_contents_get_greatest_child
(
zone
,
owner
)
!=
NULL
;
}
// Public API
int
zone_contents_add_rr
(
zone_contents_t
*
z
,
const
knot_rrset_t
*
rr
,
zone_node_t
**
n
)
{
...
...
@@ -662,15 +705,82 @@ int zone_contents_add_rr(zone_contents_t *z, const knot_rrset_t *rr,
return
KNOT_EINVAL
;
}
return
insert_rr
(
z
,
rr
,
n
,
zone_contents_rrset_is_nsec3rel
(
rr
));
return
insert_rr
(
z
,
rr
,
n
,
knot_rrset_is_nsec3rel
(
rr
));
}
zone_node_t
*
zone_contents_get_node_for_rr
(
zone_contents_t
*
zone
,
const
knot_rrset_t
*
rrset
)
{
if
(
zone
==
NULL
||
rrset
==
NULL
)
{
return
NULL
;
}
const
bool
nsec3
=
knot_rrset_is_nsec3rel
(
rrset
);
zone_node_t
*
node
=
nsec3
?
get_nsec3_node
(
zone
,
rrset
->
owner
)
:
get_node
(
zone
,
rrset
->
owner
);
if
(
node
==
NULL
)
{
node
=
node_new
(
rrset
->
owner
,
NULL
);
int
ret
=
nsec3
?
add_nsec3_node
(
zone
,
node
)
:
add_node
(
zone
,
node
,
1
);
if
(
ret
!=
KNOT_EOK
)
{
node_free
(
&
node
,
NULL
);
return
NULL
;
}
return
node
;
}
else
{
return
node
;
}
}
int
zone_contents_delete_empty_node
(
zone_contents_t
*
contents
,
zone_tree_t
*
tree
,
zone_node_t
*
node
)
{
if
(
!
contents
||
!
tree
||
!
node
)
{
return
KNOT_EINVAL
;
}
if
(
node
->
rrset_count
==
0
&&
!
contents_has_children
(
contents
,
node
->
owner
))
{
const
knot_dname_t
*
parent_dname
=
knot_wire_next_label
(
node
->
owner
,
NULL
);
zone_node_t
*
parent_node
=
NULL
;
if
(
tree
==
contents
->
nsec3_nodes
)
{
// Only one level in NSEC3 tree
parent_node
=
(
node
==
contents
->
apex
)
?
NULL
:
contents
->
apex
;
}
else
{
parent_node
=
(
zone_node_t
*
)
zone_contents_find_node
(
contents
,
parent_dname
);
}
if
(
parent_node
&&
parent_node
!=
contents
->
apex
)
{
// Recurse using the parent node, do not delete possibly empty parent.
int
ret
=
zone_contents_delete_empty_node
(
contents
,
tree
,
parent_node
);
if
(
ret
!=
KNOT_EOK
)
{
return
ret
;
}
}
// Delete node
zone_node_t
*
removed_node
=
NULL
;
zone_tree_remove
(
tree
,
node
->
owner
,
&
removed_node
);
UNUSED
(
removed_node
);
node_free
(
&
node
,
NULL
);
}
return
KNOT_EOK
;
}
const
zone_node_t
*
zone_contents_find_node
(
const
zone_contents_t
*
zone
,
const
knot_dname_t
*
name
)
const
zone_node_t
*
zone_contents_find_node
(
const
zone_contents_t
*
zone
,
const
knot_dname_t
*
name
)
{
return
get_node
(
zone
,
name
);
}
zone_node_t
*
zone_contents_find_node_for_rr
(
zone_contents_t
*
contents
,
const
knot_rrset_t
*
rrset
)
{
if
(
contents
==
NULL
||
rrset
==
NULL
)
{
return
NULL
;
}
const
bool
nsec3
=
knot_rrset_is_nsec3rel
(
rrset
);
return
nsec3
?
get_nsec3_node
(
contents
,
rrset
->
owner
)
:
get_node
(
contents
,
rrset
->
owner
);
}
int
zone_contents_find_dname
(
const
zone_contents_t
*
zone
,
const
knot_dname_t
*
name
,
const
zone_node_t
**
node
,
...
...
@@ -723,22 +833,6 @@ int zone_contents_find_dname(const zone_contents_t *zone,
return
exact_match
?
ZONE_NAME_FOUND
:
ZONE_NAME_NOT_FOUND
;
}
static
zone_node_t
*
get_previous
(
const
zone_contents_t
*
zone
,
const
knot_dname_t
*
name
)
{
if
(
zone
==
NULL
||
name
==
NULL
)
{
return
NULL
;
}
zone_node_t
*
found
=
NULL
,
*
prev
=
NULL
;
int
exact_match
=
find_in_tree
(
zone
->
nodes
,
name
,
&
found
,
&
prev
);
assert
(
exact_match
>=
0
);
//assert(prev != NULL);
return
prev
;
}
const
zone_node_t
*
zone_contents_find_previous
(
const
zone_contents_t
*
zone
,
const
knot_dname_t
*
name
)
{
...
...
@@ -1100,102 +1194,3 @@ bool zone_contents_is_empty(const zone_contents_t *zone)
{
return
!
zone
||
!
node_rrtype_exists
(
zone
->
apex
,
KNOT_RRTYPE_SOA
);
}
zone_node_t
*
zone_contents_get_node_for_rr
(
zone_contents_t
*
zone
,
const
knot_rrset_t
*
rrset
)
{
if
(
zone
==
NULL
||
rrset
==
NULL
)
{
return
NULL
;
}
const
bool
nsec3
=
zone_contents_rrset_is_nsec3rel
(
rrset
);
zone_node_t
*
node
=
nsec3
?
get_nsec3_node
(
zone
,
rrset
->
owner
)
:
get_node
(
zone
,
rrset
->
owner
);
if
(
node
==
NULL
)
{
node
=
node_new
(
rrset
->
owner
,
NULL
);
int
ret
=
nsec3
?
add_nsec3_node
(
zone
,
node
)
:
add_node
(
zone
,
node
,
1
);
if
(
ret
!=
KNOT_EOK
)
{
node_free
(
&
node
,
NULL
);
return
NULL
;
}
return
node
;
}
else
{
return
node
;
}
}
zone_node_t
*
zone_contents_find_node_for_rr
(
zone_contents_t
*
zone
,
const
knot_rrset_t
*
rrset
)
{
if
(
zone
==
NULL
||
rrset
==
NULL
)
{
return
NULL
;
}
const
bool
nsec3
=
zone_contents_rrset_is_nsec3rel
(
rrset
);
return
nsec3
?
get_nsec3_node
(
zone
,
rrset
->
owner
)
:
get_node
(
zone
,
rrset
->
owner
);
}
zone_node_t
*
zone_contents_greatest_child
(
const
zone_contents_t
*
zone
,
const
knot_dname_t
*
parent
)
{
if
(
knot_dname_size
(
parent
)
+
2
>
KNOT_DNAME_MAXLEN
)
{
// Not enough space for children.
return
NULL
;
}
knot_dname_t
dn
[
KNOT_DNAME_MAXLEN
]
=
{
0x01
,
0xff
};
knot_dname_to_wire
(
dn
+
2
,
parent
,
KNOT_DNAME_MAXLEN
);
zone_node_t
*
child
=
get_node
(
zone
,
dn
);
if
(
child
)
{
return
child
;
}
child
=
get_previous
(
zone
,
dn
);
if
(
!
child
)
{
return
NULL
;
}
//assert(child);
const
int
parent_labels
=
knot_dname_labels
(
parent
,
NULL
);
const
int
child_labels
=
knot_dname_labels
(
child
->
owner
,
NULL
);
if
(
child_labels
<=
parent_labels
)
{
return
NULL
;
}
if
(
knot_dname_matched_labels
(
parent
,
child
->
owner
)
!=
parent_labels
)
{
return
NULL
;
}
return
child
;
}
static
bool
contents_has_children
(
const
zone_contents_t
*
zone
,
const
knot_dname_t
*
owner
)
{
return
zone_contents_greatest_child
(
zone
,
owner
)
!=
NULL
;
}
void
zone_contents_delete_empty_node
(
zone_contents_t
*
zone
,
zone_tree_t
*
tree
,
zone_node_t
*
node
)
{
assert
(
zone
);
assert
(
tree
);
assert
(
node
);
if
(
node
->
rrset_count
==
0
&&
!
contents_has_children
(
zone
,
node
->
owner
))
{
const
knot_dname_t
*
parent_dname
=
knot_wire_next_label
(
node
->
owner
,
NULL
);
zone_node_t
*
parent_node
=
NULL
;
if
(
tree
==
zone
->
nsec3_nodes
)
{
// Only one level in NSEC3 tree
parent_node
=
(
node
==
zone
->
apex
)
?
NULL
:
zone
->
apex
;
}
else
{
parent_node
=
zone_contents_find_node
(
zone
,
parent_dname
);
}
if
(
parent_node
&&
parent_node
!=
zone
->
apex
)
{
// Recurse using the parent node, do not delete possibly empty parent.
zone_contents_delete_empty_node
(
zone
,
tree
,
parent_node
);
}
// Delete node
zone_node_t
*
removed_node
=
NULL
;
zone_tree_remove
(
tree
,
node
->
owner
,
&
removed_node
);
UNUSED
(
removed_node
);
node_free
(
&
node
,
NULL
);
}
}
src/knot/zone/contents.h
View file @
6148338b
...
...
@@ -48,13 +48,46 @@ typedef struct zone_contents {
*/
typedef
int
(
*
zone_contents_apply_cb_t
)(
zone_node_t
*
node
,
void
*
data
);
/*!
* \brief Allocate and create new zone contents.
*
* \param apex_name Name of the root node.
*
* \return New contents or NULL on error.
*/
zone_contents_t
*
zone_contents_new
(
const
knot_dname_t
*
apex_name
);
/*!
* \brief Add an RR to contents.
*
* \param z Contents to add to.
* \param rr The RR to add.
* \param n Node to which the RR has been added to on success, unchanged otherwise.
*
* \return KNOT_E*
*/
int
zone_contents_add_rr
(
zone_contents_t
*
z
,
const
knot_rrset_t
*
rr
,
zone_node_t
**
n
);
bool
zone_contents_rrset_is_nsec3rel
(
const
knot_rrset_t
*
rr
);
/*!
* \brief Get the node with this RR (the RR's owner).
*
* \param zone Contents to add to.
* \param rrset The RR to add.
*
* \return The searched node if it exists, a new added empty node or NULL on error.
*/
zone_node_t
*
zone_contents_get_node_for_rr
(
zone_contents_t
*
zone
,
const
knot_rrset_t
*
rrset
);
int
zone_contents_add_rr
(
zone_contents_t
*
z
,
const
knot_rrset_t
*
rr
,
zone_node_t
**
n
);
/*!
* \brief Delete a node that has no RRSets and no children.
*
* \param contents Contents to delete from.
* \param tree The tree to remove from.
* \param node The node to remove.
*
* \return KNOT_E*.
*/
int
zone_contents_delete_empty_node
(
zone_contents_t
*
contents
,
zone_tree_t
*
tree
,
zone_node_t
*
node
);
/*!
* \brief Tries to find a node with the specified name in the zone.
...
...
@@ -67,8 +100,9 @@ int zone_contents_add_rr(zone_contents_t *z, const knot_rrset_t *rr, zone_node_t
*
* \return Corresponding node if found, NULL otherwise.
*/
const
zone_node_t
*
zone_contents_find_node
(
const
zone_contents_t
*
contents
,
const
knot_dname_t
*
name
);
const
zone_node_t
*
zone_contents_find_node
(
const
zone_contents_t
*
contents
,
const
knot_dname_t
*
name
);
zone_node_t
*
zone_contents_find_node_for_rr
(
zone_contents_t
*
contents
,
const
knot_rrset_t
*
rrset
);
/*!
* \brief Tries to find a node by owner in the zone contents.
...
...
@@ -249,8 +283,18 @@ int zone_contents_nsec3_apply_inorder(zone_contents_t *zone,
*/
int
zone_contents_shallow_copy
(
const
zone_contents_t
*
from
,
zone_contents_t
**
to
);
/*!
* \brief Deallocate directly owned data of zone contents.
*
* \param contents Zone contents to free.
*/
void
zone_contents_free
(
zone_contents_t
**
contents
);
/*!
* \brief Deallocate node RRSets inside the trees, then call zone_contents_free.
*
* \param contents Zone contents to free.
*/
void
zone_contents_deep_free
(
zone_contents_t
**
contents
);
/*!
...
...
@@ -272,9 +316,4 @@ bool zone_contents_is_signed(const zone_contents_t *zone);
*/
bool
zone_contents_is_empty
(
const
zone_contents_t
*
zone
);
zone_node_t
*
zone_contents_get_node_for_rr
(
zone_contents_t
*
zone
,
const
knot_rrset_t
*
rrset
);
zone_node_t
*
zone_contents_find_node_for_rr
(
zone_contents_t
*
zone
,
const
knot_rrset_t
*
rrset
);
void
zone_contents_delete_empty_node
(
zone_contents_t
*
zone
,
zone_tree_t
*
tree
,
zone_node_t
*
node
);
/*! @} */
src/libknot/rrset.c
View file @
6148338b
...
...
@@ -26,6 +26,7 @@
#include "libknot/internal/mempattern.h"
#include "libknot/rrset.h"
#include "libknot/rrtype/naptr.h"
#include "libknot/rrtype/rrsig.h"
_public_
knot_rrset_t
*
knot_rrset_new
(
const
knot_dname_t
*
owner
,
uint16_t
type
,
...
...
@@ -168,6 +169,19 @@ uint32_t knot_rrset_ttl(const knot_rrset_t *rrset)
return
knot_rdata_ttl
(
knot_rdataset_at
(
&
(
rrset
->
rrs
),
0
));
}
_public_
bool
knot_rrset_is_nsec3rel
(
const
knot_rrset_t
*
rr
)
{
if
(
rr
==
NULL
)
{
return
false
;
}
/* Is NSEC3 or non-empty RRSIG covering NSEC3. */
return
((
rr
->
type
==
KNOT_RRTYPE_NSEC3
)
||
(
rr
->
type
==
KNOT_RRTYPE_RRSIG
&&
knot_rrsig_type_covered
(
&
rr
->
rrs
,
0
)
==
KNOT_RRTYPE_NSEC3
));
}
_public_
int
knot_rrset_rr_to_canonical
(
knot_rrset_t
*
rrset
)
{
...
...
src/libknot/rrset.h
View file @
6148338b
...
...
@@ -175,6 +175,12 @@ bool knot_rrset_empty(const knot_rrset_t *rrset);
*/
uint32_t
knot_rrset_ttl
(
const
knot_rrset_t
*
rrset
);
/*!
* \brief Return whether the RR type is NSEC3 related (NSEC3 or RRSIG).
*/
bool
knot_rrset_is_nsec3rel
(
const
knot_rrset_t
*
rr
);
/*!
* \brief Convert one RR into canonical format.
*
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment