Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
7
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Open sidebar
Knot projects
Knot DNS
Commits
fbcf93ea
Commit
fbcf93ea
authored
Jun 17, 2014
by
Ondřej Surý
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'events-replan' into 'master'
Events replan
parents
63022901
807b3198
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
153 additions
and
32 deletions
+153
-32
src/knot/nameserver/update.c
src/knot/nameserver/update.c
+5
-1
src/knot/zone/events.c
src/knot/zone/events.c
+127
-9
src/knot/zone/events.h
src/knot/zone/events.h
+16
-0
src/knot/zone/zone.c
src/knot/zone/zone.c
+1
-1
src/knot/zone/zonedb-load.c
src/knot/zone/zonedb-load.c
+3
-20
tests-extra/tests/events/soa/test.py
tests-extra/tests/events/soa/test.py
+1
-1
No files found.
src/knot/nameserver/update.c
View file @
fbcf93ea
...
...
@@ -133,7 +133,11 @@ static int sign_update(zone_t *zone, const zone_contents_t *old_contents,
free
(
sec_chs
);
// Plan next zone resign.
zone_events_schedule
(
zone
,
ZONE_EVENT_DNSSEC
,
refresh_at
);
const
time_t
resign_time
=
zone_events_get_time
(
zone
,
ZONE_EVENT_DNSSEC
);
assert
(
resign_time
>
ZONE_EVENT_NOW
);
if
(
time
(
NULL
)
+
refresh_at
<
resign_time
)
{
zone_events_schedule
(
zone
,
ZONE_EVENT_DNSSEC
,
refresh_at
);
}
return
ret
;
}
...
...
src/knot/zone/events.c
View file @
fbcf93ea
...
...
@@ -220,7 +220,7 @@ static uint32_t soa_graceful_expire(const knot_rdataset_t *soa)
{
// Allow for timeouts. Otherwise zones with very short
// expiry may expire before the timeout is reached.
return
knot_soa_expire
(
soa
)
+
2
*
(
conf
()
->
max_conn_idle
*
1000
)
;
return
knot_soa_expire
(
soa
)
+
2
*
conf
()
->
max_conn_idle
;
}
typedef
int
(
*
zone_event_cb
)(
zone_t
*
zone
);
...
...
@@ -277,6 +277,8 @@ static int event_reload(zone_t *zone)
/* Schedule notify and refresh after load. */
if
(
zone_master
(
zone
))
{
zone_events_schedule
(
zone
,
ZONE_EVENT_REFRESH
,
ZONE_EVENT_NOW
);
const
knot_rdataset_t
*
soa
=
node_rdataset
(
contents
->
apex
,
KNOT_RRTYPE_SOA
);
zone_events_schedule
(
zone
,
ZONE_EVENT_EXPIRE
,
soa_graceful_expire
(
soa
));
}
if
(
!
zone_contents_is_empty
(
contents
))
{
zone_events_schedule
(
zone
,
ZONE_EVENT_NOTIFY
,
ZONE_EVENT_NOW
);
...
...
@@ -550,6 +552,110 @@ done:
#undef ZONE_QUERY_LOG
/* -- Zone event replanning functions --------------------------------------- */
/*!< \brief Replans event for new zone according to old zone. */
static
void
replan_event
(
zone_t
*
zone
,
const
zone_t
*
old_zone
,
zone_event_type_t
e
)
{
const
time_t
event_time
=
zone_events_get_time
(
old_zone
,
e
);
if
(
event_time
>
ZONE_EVENT_NOW
)
{
zone_events_schedule_at
(
zone
,
e
,
event_time
);
}
}
/*!< \brief Replans events that are dependent on the SOA record. */
static
void
replan_soa_events
(
zone_t
*
zone
,
const
zone_t
*
old_zone
)
{
if
(
!
zone_master
(
zone
))
{
// Events only valid for slaves.
return
;
}
if
(
zone_master
(
old_zone
))
{
// Replan SOA events.
replan_event
(
zone
,
old_zone
,
ZONE_EVENT_REFRESH
);
replan_event
(
zone
,
old_zone
,
ZONE_EVENT_EXPIRE
);
}
else
{
// Plan SOA events anew.
if
(
!
zone_contents_is_empty
(
zone
->
contents
))
{
const
knot_rdataset_t
*
soa
=
node_rdataset
(
zone
->
contents
->
apex
,
KNOT_RRTYPE_SOA
);
assert
(
soa
);
zone_events_schedule
(
zone
,
ZONE_EVENT_REFRESH
,
knot_soa_refresh
(
soa
));
zone_events_schedule
(
zone
,
ZONE_EVENT_EXPIRE
,
soa_graceful_expire
(
soa
));
}
}
}
/*!< \brief Replans transfer event. */
static
void
replan_xfer
(
zone_t
*
zone
,
const
zone_t
*
old_zone
)
{
if
(
!
zone_master
(
zone
))
{
// Only valid for slaves.
return
;
}
if
(
zone_master
(
old_zone
))
{
// Replan the transfer from old zone.
replan_event
(
zone
,
old_zone
,
ZONE_EVENT_XFER
);
}
else
if
(
zone_contents_is_empty
(
zone
->
contents
))
{
// Plan transfer anew.
zone
->
bootstrap_retry
=
bootstrap_next
(
zone
->
bootstrap_retry
);
zone_events_schedule
(
zone
,
ZONE_EVENT_XFER
,
zone
->
bootstrap_retry
);
}
}
/*!< \brief Replans flush event. */
static
void
replan_flush
(
zone_t
*
zone
,
const
zone_t
*
old_zone
)
{
if
(
zone
->
conf
->
dbsync_timeout
<=
0
)
{
// Immediate sync scheduled after events.
return
;
}
const
time_t
flush_time
=
zone_events_get_time
(
old_zone
,
ZONE_EVENT_FLUSH
);
if
(
flush_time
<
ZONE_EVENT_NOW
)
{
// Not scheduled previously.
zone_events_schedule_at
(
zone
,
ZONE_EVENT_FLUSH
,
zone
->
conf
->
dbsync_timeout
);
return
;
}
// Pick time to schedule: either reuse or schedule sooner than old event.
const
time_t
schedule_at
=
MIN
(
time
(
NULL
)
-
zone
->
conf
->
dbsync_timeout
,
flush_time
);
zone_events_schedule_at
(
zone
,
ZONE_EVENT_FLUSH
,
schedule_at
);
}
/*!< \brief Creates new DDNS q in the new zone - q contains references from the old zone. */
static
void
duplicate_ddns_q
(
zone_t
*
zone
,
const
zone_t
*
old_zone
)
{
struct
request_data
*
d
;
WALK_LIST
(
d
,
old_zone
->
ddns_queue
)
{
add_tail
(
&
zone
->
ddns_queue
,
(
node_t
*
)
d
);
}
// Reset the list, new zone will free the data.
init_list
(
&
((
zone_t
*
)
old_zone
)
->
ddns_queue
);
}
/*!< Replans DDNS event. */
static
void
replan_update
(
zone_t
*
zone
,
const
zone_t
*
old_zone
)
{
if
(
!
EMPTY_LIST
(
old_zone
->
ddns_queue
))
{
duplicate_ddns_q
(
zone
,
old_zone
);
// \todo #254 Old zone *must* have the event planned, but it was not always so
zone_events_schedule
(
zone
,
ZONE_EVENT_UPDATE
,
ZONE_EVENT_NOW
);
}
}
/*!< Replans DNSSEC event. Not whole resign needed, \todo #247 */
static
void
replan_dnssec
(
zone_t
*
zone
)
{
if
(
zone
->
conf
->
dnssec_enable
)
{
/* Keys could have changed, force resign. */
zone_events_schedule
(
zone
,
ZONE_EVENT_DNSSEC
,
ZONE_EVENT_NOW
);
}
}
/* -- internal API --------------------------------------------------------- */
static
bool
valid_event
(
zone_event_type_t
type
)
...
...
@@ -792,14 +898,8 @@ void zone_events_schedule_at(zone_t *zone, zone_event_type_t type, time_t time)
zone_events_t
*
events
=
&
zone
->
events
;
pthread_mutex_lock
(
&
events
->
mx
);
time_t
current
=
event_get_time
(
events
,
type
);
if
(
current
==
0
||
time
==
0
||
time
<
current
)
{
event_set_time
(
events
,
type
,
time
);
reschedule
(
events
);
}
event_set_time
(
events
,
type
,
time
);
reschedule
(
events
);
pthread_mutex_unlock
(
&
events
->
mx
);
}
...
...
@@ -922,3 +1022,21 @@ time_t zone_events_get_next(const struct zone_t *zone, zone_event_type_t *type)
return
next_time
;
}
void
zone_events_update
(
zone_t
*
zone
,
const
zone_t
*
old_zone
)
{
replan_soa_events
(
zone
,
old_zone
);
replan_xfer
(
zone
,
old_zone
);
replan_flush
(
zone
,
old_zone
);
replan_event
(
zone
,
old_zone
,
ZONE_EVENT_NOTIFY
);
replan_update
(
zone
,
old_zone
);
replan_dnssec
(
zone
);
}
void
zone_events_replan_ddns
(
struct
zone_t
*
zone
,
const
struct
zone_t
*
old_zone
)
{
if
(
old_zone
)
{
replan_update
(
zone
,
old_zone
);
}
}
src/knot/zone/events.h
View file @
fbcf93ea
...
...
@@ -168,3 +168,19 @@ const char *zone_events_get_name(zone_event_type_t type);
* \return time of the next event or an error (negative number)
*/
time_t
zone_events_get_next
(
const
struct
zone_t
*
zone
,
zone_event_type_t
*
type
);
/*!
* \brief Replans zone events after config change. Will reuse events where applicable.
*
* \param zone Zone with new config.
* \param old_zone Zone with old config.
*/
void
zone_events_update
(
struct
zone_t
*
zone
,
const
struct
zone_t
*
old_zone
);
/*!
* \brief Replans DDNS processing event if DDNS queue is not empty.
*
* \param zone Zone with new config.
* \param old_zone Zone with old config.
*/
void
zone_events_replan_ddns
(
struct
zone_t
*
zone
,
const
struct
zone_t
*
old_zone
);
src/knot/zone/zone.c
View file @
fbcf93ea
...
...
@@ -302,7 +302,7 @@ int zone_update_enqueue(zone_t *zone, knot_pkt_t *pkt, struct process_query_para
pthread_mutex_unlock
(
&
zone
->
ddns_lock
);
/* Schedule UPDATE event.
If already scheduled, older event will stay.
*/
/* Schedule UPDATE event. */
zone_events_schedule
(
zone
,
ZONE_EVENT_UPDATE
,
ZONE_EVENT_NOW
);
return
KNOT_EOK
;
...
...
src/knot/zone/zonedb-load.c
View file @
fbcf93ea
...
...
@@ -103,25 +103,6 @@ static void log_zone_load_info(const zone_t *zone, const char *zone_name,
log_zone_info
(
"Zone '%s' %s (serial %u)
\n
"
,
zone_name
,
action
,
serial
);
}
/*!
* \brief Copy zone events from the old zone.
*/
static
void
update_zone_events
(
zone_t
*
zone
,
const
zone_t
*
old_zone
)
{
for
(
zone_event_type_t
i
=
0
;
i
<
ZONE_EVENT_COUNT
;
++
i
)
{
/* DNSSEC: keys could have changed, force resign. */
if
(
i
==
ZONE_EVENT_DNSSEC
&&
zone
->
conf
->
dnssec_enable
)
{
zone_events_schedule
(
zone
,
i
,
ZONE_EVENT_NOW
);
continue
;
}
time_t
event_time
=
zone_events_get_time
(
old_zone
,
i
);
if
(
event_time
>
ZONE_EVENT_NOW
)
{
zone_events_schedule_at
(
zone
,
i
,
event_time
);
}
}
}
/*!
* \brief Load or reload the zone.
*
...
...
@@ -159,6 +140,8 @@ static zone_t *create_zone(conf_zone_t *conf, server_t *server, zone_t *old_zone
case
ZONE_STATUS_FOUND_UPDATED
:
/* Enqueueing makes the first zone load waitable. */
zone_events_enqueue
(
zone
,
ZONE_EVENT_RELOAD
);
/* Replan DDNS processing if there are pending updates. */
zone_events_replan_ddns
(
zone
,
old_zone
);
break
;
case
ZONE_STATUS_BOOSTRAP
:
zone_events_schedule
(
zone
,
ZONE_EVENT_REFRESH
,
ZONE_EVENT_NOW
);
...
...
@@ -169,7 +152,7 @@ static zone_t *create_zone(conf_zone_t *conf, server_t *server, zone_t *old_zone
assert
(
old_zone
);
zone
->
zonefile_mtime
=
old_zone
->
zonefile_mtime
;
zone
->
zonefile_serial
=
old_zone
->
zonefile_serial
;
update_
zone_events
(
zone
,
old_zone
);
zone_events
_update
(
zone
,
old_zone
);
break
;
default:
assert
(
0
);
...
...
tests-extra/tests/events/soa/test.py
View file @
fbcf93ea
#!/usr/bin/env python3
'''Test
to end all tests
'''
'''Test
for SOA events and planning thereof
'''
from
dnstest.utils
import
*
from
dnstest.test
import
Test
...
...
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