Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Knot DNS
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
24
Issues
24
List
Boards
Labels
Milestones
Merge Requests
6
Merge Requests
6
Packages
Packages
Container Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Knot projects
Knot DNS
Commits
8de33ea6
Commit
8de33ea6
authored
Sep 09, 2011
by
Marek Vavrusa
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Reworked NOTIFY event mechanism to be truly thread-safe, bugfixes, more helpful output to log.
Commit refs #1253.
parent
ed7295aa
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
204 additions
and
121 deletions
+204
-121
libknot/util/debug.h
libknot/util/debug.h
+4
-4
src/knot/main.c
src/knot/main.c
+5
-0
src/knot/other/debug.h
src/knot/other/debug.h
+1
-1
src/knot/server/notify.c
src/knot/server/notify.c
+20
-16
src/knot/server/notify.h
src/knot/server/notify.h
+1
-1
src/knot/server/server.c
src/knot/server/server.c
+3
-0
src/knot/server/udp-handler.c
src/knot/server/udp-handler.c
+0
-5
src/knot/server/xfr-handler.c
src/knot/server/xfr-handler.c
+50
-11
src/knot/server/zones.c
src/knot/server/zones.c
+102
-82
src/knot/server/zones.h
src/knot/server/zones.h
+15
-0
src/tests/common/events_tests.c
src/tests/common/events_tests.c
+3
-1
No files found.
libknot/util/debug.h
View file @
8de33ea6
...
...
@@ -92,15 +92,15 @@ void knot_zone_contents_dump(knot_zone_contents_t *zone, char loaded_zone);
//#define KNOT_RESPONSE_DEBUG
//#define KNOT_ZONEDB_DEBUG
//#define KNOT_DNAME_DEBUG
#define KNOT_NODE_DEBUG
//
#define KNOT_NODE_DEBUG
//#define KNOT_PACKET_DEBUG
//#define KNOT_EDNS_DEBUG
#define KNOT_RRSET_DEBUG
//
#define KNOT_RRSET_DEBUG
//#define KNOT_NSEC3_DEBUG
//#define CUCKOO_DEBUG
//#define CUCKOO_DEBUG_HASH
#define KNOT_NS_DEBUG
#define KNOT_XFR_DEBUG
//
#define KNOT_NS_DEBUG
//
#define KNOT_XFR_DEBUG
//#define KNOT_DDNS_DEBUG
#ifdef KNOT_NS_DEBUG
...
...
src/knot/main.c
View file @
8de33ea6
...
...
@@ -192,6 +192,11 @@ int main(int argc, char **argv)
"PID = %ld
\n
"
,
(
long
)
getpid
());
}
log_server_info
(
"PID stored in %s
\n
"
,
pidfile
);
size_t
zcount
=
server
->
nameserver
->
zone_db
->
zone_count
;
if
(
!
zcount
)
{
log_server_warning
(
"Server started, but no zones served.
\n
"
);
}
// Setup signal handler
struct
sigaction
sa
;
...
...
src/knot/other/debug.h
View file @
8de33ea6
...
...
@@ -21,7 +21,7 @@
//#define KNOTD_JOURNAL_DEBUG
//#define KNOTD_NET_DEBUG
//#define KNOTD_ZONES_DEBUG
#define KNOTD_XFR_DEBUG
//
#define KNOTD_XFR_DEBUG
//#define KNOTD_NOTIFY_DEBUG
//#define KNOTD_ZDUMP_DEBUG
//#define KNOTD_ZLOAD_DEBUG
...
...
src/knot/server/notify.c
View file @
8de33ea6
...
...
@@ -204,7 +204,7 @@ static int notify_check_and_schedule(knot_nameserver_t *nameserver,
/*----------------------------------------------------------------------------*/
int
notify_process_request
(
knot_nameserver_t
*
n
ameserver
,
int
notify_process_request
(
knot_nameserver_t
*
n
s
,
knot_packet_t
*
notify
,
sockaddr_t
*
from
,
uint8_t
*
buffer
,
size_t
*
size
)
...
...
@@ -213,7 +213,7 @@ int notify_process_request(knot_nameserver_t *nameserver,
* - it will be fine to merge the code somehow.
*/
if
(
notify
==
NULL
||
n
ameserver
==
NULL
||
buffer
==
NULL
if
(
notify
==
NULL
||
n
s
==
NULL
||
buffer
==
NULL
||
size
==
NULL
||
from
==
NULL
)
{
debug_notify
(
"notify: invalid parameters for query
\n
"
);
return
KNOTD_EINVAL
;
...
...
@@ -226,7 +226,10 @@ int notify_process_request(knot_nameserver_t *nameserver,
ret
=
knot_packet_parse_rest
(
notify
);
if
(
ret
!=
KNOT_EOK
)
{
debug_notify
(
"notify: failed to parse NOTIFY query
\n
"
);
return
KNOTD_EMALF
;
knot_ns_error_response
(
ns
,
knot_packet_id
(
notify
),
KNOT_RCODE_FORMERR
,
buffer
,
size
);
return
KNOTD_EOK
;
}
}
...
...
@@ -235,20 +238,26 @@ int notify_process_request(knot_nameserver_t *nameserver,
ret
=
notify_create_response
(
notify
,
buffer
,
size
);
if
(
ret
!=
KNOTD_EOK
)
{
debug_notify
(
"notify: failed to create NOTIFY response
\n
"
);
return
KNOTD_ERROR
;
/*! \todo Some other error. */
knot_ns_error_response
(
ns
,
knot_packet_id
(
notify
),
KNOT_RCODE_SERVFAIL
,
buffer
,
size
);
return
KNOTD_EOK
;
}
// find the zone
debug_notify
(
"notify: looking up zone by name
\n
"
);
const
knot_dname_t
*
qname
=
knot_packet_qname
(
notify
);
const
knot_zone_t
*
z
=
knot_zonedb_find_zone_for_name
(
n
ameserver
->
zone_db
,
qname
);
n
s
->
zone_db
,
qname
);
if
(
z
==
NULL
)
{
debug_notify
(
"notify: failed to find zone by name
\n
"
);
return
KNOTD_ERROR
;
/*! \todo Some other error. */
knot_ns_error_response
(
ns
,
knot_packet_id
(
notify
),
KNOT_RCODE_REFUSED
,
buffer
,
size
);
return
KNOTD_EOK
;
}
notify_check_and_schedule
(
n
ameserver
,
z
,
from
);
notify_check_and_schedule
(
n
s
,
z
,
from
);
return
KNOTD_EOK
;
}
...
...
@@ -281,9 +290,9 @@ int notify_process_response(knot_nameserver_t *nameserver,
/* Match ID against awaited. */
zonedata_t
*
zd
=
(
zonedata_t
*
)
knot_zone_data
(
zone
);
pthread_mutex_lock
(
&
zd
->
lock
);
uint16_t
pkt_id
=
knot_packet_id
(
notify
);
notify_ev_t
*
ev
=
0
,
*
match
=
0
;
pthread_mutex_lock
(
&
zd
->
lock
);
WALK_LIST
(
ev
,
zd
->
notify_pending
)
{
if
((
int
)
pkt_id
==
ev
->
msgid
)
{
match
=
ev
;
...
...
@@ -299,14 +308,9 @@ int notify_process_response(knot_nameserver_t *nameserver,
}
/* NOTIFY is now finished. */
evsched_t
*
sched
=
((
server_t
*
)
knot_ns_get_data
(
nameserver
))
->
sched
;
if
(
match
->
timer
)
{
log_zone_info
(
"NOTIFY query for zone %s answered.
\n
"
,
zd
->
conf
->
name
);
evsched_cancel
(
sched
,
(
event_t
*
)
match
->
timer
);
evsched_schedule
(
sched
,
(
event_t
*
)
match
->
timer
,
0
);
match
->
timer
=
0
;
}
zones_cancel_notify
(
zd
,
match
);
/* Zone was removed/reloaded. */
pthread_mutex_unlock
(
&
zd
->
lock
);
log_server_info
(
"Received response for pending NOTIFY query ID=%u
\n
"
,
...
...
src/knot/server/notify.h
View file @
8de33ea6
...
...
@@ -32,7 +32,7 @@ typedef struct notify_ev_t {
int
retries
;
/*!< Number of retries. */
int
msgid
;
/*!< ID of pending NOTIFY. */
sockaddr_t
addr
;
/*!< Slave server address. */
volatile
struct
event_t
*
timer
;
/*!< Event timer. */
struct
event_t
*
timer
;
/*!< Event timer. */
knot_zone_t
*
zone
;
/*!< Associated zone. */
}
notify_ev_t
;
...
...
src/knot/server/server.c
View file @
8de33ea6
...
...
@@ -42,6 +42,7 @@ static int evsched_run(dthread_t *thread)
/* Process termination event. */
if
(
ev
->
type
==
EVSCHED_TERM
)
{
evsched_event_finished
(
s
);
evsched_event_free
(
s
,
ev
);
break
;
}
...
...
@@ -49,7 +50,9 @@ static int evsched_run(dthread_t *thread)
/* Process event. */
if
(
ev
->
type
==
EVSCHED_CB
&&
ev
->
cb
)
{
ev
->
cb
(
ev
);
evsched_event_finished
(
s
);
}
else
{
evsched_event_finished
(
s
);
evsched_event_free
(
s
,
ev
);
}
...
...
src/knot/server/udp-handler.c
View file @
8de33ea6
...
...
@@ -64,12 +64,9 @@ int udp_handle(uint8_t *qbuf, size_t qbuflen, size_t *resp_len,
case
KNOT_RESPONSE_NORMAL
:
res
=
zones_process_response
(
ns
,
addr
,
packet
,
qbuf
,
resp_len
);
// res = knot_ns_process_response();
break
;
case
KNOT_RESPONSE_AXFR
:
case
KNOT_RESPONSE_IXFR
:
/*! \todo SLAVE DISABLED */
break
;
case
KNOT_RESPONSE_NOTIFY
:
res
=
notify_process_response
(
ns
,
packet
,
addr
,
qbuf
,
resp_len
);
...
...
@@ -91,8 +88,6 @@ int udp_handle(uint8_t *qbuf, size_t qbuflen, size_t *resp_len,
case
KNOT_QUERY_NOTIFY
:
res
=
notify_process_request
(
ns
,
packet
,
addr
,
qbuf
,
resp_len
);
*
resp_len
=
0
;
res
=
KNOTD_EOK
;
break
;
case
KNOT_QUERY_UPDATE
:
default:
...
...
src/knot/server/xfr-handler.c
View file @
8de33ea6
...
...
@@ -96,7 +96,6 @@ static inline void qr_response_ev(struct ev_loop *loop, ev_io *w, int revents)
msg
.
msg_namelen
=
qw
->
addr
.
len
;
/* Receive msg. */
debug_xfr
(
"qr_response_ev: reading response
\n
"
);
ssize_t
n
=
recvmsg
(
w
->
fd
,
&
msg
,
0
);
size_t
resp_len
=
sizeof
(
qbuf
);
if
(
n
>
0
)
{
...
...
@@ -109,8 +108,10 @@ static inline void qr_response_ev(struct ev_loop *loop, ev_io *w, int revents)
((
server_t
*
)
knot_ns_get_data
(
qw
->
ns
))
->
sched
;
if
(
qw
->
ev
)
{
evsched_cancel
(
sched
,
qw
->
ev
);
evsched_event_free
(
sched
,
qw
->
ev
);
qw
->
ev
=
0
;
if
(
qw
->
ev
)
{
evsched_event_free
(
sched
,
qw
->
ev
);
qw
->
ev
=
0
;
}
}
/* Close after receiving response. */
...
...
@@ -204,7 +205,7 @@ static inline void xfr_client_ev(struct ev_loop *loop, ev_io *w, int revents)
knotd_strerror
(
ret
));
}
}
debug_xfr
(
"xfr_client_ev: AXFR/IN transfer finished
\n
"
);
log_server_info
(
"AXFR/IN transfer finished.
\n
"
);
break
;
case
XFR_TYPE_IIN
:
/* Save changesets. */
...
...
@@ -228,7 +229,7 @@ static inline void xfr_client_ev(struct ev_loop *loop, ev_io *w, int revents)
free
(
chs
->
sets
);
free
(
chs
);
request
->
data
=
0
;
debug_xfr
(
"xfr_client_ev: IXFR/IN transfer finished
\n
"
);
log_server_info
(
"IXFR/IN transfer finished.
\n
"
);
break
;
default:
ret
=
KNOTD_EINVAL
;
...
...
@@ -314,14 +315,49 @@ static inline void xfr_bridge_ev(struct ev_loop *loop, ev_io *w, int revents)
return
;
}
/* Update address. */
sockaddr_update
(
&
req
->
addr
);
int
r_port
=
-
1
;
#ifdef DISABLE_IPV6
char
r_addr
[
INET_ADDRSTRLEN
];
memset
(
r_addr
,
0
,
sizeof
(
r_addr
));
#else
/* Load IPv6 addr if default. */
char
r_addr
[
INET6_ADDRSTRLEN
];
memset
(
r_addr
,
0
,
sizeof
(
r_addr
));
if
(
req
->
addr
.
family
==
AF_INET6
)
{
r_port
=
ntohs
(
req
->
addr
.
addr6
.
sin6_port
);
inet_ntop
(
req
->
addr
.
family
,
&
req
->
addr
.
addr6
.
sin6_addr
,
r_addr
,
sizeof
(
r_addr
));
}
#endif
/* Load IPv4 if set. */
if
(
req
->
addr
.
family
==
AF_INET
)
{
r_port
=
ntohs
(
req
->
addr
.
addr4
.
sin_port
);
inet_ntop
(
req
->
addr
.
family
,
&
req
->
addr
.
addr4
.
sin_addr
,
r_addr
,
sizeof
(
r_addr
));
}
/* Connect to remote. */
if
(
req
->
session
<=
0
)
{
int
fd
=
socket_create
(
req
->
addr
.
family
,
SOCK_STREAM
);
if
(
fd
<
0
)
{
log_server_warning
(
"Failed to create socket "
"(type=%s, family=%s).
\n
"
,
"SOCK_STREAM"
,
req
->
addr
.
family
==
AF_INET
?
"AF_INET"
:
"AF_INET6"
);
return
;
}
ret
=
connect
(
fd
,
req
->
addr
.
ptr
,
req
->
addr
.
len
);
if
(
ret
<
0
)
{
log_server_warning
(
"Failed to connect to %cXFR master "
"at %s:%d.
\n
"
,
req
->
type
==
XFR_TYPE_AIN
?
'A'
:
'I'
,
r_addr
,
r_port
);
if
(
!
knot_zone_contents
(
zone
))
{
log_zone_notice
(
"Zone AXFR bootstrap failed.
\n
"
);
}
return
;
}
...
...
@@ -337,7 +373,8 @@ static inline void xfr_bridge_ev(struct ev_loop *loop, ev_io *w, int revents)
const
knot_zone_contents_t
*
contents
=
knot_zone_contents
(
zone
);
if
(
!
contents
&&
req
->
type
==
XFR_TYPE_IIN
)
{
rcu_read_unlock
();
debug_xfr
(
"xfr_in: failed start IXFR on zone with no contents
\n
"
);
log_server_warning
(
"Failed start IXFR on zone with no "
"contents
\n
"
);
socket_close
(
req
->
session
);
return
;
}
...
...
@@ -369,11 +406,13 @@ static inline void xfr_bridge_ev(struct ev_loop *loop, ev_io *w, int revents)
}
/* Send XFR query. */
debug_xfr
(
"xfr_in: sending XFR query (%zu bytes)
\n
"
,
bufsize
);
log_server_info
(
"Sending %cXFR query to %s:%d (%zu bytes).
\n
"
,
req
->
type
==
XFR_TYPE_AIN
?
'A'
:
'I'
,
r_addr
,
r_port
,
bufsize
);
ret
=
req
->
send
(
req
->
session
,
&
req
->
addr
,
req
->
wire
,
bufsize
);
if
(
ret
!=
bufsize
)
{
debug_xfr
(
"xfr_in: failed to send XFR query type %d
\n
"
,
req
->
type
);
log_server_notice
(
"Failed to send %cXFR query.
"
,
req
->
type
==
XFR_TYPE_AIN
?
'A'
:
'I'
);
socket_close
(
req
->
session
);
return
;
}
...
...
@@ -569,14 +608,14 @@ int xfr_master(dthread_t *thread)
char
r_addr
[
INET6_ADDRSTRLEN
];
memset
(
r_addr
,
0
,
sizeof
(
r_addr
));
if
(
xfr
.
addr
.
family
==
AF_INET6
)
{
r_port
=
xfr
.
addr
.
addr6
.
sin6_port
;
r_port
=
ntohs
(
xfr
.
addr
.
addr6
.
sin6_port
)
;
inet_ntop
(
xfr
.
addr
.
family
,
&
xfr
.
addr
.
addr6
.
sin6_addr
,
r_addr
,
sizeof
(
r_addr
));
}
#endif
/* Load IPv4 if set. */
if
(
xfr
.
addr
.
family
==
AF_INET
)
{
r_port
=
xfr
.
addr
.
addr4
.
sin_port
;
r_port
=
ntohs
(
xfr
.
addr
.
addr4
.
sin_port
)
;
inet_ntop
(
xfr
.
addr
.
family
,
&
xfr
.
addr
.
addr4
.
sin_addr
,
r_addr
,
sizeof
(
r_addr
));
}
...
...
src/knot/server/zones.c
View file @
8de33ea6
...
...
@@ -64,18 +64,9 @@ static int zonedata_destroy(knot_zone_t *zone)
/* Remove list of pending NOTIFYs. */
pthread_mutex_lock
(
&
zd
->
lock
);
node
*
n
=
0
;
WALK_LIST
(
n
,
zd
->
notify_pending
)
{
notify_ev_t
*
ev
=
(
notify_ev_t
*
)
n
;
if
(
ev
->
timer
)
{
ev
->
zone
=
0
;
evsched_t
*
sch
=
ev
->
timer
->
parent
;
evsched_cancel
(
sch
,
(
event_t
*
)
ev
->
timer
);
evsched_event_free
(
sch
,
(
event_t
*
)
ev
->
timer
);
rem_node
(
&
ev
->
n
);
ev
->
timer
=
0
;
free
(
ev
);
}
notify_ev_t
*
ev
=
0
,
*
evn
=
0
;
WALK_LIST_DELSAFE
(
ev
,
evn
,
zd
->
notify_pending
)
{
zones_cancel_notify
(
zd
,
ev
);
}
pthread_mutex_unlock
(
&
zd
->
lock
);
...
...
@@ -255,8 +246,10 @@ static int zones_expire_ev(event_t *e)
zonedata_t
*
zd
=
(
zonedata_t
*
)
zone
->
data
;
if
(
zd
->
xfr_in
.
timer
)
{
evsched_cancel
(
e
->
parent
,
zd
->
xfr_in
.
timer
);
evsched_event_free
(
e
->
parent
,
zd
->
xfr_in
.
timer
);
zd
->
xfr_in
.
timer
=
0
;
if
(
zd
->
xfr_in
.
timer
)
{
evsched_event_free
(
e
->
parent
,
zd
->
xfr_in
.
timer
);
zd
->
xfr_in
.
timer
=
0
;
}
}
/* Delete self. */
...
...
@@ -311,9 +304,6 @@ static int zones_refresh_ev(event_t *e)
if
(
!
knot_zone_contents
(
zone
))
{
/* Bootstrap from XFR master. */
evsched_cancel
(
e
->
parent
,
e
);
/* Prepare XFR client transfer. */
knot_ns_xfr_t
xfr_req
;
memset
(
&
xfr_req
,
0
,
sizeof
(
knot_ns_xfr_t
));
memcpy
(
&
xfr_req
.
addr
,
&
zd
->
xfr_in
.
master
,
sizeof
(
sockaddr_t
));
...
...
@@ -327,7 +317,8 @@ static int zones_refresh_ev(event_t *e)
rcu_read_unlock
();
/* Enqueue XFR request. */
debug_zones
(
"xfr_in: attempting to bootstrap zone from master
\n
"
);
log_zone_info
(
"Attempting to bootstrap zone %s from master
\n
"
,
zd
->
conf
->
name
);
return
xfr_request
(
zd
->
server
->
xfr_h
,
&
xfr_req
);
}
...
...
@@ -393,30 +384,36 @@ static int zones_notify_send(event_t *e)
{
notify_ev_t
*
ev
=
(
notify_ev_t
*
)
e
->
data
;
knot_zone_t
*
zone
=
ev
->
zone
;
knot_zone_contents_t
*
contents
=
knot_zone_get_contents
(
zone
);
if
(
!
zone
||
!
knot_zone_data
(
zone
)
||
!
contents
)
{
if
(
!
zone
)
{
log_zone_error
(
"notify: NOTIFY invalid event received
\n
"
);
evsched_event_free
(
e
->
parent
,
(
event_t
*
)
ev
->
timer
);
evsched_event_free
(
e
->
parent
,
e
);
free
(
ev
);
return
KNOTD_EINVAL
;
}
/* Check for answered/cancelled query. */
zonedata_t
*
zd
=
(
zonedata_t
*
)
knot_zone_data
(
zone
);
pthread_mutex_lock
(
&
zd
->
lock
);
if
(
ev
->
timer
==
NULL
)
{
debug_zones
(
"notify: cancelling old NOTIFY timer for %s.
\n
"
,
zd
->
conf
->
name
);
evsched_cancel
(
e
->
parent
,
e
);
evsched_event_free
(
e
->
parent
,
e
);
knot_zone_contents_t
*
contents
=
knot_zone_get_contents
(
zone
);
debug_notify
(
"notify: NOTIFY timer event
\n
"
);
/* Reduce number of available retries. */
--
ev
->
retries
;
/* Check number of retries. */
if
(
ev
->
retries
<
0
)
{
log_server_notice
(
"NOTIFY query maximum number of retries "
"for zone %s exceeded.
\n
"
,
zd
->
conf
->
name
);
pthread_mutex_lock
(
&
zd
->
lock
);
debug_notify
(
"notify: Deleting NOTIFY event because "
"maximum number of retries was reached.
\n
"
);
rem_node
(
&
ev
->
n
);
pthread_mutex_unlock
(
&
zd
->
lock
);
evsched_event_free
(
e
->
parent
,
e
);
free
(
ev
);
return
KNOTD_EOK
;
pthread_mutex_unlock
(
&
zd
->
lock
);
return
KNOTD_EMALF
;
}
pthread_mutex_unlock
(
&
zd
->
lock
);
debug_zones
(
"notify: NOTIFY timer event
\n
"
);
/* Prepare buffer for query. */
uint8_t
qbuf
[
SOCKET_MTU_SZ
];
...
...
@@ -456,32 +453,14 @@ static int zones_notify_send(event_t *e)
}
/* Reduce number of available retries. */
--
ev
->
retries
;
/* Check number of retries. */
if
(
ev
->
retries
<=
0
)
{
log_server_notice
(
"NOTIFY query maximum number of retries "
"for zone %s exceeded.
\n
"
,
zd
->
conf
->
name
);
pthread_mutex_lock
(
&
zd
->
lock
);
if
(
ev
->
timer
)
{
evsched_cancel
(
e
->
parent
,
e
);
evsched_schedule
(
e
->
parent
,
e
,
0
);
ev
->
timer
=
0
;
}
pthread_mutex_unlock
(
&
zd
->
lock
);
return
KNOTD_EMALF
;
}
/* RFC suggests 60s, but it is configurable. */
int
retry_tmr
=
ev
->
timeout
*
1000
;
/* Reschedule. */
evsched_schedule
(
e
->
parent
,
e
,
retry_tmr
);
debug_
zones
(
"notify: RETRY after %u secs
\n
"
,
retry_tmr
/
1000
);
debug_
notify
(
"notify: RETRY after %u secs
\n
"
,
retry_tmr
/
1000
);
return
ret
;
}
...
...
@@ -1039,8 +1018,7 @@ static int zones_insert_zones(knot_nameserver_t *ns,
int
ret
=
KNOT_ERROR
;
if
(
reload
)
{
/* Zone file not exists and has master set. */
/*! \todo SLAVE DISABLED Bootstrapping is disabled. */
if
(
0
&&
stat_ret
<
0
&&
!
EMPTY_LIST
(
z
->
acl
.
xfr_in
))
{
if
(
stat_ret
<
0
&&
!
EMPTY_LIST
(
z
->
acl
.
xfr_in
))
{
/* Create stub database. */
debug_zones
(
"Loading stub zone for bootstrap.
\n
"
);
...
...
@@ -1998,27 +1976,39 @@ int zones_timers_update(knot_zone_t *zone, conf_zone_t *cfzone, evsched_t *sch)
/* Remove list of pending NOTIFYs. */
pthread_mutex_lock
(
&
zd
->
lock
);
node
*
n
=
0
;
WALK_LIST
(
n
,
zd
->
notify_pending
)
{
notify_ev_t
*
ev
=
(
notify_ev_t
*
)
n
;
if
(
ev
->
timer
)
{
evsched_cancel
(
sch
,
(
event_t
*
)
ev
->
timer
);
evsched_schedule
(
sch
,
(
event_t
*
)
ev
->
timer
,
0
);
ev
->
timer
=
0
;
}
notify_ev_t
*
ev
=
0
,
*
evn
=
0
;
WALK_LIST_DELSAFE
(
ev
,
evn
,
zd
->
notify_pending
)
{
zones_cancel_notify
(
zd
,
ev
);
}
pthread_mutex_unlock
(
&
zd
->
lock
);
/* Check XFR/IN master server. */
/*! \todo SLAVE DISABLED */
// if (zd->xfr_in.master.ptr) {
if
(
zd
->
xfr_in
.
master
.
ptr
)
{
// /* Schedule REFRESH timer. */
// uint32_t refresh_tmr = zones_soa_refresh(zone);
// zd->xfr_in.timer = evsched_schedule_cb(sch, zones_refresh_ev,
// zone, refresh_tmr);
// debug_zones("notify: REFRESH set to %u\n", refresh_tmr);
// }
/* Schedule REFRESH timer. */
uint32_t
refresh_tmr
=
zones_soa_refresh
(
zone
);
zd
->
xfr_in
.
timer
=
evsched_schedule_cb
(
sch
,
zones_refresh_ev
,
zone
,
refresh_tmr
);
debug_zones
(
"notify: REFRESH set to %u
\n
"
,
refresh_tmr
);
}
/* Schedule IXFR database syncing. */
/*! \todo Sync timer should not be reset after each xfr. */
int
sync_timeout
=
cfzone
->
dbsync_timeout
*
1000
;
/* Convert to ms. */
if
(
zd
->
ixfr_dbsync
)
{
evsched_cancel
(
sch
,
zd
->
ixfr_dbsync
);
evsched_event_free
(
sch
,
zd
->
ixfr_dbsync
);
zd
->
ixfr_dbsync
=
0
;
}
zd
->
ixfr_dbsync
=
evsched_schedule_cb
(
sch
,
zones_zonefile_sync_ev
,
zone
,
sync_timeout
);
/* Do not issue NOTIFY queries if stub. */
if
(
!
knot_zone_contents
(
zone
))
{
conf_read_unlock
();
return
KNOTD_EOK
;
}
/* Schedule NOTIFY to slaves. */
conf_remote_t
*
r
=
0
;
...
...
@@ -2050,7 +2040,7 @@ int zones_timers_update(knot_zone_t *zone, conf_zone_t *cfzone, evsched_t *sch)
/* Prepare request. */
ev
->
retries
=
cfzone
->
notify_retries
+
1
;
/* first + N retries*/
ev
->
msgid
=
-
1
;
ev
->
msgid
=
0
;
ev
->
zone
=
zone
;
ev
->
timeout
=
cfzone
->
notify_timeout
;
...
...
@@ -2066,19 +2056,49 @@ int zones_timers_update(knot_zone_t *zone, conf_zone_t *cfzone, evsched_t *sch)
tmr_s
,
cfg_if
->
address
,
cfg_if
->
port
);
}
/* Schedule IXFR database syncing. */
/*! \todo Sync timer should not be reset after each xfr. */
int
sync_timeout
=
cfzone
->
dbsync_timeout
*
1000
;
/* Convert to ms. */
if
(
zd
->
ixfr_dbsync
)
{
evsched_cancel
(
sch
,
zd
->
ixfr_dbsync
);
evsched_event_free
(
sch
,
zd
->
ixfr_dbsync
);
zd
->
ixfr_dbsync
=
0
;
conf_read_unlock
();
return
KNOTD_EOK
;
}
int
zones_cancel_notify
(
zonedata_t
*
zd
,
notify_ev_t
*
ev
)
{
if
(
!
zd
||
!
ev
||
!
ev
->
timer
)
{
return
KNOTD_EINVAL
;
}
zd
->
ixfr_dbsync
=
evsched_schedule_cb
(
sch
,
zones_zonefile_sync_ev
,
zone
,
sync_timeout
);
conf_read_unlock
();
/* Wait for event to finish running. */
int
pkt_id
=
ev
->
msgid
;
/*< Do not optimize! */
event_t
*
tmr
=
ev
->
timer
;
ev
->
timer
=
0
;
pthread_mutex_unlock
(
&
zd
->
lock
);
evsched_cancel
(
tmr
->
parent
,
tmr
);
/* Re-lock and find again (if not deleted). */
pthread_mutex_lock
(
&
zd
->
lock
);
int
match_exists
=
0
;
notify_ev_t
*
tmpev
=
0
;
WALK_LIST
(
tmpev
,
zd
->
notify_pending
)
{
if
(
tmpev
==
ev
)
{
match_exists
=
1
;
break
;
}
}
/* Event deleted before cancelled. */
if
(
!
match_exists
)
{
debug_notify
(
"notify: NOTIFY event for query ID=%u was"
" deleted before cancellation.
\n
"
,
pkt_id
);
return
KNOTD_EOK
;
}
/* Free event (won't be scheduled again). */
debug_notify
(
"notify: NOTIFY query ID=%u event cancelled.
\n
"
,
pkt_id
);
rem_node
(
&
ev
->
n
);
evsched_event_free
(
tmr
->
parent
,
tmr
);
free
(
ev
);
return
KNOTD_EOK
;
}
src/knot/server/zones.h
View file @
8de33ea6
...
...
@@ -18,6 +18,7 @@
#include "libknot/nameserver/name-server.h"
#include "libknot/zone/zonedb.h"
#include "knot/conf/conf.h"
#include "knot/server/notify.h"
#include "knot/server/server.h"
#include "knot/server/journal.h"
#include "libknot/zone/zone.h"
...
...
@@ -231,6 +232,20 @@ int zones_apply_changesets(knot_ns_xfr_t *xfr);
*/
int
zones_timers_update
(
knot_zone_t
*
zone
,
conf_zone_t
*
cfzone
,
evsched_t
*
sch
);
/*!
* \brief Cancel pending NOTIFY timer.
*
* \warning Expects locked zonedata lock.
*
* \param zd Zone data.
* \param ev NOTIFY event.
*
* \retval KNOTD_EOK
* \retval KNOTD_ERROR
* \retval KNOTD_EINVAL
*/
int
zones_cancel_notify
(
zonedata_t
*
zd
,
notify_ev_t
*
ev
);
#endif // _KNOTD_ZONES_H_
/*! @} */
src/tests/common/events_tests.c
View file @
8de33ea6
...
...
@@ -116,6 +116,7 @@ static int events_tests_run(int argc, char *argv[])
// 3. Wait for next event
e
=
evsched_next
(
s
);
evsched_event_finished
(
s
);
gettimeofday
(
&
rt
,
0
);
ok
(
e
!=
0
,
"evsched: received valid event"
);
...
...
@@ -135,7 +136,7 @@ static int events_tests_run(int argc, char *argv[])
lives_ok
({
evsched_event_free
(
s
,
e
);},
"evsched: deleted event"
);
// 7. Insert and immediately cancel an event
e
=
evsched_schedule_cb
(
s
,
0
,
(
void
*
)
0xdead
,
10
);
e
=
evsched_schedule_cb
(
s
,
0
,
(
void
*
)
0xdead
,
10
00
);
ret
=
evsched_cancel
(
s
,
e
);
ok
(
ret
==
0
,
"evsched: inserted and cancelled an event"
);
if
(
e
)
{
...
...
@@ -146,6 +147,7 @@ static int events_tests_run(int argc, char *argv[])
pthread_t
t
;
pthread_create
(
&
t
,
0
,
term_thr
,
s
);
e
=
evsched_next
(
s
);
evsched_event_finished
(
s
);
ok
(
e
!=
0
,
"evsched: received termination event"
);
// 9. Termination event is valid
...
...
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