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
fc71c1f0
Commit
fc71c1f0
authored
Dec 14, 2016
by
Daniel Salzman
1
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
module: make a mod-rrl module from query_processing rrl code
parent
283f68ca
Changes
31
Hide whitespace changes
Inline
Side-by-side
Showing
31 changed files
with
972 additions
and
393 deletions
+972
-393
Knot.files
Knot.files
+7
-3
doc/configuration.rst
doc/configuration.rst
+0
-25
doc/man/knot.conf.5in
doc/man/knot.conf.5in
+84
-67
doc/modules.rst
doc/modules.rst
+31
-2
doc/reference.rst
doc/reference.rst
+100
-81
src/Makefile.am
src/Makefile.am
+6
-2
src/knot/conf/base.c
src/knot/conf/base.c
+0
-5
src/knot/conf/base.h
src/knot/conf/base.h
+0
-2
src/knot/conf/migration.c
src/knot/conf/migration.c
+133
-0
src/knot/conf/migration.h
src/knot/conf/migration.h
+30
-0
src/knot/conf/scheme.c
src/knot/conf/scheme.c
+8
-5
src/knot/conf/tools.c
src/knot/conf/tools.c
+36
-2
src/knot/conf/tools.h
src/knot/conf/tools.h
+4
-0
src/knot/modules/rrl/functions.c
src/knot/modules/rrl/functions.c
+25
-31
src/knot/modules/rrl/functions.h
src/knot/modules/rrl/functions.h
+20
-32
src/knot/modules/rrl/rrl.c
src/knot/modules/rrl/rrl.c
+173
-0
src/knot/modules/rrl/rrl.h
src/knot/modules/rrl/rrl.h
+29
-0
src/knot/nameserver/process_query.c
src/knot/nameserver/process_query.c
+0
-51
src/knot/nameserver/process_query.h
src/knot/nameserver/process_query.h
+1
-2
src/knot/nameserver/query_module.c
src/knot/nameserver/query_module.c
+2
-0
src/knot/server/server.c
src/knot/server/server.c
+8
-43
src/knot/server/server.h
src/knot/server/server.h
+1
-5
src/knot/server/udp-handler.c
src/knot/server/udp-handler.c
+9
-13
src/utils/knotd/main.c
src/utils/knotd/main.c
+7
-0
tests-extra/tests/modules/rrl/test.py
tests-extra/tests/modules/rrl/test.py
+203
-0
tests-extra/tools/dnstest/module.py
tests-extra/tools/dnstest/module.py
+30
-0
tests-extra/tools/dnstest/server.py
tests-extra/tools/dnstest/server.py
+11
-0
tests/.gitignore
tests/.gitignore
+1
-1
tests/Makefile.am
tests/Makefile.am
+1
-1
tests/confio.c
tests/confio.c
+5
-7
tests/modules/rrl.c
tests/modules/rrl.c
+7
-13
No files found.
Knot.files
View file @
fc71c1f0
...
...
@@ -218,6 +218,8 @@ src/knot/conf/confdb.c
src/knot/conf/confdb.h
src/knot/conf/confio.c
src/knot/conf/confio.h
src/knot/conf/migration.c
src/knot/conf/migration.h
src/knot/conf/scheme.c
src/knot/conf/scheme.h
src/knot/conf/tools.c
...
...
@@ -269,6 +271,10 @@ src/knot/modules/online_sign/online_sign.h
src/knot/modules/rosedb/rosedb.c
src/knot/modules/rosedb/rosedb.h
src/knot/modules/rosedb/rosedb_tool.c
src/knot/modules/rrl/functions.c
src/knot/modules/rrl/functions.h
src/knot/modules/rrl/rrl.c
src/knot/modules/rrl/rrl.h
src/knot/modules/stats/stats.c
src/knot/modules/stats/stats.h
src/knot/modules/synth_record/synth_record.c
...
...
@@ -308,8 +314,6 @@ src/knot/server/dthreads.c
src/knot/server/dthreads.h
src/knot/server/journal.c
src/knot/server/journal.h
src/knot/server/rrl.c
src/knot/server/rrl.h
src/knot/server/serialization.c
src/knot/server/serialization.h
src/knot/server/server.c
...
...
@@ -579,12 +583,12 @@ tests/libknot/test_yparser.c
tests/libknot/test_ypscheme.c
tests/libknot/test_yptrafo.c
tests/modules/online_sign.c
tests/modules/rrl.c
tests/node.c
tests/process_answer.c
tests/process_query.c
tests/query_module.c
tests/requestor.c
tests/rrl.c
tests/server.c
tests/test_conf.h
tests/utils/test_cert.c
...
...
doc/configuration.rst
View file @
fc71c1f0
...
...
@@ -247,31 +247,6 @@ processed::
file: example.com.zone
acl: update_acl
Response rate limiting
======================
Response rate limiting (RRL) is a method to combat DNS reflection amplification
attacks. These attacks rely on the fact that source address of a UDP query
can be forged, and without a worldwide deployment of `BCP38
<https://tools.ietf.org/html/bcp38>`_, such a forgery cannot be prevented.
An attacker can use a DNS server (or multiple servers) as an amplification
source and can flood a victim with a large number of unsolicited DNS responses.
The RRL lowers the amplification factor of these attacks by sending some of
the responses as truncated or by dropping them altogether.
You can enable RRL by setting the :ref:`server_rate-limit` option in the
:ref:`server section<Server section>`. The option controls how many responses
per second are permitted for each flow. Responses exceeding this rate are
limited. The option :ref:`server_rate-limit-slip` then configures how many
limited responses are sent as truncated (slip) instead of being dropped.
::
server:
rate-limit: 200 # Allow 200 resp/s for each flow
rate-limit-slip: 2 # Every other response slips
.. _dnssec:
Automatic DNSSEC signing
...
...
doc/man/knot.conf.5in
View file @
fc71c1f0
...
...
@@ -149,10 +149,6 @@ server:
max\-udp\-payload: SIZE
max\-ipv4\-udp\-payload: SIZE
max\-ipv6\-udp\-payload: SIZE
rate\-limit: INT
rate\-limit\-slip: INT
rate\-limit\-table\-size: INT
rate\-limit\-whitelist: ADDR[/INT] | ADDR\-ADDR ...
listen: ADDR[@INT] ...
.ft P
.fi
...
...
@@ -243,69 +239,6 @@ A maximum number of TCP clients connected in parallel, set this below the file
descriptor limit to avoid resource exhaustion.
.sp
\fIDefault:\fP 100
.SS rate\-limit
.sp
Rate limiting is based on the token bucket scheme. A rate basically
represents a number of tokens available each second. Each response is
processed and classified (based on several discriminators, e.g.
source netblock, query type, zone name, rcode, etc.). Classified responses are
then hashed and assigned to a bucket containing number of available
tokens, timestamp and metadata. When available tokens are exhausted,
response is dropped or sent as truncated (see \fI\%rate\-limit\-slip\fP).
Number of available tokens is recalculated each second.
.sp
\fIDefault:\fP 0 (disabled)
.SS rate\-limit\-table\-size
.sp
Size of the hash table in a number of buckets. The larger the hash table, the lesser
the probability of a hash collision, but at the expense of additional memory costs.
Each bucket is estimated roughly to 32 bytes. The size should be selected as
a reasonably large prime due to better hash function distribution properties.
Hash table is internally chained and works well up to a fill rate of 90 %, general
rule of thumb is to select a prime near 1.2 * maximum_qps.
.sp
\fIDefault:\fP 393241
.SS rate\-limit\-slip
.sp
As attacks using DNS/UDP are usually based on a forged source address,
an attacker could deny services to the victim\(aqs netblock if all
responses would be completely blocked. The idea behind SLIP mechanism
is to send each N\s-2\uth\d\s0 response as truncated, thus allowing client to
reconnect via TCP for at least some degree of service. It is worth
noting, that some responses can\(aqt be truncated (e.g. SERVFAIL).
.INDENT 0.0
.IP \(bu 2
Setting the value to \fB0\fP will cause that all rate\-limited responses will
be dropped. The outbound bandwidth and packet rate will be strictly capped
by the \fI\%rate\-limit\fP option. All legitimate requestors affected
by the limit will face denial of service and will observe excessive timeouts.
Therefore this setting is not recommended.
.IP \(bu 2
Setting the value to \fB1\fP will cause that all rate\-limited responses will
be sent as truncated. The amplification factor of the attack will be reduced,
but the outbound data bandwidth won\(aqt be lower than the incoming bandwidth.
Also the outbound packet rate will be the same as without RRL.
.IP \(bu 2
Setting the value to \fB2\fP will cause that half of the rate\-limited responses
will be dropped, the other half will be sent as truncated. With this
configuration, both outbound bandwidth and packet rate will be lower than the
inbound. On the other hand, the dropped responses enlarge the time window
for possible cache poisoning attack on the resolver.
.IP \(bu 2
Setting the value to anything \fBlarger than 2\fP will keep on decreasing
the outgoing rate\-limited bandwidth, packet rate, and chances to notify
legitimate requestors to reconnect using TCP. These attributes are inversely
proportional to the configured value. Setting the value high is not advisable.
.UNINDENT
.sp
\fIDefault:\fP 1
.SS rate\-limit\-whitelist
.sp
A list of IP addresses, network subnets, or network ranges to exempt from
rate limiting. Empty list means that no incoming connection will be
white\-listed.
.sp
\fIDefault:\fP not set
.SS max\-udp\-payload
.sp
Maximum EDNS0 UDP payload size default for both IPv4 and IPv6.
...
...
@@ -1089,6 +1022,90 @@ Minimum severity level for messages related to zones that are logged.
Minimum severity level for all message types that are logged.
.sp
\fIDefault:\fP not set
.SH MODULE RRL
.sp
A response rate limiting module.
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
mod\-rrl:
\- id: STR
rate\-limit: INT
slip: INT
table\-size: INT
whitelist: ADDR[/INT] | ADDR\-ADDR ...
.ft P
.fi
.UNINDENT
.UNINDENT
.SS id
.sp
A module identifier.
.SS rate\-limit
.sp
Rate limiting is based on the token bucket scheme. A rate basically
represents a number of tokens available each second. Each response is
processed and classified (based on several discriminators, e.g.
source netblock, query type, zone name, rcode, etc.). Classified responses are
then hashed and assigned to a bucket containing number of available
tokens, timestamp and metadata. When available tokens are exhausted,
response is dropped or sent as truncated (see \fI\%slip\fP).
Number of available tokens is recalculated each second.
.sp
\fIRequired\fP
.SS table\-size
.sp
Size of the hash table in a number of buckets. The larger the hash table, the lesser
the probability of a hash collision, but at the expense of additional memory costs.
Each bucket is estimated roughly to 32 bytes. The size should be selected as
a reasonably large prime due to better hash function distribution properties.
Hash table is internally chained and works well up to a fill rate of 90 %, general
rule of thumb is to select a prime near 1.2 * maximum_qps.
.sp
\fIDefault:\fP 393241
.SS slip
.sp
As attacks using DNS/UDP are usually based on a forged source address,
an attacker could deny services to the victim\(aqs netblock if all
responses would be completely blocked. The idea behind SLIP mechanism
is to send each N\s-2\uth\d\s0 response as truncated, thus allowing client to
reconnect via TCP for at least some degree of service. It is worth
noting, that some responses can\(aqt be truncated (e.g. SERVFAIL).
.INDENT 0.0
.IP \(bu 2
Setting the value to \fB0\fP will cause that all rate\-limited responses will
be dropped. The outbound bandwidth and packet rate will be strictly capped
by the \fI\%rate\-limit\fP option. All legitimate requestors affected
by the limit will face denial of service and will observe excessive timeouts.
Therefore this setting is not recommended.
.IP \(bu 2
Setting the value to \fB1\fP will cause that all rate\-limited responses will
be sent as truncated. The amplification factor of the attack will be reduced,
but the outbound data bandwidth won\(aqt be lower than the incoming bandwidth.
Also the outbound packet rate will be the same as without RRL.
.IP \(bu 2
Setting the value to \fB2\fP will cause that half of the rate\-limited responses
will be dropped, the other half will be sent as truncated. With this
configuration, both outbound bandwidth and packet rate will be lower than the
inbound. On the other hand, the dropped responses enlarge the time window
for possible cache poisoning attack on the resolver.
.IP \(bu 2
Setting the value to anything \fBlarger than 2\fP will keep on decreasing
the outgoing rate\-limited bandwidth, packet rate, and chances to notify
legitimate requestors to reconnect using TCP. These attributes are inversely
proportional to the configured value. Setting the value high is not advisable.
.UNINDENT
.sp
\fIDefault:\fP 1
.SS whitelist
.sp
A list of IP addresses, network subnets, or network ranges to exempt from
rate limiting. Empty list means that no incoming connection will be
white\-listed.
.sp
\fIDefault:\fP not set
.SH MODULE DNSTAP
.sp
The module dnstap allows query and response logging.
...
...
doc/modules.rst
View file @
fc71c1f0
...
...
@@ -31,7 +31,36 @@ an identifier must be created and then referenced in the form of
.. NOTE::
Query modules are processed in the order they are specified in the
zone/template configuration.
zone/template configuration. In most cases, the recommended order is::
mod-synth-record, mod-online-sign, mod-rrl, mod-dnstap, mod-stats
``rrl`` — Response rate limiting
--------------------------------
Response rate limiting (RRL) is a method to combat DNS reflection amplification
attacks. These attacks rely on the fact that source address of a UDP query
can be forged, and without a worldwide deployment of `BCP38
<https://tools.ietf.org/html/bcp38>`_, such a forgery cannot be prevented.
An attacker can use a DNS server (or multiple servers) as an amplification
source and can flood a victim with a large number of unsolicited DNS responses.
The RRL lowers the amplification factor of these attacks by sending some of
the responses as truncated or by dropping them altogether.
The module introduces two counters. The number of slipped and dropped responses.
You can enable RRL by setting the :ref:`mod-rrl<mod-rrl>` module globally or per zone.
::
mod-rrl:
- id: default
rate-limit: 200 # Allow 200 resp/s for each flow
slip: 2 # Every other response slips
template:
- id: default
global-module: mod-rrl/default # Enable RRL globally
``dnstap`` – dnstap-enabled query logging
-----------------------------------------
...
...
@@ -503,7 +532,7 @@ AAAA-only glue records.
------------------------
The module sends empty truncated response to any UDP query. This is similar
to a slipped answer in :ref:`response rate limiting<
server
_rate-limit>`.
to a slipped answer in :ref:`response rate limiting<
mod-rrl
_rate-limit>`.
TCP queries are not affected.
To enable this module globally, you need to add something like the following
...
...
doc/reference.rst
View file @
fc71c1f0
...
...
@@ -102,10 +102,6 @@ General options related to the server.
max-udp-payload: SIZE
max-ipv4-udp-payload: SIZE
max-ipv6-udp-payload: SIZE
rate-limit: INT
rate-limit-slip: INT
rate-limit-table-size: INT
rate-limit-whitelist: ADDR[/INT] | ADDR-ADDR ...
listen: ADDR[@INT] ...
.. _server_identity:
...
...
@@ -249,83 +245,6 @@ descriptor limit to avoid resource exhaustion.
*Default:* 100
.. _server_rate-limit:
rate-limit
----------
Rate limiting is based on the token bucket scheme. A rate basically
represents a number of tokens available each second. Each response is
processed and classified (based on several discriminators, e.g.
source netblock, query type, zone name, rcode, etc.). Classified responses are
then hashed and assigned to a bucket containing number of available
tokens, timestamp and metadata. When available tokens are exhausted,
response is dropped or sent as truncated (see :ref:`server_rate-limit-slip`).
Number of available tokens is recalculated each second.
*Default:* 0 (disabled)
.. _server_rate-limit-table-size:
rate-limit-table-size
---------------------
Size of the hash table in a number of buckets. The larger the hash table, the lesser
the probability of a hash collision, but at the expense of additional memory costs.
Each bucket is estimated roughly to 32 bytes. The size should be selected as
a reasonably large prime due to better hash function distribution properties.
Hash table is internally chained and works well up to a fill rate of 90 %, general
rule of thumb is to select a prime near 1.2 * maximum_qps.
*Default:* 393241
.. _server_rate-limit-slip:
rate-limit-slip
---------------
As attacks using DNS/UDP are usually based on a forged source address,
an attacker could deny services to the victim's netblock if all
responses would be completely blocked. The idea behind SLIP mechanism
is to send each N\ :sup:`th` response as truncated, thus allowing client to
reconnect via TCP for at least some degree of service. It is worth
noting, that some responses can't be truncated (e.g. SERVFAIL).
- Setting the value to **0** will cause that all rate-limited responses will
be dropped. The outbound bandwidth and packet rate will be strictly capped
by the :ref:`server_rate-limit` option. All legitimate requestors affected
by the limit will face denial of service and will observe excessive timeouts.
Therefore this setting is not recommended.
- Setting the value to **1** will cause that all rate-limited responses will
be sent as truncated. The amplification factor of the attack will be reduced,
but the outbound data bandwidth won't be lower than the incoming bandwidth.
Also the outbound packet rate will be the same as without RRL.
- Setting the value to **2** will cause that half of the rate-limited responses
will be dropped, the other half will be sent as truncated. With this
configuration, both outbound bandwidth and packet rate will be lower than the
inbound. On the other hand, the dropped responses enlarge the time window
for possible cache poisoning attack on the resolver.
- Setting the value to anything **larger than 2** will keep on decreasing
the outgoing rate-limited bandwidth, packet rate, and chances to notify
legitimate requestors to reconnect using TCP. These attributes are inversely
proportional to the configured value. Setting the value high is not advisable.
*Default:* 1
.. _server_rate-limit-whitelist:
rate-limit-whitelist
--------------------
A list of IP addresses, network subnets, or network ranges to exempt from
rate limiting. Empty list means that no incoming connection will be
white-listed.
*Default:* not set
.. _server_max-udp-payload:
max-udp-payload
...
...
@@ -1274,6 +1193,106 @@ Minimum severity level for all message types that are logged.
*Default:* not set
.. _mod-rrl:
Module rrl
==========
A response rate limiting module.
::
mod-rrl:
- id: STR
rate-limit: INT
slip: INT
table-size: INT
whitelist: ADDR[/INT] | ADDR-ADDR ...
.. _mod-rrl_id:
id
--
A module identifier.
.. _mod-rrl_rate-limit:
rate-limit
----------
Rate limiting is based on the token bucket scheme. A rate basically
represents a number of tokens available each second. Each response is
processed and classified (based on several discriminators, e.g.
source netblock, query type, zone name, rcode, etc.). Classified responses are
then hashed and assigned to a bucket containing number of available
tokens, timestamp and metadata. When available tokens are exhausted,
response is dropped or sent as truncated (see :ref:`mod-rrl_slip`).
Number of available tokens is recalculated each second.
*Required*
.. _mod-rrl_table-size:
table-size
----------
Size of the hash table in a number of buckets. The larger the hash table, the lesser
the probability of a hash collision, but at the expense of additional memory costs.
Each bucket is estimated roughly to 32 bytes. The size should be selected as
a reasonably large prime due to better hash function distribution properties.
Hash table is internally chained and works well up to a fill rate of 90 %, general
rule of thumb is to select a prime near 1.2 * maximum_qps.
*Default:* 393241
.. _mod-rrl_slip:
slip
----
As attacks using DNS/UDP are usually based on a forged source address,
an attacker could deny services to the victim's netblock if all
responses would be completely blocked. The idea behind SLIP mechanism
is to send each N\ :sup:`th` response as truncated, thus allowing client to
reconnect via TCP for at least some degree of service. It is worth
noting, that some responses can't be truncated (e.g. SERVFAIL).
- Setting the value to **0** will cause that all rate-limited responses will
be dropped. The outbound bandwidth and packet rate will be strictly capped
by the :ref:`mod-rrl_rate-limit` option. All legitimate requestors affected
by the limit will face denial of service and will observe excessive timeouts.
Therefore this setting is not recommended.
- Setting the value to **1** will cause that all rate-limited responses will
be sent as truncated. The amplification factor of the attack will be reduced,
but the outbound data bandwidth won't be lower than the incoming bandwidth.
Also the outbound packet rate will be the same as without RRL.
- Setting the value to **2** will cause that half of the rate-limited responses
will be dropped, the other half will be sent as truncated. With this
configuration, both outbound bandwidth and packet rate will be lower than the
inbound. On the other hand, the dropped responses enlarge the time window
for possible cache poisoning attack on the resolver.
- Setting the value to anything **larger than 2** will keep on decreasing
the outgoing rate-limited bandwidth, packet rate, and chances to notify
legitimate requestors to reconnect using TCP. These attributes are inversely
proportional to the configured value. Setting the value high is not advisable.
*Default:* 1
.. _mod-rrl_whitelist:
whitelist
---------
A list of IP addresses, network subnets, or network ranges to exempt from
rate limiting. Empty list means that no incoming connection will be
white-listed.
*Default:* not set
.. _Module dnstap:
Module dnstap
...
...
src/Makefile.am
View file @
fc71c1f0
...
...
@@ -234,6 +234,8 @@ libknotd_la_SOURCES = \
knot/conf/confdb.h
\
knot/conf/confio.c
\
knot/conf/confio.h
\
knot/conf/migration.c
\
knot/conf/migration.h
\
knot/conf/scheme.c
\
knot/conf/scheme.h
\
knot/conf/tools.c
\
...
...
@@ -280,6 +282,10 @@ libknotd_la_SOURCES = \
knot/modules/online_sign/online_sign.h
\
knot/modules/online_sign/nsec_next.c
\
knot/modules/online_sign/nsec_next.h
\
knot/modules/rrl/functions.c
\
knot/modules/rrl/functions.h
\
knot/modules/rrl/rrl.c
\
knot/modules/rrl/rrl.h
\
knot/modules/stats/stats.c
\
knot/modules/stats/stats.h
\
knot/modules/synth_record/synth_record.c
\
...
...
@@ -331,8 +337,6 @@ libknotd_la_SOURCES = \
knot/server/dthreads.h
\
knot/server/journal.c
\
knot/server/journal.h
\
knot/server/rrl.c
\
knot/server/rrl.h
\
knot/server/serialization.c
\
knot/server/serialization.h
\
knot/server/server.c
\
...
...
src/knot/conf/base.c
View file @
fc71c1f0
...
...
@@ -133,15 +133,10 @@ static void init_cache(
val
=
conf_get
(
conf
,
C_SRV
,
C_MAX_TCP_CLIENTS
);
conf
->
cache
.
srv_max_tcp_clients
=
conf_int
(
&
val
);
val
=
conf_get
(
conf
,
C_SRV
,
C_RATE_LIMIT_SLIP
);
conf
->
cache
.
srv_rate_limit_slip
=
conf_int
(
&
val
);
val
=
conf_get
(
conf
,
C_CTL
,
C_TIMEOUT
);
conf
->
cache
.
ctl_timeout
=
conf_int
(
&
val
)
*
1000
;
conf
->
cache
.
srv_nsid
=
conf_get
(
conf
,
C_SRV
,
C_NSID
);
conf
->
cache
.
srv_rate_limit_whitelist
=
conf_get
(
conf
,
C_SRV
,
C_RATE_LIMIT_WHITELIST
);
}
int
conf_new
(
...
...
src/knot/conf/base.h
View file @
fc71c1f0
...
...
@@ -106,10 +106,8 @@ typedef struct {
int32_t
srv_tcp_idle_timeout
;
int32_t
srv_tcp_reply_timeout
;
int32_t
srv_max_tcp_clients
;
int32_t
srv_rate_limit_slip
;
int32_t
ctl_timeout
;
conf_val_t
srv_nsid
;
conf_val_t
srv_rate_limit_whitelist
;
}
cache
;
/*! List of active query modules. */
...
...
src/knot/conf/migration.c
0 → 100644
View file @
fc71c1f0
/* Copyright (C) 2016 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "knot/common/log.h"
#include "knot/conf/migration.h"
#include "knot/conf/confdb.h"
static
void
try_unset
(
conf_t
*
conf
,
knot_db_txn_t
*
txn
,
yp_name_t
*
key0
,
yp_name_t
*
key1
)
{
int
ret
=
conf_db_unset
(
conf
,
txn
,
key0
,
key1
,
NULL
,
0
,
NULL
,
0
,
true
);
if
(
ret
!=
KNOT_EOK
&&
ret
!=
KNOT_ENOENT
)
{
log_warning
(
"conf, migration, failed to unset '%s%s%s' (%s)"
,
key0
+
1
,
(
key1
!=
NULL
)
?
"/"
:
""
,
(
key1
!=
NULL
)
?
key1
+
1
:
""
,
knot_strerror
(
ret
));
}
}
#define check_set(conf, txn, key0, key1, id, id_len, data, data_len) \
ret = conf_db_set(conf, txn, key0, key1, id, id_len, data, data_len); \
if (ret != KNOT_EOK && ret != KNOT_CONF_EREDEFINE) { \
log_error("conf, migration, failed to set '%s%s%s' (%s)", \
key0 + 1, \
(key1 != NULL) ? "/" : "", \
(key1 != NULL) ? key1 + 1 : "", \
knot_strerror(ret)); \
return ret; \
}
static
int
migrate_rrl
(
conf_t
*
conf
,
knot_db_txn_t
*
txn
)
{
#define MOD_RRL "\x07""mod-rrl"
#define MOD_RATE_LIMIT "\x0A""rate-limit"
#define MOD_SLIP "\x04""slip"
#define MOD_TBL_SIZE "\x0A""table-size"
#define MOD_WHITELIST "\x09""whitelist"
const
uint8_t
*
id
=
CONF_DEFAULT_ID
+
1
;
const
size_t
id_len
=
CONF_DEFAULT_ID
[
0
];
const
uint8_t
*
dflt_rrl
=
(
const
uint8_t
*
)
MOD_RRL
"default
\0
"
;
const
size_t
dflt_rrl_len
=
16
;
conf_val_t
val
;
int
ret
=
conf_db_get
(
conf
,
txn
,
C_SRV
,
C_RATE_LIMIT
,
NULL
,
0
,
&
val
);
// Migrate old configuration if RRL enabled.
if
(
ret
==
KNOT_EOK
&&
conf_int
(
&
val
)
>
0
)
{
log_notice
(
"config, migrating RRL configuration from server to mod-rrl"
);
// Create equivalent mod-rrl configuration.
check_set
(
conf
,
txn
,
MOD_RRL
,
C_ID
,
id
,
id_len
,
NULL
,
0
);
check_set
(
conf
,
txn
,
MOD_RRL
,
MOD_RATE_LIMIT
,
id
,
id_len
,
val
.
data
,
val
.
len
);
conf_db_get
(
conf
,
txn
,
C_SRV
,
C_RATE_LIMIT_SLIP
,
NULL
,
0
,
&
val
);
if
(
val
.
code
==
KNOT_EOK
)
{
conf_val
(
&
val
);
check_set
(
conf
,
txn
,
MOD_RRL
,
MOD_SLIP
,
id
,
id_len
,
val
.
data
,
val
.
len
);
}
conf_db_get
(
conf
,
txn
,
C_SRV
,
C_RATE_LIMIT_TBL_SIZE
,
NULL
,
0
,
&
val
);
if
(
val
.
code
==
KNOT_EOK
)
{
conf_val
(
&
val
);
check_set
(
conf
,
txn
,
MOD_RRL
,
MOD_TBL_SIZE
,
id
,
id_len
,
val
.
data
,
val
.
len
);
}
conf_db_get
(
conf
,
txn
,
C_SRV
,
C_RATE_LIMIT_WHITELIST
,
NULL
,
0
,
&
val
);
while
(
val
.
code
==
KNOT_EOK
)
{
conf_val
(
&
val
);
check_set
(
conf
,
txn
,
MOD_RRL
,
MOD_WHITELIST
,
id
,
id_len
,
val
.
data
,
val
.
len
);
conf_val_next
(
&
val
);
}
// Create default template and assing global module.
check_set
(
conf
,
txn
,
C_TPL
,
C_ID
,
id
,
id_len
,
NULL
,
0
);
check_set
(
conf
,
txn
,
C_TPL
,
C_GLOBAL_MODULE
,
id
,
id_len
,
dflt_rrl
,
dflt_rrl_len
);
}
// Drop old RRL configuration.
try_unset
(
conf
,
txn
,
C_SRV
,
C_RATE_LIMIT
);
try_unset
(
conf
,
txn
,
C_SRV
,
C_RATE_LIMIT_SLIP
);
try_unset
(
conf
,
txn
,
C_SRV
,
C_RATE_LIMIT_TBL_SIZE
);
try_unset
(
conf
,
txn
,
C_SRV
,
C_RATE_LIMIT_WHITELIST
);
return
KNOT_EOK
;
}
int
conf_migrate
(