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
aa779124
Commit
aa779124
authored
Jun 19, 2013
by
Marek Vavrusa
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fixed a problem with too many differences (>1k) in one IXFR.
parent
94a96f86
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
71 additions
and
84 deletions
+71
-84
src/knot/server/journal.c
src/knot/server/journal.c
+1
-1
src/knot/server/xfr-handler.c
src/knot/server/xfr-handler.c
+44
-22
src/knot/server/zones.c
src/knot/server/zones.c
+17
-58
src/libknot/nameserver/name-server.c
src/libknot/nameserver/name-server.c
+0
-1
src/libknot/updates/xfr-in.c
src/libknot/updates/xfr-in.c
+9
-2
No files found.
src/knot/server/journal.c
View file @
aa779124
...
...
@@ -189,7 +189,7 @@ int journal_write_in(journal_t *j, journal_node_t **rn, uint64_t id, size_t len)
/* Check if it has been synced to disk. */
if
(
head
->
flags
&
JOURNAL_DIRTY
)
{
return
KNOT_E
AGAIN
;
return
KNOT_E
BUSY
;
}
/* Write back evicted node. */
...
...
src/knot/server/xfr-handler.c
View file @
aa779124
...
...
@@ -296,6 +296,7 @@ static void xfr_task_cleanup(knot_ns_xfr_t *rq)
/* Cleanup other data - so that the structure may be reused. */
rq
->
packet_nr
=
0
;
rq
->
tsig_data_size
=
0
;
hattrie_clear
(
rq
->
lookup_tree
);
}
/*! \brief Close and free task. */
...
...
@@ -642,6 +643,28 @@ static int xfr_task_resp(xfrworker_t *w, knot_ns_xfr_t *rq)
return
ret
;
}
static
int
xfr_fallback_axfr
(
knot_ns_xfr_t
*
rq
)
{
log_server_notice
(
"%s Retrying with AXFR.
\n
"
,
rq
->
msg
);
rq
->
wire_size
=
rq
->
wire_maxlen
;
/* Reset maximum bufsize */
int
ret
=
xfrin_create_axfr_query
(
rq
->
zone
->
name
,
rq
,
&
rq
->
wire_size
,
1
);
/* Send AXFR/IN query. */
if
(
ret
==
KNOT_EOK
)
{
ret
=
rq
->
send
(
rq
->
session
,
&
rq
->
addr
,
rq
->
wire
,
rq
->
wire_size
);
/* Switch to AXFR and return. */
if
(
ret
==
rq
->
wire_size
)
{
xfr_task_cleanup
(
rq
);
rq
->
type
=
XFR_TYPE_AIN
;
rq
->
msg
[
XFR_MSG_DLTTR
]
=
'A'
;
ret
=
KNOT_EOK
;
}
else
{
ret
=
KNOT_ERROR
;
}
}
return
ret
;
}
static
int
xfr_task_xfer
(
xfrworker_t
*
w
,
knot_ns_xfr_t
*
rq
)
{
...
...
@@ -675,25 +698,16 @@ static int xfr_task_xfer(xfrworker_t *w, knot_ns_xfr_t *rq)
dbg_xfr_verb
(
"xfr: processed XFR pkt (%s)
\n
"
,
knot_strerror
(
ret
));
/* IXFR refused, try again with AXFR. */
if
(
rq
->
type
==
XFR_TYPE_IIN
&&
ret
==
KNOT_EXFRREFUSED
)
{
log_server_notice
(
"%s Transfer failed, fallback to AXFR.
\n
"
,
rq
->
msg
);
rq
->
wire_size
=
rq
->
wire_maxlen
;
/* Reset maximum bufsize */
ret
=
xfrin_create_axfr_query
(
rq
->
zone
->
name
,
rq
,
&
rq
->
wire_size
,
1
);
/* Send AXFR/IN query. */
if
(
ret
==
KNOT_EOK
)
{
ret
=
rq
->
send
(
rq
->
session
,
&
rq
->
addr
,
rq
->
wire
,
rq
->
wire_size
);
/* Switch to AXFR and return. */
if
(
ret
==
rq
->
wire_size
)
{
xfr_task_cleanup
(
rq
);
rq
->
type
=
XFR_TYPE_AIN
;
rq
->
msg
[
XFR_MSG_DLTTR
]
=
'A'
;
return
KNOT_EOK
;
}
else
{
ret
=
KNOT_ERROR
;
}
if
(
rq
->
type
==
XFR_TYPE_IIN
)
{
switch
(
ret
)
{
case
KNOT_ESPACE
:
/* Fallthrough */
log_server_notice
(
"%s Exceeded journal size limit.
\n
"
,
rq
->
msg
);
case
KNOT_EXFRREFUSED
:
return
xfr_fallback_axfr
(
rq
);
default:
break
;
}
return
ret
;
/* Something failed in fallback. */
}
/* Handle errors. */
...
...
@@ -706,19 +720,26 @@ static int xfr_task_xfer(xfrworker_t *w, knot_ns_xfr_t *rq)
/* Only for successful xfers. */
if
(
ret
>
0
)
{
ret
=
xfr_task_finalize
(
w
,
rq
);
/* AXFR bootstrap timeout. */
if
(
ret
!=
KNOT_EOK
&&
!
knot_zone_contents
(
rq
->
zone
))
{
/* AXFR bootstrap timeout. */
zonedata_t
*
zd
=
(
zonedata_t
*
)
knot_zone_data
(
rq
->
zone
);
int
tmr_s
=
AXFR_BOOTSTRAP_RETRY
*
tls_rand
();
zd
->
xfr_in
.
bootstrap_retry
=
tmr_s
;
log_zone_info
(
"%s Next attempt to bootstrap "
"in %d seconds.
\n
"
,
rq
->
msg
,
tmr_s
/
1000
);
}
else
if
(
ret
==
KNOT_EBUSY
&&
rq
->
type
==
XFR_TYPE_IIN
)
{
/* Attempt to retry with AXFR. */
ret
=
xfr_fallback_axfr
(
rq
);
if
(
ret
==
KNOT_EOK
)
return
ret
;
}
else
{
zones_schedule_notify
(
rq
->
zone
);
/* NOTIFY */
}
/* Passed, schedule NOTIFYs. */
zones_schedule_notify
(
rq
->
zone
);
}
/* Update REFRESH/RETRY */
zones_schedule_refresh
(
rq
->
zone
);
...
...
@@ -1264,6 +1285,7 @@ int xfr_task_free(knot_ns_xfr_t *rq)
/* Free DNAME trie. */
hattrie_free
(
rq
->
lookup_tree
);
rq
->
lookup_tree
=
NULL
;
/* Free TSIG buffers. */
free
(
rq
->
digest
);
...
...
src/knot/server/zones.c
View file @
aa779124
...
...
@@ -2836,48 +2836,6 @@ static int zones_store_changeset(const knot_changeset_t *chs, journal_t *j,
/* Reserve space for the journal entry. */
char
*
journal_entry
=
NULL
;
ret
=
journal_map
(
j
,
k
,
&
journal_entry
,
entry_size
);
/* Sync to zonefile may be needed. */
while
(
ret
==
KNOT_EAGAIN
)
{
/* Cancel sync timer. */
event_t
*
tmr
=
zd
->
ixfr_dbsync
;
if
(
tmr
)
{
dbg_xfr_verb
(
"xfr: cancelling zonefile "
"SYNC timer of '%s'
\n
"
,
zd
->
conf
->
name
);
evsched_cancel
(
tmr
->
parent
,
tmr
);
}
/* Synchronize. */
dbg_xfr_verb
(
"xfr: forcing zonefile SYNC "
"of '%s'
\n
"
,
zd
->
conf
->
name
);
ret
=
zones_zonefile_sync
(
zone
,
j
);
if
(
ret
!=
KNOT_EOK
&&
ret
!=
KNOT_ERANGE
)
{
continue
;
}
/* Reschedule sync timer. */
if
(
tmr
)
{
/* Fetch sync timeout. */
rcu_read_lock
();
int
timeout
=
zd
->
conf
->
dbsync_timeout
;
timeout
*=
1000
;
/* Convert to ms. */
rcu_read_unlock
();
/* Reschedule. */
dbg_xfr_verb
(
"xfr: resuming SYNC "
"of '%s'
\n
"
,
zd
->
conf
->
name
);
evsched_schedule
(
tmr
->
parent
,
tmr
,
timeout
);
}
/* Attempt to map again. */
ret
=
journal_map
(
j
,
k
,
&
journal_entry
,
entry_size
);
}
if
(
ret
!=
KNOT_EOK
)
{
dbg_xfr
(
"Failed to map space for journal entry: %s.
\n
"
,
knot_strerror
(
ret
));
...
...
@@ -2960,8 +2918,7 @@ int zones_store_changesets(knot_zone_t *zone, knot_changesets_t *src)
return
KNOT_EINVAL
;
}
// knot_zone_t *zone = xfr->zone;
// knot_changesets_t *src = (knot_changesets_t *)xfr->data;
int
ret
=
KNOT_EOK
;
/* Fetch zone-specific data. */
zonedata_t
*
zd
=
(
zonedata_t
*
)
zone
->
data
;
...
...
@@ -2974,7 +2931,6 @@ int zones_store_changesets(knot_zone_t *zone, knot_changesets_t *src)
if
(
j
==
NULL
)
{
return
KNOT_EBUSY
;
}
int
ret
=
0
;
/* Begin writing to journal. */
for
(
unsigned
i
=
0
;
i
<
src
->
count
;
++
i
)
{
...
...
@@ -2982,17 +2938,24 @@ int zones_store_changesets(knot_zone_t *zone, knot_changesets_t *src)
knot_changeset_t
*
chs
=
src
->
sets
+
i
;
ret
=
zones_store_changeset
(
chs
,
j
,
zone
,
zd
);
if
(
ret
!=
KNOT_EOK
)
{
journal_release
(
j
);
return
ret
;
}
if
(
ret
!=
KNOT_EOK
)
break
;
}
/* Release journal. */
journal_release
(
j
);
/* Flush if the journal is full. */
event_t
*
tmr
=
zd
->
ixfr_dbsync
;
if
(
ret
==
KNOT_EBUSY
&&
tmr
)
{
log_server_notice
(
"Journal for '%s' is full, flushing.
\n
"
,
zd
->
conf
->
name
);
evsched_cancel
(
tmr
->
parent
,
tmr
);
evsched_schedule
(
tmr
->
parent
,
tmr
,
0
);
}
/* Written changesets to journal. */
return
KNOT_EOK
;
return
ret
;
}
/*----------------------------------------------------------------------------*/
...
...
@@ -3125,8 +3088,7 @@ int zones_store_and_apply_chgsets(knot_changesets_t *chs,
}
if
(
ret
!=
KNOT_EOK
)
{
log_zone_error
(
"%s Failed to serialize and store "
"changesets - %s
\n
"
,
msgpref
,
knot_strerror
(
ret
));
"changesets.
\n
"
,
msgpref
);
/* Free changesets, but not the data. */
zones_store_changesets_rollback
(
transaction
);
knot_free_changesets
(
&
chs
);
...
...
@@ -3137,8 +3099,7 @@ int zones_store_and_apply_chgsets(knot_changesets_t *chs,
apply_ret
=
xfrin_apply_changesets
(
zone
,
chs
,
new_contents
);
if
(
apply_ret
!=
KNOT_EOK
)
{
log_zone_error
(
"%s Failed to apply changesets - %s
\n
"
,
msgpref
,
knot_strerror
(
apply_ret
));
log_zone_error
(
"%s Failed to apply changesets.
\n
"
,
msgpref
);
/* Free changesets, but not the data. */
zones_store_changesets_rollback
(
transaction
);
...
...
@@ -3150,8 +3111,7 @@ int zones_store_and_apply_chgsets(knot_changesets_t *chs,
ret
=
zones_store_changesets_commit
(
transaction
);
if
(
ret
!=
KNOT_EOK
)
{
/*! \todo THIS WILL LEAK!! xfrin_rollback_update() needed. */
log_zone_error
(
"%s Failed to commit stored changesets "
"- %s
\n
"
,
msgpref
,
knot_strerror
(
apply_ret
));
log_zone_error
(
"%s Failed to commit stored changesets.
\n
"
,
msgpref
);
knot_free_changesets
(
&
chs
);
return
ret
;
}
...
...
@@ -3160,8 +3120,7 @@ int zones_store_and_apply_chgsets(knot_changesets_t *chs,
switch_ret
=
xfrin_switch_zone
(
zone
,
*
new_contents
,
type
);
if
(
switch_ret
!=
KNOT_EOK
)
{
log_zone_error
(
"%s Failed to replace current zone - %s
\n
"
,
msgpref
,
knot_strerror
(
switch_ret
));
log_zone_error
(
"%s Failed to replace current zone.
\n
"
,
msgpref
);
// Cleanup old and new contents
xfrin_rollback_update
(
zone
->
contents
,
new_contents
,
&
chs
->
changes
);
...
...
src/libknot/nameserver/name-server.c
View file @
aa779124
...
...
@@ -4176,7 +4176,6 @@ int knot_ns_process_ixfrin(knot_nameserver_t *nameserver,
if
(
ret
<
0
)
{
knot_packet_free
(
&
xfr
->
query
);
hattrie_clear
(
xfr
->
lookup_tree
);
return
ret
;
}
else
if
(
ret
>
0
)
{
dbg_ns
(
"ns_process_ixfrin: IXFR finished
\n
"
);
...
...
src/libknot/updates/xfr-in.c
View file @
aa779124
...
...
@@ -18,6 +18,8 @@
#include <assert.h>
#include <urcu.h>
#include "knot/server/journal.h"
#include "updates/xfr-in.h"
#include "nameserver/name-server.h"
...
...
@@ -1159,8 +1161,13 @@ dbg_xfrin_exec_verb(
}
else
{
// normal SOA, start new changeset
(
*
chs
)
->
count
++
;
if
((
ret
=
knot_changesets_check_size
(
*
chs
))
!=
KNOT_EOK
)
{
ret
=
knot_changesets_check_size
(
*
chs
);
/* Check changesets for maximum count (so they fit into journal). */
if
((
*
chs
)
->
count
>
JOURNAL_NCOUNT
)
ret
=
KNOT_ESPACE
;
if
(
ret
!=
KNOT_EOK
)
{
(
*
chs
)
->
count
--
;
knot_rrset_deep_free
(
&
rr
,
1
,
1
);
goto
cleanup
;
...
...
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