sync code with last improvements from OpenBSD
This commit is contained in:
parent
30d14db1d3
commit
0c904fa153
235 changed files with 12410 additions and 6193 deletions
|
@ -1,10 +1,10 @@
|
|||
.\" $OpenBSD: ASN1_OBJECT_new.3,v 1.15 2021/12/15 20:07:51 schwarze Exp $
|
||||
.\" $OpenBSD: ASN1_OBJECT_new.3,v 1.16 2023/09/05 15:01:39 schwarze Exp $
|
||||
.\" full merge up to: OpenSSL 99d63d4 Mar 19 12:28:58 2016 -0400
|
||||
.\"
|
||||
.\" This file is a derived work.
|
||||
.\" The changes are covered by the following Copyright and license:
|
||||
.\"
|
||||
.\" Copyright (c) 2017, 2021 Ingo Schwarze <schwarze@openbsd.org>
|
||||
.\" Copyright (c) 2017, 2021, 2023 Ingo Schwarze <schwarze@openbsd.org>
|
||||
.\"
|
||||
.\" Permission to use, copy, modify, and distribute this software for any
|
||||
.\" purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -65,7 +65,7 @@
|
|||
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
.\" OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd $Mdocdate: December 15 2021 $
|
||||
.Dd $Mdocdate: September 5 2023 $
|
||||
.Dt ASN1_OBJECT_NEW 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -207,3 +207,22 @@ first appeared in SSLeay 0.5.1 and
|
|||
in SSLeay 0.8.0.
|
||||
These functions have been available since
|
||||
.Ox 2.4 .
|
||||
.Sh BUGS
|
||||
The function
|
||||
.Fn ASN1_OBJECT_new
|
||||
is not useful for any practical purpose because the library does not
|
||||
provide any function capable of adding data to an existing object.
|
||||
Consequently, if the application program creates an object with
|
||||
.Fn ASN1_OBJECT_new ,
|
||||
that object will always remain empty.
|
||||
.Pp
|
||||
Similarly, if an
|
||||
.Fa nid
|
||||
of
|
||||
.Dv NID_undef
|
||||
is passed to
|
||||
.Fn ASN1_OBJECT_create ,
|
||||
or if
|
||||
.Dv NULL
|
||||
is passed for any of its pointer arguments, the returned object
|
||||
will permanently remain incomplete.
|
||||
|
|
|
@ -1,6 +1,23 @@
|
|||
.\" $OpenBSD: EVP_CIPHER_meth_new.3,v 1.2 2023/08/26 15:14:28 schwarze Exp $
|
||||
.\" $OpenBSD: EVP_CIPHER_meth_new.3,v 1.4 2023/09/05 14:37:00 schwarze Exp $
|
||||
.\" selective merge up to: OpenSSL b0edda11 Mar 20 13:00:17 2018 +0000
|
||||
.\"
|
||||
.\" This file is a derived work.
|
||||
.\" The changes are covered by the following Copyright and license:
|
||||
.\"
|
||||
.\" Copyright (c) 2023 Ingo Schwarze <schwarze@openbsd.org>
|
||||
.\"
|
||||
.\" Permission to use, copy, modify, and distribute this software for any
|
||||
.\" purpose with or without fee is hereby granted, provided that the above
|
||||
.\" copyright notice and this permission notice appear in all copies.
|
||||
.\"
|
||||
.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.\" The original file was written by Richard Levitte <levitte@openssl.org>
|
||||
.\" Copyright (c) 2015 The OpenSSL Project.
|
||||
.\" All rights reserved.
|
||||
|
@ -49,7 +66,7 @@
|
|||
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
.\" OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd $Mdocdate: August 26 2023 $
|
||||
.Dd $Mdocdate: September 5 2023 $
|
||||
.Dt EVP_CIPHER_METH_NEW 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -184,75 +201,116 @@ Zero or more of the following flags can be OR'ed into the
|
|||
.Fa flags
|
||||
argument:
|
||||
.Bl -tag -width Ds
|
||||
.It EVP_CIPH_VARIABLE_LENGTH
|
||||
This cipher is of variable length.
|
||||
.It EVP_CIPH_CUSTOM_IV
|
||||
Storing and initialising the IV is left entirely to the implementation.
|
||||
.It EVP_CIPH_ALWAYS_CALL_INIT
|
||||
Set this if the implementation's
|
||||
.Fn init
|
||||
function should be called even if
|
||||
.Fa key
|
||||
is
|
||||
.Dv NULL .
|
||||
.It EVP_CIPH_CTRL_INIT
|
||||
Set this to have the implementation's
|
||||
.Fn ctrl
|
||||
function called with command code
|
||||
.Dv EVP_CTRL_INIT
|
||||
early in its setup.
|
||||
.It EVP_CIPH_CUSTOM_KEY_LENGTH
|
||||
Checking and setting the key length after creating the
|
||||
.Vt EVP_CIPHER
|
||||
is left to the implementation.
|
||||
Whenever someone uses
|
||||
.It Dv EVP_CIPH_VARIABLE_LENGTH
|
||||
This cipher has a variable key length, and the function
|
||||
.Xr EVP_CIPHER_CTX_set_key_length 3
|
||||
on a
|
||||
.Vt EVP_CIPHER
|
||||
with this flag set, the implementation's
|
||||
.Fn ctrl
|
||||
function will be called with the control code
|
||||
can be used with it.
|
||||
.It Dv EVP_CIPH_CUSTOM_IV
|
||||
Instruct
|
||||
.Xr EVP_CipherInit_ex 3
|
||||
and similar initialization functions to leave storing and initialising
|
||||
the IV entirely to the implementation.
|
||||
If this flag is set,
|
||||
the implementation is typically expected to do that in its
|
||||
.Fa init
|
||||
function.
|
||||
.It Dv EVP_CIPH_ALWAYS_CALL_INIT
|
||||
Instruct
|
||||
.Xr EVP_CipherInit_ex 3
|
||||
and similar initialization functions to call the implementation's
|
||||
.Fa init
|
||||
function even if the
|
||||
.Fa key
|
||||
argument is
|
||||
.Dv NULL .
|
||||
.It Dv EVP_CIPH_CTRL_INIT
|
||||
Instruct
|
||||
.Xr EVP_CipherInit_ex 3
|
||||
and similar initialization functions to call the implementation's
|
||||
.Fa ctrl
|
||||
function with a command
|
||||
.Fa type
|
||||
of
|
||||
.Dv EVP_CTRL_INIT
|
||||
early during the setup.
|
||||
.It Dv EVP_CIPH_CUSTOM_KEY_LENGTH
|
||||
Instruct
|
||||
.Xr EVP_CIPHER_CTX_set_key_length 3
|
||||
to not check and set the key length itself,
|
||||
but to leave that to the implementation by instead calling its
|
||||
.Fa ctrl
|
||||
function with a command
|
||||
.Fa type
|
||||
of
|
||||
.Dv EVP_CTRL_SET_KEY_LENGTH
|
||||
and the key length in
|
||||
.Fa arg .
|
||||
.It EVP_CIPH_NO_PADDING
|
||||
Don't use standard block padding.
|
||||
.It EVP_CIPH_RAND_KEY
|
||||
Making a key with random content is left to the implementation.
|
||||
This is done by calling the implementation's
|
||||
.Fn ctrl
|
||||
function with the control code
|
||||
.It Dv EVP_CIPH_NO_PADDING
|
||||
Instruct
|
||||
.Xr EVP_CipherFinal_ex 3
|
||||
and similar finalization functions to not use standard block padding
|
||||
but instead report an error if the total amount of data
|
||||
to be encrypted or decrypted is not a multiple of the block size.
|
||||
.It Dv EVP_CIPH_RAND_KEY
|
||||
Instruct
|
||||
.Xr EVP_CIPHER_CTX_rand_key 3
|
||||
to not generate a random key using
|
||||
.Xr arc4random_buf 3
|
||||
but instead leave that to the implementation by calling the
|
||||
.Fa ctrl
|
||||
function with a command
|
||||
.Fa type
|
||||
of
|
||||
.Dv EVP_CTRL_RAND_KEY
|
||||
and the pointer to the key memory storage in
|
||||
.Fa ptr .
|
||||
.It EVP_CIPH_CUSTOM_COPY
|
||||
Set this to have the implementation's
|
||||
.Fn ctrl
|
||||
function called with command code
|
||||
.It Dv EVP_CIPH_CUSTOM_COPY
|
||||
Instruct
|
||||
.Xr EVP_CIPHER_CTX_copy 3
|
||||
to call the implementation's
|
||||
.Fa ctrl
|
||||
function with a command
|
||||
.Fa type
|
||||
of
|
||||
.Dv EVP_CTRL_COPY
|
||||
at the end of
|
||||
.Xr EVP_CIPHER_CTX_copy 3 .
|
||||
and the destination
|
||||
.Fa "EVP_CIPHER_CTX *out"
|
||||
in the
|
||||
.Fa ptr
|
||||
argument immediately before returning successfully.
|
||||
The intended use is for further things to deal with after the
|
||||
implementation specific data block has been copied.
|
||||
The destination
|
||||
.Vt EVP_CIPHER_CTX
|
||||
object is passed to the control with the
|
||||
.Fa ptr
|
||||
parameter.
|
||||
The implementation-specific data block is reached with
|
||||
.Xr EVP_CIPHER_CTX_get_cipher_data 3 .
|
||||
.It EVP_CIPH_FLAG_DEFAULT_ASN1
|
||||
Use the default EVP routines to pass IV to and from ASN.1.
|
||||
.It EVP_CIPH_FLAG_LENGTH_BITS
|
||||
.It Dv EVP_CIPH_FLAG_DEFAULT_ASN1
|
||||
Instruct
|
||||
.Xr EVP_CIPHER_param_to_asn1 3
|
||||
to use
|
||||
.Xr ASN1_TYPE_set_octetstring 3
|
||||
if no
|
||||
.Fa set_asn1_parameters
|
||||
function is installed, and instruct
|
||||
.Xr EVP_CIPHER_asn1_to_param 3
|
||||
to use
|
||||
.Xr ASN1_TYPE_get_octetstring 3
|
||||
if no
|
||||
.Fa get_asn1_parameters
|
||||
function is installed.
|
||||
.It Dv EVP_CIPH_FLAG_LENGTH_BITS
|
||||
Signals that the length of the input buffer for encryption / decryption
|
||||
is to be understood as the number of bits instead of bytes for this
|
||||
implementation.
|
||||
This is only useful for CFB1 ciphers.
|
||||
.It EVP_CIPH_FLAG_CUSTOM_CIPHER
|
||||
This indicates that the implementation takes care of everything,
|
||||
.It Dv EVP_CIPH_FLAG_CUSTOM_CIPHER
|
||||
Instruct
|
||||
.Xr EVP_CipherUpdate 3 ,
|
||||
.Xr EVP_CipherFinal_ex 3 ,
|
||||
and similar encryption, decryption, and finalization functions
|
||||
that the implementation's
|
||||
.Fa do_cipher
|
||||
function takes care of everything,
|
||||
including padding, buffering and finalization.
|
||||
The EVP routines will simply give them control and do nothing more.
|
||||
.It EVP_CIPH_FLAG_AEAD_CIPHER
|
||||
.It Dv EVP_CIPH_FLAG_AEAD_CIPHER
|
||||
This indicates that this is an AEAD cipher implementation.
|
||||
.El
|
||||
.Pp
|
||||
|
@ -261,7 +319,9 @@ sets the size of the EVP_CIPHER's implementation context so that it can
|
|||
be automatically allocated.
|
||||
.Pp
|
||||
.Fn EVP_CIPHER_meth_set_init
|
||||
sets the cipher init function for
|
||||
sets the
|
||||
.Fa init
|
||||
function for
|
||||
.Fa cipher .
|
||||
The cipher init function is called by
|
||||
.Xr EVP_CipherInit 3 ,
|
||||
|
@ -269,6 +329,7 @@ The cipher init function is called by
|
|||
.Xr EVP_EncryptInit 3 ,
|
||||
.Xr EVP_EncryptInit_ex 3 ,
|
||||
.Xr EVP_DecryptInit 3 ,
|
||||
and
|
||||
.Xr EVP_DecryptInit_ex 3 .
|
||||
.Pp
|
||||
.Fn EVP_CIPHER_meth_set_do_cipher
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
.\" $OpenBSD: EVP_CIPHER_nid.3,v 1.2 2023/09/01 17:28:21 schwarze Exp $
|
||||
.\" $OpenBSD: EVP_CIPHER_nid.3,v 1.3 2023/09/05 14:54:21 schwarze Exp $
|
||||
.\" full merge up to: OpenSSL man3/EVP_EncryptInit.pod
|
||||
.\" 0874d7f2 Oct 11 13:13:47 2022 +0100
|
||||
.\"
|
||||
|
@ -66,12 +66,13 @@
|
|||
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
.\" OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd $Mdocdate: September 1 2023 $
|
||||
.Dd $Mdocdate: September 5 2023 $
|
||||
.Dt EVP_CIPHER_NID 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm EVP_CIPHER_nid ,
|
||||
.Nm EVP_CIPHER_CTX_nid ,
|
||||
.Nm EVP_CIPHER_name ,
|
||||
.Nm EVP_CIPHER_type ,
|
||||
.Nm EVP_CIPHER_CTX_type ,
|
||||
.Nm EVP_CIPHER_block_size ,
|
||||
|
@ -91,6 +92,10 @@
|
|||
.Fo EVP_CIPHER_CTX_nid
|
||||
.Fa "const EVP_CIPHER_CTX *ctx"
|
||||
.Fc
|
||||
.Ft const char *
|
||||
.Fo EVP_CIPHER_name
|
||||
.Fa "const EVP_CIPHER *cipher"
|
||||
.Fc
|
||||
.Ft int
|
||||
.Fo EVP_CIPHER_type
|
||||
.Fa "const EVP_CIPHER *ctx"
|
||||
|
@ -137,6 +142,12 @@ returns the NID of the cipher that
|
|||
.Fa ctx
|
||||
is configured to use.
|
||||
.Pp
|
||||
.Fn EVP_CIPHER_name
|
||||
converts the NID of the
|
||||
.Fa cipher
|
||||
to its short name with
|
||||
.Xr OBJ_nid2sn 3 .
|
||||
.Pp
|
||||
.Fn EVP_CIPHER_type
|
||||
returns the NID associated with the ASN.1 OBJECT IDENTIFIER of the
|
||||
.Fa cipher ,
|
||||
|
@ -196,12 +207,27 @@ and the return value of
|
|||
returns the cipher mode of the cipher that
|
||||
.Fa ctx
|
||||
is configured to use.
|
||||
.Pp
|
||||
.Fn EVP_CIPHER_name ,
|
||||
.Fn EVP_CIPHER_CTX_type ,
|
||||
.Fn EVP_CIPHER_mode ,
|
||||
and
|
||||
.Fn EVP_CIPHER_CTX_mode
|
||||
are implemented as macros.
|
||||
.Sh RETURN VALUES
|
||||
.Fn EVP_CIPHER_nid
|
||||
and
|
||||
.Fn EVP_CIPHER_CTX_nid
|
||||
return an NID.
|
||||
.Pp
|
||||
.Fn EVP_CIPHER_name
|
||||
returns a pointer to a string that is owned by an internal library object or
|
||||
.Dv NULL
|
||||
if the NID is neither built into the library nor added to the global
|
||||
object table by one of the functions documented in the manual page
|
||||
.Xr OBJ_create 3 ,
|
||||
of if the object does not contain a short name.
|
||||
.Pp
|
||||
.Fn EVP_CIPHER_type
|
||||
and
|
||||
.Fn EVP_CIPHER_CTX_type
|
||||
|
@ -264,6 +290,10 @@ and
|
|||
.Fn EVP_CIPHER_CTX_mode
|
||||
first appeared in OpenSSL 0.9.6 and have been available since
|
||||
.Ox 2.9 .
|
||||
.Pp
|
||||
.Fn EVP_CIPHER_name
|
||||
first appeared in OpenSSL 0.9.7 and has been available since
|
||||
.Ox 3.2 .
|
||||
.Sh CAVEATS
|
||||
The behaviour of the functions taking an
|
||||
.Vt EVP_CIPHER_CTX
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
.\" $OpenBSD: OBJ_nid2obj.3,v 1.20 2023/07/21 05:02:53 tb Exp $
|
||||
.\" $OpenBSD: OBJ_nid2obj.3,v 1.21 2023/09/05 13:50:22 schwarze Exp $
|
||||
.\" full merge up to: OpenSSL c264592d May 14 11:28:00 2006 +0000
|
||||
.\" selective merge up to: OpenSSL 35fd9953 May 28 14:49:38 2019 +0200
|
||||
.\"
|
||||
.\" This file is a derived work.
|
||||
.\" The changes are covered by the following Copyright and license:
|
||||
.\"
|
||||
.\" Copyright (c) 2017, 2021 Ingo Schwarze <schwarze@openbsd.org>
|
||||
.\" Copyright (c) 2017, 2021, 2023 Ingo Schwarze <schwarze@openbsd.org>
|
||||
.\"
|
||||
.\" Permission to use, copy, modify, and distribute this software for any
|
||||
.\" purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -67,7 +67,7 @@
|
|||
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
.\" OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd $Mdocdate: July 21 2023 $
|
||||
.Dd $Mdocdate: September 5 2023 $
|
||||
.Dt OBJ_NID2OBJ 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -89,19 +89,19 @@
|
|||
.In openssl/objects.h
|
||||
.Ft ASN1_OBJECT *
|
||||
.Fo OBJ_nid2obj
|
||||
.Fa "int n"
|
||||
.Fa "int nid"
|
||||
.Fc
|
||||
.Ft const char *
|
||||
.Fo OBJ_nid2ln
|
||||
.Fa "int n"
|
||||
.Fa "int nid"
|
||||
.Fc
|
||||
.Ft const char *
|
||||
.Fo OBJ_nid2sn
|
||||
.Fa "int n"
|
||||
.Fa "int nid"
|
||||
.Fc
|
||||
.Ft int
|
||||
.Fo OBJ_obj2nid
|
||||
.Fa "const ASN1_OBJECT *o"
|
||||
.Fa "const ASN1_OBJECT *object"
|
||||
.Fc
|
||||
.Ft int
|
||||
.Fo OBJ_ln2nid
|
||||
|
@ -124,7 +124,7 @@
|
|||
.Fo OBJ_obj2txt
|
||||
.Fa "char *buf"
|
||||
.Fa "int buf_len"
|
||||
.Fa "const ASN1_OBJECT *a"
|
||||
.Fa "const ASN1_OBJECT *object"
|
||||
.Fa "int no_name"
|
||||
.Fc
|
||||
.Ft int
|
||||
|
@ -134,86 +134,102 @@
|
|||
.Fc
|
||||
.Ft ASN1_OBJECT *
|
||||
.Fo OBJ_dup
|
||||
.Fa "const ASN1_OBJECT *o"
|
||||
.Fa "const ASN1_OBJECT *object"
|
||||
.Fc
|
||||
.In openssl/asn1.h
|
||||
.Ft int
|
||||
.Fo i2t_ASN1_OBJECT
|
||||
.Fa "char *buf"
|
||||
.Fa "int buf_len"
|
||||
.Fa "const ASN1_OBJECT *a"
|
||||
.Fa "const ASN1_OBJECT *object"
|
||||
.Fc
|
||||
.Ft int
|
||||
.Fo i2a_ASN1_OBJECT
|
||||
.Fa "BIO *out_bio"
|
||||
.Fa "const ASN1_OBJECT *a"
|
||||
.Fa "const ASN1_OBJECT *object"
|
||||
.Fc
|
||||
.Sh DESCRIPTION
|
||||
The ASN.1 object utility functions process
|
||||
.Vt ASN1_OBJECT
|
||||
structures which are a representation of the ASN.1 OBJECT IDENTIFIER
|
||||
(OID) type.
|
||||
For convenience, OIDs are usually represented in source code as
|
||||
numeric identifiers, or NIDs.
|
||||
OpenSSL has an internal table of OIDs that are generated when the
|
||||
library is built, and their corresponding NIDs are available as
|
||||
defined constants.
|
||||
For the functions below, application code should treat all returned
|
||||
values \(em OIDs, NIDs, or names \(em as constants.
|
||||
structures, in the following called
|
||||
.Dq objects .
|
||||
An object represents an ASN.1
|
||||
.Vt OBJECT IDENTIFIER
|
||||
.Pq OID .
|
||||
The library maintains an internal global table of objects.
|
||||
Many of these objects are built into the library
|
||||
and contained in the global table by default.
|
||||
The application program can add additional objects to the global table
|
||||
by using functions documented in the
|
||||
.Xr OBJ_create 3
|
||||
manual page.
|
||||
Consequently, there are three classes of objects:
|
||||
built-in table objects, user-defined table objects, and non-table objects.
|
||||
.Pp
|
||||
.Fn OBJ_nid2obj ,
|
||||
.Fn OBJ_nid2ln ,
|
||||
In addition to the OID, each object can hold
|
||||
a long name, a short name, and a numerical identifier (NID).
|
||||
Even though the concept of NIDs is specific to the library
|
||||
and not standardized, using the NID is often the most convenient way
|
||||
for source code to refer to a specific OID.
|
||||
The NIDs of the built-in objects are available as defined constants.
|
||||
.Pp
|
||||
Built-in table objects have certain advantages
|
||||
over objects that are not in the global table:
|
||||
for example, their NIDs can be used in C language switch statements.
|
||||
They are also shared:
|
||||
there is only a single static constant structure for each built-on OID.
|
||||
.Pp
|
||||
Some functions operate on table objects only:
|
||||
.Pp
|
||||
.Fn OBJ_nid2obj
|
||||
retrieves the table object associated with the
|
||||
.Fa nid .
|
||||
.Fn OBJ_nid2ln
|
||||
and
|
||||
.Fn OBJ_nid2sn
|
||||
convert the NID
|
||||
.Fa n
|
||||
to an
|
||||
.Vt ASN1_OBJECT
|
||||
structure, its long name, and its short name, respectively, or return
|
||||
.Dv NULL
|
||||
if an error occurred.
|
||||
retrieve its long and short name, respectively.
|
||||
.Pp
|
||||
.Fn OBJ_obj2nid ,
|
||||
.Fn OBJ_ln2nid ,
|
||||
.Fn OBJ_obj2nid
|
||||
retrieves the NID associated with the given
|
||||
.Fa object ,
|
||||
which is either the NID stored in the
|
||||
.Fa object
|
||||
itself, if any, or otherwise the NID stored in a table object
|
||||
containing the same OID.
|
||||
.Pp
|
||||
.Fn OBJ_ln2nid
|
||||
and
|
||||
.Fn OBJ_sn2nid
|
||||
return the corresponding NID for the object
|
||||
.Fa o ,
|
||||
the long name
|
||||
.Fa ln ,
|
||||
retrieve the NID from the table object with the long name
|
||||
.Fa ln
|
||||
or the short name
|
||||
.Fa sn ,
|
||||
respectively, or
|
||||
.Dv NID_undef
|
||||
if an error occurred.
|
||||
respectively.
|
||||
.Pp
|
||||
.Fn OBJ_txt2nid
|
||||
returns the NID corresponding to text string
|
||||
.Fa s .
|
||||
.Fa s
|
||||
can be a long name, a short name, or the numerical representation
|
||||
of an object.
|
||||
retrieves the NID from the table object described by the text string
|
||||
.Fa s ,
|
||||
which can be a long name, a short name,
|
||||
or the numerical representation of an OID.
|
||||
.Pp
|
||||
The remaining functions can be used both on table objects
|
||||
and on objects that are not in the global table:
|
||||
.Pp
|
||||
.Fn OBJ_txt2obj
|
||||
converts the text string
|
||||
.Fa s
|
||||
into an
|
||||
.Vt ASN1_OBJECT
|
||||
structure.
|
||||
retrieves or creates an object matching the text string
|
||||
.Fa s .
|
||||
If
|
||||
.Fa no_name
|
||||
is 0 then long names and short names will be interpreted as well as
|
||||
numerical forms.
|
||||
is 1, only the numerical representation of an OID is accepted.
|
||||
If
|
||||
.Fa no_name
|
||||
is 1, only the numerical form is acceptable.
|
||||
is 0, long names and short names are accepted as well.
|
||||
.Pp
|
||||
.Fn OBJ_obj2txt
|
||||
converts the
|
||||
.Vt ASN1_OBJECT
|
||||
.Fa a
|
||||
into a textual representation.
|
||||
The representation is written as a NUL terminated string to
|
||||
writes a NUL terminated textual representation
|
||||
of the OID contained in the given
|
||||
.Fa object
|
||||
into
|
||||
.Fa buf .
|
||||
At most
|
||||
.Fa buf_len
|
||||
|
@ -221,8 +237,13 @@ bytes are written, truncating the result if necessary.
|
|||
The total amount of space required is returned.
|
||||
If
|
||||
.Fa no_name
|
||||
is 0 and the object has a long or short name, then that will be used,
|
||||
otherwise the numerical form will be used.
|
||||
is 0 and the table object containing the same OID
|
||||
contains a long name, the long name is written.
|
||||
Otherwise, if
|
||||
.Fa no_name
|
||||
is 0 and the table object containing the same OID
|
||||
contains a short name, the short name is written.
|
||||
Otherwise, the numerical representation of the OID is written.
|
||||
.Pp
|
||||
.Fn i2t_ASN1_OBJECT
|
||||
is the same as
|
||||
|
@ -232,18 +253,18 @@ with
|
|||
set to 0.
|
||||
.Pp
|
||||
.Fn i2a_ASN1_OBJECT
|
||||
writes a textual representation of
|
||||
.Fa a
|
||||
writes a textual representation of the OID contained in the given
|
||||
.Fa object
|
||||
to
|
||||
.Fa out_bio
|
||||
using
|
||||
.Xr BIO_write 3 .
|
||||
It does not write a terminating NUL byte.
|
||||
If
|
||||
.Fa a
|
||||
is
|
||||
If the
|
||||
.Fa object
|
||||
argument is
|
||||
.Dv NULL
|
||||
or contains no data, it writes the 4-byte string
|
||||
or contains no OID, it writes the 4-byte string
|
||||
.Qq NULL .
|
||||
If
|
||||
.Fn i2t_ASN1_OBJECT
|
||||
|
@ -255,103 +276,128 @@ Otherwise, it writes the string constructed with
|
|||
.Fn i2t_ASN1_OBJECT .
|
||||
.Pp
|
||||
.Fn OBJ_cmp
|
||||
compares
|
||||
tests whether
|
||||
.Fa a
|
||||
to
|
||||
.Fa b .
|
||||
If the two are identical, 0 is returned.
|
||||
and
|
||||
.Fa b
|
||||
represent the same ASN.1
|
||||
.Vt OBJECT IDENTIFIER .
|
||||
Any names and NIDs contained in the two objects are ignored,
|
||||
even if they differ between both objects.
|
||||
.Pp
|
||||
.Fn OBJ_dup
|
||||
returns a deep copy of
|
||||
.Fa o
|
||||
if
|
||||
.Fa o
|
||||
is marked as dynamically allocated.
|
||||
The new object and all data contained in it is marked as dynamically
|
||||
returns a deep copy of the given
|
||||
.Fa object
|
||||
if it is marked as dynamically allocated.
|
||||
The new object and all data contained in it are marked as dynamically
|
||||
allocated.
|
||||
If
|
||||
.Fa o
|
||||
If the given
|
||||
.Fa object
|
||||
is not marked as dynamically allocated,
|
||||
.Fn OBJ_dup
|
||||
just returns
|
||||
.Fa o
|
||||
just returns a pointer to the
|
||||
.Fa object
|
||||
itself.
|
||||
.Pp
|
||||
Objects can have a short name, a long name, and a numerical
|
||||
identifier (NID) associated with them.
|
||||
A standard set of objects is represented in an internal table.
|
||||
The appropriate values are defined in the header file
|
||||
.In openssl/objects.h .
|
||||
.Pp
|
||||
For example, the OID for commonName has the following definitions:
|
||||
.Bd -literal
|
||||
#define SN_commonName "CN"
|
||||
#define LN_commonName "commonName"
|
||||
#define NID_commonName 13
|
||||
.Ed
|
||||
.Pp
|
||||
New objects can be added by calling
|
||||
.Xr OBJ_create 3 .
|
||||
.Pp
|
||||
Table objects have certain advantages over other objects: for example
|
||||
their NIDs can be used in a C language switch statement.
|
||||
They are also static constant structures which are shared: that is there
|
||||
is only a single constant structure for each table object.
|
||||
.Pp
|
||||
Objects which are not in the table have the NID value
|
||||
.Dv NID_undef .
|
||||
.Pp
|
||||
Objects do not need to be in the internal tables to be processed:
|
||||
the functions
|
||||
.Fn OBJ_txt2obj
|
||||
and
|
||||
.Fn OBJ_obj2txt
|
||||
can process the numerical form of an OID.
|
||||
.Sh RETURN VALUES
|
||||
.Fn OBJ_nid2obj ,
|
||||
.Fn OBJ_txt2obj ,
|
||||
and
|
||||
.Fn OBJ_dup
|
||||
return an
|
||||
.Vt ASN1_OBJECT
|
||||
object or
|
||||
Application code should treat all returned values \(em
|
||||
objects, names, and NIDs \(em as constants.
|
||||
.Pp
|
||||
.Fn OBJ_nid2obj
|
||||
returns a pointer to a table object owned by the library or
|
||||
.Dv NULL
|
||||
if an error occurs.
|
||||
if no matching table object is found.
|
||||
.Pp
|
||||
.Fn OBJ_nid2ln
|
||||
and
|
||||
.Fn OBJ_nid2sn
|
||||
return a valid string or
|
||||
return a pointer to a string owned by a table object or
|
||||
.Dv NULL
|
||||
on error.
|
||||
.Pp
|
||||
.Fn OBJ_obj2nid ,
|
||||
.Fn OBJ_ln2nid ,
|
||||
.Fn OBJ_sn2nid ,
|
||||
if no matching table object is found.
|
||||
For
|
||||
.Dv NID_undef ,
|
||||
they return the constant static strings
|
||||
.Qq undefined
|
||||
and
|
||||
.Fn OBJ_txt2nid
|
||||
return a NID or
|
||||
.Qq UNDEF ,
|
||||
respectively.
|
||||
.Pp
|
||||
.Fn OBJ_obj2nid
|
||||
returns an NID on success, or
|
||||
.Dv NID_undef
|
||||
on error.
|
||||
if
|
||||
.Fa object
|
||||
is
|
||||
.Dv NULL ,
|
||||
does not contain an OID,
|
||||
if no table object matching the OID is found,
|
||||
or if the matching object does not contain an NID.
|
||||
.Pp
|
||||
.Fn OBJ_ln2nid
|
||||
and
|
||||
.Fn OBJ_sn2nid
|
||||
return an NID on success or
|
||||
.Dv NID_undef
|
||||
if no matching table object is found
|
||||
or if the matching object does not contain an NID.
|
||||
.Pp
|
||||
.Fn OBJ_txt2nid
|
||||
returns an NID on success or
|
||||
.Dv NID_undef
|
||||
if parsing of
|
||||
.Fa s
|
||||
or memory allocation fails, if no matching table object is found,
|
||||
or if the matching object does not contain an NID.
|
||||
.Pp
|
||||
.Fn OBJ_txt2obj
|
||||
returns a pointer to a table object owned by the library if lookup of
|
||||
.Fa s
|
||||
as a long or short name succeeds.
|
||||
Otherwise, it returns a newly created object,
|
||||
transferring ownership to the caller, or
|
||||
.Dv NULL
|
||||
if parsing of
|
||||
.Fa s
|
||||
or memory allocation fails.
|
||||
.Pp
|
||||
.Fn OBJ_obj2txt
|
||||
and
|
||||
.Fn i2t_ASN1_OBJECT
|
||||
return the amount of space required in bytes,
|
||||
including the terminating NUL byte.
|
||||
.Pp
|
||||
.Fn i2a_ASN1_OBJECT
|
||||
returns the number of bytes written, even if
|
||||
.Fa a
|
||||
is invalid or contains invalid data,
|
||||
but a negative value if memory allocation or a write operation fails.
|
||||
including the terminating NUL byte,
|
||||
or zero if an error occurs before the required space can be calculated,
|
||||
in particular if
|
||||
.Fa buf_len
|
||||
is negative,
|
||||
.Fa object
|
||||
is
|
||||
.Dv NULL
|
||||
or does not contain an OID,
|
||||
or if memory allocation fails.
|
||||
.Pp
|
||||
.Fn OBJ_cmp
|
||||
returns 0 if the contents of
|
||||
.Fa a
|
||||
and
|
||||
.Fa b
|
||||
are identical, or non-zero otherwise.
|
||||
returns 0 if both objects refer to the same OID
|
||||
or neither of them are associated with any OID,
|
||||
or a non-zero value if at least one of them refers to an OID
|
||||
but the other one does not refer to the same OID.
|
||||
.Pp
|
||||
.Fn OBJ_dup
|
||||
returns the pointer to the original
|
||||
.Fa object
|
||||
if it is not marked as dynamically allocated.
|
||||
Otherwise, it returns a newly created object,
|
||||
transferring ownership to the caller, or
|
||||
.Dv NULL
|
||||
if
|
||||
.Fa object
|
||||
is
|
||||
.Dv NULL
|
||||
or memory allocation fails.
|
||||
.Pp
|
||||
.Fn i2a_ASN1_OBJECT
|
||||
returns the number of bytes written, even if the given
|
||||
.Fa object
|
||||
is invalid or contains invalid data,
|
||||
but a negative value if memory allocation or a write operation fails.
|
||||
.Pp
|
||||
In some cases of failure of
|
||||
.Fn OBJ_nid2obj ,
|
||||
|
@ -367,23 +413,23 @@ and
|
|||
the reason can be determined with
|
||||
.Xr ERR_get_error 3 .
|
||||
.Sh EXAMPLES
|
||||
Create an object for
|
||||
Retrieve the object for
|
||||
.Sy commonName :
|
||||
.Bd -literal -offset indent
|
||||
ASN1_OBJECT *o;
|
||||
o = OBJ_nid2obj(NID_commonName);
|
||||
ASN1_OBJECT *object;
|
||||
object = OBJ_nid2obj(NID_commonName);
|
||||
.Ed
|
||||
.Pp
|
||||
Check if an object is
|
||||
Check whether an object contains the OID for
|
||||
.Sy commonName :
|
||||
.Bd -literal -offset indent
|
||||
if (OBJ_obj2nid(obj) == NID_commonName)
|
||||
if (OBJ_obj2nid(object) == NID_commonName)
|
||||
/* Do something */
|
||||
.Ed
|
||||
.Pp
|
||||
Create a new object directly:
|
||||
.Bd -literal -offset indent
|
||||
obj = OBJ_txt2obj("1.2.3.4", 1);
|
||||
object = OBJ_txt2obj("1.2.3.4", 1);
|
||||
.Ed
|
||||
.Sh SEE ALSO
|
||||
.Xr ASN1_OBJECT_new 3 ,
|
||||
|
@ -416,7 +462,52 @@ first appeared in OpenSSL 0.9.2b.
|
|||
first appeared in OpenSSL 0.9.4.
|
||||
Both functions have been available since
|
||||
.Ox 2.6 .
|
||||
.Sh CAVEATS
|
||||
The API contract of
|
||||
.Fn OBJ_txt2obj
|
||||
when called with a
|
||||
.Fa no_name
|
||||
argument of 0 and of
|
||||
.Fn OBJ_dup
|
||||
is scary in so far as the caller cannot find out from the returned
|
||||
object whether it is owned by the library or whether ownership was
|
||||
transferred to the caller.
|
||||
Consequently, it is best practice to assume that ownership of the object
|
||||
may have been transferred and call
|
||||
.Xr ASN1_OBJECT_free 3
|
||||
on the returned object when the caller no longer needs it.
|
||||
In case the library retained ownership of the returned object,
|
||||
.Xr ASN1_OBJECT_free 3
|
||||
has no effect and is harmless.
|
||||
.Pp
|
||||
Objects returned from
|
||||
.Fn OBJ_txt2obj
|
||||
with a
|
||||
.Fa no_name
|
||||
argument of 1 always require
|
||||
.Xr ASN1_OBJECT_free 3
|
||||
to prevent memory leaks.
|
||||
.Pp
|
||||
Objects returned from
|
||||
.Fn OBJ_nid2obj
|
||||
never require
|
||||
.Xr ASN1_OBJECT_free 3 ,
|
||||
but calling it anyway has no effect and is harmless.
|
||||
.Sh BUGS
|
||||
Usually, an object is expected to contain an NID other than
|
||||
.Dv NID_undef
|
||||
if and only if it is a table object.
|
||||
However, this is not an invariant guaranteed by the API.
|
||||
In particular,
|
||||
.Xr ASN1_OBJECT_create 3
|
||||
allows the creation of non-table objects containing bogus NIDs.
|
||||
.Fn OBJ_obj2nid
|
||||
returns such bogus NIDs even though
|
||||
.Fn OBJ_nid2obj
|
||||
cannot use them for retrieval.
|
||||
On top of that, the global table contains one built-in object with an NID of
|
||||
.Dv NID_undef .
|
||||
.Pp
|
||||
.Fn OBJ_obj2txt
|
||||
is awkward and messy to use: it doesn't follow the convention of other
|
||||
OpenSSL functions where the buffer can be set to
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: obj_dat.c,v 1.60 2023/08/17 09:28:43 tb Exp $ */
|
||||
/* $OpenBSD: obj_dat.c,v 1.61 2023/09/05 14:59:00 tb Exp $ */
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
|
@ -208,15 +208,6 @@ added_obj_cmp(const ADDED_OBJ *ca, const ADDED_OBJ *cb)
|
|||
}
|
||||
static IMPLEMENT_LHASH_COMP_FN(added_obj, ADDED_OBJ)
|
||||
|
||||
static int
|
||||
init_added(void)
|
||||
{
|
||||
if (added != NULL)
|
||||
return (1);
|
||||
added = lh_ADDED_OBJ_new();
|
||||
return (added != NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
cleanup1_doall(ADDED_OBJ *a)
|
||||
{
|
||||
|
@ -289,13 +280,16 @@ LCRYPTO_ALIAS(OBJ_new_nid);
|
|||
int
|
||||
OBJ_add_object(const ASN1_OBJECT *obj)
|
||||
{
|
||||
ASN1_OBJECT *o;
|
||||
ASN1_OBJECT *o = NULL;
|
||||
ADDED_OBJ *ao[4] = {NULL, NULL, NULL, NULL}, *aop;
|
||||
int i;
|
||||
|
||||
if (added == NULL)
|
||||
if (!init_added())
|
||||
return (0);
|
||||
added = lh_ADDED_OBJ_new();
|
||||
if (added == NULL)
|
||||
goto err;
|
||||
if (obj == NULL || obj->nid == NID_undef)
|
||||
goto err;
|
||||
if ((o = OBJ_dup(obj)) == NULL)
|
||||
goto err;
|
||||
if (!(ao[ADDED_NID] = malloc(sizeof(ADDED_OBJ))))
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: pfctl_radix.c,v 1.37 2020/01/15 22:31:51 kn Exp $ */
|
||||
/* $OpenBSD: pfctl_radix.c,v 1.38 2023/09/05 15:37:07 robert Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2002 Cedric Berger
|
||||
|
@ -53,7 +53,7 @@
|
|||
|
||||
extern int dev;
|
||||
|
||||
static int pfr_next_token(char buf[], FILE *);
|
||||
static int pfr_next_token(char buf[BUF_SIZE], FILE *);
|
||||
|
||||
|
||||
int
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: frontend.c,v 1.78 2023/04/30 23:46:52 jsg Exp $ */
|
||||
/* $OpenBSD: frontend.c,v 1.79 2023/09/05 15:44:39 florian Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2018 Florian Obser <florian@openbsd.org>
|
||||
|
@ -773,7 +773,7 @@ handle_query(struct pending_query *pq)
|
|||
}
|
||||
|
||||
rcode = parse_edns_from_query_pkt(pq->qbuf, &pq->edns, NULL, NULL,
|
||||
pq->region);
|
||||
NULL, 0, pq->region);
|
||||
if (rcode != LDNS_RCODE_NOERROR) {
|
||||
error_answer(pq, rcode);
|
||||
goto send_answer;
|
||||
|
@ -927,7 +927,7 @@ synthesize_dns64_answer(struct pending_query *pq)
|
|||
rinfo->qdcount, rinfo->ttl, rinfo->prefetch_ttl,
|
||||
rinfo->serve_expired_ttl, rinfo->an_numrrsets,
|
||||
rinfo->ns_numrrsets, rinfo->ar_numrrsets, rinfo->rrset_count,
|
||||
rinfo->security);
|
||||
rinfo->security, rinfo->reason_bogus);
|
||||
|
||||
if (!synth_rinfo)
|
||||
goto srvfail;
|
||||
|
@ -1059,7 +1059,7 @@ resend_dns64_query(struct pending_query *opq)
|
|||
}
|
||||
|
||||
rcode = parse_edns_from_query_pkt(pq->qbuf, &pq->edns, NULL, NULL,
|
||||
pq->region);
|
||||
NULL, 0, pq->region);
|
||||
if (rcode != LDNS_RCODE_NOERROR) {
|
||||
error_answer(pq, rcode);
|
||||
goto send_answer;
|
||||
|
|
|
@ -368,6 +368,9 @@
|
|||
/* Define if we have LibreSSL */
|
||||
#define HAVE_LIBRESSL 1
|
||||
|
||||
/* Define to 1 if you have the <linux/net_tstamp.h> header file. */
|
||||
/* #undef HAVE_LINUX_NET_TSTAMP_H */
|
||||
|
||||
/* Define to 1 if you have the `localtime_r' function. */
|
||||
#define HAVE_LOCALTIME_R 1
|
||||
|
||||
|
@ -773,7 +776,7 @@
|
|||
#define PACKAGE_NAME "unbound"
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#define PACKAGE_STRING "unbound 1.17.0"
|
||||
#define PACKAGE_STRING "unbound 1.18.0"
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#define PACKAGE_TARNAME "unbound"
|
||||
|
@ -782,7 +785,7 @@
|
|||
#define PACKAGE_URL ""
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#define PACKAGE_VERSION "1.17.0"
|
||||
#define PACKAGE_VERSION "1.18.0"
|
||||
|
||||
/* default pidfile location */
|
||||
#define PIDFILE ""
|
||||
|
@ -805,7 +808,7 @@
|
|||
#define ROOT_CERT_FILE "/var/unbound/etc/icannbundle.pem"
|
||||
|
||||
/* version number for resource files */
|
||||
#define RSRC_PACKAGE_VERSION 1,17,0,0
|
||||
#define RSRC_PACKAGE_VERSION 1,18,0,0
|
||||
|
||||
/* Directory to chdir to */
|
||||
#define RUN_DIR "/var/unbound/etc"
|
||||
|
|
|
@ -64,8 +64,12 @@ enum acl_access {
|
|||
acl_allow,
|
||||
/** allow full access for all queries, recursion and cache snooping */
|
||||
acl_allow_snoop,
|
||||
/** allow full access for recursion queries and set RD flag regardless of request */
|
||||
acl_allow_setrd
|
||||
/** allow full access for recursion queries and set RD flag regardless
|
||||
* of request */
|
||||
acl_allow_setrd,
|
||||
/** allow full access for recursion (+RD) queries if valid cookie
|
||||
* present or stateful transport */
|
||||
acl_allow_cookie
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -126,4 +126,11 @@ void server_stats_insquery(struct ub_server_stats* stats, struct comm_point* c,
|
|||
*/
|
||||
void server_stats_insrcode(struct ub_server_stats* stats, struct sldns_buffer* buf);
|
||||
|
||||
/**
|
||||
* Add DNS Cookie stats for this query
|
||||
* @param stats: the stats
|
||||
* @param edns: edns record
|
||||
*/
|
||||
void server_stats_downstream_cookie(struct ub_server_stats* stats,
|
||||
struct edns_data* edns);
|
||||
#endif /* DAEMON_STATS_H */
|
||||
|
|
|
@ -118,7 +118,7 @@ struct worker {
|
|||
/** do we need to restart or quit (on signal) */
|
||||
int need_to_exit;
|
||||
/** allocation cache for this thread */
|
||||
struct alloc_cache alloc;
|
||||
struct alloc_cache *alloc;
|
||||
/** per thread statistics */
|
||||
struct ub_server_stats stats;
|
||||
/** thread scratch regional */
|
||||
|
@ -131,6 +131,8 @@ struct worker {
|
|||
/** dnstap environment, changed for this thread */
|
||||
struct dt_env dtenv;
|
||||
#endif
|
||||
/** reuse existing cache on reload if other conditions allow it. */
|
||||
int reuse_cache;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -59,7 +59,7 @@
|
|||
******************************************************************************/
|
||||
|
||||
/**
|
||||
* This is the default DNS64 prefix that is used whent he dns64 module is listed
|
||||
* This is the default DNS64 prefix that is used when the dns64 module is listed
|
||||
* in module-config but when the dns64-prefix variable is not present.
|
||||
*/
|
||||
static const char DEFAULT_DNS64_PREFIX[] = "64:ff9b::/96";
|
||||
|
@ -841,7 +841,7 @@ dns64_adjust_a(int id, struct module_qstate* super, struct module_qstate* qstate
|
|||
cp = construct_reply_info_base(super->region, rep->flags, rep->qdcount,
|
||||
rep->ttl, rep->prefetch_ttl, rep->serve_expired_ttl,
|
||||
rep->an_numrrsets, rep->ns_numrrsets, rep->ar_numrrsets,
|
||||
rep->rrset_count, rep->security);
|
||||
rep->rrset_count, rep->security, LDNS_EDE_NONE);
|
||||
if(!cp)
|
||||
return;
|
||||
|
||||
|
|
|
@ -126,13 +126,15 @@ dt_delete(struct dt_env *env);
|
|||
* @param rsock: local (service) address/port.
|
||||
* @param cptype: comm_udp or comm_tcp.
|
||||
* @param qmsg: query message.
|
||||
* @param tstamp: timestamp or NULL if none provided.
|
||||
*/
|
||||
void
|
||||
dt_msg_send_client_query(struct dt_env *env,
|
||||
struct sockaddr_storage *qsock,
|
||||
struct sockaddr_storage *rsock,
|
||||
enum comm_point_type cptype,
|
||||
struct sldns_buffer *qmsg);
|
||||
struct sldns_buffer *qmsg,
|
||||
struct timeval* tstamp);
|
||||
|
||||
/**
|
||||
* Create and send a new dnstap "Message" event of type CLIENT_RESPONSE.
|
||||
|
|
|
@ -321,6 +321,45 @@ void delegpt_log(enum verbosity_value v, struct delegpt* dp)
|
|||
}
|
||||
}
|
||||
|
||||
int
|
||||
delegpt_addr_on_result_list(struct delegpt* dp, struct delegpt_addr* find)
|
||||
{
|
||||
struct delegpt_addr* a = dp->result_list;
|
||||
while(a) {
|
||||
if(a == find)
|
||||
return 1;
|
||||
a = a->next_result;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
delegpt_usable_list_remove_addr(struct delegpt* dp, struct delegpt_addr* del)
|
||||
{
|
||||
struct delegpt_addr* usa = dp->usable_list, *prev = NULL;
|
||||
while(usa) {
|
||||
if(usa == del) {
|
||||
/* snip off the usable list */
|
||||
if(prev)
|
||||
prev->next_usable = usa->next_usable;
|
||||
else dp->usable_list = usa->next_usable;
|
||||
return;
|
||||
}
|
||||
prev = usa;
|
||||
usa = usa->next_usable;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
delegpt_add_to_result_list(struct delegpt* dp, struct delegpt_addr* a)
|
||||
{
|
||||
if(delegpt_addr_on_result_list(dp, a))
|
||||
return;
|
||||
delegpt_usable_list_remove_addr(dp, a);
|
||||
a->next_result = dp->result_list;
|
||||
dp->result_list = a;
|
||||
}
|
||||
|
||||
void
|
||||
delegpt_add_unused_targets(struct delegpt* dp)
|
||||
{
|
||||
|
|
|
@ -457,4 +457,29 @@ int delegpt_add_target_mlc(struct delegpt* dp, uint8_t* name, size_t namelen,
|
|||
/** get memory in use by dp */
|
||||
size_t delegpt_get_mem(struct delegpt* dp);
|
||||
|
||||
/**
|
||||
* See if the addr is on the result list.
|
||||
* @param dp: delegation point.
|
||||
* @param find: the pointer is searched for on the result list.
|
||||
* @return 1 if found, 0 if not found.
|
||||
*/
|
||||
int delegpt_addr_on_result_list(struct delegpt* dp, struct delegpt_addr* find);
|
||||
|
||||
/**
|
||||
* Remove the addr from the usable list.
|
||||
* @param dp: the delegation point.
|
||||
* @param del: the addr to remove from the list, the pointer is searched for.
|
||||
*/
|
||||
void delegpt_usable_list_remove_addr(struct delegpt* dp,
|
||||
struct delegpt_addr* del);
|
||||
|
||||
/**
|
||||
* Add the delegpt_addr back to the result list, if it is not already on
|
||||
* the result list. Also removes it from the usable list.
|
||||
* @param dp: delegation point.
|
||||
* @param a: addr to add, nothing happens if it is already on the result list.
|
||||
* It is removed from the usable list.
|
||||
*/
|
||||
void delegpt_add_to_result_list(struct delegpt* dp, struct delegpt_addr* a);
|
||||
|
||||
#endif /* ITERATOR_ITER_DELEGPT_H */
|
||||
|
|
|
@ -284,6 +284,13 @@ response_type_from_server(int rdset,
|
|||
|
||||
/* If we've gotten this far, this is NOERROR/NODATA (which could
|
||||
* be an entirely empty message) */
|
||||
/* but ignore entirely empty messages, noerror/nodata has a soa
|
||||
* negative ttl value in the authority section, this makes it try
|
||||
* again at another authority. And turns it from a 5 second empty
|
||||
* message into a 5 second servfail response. */
|
||||
if(msg->rep->an_numrrsets == 0 && msg->rep->ns_numrrsets == 0 &&
|
||||
msg->rep->ar_numrrsets == 0)
|
||||
return RESPONSE_TYPE_THROWAWAY;
|
||||
/* check if recursive answer; saying it has empty cache */
|
||||
if( (msg->rep->flags&BIT_RA) && !(msg->rep->flags&BIT_AA) && !rdset)
|
||||
return RESPONSE_TYPE_REC_LAME;
|
||||
|
|
|
@ -346,6 +346,26 @@ soa_in_auth(struct msg_parse* msg)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/** Check if type is allowed in the authority section */
|
||||
static int
|
||||
type_allowed_in_authority_section(uint16_t tp)
|
||||
{
|
||||
if(tp == LDNS_RR_TYPE_SOA || tp == LDNS_RR_TYPE_NS ||
|
||||
tp == LDNS_RR_TYPE_DS || tp == LDNS_RR_TYPE_NSEC ||
|
||||
tp == LDNS_RR_TYPE_NSEC3)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Check if type is allowed in the additional section */
|
||||
static int
|
||||
type_allowed_in_additional_section(uint16_t tp)
|
||||
{
|
||||
if(tp == LDNS_RR_TYPE_A || tp == LDNS_RR_TYPE_AAAA)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* This routine normalizes a response. This includes removing "irrelevant"
|
||||
* records from the answer and additional sections and (re)synthesizing
|
||||
|
@ -355,11 +375,13 @@ soa_in_auth(struct msg_parse* msg)
|
|||
* @param msg: msg to normalize.
|
||||
* @param qinfo: original query.
|
||||
* @param region: where to allocate synthesized CNAMEs.
|
||||
* @param env: module env with config options.
|
||||
* @return 0 on error.
|
||||
*/
|
||||
static int
|
||||
scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
|
||||
struct query_info* qinfo, struct regional* region)
|
||||
struct query_info* qinfo, struct regional* region,
|
||||
struct module_env* env)
|
||||
{
|
||||
uint8_t* sname = qinfo->qname;
|
||||
size_t snamelen = qinfo->qname_len;
|
||||
|
@ -511,6 +533,7 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
|
|||
|
||||
/* Mark additional names from AUTHORITY */
|
||||
while(rrset && rrset->section == LDNS_SECTION_AUTHORITY) {
|
||||
/* protect internals of recursor by making sure to del these */
|
||||
if(rrset->type==LDNS_RR_TYPE_DNAME ||
|
||||
rrset->type==LDNS_RR_TYPE_CNAME ||
|
||||
rrset->type==LDNS_RR_TYPE_A ||
|
||||
|
@ -519,6 +542,13 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
|
|||
"RRset:", pkt, msg, prev, &rrset);
|
||||
continue;
|
||||
}
|
||||
/* Allowed list of types in the authority section */
|
||||
if(env->cfg->harden_unknown_additional &&
|
||||
!type_allowed_in_authority_section(rrset->type)) {
|
||||
remove_rrset("normalize: removing irrelevant "
|
||||
"RRset:", pkt, msg, prev, &rrset);
|
||||
continue;
|
||||
}
|
||||
/* only one NS set allowed in authority section */
|
||||
if(rrset->type==LDNS_RR_TYPE_NS) {
|
||||
/* NS set must be pertinent to the query */
|
||||
|
@ -576,7 +606,6 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
|
|||
* found in ANSWER and AUTHORITY. */
|
||||
/* These records have not been marked OK previously */
|
||||
while(rrset && rrset->section == LDNS_SECTION_ADDITIONAL) {
|
||||
/* FIXME: what about other types? */
|
||||
if(rrset->type==LDNS_RR_TYPE_A ||
|
||||
rrset->type==LDNS_RR_TYPE_AAAA)
|
||||
{
|
||||
|
@ -589,6 +618,7 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
|
|||
continue;
|
||||
}
|
||||
}
|
||||
/* protect internals of recursor by making sure to del these */
|
||||
if(rrset->type==LDNS_RR_TYPE_DNAME ||
|
||||
rrset->type==LDNS_RR_TYPE_CNAME ||
|
||||
rrset->type==LDNS_RR_TYPE_NS) {
|
||||
|
@ -596,6 +626,13 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
|
|||
"RRset:", pkt, msg, prev, &rrset);
|
||||
continue;
|
||||
}
|
||||
/* Allowed list of types in the additional section */
|
||||
if(env->cfg->harden_unknown_additional &&
|
||||
!type_allowed_in_additional_section(rrset->type)) {
|
||||
remove_rrset("normalize: removing irrelevant "
|
||||
"RRset:", pkt, msg, prev, &rrset);
|
||||
continue;
|
||||
}
|
||||
prev = rrset;
|
||||
rrset = rrset->rrset_all_next;
|
||||
}
|
||||
|
@ -846,7 +883,7 @@ scrub_message(sldns_buffer* pkt, struct msg_parse* msg,
|
|||
}
|
||||
|
||||
/* normalize the response, this cleans up the additional. */
|
||||
if(!scrub_normalize(pkt, msg, qinfo, region))
|
||||
if(!scrub_normalize(pkt, msg, qinfo, region, env))
|
||||
return 0;
|
||||
/* delete all out-of-zone information */
|
||||
if(!scrub_sanitize(pkt, msg, qinfo, zonename, env, ie))
|
||||
|
|
|
@ -71,6 +71,11 @@
|
|||
/** time when nameserver glue is said to be 'recent' */
|
||||
#define SUSPICION_RECENT_EXPIRY 86400
|
||||
|
||||
/** if NAT64 is enabled and no NAT64 prefix is configured, first fall back to
|
||||
* DNS64 prefix. If that is not configured, fall back to this default value.
|
||||
*/
|
||||
static const char DEFAULT_NAT64_PREFIX[] = "64:ff9b::/96";
|
||||
|
||||
/** fillup fetch policy array */
|
||||
static void
|
||||
fetch_fill(struct iter_env* ie, const char* str)
|
||||
|
@ -142,6 +147,7 @@ caps_white_apply_cfg(rbtree_type* ntree, struct config_file* cfg)
|
|||
int
|
||||
iter_apply_cfg(struct iter_env* iter_env, struct config_file* cfg)
|
||||
{
|
||||
const char *nat64_prefix;
|
||||
int i;
|
||||
/* target fetch policy */
|
||||
if(!read_fetch_policy(iter_env, cfg->target_fetch_policy))
|
||||
|
@ -172,9 +178,35 @@ iter_apply_cfg(struct iter_env* iter_env, struct config_file* cfg)
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
nat64_prefix = cfg->nat64_prefix;
|
||||
if(!nat64_prefix)
|
||||
nat64_prefix = cfg->dns64_prefix;
|
||||
if(!nat64_prefix)
|
||||
nat64_prefix = DEFAULT_NAT64_PREFIX;
|
||||
if(!netblockstrtoaddr(nat64_prefix, 0, &iter_env->nat64_prefix_addr,
|
||||
&iter_env->nat64_prefix_addrlen,
|
||||
&iter_env->nat64_prefix_net)) {
|
||||
log_err("cannot parse nat64-prefix netblock: %s", nat64_prefix);
|
||||
return 0;
|
||||
}
|
||||
if(!addr_is_ip6(&iter_env->nat64_prefix_addr,
|
||||
iter_env->nat64_prefix_addrlen)) {
|
||||
log_err("nat64-prefix is not IPv6: %s", cfg->nat64_prefix);
|
||||
return 0;
|
||||
}
|
||||
if(!prefixnet_is_nat64(iter_env->nat64_prefix_net)) {
|
||||
log_err("nat64-prefix length it not 32, 40, 48, 56, 64 or 96: %s",
|
||||
nat64_prefix);
|
||||
return 0;
|
||||
}
|
||||
|
||||
iter_env->supports_ipv6 = cfg->do_ip6;
|
||||
iter_env->supports_ipv4 = cfg->do_ip4;
|
||||
iter_env->use_nat64 = cfg->do_nat64;
|
||||
iter_env->outbound_msg_retry = cfg->outbound_msg_retry;
|
||||
iter_env->max_sent_count = cfg->max_sent_count;
|
||||
iter_env->max_query_restarts = cfg->max_query_restarts;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -238,7 +270,8 @@ iter_filter_unsuitable(struct iter_env* iter_env, struct module_env* env,
|
|||
if(!iter_env->supports_ipv6 && addr_is_ip6(&a->addr, a->addrlen)) {
|
||||
return -1; /* there is no ip6 available */
|
||||
}
|
||||
if(!iter_env->supports_ipv4 && !addr_is_ip6(&a->addr, a->addrlen)) {
|
||||
if(!iter_env->supports_ipv4 && !iter_env->use_nat64 &&
|
||||
!addr_is_ip6(&a->addr, a->addrlen)) {
|
||||
return -1; /* there is no ip4 available */
|
||||
}
|
||||
/* check lameness - need zone , class info */
|
||||
|
@ -745,10 +778,15 @@ iter_mark_pside_cycle_targets(struct module_qstate* qstate, struct delegpt* dp)
|
|||
|
||||
int
|
||||
iter_dp_is_useless(struct query_info* qinfo, uint16_t qflags,
|
||||
struct delegpt* dp, int supports_ipv4, int supports_ipv6)
|
||||
struct delegpt* dp, int supports_ipv4, int supports_ipv6,
|
||||
int use_nat64)
|
||||
{
|
||||
struct delegpt_ns* ns;
|
||||
struct delegpt_addr* a;
|
||||
|
||||
if(supports_ipv6 && use_nat64)
|
||||
supports_ipv4 = 1;
|
||||
|
||||
/* check:
|
||||
* o RD qflag is on.
|
||||
* o no addresses are provided.
|
||||
|
@ -1308,8 +1346,7 @@ void iter_dec_attempts(struct delegpt* dp, int d, int outbound_msg_retry)
|
|||
for(a=dp->target_list; a; a = a->next_target) {
|
||||
if(a->attempts >= outbound_msg_retry) {
|
||||
/* add back to result list */
|
||||
a->next_result = dp->result_list;
|
||||
dp->result_list = a;
|
||||
delegpt_add_to_result_list(dp, a);
|
||||
}
|
||||
if(a->attempts > d)
|
||||
a->attempts -= d;
|
||||
|
|
|
@ -189,10 +189,13 @@ void iter_mark_pside_cycle_targets(struct module_qstate* qstate,
|
|||
* if not, then the IPv4 addresses are useless.
|
||||
* @param supports_ipv6: if we support ipv6 for lookups to the target.
|
||||
* if not, then the IPv6 addresses are useless.
|
||||
* @param use_nat64: if we support NAT64 for lookups to the target.
|
||||
* if yes, IPv4 addresses are useful even if we don't support IPv4.
|
||||
* @return true if dp is useless.
|
||||
*/
|
||||
int iter_dp_is_useless(struct query_info* qinfo, uint16_t qflags,
|
||||
struct delegpt* dp, int supports_ipv4, int supports_ipv6);
|
||||
struct delegpt* dp, int supports_ipv4, int supports_ipv6,
|
||||
int use_nat64);
|
||||
|
||||
/**
|
||||
* See if qname has DNSSEC needs. This is true if there is a trust anchor above
|
||||
|
|
|
@ -255,7 +255,7 @@ error_supers(struct module_qstate* qstate, int id, struct module_qstate* super)
|
|||
log_err("out of memory adding missing");
|
||||
}
|
||||
delegpt_mark_neg(dpns, qstate->qinfo.qtype);
|
||||
if((dpns->got4 == 2 || !ie->supports_ipv4) &&
|
||||
if((dpns->got4 == 2 || (!ie->supports_ipv4 && !ie->use_nat64)) &&
|
||||
(dpns->got6 == 2 || !ie->supports_ipv6)) {
|
||||
dpns->resolved = 1; /* mark as failed */
|
||||
target_count_increase_nx(super_iq, 1);
|
||||
|
@ -302,9 +302,11 @@ error_response(struct module_qstate* qstate, int id, int rcode)
|
|||
static int
|
||||
error_response_cache(struct module_qstate* qstate, int id, int rcode)
|
||||
{
|
||||
if(!qstate->no_cache_store) {
|
||||
/* store in cache */
|
||||
struct reply_info err;
|
||||
struct msgreply_entry* msg;
|
||||
if(qstate->no_cache_store) {
|
||||
return error_response(qstate, id, rcode);
|
||||
}
|
||||
if(qstate->prefetch_leeway > NORR_TTL) {
|
||||
verbose(VERB_ALGO, "error response for prefetch in cache");
|
||||
/* attempt to adjust the cache entry prefetch */
|
||||
|
@ -313,57 +315,40 @@ error_response_cache(struct module_qstate* qstate, int id, int rcode)
|
|||
return error_response(qstate, id, rcode);
|
||||
/* if that fails (not in cache), fall through to store err */
|
||||
}
|
||||
if(qstate->env->cfg->serve_expired) {
|
||||
/* if serving expired contents, and such content is
|
||||
* already available, don't overwrite this servfail */
|
||||
struct msgreply_entry* msg;
|
||||
if((msg=msg_cache_lookup(qstate->env,
|
||||
qstate->qinfo.qname, qstate->qinfo.qname_len,
|
||||
qstate->qinfo.qtype, qstate->qinfo.qclass,
|
||||
qstate->query_flags, 0,
|
||||
qstate->env->cfg->serve_expired_ttl_reset))
|
||||
!= NULL) {
|
||||
if(qstate->env->cfg->serve_expired_ttl_reset) {
|
||||
struct reply_info* rep =
|
||||
(struct reply_info*)msg->entry.data;
|
||||
if(rep && *qstate->env->now +
|
||||
qstate->env->cfg->serve_expired_ttl >
|
||||
rep->serve_expired_ttl) {
|
||||
rep->serve_expired_ttl =
|
||||
*qstate->env->now +
|
||||
qstate->env->cfg->serve_expired_ttl_reset)) != NULL) {
|
||||
struct reply_info* rep = (struct reply_info*)msg->entry.data;
|
||||
if(qstate->env->cfg->serve_expired &&
|
||||
qstate->env->cfg->serve_expired_ttl_reset && rep &&
|
||||
*qstate->env->now + qstate->env->cfg->serve_expired_ttl
|
||||
> rep->serve_expired_ttl) {
|
||||
verbose(VERB_ALGO, "reset serve-expired-ttl for "
|
||||
"response in cache");
|
||||
rep->serve_expired_ttl = *qstate->env->now +
|
||||
qstate->env->cfg->serve_expired_ttl;
|
||||
}
|
||||
}
|
||||
lock_rw_unlock(&msg->entry.lock);
|
||||
return error_response(qstate, id, rcode);
|
||||
}
|
||||
/* serving expired contents, but nothing is cached
|
||||
* at all, so the servfail cache entry is useful
|
||||
* (stops waste of time on this servfail NORR_TTL) */
|
||||
} else {
|
||||
/* don't overwrite existing (non-expired) data in
|
||||
* cache with a servfail */
|
||||
struct msgreply_entry* msg;
|
||||
if((msg=msg_cache_lookup(qstate->env,
|
||||
qstate->qinfo.qname, qstate->qinfo.qname_len,
|
||||
qstate->qinfo.qtype, qstate->qinfo.qclass,
|
||||
qstate->query_flags, *qstate->env->now, 0))
|
||||
!= NULL) {
|
||||
struct reply_info* rep = (struct reply_info*)
|
||||
msg->entry.data;
|
||||
if(FLAGS_GET_RCODE(rep->flags) ==
|
||||
if(rep && (FLAGS_GET_RCODE(rep->flags) ==
|
||||
LDNS_RCODE_NOERROR ||
|
||||
FLAGS_GET_RCODE(rep->flags) ==
|
||||
LDNS_RCODE_NXDOMAIN) {
|
||||
/* we have a good entry,
|
||||
* don't overwrite */
|
||||
LDNS_RCODE_NXDOMAIN ||
|
||||
FLAGS_GET_RCODE(rep->flags) ==
|
||||
LDNS_RCODE_YXDOMAIN) &&
|
||||
(qstate->env->cfg->serve_expired ||
|
||||
*qstate->env->now <= rep->ttl)) {
|
||||
/* we have a good entry, don't overwrite */
|
||||
lock_rw_unlock(&msg->entry.lock);
|
||||
return error_response(qstate, id, rcode);
|
||||
}
|
||||
lock_rw_unlock(&msg->entry.lock);
|
||||
/* nothing interesting is cached (already error response or
|
||||
* expired good record when we don't serve expired), so this
|
||||
* servfail cache entry is useful (stops waste of time on this
|
||||
* servfail NORR_TTL) */
|
||||
}
|
||||
|
||||
}
|
||||
/* store in cache */
|
||||
memset(&err, 0, sizeof(err));
|
||||
err.flags = (uint16_t)(BIT_QR | BIT_RA);
|
||||
FLAGS_SET_RCODE(err.flags, rcode);
|
||||
|
@ -376,7 +361,6 @@ error_response_cache(struct module_qstate* qstate, int id, int rcode)
|
|||
verbose(VERB_ALGO, "store error response in message cache");
|
||||
iter_dns_store(qstate->env, &qstate->qinfo, &err, 0, 0, 0, NULL,
|
||||
qstate->query_flags, qstate->qstarttime);
|
||||
}
|
||||
return error_response(qstate, id, rcode);
|
||||
}
|
||||
|
||||
|
@ -590,6 +574,54 @@ handle_cname_response(struct module_qstate* qstate, struct iter_qstate* iq,
|
|||
return 1;
|
||||
}
|
||||
|
||||
/** fill fail address for later recovery */
|
||||
static void
|
||||
fill_fail_addr(struct iter_qstate* iq, struct sockaddr_storage* addr,
|
||||
socklen_t addrlen)
|
||||
{
|
||||
if(addrlen == 0) {
|
||||
iq->fail_addr_type = 0;
|
||||
return;
|
||||
}
|
||||
if(((struct sockaddr_in*)addr)->sin_family == AF_INET) {
|
||||
iq->fail_addr_type = 4;
|
||||
memcpy(&iq->fail_addr.in,
|
||||
&((struct sockaddr_in*)addr)->sin_addr,
|
||||
sizeof(iq->fail_addr.in));
|
||||
}
|
||||
#ifdef AF_INET6
|
||||
else if(((struct sockaddr_in*)addr)->sin_family == AF_INET6) {
|
||||
iq->fail_addr_type = 6;
|
||||
memcpy(&iq->fail_addr.in6,
|
||||
&((struct sockaddr_in6*)addr)->sin6_addr,
|
||||
sizeof(iq->fail_addr.in6));
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
iq->fail_addr_type = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/** print fail addr to string */
|
||||
static void
|
||||
print_fail_addr(struct iter_qstate* iq, char* buf, size_t len)
|
||||
{
|
||||
if(iq->fail_addr_type == 4) {
|
||||
if(inet_ntop(AF_INET, &iq->fail_addr.in, buf,
|
||||
(socklen_t)len) == 0)
|
||||
(void)strlcpy(buf, "(inet_ntop error)", len);
|
||||
}
|
||||
#ifdef AF_INET6
|
||||
else if(iq->fail_addr_type == 6) {
|
||||
if(inet_ntop(AF_INET6, &iq->fail_addr.in6, buf,
|
||||
(socklen_t)len) == 0)
|
||||
(void)strlcpy(buf, "(inet_ntop error)", len);
|
||||
}
|
||||
#endif
|
||||
else
|
||||
(void)strlcpy(buf, "", len);
|
||||
}
|
||||
|
||||
/** add response specific error information for log servfail */
|
||||
static void
|
||||
errinf_reply(struct module_qstate* qstate, struct iter_qstate* iq)
|
||||
|
@ -597,16 +629,14 @@ errinf_reply(struct module_qstate* qstate, struct iter_qstate* iq)
|
|||
if(qstate->env->cfg->val_log_level < 2 && !qstate->env->cfg->log_servfail)
|
||||
return;
|
||||
if((qstate->reply && qstate->reply->remote_addrlen != 0) ||
|
||||
(iq->fail_reply && iq->fail_reply->remote_addrlen != 0)) {
|
||||
(iq->fail_addr_type != 0)) {
|
||||
char from[256], frm[512];
|
||||
if(qstate->reply && qstate->reply->remote_addrlen != 0)
|
||||
addr_to_str(&qstate->reply->remote_addr,
|
||||
qstate->reply->remote_addrlen, from,
|
||||
sizeof(from));
|
||||
else
|
||||
addr_to_str(&iq->fail_reply->remote_addr,
|
||||
iq->fail_reply->remote_addrlen, from,
|
||||
sizeof(from));
|
||||
print_fail_addr(iq, from, sizeof(from));
|
||||
snprintf(frm, sizeof(frm), "from %s", from);
|
||||
errinf(qstate, frm);
|
||||
}
|
||||
|
@ -1137,7 +1167,7 @@ generate_a_aaaa_check(struct module_qstate* qstate, struct iter_qstate* iq,
|
|||
* Generate a NS check request to obtain authoritative information
|
||||
* on an NS rrset.
|
||||
*
|
||||
* @param qstate: the qtstate that triggered the need to prime.
|
||||
* @param qstate: the qstate that triggered the need to prime.
|
||||
* @param iq: iterator query state.
|
||||
* @param id: module id.
|
||||
*/
|
||||
|
@ -1314,7 +1344,7 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
|
|||
|
||||
/* We enforce a maximum number of query restarts. This is primarily a
|
||||
* cheap way to prevent CNAME loops. */
|
||||
if(iq->query_restart_count > MAX_RESTART_COUNT) {
|
||||
if(iq->query_restart_count > ie->max_query_restarts) {
|
||||
verbose(VERB_QUERY, "request has exceeded the maximum number"
|
||||
" of query restarts with %d", iq->query_restart_count);
|
||||
errinf(qstate, "request has exceeded the maximum number "
|
||||
|
@ -1451,6 +1481,19 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
|
|||
errinf(qstate, "malloc failure for forward zone");
|
||||
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
if((qstate->query_flags&BIT_RD)==0) {
|
||||
/* If the server accepts RD=0 queries and forwards
|
||||
* with RD=1, then if the server is listed as an NS
|
||||
* entry, it starts query loops. Stop that loop by
|
||||
* disallowing the query. The RD=0 was previously used
|
||||
* to check the cache with allow_snoop. For stubs,
|
||||
* the iterator pass would have primed the stub and
|
||||
* then cached information can be used for further
|
||||
* queries. */
|
||||
verbose(VERB_ALGO, "cannot forward RD=0 query, to stop query loops");
|
||||
errinf(qstate, "cannot forward RD=0 query");
|
||||
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
iq->refetch_glue = 0;
|
||||
iq->minimisation_state = DONOT_MINIMISE_STATE;
|
||||
/* the request has been forwarded.
|
||||
|
@ -1571,7 +1614,8 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
|
|||
* same server reply) if useless-checked.
|
||||
*/
|
||||
if(iter_dp_is_useless(&qstate->qinfo, qstate->query_flags,
|
||||
iq->dp, ie->supports_ipv4, ie->supports_ipv6)) {
|
||||
iq->dp, ie->supports_ipv4, ie->supports_ipv6,
|
||||
ie->use_nat64)) {
|
||||
struct delegpt* retdp = NULL;
|
||||
if(!can_have_last_resort(qstate->env, iq->dp->name, iq->dp->namelen, iq->qchase.qclass, &retdp)) {
|
||||
if(retdp) {
|
||||
|
@ -1932,7 +1976,7 @@ query_for_targets(struct module_qstate* qstate, struct iter_qstate* iq,
|
|||
break;
|
||||
}
|
||||
/* Send the A request. */
|
||||
if(ie->supports_ipv4 &&
|
||||
if((ie->supports_ipv4 || ie->use_nat64) &&
|
||||
((ns->lame && !ns->done_pside4) ||
|
||||
(!ns->lame && !ns->got4))) {
|
||||
if(!generate_target_query(qstate, iq, id,
|
||||
|
@ -2085,14 +2129,14 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq,
|
|||
/* if this nameserver is at a delegation point, but that
|
||||
* delegation point is a stub and we cannot go higher, skip*/
|
||||
if( ((ie->supports_ipv6 && !ns->done_pside6) ||
|
||||
(ie->supports_ipv4 && !ns->done_pside4)) &&
|
||||
((ie->supports_ipv4 || ie->use_nat64) && !ns->done_pside4)) &&
|
||||
!can_have_last_resort(qstate->env, ns->name, ns->namelen,
|
||||
iq->qchase.qclass, NULL)) {
|
||||
log_nametypeclass(VERB_ALGO, "cannot pside lookup ns "
|
||||
"because it is also a stub/forward,",
|
||||
ns->name, LDNS_RR_TYPE_NS, iq->qchase.qclass);
|
||||
if(ie->supports_ipv6) ns->done_pside6 = 1;
|
||||
if(ie->supports_ipv4) ns->done_pside4 = 1;
|
||||
if(ie->supports_ipv4 || ie->use_nat64) ns->done_pside4 = 1;
|
||||
continue;
|
||||
}
|
||||
/* query for parent-side A and AAAA for nameservers */
|
||||
|
@ -2117,7 +2161,7 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq,
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
if(ie->supports_ipv4 && !ns->done_pside4) {
|
||||
if((ie->supports_ipv4 || ie->use_nat64) && !ns->done_pside4) {
|
||||
/* Send the A request. */
|
||||
if(!generate_parentside_target_query(qstate, iq, id,
|
||||
ns->name, ns->namelen,
|
||||
|
@ -2259,6 +2303,8 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
|||
int tf_policy;
|
||||
struct delegpt_addr* target;
|
||||
struct outbound_entry* outq;
|
||||
struct sockaddr_storage real_addr;
|
||||
socklen_t real_addrlen;
|
||||
int auth_fallback = 0;
|
||||
uint8_t* qout_orig = NULL;
|
||||
size_t qout_orig_len = 0;
|
||||
|
@ -2276,14 +2322,13 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
|||
iq->num_current_queries, iq->sent_count);
|
||||
|
||||
/* Make sure that we haven't run away */
|
||||
/* FIXME: is this check even necessary? */
|
||||
if(iq->referral_count > MAX_REFERRAL_COUNT) {
|
||||
verbose(VERB_QUERY, "request has exceeded the maximum "
|
||||
"number of referrrals with %d", iq->referral_count);
|
||||
errinf(qstate, "exceeded the maximum of referrals");
|
||||
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
if(iq->sent_count > MAX_SENT_COUNT) {
|
||||
if(iq->sent_count > ie->max_sent_count) {
|
||||
verbose(VERB_QUERY, "request has exceeded the maximum "
|
||||
"number of sends with %d", iq->sent_count);
|
||||
errinf(qstate, "exceeded the maximum number of sends");
|
||||
|
@ -2385,7 +2430,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
|||
}
|
||||
if(!ie->supports_ipv6)
|
||||
delegpt_no_ipv6(iq->dp);
|
||||
if(!ie->supports_ipv4)
|
||||
if(!ie->supports_ipv4 && !ie->use_nat64)
|
||||
delegpt_no_ipv4(iq->dp);
|
||||
delegpt_log(VERB_ALGO, iq->dp);
|
||||
|
||||
|
@ -2630,7 +2675,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
|||
* the original query is one that matched too, so we have
|
||||
* caps_server+1 number of matching queries now */
|
||||
if(iq->caps_server+1 >= naddr*3 ||
|
||||
iq->caps_server*2+2 >= MAX_SENT_COUNT) {
|
||||
iq->caps_server*2+2 >= (size_t)ie->max_sent_count) {
|
||||
/* *2 on sentcount check because ipv6 may fail */
|
||||
/* we're done, process the response */
|
||||
verbose(VERB_ALGO, "0x20 fallback had %d responses "
|
||||
|
@ -2812,6 +2857,18 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
|||
iq->dnssec_expected?"expected": "not expected",
|
||||
iq->dnssec_lame_query?" but lame_query anyway": "");
|
||||
}
|
||||
|
||||
real_addr = target->addr;
|
||||
real_addrlen = target->addrlen;
|
||||
|
||||
if(ie->use_nat64 && target->addr.ss_family == AF_INET) {
|
||||
addr_to_nat64(&target->addr, &ie->nat64_prefix_addr,
|
||||
ie->nat64_prefix_addrlen, ie->nat64_prefix_net,
|
||||
&real_addr, &real_addrlen);
|
||||
log_name_addr(VERB_QUERY, "applied NAT64:",
|
||||
iq->dp->name, &real_addr, real_addrlen);
|
||||
}
|
||||
|
||||
fptr_ok(fptr_whitelist_modenv_send_query(qstate->env->send_query));
|
||||
outq = (*qstate->env->send_query)(&iq->qinfo_out,
|
||||
iq->chase_flags | (iq->chase_to_rd?BIT_RD:0),
|
||||
|
@ -2822,7 +2879,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
|||
!qstate->blacklist&&(!iter_qname_indicates_dnssec(qstate->env,
|
||||
&iq->qinfo_out)||target->attempts==1)?0:BIT_CD),
|
||||
iq->dnssec_expected, iq->caps_fallback || is_caps_whitelisted(
|
||||
ie, iq), sq_check_ratelimit, &target->addr, target->addrlen,
|
||||
ie, iq), sq_check_ratelimit, &real_addr, real_addrlen,
|
||||
iq->dp->name, iq->dp->namelen,
|
||||
(iq->dp->tcp_upstream || qstate->env->cfg->tcp_upstream),
|
||||
(iq->dp->ssl_upstream || qstate->env->cfg->ssl_upstream),
|
||||
|
@ -2839,7 +2896,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
|||
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
log_addr(VERB_QUERY, "error sending query to auth server",
|
||||
&target->addr, target->addrlen);
|
||||
&real_addr, real_addrlen);
|
||||
if(qstate->env->cfg->qname_minimisation)
|
||||
iq->minimisation_state = SKIP_MINIMISE_STATE;
|
||||
return next_state(iq, QUERYTARGETS_STATE);
|
||||
|
@ -2883,7 +2940,7 @@ static int
|
|||
processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
struct iter_env* ie, int id)
|
||||
{
|
||||
int dnsseclame = 0;
|
||||
int dnsseclame = 0, origtypecname = 0;
|
||||
enum response_type type;
|
||||
|
||||
iq->num_current_queries--;
|
||||
|
@ -2966,6 +3023,8 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
|||
/* YXDOMAIN is a permanent error, no need to retry */
|
||||
type = RESPONSE_TYPE_ANSWER;
|
||||
}
|
||||
if(type == RESPONSE_TYPE_CNAME)
|
||||
origtypecname = 1;
|
||||
if(type == RESPONSE_TYPE_CNAME && iq->response->rep->an_numrrsets >= 1
|
||||
&& ntohs(iq->response->rep->rrsets[0]->rk.type) == LDNS_RR_TYPE_DNAME) {
|
||||
uint8_t* sname = NULL;
|
||||
|
@ -3051,11 +3110,14 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
|||
iq->minimisation_state = DONOT_MINIMISE_STATE;
|
||||
}
|
||||
if(FLAGS_GET_RCODE(iq->response->rep->flags) ==
|
||||
LDNS_RCODE_NXDOMAIN) {
|
||||
LDNS_RCODE_NXDOMAIN && !origtypecname) {
|
||||
/* Stop resolving when NXDOMAIN is DNSSEC
|
||||
* signed. Based on assumption that nameservers
|
||||
* serving signed zones do not return NXDOMAIN
|
||||
* for empty-non-terminals. */
|
||||
/* If this response is actually a CNAME type,
|
||||
* the nxdomain rcode may not be for the qname,
|
||||
* and so it is not the final response. */
|
||||
if(iq->dnssec_expected)
|
||||
return final_state(iq);
|
||||
/* Make subrequest to validate intermediate
|
||||
|
@ -3183,7 +3245,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
|||
(*qstate->env->detach_subs)(qstate);
|
||||
iq->num_target_queries = 0;
|
||||
iq->response = NULL;
|
||||
iq->fail_reply = NULL;
|
||||
iq->fail_addr_type = 0;
|
||||
verbose(VERB_ALGO, "cleared outbound list for next round");
|
||||
return next_state(iq, QUERYTARGETS_STATE);
|
||||
} else if(type == RESPONSE_TYPE_CNAME) {
|
||||
|
@ -3565,7 +3627,7 @@ processTargetResponse(struct module_qstate* qstate, int id,
|
|||
} else {
|
||||
verbose(VERB_ALGO, "iterator TargetResponse failed");
|
||||
delegpt_mark_neg(dpns, qstate->qinfo.qtype);
|
||||
if((dpns->got4 == 2 || !ie->supports_ipv4) &&
|
||||
if((dpns->got4 == 2 || (!ie->supports_ipv4 && !ie->use_nat64)) &&
|
||||
(dpns->got6 == 2 || !ie->supports_ipv6)) {
|
||||
dpns->resolved = 1; /* fail the target */
|
||||
/* do not count cached answers */
|
||||
|
@ -3810,6 +3872,9 @@ processFinished(struct module_qstate* qstate, struct iter_qstate* iq,
|
|||
/* make sure QR flag is on */
|
||||
iq->response->rep->flags |= BIT_QR;
|
||||
|
||||
/* explicitly set the EDE string to NULL */
|
||||
iq->response->rep->reason_bogus_str = NULL;
|
||||
|
||||
/* we have finished processing this query */
|
||||
qstate->ext_state[id] = module_finished;
|
||||
|
||||
|
@ -3988,7 +4053,8 @@ process_response(struct module_qstate* qstate, struct iter_qstate* iq,
|
|||
}
|
||||
|
||||
/* parse message */
|
||||
iq->fail_reply = qstate->reply;
|
||||
fill_fail_addr(iq, &qstate->reply->remote_addr,
|
||||
qstate->reply->remote_addrlen);
|
||||
prs = (struct msg_parse*)regional_alloc(qstate->env->scratch,
|
||||
sizeof(struct msg_parse));
|
||||
if(!prs) {
|
||||
|
|
|
@ -63,12 +63,8 @@ struct rbtree_type;
|
|||
/** max number of nxdomains allowed for target lookups for a query and
|
||||
* its subqueries when fallback has kicked in */
|
||||
#define MAX_TARGET_NX_FALLBACK (MAX_TARGET_NX*2)
|
||||
/** max number of query restarts. Determines max number of CNAME chain. */
|
||||
#define MAX_RESTART_COUNT 11
|
||||
/** max number of referrals. Makes sure resolver does not run away */
|
||||
#define MAX_REFERRAL_COUNT 130
|
||||
/** max number of queries-sent-out. Make sure large NS set does not loop */
|
||||
#define MAX_SENT_COUNT 32
|
||||
/** max number of queries for which to perform dnsseclameness detection,
|
||||
* (rrsigs missing detection) after that, just pick up that response */
|
||||
#define DNSSEC_LAME_DETECT_COUNT 4
|
||||
|
@ -116,6 +112,18 @@ struct iter_env {
|
|||
/** A flag to indicate whether or not we have an IPv4 route */
|
||||
int supports_ipv4;
|
||||
|
||||
/** A flag to locally apply NAT64 to make IPv4 addrs into IPv6 */
|
||||
int use_nat64;
|
||||
|
||||
/** NAT64 prefix address, cf. dns64_env->prefix_addr */
|
||||
struct sockaddr_storage nat64_prefix_addr;
|
||||
|
||||
/** sizeof(sockaddr_in6) */
|
||||
socklen_t nat64_prefix_addrlen;
|
||||
|
||||
/** CIDR mask length of NAT64 prefix */
|
||||
int nat64_prefix_net;
|
||||
|
||||
/** A set of inetaddrs that should never be queried. */
|
||||
struct iter_donotq* donotq;
|
||||
|
||||
|
@ -145,6 +153,12 @@ struct iter_env {
|
|||
|
||||
/** number of retries on outgoing queries */
|
||||
int outbound_msg_retry;
|
||||
|
||||
/** number of queries_sent */
|
||||
int max_sent_count;
|
||||
|
||||
/** max number of query restarts to limit length of CNAME chain */
|
||||
int max_query_restarts;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -437,7 +451,14 @@ struct iter_qstate {
|
|||
/** true if there have been parse failures of reply packets */
|
||||
int parse_failures;
|
||||
/** a failure printout address for last received answer */
|
||||
struct comm_reply* fail_reply;
|
||||
union {
|
||||
struct in_addr in;
|
||||
#ifdef AF_INET6
|
||||
struct in6_addr in6;
|
||||
#endif
|
||||
} fail_addr;
|
||||
/** which fail_addr, 0 is nothing, 4 or 6 */
|
||||
int fail_addr_type;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -70,6 +70,7 @@ context_finalize(struct ub_ctx* ctx)
|
|||
} else {
|
||||
log_init(cfg->logfile, cfg->use_syslog, NULL);
|
||||
}
|
||||
ctx->pipe_pid = getpid();
|
||||
cfg_apply_local_port_policy(cfg, 65536);
|
||||
config_apply(cfg);
|
||||
if(!modstack_setup(&ctx->mods, cfg->module_conf, ctx->env))
|
||||
|
|
|
@ -89,6 +89,12 @@ struct ub_ctx {
|
|||
pid_t bg_pid;
|
||||
/** tid of bg worker thread */
|
||||
ub_thread_type bg_tid;
|
||||
/** pid when pipes are created. This was the process when the
|
||||
* setup was called. Helps with clean up, so we can tell after a fork
|
||||
* which side of the fork the delete is on. */
|
||||
pid_t pipe_pid;
|
||||
/** when threaded, the worker that exists in the created thread. */
|
||||
struct libworker* thread_worker;
|
||||
|
||||
/** do threading (instead of forking) for async resolution */
|
||||
int dothread;
|
||||
|
|
|
@ -305,11 +305,31 @@ ub_ctx_delete(struct ub_ctx* ctx)
|
|||
int do_stop = 1;
|
||||
if(!ctx) return;
|
||||
|
||||
/* if the delete is called but it has forked, and before the fork
|
||||
* the context was finalized, then the bg worker is not stopped
|
||||
* from here. There is one worker, but two contexts that refer to
|
||||
* it and only one should clean up, the one with getpid == pipe_pid.*/
|
||||
if(ctx->created_bg && ctx->pipe_pid != getpid()) {
|
||||
do_stop = 0;
|
||||
#ifndef USE_WINSOCK
|
||||
/* Stop events from getting deregistered, if the backend is
|
||||
* epoll, the epoll fd is the same as the other process.
|
||||
* That process should deregister them. */
|
||||
if(ctx->qq_pipe->listen_com)
|
||||
ctx->qq_pipe->listen_com->event_added = 0;
|
||||
if(ctx->qq_pipe->res_com)
|
||||
ctx->qq_pipe->res_com->event_added = 0;
|
||||
if(ctx->rr_pipe->listen_com)
|
||||
ctx->rr_pipe->listen_com->event_added = 0;
|
||||
if(ctx->rr_pipe->res_com)
|
||||
ctx->rr_pipe->res_com->event_added = 0;
|
||||
#endif
|
||||
}
|
||||
/* see if bg thread is created and if threads have been killed */
|
||||
/* no locks, because those may be held by terminated threads */
|
||||
/* for processes the read pipe is closed and we see that on read */
|
||||
#ifdef HAVE_PTHREAD
|
||||
if(ctx->created_bg && ctx->dothread) {
|
||||
if(ctx->created_bg && ctx->dothread && do_stop) {
|
||||
if(pthread_kill(ctx->bg_tid, 0) == ESRCH) {
|
||||
/* thread has been killed */
|
||||
do_stop = 0;
|
||||
|
@ -318,6 +338,23 @@ ub_ctx_delete(struct ub_ctx* ctx)
|
|||
#endif /* HAVE_PTHREAD */
|
||||
if(do_stop)
|
||||
ub_stop_bg(ctx);
|
||||
if(ctx->created_bg && ctx->pipe_pid != getpid() && ctx->thread_worker) {
|
||||
/* This delete is happening from a different process. Delete
|
||||
* the thread worker from this process memory space. The
|
||||
* thread is not there to do so, so it is freed here. */
|
||||
struct ub_event_base* evbase = comm_base_internal(
|
||||
ctx->thread_worker->base);
|
||||
libworker_delete_event(ctx->thread_worker);
|
||||
ctx->thread_worker = NULL;
|
||||
#ifdef USE_MINI_EVENT
|
||||
ub_event_base_free(evbase);
|
||||
#else
|
||||
/* cannot event_base_free, because the epoll_fd cleanup
|
||||
* in libevent could stop the original event_base in the
|
||||
* other process from working. */
|
||||
free(evbase);
|
||||
#endif
|
||||
}
|
||||
libworker_delete_event(ctx->event_worker);
|
||||
|
||||
modstack_desetup(&ctx->mods, ctx->env);
|
||||
|
|
|
@ -168,7 +168,6 @@ libworker_setup(struct ub_ctx* ctx, int is_bg, struct ub_event_base* eb)
|
|||
hints_delete(w->env->hints);
|
||||
w->env->hints = NULL;
|
||||
}
|
||||
if(cfg->ssl_upstream || (cfg->tls_cert_bundle && cfg->tls_cert_bundle[0]) || cfg->tls_win_cert) {
|
||||
w->sslctx = connect_sslctx_create(NULL, NULL,
|
||||
cfg->tls_cert_bundle, cfg->tls_win_cert);
|
||||
if(!w->sslctx) {
|
||||
|
@ -176,7 +175,6 @@ libworker_setup(struct ub_ctx* ctx, int is_bg, struct ub_event_base* eb)
|
|||
hints_delete(w->env->hints);
|
||||
w->env->hints = NULL;
|
||||
}
|
||||
}
|
||||
if(!w->is_bg || w->is_bg_thread) {
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
}
|
||||
|
@ -395,6 +393,7 @@ int libworker_bg(struct ub_ctx* ctx)
|
|||
w = libworker_setup(ctx, 1, NULL);
|
||||
if(!w) return UB_NOMEM;
|
||||
w->is_bg_thread = 1;
|
||||
ctx->thread_worker = w;
|
||||
#ifdef ENABLE_LOCK_CHECKS
|
||||
w->thread_num = 1; /* for nicer DEBUG checklocks */
|
||||
#endif
|
||||
|
@ -604,6 +603,8 @@ setup_qinfo_edns(struct libworker* w, struct ctx_query* q,
|
|||
edns->opt_list_out = NULL;
|
||||
edns->opt_list_inplace_cb_out = NULL;
|
||||
edns->padding_block_size = 0;
|
||||
edns->cookie_present = 0;
|
||||
edns->cookie_valid = 0;
|
||||
if(sldns_buffer_capacity(w->back->udp_buff) < 65535)
|
||||
edns->udp_size = (uint16_t)sldns_buffer_capacity(
|
||||
w->back->udp_buff);
|
||||
|
|
|
@ -52,8 +52,8 @@
|
|||
* unbound was compiled with, otherwise it wouldn't work, the event and
|
||||
* event_base structures would be different.
|
||||
*/
|
||||
#ifndef _UB_UNBOUND_EVENT_H
|
||||
#define _UB_UNBOUND_EVENT_H
|
||||
#ifndef UB_UNBOUND_EVENT_H
|
||||
#define UB_UNBOUND_EVENT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -230,7 +230,7 @@ int ub_ctx_set_event(struct ub_ctx* ctx, struct event_base* base);
|
|||
* @param callback: this is called on completion of the resolution.
|
||||
* It is called as:
|
||||
* void callback(void* mydata, int rcode, void* packet, int packet_len,
|
||||
* int sec, char* why_bogus)
|
||||
* int sec, char* why_bogus, int was_ratelimited)
|
||||
* with mydata: the same as passed here, you may pass NULL,
|
||||
* with rcode: 0 on no error, nonzero for mostly SERVFAIL situations,
|
||||
* this is a DNS rcode.
|
||||
|
@ -241,6 +241,7 @@ int ub_ctx_set_event(struct ub_ctx* ctx, struct event_base* base);
|
|||
* with packet_len: length in bytes of the packet buffer.
|
||||
* with sec: 0 if insecure, 1 if bogus, 2 if DNSSEC secure.
|
||||
* with why_bogus: text string explaining why it is bogus (or NULL).
|
||||
* with was_ratelimited: if the query was ratelimited.
|
||||
* These point to buffers inside unbound; do not deallocate the packet or
|
||||
* error string.
|
||||
*
|
||||
|
@ -261,4 +262,4 @@ int ub_resolve_event(struct ub_ctx* ctx, const char* name, int rrtype,
|
|||
}
|
||||
#endif
|
||||
|
||||
#endif /* _UB_UNBOUND_H */
|
||||
#endif /* UB_UNBOUND_EVENT_H */
|
||||
|
|
|
@ -94,8 +94,8 @@
|
|||
* The second calls another worker thread (or process) to perform the work.
|
||||
* And no buffers need to be set up, but a context-switch happens.
|
||||
*/
|
||||
#ifndef _UB_UNBOUND_H
|
||||
#define _UB_UNBOUND_H
|
||||
#ifndef UB_UNBOUND_H
|
||||
#define UB_UNBOUND_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -695,11 +695,20 @@ struct ub_server_stats {
|
|||
long long num_queries;
|
||||
/** number of queries that have been dropped/ratelimited by ip. */
|
||||
long long num_queries_ip_ratelimited;
|
||||
/** number of queries with a valid DNS Cookie. */
|
||||
long long num_queries_cookie_valid;
|
||||
/** number of queries with only the client part of the DNS Cookie. */
|
||||
long long num_queries_cookie_client;
|
||||
/** number of queries with invalid DNS Cookie. */
|
||||
long long num_queries_cookie_invalid;
|
||||
/** number of queries that had a cache-miss. */
|
||||
long long num_queries_missed_cache;
|
||||
/** number of prefetch queries - cachehits with prefetch */
|
||||
long long num_queries_prefetch;
|
||||
|
||||
/** number of queries which are too late to process */
|
||||
long long num_queries_timed_out;
|
||||
/** the longest wait time in the queue */
|
||||
long long max_query_time_us;
|
||||
/**
|
||||
* Sum of the querylistsize of the worker for
|
||||
* every query that missed cache. To calculate average.
|
||||
|
@ -788,6 +797,11 @@ struct ub_server_stats {
|
|||
/** number of key cache entries */
|
||||
long long key_cache_count;
|
||||
|
||||
/** maximum number of collisions in the msg cache */
|
||||
long long msg_cache_max_collisions;
|
||||
/** maximum number of collisions in the rrset cache */
|
||||
long long rrset_cache_max_collisions;
|
||||
|
||||
/** number of queries that used dnscrypt */
|
||||
long long num_query_dnscrypt_crypted;
|
||||
/** number of queries that queried dnscrypt certificates */
|
||||
|
@ -819,6 +833,8 @@ struct ub_server_stats {
|
|||
/** number of queries answered from edns-subnet specific data, and
|
||||
* the answer was from the edns-subnet cache. */
|
||||
long long num_query_subnet_cache;
|
||||
/** number of queries served from cachedb */
|
||||
long long num_query_cachedb;
|
||||
/** number of bytes in the stream wait buffers */
|
||||
long long mem_stream_wait;
|
||||
/** number of bytes in the HTTP2 query buffers */
|
||||
|
@ -860,4 +876,4 @@ struct ub_stats_info {
|
|||
}
|
||||
#endif
|
||||
|
||||
#endif /* _UB_UNBOUND_H */
|
||||
#endif /* UB_UNBOUND_H */
|
||||
|
|
|
@ -1306,8 +1306,8 @@ az_remove_rr(struct auth_zone* z, uint8_t* rr, size_t rr_len,
|
|||
auth_data_delete(node);
|
||||
}
|
||||
if(z->rpz) {
|
||||
rpz_remove_rr(z->rpz, z->namelen, dname, dname_len, rr_type,
|
||||
rr_class, rdata, rdatalen);
|
||||
rpz_remove_rr(z->rpz, z->name, z->namelen, dname, dname_len,
|
||||
rr_type, rr_class, rdata, rdatalen);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
@ -2756,6 +2756,7 @@ az_change_dnames(struct dns_msg* msg, uint8_t* oldname, uint8_t* newname,
|
|||
== 0) {
|
||||
msg->rep->rrsets[i]->rk.dname = newname;
|
||||
msg->rep->rrsets[i]->rk.dname_len = newlen;
|
||||
msg->rep->rrsets[i]->entry.hash = rrset_key_hash(&msg->rep->rrsets[i]->rk);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5419,6 +5420,8 @@ xfr_transfer_lookup_host(struct auth_xfer* xfr, struct module_env* env)
|
|||
edns.opt_list_out = NULL;
|
||||
edns.opt_list_inplace_cb_out = NULL;
|
||||
edns.padding_block_size = 0;
|
||||
edns.cookie_present = 0;
|
||||
edns.cookie_valid = 0;
|
||||
if(sldns_buffer_capacity(buf) < 65535)
|
||||
edns.udp_size = (uint16_t)sldns_buffer_capacity(buf);
|
||||
else edns.udp_size = 65535;
|
||||
|
@ -6612,6 +6615,8 @@ xfr_probe_lookup_host(struct auth_xfer* xfr, struct module_env* env)
|
|||
edns.opt_list_out = NULL;
|
||||
edns.opt_list_inplace_cb_out = NULL;
|
||||
edns.padding_block_size = 0;
|
||||
edns.cookie_present = 0;
|
||||
edns.cookie_valid = 0;
|
||||
if(sldns_buffer_capacity(buf) < 65535)
|
||||
edns.udp_size = (uint16_t)sldns_buffer_capacity(buf);
|
||||
else edns.udp_size = 65535;
|
||||
|
@ -7509,7 +7514,7 @@ static void add_rrlist_rrsigs_into_data(struct packed_rrset_data* data,
|
|||
size_t j;
|
||||
if(!rrlist[i])
|
||||
continue;
|
||||
if(rrlist[i] && rrlist[i]->type == LDNS_RR_TYPE_ZONEMD &&
|
||||
if(rrlist[i]->type == LDNS_RR_TYPE_ZONEMD &&
|
||||
query_dname_compare(z->name, node->name)==0) {
|
||||
/* omit RRSIGs over type ZONEMD at apex */
|
||||
continue;
|
||||
|
|
58
sbin/unwind/libunbound/services/cache/dns.c
vendored
58
sbin/unwind/libunbound/services/cache/dns.c
vendored
|
@ -132,31 +132,6 @@ msg_cache_remove(struct module_env* env, uint8_t* qname, size_t qnamelen,
|
|||
slabhash_remove(env->msg_cache, h, &k);
|
||||
}
|
||||
|
||||
/** remove servfail msg cache entry */
|
||||
static void
|
||||
msg_del_servfail(struct module_env* env, struct query_info* qinfo,
|
||||
uint32_t flags)
|
||||
{
|
||||
struct msgreply_entry* e;
|
||||
/* see if the entry is servfail, and then remove it, so that
|
||||
* lookups move from the cacheresponse stage to the recursionresponse
|
||||
* stage */
|
||||
e = msg_cache_lookup(env, qinfo->qname, qinfo->qname_len,
|
||||
qinfo->qtype, qinfo->qclass, flags, 0, 0);
|
||||
if(!e) return;
|
||||
/* we don't check for the ttl here, also expired servfail entries
|
||||
* are removed. If the user uses serve-expired, they would still be
|
||||
* used to answer from cache */
|
||||
if(FLAGS_GET_RCODE(((struct reply_info*)e->entry.data)->flags)
|
||||
!= LDNS_RCODE_SERVFAIL) {
|
||||
lock_rw_unlock(&e->entry.lock);
|
||||
return;
|
||||
}
|
||||
lock_rw_unlock(&e->entry.lock);
|
||||
msg_cache_remove(env, qinfo->qname, qinfo->qname_len, qinfo->qtype,
|
||||
qinfo->qclass, flags);
|
||||
}
|
||||
|
||||
void
|
||||
dns_cache_store_msg(struct module_env* env, struct query_info* qinfo,
|
||||
hashvalue_type hash, struct reply_info* rep, time_t leeway, int pside,
|
||||
|
@ -182,13 +157,20 @@ dns_cache_store_msg(struct module_env* env, struct query_info* qinfo,
|
|||
/* we do not store the message, but we did store the RRs,
|
||||
* which could be useful for delegation information */
|
||||
verbose(VERB_ALGO, "TTL 0: dropped msg from cache");
|
||||
free(rep);
|
||||
/* if the message is SERVFAIL in cache, remove that SERVFAIL,
|
||||
reply_info_delete(rep, NULL);
|
||||
/* if the message is in the cache, remove that msg,
|
||||
* so that the TTL 0 response can be returned for future
|
||||
* responses (i.e. don't get answered by the servfail from
|
||||
* responses (i.e. don't get answered from
|
||||
* cache, but instead go to recursion to get this TTL0
|
||||
* response). */
|
||||
msg_del_servfail(env, qinfo, flags);
|
||||
* response).
|
||||
* Possible messages that could be in the cache:
|
||||
* - SERVFAIL
|
||||
* - NXDOMAIN
|
||||
* - NODATA
|
||||
* - an older record that is expired
|
||||
* - an older record that did not yet expire */
|
||||
msg_cache_remove(env, qinfo->qname, qinfo->qname_len,
|
||||
qinfo->qtype, qinfo->qclass, flags);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -610,6 +592,7 @@ gen_dns_msg(struct regional* region, struct query_info* q, size_t num)
|
|||
if(!msg->rep)
|
||||
return NULL;
|
||||
msg->rep->reason_bogus = LDNS_EDE_NONE;
|
||||
msg->rep->reason_bogus_str = NULL;
|
||||
if(num > RR_COUNT_MAX)
|
||||
return NULL; /* integer overflow protection */
|
||||
msg->rep->rrsets = (struct ub_packed_rrset_key**)
|
||||
|
@ -636,6 +619,14 @@ tomsg(struct module_env* env, struct query_info* q, struct reply_info* r,
|
|||
r->serve_expired_ttl < now) {
|
||||
return NULL;
|
||||
}
|
||||
/* Ignore expired failure answers */
|
||||
if(FLAGS_GET_RCODE(r->flags) !=
|
||||
LDNS_RCODE_NOERROR &&
|
||||
FLAGS_GET_RCODE(r->flags) !=
|
||||
LDNS_RCODE_NXDOMAIN &&
|
||||
FLAGS_GET_RCODE(r->flags) !=
|
||||
LDNS_RCODE_YXDOMAIN)
|
||||
return 0;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -664,6 +655,10 @@ tomsg(struct module_env* env, struct query_info* q, struct reply_info* r,
|
|||
msg->rep->rrset_count = r->rrset_count;
|
||||
msg->rep->authoritative = r->authoritative;
|
||||
msg->rep->reason_bogus = r->reason_bogus;
|
||||
if(r->reason_bogus_str) {
|
||||
msg->rep->reason_bogus_str = regional_strdup(region, r->reason_bogus_str);
|
||||
}
|
||||
|
||||
if(!rrset_array_lock(r->ref, r->rrset_count, now_control)) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1067,7 +1062,6 @@ dns_cache_store(struct module_env* env, struct query_info* msgqinf,
|
|||
/* ttl must be relative ;i.e. 0..86400 not time(0)+86400.
|
||||
* the env->now is added to message and RRsets in this routine. */
|
||||
/* the leeway is used to invalidate other rrsets earlier */
|
||||
|
||||
if(is_referral) {
|
||||
/* store rrsets */
|
||||
struct rrset_ref ref;
|
||||
|
@ -1084,7 +1078,7 @@ dns_cache_store(struct module_env* env, struct query_info* msgqinf,
|
|||
((ntohs(ref.key->rk.type)==LDNS_RR_TYPE_NS
|
||||
&& !pside) ? qstarttime:*env->now + leeway));
|
||||
}
|
||||
free(rep);
|
||||
reply_info_delete(rep, NULL);
|
||||
return 1;
|
||||
} else {
|
||||
/* store msg, and rrsets */
|
||||
|
|
75
sbin/unwind/libunbound/services/cache/infra.c
vendored
75
sbin/unwind/libunbound/services/cache/infra.c
vendored
|
@ -67,6 +67,11 @@ int infra_dp_ratelimit = 0;
|
|||
* in queries per second. */
|
||||
int infra_ip_ratelimit = 0;
|
||||
|
||||
/** ratelimit value for client ip addresses,
|
||||
* in queries per second.
|
||||
* For clients with a valid DNS Cookie. */
|
||||
int infra_ip_ratelimit_cookie = 0;
|
||||
|
||||
size_t
|
||||
infra_sizefunc(void* k, void* ATTR_UNUSED(d))
|
||||
{
|
||||
|
@ -1051,9 +1056,50 @@ infra_get_mem(struct infra_cache* infra)
|
|||
return s;
|
||||
}
|
||||
|
||||
/* Returns 1 if the limit has not been exceeded, 0 otherwise. */
|
||||
static int
|
||||
check_ip_ratelimit(struct sockaddr_storage* addr, socklen_t addrlen,
|
||||
struct sldns_buffer* buffer, int premax, int max, int has_cookie)
|
||||
{
|
||||
int limit;
|
||||
|
||||
if(has_cookie) limit = infra_ip_ratelimit_cookie;
|
||||
else limit = infra_ip_ratelimit;
|
||||
|
||||
/* Disabled */
|
||||
if(limit == 0) return 1;
|
||||
|
||||
if(premax <= limit && max > limit) {
|
||||
char client_ip[128], qnm[LDNS_MAX_DOMAINLEN+1+12+12];
|
||||
addr_to_str(addr, addrlen, client_ip, sizeof(client_ip));
|
||||
qnm[0]=0;
|
||||
if(sldns_buffer_limit(buffer)>LDNS_HEADER_SIZE &&
|
||||
LDNS_QDCOUNT(sldns_buffer_begin(buffer))!=0) {
|
||||
(void)sldns_wire2str_rrquestion_buf(
|
||||
sldns_buffer_at(buffer, LDNS_HEADER_SIZE),
|
||||
sldns_buffer_limit(buffer)-LDNS_HEADER_SIZE,
|
||||
qnm, sizeof(qnm));
|
||||
if(strlen(qnm)>0 && qnm[strlen(qnm)-1]=='\n')
|
||||
qnm[strlen(qnm)-1] = 0; /*remove newline*/
|
||||
if(strchr(qnm, '\t'))
|
||||
*strchr(qnm, '\t') = ' ';
|
||||
if(strchr(qnm, '\t'))
|
||||
*strchr(qnm, '\t') = ' ';
|
||||
verbose(VERB_OPS, "ip_ratelimit exceeded %s %d%s %s",
|
||||
client_ip, limit,
|
||||
has_cookie?"(cookie)":"", qnm);
|
||||
} else {
|
||||
verbose(VERB_OPS, "ip_ratelimit exceeded %s %d%s (no query name)",
|
||||
client_ip, limit,
|
||||
has_cookie?"(cookie)":"");
|
||||
}
|
||||
}
|
||||
return (max <= limit);
|
||||
}
|
||||
|
||||
int infra_ip_ratelimit_inc(struct infra_cache* infra,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen, time_t timenow,
|
||||
int backoff, struct sldns_buffer* buffer)
|
||||
int has_cookie, int backoff, struct sldns_buffer* buffer)
|
||||
{
|
||||
int max;
|
||||
struct lruhash_entry* entry;
|
||||
|
@ -1070,31 +1116,8 @@ int infra_ip_ratelimit_inc(struct infra_cache* infra,
|
|||
(*cur)++;
|
||||
max = infra_rate_max(entry->data, timenow, backoff);
|
||||
lock_rw_unlock(&entry->lock);
|
||||
|
||||
if(premax <= infra_ip_ratelimit && max > infra_ip_ratelimit) {
|
||||
char client_ip[128], qnm[LDNS_MAX_DOMAINLEN+1+12+12];
|
||||
addr_to_str(addr, addrlen, client_ip, sizeof(client_ip));
|
||||
qnm[0]=0;
|
||||
if(sldns_buffer_limit(buffer)>LDNS_HEADER_SIZE &&
|
||||
LDNS_QDCOUNT(sldns_buffer_begin(buffer))!=0) {
|
||||
(void)sldns_wire2str_rrquestion_buf(
|
||||
sldns_buffer_at(buffer, LDNS_HEADER_SIZE),
|
||||
sldns_buffer_limit(buffer)-LDNS_HEADER_SIZE,
|
||||
qnm, sizeof(qnm));
|
||||
if(strlen(qnm)>0 && qnm[strlen(qnm)-1]=='\n')
|
||||
qnm[strlen(qnm)-1] = 0; /*remove newline*/
|
||||
if(strchr(qnm, '\t'))
|
||||
*strchr(qnm, '\t') = ' ';
|
||||
if(strchr(qnm, '\t'))
|
||||
*strchr(qnm, '\t') = ' ';
|
||||
verbose(VERB_OPS, "ip_ratelimit exceeded %s %d %s",
|
||||
client_ip, infra_ip_ratelimit, qnm);
|
||||
} else {
|
||||
verbose(VERB_OPS, "ip_ratelimit exceeded %s %d (no query name)",
|
||||
client_ip, infra_ip_ratelimit);
|
||||
}
|
||||
}
|
||||
return (max <= infra_ip_ratelimit);
|
||||
return check_ip_ratelimit(addr, addrlen, buffer, premax, max,
|
||||
has_cookie);
|
||||
}
|
||||
|
||||
/* create */
|
||||
|
|
|
@ -153,6 +153,8 @@ struct rate_key {
|
|||
|
||||
/** ip ratelimit, 0 is off */
|
||||
extern int infra_ip_ratelimit;
|
||||
/** ip ratelimit for DNS Cookie clients, 0 is off */
|
||||
extern int infra_ip_ratelimit_cookie;
|
||||
|
||||
/**
|
||||
* key for ip_ratelimit lookups, a source IP.
|
||||
|
@ -419,13 +421,14 @@ int infra_find_ratelimit(struct infra_cache* infra, uint8_t* name,
|
|||
* @param addr: client address
|
||||
* @param addrlen: client address length
|
||||
* @param timenow: what time it is now.
|
||||
* @param has_cookie: if the request came with a DNS Cookie.
|
||||
* @param backoff: if backoff is enabled.
|
||||
* @param buffer: with query for logging.
|
||||
* @return 1 if it could be incremented. 0 if the increment overshot the
|
||||
* ratelimit and the query should be dropped. */
|
||||
int infra_ip_ratelimit_inc(struct infra_cache* infra,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen, time_t timenow,
|
||||
int backoff, struct sldns_buffer* buffer);
|
||||
int has_cookie, int backoff, struct sldns_buffer* buffer);
|
||||
|
||||
/**
|
||||
* Get memory used by the infra cache.
|
||||
|
|
|
@ -79,7 +79,9 @@
|
|||
#ifdef HAVE_NET_IF_H
|
||||
#include <net/if.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LINUX_NET_TSTAMP_H
|
||||
#include <linux/net_tstamp.h>
|
||||
#endif
|
||||
/** number of queued TCP connections for listen() */
|
||||
#define TCP_BACKLOG 256
|
||||
|
||||
|
@ -1018,7 +1020,7 @@ make_sock(int stype, const char* ifname, const char* port,
|
|||
log_err("node %s:%s getaddrinfo: %s %s",
|
||||
ifname?ifname:"default", port, gai_strerror(r),
|
||||
#ifdef EAI_SYSTEM
|
||||
r==EAI_SYSTEM?(char*)strerror(errno):""
|
||||
(r==EAI_SYSTEM?(char*)strerror(errno):"")
|
||||
#else
|
||||
""
|
||||
#endif
|
||||
|
@ -1114,6 +1116,25 @@ port_insert(struct listen_port** list, int s, enum listen_type ftype,
|
|||
return 1;
|
||||
}
|
||||
|
||||
/** set fd to receive software timestamps */
|
||||
static int
|
||||
set_recvtimestamp(int s)
|
||||
{
|
||||
#ifdef HAVE_LINUX_NET_TSTAMP_H
|
||||
int opt = SOF_TIMESTAMPING_RX_SOFTWARE | SOF_TIMESTAMPING_SOFTWARE;
|
||||
if (setsockopt(s, SOL_SOCKET, SO_TIMESTAMPNS, (void*)&opt, (socklen_t)sizeof(opt)) < 0) {
|
||||
log_err("setsockopt(..., SO_TIMESTAMPNS, ...) failed: %s",
|
||||
strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
#else
|
||||
log_err("packets timestamping is not supported on this platform");
|
||||
(void)s;
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/** set fd to receive source address packet info */
|
||||
static int
|
||||
set_recvpktinfo(int s, int family)
|
||||
|
@ -1214,6 +1235,9 @@ if_is_ssl(const char* ifname, const char* port, int ssl_port,
|
|||
* @param use_systemd: if true, fetch sockets from systemd.
|
||||
* @param dnscrypt_port: dnscrypt service port number
|
||||
* @param dscp: DSCP to use.
|
||||
* @param sock_queue_timeout: the sock_queue_timeout from config. Seconds to
|
||||
* wait to discard if UDP packets have waited for long in the socket
|
||||
* buffer.
|
||||
* @return: returns false on error.
|
||||
*/
|
||||
static int
|
||||
|
@ -1223,7 +1247,8 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
|
|||
struct config_strlist* tls_additional_port, int https_port,
|
||||
struct config_strlist* proxy_protocol_port,
|
||||
int* reuseport, int transparent, int tcp_mss, int freebind,
|
||||
int http2_nodelay, int use_systemd, int dnscrypt_port, int dscp)
|
||||
int http2_nodelay, int use_systemd, int dnscrypt_port, int dscp,
|
||||
int sock_queue_timeout)
|
||||
{
|
||||
int s, noip6=0;
|
||||
int is_https = if_is_https(ifname, port, https_port);
|
||||
|
@ -1252,6 +1277,7 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
|
|||
if((s = make_sock_port(SOCK_DGRAM, ifname, port, hints, 1,
|
||||
&noip6, rcv, snd, reuseport, transparent,
|
||||
tcp_mss, nodelay, freebind, use_systemd, dscp, ub_sock)) == -1) {
|
||||
if(ub_sock->addr)
|
||||
freeaddrinfo(ub_sock->addr);
|
||||
free(ub_sock);
|
||||
if(noip6) {
|
||||
|
@ -1263,14 +1289,19 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
|
|||
/* getting source addr packet info is highly non-portable */
|
||||
if(!set_recvpktinfo(s, hints->ai_family)) {
|
||||
sock_close(s);
|
||||
if(ub_sock->addr)
|
||||
freeaddrinfo(ub_sock->addr);
|
||||
free(ub_sock);
|
||||
return 0;
|
||||
}
|
||||
if (sock_queue_timeout && !set_recvtimestamp(s)) {
|
||||
log_warn("socket timestamping is not available");
|
||||
}
|
||||
if(!port_insert(list, s, is_dnscrypt
|
||||
?listen_type_udpancil_dnscrypt:listen_type_udpancil,
|
||||
is_pp2, ub_sock)) {
|
||||
sock_close(s);
|
||||
if(ub_sock->addr)
|
||||
freeaddrinfo(ub_sock->addr);
|
||||
free(ub_sock);
|
||||
return 0;
|
||||
|
@ -1283,6 +1314,7 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
|
|||
if((s = make_sock_port(SOCK_DGRAM, ifname, port, hints, 1,
|
||||
&noip6, rcv, snd, reuseport, transparent,
|
||||
tcp_mss, nodelay, freebind, use_systemd, dscp, ub_sock)) == -1) {
|
||||
if(ub_sock->addr)
|
||||
freeaddrinfo(ub_sock->addr);
|
||||
free(ub_sock);
|
||||
if(noip6) {
|
||||
|
@ -1291,10 +1323,14 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
if (sock_queue_timeout && !set_recvtimestamp(s)) {
|
||||
log_warn("socket timestamping is not available");
|
||||
}
|
||||
if(!port_insert(list, s, is_dnscrypt
|
||||
?listen_type_udp_dnscrypt:listen_type_udp,
|
||||
is_pp2, ub_sock)) {
|
||||
sock_close(s);
|
||||
if(ub_sock->addr)
|
||||
freeaddrinfo(ub_sock->addr);
|
||||
free(ub_sock);
|
||||
return 0;
|
||||
|
@ -1318,6 +1354,7 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
|
|||
if((s = make_sock_port(SOCK_STREAM, ifname, port, hints, 1,
|
||||
&noip6, 0, 0, reuseport, transparent, tcp_mss, nodelay,
|
||||
freebind, use_systemd, dscp, ub_sock)) == -1) {
|
||||
if(ub_sock->addr)
|
||||
freeaddrinfo(ub_sock->addr);
|
||||
free(ub_sock);
|
||||
if(noip6) {
|
||||
|
@ -1330,6 +1367,7 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
|
|||
verbose(VERB_ALGO, "setup TCP for SSL service");
|
||||
if(!port_insert(list, s, port_type, is_pp2, ub_sock)) {
|
||||
sock_close(s);
|
||||
if(ub_sock->addr)
|
||||
freeaddrinfo(ub_sock->addr);
|
||||
free(ub_sock);
|
||||
return 0;
|
||||
|
@ -1802,7 +1840,7 @@ listening_ports_open(struct config_file* cfg, char** ifs, int num_ifs,
|
|||
reuseport, cfg->ip_transparent,
|
||||
cfg->tcp_mss, cfg->ip_freebind,
|
||||
cfg->http_nodelay, cfg->use_systemd,
|
||||
cfg->dnscrypt_port, cfg->ip_dscp)) {
|
||||
cfg->dnscrypt_port, cfg->ip_dscp, cfg->sock_queue_timeout)) {
|
||||
listening_ports_free(list);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1819,7 +1857,7 @@ listening_ports_open(struct config_file* cfg, char** ifs, int num_ifs,
|
|||
reuseport, cfg->ip_transparent,
|
||||
cfg->tcp_mss, cfg->ip_freebind,
|
||||
cfg->http_nodelay, cfg->use_systemd,
|
||||
cfg->dnscrypt_port, cfg->ip_dscp)) {
|
||||
cfg->dnscrypt_port, cfg->ip_dscp, cfg->sock_queue_timeout)) {
|
||||
listening_ports_free(list);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1838,7 +1876,7 @@ listening_ports_open(struct config_file* cfg, char** ifs, int num_ifs,
|
|||
reuseport, cfg->ip_transparent,
|
||||
cfg->tcp_mss, cfg->ip_freebind,
|
||||
cfg->http_nodelay, cfg->use_systemd,
|
||||
cfg->dnscrypt_port, cfg->ip_dscp)) {
|
||||
cfg->dnscrypt_port, cfg->ip_dscp, cfg->sock_queue_timeout)) {
|
||||
listening_ports_free(list);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1854,7 +1892,7 @@ listening_ports_open(struct config_file* cfg, char** ifs, int num_ifs,
|
|||
reuseport, cfg->ip_transparent,
|
||||
cfg->tcp_mss, cfg->ip_freebind,
|
||||
cfg->http_nodelay, cfg->use_systemd,
|
||||
cfg->dnscrypt_port, cfg->ip_dscp)) {
|
||||
cfg->dnscrypt_port, cfg->ip_dscp, cfg->sock_queue_timeout)) {
|
||||
listening_ports_free(list);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1872,7 +1910,7 @@ listening_ports_open(struct config_file* cfg, char** ifs, int num_ifs,
|
|||
reuseport, cfg->ip_transparent,
|
||||
cfg->tcp_mss, cfg->ip_freebind,
|
||||
cfg->http_nodelay, cfg->use_systemd,
|
||||
cfg->dnscrypt_port, cfg->ip_dscp)) {
|
||||
cfg->dnscrypt_port, cfg->ip_dscp, cfg->sock_queue_timeout)) {
|
||||
listening_ports_free(list);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1888,7 +1926,7 @@ listening_ports_open(struct config_file* cfg, char** ifs, int num_ifs,
|
|||
reuseport, cfg->ip_transparent,
|
||||
cfg->tcp_mss, cfg->ip_freebind,
|
||||
cfg->http_nodelay, cfg->use_systemd,
|
||||
cfg->dnscrypt_port, cfg->ip_dscp)) {
|
||||
cfg->dnscrypt_port, cfg->ip_dscp, cfg->sock_queue_timeout)) {
|
||||
listening_ports_free(list);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1908,6 +1946,7 @@ void listening_ports_free(struct listen_port* list)
|
|||
}
|
||||
/* rc_ports don't have ub_socket */
|
||||
if(list->socket) {
|
||||
if(list->socket->addr)
|
||||
freeaddrinfo(list->socket->addr);
|
||||
free(list->socket);
|
||||
}
|
||||
|
|
|
@ -1308,6 +1308,7 @@ local_encode(struct query_info* qinfo, struct module_env* env,
|
|||
else rep.ns_numrrsets = 1;
|
||||
rep.rrset_count = 1;
|
||||
rep.rrsets = &rrset;
|
||||
rep.reason_bogus = LDNS_EDE_NONE;
|
||||
udpsize = edns->udp_size;
|
||||
edns->edns_version = EDNS_ADVERTISED_VERSION;
|
||||
edns->udp_size = EDNS_ADVERTISED_SIZE;
|
||||
|
@ -1603,7 +1604,7 @@ local_zone_does_not_cover(struct local_zone* z, struct query_info* qinfo,
|
|||
struct local_data key;
|
||||
struct local_data* ld = NULL;
|
||||
struct local_rrset* lr = NULL;
|
||||
if(z->type == local_zone_always_transparent)
|
||||
if(z->type == local_zone_always_transparent || z->type == local_zone_block_a)
|
||||
return 1;
|
||||
if(z->type != local_zone_transparent
|
||||
&& z->type != local_zone_typetransparent
|
||||
|
@ -1679,6 +1680,16 @@ local_zones_zone_answer(struct local_zone* z, struct module_env* env,
|
|||
} else if(lz_type == local_zone_typetransparent
|
||||
|| lz_type == local_zone_always_transparent) {
|
||||
/* no NODATA or NXDOMAINS for this zone type */
|
||||
return 0;
|
||||
} else if(lz_type == local_zone_block_a) {
|
||||
/* Return NODATA for all A queries */
|
||||
if(qinfo->qtype == LDNS_RR_TYPE_A) {
|
||||
local_error_encode(qinfo, env, edns, repinfo, buf, temp,
|
||||
LDNS_RCODE_NOERROR, (LDNS_RCODE_NOERROR|BIT_AA),
|
||||
LDNS_EDE_NONE, NULL);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
} else if(lz_type == local_zone_always_null) {
|
||||
/* 0.0.0.0 or ::0 or noerror/nodata for this zone type,
|
||||
|
@ -1846,7 +1857,8 @@ local_zones_answer(struct local_zones* zones, struct module_env* env,
|
|||
if(z && (lzt == local_zone_transparent ||
|
||||
lzt == local_zone_typetransparent ||
|
||||
lzt == local_zone_inform ||
|
||||
lzt == local_zone_always_transparent) &&
|
||||
lzt == local_zone_always_transparent ||
|
||||
lzt == local_zone_block_a) &&
|
||||
local_zone_does_not_cover(z, qinfo, labs)) {
|
||||
lock_rw_unlock(&z->lock);
|
||||
z = NULL;
|
||||
|
@ -1894,6 +1906,7 @@ local_zones_answer(struct local_zones* zones, struct module_env* env,
|
|||
|
||||
if(lzt != local_zone_always_refuse
|
||||
&& lzt != local_zone_always_transparent
|
||||
&& lzt != local_zone_block_a
|
||||
&& lzt != local_zone_always_nxdomain
|
||||
&& lzt != local_zone_always_nodata
|
||||
&& lzt != local_zone_always_deny
|
||||
|
@ -1924,6 +1937,7 @@ const char* local_zone_type2str(enum localzone_type t)
|
|||
case local_zone_inform_deny: return "inform_deny";
|
||||
case local_zone_inform_redirect: return "inform_redirect";
|
||||
case local_zone_always_transparent: return "always_transparent";
|
||||
case local_zone_block_a: return "block_a";
|
||||
case local_zone_always_refuse: return "always_refuse";
|
||||
case local_zone_always_nxdomain: return "always_nxdomain";
|
||||
case local_zone_always_nodata: return "always_nodata";
|
||||
|
@ -1958,6 +1972,8 @@ int local_zone_str2type(const char* type, enum localzone_type* t)
|
|||
*t = local_zone_inform_redirect;
|
||||
else if(strcmp(type, "always_transparent") == 0)
|
||||
*t = local_zone_always_transparent;
|
||||
else if(strcmp(type, "block_a") == 0)
|
||||
*t = local_zone_block_a;
|
||||
else if(strcmp(type, "always_refuse") == 0)
|
||||
*t = local_zone_always_refuse;
|
||||
else if(strcmp(type, "always_nxdomain") == 0)
|
||||
|
|
|
@ -88,6 +88,8 @@ enum localzone_type {
|
|||
local_zone_inform_redirect,
|
||||
/** resolve normally, even when there is local data */
|
||||
local_zone_always_transparent,
|
||||
/** resolve normally, even when there is local data but return NODATA for A queries */
|
||||
local_zone_block_a,
|
||||
/** answer with error, even when there is local data */
|
||||
local_zone_always_refuse,
|
||||
/** answer with nxdomain, even when there is local data */
|
||||
|
|
|
@ -63,82 +63,13 @@
|
|||
#include "util/data/dname.h"
|
||||
#include "respip/respip.h"
|
||||
#include "services/listen_dnsport.h"
|
||||
#include "util/timeval_func.h"
|
||||
|
||||
#ifdef CLIENT_SUBNET
|
||||
#include "edns-subnet/subnetmod.h"
|
||||
#include "edns-subnet/edns-subnet.h"
|
||||
#endif
|
||||
|
||||
/** subtract timers and the values do not overflow or become negative */
|
||||
static void
|
||||
timeval_subtract(struct timeval* d, const struct timeval* end, const struct timeval* start)
|
||||
{
|
||||
#ifndef S_SPLINT_S
|
||||
time_t end_usec = end->tv_usec;
|
||||
d->tv_sec = end->tv_sec - start->tv_sec;
|
||||
if(end_usec < start->tv_usec) {
|
||||
end_usec += 1000000;
|
||||
d->tv_sec--;
|
||||
}
|
||||
d->tv_usec = end_usec - start->tv_usec;
|
||||
#endif
|
||||
}
|
||||
|
||||
/** add timers and the values do not overflow or become negative */
|
||||
static void
|
||||
timeval_add(struct timeval* d, const struct timeval* add)
|
||||
{
|
||||
#ifndef S_SPLINT_S
|
||||
d->tv_sec += add->tv_sec;
|
||||
d->tv_usec += add->tv_usec;
|
||||
if(d->tv_usec >= 1000000 ) {
|
||||
d->tv_usec -= 1000000;
|
||||
d->tv_sec++;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/** divide sum of timers to get average */
|
||||
static void
|
||||
timeval_divide(struct timeval* avg, const struct timeval* sum, size_t d)
|
||||
{
|
||||
#ifndef S_SPLINT_S
|
||||
size_t leftover;
|
||||
if(d <= 0) {
|
||||
avg->tv_sec = 0;
|
||||
avg->tv_usec = 0;
|
||||
return;
|
||||
}
|
||||
avg->tv_sec = sum->tv_sec / d;
|
||||
avg->tv_usec = sum->tv_usec / d;
|
||||
/* handle fraction from seconds divide */
|
||||
leftover = sum->tv_sec - avg->tv_sec*d;
|
||||
if(leftover <= 0)
|
||||
leftover = 0;
|
||||
avg->tv_usec += (((long long)leftover)*((long long)1000000))/d;
|
||||
if(avg->tv_sec < 0)
|
||||
avg->tv_sec = 0;
|
||||
if(avg->tv_usec < 0)
|
||||
avg->tv_usec = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/** histogram compare of time values */
|
||||
static int
|
||||
timeval_smaller(const struct timeval* x, const struct timeval* y)
|
||||
{
|
||||
#ifndef S_SPLINT_S
|
||||
if(x->tv_sec < y->tv_sec)
|
||||
return 1;
|
||||
else if(x->tv_sec == y->tv_sec) {
|
||||
if(x->tv_usec <= y->tv_usec)
|
||||
return 1;
|
||||
else return 0;
|
||||
}
|
||||
else return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare two response-ip client info entries for the purpose of mesh state
|
||||
* compare. It returns 0 if ci_a and ci_b are considered equal; otherwise
|
||||
|
@ -275,6 +206,7 @@ mesh_create(struct module_stack* stack, struct module_env* env)
|
|||
mesh->stats_jostled = 0;
|
||||
mesh->stats_dropped = 0;
|
||||
mesh->ans_expired = 0;
|
||||
mesh->ans_cachedb = 0;
|
||||
mesh->max_reply_states = env->cfg->num_queries_per_thread;
|
||||
mesh->max_forever_states = (mesh->max_reply_states+1)/2;
|
||||
#ifndef S_SPLINT_S
|
||||
|
@ -517,6 +449,8 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
|
|||
comm_point_send_reply(rep);
|
||||
return;
|
||||
}
|
||||
/* set detached (it is now) */
|
||||
mesh->num_detached_states++;
|
||||
if(unique)
|
||||
mesh_state_make_unique(s);
|
||||
s->s.rpz_passthru = rpz_passthru;
|
||||
|
@ -525,13 +459,14 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
|
|||
s->s.edns_opts_front_in = edns_opt_copy_region(edns->opt_list_in,
|
||||
s->s.region);
|
||||
if(!s->s.edns_opts_front_in) {
|
||||
log_err("mesh_state_create: out of memory; SERVFAIL");
|
||||
log_err("edns_opt_copy_region: out of memory; SERVFAIL");
|
||||
if(!inplace_cb_reply_servfail_call(mesh->env, qinfo, NULL,
|
||||
NULL, LDNS_RCODE_SERVFAIL, edns, rep, mesh->env->scratch, mesh->env->now_tv))
|
||||
edns->opt_list_inplace_cb_out = NULL;
|
||||
error_encode(r_buffer, LDNS_RCODE_SERVFAIL,
|
||||
qinfo, qid, qflags, edns);
|
||||
comm_point_send_reply(rep);
|
||||
mesh_state_delete(&s->s);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -543,8 +478,6 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
|
|||
#endif
|
||||
rbtree_insert(&mesh->all, &s->node);
|
||||
log_assert(n != NULL);
|
||||
/* set detached (it is now) */
|
||||
mesh->num_detached_states++;
|
||||
added = 1;
|
||||
}
|
||||
if(!s->reply_list && !s->cb_list) {
|
||||
|
@ -637,6 +570,8 @@ mesh_new_callback(struct mesh_area* mesh, struct query_info* qinfo,
|
|||
if(!s) {
|
||||
return 0;
|
||||
}
|
||||
/* set detached (it is now) */
|
||||
mesh->num_detached_states++;
|
||||
if(unique)
|
||||
mesh_state_make_unique(s);
|
||||
s->s.rpz_passthru = rpz_passthru;
|
||||
|
@ -644,6 +579,7 @@ mesh_new_callback(struct mesh_area* mesh, struct query_info* qinfo,
|
|||
s->s.edns_opts_front_in = edns_opt_copy_region(edns->opt_list_in,
|
||||
s->s.region);
|
||||
if(!s->s.edns_opts_front_in) {
|
||||
mesh_state_delete(&s->s);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -654,8 +590,6 @@ mesh_new_callback(struct mesh_area* mesh, struct query_info* qinfo,
|
|||
#endif
|
||||
rbtree_insert(&mesh->all, &s->node);
|
||||
log_assert(n != NULL);
|
||||
/* set detached (it is now) */
|
||||
mesh->num_detached_states++;
|
||||
added = 1;
|
||||
}
|
||||
if(!s->reply_list && !s->cb_list) {
|
||||
|
@ -672,6 +606,8 @@ mesh_new_callback(struct mesh_area* mesh, struct query_info* qinfo,
|
|||
}
|
||||
/* add serve expired timer if not already there */
|
||||
if(timeout && !mesh_serve_expired_init(s, timeout)) {
|
||||
if(added)
|
||||
mesh_state_delete(&s->s);
|
||||
return 0;
|
||||
}
|
||||
/* update statistics */
|
||||
|
@ -773,7 +709,7 @@ static void mesh_schedule_prefetch(struct mesh_area* mesh,
|
|||
* attached its own ECS data. */
|
||||
static void mesh_schedule_prefetch_subnet(struct mesh_area* mesh,
|
||||
struct query_info* qinfo, uint16_t qflags, time_t leeway, int run,
|
||||
int rpz_passthru, struct comm_reply* rep, struct edns_option* edns_list)
|
||||
int rpz_passthru, struct sockaddr_storage* addr, struct edns_option* edns_list)
|
||||
{
|
||||
struct mesh_state* s = NULL;
|
||||
struct edns_option* opt = NULL;
|
||||
|
@ -803,20 +739,10 @@ static void mesh_schedule_prefetch_subnet(struct mesh_area* mesh,
|
|||
return;
|
||||
}
|
||||
} else {
|
||||
/* Fake the ECS data from the client's IP */
|
||||
struct ecs_data ecs;
|
||||
memset(&ecs, 0, sizeof(ecs));
|
||||
subnet_option_from_ss(&rep->client_addr, &ecs, mesh->env->cfg);
|
||||
if(ecs.subnet_validdata == 0) {
|
||||
log_err("prefetch_subnet subnet_option_from_ss: invalid data");
|
||||
return;
|
||||
}
|
||||
subnet_ecs_opt_list_append(&ecs, &s->s.edns_opts_front_in,
|
||||
&s->s, s->s.region);
|
||||
if(!s->s.edns_opts_front_in) {
|
||||
log_err("prefetch_subnet subnet_ecs_opt_list_append: out of memory");
|
||||
return;
|
||||
}
|
||||
/* Store the client's address. Later in the subnet module,
|
||||
* it is decided whether to include an ECS option or not.
|
||||
*/
|
||||
s->s.client_addr = *addr;
|
||||
}
|
||||
#ifdef UNBOUND_DEBUG
|
||||
n =
|
||||
|
@ -863,14 +789,14 @@ static void mesh_schedule_prefetch_subnet(struct mesh_area* mesh,
|
|||
|
||||
void mesh_new_prefetch(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
uint16_t qflags, time_t leeway, int rpz_passthru,
|
||||
struct comm_reply* rep, struct edns_option* opt_list)
|
||||
struct sockaddr_storage* addr, struct edns_option* opt_list)
|
||||
{
|
||||
(void)addr;
|
||||
(void)opt_list;
|
||||
(void)rep;
|
||||
#ifdef CLIENT_SUBNET
|
||||
if(rep)
|
||||
if(addr)
|
||||
mesh_schedule_prefetch_subnet(mesh, qinfo, qflags, leeway, 1,
|
||||
rpz_passthru, rep, opt_list);
|
||||
rpz_passthru, addr, opt_list);
|
||||
else
|
||||
#endif
|
||||
mesh_schedule_prefetch(mesh, qinfo, qflags, leeway, 1,
|
||||
|
@ -970,12 +896,6 @@ mesh_state_create(struct module_env* env, struct query_info* qinfo,
|
|||
return mstate;
|
||||
}
|
||||
|
||||
int
|
||||
mesh_state_is_unique(struct mesh_state* mstate)
|
||||
{
|
||||
return mstate->unique != NULL;
|
||||
}
|
||||
|
||||
void
|
||||
mesh_state_make_unique(struct mesh_state* mstate)
|
||||
{
|
||||
|
@ -1251,7 +1171,7 @@ mesh_do_callback(struct mesh_state* m, int rcode, struct reply_info* rep,
|
|||
else secure = 0;
|
||||
if(!rep && rcode == LDNS_RCODE_NOERROR)
|
||||
rcode = LDNS_RCODE_SERVFAIL;
|
||||
if(!rcode && (rep->security == sec_status_bogus ||
|
||||
if(!rcode && rep && (rep->security == sec_status_bogus ||
|
||||
rep->security == sec_status_secure_sentinel_fail)) {
|
||||
if(!(reason = errinf_to_str_bogus(&m->s)))
|
||||
rcode = LDNS_RCODE_SERVFAIL;
|
||||
|
@ -1291,7 +1211,8 @@ mesh_do_callback(struct mesh_state* m, int rcode, struct reply_info* rep,
|
|||
} else {
|
||||
fptr_ok(fptr_whitelist_mesh_cb(r->cb));
|
||||
(*r->cb)(r->cb_arg, LDNS_RCODE_NOERROR, r->buf,
|
||||
rep->security, reason, was_ratelimited);
|
||||
(rep?rep->security:sec_status_unchecked),
|
||||
reason, was_ratelimited);
|
||||
}
|
||||
}
|
||||
free(reason);
|
||||
|
@ -1311,10 +1232,36 @@ mesh_is_rpz_respip_tcponly_action(struct mesh_state const* m)
|
|||
}
|
||||
|
||||
static inline int
|
||||
mesh_is_udp(struct mesh_reply const* r) {
|
||||
mesh_is_udp(struct mesh_reply const* r)
|
||||
{
|
||||
return r->query_reply.c->type == comm_udp;
|
||||
}
|
||||
|
||||
static inline void
|
||||
mesh_find_and_attach_ede_and_reason(struct mesh_state* m,
|
||||
struct reply_info* rep, struct mesh_reply* r)
|
||||
{
|
||||
/* OLD note:
|
||||
* During validation the EDE code can be received via two
|
||||
* code paths. One code path fills the reply_info EDE, and
|
||||
* the other fills it in the errinf_strlist. These paths
|
||||
* intersect at some points, but where is opaque due to
|
||||
* the complexity of the validator. At the time of writing
|
||||
* we make the choice to prefer the EDE from errinf_strlist
|
||||
* but a compelling reason to do otherwise is just as valid
|
||||
* NEW note:
|
||||
* The compelling reason is that with caching support, the value
|
||||
* in the reply_info is cached.
|
||||
* The reason members of the reply_info struct should be
|
||||
* updated as they are already cached. No reason to
|
||||
* try and find the EDE information in errinf anymore.
|
||||
*/
|
||||
if(rep->reason_bogus != LDNS_EDE_NONE) {
|
||||
edns_opt_list_append_ede(&r->edns.opt_list_out,
|
||||
m->s.region, rep->reason_bogus, rep->reason_bogus_str);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send reply to mesh reply entry
|
||||
* @param m: mesh state to send it for.
|
||||
|
@ -1406,35 +1353,12 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
|
|||
&r->edns, &r->query_reply, m->s.region, &r->start_time))
|
||||
r->edns.opt_list_inplace_cb_out = NULL;
|
||||
}
|
||||
/* Send along EDE BOGUS EDNS0 option when answer is bogus */
|
||||
if(m->s.env->cfg->ede && rcode == LDNS_RCODE_SERVFAIL &&
|
||||
m->s.env->need_to_validate && (!(r->qflags&BIT_CD) ||
|
||||
m->s.env->cfg->ignore_cd) && rep &&
|
||||
(rep->security <= sec_status_bogus ||
|
||||
rep->security == sec_status_secure_sentinel_fail)) {
|
||||
char *reason = m->s.env->cfg->val_log_level >= 2
|
||||
? errinf_to_str_bogus(&m->s) : NULL;
|
||||
|
||||
/* During validation the EDE code can be received via two
|
||||
* code paths. One code path fills the reply_info EDE, and
|
||||
* the other fills it in the errinf_strlist. These paths
|
||||
* intersect at some points, but where is opaque due to
|
||||
* the complexity of the validator. At the time of writing
|
||||
* we make the choice to prefer the EDE from errinf_strlist
|
||||
* but a compelling reason to do otherwise is just as valid
|
||||
*/
|
||||
sldns_ede_code reason_bogus = errinf_to_reason_bogus(&m->s);
|
||||
if ((reason_bogus == LDNS_EDE_DNSSEC_BOGUS &&
|
||||
rep->reason_bogus != LDNS_EDE_NONE) ||
|
||||
reason_bogus == LDNS_EDE_NONE) {
|
||||
reason_bogus = rep->reason_bogus;
|
||||
}
|
||||
|
||||
if(reason_bogus != LDNS_EDE_NONE) {
|
||||
edns_opt_list_append_ede(&r->edns.opt_list_out,
|
||||
m->s.region, reason_bogus, reason);
|
||||
}
|
||||
free(reason);
|
||||
/* Send along EDE EDNS0 option when SERVFAILing; usually
|
||||
* DNSSEC validation failures */
|
||||
/* Since we are SERVFAILing here, CD bit and rep->security
|
||||
* is already handled. */
|
||||
if(m->s.env->cfg->ede && rep) {
|
||||
mesh_find_and_attach_ede_and_reason(m, rep, r);
|
||||
}
|
||||
error_encode(r_buffer, rcode, &m->s.qinfo, r->qid,
|
||||
r->qflags, &r->edns);
|
||||
|
@ -1449,6 +1373,16 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
|
|||
r->edns.bits &= EDNS_DO;
|
||||
m->s.qinfo.qname = r->qname;
|
||||
m->s.qinfo.local_alias = r->local_alias;
|
||||
|
||||
/* Attach EDE without SERVFAIL if the validation failed.
|
||||
* Need to explicitly check for rep->security otherwise failed
|
||||
* validation paths may attach to a secure answer. */
|
||||
if(m->s.env->cfg->ede && rep &&
|
||||
(rep->security <= sec_status_bogus ||
|
||||
rep->security == sec_status_secure_sentinel_fail)) {
|
||||
mesh_find_and_attach_ede_and_reason(m, rep, r);
|
||||
}
|
||||
|
||||
if(!inplace_cb_reply_call(m->s.env, &m->s.qinfo, &m->s, rep,
|
||||
LDNS_RCODE_NOERROR, &r->edns, &r->query_reply, m->s.region, &r->start_time) ||
|
||||
!reply_info_answer_encode(&m->s.qinfo, rep, r->qid,
|
||||
|
@ -1503,6 +1437,7 @@ void mesh_query_done(struct mesh_state* mstate)
|
|||
struct reply_info* rep = (mstate->s.return_msg?
|
||||
mstate->s.return_msg->rep:NULL);
|
||||
struct timeval tv = {0, 0};
|
||||
int i = 0;
|
||||
/* No need for the serve expired timer anymore; we are going to reply. */
|
||||
if(mstate->s.serve_expired_data) {
|
||||
comm_timer_delete(mstate->s.serve_expired_data->timer);
|
||||
|
@ -1522,6 +1457,7 @@ void mesh_query_done(struct mesh_state* mstate)
|
|||
}
|
||||
}
|
||||
for(r = mstate->reply_list; r; r = r->next) {
|
||||
i++;
|
||||
tv = r->start_time;
|
||||
|
||||
/* if a response-ip address block has been stored the
|
||||
|
@ -1533,16 +1469,6 @@ void mesh_query_done(struct mesh_state* mstate)
|
|||
mstate->s.qinfo.qclass, r->local_alias,
|
||||
&r->query_reply.client_addr,
|
||||
r->query_reply.client_addrlen);
|
||||
if(mstate->s.env->cfg->stat_extended &&
|
||||
mstate->s.respip_action_info->rpz_used) {
|
||||
if(mstate->s.respip_action_info->rpz_disabled)
|
||||
mstate->s.env->mesh->rpz_action[RPZ_DISABLED_ACTION]++;
|
||||
if(mstate->s.respip_action_info->rpz_cname_override)
|
||||
mstate->s.env->mesh->rpz_action[RPZ_CNAME_OVERRIDE_ACTION]++;
|
||||
else
|
||||
mstate->s.env->mesh->rpz_action[respip_action_to_rpz_action(
|
||||
mstate->s.respip_action_info->action)]++;
|
||||
}
|
||||
}
|
||||
|
||||
/* if this query is determined to be dropped during the
|
||||
|
@ -1573,6 +1499,27 @@ void mesh_query_done(struct mesh_state* mstate)
|
|||
prev_buffer = r_buffer;
|
||||
}
|
||||
}
|
||||
/* Account for each reply sent. */
|
||||
if(i > 0 && mstate->s.respip_action_info &&
|
||||
mstate->s.respip_action_info->addrinfo &&
|
||||
mstate->s.env->cfg->stat_extended &&
|
||||
mstate->s.respip_action_info->rpz_used) {
|
||||
if(mstate->s.respip_action_info->rpz_disabled)
|
||||
mstate->s.env->mesh->rpz_action[RPZ_DISABLED_ACTION] += i;
|
||||
if(mstate->s.respip_action_info->rpz_cname_override)
|
||||
mstate->s.env->mesh->rpz_action[RPZ_CNAME_OVERRIDE_ACTION] += i;
|
||||
else
|
||||
mstate->s.env->mesh->rpz_action[respip_action_to_rpz_action(
|
||||
mstate->s.respip_action_info->action)] += i;
|
||||
}
|
||||
if(!mstate->s.is_drop && i > 0) {
|
||||
if(mstate->s.env->cfg->stat_extended
|
||||
&& mstate->s.is_cachedb_answer) {
|
||||
mstate->s.env->mesh->ans_cachedb += i;
|
||||
}
|
||||
}
|
||||
|
||||
/* Mesh area accounting */
|
||||
if(mstate->reply_list) {
|
||||
mstate->reply_list = NULL;
|
||||
if(!mstate->reply_list && !mstate->cb_list) {
|
||||
|
@ -1585,6 +1532,7 @@ void mesh_query_done(struct mesh_state* mstate)
|
|||
mstate->s.env->mesh->num_detached_states++;
|
||||
}
|
||||
mstate->replies_sent = 1;
|
||||
|
||||
while((c = mstate->cb_list) != NULL) {
|
||||
/* take this cb off the list; so that the list can be
|
||||
* changed, eg. by adds from the callback routine */
|
||||
|
@ -1842,9 +1790,21 @@ mesh_continue(struct mesh_area* mesh, struct mesh_state* mstate,
|
|||
if(s == module_finished) {
|
||||
if(mstate->s.curmod == 0) {
|
||||
struct query_info* qinfo = NULL;
|
||||
struct edns_option* opt_list = NULL;
|
||||
struct sockaddr_storage addr;
|
||||
uint16_t qflags;
|
||||
int rpz_p = 0;
|
||||
|
||||
#ifdef CLIENT_SUBNET
|
||||
struct edns_option* ecs;
|
||||
if(mstate->s.need_refetch && mstate->reply_list &&
|
||||
modstack_find(&mesh->mods, "subnetcache") != -1 &&
|
||||
mstate->s.env->unique_mesh) {
|
||||
addr = mstate->reply_list->query_reply.client_addr;
|
||||
} else
|
||||
#endif
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
|
||||
mesh_query_done(mstate);
|
||||
mesh_walk_supers(mesh, mstate);
|
||||
|
||||
|
@ -1854,13 +1814,28 @@ mesh_continue(struct mesh_area* mesh, struct mesh_state* mstate,
|
|||
* we need to make a copy of the query info here. */
|
||||
if(mstate->s.need_refetch) {
|
||||
mesh_copy_qinfo(mstate, &qinfo, &qflags);
|
||||
#ifdef CLIENT_SUBNET
|
||||
/* Make also a copy of the ecs option if any */
|
||||
if((ecs = edns_opt_list_find(
|
||||
mstate->s.edns_opts_front_in,
|
||||
mstate->s.env->cfg->client_subnet_opcode)) != NULL) {
|
||||
(void)edns_opt_list_append(&opt_list,
|
||||
ecs->opt_code, ecs->opt_len,
|
||||
ecs->opt_data,
|
||||
mstate->s.env->scratch);
|
||||
}
|
||||
#endif
|
||||
rpz_p = mstate->s.rpz_passthru;
|
||||
}
|
||||
|
||||
mesh_state_delete(&mstate->s);
|
||||
if(qinfo) {
|
||||
mesh_schedule_prefetch(mesh, qinfo, qflags,
|
||||
0, 1, rpz_p);
|
||||
mesh_state_delete(&mstate->s);
|
||||
mesh_new_prefetch(mesh, qinfo, qflags, 0,
|
||||
rpz_p,
|
||||
addr.ss_family!=AF_UNSPEC?&addr:NULL,
|
||||
opt_list);
|
||||
} else {
|
||||
mesh_state_delete(&mstate->s);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -1968,6 +1943,7 @@ mesh_stats_clear(struct mesh_area* mesh)
|
|||
mesh->ans_secure = 0;
|
||||
mesh->ans_bogus = 0;
|
||||
mesh->ans_expired = 0;
|
||||
mesh->ans_cachedb = 0;
|
||||
memset(&mesh->ans_rcode[0], 0, sizeof(size_t)*UB_STATS_RCODE_NUM);
|
||||
memset(&mesh->rpz_action[0], 0, sizeof(size_t)*UB_STATS_RPZ_ACTION_NUM);
|
||||
mesh->ans_nodata = 0;
|
||||
|
@ -2104,6 +2080,7 @@ mesh_serve_expired_callback(void* arg)
|
|||
struct timeval tv = {0, 0};
|
||||
int must_validate = (!(qstate->query_flags&BIT_CD)
|
||||
|| qstate->env->cfg->ignore_cd) && qstate->env->need_to_validate;
|
||||
int i = 0;
|
||||
if(!qstate->serve_expired_data) return;
|
||||
verbose(VERB_ALGO, "Serve expired: Trying to reply with expired data");
|
||||
comm_timer_delete(qstate->serve_expired_data->timer);
|
||||
|
@ -2175,6 +2152,7 @@ mesh_serve_expired_callback(void* arg)
|
|||
log_dns_msg("Serve expired lookup", &qstate->qinfo, msg->rep);
|
||||
|
||||
for(r = mstate->reply_list; r; r = r->next) {
|
||||
i++;
|
||||
tv = r->start_time;
|
||||
|
||||
/* If address info is returned, it means the action should be an
|
||||
|
@ -2184,16 +2162,6 @@ mesh_serve_expired_callback(void* arg)
|
|||
qstate->qinfo.qtype, qstate->qinfo.qclass,
|
||||
r->local_alias, &r->query_reply.client_addr,
|
||||
r->query_reply.client_addrlen);
|
||||
|
||||
if(qstate->env->cfg->stat_extended && actinfo.rpz_used) {
|
||||
if(actinfo.rpz_disabled)
|
||||
qstate->env->mesh->rpz_action[RPZ_DISABLED_ACTION]++;
|
||||
if(actinfo.rpz_cname_override)
|
||||
qstate->env->mesh->rpz_action[RPZ_CNAME_OVERRIDE_ACTION]++;
|
||||
else
|
||||
qstate->env->mesh->rpz_action[
|
||||
respip_action_to_rpz_action(actinfo.action)]++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Add EDE Stale Answer (RCF8914). Ignore global ede as this is
|
||||
|
@ -2213,11 +2181,23 @@ mesh_serve_expired_callback(void* arg)
|
|||
tcp_req_info_remove_mesh_state(r->query_reply.c->tcp_req_info, mstate);
|
||||
prev = r;
|
||||
prev_buffer = r_buffer;
|
||||
|
||||
/* Account for each reply sent. */
|
||||
mesh->ans_expired++;
|
||||
|
||||
}
|
||||
/* Account for each reply sent. */
|
||||
if(i > 0) {
|
||||
mesh->ans_expired += i;
|
||||
if(actinfo.addrinfo && qstate->env->cfg->stat_extended &&
|
||||
actinfo.rpz_used) {
|
||||
if(actinfo.rpz_disabled)
|
||||
qstate->env->mesh->rpz_action[RPZ_DISABLED_ACTION] += i;
|
||||
if(actinfo.rpz_cname_override)
|
||||
qstate->env->mesh->rpz_action[RPZ_CNAME_OVERRIDE_ACTION] += i;
|
||||
else
|
||||
qstate->env->mesh->rpz_action[
|
||||
respip_action_to_rpz_action(actinfo.action)] += i;
|
||||
}
|
||||
}
|
||||
|
||||
/* Mesh area accounting */
|
||||
if(mstate->reply_list) {
|
||||
mstate->reply_list = NULL;
|
||||
if(!mstate->reply_list && !mstate->cb_list) {
|
||||
|
@ -2228,6 +2208,7 @@ mesh_serve_expired_callback(void* arg)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
while((c = mstate->cb_list) != NULL) {
|
||||
/* take this cb off the list; so that the list can be
|
||||
* changed, eg. by adds from the callback routine */
|
||||
|
|
|
@ -114,6 +114,8 @@ struct mesh_area {
|
|||
size_t stats_dropped;
|
||||
/** stats, number of expired replies sent */
|
||||
size_t ans_expired;
|
||||
/** stats, number of cached replies from cachedb */
|
||||
size_t ans_cachedb;
|
||||
/** number of replies sent */
|
||||
size_t replies_sent;
|
||||
/** sum of waiting times for the replies */
|
||||
|
@ -335,13 +337,13 @@ int mesh_new_callback(struct mesh_area* mesh, struct query_info* qinfo,
|
|||
* @param leeway: TTL leeway what to expire earlier for this update.
|
||||
* @param rpz_passthru: if true, the rpz passthru was previously found and
|
||||
* further rpz processing is stopped.
|
||||
* @param rep: comm_reply for the client; to be used when subnet is enabled.
|
||||
* @param addr: sockaddr_storage for the client; to be used with subnet.
|
||||
* @param opt_list: edns opt_list from the client; to be used when subnet is
|
||||
* enabled.
|
||||
*/
|
||||
void mesh_new_prefetch(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
uint16_t qflags, time_t leeway, int rpz_passthru,
|
||||
struct comm_reply* rep, struct edns_option* opt_list);
|
||||
struct sockaddr_storage* addr, struct edns_option* opt_list);
|
||||
|
||||
/**
|
||||
* Handle new event from the wire. A serviced query has returned.
|
||||
|
@ -478,14 +480,6 @@ struct mesh_state* mesh_state_create(struct module_env* env,
|
|||
struct query_info* qinfo, struct respip_client_info* cinfo,
|
||||
uint16_t qflags, int prime, int valrec);
|
||||
|
||||
/**
|
||||
* Check if the mesh state is unique.
|
||||
* A unique mesh state uses it's unique member to point to itself, else NULL.
|
||||
* @param mstate: mesh state to check.
|
||||
* @return true if the mesh state is unique, false otherwise.
|
||||
*/
|
||||
int mesh_state_is_unique(struct mesh_state* mstate);
|
||||
|
||||
/**
|
||||
* Make a mesh state unique.
|
||||
* A unique mesh state uses it's unique member to point to itself.
|
||||
|
|
|
@ -120,12 +120,16 @@ modstack_config(struct module_stack* stack, const char* module_conf)
|
|||
stack->mod[i] = module_factory(&module_conf);
|
||||
if(!stack->mod[i]) {
|
||||
char md[256];
|
||||
char * s = md;
|
||||
snprintf(md, sizeof(md), "%s", module_conf);
|
||||
if(strchr(md, ' ')) *(strchr(md, ' ')) = 0;
|
||||
if(strchr(md, '\t')) *(strchr(md, '\t')) = 0;
|
||||
/* Leading spaces are present on errors. */
|
||||
while (*s && isspace((unsigned char)*s))
|
||||
s++;
|
||||
if(strchr(s, ' ')) *(strchr(s, ' ')) = 0;
|
||||
if(strchr(s, '\t')) *(strchr(s, '\t')) = 0;
|
||||
log_err("Unknown value in module-config, module: '%s'."
|
||||
" This module is not present (not compiled in),"
|
||||
" See the list of linked modules with unbound -V", md);
|
||||
" See the list of linked modules with unbound -V", s);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -551,8 +551,27 @@ reuse_tcp_find(struct outside_network* outnet, struct sockaddr_storage* addr,
|
|||
log_assert(&key_p != ((struct reuse_tcp*)result)->pending);
|
||||
}
|
||||
/* not found, return null */
|
||||
|
||||
/* It is possible that we search for something before the first element
|
||||
* in the tree. Replace a null pointer with the first element.
|
||||
*/
|
||||
if (!result) {
|
||||
verbose(VERB_CLIENT, "reuse_tcp_find: taking first");
|
||||
result = rbtree_first(&outnet->tcp_reuse);
|
||||
}
|
||||
|
||||
if(!result || result == RBTREE_NULL)
|
||||
return NULL;
|
||||
|
||||
/* It is possible that we got the previous address, but that the
|
||||
* address we are looking for is in the tree. If the address we got
|
||||
* is less than the address we are looking, then take the next entry.
|
||||
*/
|
||||
if (reuse_cmp_addrportssl(result->key, &key_p.reuse) < 0) {
|
||||
verbose(VERB_CLIENT, "reuse_tcp_find: key too low");
|
||||
result = rbtree_next(result);
|
||||
}
|
||||
|
||||
verbose(VERB_CLIENT, "reuse_tcp_find check inexact match");
|
||||
/* inexact match, find one of possibly several connections to the
|
||||
* same destination address, with the correct port, ssl, and
|
||||
|
@ -620,6 +639,15 @@ outnet_tcp_take_into_use(struct waiting_tcp* w)
|
|||
log_assert(w->addrlen > 0);
|
||||
pend->c->tcp_do_toggle_rw = 0;
|
||||
pend->c->tcp_do_close = 0;
|
||||
|
||||
/* Consistency check, if we have ssl_upstream but no sslctx, then
|
||||
* log an error and return failure.
|
||||
*/
|
||||
if (w->ssl_upstream && !w->outnet->sslctx) {
|
||||
log_err("SSL upstream requested but no SSL context");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* open socket */
|
||||
s = outnet_get_tcp_fd(&w->addr, w->addrlen, w->outnet->tcp_mss, w->outnet->ip_dscp);
|
||||
|
||||
|
|
|
@ -1188,6 +1188,22 @@ rpz_find_zone(struct local_zones* zones, uint8_t* qname, size_t qname_len, uint1
|
|||
return z;
|
||||
}
|
||||
|
||||
/** Find entry for RR type in the list of rrsets for the clientip. */
|
||||
static struct local_rrset*
|
||||
rpz_find_synthesized_rrset(uint16_t qtype,
|
||||
struct clientip_synthesized_rr* data)
|
||||
{
|
||||
struct local_rrset* cursor = data->data;
|
||||
while( cursor != NULL) {
|
||||
struct packed_rrset_key* packed_rrset = &cursor->rrset->rk;
|
||||
if(htons(qtype) == packed_rrset->type) {
|
||||
return cursor;
|
||||
}
|
||||
cursor = cursor->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove RR from RPZ's local-data
|
||||
* @param z: local-zone for RPZ, holding write lock
|
||||
|
@ -1270,15 +1286,15 @@ rpz_rrset_delete_rr(struct resp_addr* raddr, uint16_t rr_type, uint8_t* rdata,
|
|||
|
||||
}
|
||||
|
||||
/** Remove RR from RPZ's local-zone */
|
||||
/** Remove RR from rpz localzones structure */
|
||||
static void
|
||||
rpz_remove_qname_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
|
||||
enum rpz_action a, uint16_t rr_type, uint16_t rr_class,
|
||||
uint8_t* rdatawl, size_t rdatalen)
|
||||
rpz_remove_local_zones_trigger(struct local_zones* zones, uint8_t* dname,
|
||||
size_t dnamelen, enum rpz_action a, uint16_t rr_type,
|
||||
uint16_t rr_class, uint8_t* rdatawl, size_t rdatalen)
|
||||
{
|
||||
struct local_zone* z;
|
||||
int delete_zone = 1;
|
||||
z = rpz_find_zone(r->local_zones, dname, dnamelen, rr_class,
|
||||
z = rpz_find_zone(zones, dname, dnamelen, rr_class,
|
||||
1 /* only exact */, 1 /* wr lock */, 1 /* keep lock*/);
|
||||
if(!z) {
|
||||
verbose(VERB_ALGO, "rpz: cannot remove RR from IXFR, "
|
||||
|
@ -1290,15 +1306,24 @@ rpz_remove_qname_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
|
|||
dnamelen, rr_type, rdatawl, rdatalen);
|
||||
else if(a != localzone_type_to_rpz_action(z->type)) {
|
||||
lock_rw_unlock(&z->lock);
|
||||
lock_rw_unlock(&r->local_zones->lock);
|
||||
lock_rw_unlock(&zones->lock);
|
||||
return;
|
||||
}
|
||||
lock_rw_unlock(&z->lock);
|
||||
if(delete_zone) {
|
||||
local_zones_del_zone(r->local_zones, z);
|
||||
local_zones_del_zone(zones, z);
|
||||
}
|
||||
lock_rw_unlock(&r->local_zones->lock);
|
||||
return;
|
||||
lock_rw_unlock(&zones->lock);
|
||||
}
|
||||
|
||||
/** Remove RR from RPZ's local-zone */
|
||||
static void
|
||||
rpz_remove_qname_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
|
||||
enum rpz_action a, uint16_t rr_type, uint16_t rr_class,
|
||||
uint8_t* rdatawl, size_t rdatalen)
|
||||
{
|
||||
rpz_remove_local_zones_trigger(r->local_zones, dname, dnamelen,
|
||||
a, rr_type, rr_class, rdatawl, rdatalen);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1335,15 +1360,159 @@ rpz_remove_response_ip_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
|
|||
lock_rw_unlock(&r->respip_set->lock);
|
||||
}
|
||||
|
||||
/** find and remove type from list of local_rrset entries*/
|
||||
static void
|
||||
del_local_rrset_from_list(struct local_rrset** list_head, uint16_t dtype)
|
||||
{
|
||||
struct local_rrset* prev=NULL, *p=*list_head;
|
||||
while(p && ntohs(p->rrset->rk.type) != dtype) {
|
||||
prev = p;
|
||||
p = p->next;
|
||||
}
|
||||
if(!p)
|
||||
return; /* rrset type not found */
|
||||
/* unlink it */
|
||||
if(prev) prev->next = p->next;
|
||||
else *list_head = p->next;
|
||||
/* no memory recycling for zone deletions ... */
|
||||
}
|
||||
|
||||
/** Delete client-ip trigger RR from its RRset and perhaps also the rrset
|
||||
* from the linked list. Returns if the local data is empty and the node can
|
||||
* be deleted too, or not. */
|
||||
static int rpz_remove_clientip_rr(struct clientip_synthesized_rr* node,
|
||||
uint16_t rr_type, uint8_t* rdatawl, size_t rdatalen)
|
||||
{
|
||||
struct local_rrset* rrset;
|
||||
struct packed_rrset_data* d;
|
||||
size_t index;
|
||||
rrset = rpz_find_synthesized_rrset(rr_type, node);
|
||||
if(rrset == NULL)
|
||||
return 0; /* type not found, ignore */
|
||||
d = (struct packed_rrset_data*)rrset->rrset->entry.data;
|
||||
if(!packed_rrset_find_rr(d, rdatawl, rdatalen, &index))
|
||||
return 0; /* RR not found, ignore */
|
||||
if(d->count == 1) {
|
||||
/* regional alloc'd */
|
||||
/* delete the type entry from the list */
|
||||
del_local_rrset_from_list(&node->data, rr_type);
|
||||
/* if the list is empty, the node can be removed too */
|
||||
if(node->data == NULL)
|
||||
return 1;
|
||||
} else if (d->count > 1) {
|
||||
if(!local_rrset_remove_rr(d, index))
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** remove trigger RR from clientip_syntheized set tree. */
|
||||
static void
|
||||
rpz_clientip_remove_trigger_rr(struct clientip_synthesized_rrset* set,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen, int net,
|
||||
enum rpz_action a, uint16_t rr_type, uint8_t* rdatawl, size_t rdatalen)
|
||||
{
|
||||
struct clientip_synthesized_rr* node;
|
||||
int delete_node = 1;
|
||||
|
||||
lock_rw_wrlock(&set->lock);
|
||||
node = (struct clientip_synthesized_rr*)addr_tree_find(&set->entries,
|
||||
addr, addrlen, net);
|
||||
if(node == NULL) {
|
||||
/* netblock not found */
|
||||
verbose(VERB_ALGO, "rpz: cannot remove RR from IXFR, "
|
||||
"RPZ address, netblock not found");
|
||||
lock_rw_unlock(&set->lock);
|
||||
return;
|
||||
}
|
||||
lock_rw_wrlock(&node->lock);
|
||||
if(a == RPZ_LOCAL_DATA_ACTION) {
|
||||
/* remove RR, signal whether entry can be removed */
|
||||
delete_node = rpz_remove_clientip_rr(node, rr_type, rdatawl,
|
||||
rdatalen);
|
||||
} else if(a != node->action) {
|
||||
/* ignore the RR with different action specification */
|
||||
delete_node = 0;
|
||||
}
|
||||
if(delete_node) {
|
||||
rbtree_delete(&set->entries, node->node.node.key);
|
||||
}
|
||||
lock_rw_unlock(&set->lock);
|
||||
lock_rw_unlock(&node->lock);
|
||||
if(delete_node) {
|
||||
lock_rw_destroy(&node->lock);
|
||||
}
|
||||
}
|
||||
|
||||
/** Remove clientip trigger RR from RPZ. */
|
||||
static void
|
||||
rpz_remove_clientip_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
|
||||
enum rpz_action a, uint16_t rr_type, uint8_t* rdatawl, size_t rdatalen)
|
||||
{
|
||||
struct sockaddr_storage addr;
|
||||
socklen_t addrlen;
|
||||
int net, af;
|
||||
if(a == RPZ_INVALID_ACTION)
|
||||
return;
|
||||
if(!netblockdnametoaddr(dname, dnamelen, &addr, &addrlen, &net, &af))
|
||||
return;
|
||||
rpz_clientip_remove_trigger_rr(r->client_set, &addr, addrlen, net,
|
||||
a, rr_type, rdatawl, rdatalen);
|
||||
}
|
||||
|
||||
/** Remove nsip trigger RR from RPZ. */
|
||||
static void
|
||||
rpz_remove_nsip_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
|
||||
enum rpz_action a, uint16_t rr_type, uint8_t* rdatawl, size_t rdatalen)
|
||||
{
|
||||
struct sockaddr_storage addr;
|
||||
socklen_t addrlen;
|
||||
int net, af;
|
||||
if(a == RPZ_INVALID_ACTION)
|
||||
return;
|
||||
if(!netblockdnametoaddr(dname, dnamelen, &addr, &addrlen, &net, &af))
|
||||
return;
|
||||
rpz_clientip_remove_trigger_rr(r->ns_set, &addr, addrlen, net,
|
||||
a, rr_type, rdatawl, rdatalen);
|
||||
}
|
||||
|
||||
/** Remove nsdname trigger RR from RPZ. */
|
||||
static void
|
||||
rpz_remove_nsdname_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
|
||||
enum rpz_action a, uint16_t rr_type, uint16_t rr_class,
|
||||
uint8_t* rdatawl, size_t rdatalen)
|
||||
{
|
||||
uint8_t* dname_stripped = NULL;
|
||||
size_t dnamelen_stripped = 0;
|
||||
if(a == RPZ_INVALID_ACTION)
|
||||
return;
|
||||
if(!rpz_strip_nsdname_suffix(dname, dnamelen, &dname_stripped,
|
||||
&dnamelen_stripped))
|
||||
return;
|
||||
rpz_remove_local_zones_trigger(r->nsdname_zones, dname_stripped,
|
||||
dnamelen_stripped, a, rr_type, rr_class, rdatawl, rdatalen);
|
||||
free(dname_stripped);
|
||||
}
|
||||
|
||||
void
|
||||
rpz_remove_rr(struct rpz* r, size_t aznamelen, uint8_t* dname, size_t dnamelen,
|
||||
uint16_t rr_type, uint16_t rr_class, uint8_t* rdatawl, size_t rdatalen)
|
||||
rpz_remove_rr(struct rpz* r, uint8_t* azname, size_t aznamelen, uint8_t* dname,
|
||||
size_t dnamelen, uint16_t rr_type, uint16_t rr_class, uint8_t* rdatawl,
|
||||
size_t rdatalen)
|
||||
{
|
||||
size_t policydnamelen;
|
||||
enum rpz_trigger t;
|
||||
enum rpz_action a;
|
||||
uint8_t* policydname;
|
||||
|
||||
if(rpz_type_ignored(rr_type)) {
|
||||
/* this rpz action is not valid, eg. this is the SOA or NS RR */
|
||||
return;
|
||||
}
|
||||
if(!dname_subdomain_c(dname, azname)) {
|
||||
/* not subdomain of the RPZ zone. */
|
||||
return;
|
||||
}
|
||||
|
||||
if(!(policydname = calloc(1, LDNS_MAX_DOMAINLEN + 1)))
|
||||
return;
|
||||
|
||||
|
@ -1358,13 +1527,28 @@ rpz_remove_rr(struct rpz* r, size_t aznamelen, uint8_t* dname, size_t dnamelen,
|
|||
return;
|
||||
}
|
||||
t = rpz_dname_to_trigger(policydname, policydnamelen);
|
||||
if(t == RPZ_INVALID_TRIGGER) {
|
||||
/* skipping invalid trigger */
|
||||
free(policydname);
|
||||
return;
|
||||
}
|
||||
if(t == RPZ_QNAME_TRIGGER) {
|
||||
rpz_remove_qname_trigger(r, policydname, policydnamelen, a,
|
||||
rr_type, rr_class, rdatawl, rdatalen);
|
||||
} else if(t == RPZ_RESPONSE_IP_TRIGGER) {
|
||||
rpz_remove_response_ip_trigger(r, policydname, policydnamelen,
|
||||
a, rr_type, rdatawl, rdatalen);
|
||||
} else if(t == RPZ_CLIENT_IP_TRIGGER) {
|
||||
rpz_remove_clientip_trigger(r, policydname, policydnamelen, a,
|
||||
rr_type, rdatawl, rdatalen);
|
||||
} else if(t == RPZ_NSIP_TRIGGER) {
|
||||
rpz_remove_nsip_trigger(r, policydname, policydnamelen, a,
|
||||
rr_type, rdatawl, rdatalen);
|
||||
} else if(t == RPZ_NSDNAME_TRIGGER) {
|
||||
rpz_remove_nsdname_trigger(r, policydname, policydnamelen, a,
|
||||
rr_type, rr_class, rdatawl, rdatalen);
|
||||
}
|
||||
/* else it was an unsupported trigger, also skipped. */
|
||||
free(policydname);
|
||||
}
|
||||
|
||||
|
@ -1563,21 +1747,6 @@ rpz_local_encode(struct module_env* env, struct query_info* qinfo,
|
|||
return 1;
|
||||
}
|
||||
|
||||
static struct local_rrset*
|
||||
rpz_find_synthesized_rrset(uint16_t qtype,
|
||||
struct clientip_synthesized_rr* data)
|
||||
{
|
||||
struct local_rrset* cursor = data->data;
|
||||
while( cursor != NULL) {
|
||||
struct packed_rrset_key* packed_rrset = &cursor->rrset->rk;
|
||||
if(htons(qtype) == packed_rrset->type) {
|
||||
return cursor;
|
||||
}
|
||||
cursor = cursor->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** allocate SOA record ubrrsetkey in region */
|
||||
static struct ub_packed_rrset_key*
|
||||
make_soa_ubrrset(struct auth_zone* auth_zone, struct auth_rrset* soa,
|
||||
|
@ -1713,7 +1882,8 @@ rpz_synthesize_nodata(struct rpz* ATTR_UNUSED(r), struct module_qstate* ms,
|
|||
0, /* ns */
|
||||
0, /* ar */
|
||||
0, /* total */
|
||||
sec_status_insecure);
|
||||
sec_status_insecure,
|
||||
LDNS_EDE_NONE);
|
||||
if(msg->rep)
|
||||
msg->rep->authoritative = 1;
|
||||
if(!rpz_add_soa(msg->rep, ms, az))
|
||||
|
@ -1742,7 +1912,8 @@ rpz_synthesize_nxdomain(struct rpz* r, struct module_qstate* ms,
|
|||
0, /* ns */
|
||||
0, /* ar */
|
||||
0, /* total */
|
||||
sec_status_insecure);
|
||||
sec_status_insecure,
|
||||
LDNS_EDE_NONE);
|
||||
if(msg->rep)
|
||||
msg->rep->authoritative = 1;
|
||||
if(!rpz_add_soa(msg->rep, ms, az))
|
||||
|
@ -1772,7 +1943,8 @@ rpz_synthesize_localdata_from_rrset(struct rpz* ATTR_UNUSED(r), struct module_qs
|
|||
0, /* ns */
|
||||
0, /* ar */
|
||||
1, /* total */
|
||||
sec_status_insecure);
|
||||
sec_status_insecure,
|
||||
LDNS_EDE_NONE);
|
||||
if(new_reply_info == NULL) {
|
||||
log_err("out of memory");
|
||||
return NULL;
|
||||
|
|
|
@ -84,10 +84,11 @@ enum rpz_action {
|
|||
RPZ_CNAME_OVERRIDE_ACTION, /* RPZ CNAME action override*/
|
||||
};
|
||||
|
||||
struct clientip_synthesized_rrset{
|
||||
struct clientip_synthesized_rrset {
|
||||
struct regional* region;
|
||||
struct rbtree_type entries;
|
||||
lock_rw_type lock; /* lock on the respip tree */
|
||||
/** lock on the entries tree */
|
||||
lock_rw_type lock;
|
||||
};
|
||||
|
||||
struct clientip_synthesized_rr {
|
||||
|
@ -95,10 +96,6 @@ struct clientip_synthesized_rr {
|
|||
struct addr_tree_node node;
|
||||
/** lock on the node item */
|
||||
lock_rw_type lock;
|
||||
/** tag bitlist */
|
||||
uint8_t* taglist;
|
||||
/** length of the taglist (in bytes) */
|
||||
size_t taglen;
|
||||
/** action for this address span */
|
||||
enum rpz_action action;
|
||||
/** "local data" for this node */
|
||||
|
@ -152,6 +149,7 @@ int rpz_insert_rr(struct rpz* r, uint8_t* azname, size_t aznamelen, uint8_t* dna
|
|||
/**
|
||||
* Delete policy matching RR, used for IXFR.
|
||||
* @param r: the rpz to add the policy to.
|
||||
* @param azname: dname of the auth-zone
|
||||
* @param aznamelen: the length of the auth-zone name
|
||||
* @param dname: dname of the RR
|
||||
* @param dnamelen: length of the dname
|
||||
|
@ -160,9 +158,9 @@ int rpz_insert_rr(struct rpz* r, uint8_t* azname, size_t aznamelen, uint8_t* dna
|
|||
* @param rdatawl: rdata of the RR, prepended with the rdata size
|
||||
* @param rdatalen: length if the RR, including the prepended rdata size
|
||||
*/
|
||||
void rpz_remove_rr(struct rpz* r, size_t aznamelen, uint8_t* dname,
|
||||
size_t dnamelen, uint16_t rr_type, uint16_t rr_class, uint8_t* rdatawl,
|
||||
size_t rdatalen);
|
||||
void rpz_remove_rr(struct rpz* r, uint8_t* azname, size_t aznamelen,
|
||||
uint8_t* dname, size_t dnamelen, uint16_t rr_type, uint16_t rr_class,
|
||||
uint8_t* rdatawl, size_t rdatalen);
|
||||
|
||||
/**
|
||||
* Walk over the RPZ zones to find and apply a QNAME trigger policy.
|
||||
|
|
|
@ -702,7 +702,11 @@ sldns_get_rr_type_by_name(const char *name)
|
|||
|
||||
/* TYPEXX representation */
|
||||
if (strlen(name) > 4 && strncasecmp(name, "TYPE", 4) == 0) {
|
||||
return atoi(name + 4);
|
||||
unsigned int a = atoi(name + 4);
|
||||
if (a > LDNS_RR_TYPE_LAST) {
|
||||
return (enum sldns_enum_rr_type)0;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
/* Normal types */
|
||||
|
@ -740,7 +744,11 @@ sldns_get_rr_class_by_name(const char *name)
|
|||
|
||||
/* CLASSXX representation */
|
||||
if (strlen(name) > 5 && strncasecmp(name, "CLASS", 5) == 0) {
|
||||
return atoi(name + 5);
|
||||
unsigned int a = atoi(name + 5);
|
||||
if (a > LDNS_RR_CLASS_LAST) {
|
||||
return (enum sldns_enum_rr_class)0;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
/* Normal types */
|
||||
|
|
|
@ -433,10 +433,12 @@ enum sldns_enum_edns_option
|
|||
LDNS_EDNS_DHU = 6, /* RFC6975 */
|
||||
LDNS_EDNS_N3U = 7, /* RFC6975 */
|
||||
LDNS_EDNS_CLIENT_SUBNET = 8, /* RFC7871 */
|
||||
LDNS_EDNS_COOKIE = 10, /* RFC7873 */
|
||||
LDNS_EDNS_KEEPALIVE = 11, /* draft-ietf-dnsop-edns-tcp-keepalive*/
|
||||
LDNS_EDNS_PADDING = 12, /* RFC7830 */
|
||||
LDNS_EDNS_EDE = 15, /* RFC8914 */
|
||||
LDNS_EDNS_CLIENT_TAG = 16 /* draft-bellis-dnsop-edns-tags-01 */
|
||||
LDNS_EDNS_CLIENT_TAG = 16, /* draft-bellis-dnsop-edns-tags-01 */
|
||||
LDNS_EDNS_UNBOUND_CACHEDB_TESTFRAME_TEST = 65534
|
||||
};
|
||||
typedef enum sldns_enum_edns_option sldns_edns_option;
|
||||
|
||||
|
@ -482,6 +484,9 @@ typedef enum sldns_enum_ede_code sldns_ede_code;
|
|||
#define LDNS_TSIG_ERROR_BADNAME 20
|
||||
#define LDNS_TSIG_ERROR_BADALG 21
|
||||
|
||||
/** DNS Cookie extended rcode */
|
||||
#define LDNS_EXT_RCODE_BADCOOKIE 23
|
||||
|
||||
/**
|
||||
* Contains all information about resource record types.
|
||||
*
|
||||
|
|
|
@ -698,7 +698,7 @@ static int sldns_str2wire_check_svcbparams(uint8_t* rdata, uint16_t rdata_len)
|
|||
mandatory = svcparams[i];
|
||||
}
|
||||
|
||||
/* 4. verify that all the SvcParamKeys in mandatory are present */
|
||||
/* Verify that all the SvcParamKeys in mandatory are present */
|
||||
if(mandatory) {
|
||||
/* Divide by sizeof(uint16_t)*/
|
||||
uint16_t mandatory_nkeys = sldns_read_uint16(mandatory + 2) / sizeof(uint16_t);
|
||||
|
@ -1123,36 +1123,40 @@ sldns_str2wire_svcparam_key_lookup(const char *key, size_t key_len)
|
|||
return key_value;
|
||||
|
||||
} else switch (key_len) {
|
||||
case sizeof("mandatory")-1:
|
||||
if (!strncmp(key, "mandatory", sizeof("mandatory")-1))
|
||||
return SVCB_KEY_MANDATORY;
|
||||
if (!strncmp(key, "echconfig", sizeof("echconfig")-1))
|
||||
return SVCB_KEY_ECH; /* allow "echconfig" as well as "ech" */
|
||||
case 3:
|
||||
if (!strncmp(key, "ech", key_len))
|
||||
return SVCB_KEY_ECH;
|
||||
break;
|
||||
|
||||
case sizeof("alpn")-1:
|
||||
if (!strncmp(key, "alpn", sizeof("alpn")-1))
|
||||
case 4:
|
||||
if (!strncmp(key, "alpn", key_len))
|
||||
return SVCB_KEY_ALPN;
|
||||
if (!strncmp(key, "port", sizeof("port")-1))
|
||||
if (!strncmp(key, "port", key_len))
|
||||
return SVCB_KEY_PORT;
|
||||
break;
|
||||
|
||||
case sizeof("no-default-alpn")-1:
|
||||
if (!strncmp( key , "no-default-alpn"
|
||||
, sizeof("no-default-alpn")-1))
|
||||
return SVCB_KEY_NO_DEFAULT_ALPN;
|
||||
case 7:
|
||||
if (!strncmp(key, "dohpath", key_len))
|
||||
return SVCB_KEY_DOHPATH;
|
||||
break;
|
||||
|
||||
case sizeof("ipv4hint")-1:
|
||||
if (!strncmp(key, "ipv4hint", sizeof("ipv4hint")-1))
|
||||
case 8:
|
||||
if (!strncmp(key, "ipv4hint", key_len))
|
||||
return SVCB_KEY_IPV4HINT;
|
||||
if (!strncmp(key, "ipv6hint", sizeof("ipv6hint")-1))
|
||||
if (!strncmp(key, "ipv6hint", key_len))
|
||||
return SVCB_KEY_IPV6HINT;
|
||||
break;
|
||||
|
||||
case sizeof("ech")-1:
|
||||
if (!strncmp(key, "ech", sizeof("ech")-1))
|
||||
return SVCB_KEY_ECH;
|
||||
case 9:
|
||||
if (!strncmp(key, "mandatory", key_len))
|
||||
return SVCB_KEY_MANDATORY;
|
||||
if (!strncmp(key, "echconfig", key_len))
|
||||
return SVCB_KEY_ECH; /* allow "echconfig" as well as "ech" */
|
||||
break;
|
||||
|
||||
case 15:
|
||||
if (!strncmp(key, "no-default-alpn", key_len))
|
||||
return SVCB_KEY_NO_DEFAULT_ALPN;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -1515,6 +1519,33 @@ sldns_str2wire_svcbparam_alpn_value(const char* val,
|
|||
return LDNS_WIREPARSE_ERR_OK;
|
||||
}
|
||||
|
||||
static int
|
||||
sldns_str2wire_svcbparam_dohpath_value(const char* val,
|
||||
uint8_t* rd, size_t* rd_len)
|
||||
{
|
||||
size_t val_len;
|
||||
|
||||
/* RFC6570#section-2.1
|
||||
* "The characters outside of expressions in a URI Template string are
|
||||
* intended to be copied literally"
|
||||
* Practically this means we do not have to look for "double escapes"
|
||||
* like in the alpn value list.
|
||||
*/
|
||||
|
||||
val_len = strlen(val);
|
||||
|
||||
if (*rd_len < 4 + val_len) {
|
||||
return LDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
sldns_write_uint16(rd, SVCB_KEY_DOHPATH);
|
||||
sldns_write_uint16(rd + 2, val_len);
|
||||
memcpy(rd + 4, val, val_len);
|
||||
*rd_len = 4 + val_len;
|
||||
|
||||
return LDNS_WIREPARSE_ERR_OK;
|
||||
}
|
||||
|
||||
static int
|
||||
sldns_str2wire_svcparam_value(const char *key, size_t key_len,
|
||||
const char *val, uint8_t* rd, size_t* rd_len)
|
||||
|
@ -1535,6 +1566,7 @@ sldns_str2wire_svcparam_value(const char *key, size_t key_len,
|
|||
case SVCB_KEY_PORT:
|
||||
case SVCB_KEY_IPV4HINT:
|
||||
case SVCB_KEY_IPV6HINT:
|
||||
case SVCB_KEY_DOHPATH:
|
||||
return LDNS_WIREPARSE_ERR_SVCB_MISSING_PARAM;
|
||||
#endif
|
||||
default:
|
||||
|
@ -1566,6 +1598,8 @@ sldns_str2wire_svcparam_value(const char *key, size_t key_len,
|
|||
return sldns_str2wire_svcbparam_ech_value(val, rd, rd_len);
|
||||
case SVCB_KEY_ALPN:
|
||||
return sldns_str2wire_svcbparam_alpn_value(val, rd, rd_len);
|
||||
case SVCB_KEY_DOHPATH:
|
||||
return sldns_str2wire_svcbparam_dohpath_value(val, rd, rd_len);
|
||||
default:
|
||||
str_len = strlen(val);
|
||||
if (*rd_len < 4 + str_len)
|
||||
|
|
|
@ -38,7 +38,8 @@ struct sldns_struct_lookup_table;
|
|||
#define SVCB_KEY_IPV4HINT 4
|
||||
#define SVCB_KEY_ECH 5
|
||||
#define SVCB_KEY_IPV6HINT 6
|
||||
#define SVCPARAMKEY_COUNT 7
|
||||
#define SVCB_KEY_DOHPATH 7
|
||||
#define SVCPARAMKEY_COUNT 8
|
||||
|
||||
#define MAX_NUMBER_OF_SVCPARAMS 64
|
||||
|
||||
|
@ -236,6 +237,7 @@ uint8_t* sldns_wirerr_get_rdatawl(uint8_t* rr, size_t len, size_t dname_len);
|
|||
#define LDNS_WIREPARSE_ERR_SVCB_NO_DEFAULT_ALPN_VALUE 385
|
||||
#define LDNS_WIREPARSE_ERR_SVCPARAM_BROKEN_RDATA 386
|
||||
|
||||
|
||||
/**
|
||||
* Get reference to a constant string for the (parse) error.
|
||||
* @param e: error return value
|
||||
|
|
|
@ -224,7 +224,7 @@ sldns_lookup_table* sldns_tsig_errors = sldns_tsig_errors_data;
|
|||
/* draft-ietf-dnsop-svcb-https-06: 6. Initial SvcParamKeys */
|
||||
const char *svcparamkey_strs[] = {
|
||||
"mandatory", "alpn", "no-default-alpn", "port",
|
||||
"ipv4hint", "ech", "ipv6hint"
|
||||
"ipv4hint", "ech", "ipv6hint", "dohpath"
|
||||
};
|
||||
|
||||
char* sldns_wire2str_pkt(uint8_t* data, size_t len)
|
||||
|
@ -1174,6 +1174,7 @@ int sldns_wire2str_svcparam_scan(uint8_t** d, size_t* dlen, char** s, size_t* sl
|
|||
case SVCB_KEY_IPV4HINT:
|
||||
case SVCB_KEY_IPV6HINT:
|
||||
case SVCB_KEY_MANDATORY:
|
||||
case SVCB_KEY_DOHPATH:
|
||||
return -1;
|
||||
default:
|
||||
return written_chars;
|
||||
|
@ -1201,6 +1202,8 @@ int sldns_wire2str_svcparam_scan(uint8_t** d, size_t* dlen, char** s, size_t* sl
|
|||
case SVCB_KEY_ECH:
|
||||
r = sldns_wire2str_svcparam_ech2str(s, slen, data_len, *d);
|
||||
break;
|
||||
case SVCB_KEY_DOHPATH:
|
||||
/* fallthrough */
|
||||
default:
|
||||
r = sldns_str_print(s, slen, "=\"");
|
||||
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
# $OpenBSD: Makefile.inc,v 1.5 2022/10/22 16:37:57 florian Exp $
|
||||
# $OpenBSD: Makefile.inc,v 1.6 2023/09/05 15:44:02 florian Exp $
|
||||
|
||||
.PATH: ${.CURDIR}/libunbound/util
|
||||
|
||||
SRCS+= alloc.c as112.c config_file.c configlexer.c configparser.y edns.c \
|
||||
fptr_wlist.c locks.c mini_event.c module.c net_help.c netevent.c \
|
||||
proxy_protocol.c random.c rbtree.c regional.c rtt.c tcp_conn_limit.c \
|
||||
timehist.c tube.c ub_event_pluggable.c util_log.c winsock_event.c
|
||||
proxy_protocol.c random.c rbtree.c regional.c rfc_1982.c rtt.c siphash.c \
|
||||
tcp_conn_limit.c timehist.c timeval_func.c tube.c ub_event_pluggable.c \
|
||||
util_log.c winsock_event.c
|
||||
|
||||
util_log.c:
|
||||
ln -s ${.CURDIR}/libunbound/util/log.c $@
|
||||
|
|
|
@ -55,6 +55,7 @@
|
|||
#include "util/regional.h"
|
||||
#include "util/fptr_wlist.h"
|
||||
#include "util/data/dname.h"
|
||||
#include "util/random.h"
|
||||
#include "util/rtt.h"
|
||||
#include "services/cache/infra.h"
|
||||
#include "sldns/wire2str.h"
|
||||
|
@ -87,6 +88,9 @@ struct config_parser_state* cfg_parser = 0;
|
|||
/** init ports possible for use */
|
||||
static void init_outgoing_availports(int* array, int num);
|
||||
|
||||
/** init cookie with random data */
|
||||
static void init_cookie_secret(uint8_t* cookie_secret, size_t cookie_secret_len);
|
||||
|
||||
struct config_file*
|
||||
config_create(void)
|
||||
{
|
||||
|
@ -99,6 +103,7 @@ config_create(void)
|
|||
cfg->stat_interval = 0;
|
||||
cfg->stat_cumulative = 0;
|
||||
cfg->stat_extended = 0;
|
||||
cfg->stat_inhibit_zero = 1;
|
||||
cfg->num_threads = 1;
|
||||
cfg->port = UNBOUND_DNS_PORT;
|
||||
cfg->do_ip4 = 1;
|
||||
|
@ -115,6 +120,7 @@ config_create(void)
|
|||
cfg->tcp_auth_query_timeout = 3 * 1000; /* 3s in millisecs */
|
||||
cfg->do_tcp_keepalive = 0;
|
||||
cfg->tcp_keepalive_timeout = 120 * 1000; /* 120s in millisecs */
|
||||
cfg->sock_queue_timeout = 0; /* do not check timeout */
|
||||
cfg->ssl_service_key = NULL;
|
||||
cfg->ssl_service_pem = NULL;
|
||||
cfg->ssl_port = UNBOUND_DNS_OVER_TLS_PORT;
|
||||
|
@ -232,6 +238,7 @@ config_create(void)
|
|||
cfg->harden_below_nxdomain = 1;
|
||||
cfg->harden_referral_path = 0;
|
||||
cfg->harden_algo_downgrade = 0;
|
||||
cfg->harden_unknown_additional = 0;
|
||||
cfg->use_caps_bits_for_id = 0;
|
||||
cfg->caps_whitelist = NULL;
|
||||
cfg->private_address = NULL;
|
||||
|
@ -299,7 +306,7 @@ config_create(void)
|
|||
cfg->minimal_responses = 1;
|
||||
cfg->rrset_roundrobin = 1;
|
||||
cfg->unknown_server_time_limit = 376;
|
||||
cfg->max_udp_size = 4096;
|
||||
cfg->max_udp_size = 1232; /* value taken from edns_buffer_size */
|
||||
if(!(cfg->server_key_file = strdup(RUN_DIR"/unbound_server.key")))
|
||||
goto error_exit;
|
||||
if(!(cfg->server_cert_file = strdup(RUN_DIR"/unbound_server.pem")))
|
||||
|
@ -323,6 +330,7 @@ config_create(void)
|
|||
cfg->dnstap_bidirectional = 1;
|
||||
cfg->dnstap_tls = 1;
|
||||
cfg->disable_dnssec_lame_check = 0;
|
||||
cfg->ip_ratelimit_cookie = 0;
|
||||
cfg->ip_ratelimit = 0;
|
||||
cfg->ratelimit = 0;
|
||||
cfg->ip_ratelimit_slabs = 4;
|
||||
|
@ -336,6 +344,8 @@ config_create(void)
|
|||
cfg->ip_ratelimit_backoff = 0;
|
||||
cfg->ratelimit_backoff = 0;
|
||||
cfg->outbound_msg_retry = 5;
|
||||
cfg->max_sent_count = 32;
|
||||
cfg->max_query_restarts = 11;
|
||||
cfg->qname_minimisation = 1;
|
||||
cfg->qname_minimisation_strict = 0;
|
||||
cfg->shm_enable = 0;
|
||||
|
@ -364,11 +374,17 @@ config_create(void)
|
|||
cfg->ipsecmod_whitelist = NULL;
|
||||
cfg->ipsecmod_strict = 0;
|
||||
#endif
|
||||
cfg->do_answer_cookie = 0;
|
||||
memset(cfg->cookie_secret, 0, sizeof(cfg->cookie_secret));
|
||||
cfg->cookie_secret_len = 16;
|
||||
init_cookie_secret(cfg->cookie_secret, cfg->cookie_secret_len);
|
||||
#ifdef USE_CACHEDB
|
||||
if(!(cfg->cachedb_backend = strdup("testframe"))) goto error_exit;
|
||||
if(!(cfg->cachedb_secret = strdup("default"))) goto error_exit;
|
||||
#ifdef USE_REDIS
|
||||
if(!(cfg->redis_server_host = strdup("127.0.0.1"))) goto error_exit;
|
||||
cfg->redis_server_path = NULL;
|
||||
cfg->redis_server_password = NULL;
|
||||
cfg->redis_timeout = 100;
|
||||
cfg->redis_server_port = 6379;
|
||||
cfg->redis_expire_records = 0;
|
||||
|
@ -516,6 +532,7 @@ int config_set_option(struct config_file* cfg, const char* opt,
|
|||
else S_YNO("use-syslog:", use_syslog)
|
||||
else S_STR("log-identity:", log_identity)
|
||||
else S_YNO("extended-statistics:", stat_extended)
|
||||
else S_YNO("statistics-inhibit-zero:", stat_inhibit_zero)
|
||||
else S_YNO("statistics-cumulative:", stat_cumulative)
|
||||
else S_YNO("shm-enable:", shm_enable)
|
||||
else S_NUMBER_OR_ZERO("shm-key:", shm_key)
|
||||
|
@ -536,6 +553,7 @@ int config_set_option(struct config_file* cfg, const char* opt,
|
|||
else S_NUMBER_NONZERO("tcp-reuse-timeout:", tcp_reuse_timeout)
|
||||
else S_YNO("edns-tcp-keepalive:", do_tcp_keepalive)
|
||||
else S_NUMBER_NONZERO("edns-tcp-keepalive-timeout:", tcp_keepalive_timeout)
|
||||
else S_NUMBER_OR_ZERO("sock-queue-timeout:", sock_queue_timeout)
|
||||
else S_YNO("ssl-upstream:", ssl_upstream)
|
||||
else S_YNO("tls-upstream:", ssl_upstream)
|
||||
else S_STR("ssl-service-key:", ssl_service_key)
|
||||
|
@ -645,6 +663,7 @@ int config_set_option(struct config_file* cfg, const char* opt,
|
|||
else S_YNO("harden-below-nxdomain:", harden_below_nxdomain)
|
||||
else S_YNO("harden-referral-path:", harden_referral_path)
|
||||
else S_YNO("harden-algo-downgrade:", harden_algo_downgrade)
|
||||
else S_YNO("harden-unknown-additional:", harden_unknown_additional)
|
||||
else S_YNO("use-caps-for-id:", use_caps_bits_for_id)
|
||||
else S_STRLIST("caps-whitelist:", caps_whitelist)
|
||||
else S_SIZET_OR_ZERO("unwanted-reply-threshold:", unwanted_threshold)
|
||||
|
@ -761,6 +780,10 @@ int config_set_option(struct config_file* cfg, const char* opt,
|
|||
else S_POW2("dnscrypt-nonce-cache-slabs:",
|
||||
dnscrypt_nonce_cache_slabs)
|
||||
#endif
|
||||
else if(strcmp(opt, "ip-ratelimit-cookie:") == 0) {
|
||||
IS_NUMBER_OR_ZERO; cfg->ip_ratelimit_cookie = atoi(val);
|
||||
infra_ip_ratelimit_cookie=cfg->ip_ratelimit_cookie;
|
||||
}
|
||||
else if(strcmp(opt, "ip-ratelimit:") == 0) {
|
||||
IS_NUMBER_OR_ZERO; cfg->ip_ratelimit = atoi(val);
|
||||
infra_ip_ratelimit=cfg->ip_ratelimit;
|
||||
|
@ -778,6 +801,8 @@ int config_set_option(struct config_file* cfg, const char* opt,
|
|||
else S_YNO("ip-ratelimit-backoff:", ip_ratelimit_backoff)
|
||||
else S_YNO("ratelimit-backoff:", ratelimit_backoff)
|
||||
else S_NUMBER_NONZERO("outbound-msg-retry:", outbound_msg_retry)
|
||||
else S_NUMBER_NONZERO("max-sent-count:", max_sent_count)
|
||||
else S_NUMBER_NONZERO("max-query-restarts:", max_query_restarts)
|
||||
else S_SIZET_NONZERO("fast-server-num:", fast_server_num)
|
||||
else S_NUMBER_OR_ZERO("fast-server-permil:", fast_server_permil)
|
||||
else S_YNO("qname-minimisation:", qname_minimisation)
|
||||
|
@ -996,6 +1021,7 @@ config_get_option(struct config_file* cfg, const char* opt,
|
|||
else O_DEC(opt, "statistics-interval", stat_interval)
|
||||
else O_YNO(opt, "statistics-cumulative", stat_cumulative)
|
||||
else O_YNO(opt, "extended-statistics", stat_extended)
|
||||
else O_YNO(opt, "statistics-inhibit-zero", stat_inhibit_zero)
|
||||
else O_YNO(opt, "shm-enable", shm_enable)
|
||||
else O_DEC(opt, "shm-key", shm_key)
|
||||
else O_YNO(opt, "use-syslog", use_syslog)
|
||||
|
@ -1055,6 +1081,7 @@ config_get_option(struct config_file* cfg, const char* opt,
|
|||
else O_DEC(opt, "tcp-reuse-timeout", tcp_reuse_timeout)
|
||||
else O_YNO(opt, "edns-tcp-keepalive", do_tcp_keepalive)
|
||||
else O_DEC(opt, "edns-tcp-keepalive-timeout", tcp_keepalive_timeout)
|
||||
else O_DEC(opt, "sock-queue-timeout", sock_queue_timeout)
|
||||
else O_YNO(opt, "ssl-upstream", ssl_upstream)
|
||||
else O_YNO(opt, "tls-upstream", ssl_upstream)
|
||||
else O_STR(opt, "ssl-service-key", ssl_service_key)
|
||||
|
@ -1110,6 +1137,7 @@ config_get_option(struct config_file* cfg, const char* opt,
|
|||
else O_YNO(opt, "harden-below-nxdomain", harden_below_nxdomain)
|
||||
else O_YNO(opt, "harden-referral-path", harden_referral_path)
|
||||
else O_YNO(opt, "harden-algo-downgrade", harden_algo_downgrade)
|
||||
else O_YNO(opt, "harden-unknown-additional", harden_unknown_additional)
|
||||
else O_YNO(opt, "use-caps-for-id", use_caps_bits_for_id)
|
||||
else O_LST(opt, "caps-whitelist", caps_whitelist)
|
||||
else O_DEC(opt, "unwanted-reply-threshold", unwanted_threshold)
|
||||
|
@ -1225,6 +1253,7 @@ config_get_option(struct config_file* cfg, const char* opt,
|
|||
else O_LST(opt, "python-script", python_script)
|
||||
else O_LST(opt, "dynlib-file", dynlib_file)
|
||||
else O_YNO(opt, "disable-dnssec-lame-check", disable_dnssec_lame_check)
|
||||
else O_DEC(opt, "ip-ratelimit-cookie", ip_ratelimit_cookie)
|
||||
else O_DEC(opt, "ip-ratelimit", ip_ratelimit)
|
||||
else O_DEC(opt, "ratelimit", ratelimit)
|
||||
else O_MEM(opt, "ip-ratelimit-size", ip_ratelimit_size)
|
||||
|
@ -1238,6 +1267,8 @@ config_get_option(struct config_file* cfg, const char* opt,
|
|||
else O_YNO(opt, "ip-ratelimit-backoff", ip_ratelimit_backoff)
|
||||
else O_YNO(opt, "ratelimit-backoff", ratelimit_backoff)
|
||||
else O_UNS(opt, "outbound-msg-retry", outbound_msg_retry)
|
||||
else O_UNS(opt, "max-sent-count", max_sent_count)
|
||||
else O_UNS(opt, "max-query-restarts", max_query_restarts)
|
||||
else O_DEC(opt, "fast-server-num", fast_server_num)
|
||||
else O_DEC(opt, "fast-server-permil", fast_server_permil)
|
||||
else O_DEC(opt, "val-sig-skew-min", val_sig_skew_min)
|
||||
|
@ -1278,6 +1309,8 @@ config_get_option(struct config_file* cfg, const char* opt,
|
|||
#ifdef USE_REDIS
|
||||
else O_STR(opt, "redis-server-host", redis_server_host)
|
||||
else O_DEC(opt, "redis-server-port", redis_server_port)
|
||||
else O_STR(opt, "redis-server-path", redis_server_path)
|
||||
else O_STR(opt, "redis-server-password", redis_server_password)
|
||||
else O_DEC(opt, "redis-timeout", redis_timeout)
|
||||
else O_YNO(opt, "redis-expire-records", redis_expire_records)
|
||||
#endif /* USE_REDIS */
|
||||
|
@ -1629,6 +1662,7 @@ config_delete(struct config_file* cfg)
|
|||
free(cfg->server_cert_file);
|
||||
free(cfg->control_key_file);
|
||||
free(cfg->control_cert_file);
|
||||
free(cfg->nat64_prefix);
|
||||
free(cfg->dns64_prefix);
|
||||
config_delstrlist(cfg->dns64_ignore_aaaa);
|
||||
free(cfg->dnstap_socket_path);
|
||||
|
@ -1654,6 +1688,8 @@ config_delete(struct config_file* cfg)
|
|||
free(cfg->cachedb_secret);
|
||||
#ifdef USE_REDIS
|
||||
free(cfg->redis_server_host);
|
||||
free(cfg->redis_server_path);
|
||||
free(cfg->redis_server_password);
|
||||
#endif /* USE_REDIS */
|
||||
#endif /* USE_CACHEDB */
|
||||
#ifdef USE_IPSET
|
||||
|
@ -1663,6 +1699,20 @@ config_delete(struct config_file* cfg)
|
|||
free(cfg);
|
||||
}
|
||||
|
||||
static void
|
||||
init_cookie_secret(uint8_t* cookie_secret, size_t cookie_secret_len)
|
||||
{
|
||||
struct ub_randstate *rand = ub_initstate(NULL);
|
||||
|
||||
if (!rand)
|
||||
fatal_exit("could not init random generator");
|
||||
while (cookie_secret_len) {
|
||||
*cookie_secret++ = (uint8_t)ub_random(rand);
|
||||
cookie_secret_len--;
|
||||
}
|
||||
ub_randfree(rand);
|
||||
}
|
||||
|
||||
static void
|
||||
init_outgoing_availports(int* a, int num)
|
||||
{
|
||||
|
|
|
@ -76,6 +76,8 @@ struct config_file {
|
|||
int stat_cumulative;
|
||||
/** if true, the statistics are kept in greater detail */
|
||||
int stat_extended;
|
||||
/** if true, inhibits a lot of =0 lines from the extended stats output */
|
||||
int stat_inhibit_zero;
|
||||
|
||||
/** number of threads to create */
|
||||
int num_threads;
|
||||
|
@ -86,6 +88,8 @@ struct config_file {
|
|||
int do_ip4;
|
||||
/** do ip6 query support. */
|
||||
int do_ip6;
|
||||
/** do nat64 on queries */
|
||||
int do_nat64;
|
||||
/** prefer ip4 upstream queries. */
|
||||
int prefer_ip4;
|
||||
/** prefer ip6 upstream queries. */
|
||||
|
@ -114,6 +118,8 @@ struct config_file {
|
|||
int do_tcp_keepalive;
|
||||
/** tcp keepalive timeout, in msec */
|
||||
int tcp_keepalive_timeout;
|
||||
/** timeout of packets sitting in the socket queue */
|
||||
int sock_queue_timeout;
|
||||
/** proxy protocol ports */
|
||||
struct config_strlist* proxy_protocol_port;
|
||||
|
||||
|
@ -290,6 +296,9 @@ struct config_file {
|
|||
int harden_referral_path;
|
||||
/** harden against algorithm downgrade */
|
||||
int harden_algo_downgrade;
|
||||
/** harden against unknown records in the authority section and in
|
||||
* the additional section */
|
||||
int harden_unknown_additional;
|
||||
/** use 0x20 bits in query as random ID bits */
|
||||
int use_caps_bits_for_id;
|
||||
/** 0x20 whitelist, domains that do not use capsforid */
|
||||
|
@ -533,6 +542,9 @@ struct config_file {
|
|||
/** ignore AAAAs for these domain names and use A record anyway */
|
||||
struct config_strlist* dns64_ignore_aaaa;
|
||||
|
||||
/* NAT64 prefix; if unset defaults to dns64_prefix */
|
||||
char* nat64_prefix;
|
||||
|
||||
/** true to enable dnstap support */
|
||||
int dnstap;
|
||||
/** using bidirectional frame streams if true */
|
||||
|
@ -578,6 +590,9 @@ struct config_file {
|
|||
|
||||
/** ratelimit for ip addresses. 0 is off, otherwise qps (unless overridden) */
|
||||
int ip_ratelimit;
|
||||
/** ratelimit for ip addresses with a valid DNS Cookie. 0 is off,
|
||||
* otherwise qps (unless overridden) */
|
||||
int ip_ratelimit_cookie;
|
||||
/** number of slabs for ip_ratelimit cache */
|
||||
size_t ip_ratelimit_slabs;
|
||||
/** memory size in bytes for ip_ratelimit cache */
|
||||
|
@ -608,6 +623,11 @@ struct config_file {
|
|||
|
||||
/** number of retries on outgoing queries */
|
||||
int outbound_msg_retry;
|
||||
/** max sent queries per qstate; resets on query restarts (e.g.,
|
||||
* CNAMES) and referrals */
|
||||
int max_sent_count;
|
||||
/** max number of query restarts; determines max length of CNAME chain */
|
||||
int max_query_restarts;
|
||||
/** minimise outgoing QNAME and hide original QTYPE if possible */
|
||||
int qname_minimisation;
|
||||
/** minimise QNAME in strict mode, minimise according to RFC.
|
||||
|
@ -684,12 +704,23 @@ struct config_file {
|
|||
char* redis_server_host;
|
||||
/** redis server's TCP port */
|
||||
int redis_server_port;
|
||||
/** redis server's unix path. Or "", NULL if unused */
|
||||
char* redis_server_path;
|
||||
/** redis server's AUTH password. Or "", NULL if unused */
|
||||
char* redis_server_password;
|
||||
/** timeout (in ms) for communication with the redis server */
|
||||
int redis_timeout;
|
||||
/** set timeout on redis records based on DNS response ttl */
|
||||
int redis_expire_records;
|
||||
#endif
|
||||
#endif
|
||||
/** Downstream DNS Cookies */
|
||||
/** do answer with server cookie when request contained cookie option */
|
||||
int do_answer_cookie;
|
||||
/** cookie secret */
|
||||
uint8_t cookie_secret[40];
|
||||
/** cookie secret length */
|
||||
size_t cookie_secret_len;
|
||||
|
||||
/* ipset module */
|
||||
#ifdef USE_IPSET
|
||||
|
@ -1335,4 +1366,3 @@ int if_is_dnscrypt(const char* ifname, const char* port, int dnscrypt_port);
|
|||
#endif
|
||||
|
||||
#endif /* UTIL_CONFIG_FILE_H */
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -227,6 +227,7 @@ outgoing-num-tcp{COLON} { YDVAR(1, VAR_OUTGOING_NUM_TCP) }
|
|||
incoming-num-tcp{COLON} { YDVAR(1, VAR_INCOMING_NUM_TCP) }
|
||||
do-ip4{COLON} { YDVAR(1, VAR_DO_IP4) }
|
||||
do-ip6{COLON} { YDVAR(1, VAR_DO_IP6) }
|
||||
do-nat64{COLON} { YDVAR(1, VAR_DO_NAT64) }
|
||||
prefer-ip4{COLON} { YDVAR(1, VAR_PREFER_IP4) }
|
||||
prefer-ip6{COLON} { YDVAR(1, VAR_PREFER_IP6) }
|
||||
do-udp{COLON} { YDVAR(1, VAR_DO_UDP) }
|
||||
|
@ -240,6 +241,7 @@ tcp-reuse-timeout{COLON} { YDVAR(1, VAR_TCP_REUSE_TIMEOUT) }
|
|||
tcp-auth-query-timeout{COLON} { YDVAR(1, VAR_TCP_AUTH_QUERY_TIMEOUT) }
|
||||
edns-tcp-keepalive{COLON} { YDVAR(1, VAR_EDNS_TCP_KEEPALIVE) }
|
||||
edns-tcp-keepalive-timeout{COLON} { YDVAR(1, VAR_EDNS_TCP_KEEPALIVE_TIMEOUT) }
|
||||
sock-queue-timeout{COLON} { YDVAR(1, VAR_SOCK_QUEUE_TIMEOUT) }
|
||||
ssl-upstream{COLON} { YDVAR(1, VAR_SSL_UPSTREAM) }
|
||||
tls-upstream{COLON} { YDVAR(1, VAR_SSL_UPSTREAM) }
|
||||
ssl-service-key{COLON} { YDVAR(1, VAR_SSL_SERVICE_KEY) }
|
||||
|
@ -316,6 +318,7 @@ harden-dnssec-stripped{COLON} { YDVAR(1, VAR_HARDEN_DNSSEC_STRIPPED) }
|
|||
harden-below-nxdomain{COLON} { YDVAR(1, VAR_HARDEN_BELOW_NXDOMAIN) }
|
||||
harden-referral-path{COLON} { YDVAR(1, VAR_HARDEN_REFERRAL_PATH) }
|
||||
harden-algo-downgrade{COLON} { YDVAR(1, VAR_HARDEN_ALGO_DOWNGRADE) }
|
||||
harden-unknown-additional{COLON} { YDVAR(1, VAR_HARDEN_UNKNOWN_ADDITIONAL) }
|
||||
use-caps-for-id{COLON} { YDVAR(1, VAR_USE_CAPS_FOR_ID) }
|
||||
caps-whitelist{COLON} { YDVAR(1, VAR_CAPS_WHITELIST) }
|
||||
caps-exempt{COLON} { YDVAR(1, VAR_CAPS_WHITELIST) }
|
||||
|
@ -438,6 +441,7 @@ insecure-lan-zones{COLON} { YDVAR(1, VAR_INSECURE_LAN_ZONES) }
|
|||
statistics-interval{COLON} { YDVAR(1, VAR_STATISTICS_INTERVAL) }
|
||||
statistics-cumulative{COLON} { YDVAR(1, VAR_STATISTICS_CUMULATIVE) }
|
||||
extended-statistics{COLON} { YDVAR(1, VAR_EXTENDED_STATISTICS) }
|
||||
statistics-inhibit-zero{COLON} { YDVAR(1, VAR_STATISTICS_INHIBIT_ZERO) }
|
||||
shm-enable{COLON} { YDVAR(1, VAR_SHM_ENABLE) }
|
||||
shm-key{COLON} { YDVAR(1, VAR_SHM_KEY) }
|
||||
remote-control{COLON} { YDVAR(0, VAR_REMOTE_CONTROL) }
|
||||
|
@ -461,6 +465,7 @@ max-udp-size{COLON} { YDVAR(1, VAR_MAX_UDP_SIZE) }
|
|||
dns64-prefix{COLON} { YDVAR(1, VAR_DNS64_PREFIX) }
|
||||
dns64-synthall{COLON} { YDVAR(1, VAR_DNS64_SYNTHALL) }
|
||||
dns64-ignore-aaaa{COLON} { YDVAR(1, VAR_DNS64_IGNORE_AAAA) }
|
||||
nat64-prefix{COLON} { YDVAR(1, VAR_NAT64_PREFIX) }
|
||||
define-tag{COLON} { YDVAR(1, VAR_DEFINE_TAG) }
|
||||
local-zone-tag{COLON} { YDVAR(2, VAR_LOCAL_ZONE_TAG) }
|
||||
access-control-tag{COLON} { YDVAR(2, VAR_ACCESS_CONTROL_TAG) }
|
||||
|
@ -502,6 +507,7 @@ dnstap-log-forwarder-response-messages{COLON} {
|
|||
YDVAR(1, VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES) }
|
||||
disable-dnssec-lame-check{COLON} { YDVAR(1, VAR_DISABLE_DNSSEC_LAME_CHECK) }
|
||||
ip-ratelimit{COLON} { YDVAR(1, VAR_IP_RATELIMIT) }
|
||||
ip-ratelimit-cookie{COLON} { YDVAR(1, VAR_IP_RATELIMIT_COOKIE) }
|
||||
ratelimit{COLON} { YDVAR(1, VAR_RATELIMIT) }
|
||||
ip-ratelimit-slabs{COLON} { YDVAR(1, VAR_IP_RATELIMIT_SLABS) }
|
||||
ratelimit-slabs{COLON} { YDVAR(1, VAR_RATELIMIT_SLABS) }
|
||||
|
@ -514,6 +520,8 @@ ratelimit-factor{COLON} { YDVAR(1, VAR_RATELIMIT_FACTOR) }
|
|||
ip-ratelimit-backoff{COLON} { YDVAR(1, VAR_IP_RATELIMIT_BACKOFF) }
|
||||
ratelimit-backoff{COLON} { YDVAR(1, VAR_RATELIMIT_BACKOFF) }
|
||||
outbound-msg-retry{COLON} { YDVAR(1, VAR_OUTBOUND_MSG_RETRY) }
|
||||
max-sent-count{COLON} { YDVAR(1, VAR_MAX_SENT_COUNT) }
|
||||
max-query-restarts{COLON} { YDVAR(1, VAR_MAX_QUERY_RESTARTS) }
|
||||
low-rtt{COLON} { YDVAR(1, VAR_LOW_RTT) }
|
||||
fast-server-num{COLON} { YDVAR(1, VAR_FAST_SERVER_NUM) }
|
||||
low-rtt-pct{COLON} { YDVAR(1, VAR_FAST_SERVER_PERMIL) }
|
||||
|
@ -551,6 +559,8 @@ backend{COLON} { YDVAR(1, VAR_CACHEDB_BACKEND) }
|
|||
secret-seed{COLON} { YDVAR(1, VAR_CACHEDB_SECRETSEED) }
|
||||
redis-server-host{COLON} { YDVAR(1, VAR_CACHEDB_REDISHOST) }
|
||||
redis-server-port{COLON} { YDVAR(1, VAR_CACHEDB_REDISPORT) }
|
||||
redis-server-path{COLON} { YDVAR(1, VAR_CACHEDB_REDISPATH) }
|
||||
redis-server-password{COLON} { YDVAR(1, VAR_CACHEDB_REDISPASSWORD) }
|
||||
redis-timeout{COLON} { YDVAR(1, VAR_CACHEDB_REDISTIMEOUT) }
|
||||
redis-expire-records{COLON} { YDVAR(1, VAR_CACHEDB_REDISEXPIRERECORDS) }
|
||||
ipset{COLON} { YDVAR(0, VAR_IPSET) }
|
||||
|
@ -558,6 +568,8 @@ name-v4{COLON} { YDVAR(1, VAR_IPSET_NAME_V4) }
|
|||
name-v6{COLON} { YDVAR(1, VAR_IPSET_NAME_V6) }
|
||||
udp-upstream-without-downstream{COLON} { YDVAR(1, VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM) }
|
||||
tcp-connection-limit{COLON} { YDVAR(2, VAR_TCP_CONNECTION_LIMIT) }
|
||||
answer-cookie{COLON} { YDVAR(1, VAR_ANSWER_COOKIE ) }
|
||||
cookie-secret{COLON} { YDVAR(1, VAR_COOKIE_SECRET) }
|
||||
edns-client-string{COLON} { YDVAR(2, VAR_EDNS_CLIENT_STRING) }
|
||||
edns-client-string-opcode{COLON} { YDVAR(1, VAR_EDNS_CLIENT_STRING_OPCODE) }
|
||||
nsid{COLON} { YDVAR(1, VAR_NSID ) }
|
||||
|
|
|
@ -16,319 +16,331 @@
|
|||
#define VAR_PREFER_IP4 272
|
||||
#define VAR_DO_IP4 273
|
||||
#define VAR_DO_IP6 274
|
||||
#define VAR_PREFER_IP6 275
|
||||
#define VAR_DO_UDP 276
|
||||
#define VAR_DO_TCP 277
|
||||
#define VAR_TCP_MSS 278
|
||||
#define VAR_OUTGOING_TCP_MSS 279
|
||||
#define VAR_TCP_IDLE_TIMEOUT 280
|
||||
#define VAR_EDNS_TCP_KEEPALIVE 281
|
||||
#define VAR_EDNS_TCP_KEEPALIVE_TIMEOUT 282
|
||||
#define VAR_CHROOT 283
|
||||
#define VAR_USERNAME 284
|
||||
#define VAR_DIRECTORY 285
|
||||
#define VAR_LOGFILE 286
|
||||
#define VAR_PIDFILE 287
|
||||
#define VAR_MSG_CACHE_SIZE 288
|
||||
#define VAR_MSG_CACHE_SLABS 289
|
||||
#define VAR_NUM_QUERIES_PER_THREAD 290
|
||||
#define VAR_RRSET_CACHE_SIZE 291
|
||||
#define VAR_RRSET_CACHE_SLABS 292
|
||||
#define VAR_OUTGOING_NUM_TCP 293
|
||||
#define VAR_INFRA_HOST_TTL 294
|
||||
#define VAR_INFRA_LAME_TTL 295
|
||||
#define VAR_INFRA_CACHE_SLABS 296
|
||||
#define VAR_INFRA_CACHE_NUMHOSTS 297
|
||||
#define VAR_INFRA_CACHE_LAME_SIZE 298
|
||||
#define VAR_NAME 299
|
||||
#define VAR_STUB_ZONE 300
|
||||
#define VAR_STUB_HOST 301
|
||||
#define VAR_STUB_ADDR 302
|
||||
#define VAR_TARGET_FETCH_POLICY 303
|
||||
#define VAR_HARDEN_SHORT_BUFSIZE 304
|
||||
#define VAR_HARDEN_LARGE_QUERIES 305
|
||||
#define VAR_FORWARD_ZONE 306
|
||||
#define VAR_FORWARD_HOST 307
|
||||
#define VAR_FORWARD_ADDR 308
|
||||
#define VAR_DO_NOT_QUERY_ADDRESS 309
|
||||
#define VAR_HIDE_IDENTITY 310
|
||||
#define VAR_HIDE_VERSION 311
|
||||
#define VAR_IDENTITY 312
|
||||
#define VAR_VERSION 313
|
||||
#define VAR_HARDEN_GLUE 314
|
||||
#define VAR_MODULE_CONF 315
|
||||
#define VAR_TRUST_ANCHOR_FILE 316
|
||||
#define VAR_TRUST_ANCHOR 317
|
||||
#define VAR_VAL_OVERRIDE_DATE 318
|
||||
#define VAR_BOGUS_TTL 319
|
||||
#define VAR_VAL_CLEAN_ADDITIONAL 320
|
||||
#define VAR_VAL_PERMISSIVE_MODE 321
|
||||
#define VAR_INCOMING_NUM_TCP 322
|
||||
#define VAR_MSG_BUFFER_SIZE 323
|
||||
#define VAR_KEY_CACHE_SIZE 324
|
||||
#define VAR_KEY_CACHE_SLABS 325
|
||||
#define VAR_TRUSTED_KEYS_FILE 326
|
||||
#define VAR_VAL_NSEC3_KEYSIZE_ITERATIONS 327
|
||||
#define VAR_USE_SYSLOG 328
|
||||
#define VAR_OUTGOING_INTERFACE 329
|
||||
#define VAR_ROOT_HINTS 330
|
||||
#define VAR_DO_NOT_QUERY_LOCALHOST 331
|
||||
#define VAR_CACHE_MAX_TTL 332
|
||||
#define VAR_HARDEN_DNSSEC_STRIPPED 333
|
||||
#define VAR_ACCESS_CONTROL 334
|
||||
#define VAR_LOCAL_ZONE 335
|
||||
#define VAR_LOCAL_DATA 336
|
||||
#define VAR_INTERFACE_AUTOMATIC 337
|
||||
#define VAR_STATISTICS_INTERVAL 338
|
||||
#define VAR_DO_DAEMONIZE 339
|
||||
#define VAR_USE_CAPS_FOR_ID 340
|
||||
#define VAR_STATISTICS_CUMULATIVE 341
|
||||
#define VAR_OUTGOING_PORT_PERMIT 342
|
||||
#define VAR_OUTGOING_PORT_AVOID 343
|
||||
#define VAR_DLV_ANCHOR_FILE 344
|
||||
#define VAR_DLV_ANCHOR 345
|
||||
#define VAR_NEG_CACHE_SIZE 346
|
||||
#define VAR_HARDEN_REFERRAL_PATH 347
|
||||
#define VAR_PRIVATE_ADDRESS 348
|
||||
#define VAR_PRIVATE_DOMAIN 349
|
||||
#define VAR_REMOTE_CONTROL 350
|
||||
#define VAR_CONTROL_ENABLE 351
|
||||
#define VAR_CONTROL_INTERFACE 352
|
||||
#define VAR_CONTROL_PORT 353
|
||||
#define VAR_SERVER_KEY_FILE 354
|
||||
#define VAR_SERVER_CERT_FILE 355
|
||||
#define VAR_CONTROL_KEY_FILE 356
|
||||
#define VAR_CONTROL_CERT_FILE 357
|
||||
#define VAR_CONTROL_USE_CERT 358
|
||||
#define VAR_TCP_REUSE_TIMEOUT 359
|
||||
#define VAR_MAX_REUSE_TCP_QUERIES 360
|
||||
#define VAR_EXTENDED_STATISTICS 361
|
||||
#define VAR_LOCAL_DATA_PTR 362
|
||||
#define VAR_JOSTLE_TIMEOUT 363
|
||||
#define VAR_STUB_PRIME 364
|
||||
#define VAR_UNWANTED_REPLY_THRESHOLD 365
|
||||
#define VAR_LOG_TIME_ASCII 366
|
||||
#define VAR_DOMAIN_INSECURE 367
|
||||
#define VAR_PYTHON 368
|
||||
#define VAR_PYTHON_SCRIPT 369
|
||||
#define VAR_VAL_SIG_SKEW_MIN 370
|
||||
#define VAR_VAL_SIG_SKEW_MAX 371
|
||||
#define VAR_VAL_MAX_RESTART 372
|
||||
#define VAR_CACHE_MIN_TTL 373
|
||||
#define VAR_VAL_LOG_LEVEL 374
|
||||
#define VAR_AUTO_TRUST_ANCHOR_FILE 375
|
||||
#define VAR_KEEP_MISSING 376
|
||||
#define VAR_ADD_HOLDDOWN 377
|
||||
#define VAR_DEL_HOLDDOWN 378
|
||||
#define VAR_SO_RCVBUF 379
|
||||
#define VAR_EDNS_BUFFER_SIZE 380
|
||||
#define VAR_PREFETCH 381
|
||||
#define VAR_PREFETCH_KEY 382
|
||||
#define VAR_SO_SNDBUF 383
|
||||
#define VAR_SO_REUSEPORT 384
|
||||
#define VAR_HARDEN_BELOW_NXDOMAIN 385
|
||||
#define VAR_IGNORE_CD_FLAG 386
|
||||
#define VAR_LOG_QUERIES 387
|
||||
#define VAR_LOG_REPLIES 388
|
||||
#define VAR_LOG_LOCAL_ACTIONS 389
|
||||
#define VAR_TCP_UPSTREAM 390
|
||||
#define VAR_SSL_UPSTREAM 391
|
||||
#define VAR_TCP_AUTH_QUERY_TIMEOUT 392
|
||||
#define VAR_SSL_SERVICE_KEY 393
|
||||
#define VAR_SSL_SERVICE_PEM 394
|
||||
#define VAR_SSL_PORT 395
|
||||
#define VAR_FORWARD_FIRST 396
|
||||
#define VAR_STUB_SSL_UPSTREAM 397
|
||||
#define VAR_FORWARD_SSL_UPSTREAM 398
|
||||
#define VAR_TLS_CERT_BUNDLE 399
|
||||
#define VAR_STUB_TCP_UPSTREAM 400
|
||||
#define VAR_FORWARD_TCP_UPSTREAM 401
|
||||
#define VAR_HTTPS_PORT 402
|
||||
#define VAR_HTTP_ENDPOINT 403
|
||||
#define VAR_HTTP_MAX_STREAMS 404
|
||||
#define VAR_HTTP_QUERY_BUFFER_SIZE 405
|
||||
#define VAR_HTTP_RESPONSE_BUFFER_SIZE 406
|
||||
#define VAR_HTTP_NODELAY 407
|
||||
#define VAR_HTTP_NOTLS_DOWNSTREAM 408
|
||||
#define VAR_STUB_FIRST 409
|
||||
#define VAR_MINIMAL_RESPONSES 410
|
||||
#define VAR_RRSET_ROUNDROBIN 411
|
||||
#define VAR_MAX_UDP_SIZE 412
|
||||
#define VAR_DELAY_CLOSE 413
|
||||
#define VAR_UDP_CONNECT 414
|
||||
#define VAR_UNBLOCK_LAN_ZONES 415
|
||||
#define VAR_INSECURE_LAN_ZONES 416
|
||||
#define VAR_INFRA_CACHE_MIN_RTT 417
|
||||
#define VAR_INFRA_CACHE_MAX_RTT 418
|
||||
#define VAR_INFRA_KEEP_PROBING 419
|
||||
#define VAR_DNS64_PREFIX 420
|
||||
#define VAR_DNS64_SYNTHALL 421
|
||||
#define VAR_DNS64_IGNORE_AAAA 422
|
||||
#define VAR_DNSTAP 423
|
||||
#define VAR_DNSTAP_ENABLE 424
|
||||
#define VAR_DNSTAP_SOCKET_PATH 425
|
||||
#define VAR_DNSTAP_IP 426
|
||||
#define VAR_DNSTAP_TLS 427
|
||||
#define VAR_DNSTAP_TLS_SERVER_NAME 428
|
||||
#define VAR_DNSTAP_TLS_CERT_BUNDLE 429
|
||||
#define VAR_DNSTAP_TLS_CLIENT_KEY_FILE 430
|
||||
#define VAR_DNSTAP_TLS_CLIENT_CERT_FILE 431
|
||||
#define VAR_DNSTAP_SEND_IDENTITY 432
|
||||
#define VAR_DNSTAP_SEND_VERSION 433
|
||||
#define VAR_DNSTAP_BIDIRECTIONAL 434
|
||||
#define VAR_DNSTAP_IDENTITY 435
|
||||
#define VAR_DNSTAP_VERSION 436
|
||||
#define VAR_DNSTAP_LOG_RESOLVER_QUERY_MESSAGES 437
|
||||
#define VAR_DNSTAP_LOG_RESOLVER_RESPONSE_MESSAGES 438
|
||||
#define VAR_DNSTAP_LOG_CLIENT_QUERY_MESSAGES 439
|
||||
#define VAR_DNSTAP_LOG_CLIENT_RESPONSE_MESSAGES 440
|
||||
#define VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES 441
|
||||
#define VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES 442
|
||||
#define VAR_RESPONSE_IP_TAG 443
|
||||
#define VAR_RESPONSE_IP 444
|
||||
#define VAR_RESPONSE_IP_DATA 445
|
||||
#define VAR_HARDEN_ALGO_DOWNGRADE 446
|
||||
#define VAR_IP_TRANSPARENT 447
|
||||
#define VAR_IP_DSCP 448
|
||||
#define VAR_DISABLE_DNSSEC_LAME_CHECK 449
|
||||
#define VAR_IP_RATELIMIT 450
|
||||
#define VAR_IP_RATELIMIT_SLABS 451
|
||||
#define VAR_IP_RATELIMIT_SIZE 452
|
||||
#define VAR_RATELIMIT 453
|
||||
#define VAR_RATELIMIT_SLABS 454
|
||||
#define VAR_RATELIMIT_SIZE 455
|
||||
#define VAR_OUTBOUND_MSG_RETRY 456
|
||||
#define VAR_RATELIMIT_FOR_DOMAIN 457
|
||||
#define VAR_RATELIMIT_BELOW_DOMAIN 458
|
||||
#define VAR_IP_RATELIMIT_FACTOR 459
|
||||
#define VAR_RATELIMIT_FACTOR 460
|
||||
#define VAR_IP_RATELIMIT_BACKOFF 461
|
||||
#define VAR_RATELIMIT_BACKOFF 462
|
||||
#define VAR_SEND_CLIENT_SUBNET 463
|
||||
#define VAR_CLIENT_SUBNET_ZONE 464
|
||||
#define VAR_CLIENT_SUBNET_ALWAYS_FORWARD 465
|
||||
#define VAR_CLIENT_SUBNET_OPCODE 466
|
||||
#define VAR_MAX_CLIENT_SUBNET_IPV4 467
|
||||
#define VAR_MAX_CLIENT_SUBNET_IPV6 468
|
||||
#define VAR_MIN_CLIENT_SUBNET_IPV4 469
|
||||
#define VAR_MIN_CLIENT_SUBNET_IPV6 470
|
||||
#define VAR_MAX_ECS_TREE_SIZE_IPV4 471
|
||||
#define VAR_MAX_ECS_TREE_SIZE_IPV6 472
|
||||
#define VAR_CAPS_WHITELIST 473
|
||||
#define VAR_CACHE_MAX_NEGATIVE_TTL 474
|
||||
#define VAR_PERMIT_SMALL_HOLDDOWN 475
|
||||
#define VAR_QNAME_MINIMISATION 476
|
||||
#define VAR_QNAME_MINIMISATION_STRICT 477
|
||||
#define VAR_IP_FREEBIND 478
|
||||
#define VAR_DEFINE_TAG 479
|
||||
#define VAR_LOCAL_ZONE_TAG 480
|
||||
#define VAR_ACCESS_CONTROL_TAG 481
|
||||
#define VAR_LOCAL_ZONE_OVERRIDE 482
|
||||
#define VAR_ACCESS_CONTROL_TAG_ACTION 483
|
||||
#define VAR_ACCESS_CONTROL_TAG_DATA 484
|
||||
#define VAR_VIEW 485
|
||||
#define VAR_ACCESS_CONTROL_VIEW 486
|
||||
#define VAR_VIEW_FIRST 487
|
||||
#define VAR_SERVE_EXPIRED 488
|
||||
#define VAR_SERVE_EXPIRED_TTL 489
|
||||
#define VAR_SERVE_EXPIRED_TTL_RESET 490
|
||||
#define VAR_SERVE_EXPIRED_REPLY_TTL 491
|
||||
#define VAR_SERVE_EXPIRED_CLIENT_TIMEOUT 492
|
||||
#define VAR_EDE_SERVE_EXPIRED 493
|
||||
#define VAR_SERVE_ORIGINAL_TTL 494
|
||||
#define VAR_FAKE_DSA 495
|
||||
#define VAR_FAKE_SHA1 496
|
||||
#define VAR_LOG_IDENTITY 497
|
||||
#define VAR_HIDE_TRUSTANCHOR 498
|
||||
#define VAR_HIDE_HTTP_USER_AGENT 499
|
||||
#define VAR_HTTP_USER_AGENT 500
|
||||
#define VAR_TRUST_ANCHOR_SIGNALING 501
|
||||
#define VAR_AGGRESSIVE_NSEC 502
|
||||
#define VAR_USE_SYSTEMD 503
|
||||
#define VAR_SHM_ENABLE 504
|
||||
#define VAR_SHM_KEY 505
|
||||
#define VAR_ROOT_KEY_SENTINEL 506
|
||||
#define VAR_DNSCRYPT 507
|
||||
#define VAR_DNSCRYPT_ENABLE 508
|
||||
#define VAR_DNSCRYPT_PORT 509
|
||||
#define VAR_DNSCRYPT_PROVIDER 510
|
||||
#define VAR_DNSCRYPT_SECRET_KEY 511
|
||||
#define VAR_DNSCRYPT_PROVIDER_CERT 512
|
||||
#define VAR_DNSCRYPT_PROVIDER_CERT_ROTATED 513
|
||||
#define VAR_DNSCRYPT_SHARED_SECRET_CACHE_SIZE 514
|
||||
#define VAR_DNSCRYPT_SHARED_SECRET_CACHE_SLABS 515
|
||||
#define VAR_DNSCRYPT_NONCE_CACHE_SIZE 516
|
||||
#define VAR_DNSCRYPT_NONCE_CACHE_SLABS 517
|
||||
#define VAR_PAD_RESPONSES 518
|
||||
#define VAR_PAD_RESPONSES_BLOCK_SIZE 519
|
||||
#define VAR_PAD_QUERIES 520
|
||||
#define VAR_PAD_QUERIES_BLOCK_SIZE 521
|
||||
#define VAR_IPSECMOD_ENABLED 522
|
||||
#define VAR_IPSECMOD_HOOK 523
|
||||
#define VAR_IPSECMOD_IGNORE_BOGUS 524
|
||||
#define VAR_IPSECMOD_MAX_TTL 525
|
||||
#define VAR_IPSECMOD_WHITELIST 526
|
||||
#define VAR_IPSECMOD_STRICT 527
|
||||
#define VAR_CACHEDB 528
|
||||
#define VAR_CACHEDB_BACKEND 529
|
||||
#define VAR_CACHEDB_SECRETSEED 530
|
||||
#define VAR_CACHEDB_REDISHOST 531
|
||||
#define VAR_CACHEDB_REDISPORT 532
|
||||
#define VAR_CACHEDB_REDISTIMEOUT 533
|
||||
#define VAR_CACHEDB_REDISEXPIRERECORDS 534
|
||||
#define VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM 535
|
||||
#define VAR_FOR_UPSTREAM 536
|
||||
#define VAR_AUTH_ZONE 537
|
||||
#define VAR_ZONEFILE 538
|
||||
#define VAR_MASTER 539
|
||||
#define VAR_URL 540
|
||||
#define VAR_FOR_DOWNSTREAM 541
|
||||
#define VAR_FALLBACK_ENABLED 542
|
||||
#define VAR_TLS_ADDITIONAL_PORT 543
|
||||
#define VAR_LOW_RTT 544
|
||||
#define VAR_LOW_RTT_PERMIL 545
|
||||
#define VAR_FAST_SERVER_PERMIL 546
|
||||
#define VAR_FAST_SERVER_NUM 547
|
||||
#define VAR_ALLOW_NOTIFY 548
|
||||
#define VAR_TLS_WIN_CERT 549
|
||||
#define VAR_TCP_CONNECTION_LIMIT 550
|
||||
#define VAR_FORWARD_NO_CACHE 551
|
||||
#define VAR_STUB_NO_CACHE 552
|
||||
#define VAR_LOG_SERVFAIL 553
|
||||
#define VAR_DENY_ANY 554
|
||||
#define VAR_UNKNOWN_SERVER_TIME_LIMIT 555
|
||||
#define VAR_LOG_TAG_QUERYREPLY 556
|
||||
#define VAR_STREAM_WAIT_SIZE 557
|
||||
#define VAR_TLS_CIPHERS 558
|
||||
#define VAR_TLS_CIPHERSUITES 559
|
||||
#define VAR_TLS_USE_SNI 560
|
||||
#define VAR_IPSET 561
|
||||
#define VAR_IPSET_NAME_V4 562
|
||||
#define VAR_IPSET_NAME_V6 563
|
||||
#define VAR_TLS_SESSION_TICKET_KEYS 564
|
||||
#define VAR_RPZ 565
|
||||
#define VAR_TAGS 566
|
||||
#define VAR_RPZ_ACTION_OVERRIDE 567
|
||||
#define VAR_RPZ_CNAME_OVERRIDE 568
|
||||
#define VAR_RPZ_LOG 569
|
||||
#define VAR_RPZ_LOG_NAME 570
|
||||
#define VAR_DYNLIB 571
|
||||
#define VAR_DYNLIB_FILE 572
|
||||
#define VAR_EDNS_CLIENT_STRING 573
|
||||
#define VAR_EDNS_CLIENT_STRING_OPCODE 574
|
||||
#define VAR_NSID 575
|
||||
#define VAR_ZONEMD_PERMISSIVE_MODE 576
|
||||
#define VAR_ZONEMD_CHECK 577
|
||||
#define VAR_ZONEMD_REJECT_ABSENCE 578
|
||||
#define VAR_RPZ_SIGNAL_NXDOMAIN_RA 579
|
||||
#define VAR_INTERFACE_AUTOMATIC_PORTS 580
|
||||
#define VAR_EDE 581
|
||||
#define VAR_INTERFACE_ACTION 582
|
||||
#define VAR_INTERFACE_VIEW 583
|
||||
#define VAR_INTERFACE_TAG 584
|
||||
#define VAR_INTERFACE_TAG_ACTION 585
|
||||
#define VAR_INTERFACE_TAG_DATA 586
|
||||
#define VAR_PROXY_PROTOCOL_PORT 587
|
||||
#define VAR_DO_NAT64 275
|
||||
#define VAR_PREFER_IP6 276
|
||||
#define VAR_DO_UDP 277
|
||||
#define VAR_DO_TCP 278
|
||||
#define VAR_TCP_MSS 279
|
||||
#define VAR_OUTGOING_TCP_MSS 280
|
||||
#define VAR_TCP_IDLE_TIMEOUT 281
|
||||
#define VAR_EDNS_TCP_KEEPALIVE 282
|
||||
#define VAR_EDNS_TCP_KEEPALIVE_TIMEOUT 283
|
||||
#define VAR_SOCK_QUEUE_TIMEOUT 284
|
||||
#define VAR_CHROOT 285
|
||||
#define VAR_USERNAME 286
|
||||
#define VAR_DIRECTORY 287
|
||||
#define VAR_LOGFILE 288
|
||||
#define VAR_PIDFILE 289
|
||||
#define VAR_MSG_CACHE_SIZE 290
|
||||
#define VAR_MSG_CACHE_SLABS 291
|
||||
#define VAR_NUM_QUERIES_PER_THREAD 292
|
||||
#define VAR_RRSET_CACHE_SIZE 293
|
||||
#define VAR_RRSET_CACHE_SLABS 294
|
||||
#define VAR_OUTGOING_NUM_TCP 295
|
||||
#define VAR_INFRA_HOST_TTL 296
|
||||
#define VAR_INFRA_LAME_TTL 297
|
||||
#define VAR_INFRA_CACHE_SLABS 298
|
||||
#define VAR_INFRA_CACHE_NUMHOSTS 299
|
||||
#define VAR_INFRA_CACHE_LAME_SIZE 300
|
||||
#define VAR_NAME 301
|
||||
#define VAR_STUB_ZONE 302
|
||||
#define VAR_STUB_HOST 303
|
||||
#define VAR_STUB_ADDR 304
|
||||
#define VAR_TARGET_FETCH_POLICY 305
|
||||
#define VAR_HARDEN_SHORT_BUFSIZE 306
|
||||
#define VAR_HARDEN_LARGE_QUERIES 307
|
||||
#define VAR_FORWARD_ZONE 308
|
||||
#define VAR_FORWARD_HOST 309
|
||||
#define VAR_FORWARD_ADDR 310
|
||||
#define VAR_DO_NOT_QUERY_ADDRESS 311
|
||||
#define VAR_HIDE_IDENTITY 312
|
||||
#define VAR_HIDE_VERSION 313
|
||||
#define VAR_IDENTITY 314
|
||||
#define VAR_VERSION 315
|
||||
#define VAR_HARDEN_GLUE 316
|
||||
#define VAR_MODULE_CONF 317
|
||||
#define VAR_TRUST_ANCHOR_FILE 318
|
||||
#define VAR_TRUST_ANCHOR 319
|
||||
#define VAR_VAL_OVERRIDE_DATE 320
|
||||
#define VAR_BOGUS_TTL 321
|
||||
#define VAR_VAL_CLEAN_ADDITIONAL 322
|
||||
#define VAR_VAL_PERMISSIVE_MODE 323
|
||||
#define VAR_INCOMING_NUM_TCP 324
|
||||
#define VAR_MSG_BUFFER_SIZE 325
|
||||
#define VAR_KEY_CACHE_SIZE 326
|
||||
#define VAR_KEY_CACHE_SLABS 327
|
||||
#define VAR_TRUSTED_KEYS_FILE 328
|
||||
#define VAR_VAL_NSEC3_KEYSIZE_ITERATIONS 329
|
||||
#define VAR_USE_SYSLOG 330
|
||||
#define VAR_OUTGOING_INTERFACE 331
|
||||
#define VAR_ROOT_HINTS 332
|
||||
#define VAR_DO_NOT_QUERY_LOCALHOST 333
|
||||
#define VAR_CACHE_MAX_TTL 334
|
||||
#define VAR_HARDEN_DNSSEC_STRIPPED 335
|
||||
#define VAR_ACCESS_CONTROL 336
|
||||
#define VAR_LOCAL_ZONE 337
|
||||
#define VAR_LOCAL_DATA 338
|
||||
#define VAR_INTERFACE_AUTOMATIC 339
|
||||
#define VAR_STATISTICS_INTERVAL 340
|
||||
#define VAR_DO_DAEMONIZE 341
|
||||
#define VAR_USE_CAPS_FOR_ID 342
|
||||
#define VAR_STATISTICS_CUMULATIVE 343
|
||||
#define VAR_OUTGOING_PORT_PERMIT 344
|
||||
#define VAR_OUTGOING_PORT_AVOID 345
|
||||
#define VAR_DLV_ANCHOR_FILE 346
|
||||
#define VAR_DLV_ANCHOR 347
|
||||
#define VAR_NEG_CACHE_SIZE 348
|
||||
#define VAR_HARDEN_REFERRAL_PATH 349
|
||||
#define VAR_PRIVATE_ADDRESS 350
|
||||
#define VAR_PRIVATE_DOMAIN 351
|
||||
#define VAR_REMOTE_CONTROL 352
|
||||
#define VAR_CONTROL_ENABLE 353
|
||||
#define VAR_CONTROL_INTERFACE 354
|
||||
#define VAR_CONTROL_PORT 355
|
||||
#define VAR_SERVER_KEY_FILE 356
|
||||
#define VAR_SERVER_CERT_FILE 357
|
||||
#define VAR_CONTROL_KEY_FILE 358
|
||||
#define VAR_CONTROL_CERT_FILE 359
|
||||
#define VAR_CONTROL_USE_CERT 360
|
||||
#define VAR_TCP_REUSE_TIMEOUT 361
|
||||
#define VAR_MAX_REUSE_TCP_QUERIES 362
|
||||
#define VAR_EXTENDED_STATISTICS 363
|
||||
#define VAR_LOCAL_DATA_PTR 364
|
||||
#define VAR_JOSTLE_TIMEOUT 365
|
||||
#define VAR_STUB_PRIME 366
|
||||
#define VAR_UNWANTED_REPLY_THRESHOLD 367
|
||||
#define VAR_LOG_TIME_ASCII 368
|
||||
#define VAR_DOMAIN_INSECURE 369
|
||||
#define VAR_PYTHON 370
|
||||
#define VAR_PYTHON_SCRIPT 371
|
||||
#define VAR_VAL_SIG_SKEW_MIN 372
|
||||
#define VAR_VAL_SIG_SKEW_MAX 373
|
||||
#define VAR_VAL_MAX_RESTART 374
|
||||
#define VAR_CACHE_MIN_TTL 375
|
||||
#define VAR_VAL_LOG_LEVEL 376
|
||||
#define VAR_AUTO_TRUST_ANCHOR_FILE 377
|
||||
#define VAR_KEEP_MISSING 378
|
||||
#define VAR_ADD_HOLDDOWN 379
|
||||
#define VAR_DEL_HOLDDOWN 380
|
||||
#define VAR_SO_RCVBUF 381
|
||||
#define VAR_EDNS_BUFFER_SIZE 382
|
||||
#define VAR_PREFETCH 383
|
||||
#define VAR_PREFETCH_KEY 384
|
||||
#define VAR_SO_SNDBUF 385
|
||||
#define VAR_SO_REUSEPORT 386
|
||||
#define VAR_HARDEN_BELOW_NXDOMAIN 387
|
||||
#define VAR_IGNORE_CD_FLAG 388
|
||||
#define VAR_LOG_QUERIES 389
|
||||
#define VAR_LOG_REPLIES 390
|
||||
#define VAR_LOG_LOCAL_ACTIONS 391
|
||||
#define VAR_TCP_UPSTREAM 392
|
||||
#define VAR_SSL_UPSTREAM 393
|
||||
#define VAR_TCP_AUTH_QUERY_TIMEOUT 394
|
||||
#define VAR_SSL_SERVICE_KEY 395
|
||||
#define VAR_SSL_SERVICE_PEM 396
|
||||
#define VAR_SSL_PORT 397
|
||||
#define VAR_FORWARD_FIRST 398
|
||||
#define VAR_STUB_SSL_UPSTREAM 399
|
||||
#define VAR_FORWARD_SSL_UPSTREAM 400
|
||||
#define VAR_TLS_CERT_BUNDLE 401
|
||||
#define VAR_STUB_TCP_UPSTREAM 402
|
||||
#define VAR_FORWARD_TCP_UPSTREAM 403
|
||||
#define VAR_HTTPS_PORT 404
|
||||
#define VAR_HTTP_ENDPOINT 405
|
||||
#define VAR_HTTP_MAX_STREAMS 406
|
||||
#define VAR_HTTP_QUERY_BUFFER_SIZE 407
|
||||
#define VAR_HTTP_RESPONSE_BUFFER_SIZE 408
|
||||
#define VAR_HTTP_NODELAY 409
|
||||
#define VAR_HTTP_NOTLS_DOWNSTREAM 410
|
||||
#define VAR_STUB_FIRST 411
|
||||
#define VAR_MINIMAL_RESPONSES 412
|
||||
#define VAR_RRSET_ROUNDROBIN 413
|
||||
#define VAR_MAX_UDP_SIZE 414
|
||||
#define VAR_DELAY_CLOSE 415
|
||||
#define VAR_UDP_CONNECT 416
|
||||
#define VAR_UNBLOCK_LAN_ZONES 417
|
||||
#define VAR_INSECURE_LAN_ZONES 418
|
||||
#define VAR_INFRA_CACHE_MIN_RTT 419
|
||||
#define VAR_INFRA_CACHE_MAX_RTT 420
|
||||
#define VAR_INFRA_KEEP_PROBING 421
|
||||
#define VAR_DNS64_PREFIX 422
|
||||
#define VAR_DNS64_SYNTHALL 423
|
||||
#define VAR_DNS64_IGNORE_AAAA 424
|
||||
#define VAR_NAT64_PREFIX 425
|
||||
#define VAR_DNSTAP 426
|
||||
#define VAR_DNSTAP_ENABLE 427
|
||||
#define VAR_DNSTAP_SOCKET_PATH 428
|
||||
#define VAR_DNSTAP_IP 429
|
||||
#define VAR_DNSTAP_TLS 430
|
||||
#define VAR_DNSTAP_TLS_SERVER_NAME 431
|
||||
#define VAR_DNSTAP_TLS_CERT_BUNDLE 432
|
||||
#define VAR_DNSTAP_TLS_CLIENT_KEY_FILE 433
|
||||
#define VAR_DNSTAP_TLS_CLIENT_CERT_FILE 434
|
||||
#define VAR_DNSTAP_SEND_IDENTITY 435
|
||||
#define VAR_DNSTAP_SEND_VERSION 436
|
||||
#define VAR_DNSTAP_BIDIRECTIONAL 437
|
||||
#define VAR_DNSTAP_IDENTITY 438
|
||||
#define VAR_DNSTAP_VERSION 439
|
||||
#define VAR_DNSTAP_LOG_RESOLVER_QUERY_MESSAGES 440
|
||||
#define VAR_DNSTAP_LOG_RESOLVER_RESPONSE_MESSAGES 441
|
||||
#define VAR_DNSTAP_LOG_CLIENT_QUERY_MESSAGES 442
|
||||
#define VAR_DNSTAP_LOG_CLIENT_RESPONSE_MESSAGES 443
|
||||
#define VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES 444
|
||||
#define VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES 445
|
||||
#define VAR_RESPONSE_IP_TAG 446
|
||||
#define VAR_RESPONSE_IP 447
|
||||
#define VAR_RESPONSE_IP_DATA 448
|
||||
#define VAR_HARDEN_ALGO_DOWNGRADE 449
|
||||
#define VAR_IP_TRANSPARENT 450
|
||||
#define VAR_IP_DSCP 451
|
||||
#define VAR_DISABLE_DNSSEC_LAME_CHECK 452
|
||||
#define VAR_IP_RATELIMIT 453
|
||||
#define VAR_IP_RATELIMIT_SLABS 454
|
||||
#define VAR_IP_RATELIMIT_SIZE 455
|
||||
#define VAR_RATELIMIT 456
|
||||
#define VAR_RATELIMIT_SLABS 457
|
||||
#define VAR_RATELIMIT_SIZE 458
|
||||
#define VAR_OUTBOUND_MSG_RETRY 459
|
||||
#define VAR_MAX_SENT_COUNT 460
|
||||
#define VAR_MAX_QUERY_RESTARTS 461
|
||||
#define VAR_RATELIMIT_FOR_DOMAIN 462
|
||||
#define VAR_RATELIMIT_BELOW_DOMAIN 463
|
||||
#define VAR_IP_RATELIMIT_FACTOR 464
|
||||
#define VAR_RATELIMIT_FACTOR 465
|
||||
#define VAR_IP_RATELIMIT_BACKOFF 466
|
||||
#define VAR_RATELIMIT_BACKOFF 467
|
||||
#define VAR_SEND_CLIENT_SUBNET 468
|
||||
#define VAR_CLIENT_SUBNET_ZONE 469
|
||||
#define VAR_CLIENT_SUBNET_ALWAYS_FORWARD 470
|
||||
#define VAR_CLIENT_SUBNET_OPCODE 471
|
||||
#define VAR_MAX_CLIENT_SUBNET_IPV4 472
|
||||
#define VAR_MAX_CLIENT_SUBNET_IPV6 473
|
||||
#define VAR_MIN_CLIENT_SUBNET_IPV4 474
|
||||
#define VAR_MIN_CLIENT_SUBNET_IPV6 475
|
||||
#define VAR_MAX_ECS_TREE_SIZE_IPV4 476
|
||||
#define VAR_MAX_ECS_TREE_SIZE_IPV6 477
|
||||
#define VAR_CAPS_WHITELIST 478
|
||||
#define VAR_CACHE_MAX_NEGATIVE_TTL 479
|
||||
#define VAR_PERMIT_SMALL_HOLDDOWN 480
|
||||
#define VAR_QNAME_MINIMISATION 481
|
||||
#define VAR_QNAME_MINIMISATION_STRICT 482
|
||||
#define VAR_IP_FREEBIND 483
|
||||
#define VAR_DEFINE_TAG 484
|
||||
#define VAR_LOCAL_ZONE_TAG 485
|
||||
#define VAR_ACCESS_CONTROL_TAG 486
|
||||
#define VAR_LOCAL_ZONE_OVERRIDE 487
|
||||
#define VAR_ACCESS_CONTROL_TAG_ACTION 488
|
||||
#define VAR_ACCESS_CONTROL_TAG_DATA 489
|
||||
#define VAR_VIEW 490
|
||||
#define VAR_ACCESS_CONTROL_VIEW 491
|
||||
#define VAR_VIEW_FIRST 492
|
||||
#define VAR_SERVE_EXPIRED 493
|
||||
#define VAR_SERVE_EXPIRED_TTL 494
|
||||
#define VAR_SERVE_EXPIRED_TTL_RESET 495
|
||||
#define VAR_SERVE_EXPIRED_REPLY_TTL 496
|
||||
#define VAR_SERVE_EXPIRED_CLIENT_TIMEOUT 497
|
||||
#define VAR_EDE_SERVE_EXPIRED 498
|
||||
#define VAR_SERVE_ORIGINAL_TTL 499
|
||||
#define VAR_FAKE_DSA 500
|
||||
#define VAR_FAKE_SHA1 501
|
||||
#define VAR_LOG_IDENTITY 502
|
||||
#define VAR_HIDE_TRUSTANCHOR 503
|
||||
#define VAR_HIDE_HTTP_USER_AGENT 504
|
||||
#define VAR_HTTP_USER_AGENT 505
|
||||
#define VAR_TRUST_ANCHOR_SIGNALING 506
|
||||
#define VAR_AGGRESSIVE_NSEC 507
|
||||
#define VAR_USE_SYSTEMD 508
|
||||
#define VAR_SHM_ENABLE 509
|
||||
#define VAR_SHM_KEY 510
|
||||
#define VAR_ROOT_KEY_SENTINEL 511
|
||||
#define VAR_DNSCRYPT 512
|
||||
#define VAR_DNSCRYPT_ENABLE 513
|
||||
#define VAR_DNSCRYPT_PORT 514
|
||||
#define VAR_DNSCRYPT_PROVIDER 515
|
||||
#define VAR_DNSCRYPT_SECRET_KEY 516
|
||||
#define VAR_DNSCRYPT_PROVIDER_CERT 517
|
||||
#define VAR_DNSCRYPT_PROVIDER_CERT_ROTATED 518
|
||||
#define VAR_DNSCRYPT_SHARED_SECRET_CACHE_SIZE 519
|
||||
#define VAR_DNSCRYPT_SHARED_SECRET_CACHE_SLABS 520
|
||||
#define VAR_DNSCRYPT_NONCE_CACHE_SIZE 521
|
||||
#define VAR_DNSCRYPT_NONCE_CACHE_SLABS 522
|
||||
#define VAR_PAD_RESPONSES 523
|
||||
#define VAR_PAD_RESPONSES_BLOCK_SIZE 524
|
||||
#define VAR_PAD_QUERIES 525
|
||||
#define VAR_PAD_QUERIES_BLOCK_SIZE 526
|
||||
#define VAR_IPSECMOD_ENABLED 527
|
||||
#define VAR_IPSECMOD_HOOK 528
|
||||
#define VAR_IPSECMOD_IGNORE_BOGUS 529
|
||||
#define VAR_IPSECMOD_MAX_TTL 530
|
||||
#define VAR_IPSECMOD_WHITELIST 531
|
||||
#define VAR_IPSECMOD_STRICT 532
|
||||
#define VAR_CACHEDB 533
|
||||
#define VAR_CACHEDB_BACKEND 534
|
||||
#define VAR_CACHEDB_SECRETSEED 535
|
||||
#define VAR_CACHEDB_REDISHOST 536
|
||||
#define VAR_CACHEDB_REDISPORT 537
|
||||
#define VAR_CACHEDB_REDISTIMEOUT 538
|
||||
#define VAR_CACHEDB_REDISEXPIRERECORDS 539
|
||||
#define VAR_CACHEDB_REDISPATH 540
|
||||
#define VAR_CACHEDB_REDISPASSWORD 541
|
||||
#define VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM 542
|
||||
#define VAR_FOR_UPSTREAM 543
|
||||
#define VAR_AUTH_ZONE 544
|
||||
#define VAR_ZONEFILE 545
|
||||
#define VAR_MASTER 546
|
||||
#define VAR_URL 547
|
||||
#define VAR_FOR_DOWNSTREAM 548
|
||||
#define VAR_FALLBACK_ENABLED 549
|
||||
#define VAR_TLS_ADDITIONAL_PORT 550
|
||||
#define VAR_LOW_RTT 551
|
||||
#define VAR_LOW_RTT_PERMIL 552
|
||||
#define VAR_FAST_SERVER_PERMIL 553
|
||||
#define VAR_FAST_SERVER_NUM 554
|
||||
#define VAR_ALLOW_NOTIFY 555
|
||||
#define VAR_TLS_WIN_CERT 556
|
||||
#define VAR_TCP_CONNECTION_LIMIT 557
|
||||
#define VAR_ANSWER_COOKIE 558
|
||||
#define VAR_COOKIE_SECRET 559
|
||||
#define VAR_IP_RATELIMIT_COOKIE 560
|
||||
#define VAR_FORWARD_NO_CACHE 561
|
||||
#define VAR_STUB_NO_CACHE 562
|
||||
#define VAR_LOG_SERVFAIL 563
|
||||
#define VAR_DENY_ANY 564
|
||||
#define VAR_UNKNOWN_SERVER_TIME_LIMIT 565
|
||||
#define VAR_LOG_TAG_QUERYREPLY 566
|
||||
#define VAR_STREAM_WAIT_SIZE 567
|
||||
#define VAR_TLS_CIPHERS 568
|
||||
#define VAR_TLS_CIPHERSUITES 569
|
||||
#define VAR_TLS_USE_SNI 570
|
||||
#define VAR_IPSET 571
|
||||
#define VAR_IPSET_NAME_V4 572
|
||||
#define VAR_IPSET_NAME_V6 573
|
||||
#define VAR_TLS_SESSION_TICKET_KEYS 574
|
||||
#define VAR_RPZ 575
|
||||
#define VAR_TAGS 576
|
||||
#define VAR_RPZ_ACTION_OVERRIDE 577
|
||||
#define VAR_RPZ_CNAME_OVERRIDE 578
|
||||
#define VAR_RPZ_LOG 579
|
||||
#define VAR_RPZ_LOG_NAME 580
|
||||
#define VAR_DYNLIB 581
|
||||
#define VAR_DYNLIB_FILE 582
|
||||
#define VAR_EDNS_CLIENT_STRING 583
|
||||
#define VAR_EDNS_CLIENT_STRING_OPCODE 584
|
||||
#define VAR_NSID 585
|
||||
#define VAR_ZONEMD_PERMISSIVE_MODE 586
|
||||
#define VAR_ZONEMD_CHECK 587
|
||||
#define VAR_ZONEMD_REJECT_ABSENCE 588
|
||||
#define VAR_RPZ_SIGNAL_NXDOMAIN_RA 589
|
||||
#define VAR_INTERFACE_AUTOMATIC_PORTS 590
|
||||
#define VAR_EDE 591
|
||||
#define VAR_INTERFACE_ACTION 592
|
||||
#define VAR_INTERFACE_VIEW 593
|
||||
#define VAR_INTERFACE_TAG 594
|
||||
#define VAR_INTERFACE_TAG_ACTION 595
|
||||
#define VAR_INTERFACE_TAG_DATA 596
|
||||
#define VAR_PROXY_PROTOCOL_PORT 597
|
||||
#define VAR_STATISTICS_INHIBIT_ZERO 598
|
||||
#define VAR_HARDEN_UNKNOWN_ADDITIONAL 599
|
||||
#ifndef YYSTYPE_DEFINED
|
||||
#define YYSTYPE_DEFINED
|
||||
typedef union {
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
#include "util/configyyrename.h"
|
||||
#include "util/config_file.h"
|
||||
#include "util/net_help.h"
|
||||
#include "sldns/str2wire.h"
|
||||
|
||||
int ub_c_lex(void);
|
||||
void ub_c_error(const char *message);
|
||||
|
@ -73,9 +74,10 @@ extern struct config_parser_state* cfg_parser;
|
|||
%token VAR_FORCE_TOPLEVEL
|
||||
%token VAR_SERVER VAR_VERBOSITY VAR_NUM_THREADS VAR_PORT
|
||||
%token VAR_OUTGOING_RANGE VAR_INTERFACE VAR_PREFER_IP4
|
||||
%token VAR_DO_IP4 VAR_DO_IP6 VAR_PREFER_IP6 VAR_DO_UDP VAR_DO_TCP
|
||||
%token VAR_DO_IP4 VAR_DO_IP6 VAR_DO_NAT64 VAR_PREFER_IP6 VAR_DO_UDP VAR_DO_TCP
|
||||
%token VAR_TCP_MSS VAR_OUTGOING_TCP_MSS VAR_TCP_IDLE_TIMEOUT
|
||||
%token VAR_EDNS_TCP_KEEPALIVE VAR_EDNS_TCP_KEEPALIVE_TIMEOUT
|
||||
%token VAR_SOCK_QUEUE_TIMEOUT
|
||||
%token VAR_CHROOT VAR_USERNAME VAR_DIRECTORY VAR_LOGFILE VAR_PIDFILE
|
||||
%token VAR_MSG_CACHE_SIZE VAR_MSG_CACHE_SLABS VAR_NUM_QUERIES_PER_THREAD
|
||||
%token VAR_RRSET_CACHE_SIZE VAR_RRSET_CACHE_SLABS VAR_OUTGOING_NUM_TCP
|
||||
|
@ -123,6 +125,7 @@ extern struct config_parser_state* cfg_parser;
|
|||
%token VAR_UNBLOCK_LAN_ZONES VAR_INSECURE_LAN_ZONES
|
||||
%token VAR_INFRA_CACHE_MIN_RTT VAR_INFRA_CACHE_MAX_RTT VAR_INFRA_KEEP_PROBING
|
||||
%token VAR_DNS64_PREFIX VAR_DNS64_SYNTHALL VAR_DNS64_IGNORE_AAAA
|
||||
%token VAR_NAT64_PREFIX
|
||||
%token VAR_DNSTAP VAR_DNSTAP_ENABLE VAR_DNSTAP_SOCKET_PATH VAR_DNSTAP_IP
|
||||
%token VAR_DNSTAP_TLS VAR_DNSTAP_TLS_SERVER_NAME VAR_DNSTAP_TLS_CERT_BUNDLE
|
||||
%token VAR_DNSTAP_TLS_CLIENT_KEY_FILE VAR_DNSTAP_TLS_CLIENT_CERT_FILE
|
||||
|
@ -140,7 +143,7 @@ extern struct config_parser_state* cfg_parser;
|
|||
%token VAR_DISABLE_DNSSEC_LAME_CHECK
|
||||
%token VAR_IP_RATELIMIT VAR_IP_RATELIMIT_SLABS VAR_IP_RATELIMIT_SIZE
|
||||
%token VAR_RATELIMIT VAR_RATELIMIT_SLABS VAR_RATELIMIT_SIZE
|
||||
%token VAR_OUTBOUND_MSG_RETRY
|
||||
%token VAR_OUTBOUND_MSG_RETRY VAR_MAX_SENT_COUNT VAR_MAX_QUERY_RESTARTS
|
||||
%token VAR_RATELIMIT_FOR_DOMAIN VAR_RATELIMIT_BELOW_DOMAIN
|
||||
%token VAR_IP_RATELIMIT_FACTOR VAR_RATELIMIT_FACTOR
|
||||
%token VAR_IP_RATELIMIT_BACKOFF VAR_RATELIMIT_BACKOFF
|
||||
|
@ -175,12 +178,13 @@ extern struct config_parser_state* cfg_parser;
|
|||
%token VAR_IPSECMOD_MAX_TTL VAR_IPSECMOD_WHITELIST VAR_IPSECMOD_STRICT
|
||||
%token VAR_CACHEDB VAR_CACHEDB_BACKEND VAR_CACHEDB_SECRETSEED
|
||||
%token VAR_CACHEDB_REDISHOST VAR_CACHEDB_REDISPORT VAR_CACHEDB_REDISTIMEOUT
|
||||
%token VAR_CACHEDB_REDISEXPIRERECORDS
|
||||
%token VAR_CACHEDB_REDISEXPIRERECORDS VAR_CACHEDB_REDISPATH VAR_CACHEDB_REDISPASSWORD
|
||||
%token VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM VAR_FOR_UPSTREAM
|
||||
%token VAR_AUTH_ZONE VAR_ZONEFILE VAR_MASTER VAR_URL VAR_FOR_DOWNSTREAM
|
||||
%token VAR_FALLBACK_ENABLED VAR_TLS_ADDITIONAL_PORT VAR_LOW_RTT VAR_LOW_RTT_PERMIL
|
||||
%token VAR_FAST_SERVER_PERMIL VAR_FAST_SERVER_NUM
|
||||
%token VAR_ALLOW_NOTIFY VAR_TLS_WIN_CERT VAR_TCP_CONNECTION_LIMIT
|
||||
%token VAR_ANSWER_COOKIE VAR_COOKIE_SECRET VAR_IP_RATELIMIT_COOKIE
|
||||
%token VAR_FORWARD_NO_CACHE VAR_STUB_NO_CACHE VAR_LOG_SERVFAIL VAR_DENY_ANY
|
||||
%token VAR_UNKNOWN_SERVER_TIME_LIMIT VAR_LOG_TAG_QUERYREPLY
|
||||
%token VAR_STREAM_WAIT_SIZE VAR_TLS_CIPHERS VAR_TLS_CIPHERSUITES VAR_TLS_USE_SNI
|
||||
|
@ -193,7 +197,8 @@ extern struct config_parser_state* cfg_parser;
|
|||
%token VAR_RPZ_SIGNAL_NXDOMAIN_RA VAR_INTERFACE_AUTOMATIC_PORTS VAR_EDE
|
||||
%token VAR_INTERFACE_ACTION VAR_INTERFACE_VIEW VAR_INTERFACE_TAG
|
||||
%token VAR_INTERFACE_TAG_ACTION VAR_INTERFACE_TAG_DATA
|
||||
%token VAR_PROXY_PROTOCOL_PORT
|
||||
%token VAR_PROXY_PROTOCOL_PORT VAR_STATISTICS_INHIBIT_ZERO
|
||||
%token VAR_HARDEN_UNKNOWN_ADDITIONAL
|
||||
|
||||
%%
|
||||
toplevelvars: /* empty */ | toplevelvars toplevelvar ;
|
||||
|
@ -222,10 +227,11 @@ contents_server: contents_server content_server
|
|||
| ;
|
||||
content_server: server_num_threads | server_verbosity | server_port |
|
||||
server_outgoing_range | server_do_ip4 |
|
||||
server_do_ip6 | server_prefer_ip4 | server_prefer_ip6 |
|
||||
server_do_udp | server_do_tcp |
|
||||
server_do_ip6 | server_do_nat64 | server_prefer_ip4 |
|
||||
server_prefer_ip6 | server_do_udp | server_do_tcp |
|
||||
server_tcp_mss | server_outgoing_tcp_mss | server_tcp_idle_timeout |
|
||||
server_tcp_keepalive | server_tcp_keepalive_timeout |
|
||||
server_sock_queue_timeout |
|
||||
server_interface | server_chroot | server_username |
|
||||
server_directory | server_logfile | server_pidfile |
|
||||
server_msg_cache_size | server_msg_cache_slabs |
|
||||
|
@ -273,6 +279,7 @@ content_server: server_num_threads | server_verbosity | server_port |
|
|||
server_so_reuseport | server_delay_close | server_udp_connect |
|
||||
server_unblock_lan_zones | server_insecure_lan_zones |
|
||||
server_dns64_prefix | server_dns64_synthall | server_dns64_ignore_aaaa |
|
||||
server_nat64_prefix |
|
||||
server_infra_cache_min_rtt | server_infra_cache_max_rtt | server_harden_algo_downgrade |
|
||||
server_ip_transparent | server_ip_ratelimit | server_ratelimit |
|
||||
server_ip_dscp | server_infra_keep_probing |
|
||||
|
@ -282,6 +289,7 @@ content_server: server_num_threads | server_verbosity | server_port |
|
|||
server_ratelimit_below_domain | server_ratelimit_factor |
|
||||
server_ip_ratelimit_factor | server_ratelimit_backoff |
|
||||
server_ip_ratelimit_backoff | server_outbound_msg_retry |
|
||||
server_max_sent_count | server_max_query_restarts |
|
||||
server_send_client_subnet | server_client_subnet_zone |
|
||||
server_client_subnet_always_forward | server_client_subnet_opcode |
|
||||
server_max_client_subnet_ipv4 | server_max_client_subnet_ipv6 |
|
||||
|
@ -317,12 +325,14 @@ content_server: server_num_threads | server_verbosity | server_port |
|
|||
server_unknown_server_time_limit | server_log_tag_queryreply |
|
||||
server_stream_wait_size | server_tls_ciphers |
|
||||
server_tls_ciphersuites | server_tls_session_ticket_keys |
|
||||
server_answer_cookie | server_cookie_secret | server_ip_ratelimit_cookie |
|
||||
server_tls_use_sni | server_edns_client_string |
|
||||
server_edns_client_string_opcode | server_nsid |
|
||||
server_zonemd_permissive_mode | server_max_reuse_tcp_queries |
|
||||
server_tcp_reuse_timeout | server_tcp_auth_query_timeout |
|
||||
server_interface_automatic_ports | server_ede |
|
||||
server_proxy_protocol_port
|
||||
server_proxy_protocol_port | server_statistics_inhibit_zero |
|
||||
server_harden_unknown_additional
|
||||
;
|
||||
stubstart: VAR_STUB_ZONE
|
||||
{
|
||||
|
@ -554,6 +564,15 @@ server_extended_statistics: VAR_EXTENDED_STATISTICS STRING_ARG
|
|||
free($2);
|
||||
}
|
||||
;
|
||||
server_statistics_inhibit_zero: VAR_STATISTICS_INHIBIT_ZERO STRING_ARG
|
||||
{
|
||||
OUTYY(("P(server_statistics_inhibit_zero:%s)\n", $2));
|
||||
if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
|
||||
yyerror("expected yes or no.");
|
||||
else cfg_parser->cfg->stat_inhibit_zero = (strcmp($2, "yes")==0);
|
||||
free($2);
|
||||
}
|
||||
;
|
||||
server_shm_enable: VAR_SHM_ENABLE STRING_ARG
|
||||
{
|
||||
OUTYY(("P(server_shm_enable:%s)\n", $2));
|
||||
|
@ -840,6 +859,15 @@ server_do_ip6: VAR_DO_IP6 STRING_ARG
|
|||
free($2);
|
||||
}
|
||||
;
|
||||
server_do_nat64: VAR_DO_NAT64 STRING_ARG
|
||||
{
|
||||
OUTYY(("P(server_do_nat64:%s)\n", $2));
|
||||
if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
|
||||
yyerror("expected yes or no.");
|
||||
else cfg_parser->cfg->do_nat64 = (strcmp($2, "yes")==0);
|
||||
free($2);
|
||||
}
|
||||
;
|
||||
server_do_udp: VAR_DO_UDP STRING_ARG
|
||||
{
|
||||
OUTYY(("P(server_do_udp:%s)\n", $2));
|
||||
|
@ -962,6 +990,19 @@ server_tcp_keepalive_timeout: VAR_EDNS_TCP_KEEPALIVE_TIMEOUT STRING_ARG
|
|||
free($2);
|
||||
}
|
||||
;
|
||||
server_sock_queue_timeout: VAR_SOCK_QUEUE_TIMEOUT STRING_ARG
|
||||
{
|
||||
OUTYY(("P(server_sock_queue_timeout:%s)\n", $2));
|
||||
if(atoi($2) == 0 && strcmp($2, "0") != 0)
|
||||
yyerror("number expected");
|
||||
else if (atoi($2) > 6553500)
|
||||
cfg_parser->cfg->sock_queue_timeout = 6553500;
|
||||
else if (atoi($2) < 1)
|
||||
cfg_parser->cfg->sock_queue_timeout = 0;
|
||||
else cfg_parser->cfg->sock_queue_timeout = atoi($2);
|
||||
free($2);
|
||||
}
|
||||
;
|
||||
server_tcp_upstream: VAR_TCP_UPSTREAM STRING_ARG
|
||||
{
|
||||
OUTYY(("P(server_tcp_upstream:%s)\n", $2));
|
||||
|
@ -1122,7 +1163,7 @@ server_http_nodelay: VAR_HTTP_NODELAY STRING_ARG
|
|||
yyerror("expected yes or no.");
|
||||
else cfg_parser->cfg->http_nodelay = (strcmp($2, "yes")==0);
|
||||
free($2);
|
||||
}
|
||||
};
|
||||
server_http_notls_downstream: VAR_HTTP_NOTLS_DOWNSTREAM STRING_ARG
|
||||
{
|
||||
OUTYY(("P(server_http_notls_downstream:%s)\n", $2));
|
||||
|
@ -1768,6 +1809,16 @@ server_harden_algo_downgrade: VAR_HARDEN_ALGO_DOWNGRADE STRING_ARG
|
|||
free($2);
|
||||
}
|
||||
;
|
||||
server_harden_unknown_additional: VAR_HARDEN_UNKNOWN_ADDITIONAL STRING_ARG
|
||||
{
|
||||
OUTYY(("P(server_harden_unknown_additional:%s)\n", $2));
|
||||
if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
|
||||
yyerror("expected yes or no.");
|
||||
else cfg_parser->cfg->harden_unknown_additional =
|
||||
(strcmp($2, "yes")==0);
|
||||
free($2);
|
||||
}
|
||||
;
|
||||
server_use_caps_for_id: VAR_USE_CAPS_FOR_ID STRING_ARG
|
||||
{
|
||||
OUTYY(("P(server_use_caps_for_id:%s)\n", $2));
|
||||
|
@ -2159,6 +2210,7 @@ server_permit_small_holddown: VAR_PERMIT_SMALL_HOLDDOWN STRING_ARG
|
|||
(strcmp($2, "yes")==0);
|
||||
free($2);
|
||||
}
|
||||
;
|
||||
server_key_cache_size: VAR_KEY_CACHE_SIZE STRING_ARG
|
||||
{
|
||||
OUTYY(("P(server_key_cache_size:%s)\n", $2));
|
||||
|
@ -2196,6 +2248,7 @@ server_local_zone: VAR_LOCAL_ZONE STRING_ARG STRING_ARG
|
|||
strcmp($3, "transparent")!=0 && strcmp($3, "nodefault")!=0
|
||||
&& strcmp($3, "typetransparent")!=0
|
||||
&& strcmp($3, "always_transparent")!=0
|
||||
&& strcmp($3, "block_a")!=0
|
||||
&& strcmp($3, "always_refuse")!=0
|
||||
&& strcmp($3, "always_nxdomain")!=0
|
||||
&& strcmp($3, "always_nodata")!=0
|
||||
|
@ -2208,7 +2261,7 @@ server_local_zone: VAR_LOCAL_ZONE STRING_ARG STRING_ARG
|
|||
yyerror("local-zone type: expected static, deny, "
|
||||
"refuse, redirect, transparent, "
|
||||
"typetransparent, inform, inform_deny, "
|
||||
"inform_redirect, always_transparent, "
|
||||
"inform_redirect, always_transparent, block_a,"
|
||||
"always_refuse, always_nxdomain, "
|
||||
"always_nodata, always_deny, always_null, "
|
||||
"noview, nodefault or ipset");
|
||||
|
@ -2323,6 +2376,13 @@ server_dns64_ignore_aaaa: VAR_DNS64_IGNORE_AAAA STRING_ARG
|
|||
fatal_exit("out of memory adding dns64-ignore-aaaa");
|
||||
}
|
||||
;
|
||||
server_nat64_prefix: VAR_NAT64_PREFIX STRING_ARG
|
||||
{
|
||||
OUTYY(("P(nat64_prefix:%s)\n", $2));
|
||||
free(cfg_parser->cfg->nat64_prefix);
|
||||
cfg_parser->cfg->nat64_prefix = $2;
|
||||
}
|
||||
;
|
||||
server_define_tag: VAR_DEFINE_TAG STRING_ARG
|
||||
{
|
||||
char* p, *s = $2;
|
||||
|
@ -2508,6 +2568,15 @@ server_ip_ratelimit: VAR_IP_RATELIMIT STRING_ARG
|
|||
free($2);
|
||||
}
|
||||
;
|
||||
server_ip_ratelimit_cookie: VAR_IP_RATELIMIT_COOKIE STRING_ARG
|
||||
{
|
||||
OUTYY(("P(server_ip_ratelimit_cookie:%s)\n", $2));
|
||||
if(atoi($2) == 0 && strcmp($2, "0") != 0)
|
||||
yyerror("number expected");
|
||||
else cfg_parser->cfg->ip_ratelimit_cookie = atoi($2);
|
||||
free($2);
|
||||
}
|
||||
;
|
||||
server_ratelimit: VAR_RATELIMIT STRING_ARG
|
||||
{
|
||||
OUTYY(("P(server_ratelimit:%s)\n", $2));
|
||||
|
@ -2636,6 +2705,24 @@ server_outbound_msg_retry: VAR_OUTBOUND_MSG_RETRY STRING_ARG
|
|||
free($2);
|
||||
}
|
||||
;
|
||||
server_max_sent_count: VAR_MAX_SENT_COUNT STRING_ARG
|
||||
{
|
||||
OUTYY(("P(server_max_sent_count:%s)\n", $2));
|
||||
if(atoi($2) == 0 && strcmp($2, "0") != 0)
|
||||
yyerror("number expected");
|
||||
else cfg_parser->cfg->max_sent_count = atoi($2);
|
||||
free($2);
|
||||
}
|
||||
;
|
||||
server_max_query_restarts: VAR_MAX_QUERY_RESTARTS STRING_ARG
|
||||
{
|
||||
OUTYY(("P(server_max_query_restarts:%s)\n", $2));
|
||||
if(atoi($2) == 0 && strcmp($2, "0") != 0)
|
||||
yyerror("number expected");
|
||||
else cfg_parser->cfg->max_query_restarts = atoi($2);
|
||||
free($2);
|
||||
}
|
||||
;
|
||||
server_low_rtt: VAR_LOW_RTT STRING_ARG
|
||||
{
|
||||
OUTYY(("P(low-rtt option is deprecated, use fast-server-num instead)\n"));
|
||||
|
@ -3443,6 +3530,7 @@ py_script: VAR_PYTHON_SCRIPT STRING_ARG
|
|||
if(!cfg_strlist_append_ex(&cfg_parser->cfg->python_script, $2))
|
||||
yyerror("out of memory");
|
||||
}
|
||||
;
|
||||
dynlibstart: VAR_DYNLIB
|
||||
{
|
||||
OUTYY(("\nP(dynlib:)\n"));
|
||||
|
@ -3459,6 +3547,7 @@ dl_file: VAR_DYNLIB_FILE STRING_ARG
|
|||
if(!cfg_strlist_append_ex(&cfg_parser->cfg->dynlib_file, $2))
|
||||
yyerror("out of memory");
|
||||
}
|
||||
;
|
||||
server_disable_dnssec_lame_check: VAR_DISABLE_DNSSEC_LAME_CHECK STRING_ARG
|
||||
{
|
||||
OUTYY(("P(disable_dnssec_lame_check:%s)\n", $2));
|
||||
|
@ -3519,7 +3608,6 @@ dnsc_dnscrypt_enable: VAR_DNSCRYPT_ENABLE STRING_ARG
|
|||
free($2);
|
||||
}
|
||||
;
|
||||
|
||||
dnsc_dnscrypt_port: VAR_DNSCRYPT_PORT STRING_ARG
|
||||
{
|
||||
OUTYY(("P(dnsc_dnscrypt_port:%s)\n", $2));
|
||||
|
@ -3613,7 +3701,7 @@ contents_cachedb: contents_cachedb content_cachedb
|
|||
| ;
|
||||
content_cachedb: cachedb_backend_name | cachedb_secret_seed |
|
||||
redis_server_host | redis_server_port | redis_timeout |
|
||||
redis_expire_records
|
||||
redis_expire_records | redis_server_path | redis_server_password
|
||||
;
|
||||
cachedb_backend_name: VAR_CACHEDB_BACKEND STRING_ARG
|
||||
{
|
||||
|
@ -3666,6 +3754,30 @@ redis_server_port: VAR_CACHEDB_REDISPORT STRING_ARG
|
|||
free($2);
|
||||
}
|
||||
;
|
||||
redis_server_path: VAR_CACHEDB_REDISPATH STRING_ARG
|
||||
{
|
||||
#if defined(USE_CACHEDB) && defined(USE_REDIS)
|
||||
OUTYY(("P(redis_server_path:%s)\n", $2));
|
||||
free(cfg_parser->cfg->redis_server_path);
|
||||
cfg_parser->cfg->redis_server_path = $2;
|
||||
#else
|
||||
OUTYY(("P(Compiled without cachedb or redis, ignoring)\n"));
|
||||
free($2);
|
||||
#endif
|
||||
}
|
||||
;
|
||||
redis_server_password: VAR_CACHEDB_REDISPASSWORD STRING_ARG
|
||||
{
|
||||
#if defined(USE_CACHEDB) && defined(USE_REDIS)
|
||||
OUTYY(("P(redis_server_password:%s)\n", $2));
|
||||
free(cfg_parser->cfg->redis_server_password);
|
||||
cfg_parser->cfg->redis_server_password = $2;
|
||||
#else
|
||||
OUTYY(("P(Compiled without cachedb or redis, ignoring)\n"));
|
||||
free($2);
|
||||
#endif
|
||||
}
|
||||
;
|
||||
redis_timeout: VAR_CACHEDB_REDISTIMEOUT STRING_ARG
|
||||
{
|
||||
#if defined(USE_CACHEDB) && defined(USE_REDIS)
|
||||
|
@ -3703,6 +3815,31 @@ server_tcp_connection_limit: VAR_TCP_CONNECTION_LIMIT STRING_ARG STRING_ARG
|
|||
}
|
||||
}
|
||||
;
|
||||
server_answer_cookie: VAR_ANSWER_COOKIE STRING_ARG
|
||||
{
|
||||
OUTYY(("P(server_answer_cookie:%s)\n", $2));
|
||||
if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
|
||||
yyerror("expected yes or no.");
|
||||
else cfg_parser->cfg->do_answer_cookie = (strcmp($2, "yes")==0);
|
||||
free($2);
|
||||
}
|
||||
;
|
||||
server_cookie_secret: VAR_COOKIE_SECRET STRING_ARG
|
||||
{
|
||||
uint8_t secret[32];
|
||||
size_t secret_len = sizeof(secret);
|
||||
|
||||
OUTYY(("P(server_cookie_secret:%s)\n", $2));
|
||||
if(sldns_str2wire_hex_buf($2, secret, &secret_len)
|
||||
|| (secret_len != 16))
|
||||
yyerror("expected 128 bit hex string");
|
||||
else {
|
||||
cfg_parser->cfg->cookie_secret_len = secret_len;
|
||||
memcpy(cfg_parser->cfg->cookie_secret, secret, sizeof(secret));
|
||||
}
|
||||
free($2);
|
||||
}
|
||||
;
|
||||
ipsetstart: VAR_IPSET
|
||||
{
|
||||
OUTYY(("\nP(ipset:)\n"));
|
||||
|
@ -3772,10 +3909,11 @@ validate_acl_action(const char* action)
|
|||
strcmp(action, "refuse_non_local")!=0 &&
|
||||
strcmp(action, "allow_setrd")!=0 &&
|
||||
strcmp(action, "allow")!=0 &&
|
||||
strcmp(action, "allow_snoop")!=0)
|
||||
strcmp(action, "allow_snoop")!=0 &&
|
||||
strcmp(action, "allow_cookie")!=0)
|
||||
{
|
||||
yyerror("expected deny, refuse, deny_non_local, "
|
||||
"refuse_non_local, allow, allow_setrd or "
|
||||
"allow_snoop as access control action");
|
||||
"refuse_non_local, allow, allow_setrd, "
|
||||
"allow_snoop or allow_cookie as access control action");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -806,6 +806,95 @@ calc_edns_field_size(struct edns_data* edns)
|
|||
return 1 + 2 + 2 + 4 + 2 + rdatalen;
|
||||
}
|
||||
|
||||
uint16_t
|
||||
calc_edns_option_size(struct edns_data* edns, uint16_t code)
|
||||
{
|
||||
size_t rdatalen = 0;
|
||||
struct edns_option* opt;
|
||||
if(!edns || !edns->edns_present)
|
||||
return 0;
|
||||
for(opt = edns->opt_list_inplace_cb_out; opt; opt = opt->next) {
|
||||
if(opt->opt_code == code)
|
||||
rdatalen += 4 + opt->opt_len;
|
||||
}
|
||||
for(opt = edns->opt_list_out; opt; opt = opt->next) {
|
||||
if(opt->opt_code == code)
|
||||
rdatalen += 4 + opt->opt_len;
|
||||
}
|
||||
return rdatalen;
|
||||
}
|
||||
|
||||
uint16_t
|
||||
calc_ede_option_size(struct edns_data* edns, uint16_t* txt_size)
|
||||
{
|
||||
size_t rdatalen = 0;
|
||||
struct edns_option* opt;
|
||||
*txt_size = 0;
|
||||
if(!edns || !edns->edns_present)
|
||||
return 0;
|
||||
for(opt = edns->opt_list_inplace_cb_out; opt; opt = opt->next) {
|
||||
if(opt->opt_code == LDNS_EDNS_EDE) {
|
||||
rdatalen += 4 + opt->opt_len;
|
||||
if(opt->opt_len > 2) *txt_size += opt->opt_len - 2;
|
||||
if(opt->opt_len >= 2 && sldns_read_uint16(
|
||||
opt->opt_data) == LDNS_EDE_OTHER) {
|
||||
*txt_size += 4 + 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
for(opt = edns->opt_list_out; opt; opt = opt->next) {
|
||||
if(opt->opt_code == LDNS_EDNS_EDE) {
|
||||
rdatalen += 4 + opt->opt_len;
|
||||
if(opt->opt_len > 2) *txt_size += opt->opt_len - 2;
|
||||
if(opt->opt_len >= 2 && sldns_read_uint16(
|
||||
opt->opt_data) == LDNS_EDE_OTHER) {
|
||||
*txt_size += 4 + 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
return rdatalen;
|
||||
}
|
||||
|
||||
/* Trims the EDE OPTION-DATA to not include any EXTRA-TEXT data.
|
||||
* Also removes any LDNS_EDE_OTHER options from the list since they are useless
|
||||
* without the extra text. */
|
||||
static void
|
||||
ede_trim_text(struct edns_option** list)
|
||||
{
|
||||
struct edns_option* curr, *prev = NULL;
|
||||
if(!list || !(*list)) return;
|
||||
/* Unlink and repoint if LDNS_EDE_OTHER are first in list */
|
||||
while(list && *list && (*list)->opt_code == LDNS_EDNS_EDE
|
||||
&& (*list)->opt_len >= 2
|
||||
&& sldns_read_uint16((*list)->opt_data) == LDNS_EDE_OTHER ) {
|
||||
*list = (*list)->next;
|
||||
}
|
||||
if(!list || !(*list)) return;
|
||||
curr = *list;
|
||||
while(curr) {
|
||||
if(curr->opt_code == LDNS_EDNS_EDE) {
|
||||
if(curr->opt_len >= 2 && sldns_read_uint16(
|
||||
curr->opt_data) == LDNS_EDE_OTHER) {
|
||||
/* LDNS_EDE_OTHER cannot be the first option in
|
||||
* this while, so prev is always initialized at
|
||||
* this point from the other branches;
|
||||
* cut this option off */
|
||||
prev->next = curr->next;
|
||||
curr = curr->next;
|
||||
} else if(curr->opt_len > 2) {
|
||||
/* trim this option's EXTRA-TEXT */
|
||||
curr->opt_len = 2;
|
||||
prev = curr;
|
||||
curr = curr->next;
|
||||
}
|
||||
} else {
|
||||
/* continue */
|
||||
prev = curr;
|
||||
curr = curr->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
attach_edns_record_max_msg_sz(sldns_buffer* pkt, struct edns_data* edns,
|
||||
uint16_t max_msg_sz)
|
||||
|
@ -894,6 +983,7 @@ reply_info_answer_encode(struct query_info* qinf, struct reply_info* rep,
|
|||
{
|
||||
uint16_t flags;
|
||||
unsigned int attach_edns = 0;
|
||||
uint16_t edns_field_size, ede_size, ede_txt_size;
|
||||
|
||||
if(!cached || rep->authoritative) {
|
||||
/* original flags, copy RD and CD bits from query. */
|
||||
|
@ -916,25 +1006,39 @@ reply_info_answer_encode(struct query_info* qinf, struct reply_info* rep,
|
|||
log_assert(flags & BIT_QR); /* QR bit must be on in our replies */
|
||||
if(udpsize < LDNS_HEADER_SIZE)
|
||||
return 0;
|
||||
/* currently edns does not change during calculations;
|
||||
* calculate sizes once here */
|
||||
edns_field_size = calc_edns_field_size(edns);
|
||||
ede_size = calc_ede_option_size(edns, &ede_txt_size);
|
||||
if(sldns_buffer_capacity(pkt) < udpsize)
|
||||
udpsize = sldns_buffer_capacity(pkt);
|
||||
if(udpsize < LDNS_HEADER_SIZE + calc_edns_field_size(edns)) {
|
||||
/* EDEs are optional, try to fit anything else before them */
|
||||
if(udpsize < LDNS_HEADER_SIZE + edns_field_size - ede_size) {
|
||||
/* packet too small to contain edns, omit it. */
|
||||
attach_edns = 0;
|
||||
} else {
|
||||
/* reserve space for edns record */
|
||||
attach_edns = (unsigned int)calc_edns_field_size(edns);
|
||||
udpsize -= attach_edns;
|
||||
attach_edns = (unsigned int)edns_field_size - ede_size;
|
||||
}
|
||||
|
||||
if(!reply_info_encode(qinf, rep, id, flags, pkt, timenow, region,
|
||||
udpsize, dnssec, MINIMAL_RESPONSES)) {
|
||||
udpsize - attach_edns, dnssec, MINIMAL_RESPONSES)) {
|
||||
log_err("reply encode: out of memory");
|
||||
return 0;
|
||||
}
|
||||
if(attach_edns && sldns_buffer_capacity(pkt) >=
|
||||
sldns_buffer_limit(pkt)+attach_edns)
|
||||
attach_edns_record_max_msg_sz(pkt, edns, udpsize+attach_edns);
|
||||
if(attach_edns) {
|
||||
if(udpsize >= sldns_buffer_limit(pkt) + edns_field_size)
|
||||
attach_edns_record_max_msg_sz(pkt, edns, udpsize);
|
||||
else if(udpsize >= sldns_buffer_limit(pkt) + edns_field_size - ede_txt_size) {
|
||||
ede_trim_text(&edns->opt_list_inplace_cb_out);
|
||||
ede_trim_text(&edns->opt_list_out);
|
||||
attach_edns_record_max_msg_sz(pkt, edns, udpsize);
|
||||
} else if(udpsize >= sldns_buffer_limit(pkt) + edns_field_size - ede_size) {
|
||||
edns_opt_list_remove(&edns->opt_list_inplace_cb_out, LDNS_EDNS_EDE);
|
||||
edns_opt_list_remove(&edns->opt_list_out, LDNS_EDNS_EDE);
|
||||
attach_edns_record_max_msg_sz(pkt, edns, udpsize);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -959,14 +1063,16 @@ qinfo_query_encode(sldns_buffer* pkt, struct query_info* qinfo)
|
|||
}
|
||||
|
||||
void
|
||||
error_encode(sldns_buffer* buf, int r, struct query_info* qinfo,
|
||||
uint16_t qid, uint16_t qflags, struct edns_data* edns)
|
||||
extended_error_encode(sldns_buffer* buf, uint16_t rcode,
|
||||
struct query_info* qinfo, uint16_t qid, uint16_t qflags,
|
||||
uint16_t xflags, struct edns_data* edns)
|
||||
{
|
||||
uint16_t flags;
|
||||
|
||||
sldns_buffer_clear(buf);
|
||||
sldns_buffer_write(buf, &qid, sizeof(uint16_t));
|
||||
flags = (uint16_t)(BIT_QR | BIT_RA | r); /* QR and retcode*/
|
||||
flags = (uint16_t)(BIT_QR | BIT_RA | (rcode & 0xF)); /* QR and retcode*/
|
||||
flags |= xflags;
|
||||
flags |= (qflags & (BIT_RD|BIT_CD)); /* copy RD and CD bit */
|
||||
sldns_buffer_write_u16(buf, flags);
|
||||
if(qinfo) flags = 1;
|
||||
|
@ -993,11 +1099,25 @@ error_encode(sldns_buffer* buf, int r, struct query_info* qinfo,
|
|||
struct edns_data es = *edns;
|
||||
es.edns_version = EDNS_ADVERTISED_VERSION;
|
||||
es.udp_size = EDNS_ADVERTISED_SIZE;
|
||||
es.ext_rcode = 0;
|
||||
es.ext_rcode = (uint8_t)(rcode >> 4);
|
||||
es.bits &= EDNS_DO;
|
||||
if(sldns_buffer_limit(buf) + calc_edns_field_size(&es) >
|
||||
edns->udp_size)
|
||||
edns->udp_size) {
|
||||
edns_opt_list_remove(&es.opt_list_inplace_cb_out, LDNS_EDNS_EDE);
|
||||
edns_opt_list_remove(&es.opt_list_out, LDNS_EDNS_EDE);
|
||||
if(sldns_buffer_limit(buf) + calc_edns_field_size(&es) >
|
||||
edns->udp_size) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
attach_edns_record(buf, &es);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
error_encode(sldns_buffer* buf, int r, struct query_info* qinfo,
|
||||
uint16_t qid, uint16_t qflags, struct edns_data* edns)
|
||||
{
|
||||
extended_error_encode(buf, (r & 0x000F), qinfo, qid, qflags,
|
||||
(r & 0xFFF0), edns);
|
||||
}
|
||||
|
|
|
@ -108,6 +108,27 @@ void qinfo_query_encode(struct sldns_buffer* pkt, struct query_info* qinfo);
|
|||
*/
|
||||
uint16_t calc_edns_field_size(struct edns_data* edns);
|
||||
|
||||
/**
|
||||
* Calculate the size of a specific EDNS option in packet.
|
||||
* @param edns: edns data or NULL.
|
||||
* @param code: the opt code to get the size of.
|
||||
* @return octets the option will take up.
|
||||
*/
|
||||
uint16_t calc_edns_option_size(struct edns_data* edns, uint16_t code);
|
||||
|
||||
/**
|
||||
* Calculate the size of the EDE option(s) in packet. Also calculate seperately
|
||||
* the size of the EXTRA-TEXT field(s) in case we can trim them to fit.
|
||||
* In this case include any LDNS_EDE_OTHER options in their entirety since they
|
||||
* are useless without extra text.
|
||||
* @param edns: edns data or NULL.
|
||||
* @param txt_size: the size of the EXTRA-TEXT field(s); this includes
|
||||
* LDNS_EDE_OTHER in their entirety since they are useless without
|
||||
* extra text.
|
||||
* @return octets the option will take up.
|
||||
*/
|
||||
uint16_t calc_ede_option_size(struct edns_data* edns, uint16_t* txt_size);
|
||||
|
||||
/**
|
||||
* Attach EDNS record to buffer. Buffer has complete packet. There must
|
||||
* be enough room left for the EDNS record.
|
||||
|
@ -120,7 +141,7 @@ void attach_edns_record(struct sldns_buffer* pkt, struct edns_data* edns);
|
|||
* Encode an error. With QR and RA set.
|
||||
*
|
||||
* @param pkt: where to store the packet.
|
||||
* @param r: RCODE value to encode.
|
||||
* @param r: RCODE value to encode (may contain extra flags).
|
||||
* @param qinfo: if not NULL, the query is included.
|
||||
* @param qid: query ID to set in packet. network order.
|
||||
* @param qflags: original query flags (to copy RD and CD bits). host order.
|
||||
|
@ -130,4 +151,21 @@ void attach_edns_record(struct sldns_buffer* pkt, struct edns_data* edns);
|
|||
void error_encode(struct sldns_buffer* pkt, int r, struct query_info* qinfo,
|
||||
uint16_t qid, uint16_t qflags, struct edns_data* edns);
|
||||
|
||||
/**
|
||||
* Encode an extended error. With QR and RA set.
|
||||
*
|
||||
* @param pkt: where to store the packet.
|
||||
* @param rcode: Extended RCODE value to encode.
|
||||
* @param qinfo: if not NULL, the query is included.
|
||||
* @param qid: query ID to set in packet. network order.
|
||||
* @param qflags: original query flags (to copy RD and CD bits). host order.
|
||||
* @param xflags: extra flags to set (such as for example BIT_AA and/or BIT_TC)
|
||||
* @param edns: if not NULL, this is the query edns info,
|
||||
* and an edns reply is attached. Only attached if EDNS record fits reply.
|
||||
* Without edns extended errors (i.e. > 15) will not be conveyed.
|
||||
*/
|
||||
void extended_error_encode(struct sldns_buffer* pkt, uint16_t rcode,
|
||||
struct query_info* qinfo, uint16_t qid, uint16_t qflags,
|
||||
uint16_t xflags, struct edns_data* edns);
|
||||
|
||||
#endif /* UTIL_DATA_MSGENCODE_H */
|
||||
|
|
|
@ -45,6 +45,8 @@
|
|||
#include "util/netevent.h"
|
||||
#include "util/storage/lookup3.h"
|
||||
#include "util/regional.h"
|
||||
#include "util/rfc_1982.h"
|
||||
#include "util/edns.h"
|
||||
#include "sldns/rrdef.h"
|
||||
#include "sldns/sbuffer.h"
|
||||
#include "sldns/parseutil.h"
|
||||
|
@ -940,22 +942,11 @@ parse_packet(sldns_buffer* pkt, struct msg_parse* msg, struct regional* region)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
edns_opt_list_append_keepalive(struct edns_option** list, int msec,
|
||||
struct regional* region)
|
||||
{
|
||||
uint8_t data[2]; /* For keepalive value */
|
||||
data[0] = (uint8_t)((msec >> 8) & 0xff);
|
||||
data[1] = (uint8_t)(msec & 0xff);
|
||||
return edns_opt_list_append(list, LDNS_EDNS_KEEPALIVE, sizeof(data),
|
||||
data, region);
|
||||
}
|
||||
|
||||
/** parse EDNS options from EDNS wireformat rdata */
|
||||
static int
|
||||
parse_edns_options_from_query(uint8_t* rdata_ptr, size_t rdata_len,
|
||||
struct edns_data* edns, struct config_file* cfg, struct comm_point* c,
|
||||
struct regional* region)
|
||||
struct comm_reply* repinfo, uint32_t now, struct regional* region)
|
||||
{
|
||||
/* To respond with a Keepalive option, the client connection must have
|
||||
* received one message with a TCP Keepalive EDNS option, and that
|
||||
|
@ -979,6 +970,10 @@ parse_edns_options_from_query(uint8_t* rdata_ptr, size_t rdata_len,
|
|||
while(rdata_len >= 4) {
|
||||
uint16_t opt_code = sldns_read_uint16(rdata_ptr);
|
||||
uint16_t opt_len = sldns_read_uint16(rdata_ptr+2);
|
||||
uint8_t server_cookie[40];
|
||||
enum edns_cookie_val_status cookie_val_status;
|
||||
int cookie_is_v4 = 1;
|
||||
|
||||
rdata_ptr += 4;
|
||||
rdata_len -= 4;
|
||||
if(opt_len > rdata_len)
|
||||
|
@ -1041,6 +1036,76 @@ parse_edns_options_from_query(uint8_t* rdata_ptr, size_t rdata_len,
|
|||
edns->padding_block_size = cfg->pad_responses_block_size;
|
||||
break;
|
||||
|
||||
case LDNS_EDNS_COOKIE:
|
||||
if(!cfg || !cfg->do_answer_cookie || !repinfo)
|
||||
break;
|
||||
if(opt_len != 8 && (opt_len < 16 || opt_len > 40)) {
|
||||
verbose(VERB_ALGO, "worker request: "
|
||||
"badly formatted cookie");
|
||||
return LDNS_RCODE_FORMERR;
|
||||
}
|
||||
edns->cookie_present = 1;
|
||||
|
||||
/* Copy client cookie, version and timestamp for
|
||||
* validation and creation purposes.
|
||||
*/
|
||||
if(opt_len >= 16) {
|
||||
memmove(server_cookie, rdata_ptr, 16);
|
||||
} else {
|
||||
memset(server_cookie, 0, 16);
|
||||
memmove(server_cookie, rdata_ptr, opt_len);
|
||||
}
|
||||
|
||||
/* Copy client ip for validation and creation
|
||||
* purposes. It will be overwritten if (re)creation
|
||||
* is needed.
|
||||
*/
|
||||
if(repinfo->remote_addr.ss_family == AF_INET) {
|
||||
memcpy(server_cookie + 16,
|
||||
&((struct sockaddr_in*)&repinfo->remote_addr)->sin_addr, 4);
|
||||
} else {
|
||||
cookie_is_v4 = 0;
|
||||
memcpy(server_cookie + 16,
|
||||
&((struct sockaddr_in6*)&repinfo->remote_addr)->sin6_addr, 16);
|
||||
}
|
||||
|
||||
cookie_val_status = edns_cookie_server_validate(
|
||||
rdata_ptr, opt_len, cfg->cookie_secret,
|
||||
cfg->cookie_secret_len, cookie_is_v4,
|
||||
server_cookie, now);
|
||||
switch(cookie_val_status) {
|
||||
case COOKIE_STATUS_VALID:
|
||||
case COOKIE_STATUS_VALID_RENEW:
|
||||
edns->cookie_valid = 1;
|
||||
/* Reuse cookie */
|
||||
if(!edns_opt_list_append(
|
||||
&edns->opt_list_out, LDNS_EDNS_COOKIE,
|
||||
opt_len, rdata_ptr, region)) {
|
||||
log_err("out of memory");
|
||||
return LDNS_RCODE_SERVFAIL;
|
||||
}
|
||||
/* Cookie to be reused added to outgoing
|
||||
* options. Done!
|
||||
*/
|
||||
break;
|
||||
case COOKIE_STATUS_CLIENT_ONLY:
|
||||
edns->cookie_client = 1;
|
||||
/* fallthrough */
|
||||
case COOKIE_STATUS_FUTURE:
|
||||
case COOKIE_STATUS_EXPIRED:
|
||||
case COOKIE_STATUS_INVALID:
|
||||
default:
|
||||
edns_cookie_server_write(server_cookie,
|
||||
cfg->cookie_secret, cookie_is_v4, now);
|
||||
if(!edns_opt_list_append(&edns->opt_list_out,
|
||||
LDNS_EDNS_COOKIE, 24, server_cookie,
|
||||
region)) {
|
||||
log_err("out of memory");
|
||||
return LDNS_RCODE_SERVFAIL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -1115,6 +1180,8 @@ parse_extract_edns_from_response_msg(struct msg_parse* msg,
|
|||
edns->opt_list_out = NULL;
|
||||
edns->opt_list_inplace_cb_out = NULL;
|
||||
edns->padding_block_size = 0;
|
||||
edns->cookie_present = 0;
|
||||
edns->cookie_valid = 0;
|
||||
|
||||
/* take the options */
|
||||
rdata_len = found->rr_first->size-2;
|
||||
|
@ -1170,7 +1237,8 @@ skip_pkt_rrs(sldns_buffer* pkt, int num)
|
|||
|
||||
int
|
||||
parse_edns_from_query_pkt(sldns_buffer* pkt, struct edns_data* edns,
|
||||
struct config_file* cfg, struct comm_point* c, struct regional* region)
|
||||
struct config_file* cfg, struct comm_point* c,
|
||||
struct comm_reply* repinfo, time_t now, struct regional* region)
|
||||
{
|
||||
size_t rdata_len;
|
||||
uint8_t* rdata_ptr;
|
||||
|
@ -1206,6 +1274,8 @@ parse_edns_from_query_pkt(sldns_buffer* pkt, struct edns_data* edns,
|
|||
edns->opt_list_out = NULL;
|
||||
edns->opt_list_inplace_cb_out = NULL;
|
||||
edns->padding_block_size = 0;
|
||||
edns->cookie_present = 0;
|
||||
edns->cookie_valid = 0;
|
||||
|
||||
/* take the options */
|
||||
rdata_len = sldns_buffer_read_u16(pkt);
|
||||
|
@ -1214,7 +1284,7 @@ parse_edns_from_query_pkt(sldns_buffer* pkt, struct edns_data* edns,
|
|||
rdata_ptr = sldns_buffer_current(pkt);
|
||||
/* ignore rrsigs */
|
||||
return parse_edns_options_from_query(rdata_ptr, rdata_len, edns, cfg,
|
||||
c, region);
|
||||
c, repinfo, now, region);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -72,6 +72,7 @@ struct regional;
|
|||
struct edns_option;
|
||||
struct config_file;
|
||||
struct comm_point;
|
||||
struct comm_reply;
|
||||
|
||||
/** number of buckets in parse rrset hash table. Must be power of 2. */
|
||||
#define PARSE_TABLE_SIZE 32
|
||||
|
@ -217,8 +218,6 @@ struct rr_parse {
|
|||
* region.
|
||||
*/
|
||||
struct edns_data {
|
||||
/** if EDNS OPT record was present */
|
||||
int edns_present;
|
||||
/** Extended RCODE */
|
||||
uint8_t ext_rcode;
|
||||
/** The EDNS version number */
|
||||
|
@ -238,6 +237,14 @@ struct edns_data {
|
|||
struct edns_option* opt_list_inplace_cb_out;
|
||||
/** block size to pad */
|
||||
uint16_t padding_block_size;
|
||||
/** if EDNS OPT record was present */
|
||||
unsigned int edns_present : 1;
|
||||
/** if a cookie was present */
|
||||
unsigned int cookie_present : 1;
|
||||
/** if the cookie validated */
|
||||
unsigned int cookie_valid : 1;
|
||||
/** if the cookie holds only the client part */
|
||||
unsigned int cookie_client : 1;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -310,12 +317,15 @@ int skip_pkt_rrs(struct sldns_buffer* pkt, int num);
|
|||
* initialised.
|
||||
* @param cfg: the configuration (with nsid value etc.)
|
||||
* @param c: commpoint to determine transport (if needed)
|
||||
* @param repinfo: commreply to determine the client address
|
||||
* @param now: current time
|
||||
* @param region: region to alloc results in (edns option contents)
|
||||
* @return: 0 on success, or an RCODE on error.
|
||||
* RCODE formerr if OPT is badly formatted and so on.
|
||||
*/
|
||||
int parse_edns_from_query_pkt(struct sldns_buffer* pkt, struct edns_data* edns,
|
||||
struct config_file* cfg, struct comm_point* c, struct regional* region);
|
||||
struct config_file* cfg, struct comm_point* c,
|
||||
struct comm_reply* repinfo, time_t now, struct regional* region);
|
||||
|
||||
/**
|
||||
* Calculate hash value for rrset in packet.
|
||||
|
|
|
@ -94,7 +94,7 @@ parse_create_qinfo(sldns_buffer* pkt, struct msg_parse* msg,
|
|||
struct reply_info*
|
||||
construct_reply_info_base(struct regional* region, uint16_t flags, size_t qd,
|
||||
time_t ttl, time_t prettl, time_t expttl, size_t an, size_t ns,
|
||||
size_t ar, size_t total, enum sec_status sec)
|
||||
size_t ar, size_t total, enum sec_status sec, sldns_ede_code reason_bogus)
|
||||
{
|
||||
struct reply_info* rep;
|
||||
/* rrset_count-1 because the first ref is part of the struct. */
|
||||
|
@ -117,7 +117,9 @@ construct_reply_info_base(struct regional* region, uint16_t flags, size_t qd,
|
|||
rep->ar_numrrsets = ar;
|
||||
rep->rrset_count = total;
|
||||
rep->security = sec;
|
||||
rep->reason_bogus = LDNS_EDE_NONE;
|
||||
rep->reason_bogus = reason_bogus;
|
||||
/* this is only allocated and used for caching on copy */
|
||||
rep->reason_bogus_str = NULL;
|
||||
rep->authoritative = 0;
|
||||
/* array starts after the refs */
|
||||
if(region)
|
||||
|
@ -137,7 +139,7 @@ parse_create_repinfo(struct msg_parse* msg, struct reply_info** rep,
|
|||
{
|
||||
*rep = construct_reply_info_base(region, msg->flags, msg->qdcount, 0,
|
||||
0, 0, msg->an_rrsets, msg->ns_rrsets, msg->ar_rrsets,
|
||||
msg->rrset_count, sec_status_unchecked);
|
||||
msg->rrset_count, sec_status_unchecked, LDNS_EDE_NONE);
|
||||
if(!*rep)
|
||||
return 0;
|
||||
return 1;
|
||||
|
@ -182,7 +184,7 @@ make_new_reply_info(const struct reply_info* rep, struct regional* region,
|
|||
new_rep = construct_reply_info_base(region, rep->flags,
|
||||
rep->qdcount, rep->ttl, rep->prefetch_ttl,
|
||||
rep->serve_expired_ttl, an_numrrsets, 0, 0, an_numrrsets,
|
||||
sec_status_insecure);
|
||||
sec_status_insecure, LDNS_EDE_NONE);
|
||||
if(!new_rep)
|
||||
return NULL;
|
||||
if(!reply_info_alloc_rrset_keys(new_rep, NULL, region))
|
||||
|
@ -580,6 +582,10 @@ reply_info_parsedelete(struct reply_info* rep, struct alloc_cache* alloc)
|
|||
for(i=0; i<rep->rrset_count; i++) {
|
||||
ub_packed_rrset_parsedelete(rep->rrsets[i], alloc);
|
||||
}
|
||||
if(rep->reason_bogus_str) {
|
||||
free(rep->reason_bogus_str);
|
||||
rep->reason_bogus_str = NULL;
|
||||
}
|
||||
free(rep);
|
||||
}
|
||||
|
||||
|
@ -661,6 +667,10 @@ void
|
|||
reply_info_delete(void* d, void* ATTR_UNUSED(arg))
|
||||
{
|
||||
struct reply_info* r = (struct reply_info*)d;
|
||||
if(r->reason_bogus_str) {
|
||||
free(r->reason_bogus_str);
|
||||
r->reason_bogus_str = NULL;
|
||||
}
|
||||
free(r);
|
||||
}
|
||||
|
||||
|
@ -745,9 +755,28 @@ reply_info_copy(struct reply_info* rep, struct alloc_cache* alloc,
|
|||
cp = construct_reply_info_base(region, rep->flags, rep->qdcount,
|
||||
rep->ttl, rep->prefetch_ttl, rep->serve_expired_ttl,
|
||||
rep->an_numrrsets, rep->ns_numrrsets, rep->ar_numrrsets,
|
||||
rep->rrset_count, rep->security);
|
||||
rep->rrset_count, rep->security, rep->reason_bogus);
|
||||
if(!cp)
|
||||
return NULL;
|
||||
|
||||
if(rep->reason_bogus_str && *rep->reason_bogus_str != 0) {
|
||||
if(region) {
|
||||
cp->reason_bogus_str = (char*)regional_alloc(region,
|
||||
sizeof(char)
|
||||
* (strlen(rep->reason_bogus_str)+1));
|
||||
} else {
|
||||
cp->reason_bogus_str = malloc(sizeof(char)
|
||||
* (strlen(rep->reason_bogus_str)+1));
|
||||
}
|
||||
if(!cp->reason_bogus_str) {
|
||||
if(!region)
|
||||
reply_info_parsedelete(cp, alloc);
|
||||
return NULL;
|
||||
}
|
||||
memcpy(cp->reason_bogus_str, rep->reason_bogus_str,
|
||||
strlen(rep->reason_bogus_str)+1);
|
||||
}
|
||||
|
||||
/* allocate ub_key structures special or not */
|
||||
if(!reply_info_alloc_rrset_keys(cp, alloc, region)) {
|
||||
if(!region)
|
||||
|
@ -1020,6 +1049,16 @@ int edns_opt_list_append_ede(struct edns_option** list, struct regional* region,
|
|||
return 1;
|
||||
}
|
||||
|
||||
int edns_opt_list_append_keepalive(struct edns_option** list, int msec,
|
||||
struct regional* region)
|
||||
{
|
||||
uint8_t data[2]; /* For keepalive value */
|
||||
data[0] = (uint8_t)((msec >> 8) & 0xff);
|
||||
data[1] = (uint8_t)(msec & 0xff);
|
||||
return edns_opt_list_append(list, LDNS_EDNS_KEEPALIVE, sizeof(data),
|
||||
data, region);
|
||||
}
|
||||
|
||||
int edns_opt_list_append(struct edns_option** list, uint16_t code, size_t len,
|
||||
uint8_t* data, struct regional* region)
|
||||
{
|
||||
|
@ -1224,6 +1263,42 @@ struct edns_option* edns_opt_copy_region(struct edns_option* list,
|
|||
return result;
|
||||
}
|
||||
|
||||
struct edns_option* edns_opt_copy_filter_region(struct edns_option* list,
|
||||
uint16_t* filter_list, size_t filter_list_len, struct regional* region)
|
||||
{
|
||||
struct edns_option* result = NULL, *cur = NULL, *s;
|
||||
size_t i;
|
||||
while(list) {
|
||||
for(i=0; i<filter_list_len; i++)
|
||||
if(filter_list[i] == list->opt_code) goto found;
|
||||
if(i == filter_list_len) goto next;
|
||||
found:
|
||||
/* copy edns option structure */
|
||||
s = regional_alloc_init(region, list, sizeof(*list));
|
||||
if(!s) return NULL;
|
||||
s->next = NULL;
|
||||
|
||||
/* copy option data */
|
||||
if(s->opt_data) {
|
||||
s->opt_data = regional_alloc_init(region, s->opt_data,
|
||||
s->opt_len);
|
||||
if(!s->opt_data)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* link into list */
|
||||
if(cur)
|
||||
cur->next = s;
|
||||
else result = s;
|
||||
cur = s;
|
||||
|
||||
next:
|
||||
/* examine next element */
|
||||
list = list->next;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int edns_opt_compare(struct edns_option* p, struct edns_option* q)
|
||||
{
|
||||
if(!p && !q) return 0;
|
||||
|
|
|
@ -170,9 +170,17 @@ struct reply_info {
|
|||
|
||||
/**
|
||||
* EDE (rfc8914) code with reason for DNSSEC bogus status.
|
||||
* Used for caching the EDE.
|
||||
*/
|
||||
sldns_ede_code reason_bogus;
|
||||
|
||||
/**
|
||||
* EDE (rfc8914) NULL-terminated string with human-readable reason
|
||||
* for DNSSEC bogus status.
|
||||
* Used for caching the EDE.
|
||||
*/
|
||||
char* reason_bogus_str;
|
||||
|
||||
/**
|
||||
* Number of RRsets in each section.
|
||||
* The answer section. Add up the RRs in every RRset to calculate
|
||||
|
@ -240,13 +248,15 @@ struct msgreply_entry {
|
|||
* @param ar: ar count
|
||||
* @param total: total rrset count (presumably an+ns+ar).
|
||||
* @param sec: security status of the reply info.
|
||||
* @param reason_bogus: the Extended DNS Error for DNSSEC bogus status
|
||||
* @return the reply_info base struct with the array for putting the rrsets
|
||||
* in. The array has been zeroed. Returns NULL on malloc failure.
|
||||
*/
|
||||
struct reply_info*
|
||||
construct_reply_info_base(struct regional* region, uint16_t flags, size_t qd,
|
||||
time_t ttl, time_t prettl, time_t expttl, size_t an, size_t ns,
|
||||
size_t ar, size_t total, enum sec_status sec);
|
||||
size_t ar, size_t total, enum sec_status sec,
|
||||
sldns_ede_code reason_bogus);
|
||||
|
||||
/**
|
||||
* Parse wire query into a queryinfo structure, return 0 on parse error.
|
||||
|
@ -567,6 +577,16 @@ int edns_opt_list_append(struct edns_option** list, uint16_t code, size_t len,
|
|||
int edns_opt_list_append_ede(struct edns_option** list, struct regional* region,
|
||||
sldns_ede_code code, const char *txt);
|
||||
|
||||
/**
|
||||
* Append edns keep alive option to edns options list
|
||||
* @param list: the edns option list to append the edns option to.
|
||||
* @param msec: the duration in msecs for the keep alive.
|
||||
* @param region: region to allocate the new edns option.
|
||||
* @return false on failure.
|
||||
*/
|
||||
int edns_opt_list_append_keepalive(struct edns_option** list, int msec,
|
||||
struct regional* region);
|
||||
|
||||
/**
|
||||
* Remove any option found on the edns option list that matches the code.
|
||||
* @param list: the list of edns options.
|
||||
|
@ -718,6 +738,12 @@ int inplace_cb_query_response_call(struct module_env* env,
|
|||
struct edns_option* edns_opt_copy_region(struct edns_option* list,
|
||||
struct regional* region);
|
||||
|
||||
/**
|
||||
* Copy a filtered edns option list allocated to the new region
|
||||
*/
|
||||
struct edns_option* edns_opt_copy_filter_region(struct edns_option* list,
|
||||
uint16_t* filter_list, size_t filter_list_len, struct regional* region);
|
||||
|
||||
/**
|
||||
* Copy edns option list allocated with malloc
|
||||
*/
|
||||
|
|
|
@ -45,8 +45,11 @@
|
|||
#include "util/netevent.h"
|
||||
#include "util/net_help.h"
|
||||
#include "util/regional.h"
|
||||
#include "util/rfc_1982.h"
|
||||
#include "util/siphash.h"
|
||||
#include "util/data/msgparse.h"
|
||||
#include "util/data/msgreply.h"
|
||||
#include "sldns/sbuffer.h"
|
||||
|
||||
struct edns_strings* edns_strings_create(void)
|
||||
{
|
||||
|
@ -128,3 +131,59 @@ edns_string_addr_lookup(rbtree_type* tree, struct sockaddr_storage* addr,
|
|||
return (struct edns_string_addr*)addr_tree_lookup(tree, addr, addrlen);
|
||||
}
|
||||
|
||||
uint8_t*
|
||||
edns_cookie_server_hash(const uint8_t* in, const uint8_t* secret, int v4,
|
||||
uint8_t* hash)
|
||||
{
|
||||
v4?siphash(in, 20, secret, hash, 8):siphash(in, 32, secret, hash, 8);
|
||||
return hash;
|
||||
}
|
||||
|
||||
void
|
||||
edns_cookie_server_write(uint8_t* buf, const uint8_t* secret, int v4,
|
||||
uint32_t timestamp)
|
||||
{
|
||||
uint8_t hash[8];
|
||||
buf[ 8] = 1; /* Version */
|
||||
buf[ 9] = 0; /* Reserved */
|
||||
buf[10] = 0; /* Reserved */
|
||||
buf[11] = 0; /* Reserved */
|
||||
sldns_write_uint32(buf + 12, timestamp);
|
||||
(void)edns_cookie_server_hash(buf, secret, v4, hash);
|
||||
memcpy(buf + 16, hash, 8);
|
||||
}
|
||||
|
||||
enum edns_cookie_val_status
|
||||
edns_cookie_server_validate(const uint8_t* cookie, size_t cookie_len,
|
||||
const uint8_t* secret, size_t secret_len, int v4,
|
||||
const uint8_t* hash_input, uint32_t now)
|
||||
{
|
||||
uint8_t hash[8];
|
||||
uint32_t timestamp;
|
||||
uint32_t subt_1982 = 0; /* Initialize for the compiler; unused value */
|
||||
int comp_1982;
|
||||
if(cookie_len != 24)
|
||||
/* RFC9018 cookies are 24 bytes long */
|
||||
return COOKIE_STATUS_CLIENT_ONLY;
|
||||
if(secret_len != 16 || /* RFC9018 cookies have 16 byte secrets */
|
||||
cookie[8] != 1) /* RFC9018 cookies are cookie version 1 */
|
||||
return COOKIE_STATUS_INVALID;
|
||||
timestamp = sldns_read_uint32(cookie + 12);
|
||||
if((comp_1982 = compare_1982(now, timestamp)) > 0
|
||||
&& (subt_1982 = subtract_1982(timestamp, now)) > 3600)
|
||||
/* Cookie is older than 1 hour (see RFC9018 Section 4.3.) */
|
||||
return COOKIE_STATUS_EXPIRED;
|
||||
if(comp_1982 <= 0 && subtract_1982(now, timestamp) > 300)
|
||||
/* Cookie time is more than 5 minutes in the future.
|
||||
* (see RFC9018 Section 4.3.) */
|
||||
return COOKIE_STATUS_FUTURE;
|
||||
if(memcmp(edns_cookie_server_hash(hash_input, secret, v4, hash),
|
||||
cookie + 16, 8) != 0)
|
||||
/* Hashes do not match */
|
||||
return COOKIE_STATUS_INVALID;
|
||||
if(comp_1982 > 0 && subt_1982 > 1800)
|
||||
/* Valid cookie but older than 30 minutes, so create a new one
|
||||
* anyway */
|
||||
return COOKIE_STATUS_VALID_RENEW;
|
||||
return COOKIE_STATUS_VALID;
|
||||
}
|
||||
|
|
|
@ -75,6 +75,15 @@ struct edns_string_addr {
|
|||
size_t string_len;
|
||||
};
|
||||
|
||||
enum edns_cookie_val_status {
|
||||
COOKIE_STATUS_CLIENT_ONLY = -3,
|
||||
COOKIE_STATUS_FUTURE = -2,
|
||||
COOKIE_STATUS_EXPIRED = -1,
|
||||
COOKIE_STATUS_INVALID = 0,
|
||||
COOKIE_STATUS_VALID = 1,
|
||||
COOKIE_STATUS_VALID_RENEW = 2,
|
||||
};
|
||||
|
||||
/**
|
||||
* Create structure to hold EDNS strings
|
||||
* @return: newly created edns_strings, NULL on alloc failure.
|
||||
|
@ -106,4 +115,54 @@ struct edns_string_addr*
|
|||
edns_string_addr_lookup(rbtree_type* tree, struct sockaddr_storage* addr,
|
||||
socklen_t addrlen);
|
||||
|
||||
/**
|
||||
* Compute the interoperable DNS cookie (RFC9018) hash.
|
||||
* @param in: buffer input for the hash generation. It needs to be:
|
||||
* Client Cookie | Version | Reserved | Timestamp | Client-IP
|
||||
* @param secret: the server secret; implicit length of 16 octets.
|
||||
* @param v4: if the client IP is v4 or v6.
|
||||
* @param hash: buffer to write the hash to.
|
||||
* return a pointer to the hash.
|
||||
*/
|
||||
uint8_t* edns_cookie_server_hash(const uint8_t* in, const uint8_t* secret,
|
||||
int v4, uint8_t* hash);
|
||||
|
||||
/**
|
||||
* Write an interoperable DNS server cookie (RFC9018).
|
||||
* @param buf: buffer to write to. It should have a size of at least 32 octets
|
||||
* as it doubles as the output buffer and the hash input buffer.
|
||||
* The first 8 octets are expected to be the Client Cookie and will be
|
||||
* left untouched.
|
||||
* The next 8 octets will be written with Version | Reserved | Timestamp.
|
||||
* The next 4 or 16 octets are expected to be the IPv4 or the IPv6 address
|
||||
* based on the v4 flag.
|
||||
* Thus the first 20 or 32 octets, based on the v4 flag, will be used as
|
||||
* the hash input.
|
||||
* The server hash (8 octets) will be written after the first 16 octets;
|
||||
* overwriting the address information.
|
||||
* The caller expects a complete, 24 octet long cookie in the buffer.
|
||||
* @param secret: the server secret; implicit length of 16 octets.
|
||||
* @param v4: if the client IP is v4 or v6.
|
||||
* @param timestamp: the timestamp to use.
|
||||
*/
|
||||
void edns_cookie_server_write(uint8_t* buf, const uint8_t* secret, int v4,
|
||||
uint32_t timestamp);
|
||||
|
||||
/**
|
||||
* Validate an interoperable DNS cookie (RFC9018).
|
||||
* @param cookie: pointer to the cookie data.
|
||||
* @param cookie_len: the length of the cookie data.
|
||||
* @param secret: pointer to the server secret.
|
||||
* @param secret_len: the length of the secret.
|
||||
* @param v4: if the client IP is v4 or v6.
|
||||
* @param hash_input: pointer to the hash input for validation. It needs to be:
|
||||
* Client Cookie | Version | Reserved | Timestamp | Client-IP
|
||||
* @param now: the current time.
|
||||
* return edns_cookie_val_status with the cookie validation status i.e.,
|
||||
* <=0 for invalid, else valid.
|
||||
*/
|
||||
enum edns_cookie_val_status edns_cookie_server_validate(const uint8_t* cookie,
|
||||
size_t cookie_len, const uint8_t* secret, size_t secret_len, int v4,
|
||||
const uint8_t* hash_input, uint32_t now);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -659,6 +659,10 @@ int fptr_whitelist_inplace_cb_edns_back_parsed(
|
|||
#else
|
||||
(void)fptr;
|
||||
#endif
|
||||
#ifdef WITH_PYTHONMODULE
|
||||
if(fptr == &python_inplace_cb_edns_back_parsed_call)
|
||||
return 1;
|
||||
#endif
|
||||
#ifdef WITH_DYNLIBMODULE
|
||||
if(fptr == &dynlib_inplace_cb_edns_back_parsed)
|
||||
return 1;
|
||||
|
@ -675,6 +679,10 @@ int fptr_whitelist_inplace_cb_query_response(
|
|||
#else
|
||||
(void)fptr;
|
||||
#endif
|
||||
#ifdef WITH_PYTHONMODULE
|
||||
if(fptr == &python_inplace_cb_query_response)
|
||||
return 1;
|
||||
#endif
|
||||
#ifdef WITH_DYNLIBMODULE
|
||||
if(fptr == &dynlib_inplace_cb_query_response)
|
||||
return 1;
|
||||
|
|
|
@ -674,6 +674,8 @@
|
|||
911,
|
||||
912,
|
||||
913,
|
||||
914,
|
||||
915,
|
||||
989,
|
||||
990,
|
||||
991,
|
||||
|
@ -1901,6 +1903,7 @@
|
|||
2256,
|
||||
2257,
|
||||
2258,
|
||||
2259,
|
||||
2260,
|
||||
2261,
|
||||
2262,
|
||||
|
@ -2010,6 +2013,7 @@
|
|||
2366,
|
||||
2367,
|
||||
2368,
|
||||
2369,
|
||||
2370,
|
||||
2372,
|
||||
2378,
|
||||
|
@ -4840,6 +4844,7 @@
|
|||
8403,
|
||||
8416,
|
||||
8417,
|
||||
8433,
|
||||
8442,
|
||||
8443,
|
||||
8444,
|
||||
|
|
|
@ -84,8 +84,10 @@ void errinf_ede(struct module_qstate* qstate,
|
|||
const char* str, sldns_ede_code reason_bogus)
|
||||
{
|
||||
struct errinf_strlist* p;
|
||||
if((qstate->env->cfg->val_log_level < 2 && !qstate->env->cfg->log_servfail) || !str)
|
||||
if(!str || (qstate->env->cfg->val_log_level < 2 &&
|
||||
!qstate->env->cfg->log_servfail)) {
|
||||
return;
|
||||
}
|
||||
p = (struct errinf_strlist*)regional_alloc(qstate->region, sizeof(*p));
|
||||
if(!p) {
|
||||
log_err("malloc failure in validator-error-info string");
|
||||
|
@ -152,15 +154,19 @@ char* errinf_to_str_bogus(struct module_qstate* qstate)
|
|||
return p;
|
||||
}
|
||||
|
||||
/* Try to find the latest (most specific) dnssec failure */
|
||||
sldns_ede_code errinf_to_reason_bogus(struct module_qstate* qstate)
|
||||
{
|
||||
struct errinf_strlist* s;
|
||||
sldns_ede_code ede = LDNS_EDE_NONE;
|
||||
for(s=qstate->errinf; s; s=s->next) {
|
||||
if (s->reason_bogus != LDNS_EDE_NONE) {
|
||||
return s->reason_bogus;
|
||||
if(s->reason_bogus == LDNS_EDE_NONE) continue;
|
||||
if(ede != LDNS_EDE_NONE
|
||||
&& ede != LDNS_EDE_DNSSEC_BOGUS
|
||||
&& s->reason_bogus == LDNS_EDE_DNSSEC_BOGUS) continue;
|
||||
ede = s->reason_bogus;
|
||||
}
|
||||
}
|
||||
return LDNS_EDE_NONE;
|
||||
return ede;
|
||||
}
|
||||
|
||||
char* errinf_to_str_servfail(struct module_qstate* qstate)
|
||||
|
|
|
@ -619,6 +619,12 @@ struct module_qstate {
|
|||
/** if this is a validation recursion query that does not get
|
||||
* validation itself */
|
||||
int is_valrec;
|
||||
#ifdef CLIENT_SUBNET
|
||||
/** the client network address is needed for the client-subnet option
|
||||
* when prefetching, but we can't use reply_list in mesh_info, because
|
||||
* we don't want to send a reply for the internal query. */
|
||||
struct sockaddr_storage client_addr;
|
||||
#endif
|
||||
|
||||
/** comm_reply contains server replies */
|
||||
struct comm_reply* reply;
|
||||
|
@ -671,6 +677,8 @@ struct module_qstate {
|
|||
* those servers. By comparing expiry time with qstarttime for type NS.
|
||||
*/
|
||||
time_t qstarttime;
|
||||
/** whether a message from cachedb will be used for the reply */
|
||||
int is_cachedb_answer;
|
||||
|
||||
/**
|
||||
* Attributes of clients that share the qstate that may affect IP-based
|
||||
|
@ -818,11 +826,11 @@ void errinf_dname(struct module_qstate* qstate, const char* str,
|
|||
* This string is malloced and has to be freed by caller.
|
||||
*/
|
||||
char* errinf_to_str_bogus(struct module_qstate* qstate);
|
||||
|
||||
/**
|
||||
* Check the sldns_ede_code of the qstate.
|
||||
* Check the sldns_ede_code of the qstate->errinf.
|
||||
* @param qstate: query state.
|
||||
* @return LDNS_EDE_DNSSEC_BOGUS by default, or the first explicitly set
|
||||
* sldns_ede_code.
|
||||
* @return the latest explicitly set sldns_ede_code or LDNS_EDE_NONE.
|
||||
*/
|
||||
sldns_ede_code errinf_to_reason_bogus(struct module_qstate* qstate);
|
||||
|
||||
|
|
|
@ -792,6 +792,49 @@ addr_to_str(struct sockaddr_storage* addr, socklen_t addrlen,
|
|||
}
|
||||
}
|
||||
|
||||
int
|
||||
prefixnet_is_nat64(int prefixnet)
|
||||
{
|
||||
return (prefixnet == 32 || prefixnet == 40 ||
|
||||
prefixnet == 48 || prefixnet == 56 ||
|
||||
prefixnet == 64 || prefixnet == 96);
|
||||
}
|
||||
|
||||
void
|
||||
addr_to_nat64(const struct sockaddr_storage* addr,
|
||||
const struct sockaddr_storage* nat64_prefix,
|
||||
socklen_t nat64_prefixlen, int nat64_prefixnet,
|
||||
struct sockaddr_storage* nat64_addr, socklen_t* nat64_addrlen)
|
||||
{
|
||||
struct sockaddr_in *sin = (struct sockaddr_in *)addr;
|
||||
struct sockaddr_in6 *sin6;
|
||||
uint8_t *v4_byte;
|
||||
|
||||
/* This needs to be checked by the caller */
|
||||
log_assert(addr->ss_family == AF_INET);
|
||||
/* Current usage is only from config values; prefix lengths enforced
|
||||
* during config validation */
|
||||
log_assert(prefixnet_is_nat64(nat64_prefixnet));
|
||||
|
||||
*nat64_addr = *nat64_prefix;
|
||||
*nat64_addrlen = nat64_prefixlen;
|
||||
|
||||
sin6 = (struct sockaddr_in6 *)nat64_addr;
|
||||
sin6->sin6_flowinfo = 0;
|
||||
sin6->sin6_port = sin->sin_port;
|
||||
|
||||
nat64_prefixnet = nat64_prefixnet / 8;
|
||||
|
||||
v4_byte = (uint8_t *)&sin->sin_addr.s_addr;
|
||||
for(int i = 0; i < 4; i++) {
|
||||
if(nat64_prefixnet == 8) {
|
||||
/* bits 64...71 are MBZ */
|
||||
sin6->sin6_addr.s6_addr[nat64_prefixnet++] = 0;
|
||||
}
|
||||
sin6->sin6_addr.s6_addr[nat64_prefixnet++] = *v4_byte++;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
addr_is_ip4mapped(struct sockaddr_storage* addr, socklen_t addrlen)
|
||||
{
|
||||
|
@ -1005,6 +1048,16 @@ listen_sslctx_setup(void* ctxt)
|
|||
log_crypto_err("could not set cipher list with SSL_CTX_set_cipher_list");
|
||||
}
|
||||
#endif
|
||||
#if defined(SSL_OP_IGNORE_UNEXPECTED_EOF)
|
||||
/* ignore errors when peers do not send the mandatory close_notify
|
||||
* alert on shutdown.
|
||||
* Relevant for openssl >= 3 */
|
||||
if((SSL_CTX_set_options(ctx, SSL_OP_IGNORE_UNEXPECTED_EOF) &
|
||||
SSL_OP_IGNORE_UNEXPECTED_EOF) != SSL_OP_IGNORE_UNEXPECTED_EOF) {
|
||||
log_crypto_err("could not set SSL_OP_IGNORE_UNEXPECTED_EOF");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
if((SSL_CTX_set_options(ctx, SSL_OP_CIPHER_SERVER_PREFERENCE) &
|
||||
SSL_OP_CIPHER_SERVER_PREFERENCE) !=
|
||||
|
@ -1233,6 +1286,17 @@ void* connect_sslctx_create(char* key, char* pem, char* verifypem, int wincert)
|
|||
SSL_CTX_free(ctx);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#if defined(SSL_OP_IGNORE_UNEXPECTED_EOF)
|
||||
/* ignore errors when peers do not send the mandatory close_notify
|
||||
* alert on shutdown.
|
||||
* Relevant for openssl >= 3 */
|
||||
if((SSL_CTX_set_options(ctx, SSL_OP_IGNORE_UNEXPECTED_EOF) &
|
||||
SSL_OP_IGNORE_UNEXPECTED_EOF) != SSL_OP_IGNORE_UNEXPECTED_EOF) {
|
||||
log_crypto_err("could not set SSL_OP_IGNORE_UNEXPECTED_EOF");
|
||||
SSL_CTX_free(ctx);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
if(key && key[0]) {
|
||||
if(!SSL_CTX_use_certificate_chain_file(ctx, pem)) {
|
||||
|
|
|
@ -331,6 +331,29 @@ int addr_in_common(struct sockaddr_storage* addr1, int net1,
|
|||
void addr_to_str(struct sockaddr_storage* addr, socklen_t addrlen,
|
||||
char* buf, size_t len);
|
||||
|
||||
/**
|
||||
* Check if the prefix network length is one of the allowed 32, 40, 48, 56, 64,
|
||||
* or 96.
|
||||
* @param prefixnet: prefix network length to check.
|
||||
* @return 1 on success, 0 on failure.
|
||||
*/
|
||||
int prefixnet_is_nat64(int prefixnet);
|
||||
|
||||
/**
|
||||
* Create a NAT64 address from a given address (needs to be IPv4) and a given
|
||||
* NAT64 prefix. The NAT64 prefix net needs to be one of 32, 40, 48, 56, 64, 96.
|
||||
* @param addr: IPv4 address.
|
||||
* @param nat64_prefix: NAT64 prefix.
|
||||
* @param nat64_prefixlen: NAT64 prefix len.
|
||||
* @param nat64_prefixnet: NAT64 prefix mask.
|
||||
* @param nat64_addr: the resulting NAT64 address.
|
||||
* @param nat64_addrlen: the resulting NAT64 address length.
|
||||
*/
|
||||
void addr_to_nat64(const struct sockaddr_storage* addr,
|
||||
const struct sockaddr_storage* nat64_prefix,
|
||||
socklen_t nat64_prefixlen, int nat64_prefixnet,
|
||||
struct sockaddr_storage* nat64_addr, socklen_t* nat64_addrlen);
|
||||
|
||||
/**
|
||||
* See if sockaddr is an ipv6 mapped ipv4 address, "::ffff:0.0.0.0"
|
||||
* @param addr: address
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
#include "util/tcp_conn_limit.h"
|
||||
#include "util/fptr_wlist.h"
|
||||
#include "util/proxy_protocol.h"
|
||||
#include "util/timeval_func.h"
|
||||
#include "sldns/pkthdr.h"
|
||||
#include "sldns/sbuffer.h"
|
||||
#include "sldns/str2wire.h"
|
||||
|
@ -71,7 +72,9 @@
|
|||
#ifdef HAVE_OPENSSL_ERR_H
|
||||
#include <openssl/err.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LINUX_NET_TSTAMP_H
|
||||
#include <linux/net_tstamp.h>
|
||||
#endif
|
||||
/* -------- Start of local definitions -------- */
|
||||
/** if CMSG_ALIGN is not defined on this platform, a workaround */
|
||||
#ifndef CMSG_ALIGN
|
||||
|
@ -114,6 +117,16 @@
|
|||
/** timeout in millisec to wait for write to unblock, packets dropped after.*/
|
||||
#define SEND_BLOCKED_WAIT_TIMEOUT 200
|
||||
|
||||
/** Let's make timestamping code cleaner and redefine SO_TIMESTAMP* */
|
||||
#ifndef SO_TIMESTAMP
|
||||
#define SO_TIMESTAMP 29
|
||||
#endif
|
||||
#ifndef SO_TIMESTAMPNS
|
||||
#define SO_TIMESTAMPNS 35
|
||||
#endif
|
||||
#ifndef SO_TIMESTAMPING
|
||||
#define SO_TIMESTAMPING 37
|
||||
#endif
|
||||
/**
|
||||
* The internal event structure for keeping ub_event info for the event.
|
||||
* Possibly other structures (list, tree) this is part of.
|
||||
|
@ -579,6 +592,11 @@ comm_point_send_udp_msg_if(struct comm_point *c, sldns_buffer* packet,
|
|||
cmsg_data = CMSG_DATA(cmsg);
|
||||
((struct in_pktinfo *) cmsg_data)->ipi_ifindex = 0;
|
||||
cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
|
||||
/* zero the padding bytes inserted by the CMSG_LEN */
|
||||
if(sizeof(struct in_pktinfo) < cmsg->cmsg_len)
|
||||
memset(((uint8_t*)(CMSG_DATA(cmsg))) +
|
||||
sizeof(struct in_pktinfo), 0, cmsg->cmsg_len
|
||||
- sizeof(struct in_pktinfo));
|
||||
#elif defined(IP_SENDSRCADDR)
|
||||
msg.msg_controllen = CMSG_SPACE(sizeof(struct in_addr));
|
||||
log_assert(msg.msg_controllen <= sizeof(control.buf));
|
||||
|
@ -587,6 +605,11 @@ comm_point_send_udp_msg_if(struct comm_point *c, sldns_buffer* packet,
|
|||
memmove(CMSG_DATA(cmsg), &r->pktinfo.v4addr,
|
||||
sizeof(struct in_addr));
|
||||
cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_addr));
|
||||
/* zero the padding bytes inserted by the CMSG_LEN */
|
||||
if(sizeof(struct in_addr) < cmsg->cmsg_len)
|
||||
memset(((uint8_t*)(CMSG_DATA(cmsg))) +
|
||||
sizeof(struct in_addr), 0, cmsg->cmsg_len
|
||||
- sizeof(struct in_addr));
|
||||
#else
|
||||
verbose(VERB_ALGO, "no IP_PKTINFO or IP_SENDSRCADDR");
|
||||
msg.msg_control = NULL;
|
||||
|
@ -603,6 +626,11 @@ comm_point_send_udp_msg_if(struct comm_point *c, sldns_buffer* packet,
|
|||
cmsg_data = CMSG_DATA(cmsg);
|
||||
((struct in6_pktinfo *) cmsg_data)->ipi6_ifindex = 0;
|
||||
cmsg->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
|
||||
/* zero the padding bytes inserted by the CMSG_LEN */
|
||||
if(sizeof(struct in6_pktinfo) < cmsg->cmsg_len)
|
||||
memset(((uint8_t*)(CMSG_DATA(cmsg))) +
|
||||
sizeof(struct in6_pktinfo), 0, cmsg->cmsg_len
|
||||
- sizeof(struct in6_pktinfo));
|
||||
} else {
|
||||
/* try to pass all 0 to use default route */
|
||||
msg.msg_controllen = CMSG_SPACE(sizeof(struct in6_pktinfo));
|
||||
|
@ -611,9 +639,14 @@ comm_point_send_udp_msg_if(struct comm_point *c, sldns_buffer* packet,
|
|||
cmsg->cmsg_type = IPV6_PKTINFO;
|
||||
memset(CMSG_DATA(cmsg), 0, sizeof(struct in6_pktinfo));
|
||||
cmsg->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
|
||||
/* zero the padding bytes inserted by the CMSG_LEN */
|
||||
if(sizeof(struct in6_pktinfo) < cmsg->cmsg_len)
|
||||
memset(((uint8_t*)(CMSG_DATA(cmsg))) +
|
||||
sizeof(struct in6_pktinfo), 0, cmsg->cmsg_len
|
||||
- sizeof(struct in6_pktinfo));
|
||||
}
|
||||
#endif /* S_SPLINT_S */
|
||||
if(verbosity >= VERB_ALGO)
|
||||
if(verbosity >= VERB_ALGO && r->srctype != 0)
|
||||
p_ancil("send_udp over interface", r);
|
||||
sent = sendmsg(c->fd, &msg, 0);
|
||||
if(sent == -1) {
|
||||
|
@ -833,6 +866,9 @@ comm_point_udp_ancil_callback(int fd, short event, void* arg)
|
|||
#ifndef S_SPLINT_S
|
||||
struct cmsghdr* cmsg;
|
||||
#endif /* S_SPLINT_S */
|
||||
#ifdef HAVE_LINUX_NET_TSTAMP_H
|
||||
struct timespec *ts;
|
||||
#endif /* HAVE_LINUX_NET_TSTAMP_H */
|
||||
|
||||
rep.c = (struct comm_point*)arg;
|
||||
log_assert(rep.c->type == comm_udp);
|
||||
|
@ -843,6 +879,7 @@ comm_point_udp_ancil_callback(int fd, short event, void* arg)
|
|||
ub_comm_base_now(rep.c->ev->base);
|
||||
for(i=0; i<NUM_UDP_PER_SELECT; i++) {
|
||||
sldns_buffer_clear(rep.c->buffer);
|
||||
timeval_clear(&rep.c->recv_tv);
|
||||
rep.remote_addrlen = (socklen_t)sizeof(rep.remote_addr);
|
||||
log_assert(fd != -1);
|
||||
log_assert(sldns_buffer_remaining(rep.c->buffer) > 0);
|
||||
|
@ -894,9 +931,23 @@ comm_point_udp_ancil_callback(int fd, short event, void* arg)
|
|||
sizeof(struct in_addr));
|
||||
break;
|
||||
#endif /* IP_PKTINFO or IP_RECVDSTADDR */
|
||||
#ifdef HAVE_LINUX_NET_TSTAMP_H
|
||||
} else if( cmsg->cmsg_level == SOL_SOCKET &&
|
||||
cmsg->cmsg_type == SO_TIMESTAMPNS) {
|
||||
ts = (struct timespec *)CMSG_DATA(cmsg);
|
||||
TIMESPEC_TO_TIMEVAL(&rep.c->recv_tv, ts);
|
||||
} else if( cmsg->cmsg_level == SOL_SOCKET &&
|
||||
cmsg->cmsg_type == SO_TIMESTAMPING) {
|
||||
ts = (struct timespec *)CMSG_DATA(cmsg);
|
||||
TIMESPEC_TO_TIMEVAL(&rep.c->recv_tv, ts);
|
||||
} else if( cmsg->cmsg_level == SOL_SOCKET &&
|
||||
cmsg->cmsg_type == SO_TIMESTAMP) {
|
||||
memmove(&rep.c->recv_tv, CMSG_DATA(cmsg), sizeof(struct timeval));
|
||||
#endif /* HAVE_LINUX_NET_TSTAMP_H */
|
||||
}
|
||||
}
|
||||
if(verbosity >= VERB_ALGO)
|
||||
|
||||
if(verbosity >= VERB_ALGO && rep.srctype != 0)
|
||||
p_ancil("receive_udp on interface", &rep);
|
||||
#endif /* S_SPLINT_S */
|
||||
|
||||
|
@ -2545,8 +2596,9 @@ comm_point_tcp_handle_write(int fd, struct comm_point* c)
|
|||
return 1;
|
||||
}
|
||||
|
||||
/** read again to drain buffers when there could be more to read */
|
||||
static void
|
||||
/** read again to drain buffers when there could be more to read, returns 0
|
||||
* on failure which means the comm point is closed. */
|
||||
static int
|
||||
tcp_req_info_read_again(int fd, struct comm_point* c)
|
||||
{
|
||||
while(c->tcp_req_info->read_again) {
|
||||
|
@ -2563,9 +2615,10 @@ tcp_req_info_read_again(int fd, struct comm_point* c)
|
|||
(void)(*c->callback)(c, c->cb_arg,
|
||||
NETEVENT_CLOSED, NULL);
|
||||
}
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** read again to drain buffers when there could be more to read */
|
||||
|
@ -2623,6 +2676,9 @@ comm_point_tcp_handle_callback(int fd, short event, void* arg)
|
|||
log_assert(c->type == comm_tcp);
|
||||
ub_comm_base_now(c->ev->base);
|
||||
|
||||
if(c->fd == -1 || c->fd != fd)
|
||||
return; /* duplicate event, but commpoint closed. */
|
||||
|
||||
#ifdef USE_DNSCRYPT
|
||||
/* Initialize if this is a dnscrypt socket */
|
||||
if(c->tcp_parent) {
|
||||
|
@ -2671,8 +2727,10 @@ comm_point_tcp_handle_callback(int fd, short event, void* arg)
|
|||
}
|
||||
return;
|
||||
}
|
||||
if(has_tcpq && c->tcp_req_info && c->tcp_req_info->read_again)
|
||||
tcp_req_info_read_again(fd, c);
|
||||
if(has_tcpq && c->tcp_req_info && c->tcp_req_info->read_again) {
|
||||
if(!tcp_req_info_read_again(fd, c))
|
||||
return;
|
||||
}
|
||||
if(moreread && *moreread)
|
||||
tcp_more_read_again(fd, c);
|
||||
return;
|
||||
|
@ -2690,8 +2748,10 @@ comm_point_tcp_handle_callback(int fd, short event, void* arg)
|
|||
}
|
||||
return;
|
||||
}
|
||||
if(has_tcpq && c->tcp_req_info && c->tcp_req_info->read_again)
|
||||
tcp_req_info_read_again(fd, c);
|
||||
if(has_tcpq && c->tcp_req_info && c->tcp_req_info->read_again) {
|
||||
if(!tcp_req_info_read_again(fd, c))
|
||||
return;
|
||||
}
|
||||
if(morewrite && *morewrite)
|
||||
tcp_more_write_again(fd, c);
|
||||
return;
|
||||
|
@ -3800,7 +3860,11 @@ comm_point_create_udp(struct comm_base *base, int fd, sldns_buffer* buffer,
|
|||
evbits = UB_EV_READ | UB_EV_PERSIST;
|
||||
/* ub_event stuff */
|
||||
c->ev->ev = ub_event_new(base->eb->base, c->fd, evbits,
|
||||
#ifdef USE_WINSOCK
|
||||
comm_point_udp_callback, c);
|
||||
#else
|
||||
comm_point_udp_ancil_callback, c);
|
||||
#endif
|
||||
if(c->ev->ev == NULL) {
|
||||
log_err("could not baseset udp event");
|
||||
comm_point_delete(c);
|
||||
|
@ -4488,6 +4552,11 @@ comm_point_close(struct comm_point* c)
|
|||
tcp_req_info_clear(c->tcp_req_info);
|
||||
if(c->h2_session)
|
||||
http2_session_server_delete(c->h2_session);
|
||||
/* stop the comm point from reading or writing after it is closed. */
|
||||
if(c->tcp_more_read_again && *c->tcp_more_read_again)
|
||||
*c->tcp_more_read_again = 0;
|
||||
if(c->tcp_more_write_again && *c->tcp_more_write_again)
|
||||
*c->tcp_more_write_again = 0;
|
||||
|
||||
/* close fd after removing from event lists, or epoll.. is messed up */
|
||||
if(c->fd != -1 && !c->do_not_close) {
|
||||
|
|
|
@ -60,6 +60,7 @@
|
|||
#ifndef NET_EVENT_H
|
||||
#define NET_EVENT_H
|
||||
|
||||
#include <sys/time.h>
|
||||
#include "dnscrypt/dnscrypt.h"
|
||||
#ifdef HAVE_NGHTTP2_NGHTTP2_H
|
||||
#include <nghttp2/nghttp2.h>
|
||||
|
@ -383,7 +384,8 @@ struct comm_point {
|
|||
/** number of queries outstanding on this socket, used by
|
||||
* outside network for udp ports */
|
||||
int inuse;
|
||||
|
||||
/** the timestamp when the packet was received by the kernel */
|
||||
struct timeval recv_tv;
|
||||
/** callback when done.
|
||||
tcp_accept does not get called back, is NULL then.
|
||||
If a timeout happens, callback with timeout=1 is called.
|
||||
|
|
|
@ -186,7 +186,7 @@ regional_alloc_init(struct regional* r, const void *init, size_t size)
|
|||
{
|
||||
void *s = regional_alloc(r, size);
|
||||
if(!s) return NULL;
|
||||
memcpy(s, init, size);
|
||||
memmove(s, init, size);
|
||||
return s;
|
||||
}
|
||||
|
||||
|
|
75
sbin/unwind/libunbound/util/rfc_1982.c
Normal file
75
sbin/unwind/libunbound/util/rfc_1982.c
Normal file
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* util/rfc_1982.c - RFC 1982 Serial Number Arithmetic
|
||||
*
|
||||
* Copyright (c) 2023, NLnet Labs. All rights reserved.
|
||||
*
|
||||
* This software is open source.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* Neither the name of the NLNET LABS nor the names of its contributors may
|
||||
* be used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* This file contains functions for RFC 1982 serial number arithmetic.
|
||||
*/
|
||||
#include "config.h"
|
||||
#include "util/rfc_1982.h"
|
||||
|
||||
int
|
||||
compare_1982(uint32_t a, uint32_t b)
|
||||
{
|
||||
/* for 32 bit values */
|
||||
const uint32_t cutoff = ((uint32_t) 1 << (32 - 1));
|
||||
|
||||
if (a == b) {
|
||||
return 0;
|
||||
} else if ((a < b && b - a < cutoff) || (a > b && a - b > cutoff)) {
|
||||
return -1;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t
|
||||
subtract_1982(uint32_t a, uint32_t b)
|
||||
{
|
||||
/* for 32 bit values */
|
||||
const uint32_t cutoff = ((uint32_t) 1 << (32 - 1));
|
||||
|
||||
if(a == b)
|
||||
return 0;
|
||||
if(a < b && b - a < cutoff) {
|
||||
return b-a;
|
||||
}
|
||||
if(a > b && a - b > cutoff) {
|
||||
return ((uint32_t)0xffffffff) - (a-b-1);
|
||||
}
|
||||
/* wrong case, b smaller than a */
|
||||
return 0;
|
||||
}
|
63
sbin/unwind/libunbound/util/rfc_1982.h
Normal file
63
sbin/unwind/libunbound/util/rfc_1982.h
Normal file
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* util/rfc_1982.h - RFC 1982 Serial Number Arithmetic
|
||||
*
|
||||
* Copyright (c) 2023, NLnet Labs. All rights reserved.
|
||||
*
|
||||
* This software is open source.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* Neither the name of the NLNET LABS nor the names of its contributors may
|
||||
* be used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* This file contains functions for RFC 1982 serial number arithmetic.
|
||||
*/
|
||||
#ifndef RFC_1982_H
|
||||
#define RFC_1982_H
|
||||
|
||||
/**
|
||||
* RFC 1982 comparison, uses unsigned integers, and tries to avoid
|
||||
* compiler optimization (eg. by avoiding a-b<0 comparisons).
|
||||
* @param a: value to compare.
|
||||
* @param b: value to compare.
|
||||
* @return 0 if equal, 1 if a > b, else -1.
|
||||
*/
|
||||
int compare_1982(uint32_t a, uint32_t b);
|
||||
|
||||
/**
|
||||
* RFC 1982 subtraction, uses unsigned integers, and tries to avoid
|
||||
* compiler optimization (eg. by avoiding a-b<0 comparisons).
|
||||
* @param a: value to subtract from.
|
||||
* @param b: value to subtract.
|
||||
* @return the difference between them if we know that b is larger than a,
|
||||
* that is the distance between them in serial number arithmetic.
|
||||
*/
|
||||
uint32_t subtract_1982(uint32_t a, uint32_t b);
|
||||
|
||||
#endif /* RFC_1982_H */
|
192
sbin/unwind/libunbound/util/siphash.c
Normal file
192
sbin/unwind/libunbound/util/siphash.c
Normal file
|
@ -0,0 +1,192 @@
|
|||
/*
|
||||
SipHash reference C implementation
|
||||
|
||||
Copyright (c) 2012-2016 Jean-Philippe Aumasson
|
||||
<jeanphilippe.aumasson@gmail.com>
|
||||
Copyright (c) 2012-2014 Daniel J. Bernstein <djb@cr.yp.to>
|
||||
|
||||
To the extent possible under law, the author(s) have dedicated all copyright
|
||||
and related and neighboring rights to this software to the public domain
|
||||
worldwide. This software is distributed without any warranty.
|
||||
|
||||
You should have received a copy of the CC0 Public Domain Dedication along
|
||||
with
|
||||
this software. If not, see
|
||||
<http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
/**
|
||||
* Edited slightly for integration in Unbound. Edits are noted with 'EDIT'.
|
||||
*/
|
||||
/** EDIT
|
||||
* \#include <assert.h>
|
||||
* \#include <stdint.h>
|
||||
* \#include <stdio.h>
|
||||
* \#include <string.h>
|
||||
* Replaced the above includes with Unbound's config.h
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
/** EDIT
|
||||
* prevent warning from -Wmissing-prototypes
|
||||
*/
|
||||
#include "util/siphash.h"
|
||||
|
||||
/* default: SipHash-2-4 */
|
||||
#define cROUNDS 2
|
||||
#define dROUNDS 4
|
||||
|
||||
#define ROTL(x, b) (uint64_t)(((x) << (b)) | ((x) >> (64 - (b))))
|
||||
|
||||
#define U32TO8_LE(p, v) \
|
||||
(p)[0] = (uint8_t)((v)); \
|
||||
(p)[1] = (uint8_t)((v) >> 8); \
|
||||
(p)[2] = (uint8_t)((v) >> 16); \
|
||||
(p)[3] = (uint8_t)((v) >> 24);
|
||||
|
||||
#define U64TO8_LE(p, v) \
|
||||
U32TO8_LE((p), (uint32_t)((v))); \
|
||||
U32TO8_LE((p) + 4, (uint32_t)((v) >> 32));
|
||||
|
||||
#define U8TO64_LE(p) \
|
||||
(((uint64_t)((p)[0])) | ((uint64_t)((p)[1]) << 8) | \
|
||||
((uint64_t)((p)[2]) << 16) | ((uint64_t)((p)[3]) << 24) | \
|
||||
((uint64_t)((p)[4]) << 32) | ((uint64_t)((p)[5]) << 40) | \
|
||||
((uint64_t)((p)[6]) << 48) | ((uint64_t)((p)[7]) << 56))
|
||||
|
||||
#define SIPROUND \
|
||||
do { \
|
||||
v0 += v1; \
|
||||
v1 = ROTL(v1, 13); \
|
||||
v1 ^= v0; \
|
||||
v0 = ROTL(v0, 32); \
|
||||
v2 += v3; \
|
||||
v3 = ROTL(v3, 16); \
|
||||
v3 ^= v2; \
|
||||
v0 += v3; \
|
||||
v3 = ROTL(v3, 21); \
|
||||
v3 ^= v0; \
|
||||
v2 += v1; \
|
||||
v1 = ROTL(v1, 17); \
|
||||
v1 ^= v2; \
|
||||
v2 = ROTL(v2, 32); \
|
||||
} while (0)
|
||||
|
||||
#ifdef DEBUG
|
||||
#define TRACE \
|
||||
do { \
|
||||
printf("(%3d) v0 %08x %08x\n", (int)inlen, (uint32_t)(v0 >> 32), \
|
||||
(uint32_t)v0); \
|
||||
printf("(%3d) v1 %08x %08x\n", (int)inlen, (uint32_t)(v1 >> 32), \
|
||||
(uint32_t)v1); \
|
||||
printf("(%3d) v2 %08x %08x\n", (int)inlen, (uint32_t)(v2 >> 32), \
|
||||
(uint32_t)v2); \
|
||||
printf("(%3d) v3 %08x %08x\n", (int)inlen, (uint32_t)(v3 >> 32), \
|
||||
(uint32_t)v3); \
|
||||
} while (0)
|
||||
#else
|
||||
#define TRACE
|
||||
#endif
|
||||
|
||||
int siphash(const uint8_t *in, const size_t inlen, const uint8_t *k,
|
||||
uint8_t *out, const size_t outlen) {
|
||||
|
||||
uint64_t v0 = 0x736f6d6570736575ULL;
|
||||
uint64_t v1 = 0x646f72616e646f6dULL;
|
||||
uint64_t v2 = 0x6c7967656e657261ULL;
|
||||
uint64_t v3 = 0x7465646279746573ULL;
|
||||
uint64_t k0 = U8TO64_LE(k);
|
||||
uint64_t k1 = U8TO64_LE(k + 8);
|
||||
uint64_t m;
|
||||
int i;
|
||||
const uint8_t *end = in + inlen - (inlen % sizeof(uint64_t));
|
||||
const int left = inlen & 7;
|
||||
uint64_t b = ((uint64_t)inlen) << 56;
|
||||
/** EDIT
|
||||
* The following assert moved here from the top for C90 compliance.
|
||||
*/
|
||||
assert((outlen == 8) || (outlen == 16));
|
||||
v3 ^= k1;
|
||||
v2 ^= k0;
|
||||
v1 ^= k1;
|
||||
v0 ^= k0;
|
||||
|
||||
if (outlen == 16)
|
||||
v1 ^= 0xee;
|
||||
|
||||
for (; in != end; in += 8) {
|
||||
m = U8TO64_LE(in);
|
||||
v3 ^= m;
|
||||
|
||||
TRACE;
|
||||
for (i = 0; i < cROUNDS; ++i)
|
||||
SIPROUND;
|
||||
|
||||
v0 ^= m;
|
||||
}
|
||||
|
||||
switch (left) {
|
||||
case 7:
|
||||
b |= ((uint64_t)in[6]) << 48;
|
||||
/** EDIT annotate case statement fallthrough for gcc */
|
||||
/* fallthrough */
|
||||
case 6:
|
||||
b |= ((uint64_t)in[5]) << 40;
|
||||
/** EDIT annotate case statement fallthrough for gcc */
|
||||
/* fallthrough */
|
||||
case 5:
|
||||
b |= ((uint64_t)in[4]) << 32;
|
||||
/** EDIT annotate case statement fallthrough for gcc */
|
||||
/* fallthrough */
|
||||
case 4:
|
||||
b |= ((uint64_t)in[3]) << 24;
|
||||
/** EDIT annotate case statement fallthrough for gcc */
|
||||
/* fallthrough */
|
||||
case 3:
|
||||
b |= ((uint64_t)in[2]) << 16;
|
||||
/** EDIT annotate case statement fallthrough for gcc */
|
||||
/* fallthrough */
|
||||
case 2:
|
||||
b |= ((uint64_t)in[1]) << 8;
|
||||
/** EDIT annotate case statement fallthrough for gcc */
|
||||
/* fallthrough */
|
||||
case 1:
|
||||
b |= ((uint64_t)in[0]);
|
||||
break;
|
||||
case 0:
|
||||
break;
|
||||
}
|
||||
|
||||
v3 ^= b;
|
||||
|
||||
TRACE;
|
||||
for (i = 0; i < cROUNDS; ++i)
|
||||
SIPROUND;
|
||||
|
||||
v0 ^= b;
|
||||
|
||||
if (outlen == 16)
|
||||
v2 ^= 0xee;
|
||||
else
|
||||
v2 ^= 0xff;
|
||||
|
||||
TRACE;
|
||||
for (i = 0; i < dROUNDS; ++i)
|
||||
SIPROUND;
|
||||
|
||||
b = v0 ^ v1 ^ v2 ^ v3;
|
||||
U64TO8_LE(out, b);
|
||||
|
||||
if (outlen == 8)
|
||||
return 0;
|
||||
|
||||
v1 ^= 0xdd;
|
||||
|
||||
TRACE;
|
||||
for (i = 0; i < dROUNDS; ++i)
|
||||
SIPROUND;
|
||||
|
||||
b = v0 ^ v1 ^ v2 ^ v3;
|
||||
U64TO8_LE(out + 8, b);
|
||||
|
||||
return 0;
|
||||
}
|
43
sbin/unwind/libunbound/util/siphash.h
Normal file
43
sbin/unwind/libunbound/util/siphash.h
Normal file
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* util/siphash.h - header for SipHash reference C implementation.
|
||||
*
|
||||
* Copyright (c) 2023, NLnet Labs. All rights reserved.
|
||||
*
|
||||
* This software is open source.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* Neither the name of the NLNET LABS nor the names of its contributors may
|
||||
* be used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/**
|
||||
* \file
|
||||
* Contains the SipHash reference C implementation.
|
||||
*/
|
||||
#ifndef UTIL_SIPHASH_H
|
||||
#define UTIL_SIPHASH_H
|
||||
int siphash(const uint8_t *in, const size_t inlen, const uint8_t *k,
|
||||
uint8_t *out, const size_t outlen);
|
||||
#endif /* UTIL_SIPHASH_H */
|
|
@ -81,6 +81,7 @@ lruhash_create(size_t start_size, size_t maxmem,
|
|||
table->num = 0;
|
||||
table->space_used = 0;
|
||||
table->space_max = maxmem;
|
||||
table->max_collisions = 0;
|
||||
table->array = calloc(table->size, sizeof(struct lruhash_bin));
|
||||
if(!table->array) {
|
||||
lock_quick_destroy(&table->lock);
|
||||
|
@ -216,15 +217,19 @@ reclaim_space(struct lruhash* table, struct lruhash_entry** list)
|
|||
|
||||
struct lruhash_entry*
|
||||
bin_find_entry(struct lruhash* table,
|
||||
struct lruhash_bin* bin, hashvalue_type hash, void* key)
|
||||
struct lruhash_bin* bin, hashvalue_type hash, void* key, size_t* collisions)
|
||||
{
|
||||
size_t c = 0;
|
||||
struct lruhash_entry* p = bin->overflow_list;
|
||||
while(p) {
|
||||
if(p->hash == hash && table->compfunc(p->key, key) == 0)
|
||||
return p;
|
||||
break;
|
||||
c++;
|
||||
p = p->overflow_next;
|
||||
}
|
||||
return NULL;
|
||||
if (collisions != NULL)
|
||||
*collisions = c;
|
||||
return p;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -303,6 +308,7 @@ lruhash_insert(struct lruhash* table, hashvalue_type hash,
|
|||
struct lruhash_bin* bin;
|
||||
struct lruhash_entry* found, *reclaimlist=NULL;
|
||||
size_t need_size;
|
||||
size_t collisions;
|
||||
fptr_ok(fptr_whitelist_hash_sizefunc(table->sizefunc));
|
||||
fptr_ok(fptr_whitelist_hash_delkeyfunc(table->delkeyfunc));
|
||||
fptr_ok(fptr_whitelist_hash_deldatafunc(table->deldatafunc));
|
||||
|
@ -317,12 +323,14 @@ lruhash_insert(struct lruhash* table, hashvalue_type hash,
|
|||
lock_quick_lock(&bin->lock);
|
||||
|
||||
/* see if entry exists already */
|
||||
if(!(found=bin_find_entry(table, bin, hash, entry->key))) {
|
||||
if(!(found=bin_find_entry(table, bin, hash, entry->key, &collisions))) {
|
||||
/* if not: add to bin */
|
||||
entry->overflow_next = bin->overflow_list;
|
||||
bin->overflow_list = entry;
|
||||
lru_front(table, entry);
|
||||
table->num++;
|
||||
if (table->max_collisions < collisions)
|
||||
table->max_collisions = collisions;
|
||||
table->space_used += need_size;
|
||||
} else {
|
||||
/* if so: update data - needs a writelock */
|
||||
|
@ -362,7 +370,7 @@ lruhash_lookup(struct lruhash* table, hashvalue_type hash, void* key, int wr)
|
|||
lock_quick_lock(&table->lock);
|
||||
bin = &table->array[hash & table->size_mask];
|
||||
lock_quick_lock(&bin->lock);
|
||||
if((entry=bin_find_entry(table, bin, hash, key)))
|
||||
if((entry=bin_find_entry(table, bin, hash, key, NULL)))
|
||||
lru_touch(table, entry);
|
||||
lock_quick_unlock(&table->lock);
|
||||
|
||||
|
@ -389,7 +397,7 @@ lruhash_remove(struct lruhash* table, hashvalue_type hash, void* key)
|
|||
lock_quick_lock(&table->lock);
|
||||
bin = &table->array[hash & table->size_mask];
|
||||
lock_quick_lock(&bin->lock);
|
||||
if((entry=bin_find_entry(table, bin, hash, key))) {
|
||||
if((entry=bin_find_entry(table, bin, hash, key, NULL))) {
|
||||
bin_overflow_remove(bin, entry);
|
||||
lru_remove(table, entry);
|
||||
} else {
|
||||
|
@ -579,6 +587,7 @@ lruhash_insert_or_retrieve(struct lruhash* table, hashvalue_type hash,
|
|||
struct lruhash_bin* bin;
|
||||
struct lruhash_entry* found, *reclaimlist = NULL;
|
||||
size_t need_size;
|
||||
size_t collisions;
|
||||
fptr_ok(fptr_whitelist_hash_sizefunc(table->sizefunc));
|
||||
fptr_ok(fptr_whitelist_hash_delkeyfunc(table->delkeyfunc));
|
||||
fptr_ok(fptr_whitelist_hash_deldatafunc(table->deldatafunc));
|
||||
|
@ -593,7 +602,7 @@ lruhash_insert_or_retrieve(struct lruhash* table, hashvalue_type hash,
|
|||
lock_quick_lock(&bin->lock);
|
||||
|
||||
/* see if entry exists already */
|
||||
if ((found = bin_find_entry(table, bin, hash, entry->key)) != NULL) {
|
||||
if ((found = bin_find_entry(table, bin, hash, entry->key, &collisions)) != NULL) {
|
||||
/* if so: keep the existing data - acquire a writelock */
|
||||
lock_rw_wrlock(&found->lock);
|
||||
}
|
||||
|
@ -604,6 +613,8 @@ lruhash_insert_or_retrieve(struct lruhash* table, hashvalue_type hash,
|
|||
bin->overflow_list = entry;
|
||||
lru_front(table, entry);
|
||||
table->num++;
|
||||
if (table->max_collisions < collisions)
|
||||
table->max_collisions = collisions;
|
||||
table->space_used += need_size;
|
||||
/* return the entry that was presented, and lock it */
|
||||
found = entry;
|
||||
|
|
|
@ -178,6 +178,8 @@ struct lruhash {
|
|||
size_t space_used;
|
||||
/** the amount of space the hash table is maximally allowed to use. */
|
||||
size_t space_max;
|
||||
/** the maximum collisions were detected during the lruhash_insert operations. */
|
||||
size_t max_collisions;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -357,10 +359,11 @@ void bin_delete(struct lruhash* table, struct lruhash_bin* bin);
|
|||
* @param bin: hash bin to look into.
|
||||
* @param hash: hash value to look for.
|
||||
* @param key: key to look for.
|
||||
* @param collisions: how many collisions were found during the search.
|
||||
* @return: the entry or NULL if not found.
|
||||
*/
|
||||
struct lruhash_entry* bin_find_entry(struct lruhash* table,
|
||||
struct lruhash_bin* bin, hashvalue_type hash, void* key);
|
||||
struct lruhash_bin* bin, hashvalue_type hash, void* key, size_t* collisions);
|
||||
|
||||
/**
|
||||
* Remove entry from bin overflow chain.
|
||||
|
|
|
@ -242,3 +242,21 @@ size_t count_slabhash_entries(struct slabhash* sh)
|
|||
}
|
||||
return cnt;
|
||||
}
|
||||
|
||||
void get_slabhash_stats(struct slabhash* sh, long long* num, long long* collisions)
|
||||
{
|
||||
size_t slab, cnt = 0, max_collisions = 0;
|
||||
|
||||
for(slab=0; slab<sh->size; slab++) {
|
||||
lock_quick_lock(&sh->array[slab]->lock);
|
||||
cnt += sh->array[slab]->num;
|
||||
if (max_collisions < sh->array[slab]->max_collisions) {
|
||||
max_collisions = sh->array[slab]->max_collisions;
|
||||
}
|
||||
lock_quick_unlock(&sh->array[slab]->lock);
|
||||
}
|
||||
if (num != NULL)
|
||||
*num = cnt;
|
||||
if (collisions != NULL)
|
||||
*collisions = max_collisions;
|
||||
}
|
||||
|
|
|
@ -200,6 +200,15 @@ void slabhash_traverse(struct slabhash* table, int wr,
|
|||
*/
|
||||
size_t count_slabhash_entries(struct slabhash* table);
|
||||
|
||||
/**
|
||||
* Retrieves number of items in slabhash and the current max collision level
|
||||
* @param table: slabbed hash table.
|
||||
* @param entries_count: where to save the current number of elements.
|
||||
* @param max_collisions: where to save the current max collisions level.
|
||||
*/
|
||||
void get_slabhash_stats(struct slabhash* table,
|
||||
long long* entries_count, long long* max_collisions);
|
||||
|
||||
/* --- test representation --- */
|
||||
/** test structure contains test key */
|
||||
struct slabhash_testkey {
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
#include <sys/types.h>
|
||||
#include "util/timehist.h"
|
||||
#include "util/log.h"
|
||||
#include "util/timeval_func.h"
|
||||
|
||||
/** special timestwo operation for time values in histogram setup */
|
||||
static void
|
||||
|
@ -114,23 +115,6 @@ void timehist_clear(struct timehist* hist)
|
|||
hist->buckets[i].count = 0;
|
||||
}
|
||||
|
||||
/** histogram compare of time values */
|
||||
static int
|
||||
timeval_smaller(const struct timeval* x, const struct timeval* y)
|
||||
{
|
||||
#ifndef S_SPLINT_S
|
||||
if(x->tv_sec < y->tv_sec)
|
||||
return 1;
|
||||
else if(x->tv_sec == y->tv_sec) {
|
||||
if(x->tv_usec <= y->tv_usec)
|
||||
return 1;
|
||||
else return 0;
|
||||
}
|
||||
else return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void timehist_insert(struct timehist* hist, struct timeval* tv)
|
||||
{
|
||||
size_t i;
|
||||
|
|
113
sbin/unwind/libunbound/util/timeval_func.c
Normal file
113
sbin/unwind/libunbound/util/timeval_func.c
Normal file
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
* util/timeval_func.c - helpers to work with struct timeval values.
|
||||
*
|
||||
* Copyright (c) 2023, NLnet Labs. All rights reserved.
|
||||
*
|
||||
* This software is open source.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* Neither the name of the NLNET LABS nor the names of its contributors may
|
||||
* be used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* This file contains helpers to manipulate struct timeval values.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "timeval_func.h"
|
||||
|
||||
/** subtract timers and the values do not overflow or become negative */
|
||||
void
|
||||
timeval_subtract(struct timeval* d, const struct timeval* end, const struct timeval* start)
|
||||
{
|
||||
#ifndef S_SPLINT_S
|
||||
time_t end_usec = end->tv_usec;
|
||||
d->tv_sec = end->tv_sec - start->tv_sec;
|
||||
if(end_usec < start->tv_usec) {
|
||||
end_usec += 1000000;
|
||||
d->tv_sec--;
|
||||
}
|
||||
d->tv_usec = end_usec - start->tv_usec;
|
||||
#endif
|
||||
}
|
||||
|
||||
/** add timers and the values do not overflow or become negative */
|
||||
void
|
||||
timeval_add(struct timeval* d, const struct timeval* add)
|
||||
{
|
||||
#ifndef S_SPLINT_S
|
||||
d->tv_sec += add->tv_sec;
|
||||
d->tv_usec += add->tv_usec;
|
||||
if(d->tv_usec >= 1000000 ) {
|
||||
d->tv_usec -= 1000000;
|
||||
d->tv_sec++;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/** divide sum of timers to get average */
|
||||
void
|
||||
timeval_divide(struct timeval* avg, const struct timeval* sum, long long d)
|
||||
{
|
||||
#ifndef S_SPLINT_S
|
||||
long long leftover;
|
||||
if(d <= 0) {
|
||||
avg->tv_sec = 0;
|
||||
avg->tv_usec = 0;
|
||||
return;
|
||||
}
|
||||
avg->tv_sec = sum->tv_sec / d;
|
||||
avg->tv_usec = sum->tv_usec / d;
|
||||
/* handle fraction from seconds divide */
|
||||
leftover = sum->tv_sec - avg->tv_sec*d;
|
||||
if(leftover <= 0)
|
||||
leftover = 0;
|
||||
avg->tv_usec += (((long long)leftover)*((long long)1000000))/d;
|
||||
if(avg->tv_sec < 0)
|
||||
avg->tv_sec = 0;
|
||||
if(avg->tv_usec < 0)
|
||||
avg->tv_usec = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/** histogram compare of time values */
|
||||
int
|
||||
timeval_smaller(const struct timeval* x, const struct timeval* y)
|
||||
{
|
||||
#ifndef S_SPLINT_S
|
||||
if(x->tv_sec < y->tv_sec)
|
||||
return 1;
|
||||
else if(x->tv_sec == y->tv_sec) {
|
||||
if(x->tv_usec <= y->tv_usec)
|
||||
return 1;
|
||||
else return 0;
|
||||
}
|
||||
else return 0;
|
||||
#endif
|
||||
}
|
53
sbin/unwind/libunbound/util/timeval_func.h
Normal file
53
sbin/unwind/libunbound/util/timeval_func.h
Normal file
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* util/timeval_func.h - definitions of helpers for struct timeval values.
|
||||
*
|
||||
* Copyright (c) 2023, NLnet Labs. All rights reserved.
|
||||
*
|
||||
* This software is open source.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* Neither the name of the NLNET LABS nor the names of its contributors may
|
||||
* be used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* This file contains definitions of helpers to manipulate struct timeval
|
||||
* values, implemented in the corresponding C file.
|
||||
*/
|
||||
#include <sys/time.h>
|
||||
|
||||
#ifndef timeval_isset
|
||||
#define timeval_isset(tv) ((tv)->tv_sec || (tv)->tv_usec)
|
||||
#endif
|
||||
#ifndef timeval_clear
|
||||
#define timeval_clear(tv) ((tv)->tv_sec = (tv)->tv_usec = 0)
|
||||
#endif
|
||||
void timeval_subtract(struct timeval* d, const struct timeval* end, const struct timeval* start);
|
||||
void timeval_add(struct timeval* d, const struct timeval* add);
|
||||
void timeval_divide(struct timeval* avg, const struct timeval* sum, long long d);
|
||||
int timeval_smaller(const struct timeval* x, const struct timeval* y);
|
|
@ -45,6 +45,9 @@
|
|||
#include "util/netevent.h"
|
||||
#include "util/fptr_wlist.h"
|
||||
#include "util/ub_event.h"
|
||||
#ifdef HAVE_POLL_H
|
||||
#include <poll.h>
|
||||
#endif
|
||||
|
||||
#ifndef USE_WINSOCK
|
||||
/* on unix */
|
||||
|
@ -396,20 +399,28 @@ int tube_read_msg(struct tube* tube, uint8_t** buf, uint32_t* len,
|
|||
return 1;
|
||||
}
|
||||
|
||||
/** perform a select() on the fd */
|
||||
/** perform poll() on the fd */
|
||||
static int
|
||||
pollit(int fd, struct timeval* t)
|
||||
{
|
||||
fd_set r;
|
||||
struct pollfd fds;
|
||||
int pret;
|
||||
int msec = -1;
|
||||
memset(&fds, 0, sizeof(fds));
|
||||
fds.fd = fd;
|
||||
fds.events = POLLIN | POLLERR | POLLHUP;
|
||||
#ifndef S_SPLINT_S
|
||||
FD_ZERO(&r);
|
||||
FD_SET(FD_SET_T fd, &r);
|
||||
if(t)
|
||||
msec = t->tv_sec*1000 + t->tv_usec/1000;
|
||||
#endif
|
||||
if(select(fd+1, &r, NULL, NULL, t) == -1) {
|
||||
|
||||
pret = poll(&fds, 1, msec);
|
||||
|
||||
if(pret == -1)
|
||||
return 0;
|
||||
if(pret != 0)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
errno = 0;
|
||||
return (int)(FD_ISSET(fd, &r));
|
||||
}
|
||||
|
||||
int tube_poll(struct tube* tube)
|
||||
|
@ -426,24 +437,27 @@ int tube_wait(struct tube* tube)
|
|||
|
||||
int tube_wait_timeout(struct tube* tube, int msec)
|
||||
{
|
||||
struct timeval t;
|
||||
int fd = tube->sr;
|
||||
fd_set r;
|
||||
t.tv_sec = msec/1000;
|
||||
t.tv_usec = (msec%1000)*1000;
|
||||
#ifndef S_SPLINT_S
|
||||
FD_ZERO(&r);
|
||||
FD_SET(FD_SET_T fd, &r);
|
||||
#endif
|
||||
int ret = 0;
|
||||
|
||||
while(1) {
|
||||
if(select(fd+1, &r, NULL, NULL, &t) == -1) {
|
||||
struct pollfd fds;
|
||||
memset(&fds, 0, sizeof(fds));
|
||||
|
||||
fds.fd = tube->sr;
|
||||
fds.events = POLLIN | POLLERR | POLLHUP;
|
||||
ret = poll(&fds, 1, msec);
|
||||
|
||||
if(ret == -1) {
|
||||
if(errno == EAGAIN || errno == EINTR)
|
||||
continue;
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return (int)(FD_ISSET(fd, &r));
|
||||
|
||||
if(ret != 0)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tube_read_fd(struct tube* tube)
|
||||
|
@ -529,6 +543,7 @@ struct tube* tube_create(void)
|
|||
if(tube->event == WSA_INVALID_EVENT) {
|
||||
free(tube);
|
||||
log_err("WSACreateEvent: %s", wsa_strerror(WSAGetLastError()));
|
||||
return NULL;
|
||||
}
|
||||
if(!WSAResetEvent(tube->event)) {
|
||||
log_err("WSAResetEvent: %s", wsa_strerror(WSAGetLastError()));
|
||||
|
|
|
@ -2376,6 +2376,8 @@ probe_anchor(struct module_env* env, struct trust_anchor* tp)
|
|||
edns.opt_list_out = NULL;
|
||||
edns.opt_list_inplace_cb_out = NULL;
|
||||
edns.padding_block_size = 0;
|
||||
edns.cookie_present = 0;
|
||||
edns.cookie_valid = 0;
|
||||
if(sldns_buffer_capacity(buf) < 65535)
|
||||
edns.udp_size = (uint16_t)sldns_buffer_capacity(buf);
|
||||
else edns.udp_size = 65535;
|
||||
|
|
|
@ -81,17 +81,11 @@ key_cache_delete(struct key_cache* kcache)
|
|||
|
||||
void
|
||||
key_cache_insert(struct key_cache* kcache, struct key_entry_key* kkey,
|
||||
struct module_qstate* qstate)
|
||||
int copy_reason)
|
||||
{
|
||||
struct key_entry_key* k = key_entry_copy(kkey);
|
||||
struct key_entry_key* k = key_entry_copy(kkey, copy_reason);
|
||||
if(!k)
|
||||
return;
|
||||
if(key_entry_isbad(k) && qstate->errinf &&
|
||||
qstate->env->cfg->val_log_level >= 2) {
|
||||
/* on malloc failure there is simply no reason string */
|
||||
key_entry_set_reason(k, errinf_to_str_bogus(qstate));
|
||||
key_entry_set_reason_bogus(k, errinf_to_reason_bogus(qstate));
|
||||
}
|
||||
key_entry_hash(k);
|
||||
slabhash_insert(kcache->slab, k->entry.hash, &k->entry,
|
||||
k->entry.data, NULL);
|
||||
|
|
|
@ -76,10 +76,10 @@ void key_cache_delete(struct key_cache* kcache);
|
|||
* @param kcache: the key cache.
|
||||
* @param kkey: key entry key, assumed malloced in a region, is copied
|
||||
* to perform update or insertion. Its data pointer is also copied.
|
||||
* @param qstate: store errinf reason in case its bad.
|
||||
* @param copy_reason: if the reason string needs to be copied (allocated).
|
||||
*/
|
||||
void key_cache_insert(struct key_cache* kcache, struct key_entry_key* kkey,
|
||||
struct module_qstate* qstate);
|
||||
int copy_reason);
|
||||
|
||||
/**
|
||||
* Remove an entry from the key cache.
|
||||
|
|
|
@ -152,7 +152,7 @@ key_entry_copy_toregion(struct key_entry_key* kkey, struct regional* region)
|
|||
}
|
||||
|
||||
struct key_entry_key*
|
||||
key_entry_copy(struct key_entry_key* kkey)
|
||||
key_entry_copy(struct key_entry_key* kkey, int copy_reason)
|
||||
{
|
||||
struct key_entry_key* newk;
|
||||
if(!kkey)
|
||||
|
@ -190,7 +190,7 @@ key_entry_copy(struct key_entry_key* kkey)
|
|||
}
|
||||
packed_rrset_ptr_fixup(newd->rrset_data);
|
||||
}
|
||||
if(d->reason) {
|
||||
if(copy_reason && d->reason && *d->reason != 0) {
|
||||
newd->reason = strdup(d->reason);
|
||||
if(!newd->reason) {
|
||||
free(newd->rrset_data);
|
||||
|
@ -199,6 +199,8 @@ key_entry_copy(struct key_entry_key* kkey)
|
|||
free(newk);
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
newd->reason = NULL;
|
||||
}
|
||||
if(d->algo) {
|
||||
newd->algo = (uint8_t*)strdup((char*)d->algo);
|
||||
|
@ -237,22 +239,6 @@ key_entry_isbad(struct key_entry_key* kkey)
|
|||
return (int)(d->isbad);
|
||||
}
|
||||
|
||||
void
|
||||
key_entry_set_reason(struct key_entry_key* kkey, char* reason)
|
||||
{
|
||||
struct key_entry_data* d = (struct key_entry_data*)kkey->entry.data;
|
||||
d->reason = reason;
|
||||
}
|
||||
|
||||
void
|
||||
key_entry_set_reason_bogus(struct key_entry_key* kkey, sldns_ede_code ede)
|
||||
{
|
||||
struct key_entry_data* d = (struct key_entry_data*)kkey->entry.data;
|
||||
if (ede != LDNS_EDE_NONE) { /* reason_bogus init is LDNS_EDE_NONE already */
|
||||
d->reason_bogus = ede;
|
||||
}
|
||||
}
|
||||
|
||||
char*
|
||||
key_entry_get_reason(struct key_entry_key* kkey)
|
||||
{
|
||||
|
@ -294,6 +280,7 @@ key_entry_setup(struct regional* region,
|
|||
struct key_entry_key*
|
||||
key_entry_create_null(struct regional* region,
|
||||
uint8_t* name, size_t namelen, uint16_t dclass, time_t ttl,
|
||||
sldns_ede_code reason_bogus, const char* reason,
|
||||
time_t now)
|
||||
{
|
||||
struct key_entry_key* k;
|
||||
|
@ -302,8 +289,10 @@ key_entry_create_null(struct regional* region,
|
|||
return NULL;
|
||||
d->ttl = now + ttl;
|
||||
d->isbad = 0;
|
||||
d->reason = NULL;
|
||||
d->reason_bogus = LDNS_EDE_NONE;
|
||||
d->reason = (!reason || *reason == 0)
|
||||
?NULL :(char*)regional_strdup(region, reason);
|
||||
/* On allocation error we don't store the reason string */
|
||||
d->reason_bogus = reason_bogus;
|
||||
d->rrset_type = LDNS_RR_TYPE_DNSKEY;
|
||||
d->rrset_data = NULL;
|
||||
d->algo = NULL;
|
||||
|
@ -313,7 +302,9 @@ key_entry_create_null(struct regional* region,
|
|||
struct key_entry_key*
|
||||
key_entry_create_rrset(struct regional* region,
|
||||
uint8_t* name, size_t namelen, uint16_t dclass,
|
||||
struct ub_packed_rrset_key* rrset, uint8_t* sigalg, time_t now)
|
||||
struct ub_packed_rrset_key* rrset, uint8_t* sigalg,
|
||||
sldns_ede_code reason_bogus, const char* reason,
|
||||
time_t now)
|
||||
{
|
||||
struct key_entry_key* k;
|
||||
struct key_entry_data* d;
|
||||
|
@ -323,8 +314,10 @@ key_entry_create_rrset(struct regional* region,
|
|||
return NULL;
|
||||
d->ttl = rd->ttl + now;
|
||||
d->isbad = 0;
|
||||
d->reason = NULL;
|
||||
d->reason_bogus = LDNS_EDE_NONE;
|
||||
d->reason = (!reason || *reason == 0)
|
||||
?NULL :(char*)regional_strdup(region, reason);
|
||||
/* On allocation error we don't store the reason string */
|
||||
d->reason_bogus = reason_bogus;
|
||||
d->rrset_type = ntohs(rrset->rk.type);
|
||||
d->rrset_data = (struct packed_rrset_data*)regional_alloc_init(region,
|
||||
rd, packed_rrset_sizeof(rd));
|
||||
|
@ -342,6 +335,7 @@ key_entry_create_rrset(struct regional* region,
|
|||
struct key_entry_key*
|
||||
key_entry_create_bad(struct regional* region,
|
||||
uint8_t* name, size_t namelen, uint16_t dclass, time_t ttl,
|
||||
sldns_ede_code reason_bogus, const char* reason,
|
||||
time_t now)
|
||||
{
|
||||
struct key_entry_key* k;
|
||||
|
@ -350,8 +344,10 @@ key_entry_create_bad(struct regional* region,
|
|||
return NULL;
|
||||
d->ttl = now + ttl;
|
||||
d->isbad = 1;
|
||||
d->reason = NULL;
|
||||
d->reason_bogus = LDNS_EDE_NONE;
|
||||
d->reason = (!reason || *reason == 0)
|
||||
?NULL :(char*)regional_strdup(region, reason);
|
||||
/* On allocation error we don't store the reason string */
|
||||
d->reason_bogus = reason_bogus;
|
||||
d->rrset_type = LDNS_RR_TYPE_DNSKEY;
|
||||
d->rrset_data = NULL;
|
||||
d->algo = NULL;
|
||||
|
|
|
@ -120,9 +120,11 @@ struct key_entry_key* key_entry_copy_toregion(struct key_entry_key* kkey,
|
|||
/**
|
||||
* Copy a key entry, malloced.
|
||||
* @param kkey: the key entry key (and data pointer) to copy.
|
||||
* @param copy_reason: if the reason string needs to be copied (allocated).
|
||||
* @return newly allocated entry or NULL on a failure to allocate memory.
|
||||
*/
|
||||
struct key_entry_key* key_entry_copy(struct key_entry_key* kkey);
|
||||
struct key_entry_key* key_entry_copy(struct key_entry_key* kkey,
|
||||
int copy_reason);
|
||||
|
||||
/**
|
||||
* See if this is a null entry. Does not do locking.
|
||||
|
@ -145,23 +147,6 @@ int key_entry_isgood(struct key_entry_key* kkey);
|
|||
*/
|
||||
int key_entry_isbad(struct key_entry_key* kkey);
|
||||
|
||||
/**
|
||||
* Set reason why a key is bad.
|
||||
* @param kkey: bad key.
|
||||
* @param reason: string to attach, you must allocate it.
|
||||
* Not safe to call twice unless you deallocate it yourself.
|
||||
*/
|
||||
void key_entry_set_reason(struct key_entry_key* kkey, char* reason);
|
||||
|
||||
/**
|
||||
* Set the EDE (RFC8914) code why the key is bad, if it
|
||||
* exists (so not LDNS_EDE_NONE).
|
||||
* @param kkey: bad key.
|
||||
* @param ede: EDE code to attach to this key.
|
||||
*/
|
||||
void key_entry_set_reason_bogus(struct key_entry_key* kkey, sldns_ede_code ede);
|
||||
|
||||
|
||||
/**
|
||||
* Get reason why a key is bad.
|
||||
* @param kkey: bad key
|
||||
|
@ -184,11 +169,14 @@ sldns_ede_code key_entry_get_reason_bogus(struct key_entry_key* kkey);
|
|||
* @param namelen: length of name
|
||||
* @param dclass: class of key entry. (host order);
|
||||
* @param ttl: what ttl should the key have. relative.
|
||||
* @param reason_bogus: accompanying EDE code.
|
||||
* @param reason: accompanying NULL-terminated EDE string (or NULL).
|
||||
* @param now: current time (added to ttl).
|
||||
* @return new key entry or NULL on alloc failure
|
||||
*/
|
||||
struct key_entry_key* key_entry_create_null(struct regional* region,
|
||||
uint8_t* name, size_t namelen, uint16_t dclass, time_t ttl,
|
||||
sldns_ede_code reason_bogus, const char* reason,
|
||||
time_t now);
|
||||
|
||||
/**
|
||||
|
@ -199,12 +187,16 @@ struct key_entry_key* key_entry_create_null(struct regional* region,
|
|||
* @param dclass: class of key entry. (host order);
|
||||
* @param rrset: data for key entry. This is copied to the region.
|
||||
* @param sigalg: signalled algorithm list (or NULL).
|
||||
* @param reason_bogus: accompanying EDE code (usually LDNS_EDE_NONE).
|
||||
* @param reason: accompanying NULL-terminated EDE string (or NULL).
|
||||
* @param now: current time (added to ttl of rrset)
|
||||
* @return new key entry or NULL on alloc failure
|
||||
*/
|
||||
struct key_entry_key* key_entry_create_rrset(struct regional* region,
|
||||
uint8_t* name, size_t namelen, uint16_t dclass,
|
||||
struct ub_packed_rrset_key* rrset, uint8_t* sigalg, time_t now);
|
||||
struct ub_packed_rrset_key* rrset, uint8_t* sigalg,
|
||||
sldns_ede_code reason_bogus, const char* reason,
|
||||
time_t now);
|
||||
|
||||
/**
|
||||
* Create a bad entry, in the given region.
|
||||
|
@ -213,11 +205,14 @@ struct key_entry_key* key_entry_create_rrset(struct regional* region,
|
|||
* @param namelen: length of name
|
||||
* @param dclass: class of key entry. (host order);
|
||||
* @param ttl: what ttl should the key have. relative.
|
||||
* @param reason_bogus: accompanying EDE code.
|
||||
* @param reason: accompanying NULL-terminated EDE string (or NULL).
|
||||
* @param now: current time (added to ttl).
|
||||
* @return new key entry or NULL on alloc failure
|
||||
*/
|
||||
struct key_entry_key* key_entry_create_bad(struct regional* region,
|
||||
uint8_t* name, size_t namelen, uint16_t dclass, time_t ttl,
|
||||
sldns_ede_code reason_bogus, const char* reason,
|
||||
time_t now);
|
||||
|
||||
/**
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
*/
|
||||
#include "config.h"
|
||||
#ifdef HAVE_OPENSSL_SSL_H
|
||||
#include "openssl/ssl.h"
|
||||
#include <openssl/ssl.h>
|
||||
#define NSEC3_SHA_LEN SHA_DIGEST_LENGTH
|
||||
#else
|
||||
#define NSEC3_SHA_LEN 20
|
||||
|
@ -1407,6 +1407,11 @@ val_neg_getmsg(struct val_neg_cache* neg, struct query_info* qinfo,
|
|||
/* Matching NSEC, use to generate No Data answer. Not creating answers
|
||||
* yet for No Data proven using wildcard. */
|
||||
if(nsec && nsec_proves_nodata(nsec, qinfo, &nodata_wc) && !nodata_wc) {
|
||||
/* do not create nodata answers for qtype ANY, it is a query
|
||||
* type, not an rrtype to disprove. Nameerrors are useful for
|
||||
* qtype ANY, in the else branch. */
|
||||
if(qinfo->qtype == LDNS_RR_TYPE_ANY)
|
||||
return NULL;
|
||||
if(!(msg = dns_msg_create(qinfo->qname, qinfo->qname_len,
|
||||
qinfo->qtype, qinfo->qclass, region, 2)))
|
||||
return NULL;
|
||||
|
|
|
@ -176,7 +176,8 @@ val_nsec_proves_no_ds(struct ub_packed_rrset_key* nsec,
|
|||
static int
|
||||
nsec_verify_rrset(struct module_env* env, struct val_env* ve,
|
||||
struct ub_packed_rrset_key* nsec, struct key_entry_key* kkey,
|
||||
char** reason, struct module_qstate* qstate)
|
||||
char** reason, sldns_ede_code* reason_bogus,
|
||||
struct module_qstate* qstate)
|
||||
{
|
||||
struct packed_rrset_data* d = (struct packed_rrset_data*)
|
||||
nsec->entry.data;
|
||||
|
@ -187,7 +188,7 @@ nsec_verify_rrset(struct module_env* env, struct val_env* ve,
|
|||
if(d->security == sec_status_secure)
|
||||
return 1;
|
||||
d->security = val_verify_rrset_entry(env, ve, nsec, kkey, reason,
|
||||
NULL, LDNS_SECTION_AUTHORITY, qstate);
|
||||
reason_bogus, LDNS_SECTION_AUTHORITY, qstate);
|
||||
if(d->security == sec_status_secure) {
|
||||
rrset_update_sec_status(env->rrset_cache, nsec, *env->now);
|
||||
return 1;
|
||||
|
@ -199,7 +200,7 @@ enum sec_status
|
|||
val_nsec_prove_nodata_dsreply(struct module_env* env, struct val_env* ve,
|
||||
struct query_info* qinfo, struct reply_info* rep,
|
||||
struct key_entry_key* kkey, time_t* proof_ttl, char** reason,
|
||||
struct module_qstate* qstate)
|
||||
sldns_ede_code* reason_bogus, struct module_qstate* qstate)
|
||||
{
|
||||
struct ub_packed_rrset_key* nsec = reply_find_rrset_section_ns(
|
||||
rep, qinfo->qname, qinfo->qname_len, LDNS_RR_TYPE_NSEC,
|
||||
|
@ -216,7 +217,8 @@ val_nsec_prove_nodata_dsreply(struct module_env* env, struct val_env* ve,
|
|||
* 1) this is a delegation point and there is no DS
|
||||
* 2) this is not a delegation point */
|
||||
if(nsec) {
|
||||
if(!nsec_verify_rrset(env, ve, nsec, kkey, reason, qstate)) {
|
||||
if(!nsec_verify_rrset(env, ve, nsec, kkey, reason,
|
||||
reason_bogus, qstate)) {
|
||||
verbose(VERB_ALGO, "NSEC RRset for the "
|
||||
"referral did not verify.");
|
||||
return sec_status_bogus;
|
||||
|
@ -225,6 +227,7 @@ val_nsec_prove_nodata_dsreply(struct module_env* env, struct val_env* ve,
|
|||
if(sec == sec_status_bogus) {
|
||||
/* something was wrong. */
|
||||
*reason = "NSEC does not prove absence of DS";
|
||||
*reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
|
||||
return sec;
|
||||
} else if(sec == sec_status_insecure) {
|
||||
/* this wasn't a delegation point. */
|
||||
|
@ -246,9 +249,11 @@ val_nsec_prove_nodata_dsreply(struct module_env* env, struct val_env* ve,
|
|||
if(rep->rrsets[i]->rk.type != htons(LDNS_RR_TYPE_NSEC))
|
||||
continue;
|
||||
if(!nsec_verify_rrset(env, ve, rep->rrsets[i], kkey, reason,
|
||||
qstate)) {
|
||||
reason_bogus, qstate)) {
|
||||
verbose(VERB_ALGO, "NSEC for empty non-terminal "
|
||||
"did not verify.");
|
||||
*reason = "NSEC for empty non-terminal "
|
||||
"did not verify.";
|
||||
return sec_status_bogus;
|
||||
}
|
||||
if(nsec_proves_nodata(rep->rrsets[i], qinfo, &wc)) {
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
#ifndef VALIDATOR_VAL_NSEC_H
|
||||
#define VALIDATOR_VAL_NSEC_H
|
||||
#include "util/data/packed_rrset.h"
|
||||
#include "sldns/rrdef.h"
|
||||
struct val_env;
|
||||
struct module_env;
|
||||
struct module_qstate;
|
||||
|
@ -65,6 +66,7 @@ struct key_entry_key;
|
|||
* @param kkey: key entry to use for verification of signatures.
|
||||
* @param proof_ttl: if secure, the TTL of how long this proof lasts.
|
||||
* @param reason: string explaining why bogus.
|
||||
* @param reason_bogus: relevant EDE code for validation failure.
|
||||
* @param qstate: qstate with region.
|
||||
* @return security status.
|
||||
* SECURE: proved absence of DS.
|
||||
|
@ -75,7 +77,8 @@ struct key_entry_key;
|
|||
enum sec_status val_nsec_prove_nodata_dsreply(struct module_env* env,
|
||||
struct val_env* ve, struct query_info* qinfo,
|
||||
struct reply_info* rep, struct key_entry_key* kkey,
|
||||
time_t* proof_ttl, char** reason, struct module_qstate* qstate);
|
||||
time_t* proof_ttl, char** reason, sldns_ede_code* reason_bogus,
|
||||
struct module_qstate* qstate);
|
||||
|
||||
/**
|
||||
* nsec typemap check, takes an NSEC-type bitmap as argument, checks for type.
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
#include "util/data/msgparse.h"
|
||||
#include "util/data/dname.h"
|
||||
#include "util/rbtree.h"
|
||||
#include "util/rfc_1982.h"
|
||||
#include "util/module.h"
|
||||
#include "util/net_help.h"
|
||||
#include "util/regional.h"
|
||||
|
@ -718,9 +719,9 @@ dnskey_verify_rrset(struct module_env* env, struct val_env* ve,
|
|||
}
|
||||
verbose(VERB_ALGO, "rrset failed to verify: all signatures are bogus");
|
||||
if(!numchecked) {
|
||||
*reason = "signature missing";
|
||||
*reason = "signature for expected key and algorithm missing";
|
||||
if(reason_bogus)
|
||||
*reason_bogus = LDNS_EDE_RRSIGS_MISSING;
|
||||
*reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
|
||||
} else if(numchecked == numindeterminate) {
|
||||
verbose(VERB_ALGO, "rrset failed to verify due to algorithm "
|
||||
"refusal by cryptolib");
|
||||
|
@ -1378,44 +1379,6 @@ sigdate_error(const char* str, int32_t expi, int32_t incep, int32_t now)
|
|||
(unsigned)incep, (unsigned)now);
|
||||
}
|
||||
|
||||
/** RFC 1982 comparison, uses unsigned integers, and tries to avoid
|
||||
* compiler optimization (eg. by avoiding a-b<0 comparisons),
|
||||
* this routine matches compare_serial(), for SOA serial number checks */
|
||||
static int
|
||||
compare_1982(uint32_t a, uint32_t b)
|
||||
{
|
||||
/* for 32 bit values */
|
||||
const uint32_t cutoff = ((uint32_t) 1 << (32 - 1));
|
||||
|
||||
if (a == b) {
|
||||
return 0;
|
||||
} else if ((a < b && b - a < cutoff) || (a > b && a - b > cutoff)) {
|
||||
return -1;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/** if we know that b is larger than a, return the difference between them,
|
||||
* that is the distance between them. in RFC1982 arith */
|
||||
static uint32_t
|
||||
subtract_1982(uint32_t a, uint32_t b)
|
||||
{
|
||||
/* for 32 bit values */
|
||||
const uint32_t cutoff = ((uint32_t) 1 << (32 - 1));
|
||||
|
||||
if(a == b)
|
||||
return 0;
|
||||
if(a < b && b - a < cutoff) {
|
||||
return b-a;
|
||||
}
|
||||
if(a > b && a - b > cutoff) {
|
||||
return ((uint32_t)0xffffffff) - (a-b-1);
|
||||
}
|
||||
/* wrong case, b smaller than a */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** check rrsig dates */
|
||||
static int
|
||||
check_dates(struct val_env* ve, uint32_t unow, uint8_t* expi_p,
|
||||
|
|
|
@ -587,16 +587,18 @@ val_verify_new_DNSKEYs(struct regional* region, struct module_env* env,
|
|||
return key_entry_create_rrset(region,
|
||||
ds_rrset->rk.dname, ds_rrset->rk.dname_len,
|
||||
ntohs(ds_rrset->rk.rrset_class), dnskey_rrset,
|
||||
downprot?sigalg:NULL, *env->now);
|
||||
downprot?sigalg:NULL, LDNS_EDE_NONE, NULL,
|
||||
*env->now);
|
||||
} else if(sec == sec_status_insecure) {
|
||||
return key_entry_create_null(region, ds_rrset->rk.dname,
|
||||
ds_rrset->rk.dname_len,
|
||||
ntohs(ds_rrset->rk.rrset_class),
|
||||
rrset_get_ttl(ds_rrset), *env->now);
|
||||
rrset_get_ttl(ds_rrset), *reason_bogus, *reason,
|
||||
*env->now);
|
||||
}
|
||||
return key_entry_create_bad(region, ds_rrset->rk.dname,
|
||||
ds_rrset->rk.dname_len, ntohs(ds_rrset->rk.rrset_class),
|
||||
BOGUS_KEY_TTL, *env->now);
|
||||
BOGUS_KEY_TTL, *reason_bogus, *reason, *env->now);
|
||||
}
|
||||
|
||||
enum sec_status
|
||||
|
@ -694,7 +696,7 @@ val_verify_DNSKEY_with_TA(struct module_env* env, struct val_env* ve,
|
|||
has_useful_ta = 1;
|
||||
|
||||
sec = dnskey_verify_rrset(env, ve, dnskey_rrset,
|
||||
ta_dnskey, i, reason, NULL, LDNS_SECTION_ANSWER, qstate);
|
||||
ta_dnskey, i, reason, reason_bogus, LDNS_SECTION_ANSWER, qstate);
|
||||
if(sec == sec_status_secure) {
|
||||
if(!sigalg || algo_needs_set_secure(&needs,
|
||||
(uint8_t)dnskey_get_algo(ta_dnskey, i))) {
|
||||
|
@ -743,16 +745,17 @@ val_verify_new_DNSKEYs_with_ta(struct regional* region, struct module_env* env,
|
|||
return key_entry_create_rrset(region,
|
||||
dnskey_rrset->rk.dname, dnskey_rrset->rk.dname_len,
|
||||
ntohs(dnskey_rrset->rk.rrset_class), dnskey_rrset,
|
||||
downprot?sigalg:NULL, *env->now);
|
||||
downprot?sigalg:NULL, LDNS_EDE_NONE, NULL, *env->now);
|
||||
} else if(sec == sec_status_insecure) {
|
||||
return key_entry_create_null(region, dnskey_rrset->rk.dname,
|
||||
dnskey_rrset->rk.dname_len,
|
||||
ntohs(dnskey_rrset->rk.rrset_class),
|
||||
rrset_get_ttl(dnskey_rrset), *env->now);
|
||||
rrset_get_ttl(dnskey_rrset), *reason_bogus, *reason,
|
||||
*env->now);
|
||||
}
|
||||
return key_entry_create_bad(region, dnskey_rrset->rk.dname,
|
||||
dnskey_rrset->rk.dname_len, ntohs(dnskey_rrset->rk.rrset_class),
|
||||
BOGUS_KEY_TTL, *env->now);
|
||||
BOGUS_KEY_TTL, *reason_bogus, *reason, *env->now);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -70,16 +70,16 @@ static void process_ds_response(struct module_qstate* qstate,
|
|||
struct query_info* qinfo, struct sock_list* origin);
|
||||
|
||||
|
||||
/* Updates the suplied EDE (RFC8914) code selectively so we don't loose
|
||||
* a more specific code
|
||||
*/
|
||||
/* Updates the suplied EDE (RFC8914) code selectively so we don't lose
|
||||
* a more specific code */
|
||||
static void
|
||||
update_reason_bogus(struct reply_info* rep, sldns_ede_code reason_bogus)
|
||||
{
|
||||
if (rep->reason_bogus == LDNS_EDE_DNSSEC_BOGUS ||
|
||||
rep->reason_bogus == LDNS_EDE_NONE) {
|
||||
if(reason_bogus == LDNS_EDE_NONE) return;
|
||||
if(reason_bogus == LDNS_EDE_DNSSEC_BOGUS
|
||||
&& rep->reason_bogus != LDNS_EDE_NONE
|
||||
&& rep->reason_bogus != LDNS_EDE_DNSSEC_BOGUS) return;
|
||||
rep->reason_bogus = reason_bogus;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1672,20 +1672,13 @@ processInit(struct module_qstate* qstate, struct val_qstate* vq,
|
|||
vq->state = VAL_FINISHED_STATE;
|
||||
return 1;
|
||||
} else if(key_entry_isbad(vq->key_entry)) {
|
||||
sldns_ede_code ede = LDNS_EDE_DNSSEC_BOGUS;
|
||||
|
||||
/* the key could have a more spefic EDE than just bogus */
|
||||
if(key_entry_get_reason_bogus(vq->key_entry) != LDNS_EDE_NONE) {
|
||||
ede = key_entry_get_reason_bogus(vq->key_entry);
|
||||
}
|
||||
|
||||
/* Bad keys should have the relevant EDE code and text */
|
||||
sldns_ede_code ede = key_entry_get_reason_bogus(vq->key_entry);
|
||||
/* key is bad, chain is bad, reply is bogus */
|
||||
errinf_dname(qstate, "key for validation", vq->key_entry->name);
|
||||
errinf_ede(qstate, "is marked as invalid", ede);
|
||||
if(key_entry_get_reason(vq->key_entry)) {
|
||||
errinf(qstate, "because of a previous");
|
||||
errinf(qstate, key_entry_get_reason(vq->key_entry));
|
||||
}
|
||||
|
||||
/* no retries, stop bothering the authority until timeout */
|
||||
vq->restart_count = ve->max_restart;
|
||||
|
@ -1888,7 +1881,8 @@ processValidate(struct module_qstate* qstate, struct val_qstate* vq,
|
|||
vq->chase_reply->security = sec_status_insecure;
|
||||
val_mark_insecure(vq->chase_reply, vq->key_entry->name,
|
||||
qstate->env->rrset_cache, qstate->env);
|
||||
key_cache_insert(ve->kcache, vq->key_entry, qstate);
|
||||
key_cache_insert(ve->kcache, vq->key_entry,
|
||||
qstate->env->cfg->val_log_level >= 2);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -1897,12 +1891,13 @@ processValidate(struct module_qstate* qstate, struct val_qstate* vq,
|
|||
"of trust to keys for", vq->key_entry->name,
|
||||
LDNS_RR_TYPE_DNSKEY, vq->key_entry->key_class);
|
||||
vq->chase_reply->security = sec_status_bogus;
|
||||
|
||||
update_reason_bogus(vq->chase_reply, LDNS_EDE_DNSKEY_MISSING);
|
||||
update_reason_bogus(vq->chase_reply,
|
||||
key_entry_get_reason_bogus(vq->key_entry));
|
||||
errinf_ede(qstate, "while building chain of trust",
|
||||
LDNS_EDE_DNSKEY_MISSING);
|
||||
key_entry_get_reason_bogus(vq->key_entry));
|
||||
if(vq->restart_count >= ve->max_restart)
|
||||
key_cache_insert(ve->kcache, vq->key_entry, qstate);
|
||||
key_cache_insert(ve->kcache, vq->key_entry,
|
||||
qstate->env->cfg->val_log_level >= 2);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -2151,9 +2146,19 @@ processFinished(struct module_qstate* qstate, struct val_qstate* vq,
|
|||
log_query_info(NO_VERBOSE, "validation failure",
|
||||
&qstate->qinfo);
|
||||
else {
|
||||
char* err = errinf_to_str_bogus(qstate);
|
||||
if(err) log_info("%s", err);
|
||||
free(err);
|
||||
char* err_str = errinf_to_str_bogus(qstate);
|
||||
if(err_str) {
|
||||
size_t err_str_len = strlen(err_str);
|
||||
log_info("%s", err_str);
|
||||
/* allocate space and store the error
|
||||
* string */
|
||||
vq->orig_msg->rep->reason_bogus_str = regional_alloc(
|
||||
qstate->region,
|
||||
sizeof(char) * (err_str_len+1));
|
||||
memcpy(vq->orig_msg->rep->reason_bogus_str,
|
||||
err_str, err_str_len+1);
|
||||
}
|
||||
free(err_str);
|
||||
}
|
||||
}
|
||||
/*
|
||||
|
@ -2195,6 +2200,9 @@ processFinished(struct module_qstate* qstate, struct val_qstate* vq,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Update rep->reason_bogus as it is the one being cached */
|
||||
update_reason_bogus(vq->orig_msg->rep, errinf_to_reason_bogus(qstate));
|
||||
/* store results in cache */
|
||||
if(qstate->query_flags&BIT_RD) {
|
||||
/* if secure, this will override cache anyway, no need
|
||||
|
@ -2370,13 +2378,17 @@ primeResponseToKE(struct ub_packed_rrset_key* dnskey_rrset,
|
|||
log_nametypeclass(VERB_OPS, "failed to prime trust anchor -- "
|
||||
"could not fetch DNSKEY rrset",
|
||||
ta->name, LDNS_RR_TYPE_DNSKEY, ta->dclass);
|
||||
reason_bogus = LDNS_EDE_DNSKEY_MISSING;
|
||||
reason = "no DNSKEY rrset";
|
||||
if(qstate->env->cfg->harden_dnssec_stripped) {
|
||||
errinf_ede(qstate, "no DNSKEY rrset", LDNS_EDE_DNSKEY_MISSING);
|
||||
errinf_ede(qstate, reason, reason_bogus);
|
||||
kkey = key_entry_create_bad(qstate->region, ta->name,
|
||||
ta->namelen, ta->dclass, BOGUS_KEY_TTL,
|
||||
reason_bogus, reason,
|
||||
*qstate->env->now);
|
||||
} else kkey = key_entry_create_null(qstate->region, ta->name,
|
||||
ta->namelen, ta->dclass, NULL_KEY_TTL,
|
||||
reason_bogus, reason,
|
||||
*qstate->env->now);
|
||||
if(!kkey) {
|
||||
log_err("out of memory: allocate fail prime key");
|
||||
|
@ -2409,9 +2421,11 @@ primeResponseToKE(struct ub_packed_rrset_key* dnskey_rrset,
|
|||
errinf_ede(qstate, reason, reason_bogus);
|
||||
kkey = key_entry_create_bad(qstate->region, ta->name,
|
||||
ta->namelen, ta->dclass, BOGUS_KEY_TTL,
|
||||
reason_bogus, reason,
|
||||
*qstate->env->now);
|
||||
} else kkey = key_entry_create_null(qstate->region, ta->name,
|
||||
ta->namelen, ta->dclass, NULL_KEY_TTL,
|
||||
reason_bogus, reason,
|
||||
*qstate->env->now);
|
||||
if(!kkey) {
|
||||
log_err("out of memory: allocate null prime key");
|
||||
|
@ -2458,8 +2472,9 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
|
|||
/* errors here pretty much break validation */
|
||||
verbose(VERB_DETAIL, "DS response was error, thus bogus");
|
||||
errinf(qstate, rc);
|
||||
errinf_ede(qstate, "no DS", LDNS_EDE_NETWORK_ERROR);
|
||||
|
||||
reason = "no DS";
|
||||
reason_bogus = LDNS_EDE_NETWORK_ERROR;
|
||||
errinf_ede(qstate, reason, reason_bogus);
|
||||
goto return_bogus;
|
||||
}
|
||||
|
||||
|
@ -2473,7 +2488,8 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
|
|||
if(!ds) {
|
||||
log_warn("internal error: POSITIVE DS response was "
|
||||
"missing DS.");
|
||||
errinf_ede(qstate, "no DS record", LDNS_EDE_DNSSEC_BOGUS);
|
||||
reason = "no DS record";
|
||||
errinf_ede(qstate, reason, reason_bogus);
|
||||
goto return_bogus;
|
||||
}
|
||||
/* Verify only returns BOGUS or SECURE. If the rrset is
|
||||
|
@ -2492,13 +2508,11 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
|
|||
if(!val_dsset_isusable(ds)) {
|
||||
/* If they aren't usable, then we treat it like
|
||||
* there was no DS. */
|
||||
|
||||
/* TODO add EDE Unsupported DS Digest Type; this needs
|
||||
* EDE to be added on non SERVFAIL answers. */
|
||||
|
||||
*ke = key_entry_create_null(qstate->region,
|
||||
qinfo->qname, qinfo->qname_len, qinfo->qclass,
|
||||
ub_packed_rrset_ttl(ds), *qstate->env->now);
|
||||
ub_packed_rrset_ttl(ds),
|
||||
LDNS_EDE_UNSUPPORTED_DS_DIGEST, NULL,
|
||||
*qstate->env->now);
|
||||
return (*ke) != NULL;
|
||||
}
|
||||
|
||||
|
@ -2506,7 +2520,7 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
|
|||
log_query_info(VERB_DETAIL, "validated DS", qinfo);
|
||||
*ke = key_entry_create_rrset(qstate->region,
|
||||
qinfo->qname, qinfo->qname_len, qinfo->qclass, ds,
|
||||
NULL, *qstate->env->now);
|
||||
NULL, LDNS_EDE_NONE, NULL, *qstate->env->now);
|
||||
return (*ke) != NULL;
|
||||
} else if(subtype == VAL_CLASS_NODATA ||
|
||||
subtype == VAL_CLASS_NAMEERROR) {
|
||||
|
@ -2518,7 +2532,8 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
|
|||
/* make sure there are NSECs or NSEC3s with signatures */
|
||||
if(!val_has_signed_nsecs(msg->rep, &reason)) {
|
||||
verbose(VERB_ALGO, "no NSECs: %s", reason);
|
||||
errinf_ede(qstate, reason, LDNS_EDE_NSEC_MISSING);
|
||||
reason_bogus = LDNS_EDE_NSEC_MISSING;
|
||||
errinf_ede(qstate, reason, reason_bogus);
|
||||
goto return_bogus;
|
||||
}
|
||||
|
||||
|
@ -2530,7 +2545,7 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
|
|||
/* Try to prove absence of the DS with NSEC */
|
||||
sec = val_nsec_prove_nodata_dsreply(
|
||||
qstate->env, ve, qinfo, msg->rep, vq->key_entry,
|
||||
&proof_ttl, &reason, qstate);
|
||||
&proof_ttl, &reason, &reason_bogus, qstate);
|
||||
switch(sec) {
|
||||
case sec_status_secure:
|
||||
verbose(VERB_DETAIL, "NSEC RRset for the "
|
||||
|
@ -2538,6 +2553,7 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
|
|||
*ke = key_entry_create_null(qstate->region,
|
||||
qinfo->qname, qinfo->qname_len,
|
||||
qinfo->qclass, proof_ttl,
|
||||
LDNS_EDE_NONE, NULL,
|
||||
*qstate->env->now);
|
||||
return (*ke) != NULL;
|
||||
case sec_status_insecure:
|
||||
|
@ -2571,6 +2587,7 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
|
|||
*ke = key_entry_create_null(qstate->region,
|
||||
qinfo->qname, qinfo->qname_len,
|
||||
qinfo->qclass, proof_ttl,
|
||||
LDNS_EDE_NONE, NULL,
|
||||
*qstate->env->now);
|
||||
return (*ke) != NULL;
|
||||
case sec_status_indeterminate:
|
||||
|
@ -2593,7 +2610,8 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
|
|||
* this is BOGUS. */
|
||||
verbose(VERB_DETAIL, "DS %s ran out of options, so return "
|
||||
"bogus", val_classification_to_string(subtype));
|
||||
errinf(qstate, "no DS but also no proof of that");
|
||||
reason = "no DS but also no proof of that";
|
||||
errinf_ede(qstate, reason, reason_bogus);
|
||||
goto return_bogus;
|
||||
} else if(subtype == VAL_CLASS_CNAME ||
|
||||
subtype == VAL_CLASS_CNAMENOANSWER) {
|
||||
|
@ -2605,22 +2623,25 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
|
|||
cname = reply_find_rrset_section_an(msg->rep, qinfo->qname,
|
||||
qinfo->qname_len, LDNS_RR_TYPE_CNAME, qinfo->qclass);
|
||||
if(!cname) {
|
||||
errinf(qstate, "validator classified CNAME but no "
|
||||
"CNAME of the queried name for DS");
|
||||
reason = "validator classified CNAME but no "
|
||||
"CNAME of the queried name for DS";
|
||||
errinf_ede(qstate, reason, reason_bogus);
|
||||
goto return_bogus;
|
||||
}
|
||||
if(((struct packed_rrset_data*)cname->entry.data)->rrsig_count
|
||||
== 0) {
|
||||
if(msg->rep->an_numrrsets != 0 && ntohs(msg->rep->
|
||||
rrsets[0]->rk.type)==LDNS_RR_TYPE_DNAME) {
|
||||
errinf(qstate, "DS got DNAME answer");
|
||||
reason = "DS got DNAME answer";
|
||||
} else {
|
||||
errinf(qstate, "DS got unsigned CNAME answer");
|
||||
reason = "DS got unsigned CNAME answer";
|
||||
}
|
||||
errinf_ede(qstate, reason, reason_bogus);
|
||||
goto return_bogus;
|
||||
}
|
||||
sec = val_verify_rrset_entry(qstate->env, ve, cname,
|
||||
vq->key_entry, &reason, NULL, LDNS_SECTION_ANSWER, qstate);
|
||||
vq->key_entry, &reason, &reason_bogus,
|
||||
LDNS_SECTION_ANSWER, qstate);
|
||||
if(sec == sec_status_secure) {
|
||||
verbose(VERB_ALGO, "CNAME validated, "
|
||||
"proof that DS does not exist");
|
||||
|
@ -2629,12 +2650,13 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
|
|||
return 1;
|
||||
}
|
||||
errinf(qstate, "CNAME in DS response was not secure.");
|
||||
errinf(qstate, reason);
|
||||
errinf_ede(qstate, reason, reason_bogus);
|
||||
goto return_bogus;
|
||||
} else {
|
||||
verbose(VERB_QUERY, "Encountered an unhandled type of "
|
||||
"DS response, thus bogus.");
|
||||
errinf(qstate, "no DS and");
|
||||
reason = "no DS";
|
||||
if(FLAGS_GET_RCODE(msg->rep->flags) != LDNS_RCODE_NOERROR) {
|
||||
char rc[16];
|
||||
rc[0]=0;
|
||||
|
@ -2647,8 +2669,8 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
|
|||
}
|
||||
return_bogus:
|
||||
*ke = key_entry_create_bad(qstate->region, qinfo->qname,
|
||||
qinfo->qname_len, qinfo->qclass,
|
||||
BOGUS_KEY_TTL, *qstate->env->now);
|
||||
qinfo->qname_len, qinfo->qclass, BOGUS_KEY_TTL,
|
||||
reason_bogus, reason, *qstate->env->now);
|
||||
return (*ke) != NULL;
|
||||
}
|
||||
|
||||
|
@ -2768,14 +2790,17 @@ process_dnskey_response(struct module_qstate* qstate, struct val_qstate* vq,
|
|||
vq->restart_count++;
|
||||
return;
|
||||
}
|
||||
reason = "No DNSKEY record";
|
||||
reason_bogus = LDNS_EDE_DNSKEY_MISSING;
|
||||
vq->key_entry = key_entry_create_bad(qstate->region,
|
||||
qinfo->qname, qinfo->qname_len, qinfo->qclass,
|
||||
BOGUS_KEY_TTL, *qstate->env->now);
|
||||
BOGUS_KEY_TTL, reason_bogus, reason,
|
||||
*qstate->env->now);
|
||||
if(!vq->key_entry) {
|
||||
log_err("alloc failure in missing dnskey response");
|
||||
/* key_entry is NULL for failure in Validate */
|
||||
}
|
||||
errinf_ede(qstate, "No DNSKEY record", LDNS_EDE_DNSKEY_MISSING);
|
||||
errinf_ede(qstate, reason, reason_bogus);
|
||||
errinf_origin(qstate, origin);
|
||||
errinf_dname(qstate, "for key", qinfo->qname);
|
||||
vq->state = VAL_VALIDATE_STATE;
|
||||
|
@ -2822,7 +2847,8 @@ process_dnskey_response(struct module_qstate* qstate, struct val_qstate* vq,
|
|||
qstate->errinf = NULL;
|
||||
|
||||
/* The DNSKEY validated, so cache it as a trusted key rrset. */
|
||||
key_cache_insert(ve->kcache, vq->key_entry, qstate);
|
||||
key_cache_insert(ve->kcache, vq->key_entry,
|
||||
qstate->env->cfg->val_log_level >= 2);
|
||||
|
||||
/* If good, we stay in the FINDKEY state. */
|
||||
log_query_info(VERB_DETAIL, "validated DNSKEY", qinfo);
|
||||
|
@ -2890,7 +2916,8 @@ process_prime_response(struct module_qstate* qstate, struct val_qstate* vq,
|
|||
errinf_origin(qstate, origin);
|
||||
errinf_dname(qstate, "for trust anchor", ta->name);
|
||||
/* store the freshly primed entry in the cache */
|
||||
key_cache_insert(ve->kcache, vq->key_entry, qstate);
|
||||
key_cache_insert(ve->kcache, vq->key_entry,
|
||||
qstate->env->cfg->val_log_level >= 2);
|
||||
}
|
||||
|
||||
/* If the result of the prime is a null key, skip the FINDKEY state.*/
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
.\" $OpenBSD: bsd.port.mk.5,v 1.587 2023/09/04 22:36:55 thfr Exp $
|
||||
.\" $OpenBSD: bsd.port.mk.5,v 1.602 2023/09/05 13:58:49 espie Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2000-2008 Marc Espie
|
||||
.\"
|
||||
|
@ -24,7 +24,7 @@
|
|||
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd $Mdocdate: September 4 2023 $
|
||||
.Dd $Mdocdate: September 5 2023 $
|
||||
.Dt BSD.PORT.MK 5
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -41,15 +41,31 @@ tree
|
|||
framework, in the form of documented public targets,
|
||||
variables and paths.
|
||||
.Pp
|
||||
The actual
|
||||
.Nm
|
||||
file lives under
|
||||
.Pa ${PORTSDIR}/infrastructure/mk ,
|
||||
with
|
||||
.Xr make 1 Ns 's
|
||||
system include file redirecting to it.
|
||||
.Pp
|
||||
Optional parts of this framework have been moved to
|
||||
.Xr port-modules 5
|
||||
in an effort to shrink the main file
|
||||
.Po
|
||||
see also
|
||||
.Ev MODULES
|
||||
.Pc .
|
||||
.Pp
|
||||
Identifiers beginning with an underscore
|
||||
are internal-use only and likely to change without
|
||||
notice.
|
||||
.Pp
|
||||
This documentation contains sections covering targets, variables,
|
||||
diagnostics, and filenames, ordered in alphabetic order, followed
|
||||
by a section covering the fake framework, a section
|
||||
explaining flavors and multi-packages, and a section covering
|
||||
the generation of package information.
|
||||
by a section covering the fake framework, a section covering debug
|
||||
packages generation, a section explaining flavors and multi-packages,
|
||||
and a section covering the generation of package information.
|
||||
.Pp
|
||||
It ends with sections covering some obsolete targets, variables and files,
|
||||
outlining conversion
|
||||
|
@ -84,6 +100,13 @@ run it, or to run regression tests.
|
|||
The output is formatted as package specification pairs, in a form suitable
|
||||
for
|
||||
.Xr tsort 1 .
|
||||
.Pp
|
||||
Note that is is possible to obtain reverse dependency information by
|
||||
using
|
||||
.Nm show-reverse-deps
|
||||
from the
|
||||
.Pa sqlports
|
||||
package.
|
||||
.It Cm full-{build,run,all,test}-depends
|
||||
Print all dependencies a package depends upon for building, running,
|
||||
or both, as a list of package names, sorted by dependency order with
|
||||
|
@ -235,6 +258,14 @@ for details.
|
|||
.It Cm dump-vars
|
||||
Dump the values of all relevant variables in a port, prepended with the
|
||||
port's FULLPKGPATH.
|
||||
.Pp
|
||||
Can be limited to some specific information by setting
|
||||
.Ev DPB
|
||||
to nothing or
|
||||
.Sq fetch .
|
||||
Mostly used by
|
||||
.Xr dpb 1
|
||||
for obtaining vital information from the ports tree.
|
||||
.It Cm extract
|
||||
Extract the distribution files under
|
||||
.Pa ${WRKDIR}
|
||||
|
@ -252,15 +283,16 @@ and
|
|||
.Cm do-extract
|
||||
hooks.
|
||||
.It Cm fake
|
||||
Do a fake port installation, that is, simulate the port installation under
|
||||
${WRKINST}.
|
||||
Do a fake port installation, that is, simulate the port installation into
|
||||
the staging area ${WRKINST}.
|
||||
There is no
|
||||
.Cm do-fake
|
||||
and
|
||||
.Cm post-fake
|
||||
hooks.
|
||||
hooks:
|
||||
instead
|
||||
.Cm fake
|
||||
actually uses
|
||||
runs
|
||||
.Cm pre-fake ,
|
||||
.Cm pre-install ,
|
||||
.Cm do-install
|
||||
|
@ -272,9 +304,20 @@ Override
|
|||
or
|
||||
.Cm post-install
|
||||
to change behavior.
|
||||
Do not touch
|
||||
.Pp
|
||||
There are only a handful of ports that use
|
||||
.Cm pre-fake :
|
||||
that hook can be used to finish setting up a
|
||||
.Pa fake
|
||||
directory before starting the installation proper.
|
||||
Stuff run during
|
||||
.Cm pre-fake
|
||||
unless you really know what you are doing.
|
||||
will not register with
|
||||
.Cm update-plist ,
|
||||
whereas stuff run during
|
||||
.Cm pre-install
|
||||
will be considered part of the installation process.
|
||||
.Pp
|
||||
See
|
||||
.Sx THE FAKE FRAMEWORK
|
||||
section below.
|
||||
|
@ -291,7 +334,7 @@ and
|
|||
.Ev PATCHFILES*
|
||||
using ${FETCH_CMD}.
|
||||
Files are normally retrieved from the list of sites in
|
||||
.Ev MASTER_SITES* .
|
||||
.Ev SITES* .
|
||||
.Pp
|
||||
Appending
|
||||
.Sq :0
|
||||
|
@ -299,9 +342,9 @@ to
|
|||
.Sq :9
|
||||
to an entry will let
|
||||
${FETCH_CMD} retrieve from
|
||||
.Ev MASTER_SITES0
|
||||
.Ev SITES0
|
||||
to
|
||||
.Ev MASTER_SITES9
|
||||
.Ev SITES9
|
||||
instead (deprecated).
|
||||
.Pp
|
||||
Preferably, adding a suffix to
|
||||
|
@ -309,11 +352,11 @@ Preferably, adding a suffix to
|
|||
.Ev PATCHFILES ,
|
||||
.Ev SUPDISTFILES
|
||||
will switch the site entry to the corresponding
|
||||
.Ev MASTER_SITES
|
||||
.Ev SITES
|
||||
variable, e.g.,
|
||||
.Bd -literal -offset indent
|
||||
DISTFILES.go = ...
|
||||
MASTER_SITES.go = ...
|
||||
SITES.go = ...
|
||||
.Ed
|
||||
.Pp
|
||||
If the rest of the entry parses as
|
||||
|
@ -346,9 +389,10 @@ all files relevant to a port,
|
|||
.Cm dpb Fl F
|
||||
is more efficient.
|
||||
.Pp
|
||||
Use of
|
||||
There are no
|
||||
.Cm {pre,do,post}-fetch
|
||||
hooks is forbidden, as this would make mirroring of distfiles very complicated.
|
||||
hooks, as this would break
|
||||
.Xr dpb 1 .
|
||||
.Pp
|
||||
See
|
||||
.Ev ALL_DISTFILES ,
|
||||
|
@ -361,18 +405,16 @@ See
|
|||
.Ev FETCH_MANUALLY ,
|
||||
.Ev FULLDISTDIR ,
|
||||
.Ev MAKESUMFILES ,
|
||||
.Ev MASTER_SITES* ,
|
||||
.Ev MASTER_SITES0 , ... ,
|
||||
.Ev MASTER_SITES9 ,
|
||||
.Ev PATCHFILES* ,
|
||||
.Ev SUPDISTFILES* ,
|
||||
.Ev REFETCH .
|
||||
.Ev SITES* ,
|
||||
.It Cm fetch-all
|
||||
Like
|
||||
.Cm fetch ,
|
||||
but also fetches
|
||||
.Ev SUPDISTFILES* ,
|
||||
for use with e.g.,
|
||||
for use by e.g.,
|
||||
.Cm makesum .
|
||||
.It Cm fix-permissions
|
||||
Ensure permissions are correct when using
|
||||
|
@ -425,9 +467,6 @@ and before
|
|||
or
|
||||
.Cm update-plist .
|
||||
Always rerun, as it is cheap enough.
|
||||
.It Cm index
|
||||
Top-level target, see
|
||||
.Xr ports 7 .
|
||||
.It Cm install-depends
|
||||
Before package installation, install and verify dependencies constructed from
|
||||
.Ev RUN_DEPENDS , LIB_DEPENDS ,
|
||||
|
@ -456,17 +495,18 @@ Verify that the
|
|||
.Ev LIB_DEPENDS
|
||||
and
|
||||
.Ev WANTLIB
|
||||
are accurate for the port.
|
||||
recorded in the port's packages are accurate.
|
||||
See
|
||||
.Cm port-lib-depends-check ,
|
||||
which is quicker.
|
||||
which checks files under the fake staging directory instead,
|
||||
and thus has faster turn-around.
|
||||
.It Cm license-check
|
||||
Check that
|
||||
.Ev PERMIT_PACKAGE
|
||||
settings match:
|
||||
if any dependency has a more restrictive setting, warn about it.
|
||||
This warning is advisory, because the automated license checking cannot
|
||||
figure out which ports were used only for building and did not taint
|
||||
This warning is advisory, because automated license checking cannot
|
||||
know that some ports were only used for building and did not taint
|
||||
the current port.
|
||||
.It Cm lock
|
||||
Manually obtain a lock on a given directory.
|
||||
|
@ -477,14 +517,18 @@ Seldom used, see
|
|||
.Xr ports 7
|
||||
for details.
|
||||
.It Cm makesum
|
||||
Run
|
||||
Uses
|
||||
.Cm fetch-all
|
||||
to fetch missing ${MAKESUMFILES}
|
||||
without verifying their digest, then run
|
||||
.Xr sha256 1
|
||||
on ${MAKESUMFILES}
|
||||
that is, files listed in ${DISTFILES*}, ${SUPDISTFILES*} and ${PATCHFILES*},
|
||||
and store the result in ${CHECKSUM_FILE}, normally
|
||||
on them that is,
|
||||
files listed in ${DISTFILES*}, ${SUPDISTFILES*} and ${PATCHFILES*}.
|
||||
The result is stored in ${CHECKSUM_FILE}, normally
|
||||
.Pa distinfo .
|
||||
Also store the lengths of all files for a quick check during
|
||||
.Cm fetch .
|
||||
.Cm fetch ,
|
||||
.Cm fetch-all .
|
||||
.It Cm no-lib-depends-args
|
||||
Degenerate form of
|
||||
.Cm lib-depends-args
|
||||
|
@ -511,9 +555,18 @@ for each package in the
|
|||
.Ev MULTI_PACKAGES
|
||||
list.
|
||||
If the repository already contains up-to-date packages, they are not rebuilt.
|
||||
If PLIST_REPOSITORY is set, the resulting packaging information is compared
|
||||
with existing stuff, and saved if new, with loud complaints if it changed
|
||||
without a REVISION bump.
|
||||
If PLIST_REPOSITORY is set (the default), the resulting packaging
|
||||
information is compared with existing stuff, and saved if new,
|
||||
with loud complaints if it changed without a
|
||||
.Ev REVISION
|
||||
bump.
|
||||
.Pp
|
||||
if
|
||||
.Ev DEBUG_PACKAGES
|
||||
is set, some debug information may also be set aside and saved
|
||||
in
|
||||
.Pa debug-*
|
||||
packages transparently.
|
||||
.Pp
|
||||
Also note that
|
||||
.Pa ${PLIST_REPOSITORY}/${MACHINE_ARCH}/history
|
||||
|
@ -569,7 +622,7 @@ will be applied under
|
|||
.Ev WRKDIST .
|
||||
.It Cm peek-ftp
|
||||
Connect to the first site in
|
||||
.Ev MASTER_SITES ,
|
||||
.Ev SITES ,
|
||||
in the right directory, and leaves user at
|
||||
.Xr ftp 1 Ns 's
|
||||
prompt.
|
||||
|
@ -787,7 +840,12 @@ Print the list of
|
|||
.Xr pkgpath 7
|
||||
for all ports that will be affected by the
|
||||
current port changing.
|
||||
Works by walking the list of dependencies, in reverse.
|
||||
Works by walking the full list of all dependencies of all ports, in reverse.
|
||||
.Pp
|
||||
Very slow, prefer installing the
|
||||
.Pa sqlports
|
||||
package and using
|
||||
.Nm show-reverse-deps .
|
||||
.It Cm show-run-depends
|
||||
Print all running dependencies for a port, one per-line, without duplicates.
|
||||
.It Cm subpackage
|
||||
|
@ -993,9 +1051,7 @@ Automatically set as soon as
|
|||
.Ev CONFIGURE_STYLE
|
||||
is gnu or higher.
|
||||
.It Ev AUTOCONF_VERSION
|
||||
Starting with
|
||||
.Ox 3.3 ,
|
||||
several versions of autoconf may coexist peacefully.
|
||||
Several versions of autoconf may coexist peacefully.
|
||||
The main autoconf script is a shell wrapper in the
|
||||
.Pa devel/metaauto
|
||||
package, and similarly for automake.
|
||||
|
@ -1271,7 +1327,10 @@ This is essentially the same as running
|
|||
after each package build.
|
||||
Defaults to
|
||||
.Sq \&No ,
|
||||
as this can be a big performance hit.
|
||||
as this can be a big performance hit, and also because
|
||||
.Ev lib-depends-check
|
||||
doesn't know about library subdirectories or dynamic loading through
|
||||
.Xr dlopen 3 .
|
||||
.It Ev CHECKSUMFILES
|
||||
List of all files that need to be retrieved by
|
||||
.Cm fetch ,
|
||||
|
@ -1284,8 +1343,9 @@ See also
|
|||
.It Ev CHECKSUM_FILE
|
||||
Location for this port's checksums, used by
|
||||
.Cm checksum ,
|
||||
.Cm makesum ,
|
||||
and
|
||||
.Cm makesum .
|
||||
.Xr dpb 1 .
|
||||
Defaults to
|
||||
.Pa distinfo .
|
||||
.It Ev CHECKSUM_PACKAGES
|
||||
|
@ -1594,9 +1654,9 @@ and
|
|||
entries can be added as needed
|
||||
.Pc .
|
||||
The components are used to build
|
||||
.Ev MASTER_SITES.name
|
||||
.Ev SITES.name
|
||||
.Ev DISTFILES.name
|
||||
and
|
||||
and (optionally)
|
||||
.Ev HOMEPAGE .
|
||||
.Pp
|
||||
At the end of
|
||||
|
@ -1622,7 +1682,7 @@ into account.
|
|||
.It Ev DISTFILES*
|
||||
The main port's distribution files (the actual software source, except
|
||||
for binary-only ports).
|
||||
Will be retrieved from the corresponding MASTER_SITES* (see
|
||||
Will be retrieved from the corresponding SITES* (see
|
||||
.Cm fetch ) ,
|
||||
checksummed and extracted (see
|
||||
.Cm checksum ,
|
||||
|
@ -1633,16 +1693,16 @@ normally holds a list of files, possibly with
|
|||
to
|
||||
.Sq :9
|
||||
appended to select a different
|
||||
.Ev MASTER_SITES .
|
||||
.Ev SITES .
|
||||
.Pp
|
||||
Preferably, adding a suffix to
|
||||
.Ev DISTFILES ,
|
||||
will switch the site entry to the corresponding
|
||||
.Ev MASTER_SITES
|
||||
.Ev SITES
|
||||
variable, e.g.,
|
||||
.Bd -literal -offset indent
|
||||
DISTFILES.go = ...
|
||||
MASTER_SITES.go = ...
|
||||
SITES.go = ...
|
||||
.Ed
|
||||
.Pp
|
||||
Each entry may optionally be of the form
|
||||
|
@ -1669,8 +1729,17 @@ If ${DISTFILES*} varies depending on
|
|||
or architecture, use
|
||||
.Ev SUPDISTFILES*
|
||||
to ensure distfiles mirroring and
|
||||
.Cm makesum
|
||||
.Cm makesum Ns 's
|
||||
proper operation.
|
||||
.Pp
|
||||
If no
|
||||
.Ev DISTFILES*
|
||||
is set and if
|
||||
.Ev SITES
|
||||
is not null, then
|
||||
.Ev DISTFILES
|
||||
will be set to
|
||||
.Pa ${DISNAME}${EXTRACT_SUFX} .
|
||||
.It Ev DISTNAME
|
||||
Name used to identify the port.
|
||||
See
|
||||
|
@ -1724,9 +1793,13 @@ If defined,
|
|||
.Nm
|
||||
will provide dummy values for variables mandatory for a minimally functional
|
||||
port.
|
||||
Used by various pieces of the ports tree to perform introspection and get to
|
||||
Used by
|
||||
.Pa sqlports
|
||||
and
|
||||
.Xr dpb 1
|
||||
to perform introspection and obtain
|
||||
.Nm Ns 's
|
||||
variables.
|
||||
default values for variables without needing to access any specific port.
|
||||
.It Ev ECHO_MSG
|
||||
User settings.
|
||||
Used to display
|
||||
|
@ -1782,6 +1855,9 @@ for instance to flag erroneous combinations of
|
|||
and
|
||||
.Ev BROKEN
|
||||
for other common issues).
|
||||
.Pp
|
||||
Note that setting fatal errors defeats all introspection mechanisms and breaks
|
||||
.Pa sqlports .
|
||||
.It Ev EXTRACT_CASES
|
||||
In the normal extraction stage (when
|
||||
.Ev EXTRACT_ONLY
|
||||
|
@ -1874,7 +1950,7 @@ Target built by ${MAKE_PROGRAM} on fake invocation.
|
|||
Defaults to ${INSTALL_TARGET}.
|
||||
.It Ev FAKEOBJDIR
|
||||
User settings.
|
||||
If non empty, used as a base for the fake area.
|
||||
If non empty, used as a base for the fake staging area.
|
||||
The real fake directory ${WRKINST} is created there.
|
||||
Can be set on a per-${PKGPATH} basis.
|
||||
For instance, setting FAKEOBJDIR_www/mozilla-firefox=/tmp/obj
|
||||
|
@ -2024,7 +2100,7 @@ See
|
|||
Simple support for GitHub-hosted projects.
|
||||
Leave empty for non hosted projects.
|
||||
Yields a suitable default for
|
||||
.Ev MASTER_SITES_GITHUB
|
||||
.Ev SITES_GITHUB
|
||||
and
|
||||
.Ev DISTNAME .
|
||||
.It Ev GH_ACCOUNT
|
||||
|
@ -2106,12 +2182,17 @@ to simplify bulk-package builds.
|
|||
Set to
|
||||
.Sq Yes
|
||||
if port needs human interaction to build.
|
||||
Porters should strive to minimize
|
||||
.Pp
|
||||
Note that
|
||||
.Ev IS_INTERACTIVE
|
||||
ports, by using
|
||||
.Ev FLAVORS
|
||||
for multiple choice ports, and by postponing human intervention
|
||||
to package installation time.
|
||||
ports won't be built as official packages,
|
||||
so avoid at all cost.
|
||||
.Pp
|
||||
Human intervention should be moved to binary package
|
||||
installation and/or post-installation configuration instead.
|
||||
.Pp
|
||||
Discrete Yes/No choices are better modelled as
|
||||
.Ev FLAVORS .
|
||||
.It Ev LE_ARCHS
|
||||
Set to the list of little-endian architectures.
|
||||
Read-only.
|
||||
|
@ -2273,45 +2354,6 @@ prepended and with master site selection extension removed.
|
|||
Read-only.
|
||||
See also
|
||||
.Ev CHECKSUMFILES .
|
||||
.It Ev MASTER_SITE_BACKUP
|
||||
User settings.
|
||||
List of sites to try after normal master sites.
|
||||
Normally includes ${MASTER_SITE_OPENBSD} and ${MASTER_SITE_FREEBSD}.
|
||||
.It Ev MASTER_SITE_*
|
||||
Lists of standard sites to retrieve files from, refer to
|
||||
.Pa ${PORTSDIR}/infrastructure/db/network.conf
|
||||
for a complete list.
|
||||
.Pp
|
||||
Generally used with the standard
|
||||
.Xr make 1 Ns 's
|
||||
.Li ${VARIABLE:=subdir/}
|
||||
construct to append the relevant subdir at the end of each entry, e.g.,
|
||||
.Dl MASTER_SITES = ${MASTER_SITE_GNU:=cgicc/}
|
||||
.It Ev MASTER_SITES
|
||||
List of primary locations from which distribution files and patchfiles are
|
||||
retrieved.
|
||||
See the
|
||||
.Cm fetch
|
||||
target for details.
|
||||
Defaults to ${MASTER_SITES_GITHUB} for GitHub-hosted projects,
|
||||
see
|
||||
.Ev GH_* .
|
||||
See
|
||||
.Xr ports 7
|
||||
for user configuration.
|
||||
.It Ev MASTER_SITES*
|
||||
List of alternate locations from which ${DISTFILES*}, ${PATCHFILES*},
|
||||
${SUPDISTFILES*} are retrieved.
|
||||
See
|
||||
.Cm fetch
|
||||
for details.
|
||||
Suffix should start with
|
||||
.Sq \&.
|
||||
for consistency.
|
||||
.Pp
|
||||
.It Ev MASTER_SITES0 , ... , MASTER_SITES9
|
||||
Supplementary locations from which distribution files and patchfiles are
|
||||
retrieved.
|
||||
.It Ev MESSAGE
|
||||
File recorded in the package and displayed during installation.
|
||||
Defaults to ${PKGDIR}/MESSAGE if this file exists.
|
||||
|
@ -3117,6 +3159,45 @@ Porters of software using libtool should make sure
|
|||
.Ev MAKE_FLAGS
|
||||
get propagated to the libtool invocations.
|
||||
This should be enough in most cases.
|
||||
.It Ev SITE_BACKUP
|
||||
User settings.
|
||||
List of sites to try after normal master sites.
|
||||
Normally includes ${SITE_OPENBSD} and ${SITE_FREEBSD}.
|
||||
.It Ev SITE_*
|
||||
Lists of standard sites to retrieve files from, refer to
|
||||
.Pa ${PORTSDIR}/infrastructure/db/network.conf
|
||||
for a complete list.
|
||||
.Pp
|
||||
Generally used with the standard
|
||||
.Xr make 1 Ns 's
|
||||
.Li ${VARIABLE:=subdir/}
|
||||
construct to append the relevant subdir at the end of each entry, e.g.,
|
||||
.Dl SITES = ${SITE_GNU:=cgicc/}
|
||||
.It Ev SITES
|
||||
List of primary locations from which distribution files and patchfiles are
|
||||
retrieved.
|
||||
See the
|
||||
.Cm fetch
|
||||
target for details.
|
||||
Defaults to ${SITES_GITHUB} for GitHub-hosted projects,
|
||||
see
|
||||
.Ev GH_* .
|
||||
See
|
||||
.Xr ports 7
|
||||
for user configuration.
|
||||
.It Ev SITES*
|
||||
List of alternate locations from which ${DISTFILES*}, ${PATCHFILES*},
|
||||
${SUPDISTFILES*} are retrieved.
|
||||
See
|
||||
.Cm fetch
|
||||
for details.
|
||||
Suffix should start with
|
||||
.Sq \&.
|
||||
for consistency.
|
||||
.Pp
|
||||
.It Ev SITES0 , ... , SITES9
|
||||
Supplementary locations from which distribution files and patchfiles are
|
||||
retrieved (deprecated).
|
||||
.It Ev SKIPDIR
|
||||
See
|
||||
.Xr ports 7 .
|
||||
|
@ -3329,13 +3410,6 @@ when using
|
|||
.Ev DIST_TUPLE .
|
||||
Very similar to
|
||||
.Ev TEMPLATE_DISTFILES.<name> .
|
||||
.It Ev TEMPLATES
|
||||
Base location for the templates used in the
|
||||
.Cm readmes
|
||||
target.
|
||||
User settings.
|
||||
Defaults to
|
||||
.Pa ${PORTSDIR}/infrastructure/templates .
|
||||
.It Ev TEST_DEPENDS
|
||||
See
|
||||
.Ev BUILD_DEPENDS
|
||||
|
@ -3592,7 +3666,8 @@ Subdirectory of ${WRKDIR} where the actual source is.
|
|||
Base for configuration (default: ${WRKDIST}).
|
||||
Note that WRKSRC may be a symbolic link, if set to ${WRKDIR}.
|
||||
.It Ev WRKINST
|
||||
Subdirectory of ${WRKDIR} where port normally installs (see the
|
||||
Subdirectory of ${WRKDIR} used as a staging area for installing the port.
|
||||
(See
|
||||
.Cm fake
|
||||
target).
|
||||
.It Ev WRKOBJDIR
|
||||
|
@ -3640,14 +3715,16 @@ Set to bison if needed.
|
|||
.Sh THE FAKE FRAMEWORK
|
||||
The
|
||||
.Cm fake
|
||||
target is used to install the port in a private directory first, ready for
|
||||
target is used to install the port under a staging directory first, ready for
|
||||
packaging by the
|
||||
.Cm package
|
||||
target, so that the actual installation will use the package.
|
||||
target, so that the actual
|
||||
.Cm install
|
||||
target will use the binary package instead.
|
||||
.Pp
|
||||
Essentially,
|
||||
.Cm fake
|
||||
invokes a real install process after tweaking a few variables.
|
||||
invokes the install process after tweaking a few variables.
|
||||
.Pp
|
||||
.Cm fake
|
||||
first creates a skeleton tree under ${WRKINST}, using
|
||||
|
@ -3660,6 +3737,10 @@ target may be used to complete that skeleton tree.
|
|||
For instance, a few ports may need supplementary stuff to be present (as
|
||||
it would be installed if the port's dependencies were present).
|
||||
.Pp
|
||||
In most cases,
|
||||
.Cm pre-install
|
||||
is preferred.
|
||||
.Pp
|
||||
If
|
||||
.Cm {pre,do,post}-install
|
||||
overrides are present, they are used with some
|
||||
|
@ -4390,7 +4471,7 @@ resulting in a double inclusion.
|
|||
This would lead to weird results, such as
|
||||
.Ev PKG_ARGS
|
||||
being defined twice.
|
||||
.It "Fatal: MASTER_SITES* is not defined but referenced by <file> in <DISTFILES*/PATCHFILES*/SUPDISTFILES*>"
|
||||
.It "Fatal: SITES* is not defined but referenced by <file> in <DISTFILES*/PATCHFILES*/SUPDISTFILES*>"
|
||||
Pretty much self-explanatory.
|
||||
.It "Fatal: SUBPACKAGES should always begin with -: <offending list>"
|
||||
That is the only way to differentiate between
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: vmm_machdep.c,v 1.6 2023/09/03 09:30:43 mlarkin Exp $ */
|
||||
/* $OpenBSD: vmm_machdep.c,v 1.7 2023/09/05 14:00:40 mlarkin Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2014 Mike Larkin <mlarkin@openbsd.org>
|
||||
*
|
||||
|
@ -6319,7 +6319,7 @@ vmm_handle_cpuid(struct vcpu *vcpu)
|
|||
*rax = eax;
|
||||
*rbx = ebx;
|
||||
*rcx = ecx;
|
||||
*rdx = edx & VMM_APMI_EDX_MASK;
|
||||
*rdx = edx & VMM_APMI_EDX_INCLUDE_MASK;
|
||||
break;
|
||||
case 0x80000008: /* Phys bits info and topology (AMD) */
|
||||
*rax = eax;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: vmmvar.h,v 1.92 2023/09/03 09:30:43 mlarkin Exp $ */
|
||||
/* $OpenBSD: vmmvar.h,v 1.93 2023/09/05 14:00:41 mlarkin Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2014 Mike Larkin <mlarkin@openbsd.org>
|
||||
*
|
||||
|
@ -559,7 +559,9 @@ struct vm_mprotect_ept_params {
|
|||
CPUIDEBX_STIBP | CPUIDEBX_IBRS_ALWAYSON | CPUIDEBX_STIBP_ALWAYSON | \
|
||||
CPUIDEBX_IBRS_PREF | CPUIDEBX_SSBD | CPUIDEBX_VIRT_SSBD | \
|
||||
CPUIDEBX_SSBD_NOTREQ)
|
||||
#define VMM_APMI_EDX_MASK ~(CPUIDEDX_HWPSTATE)
|
||||
|
||||
/* This mask is an include list for bits we want to expose */
|
||||
#define VMM_APMI_EDX_INCLUDE_MASK (CPUIDEDX_ITSC)
|
||||
|
||||
/*
|
||||
* SEFF flags - copy from host minus:
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: apldc.c,v 1.9 2023/07/03 15:54:07 tobhe Exp $ */
|
||||
/* $OpenBSD: apldc.c,v 1.10 2023/09/05 11:04:06 tobhe Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2022 Mark Kettenis <kettenis@openbsd.org>
|
||||
*
|
||||
|
@ -575,17 +575,22 @@ apldchidev_handle_gpio_req(struct apldchidev_softc *sc, uint8_t iface,
|
|||
if (sc->sc_ngpios >= APLDCHIDEV_NUM_GPIOS)
|
||||
return;
|
||||
|
||||
node = sc->sc_node;
|
||||
snprintf(name, sizeof(name), "apple,%s-gpios", req->name);
|
||||
len = OF_getproplen(node, name);
|
||||
if (len <= 0 || len > sizeof(gpio)) {
|
||||
/* XXX: older device trees store gpios in sub-nodes */
|
||||
if (iface == sc->sc_iface_mt)
|
||||
node = OF_getnodebyname(sc->sc_node, "multi-touch");
|
||||
else if (iface == sc->sc_iface_stm)
|
||||
node = OF_getnodebyname(sc->sc_node, "stm");
|
||||
if (node == -1)
|
||||
return;
|
||||
|
||||
snprintf(name, sizeof(name), "apple,%s-gpios", req->name);
|
||||
len = OF_getproplen(node, name);
|
||||
if (len <= 0 || len > sizeof(gpio))
|
||||
return;
|
||||
}
|
||||
|
||||
OF_getpropintarray(node, name, gpio, len);
|
||||
gpio_controller_config_pin(gpio, GPIO_CONFIG_OUTPUT);
|
||||
gpio_controller_set_pin(gpio, 0);
|
||||
|
|
|
@ -31,7 +31,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
***************************************************************************/
|
||||
|
||||
/* $OpenBSD: if_em.c,v 1.365 2023/02/09 21:21:27 naddy Exp $ */
|
||||
/* $OpenBSD: if_em.c,v 1.366 2023/09/05 13:06:42 naddy Exp $ */
|
||||
/* $FreeBSD: if_em.c,v 1.46 2004/09/29 18:28:28 mlaier Exp $ */
|
||||
|
||||
#include <dev/pci/if_em.h>
|
||||
|
@ -1474,7 +1474,7 @@ em_iff(struct em_softc *sc)
|
|||
ETHER_NEXT_MULTI(step, enm);
|
||||
}
|
||||
|
||||
em_mc_addr_list_update(&sc->hw, mta, ac->ac_multicnt, 0, 1);
|
||||
em_mc_addr_list_update(&sc->hw, mta, ac->ac_multicnt, 0);
|
||||
}
|
||||
|
||||
E1000_WRITE_REG(&sc->hw, RCTL, reg_rctl);
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
|
||||
*******************************************************************************/
|
||||
|
||||
/* $OpenBSD: if_em_hw.c,v 1.117 2023/04/11 00:45:08 jsg Exp $ */
|
||||
/* $OpenBSD: if_em_hw.c,v 1.118 2023/09/05 13:06:42 naddy Exp $ */
|
||||
/*
|
||||
* if_em_hw.c Shared functions for accessing and configuring the MAC
|
||||
*/
|
||||
|
@ -7884,20 +7884,16 @@ em_init_rx_addrs(struct em_hw *hw)
|
|||
* mc_addr_list - the list of new multicast addresses
|
||||
* mc_addr_count - number of addresses
|
||||
* pad - number of bytes between addresses in the list
|
||||
* rar_used_count - offset where to start adding mc addresses into the RAR's
|
||||
*
|
||||
* The given list replaces any existing list. Clears the last 15 receive
|
||||
* address registers and the multicast table. Uses receive address registers
|
||||
* for the first 15 multicast addresses, and hashes the rest into the
|
||||
* The given list replaces any existing list and hashes the addresses into the
|
||||
* multicast table.
|
||||
*****************************************************************************/
|
||||
void
|
||||
em_mc_addr_list_update(struct em_hw *hw, uint8_t *mc_addr_list,
|
||||
uint32_t mc_addr_count, uint32_t pad, uint32_t rar_used_count)
|
||||
uint32_t mc_addr_count, uint32_t pad)
|
||||
{
|
||||
uint32_t hash_value;
|
||||
uint32_t i;
|
||||
uint32_t num_rar_entry;
|
||||
uint32_t num_mta_entry;
|
||||
DEBUGFUNC("em_mc_addr_list_update");
|
||||
/*
|
||||
|
@ -7906,28 +7902,6 @@ em_mc_addr_list_update(struct em_hw *hw, uint8_t *mc_addr_list,
|
|||
*/
|
||||
hw->num_mc_addrs = mc_addr_count;
|
||||
|
||||
/* Clear RAR[1-15] */
|
||||
DEBUGOUT(" Clearing RAR[1-15]\n");
|
||||
num_rar_entry = E1000_RAR_ENTRIES;
|
||||
if (IS_ICH8(hw->mac_type))
|
||||
num_rar_entry = E1000_RAR_ENTRIES_ICH8LAN;
|
||||
if (hw->mac_type == em_ich8lan)
|
||||
num_rar_entry -= 1;
|
||||
/*
|
||||
* Reserve a spot for the Locally Administered Address to work around
|
||||
* an 82571 issue in which a reset on one port will reload the MAC on
|
||||
* the other port.
|
||||
*/
|
||||
if ((hw->mac_type == em_82571) && (hw->laa_is_present == TRUE))
|
||||
num_rar_entry -= 1;
|
||||
|
||||
for (i = rar_used_count; i < num_rar_entry; i++) {
|
||||
E1000_WRITE_REG_ARRAY(hw, RA, (i << 1), 0);
|
||||
E1000_WRITE_FLUSH(hw);
|
||||
E1000_WRITE_REG_ARRAY(hw, RA, ((i << 1) + 1), 0);
|
||||
E1000_WRITE_FLUSH(hw);
|
||||
}
|
||||
|
||||
/* Clear the MTA */
|
||||
DEBUGOUT(" Clearing MTA\n");
|
||||
num_mta_entry = E1000_NUM_MTA_REGISTERS;
|
||||
|
@ -7954,19 +7928,8 @@ em_mc_addr_list_update(struct em_hw *hw, uint8_t *mc_addr_list,
|
|||
(i * (ETH_LENGTH_OF_ADDRESS + pad)));
|
||||
|
||||
DEBUGOUT1(" Hash value = 0x%03X\n", hash_value);
|
||||
/*
|
||||
* Place this multicast address in the RAR if there is room, *
|
||||
* else put it in the MTA
|
||||
*/
|
||||
if (rar_used_count < num_rar_entry) {
|
||||
em_rar_set(hw, mc_addr_list +
|
||||
(i * (ETH_LENGTH_OF_ADDRESS + pad)),
|
||||
rar_used_count);
|
||||
rar_used_count++;
|
||||
} else {
|
||||
em_mta_set(hw, hash_value);
|
||||
}
|
||||
}
|
||||
DEBUGOUT("MC Update Complete\n");
|
||||
}
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
|
||||
*******************************************************************************/
|
||||
|
||||
/* $OpenBSD: if_em_hw.h,v 1.88 2022/11/06 18:17:56 mbuhl Exp $ */
|
||||
/* $OpenBSD: if_em_hw.h,v 1.89 2023/09/05 13:06:43 naddy Exp $ */
|
||||
/* $FreeBSD: if_em_hw.h,v 1.15 2005/05/26 23:32:02 tackerman Exp $ */
|
||||
|
||||
/* if_em_hw.h
|
||||
|
@ -428,7 +428,7 @@ boolean_t em_get_flash_presence_i210(struct em_hw *);
|
|||
|
||||
/* Filters (multicast, vlan, receive) */
|
||||
void em_mc_addr_list_update(struct em_hw *hw, uint8_t * mc_addr_list, uint32_t mc_addr_count,
|
||||
uint32_t pad, uint32_t rar_used_count);
|
||||
uint32_t pad);
|
||||
uint32_t em_hash_mc_addr(struct em_hw *hw, uint8_t *mc_addr);
|
||||
void em_mta_set(struct em_hw *hw, uint32_t hash_value);
|
||||
void em_rar_set(struct em_hw *hw, uint8_t *mc_addr, uint32_t rar_index);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: ksmn.c,v 1.8 2023/06/23 03:47:10 mlarkin Exp $ */
|
||||
/* $OpenBSD: ksmn.c,v 1.9 2023/09/05 13:06:01 stsp Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2019 Bryan Steele <brynet@openbsd.org>
|
||||
|
@ -105,6 +105,7 @@ static const struct pci_matchid ksmn_devices[] = {
|
|||
{ PCI_VENDOR_AMD, PCI_PRODUCT_AMD_17_1X_RC },
|
||||
{ PCI_VENDOR_AMD, PCI_PRODUCT_AMD_17_3X_RC },
|
||||
{ PCI_VENDOR_AMD, PCI_PRODUCT_AMD_17_6X_RC },
|
||||
{ PCI_VENDOR_AMD, PCI_PRODUCT_AMD_19_4X_RC },
|
||||
{ PCI_VENDOR_AMD, PCI_PRODUCT_AMD_19_6X_RC },
|
||||
};
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue