From 65b3f91c18957a0e0b3e31e77f2c65eedeb66aa5 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 9 Jul 2021 14:21:04 +0200 Subject: [PATCH] dnsdist: Document that range-based lookups expect addresses in network byte order Also document that tags are always created on a lookup, even when the key does not exist. It's a bit weird but we should probably not change that right now. --- pdns/dnsdistdist/dnsdist-kvs.cc | 3 +++ pdns/dnsdistdist/dnsdist-kvs.hh | 4 ++-- pdns/dnsdistdist/docs/reference/kvs.rst | 7 +++++-- pdns/dnsdistdist/docs/rules-actions.rst | 5 +++-- 4 files changed, 13 insertions(+), 6 deletions(-) diff --git a/pdns/dnsdistdist/dnsdist-kvs.cc b/pdns/dnsdistdist/dnsdist-kvs.cc index 552936fd84..6dd59fb663 100644 --- a/pdns/dnsdistdist/dnsdist-kvs.cc +++ b/pdns/dnsdistdist/dnsdist-kvs.cc @@ -132,6 +132,9 @@ bool LMDBKVStore::getRangeValue(const std::string& key, std::string& value) // to be stored with the last value of the range as key // and the first value of the range as data, sometimes // followed by any other content we don't care about + // range-based lookups are mostly useful for network ranges, + // for which we expect addresses to be stored in network byte + // order // retrieve the first key greater or equal to our key int rc = cursor.lower_bound(MDBInVal(key), actualKey, result); diff --git a/pdns/dnsdistdist/dnsdist-kvs.hh b/pdns/dnsdistdist/dnsdist-kvs.hh index f9f9304415..85c87c4c90 100644 --- a/pdns/dnsdistdist/dnsdist-kvs.hh +++ b/pdns/dnsdistdist/dnsdist-kvs.hh @@ -154,8 +154,8 @@ public: virtual bool keyExists(const std::string& key) = 0; virtual bool getValue(const std::string& key, std::string& value) = 0; // do a range-based lookup (mostly useful for IP addresses), assuming that: - // there is a key for the last element of the range (2001:0db8:ffff:ffff:ffff:ffff:ffff:ffff for 2001:db8::/32) - // which contains the first element of the range (2001:0db8:0000:0000:0000:0000:0000:0000) followed by any data in the value + // there is a key for the last element of the range (2001:0db8:ffff:ffff:ffff:ffff:ffff:ffff, in network byte order, for 2001:db8::/32) + // which contains the first element of the range (2001:0db8:0000:0000:0000:0000:0000:0000, in network bytes order) followed by any data in the value // AND there is no overlapping ranges in the database !! // This requires that the underlying store supports ordered keys, which is true for LMDB but not for CDB, for example. virtual bool getRangeValue(const std::string& key, std::string& value) diff --git a/pdns/dnsdistdist/docs/reference/kvs.rst b/pdns/dnsdistdist/docs/reference/kvs.rst index b7395a2eab..f39c5c6254 100644 --- a/pdns/dnsdistdist/docs/reference/kvs.rst +++ b/pdns/dnsdistdist/docs/reference/kvs.rst @@ -16,7 +16,7 @@ Then the key used for the lookup can be selected via one of the following functi * the exact qname with :func:`KeyValueLookupKeyQName` ; * a suffix match via :func:`KeyValueLookupKeySuffix`, meaning that several lookups will be done, removing one label from the qname at a time, until a match has been found or there is no label left ; - * the source IP with :func:`KeyValueLookupKeySourceIP` ; + * the source IP, in network byte order, with :func:`KeyValueLookupKeySourceIP` ; * the value of an existing tag with :func:`KeyValueLookupKeyTag`. For example, to do a suffix-based lookup into a LMDB KVS database, the following rule can be used: @@ -34,6 +34,7 @@ this would result in the following lookups: * \\8powerdns\\3com\\0 Then a match is found for the last key, and the corresponding value is stored into the 'kvs-suffix-result' tag. This tag can now be used in subsequent rules to take an action based on the result of the lookup. +Note that the tag is also created when the key has not been found, but the content of the tag is empty. .. code-block:: lua @@ -117,12 +118,14 @@ If the value found in the LMDB database for the key '\\8powerdns\\3com\\0' was ' :param int minLabels: The minimum number of labels to do a lookup for. Default is 0 which means unlimited :param bool wireFormat: Whether to do the lookup in wire format (default) or in plain text -.. function:: KeyValueLookupKeyTag() -> KeyValueLookupKey +.. function:: KeyValueLookupKeyTag(tagName) -> KeyValueLookupKey .. versionadded:: 1.4.0 Return a new KeyValueLookupKey object that, when passed to :func:`KeyValueStoreLookupAction`, will return the value of the corresponding tag for this query, if it exists. + :param str tagName: The name of the tag. + .. function:: newCDBKVStore(filename, refreshDelay) -> KeyValueStore .. versionadded:: 1.4.0 diff --git a/pdns/dnsdistdist/docs/rules-actions.rst b/pdns/dnsdistdist/docs/rules-actions.rst index 124307e1a4..8e0083e1da 100644 --- a/pdns/dnsdistdist/docs/rules-actions.rst +++ b/pdns/dnsdistdist/docs/rules-actions.rst @@ -504,7 +504,7 @@ These ``DNSRule``\ s be one of the following items: Does a range-based lookup into the key value store referenced by 'kvs' using the key returned by 'lookupKey' and returns true if there is a range covering that key. - This assumes that there is a key for the last element of the range (for example 2001:0db8:ffff:ffff:ffff:ffff:ffff:ffff for 2001:db8::/32) which contains the first element of the range (2001:0db8:0000:0000:0000:0000:0000:0000) (optionally followed by any data), as value and that there is no overlapping ranges in the database. + This assumes that there is a key, in network byte order, for the last element of the range (for example 2001:0db8:ffff:ffff:ffff:ffff:ffff:ffff for 2001:db8::/32) which contains the first element of the range (2001:0db8:0000:0000:0000:0000:0000:0000) (optionally followed by any data) as value, still in network byte order, and that there is no overlapping ranges in the database. This requires that the underlying store supports ordered keys, which is true for LMDB but not for CDB. :param KeyValueStore kvs: The key value store to query @@ -959,6 +959,7 @@ The following actions exist. The key can be based on the qname (:func:`KeyValueLookupKeyQName` and :func:`KeyValueLookupKeySuffix`), source IP (:func:`KeyValueLookupKeySourceIP`) or the value of an existing tag (:func:`KeyValueLookupKeyTag`). Subsequent rules are processed after this action. + Note that the tag is always created, even if there was no match, but in that case the content is empty. :param KeyValueStore kvs: The key value store to query :param KeyValueLookupKey lookupKey: The key to use for the lookup @@ -970,7 +971,7 @@ The following actions exist. Does a range-based lookup into the key value store referenced by 'kvs' using the key returned by 'lookupKey', and storing the result if any into the tag named 'destinationTag'. - This assumes that there is a key for the last element of the range (for example 2001:0db8:ffff:ffff:ffff:ffff:ffff:ffff for 2001:db8::/32) which contains the first element of the range (2001:0db8:0000:0000:0000:0000:0000:0000) (optionally followed by any data), as value and that there is no overlapping ranges in the database. + This assumes that there is a key in network byte order for the last element of the range (for example 2001:0db8:ffff:ffff:ffff:ffff:ffff:ffff for 2001:db8::/32) which contains the first element of the range (2001:0db8:0000:0000:0000:0000:0000:0000) (optionally followed by any data) as value, also in network byte order, and that there is no overlapping ranges in the database. This requires that the underlying store supports ordered keys, which is true for LMDB but not for CDB. Subsequent rules are processed after this action. -- 2.47.2