sync with OpenBSD -current
This commit is contained in:
parent
9b453b8087
commit
d592c28c93
298 changed files with 9365 additions and 4443 deletions
|
@ -30,6 +30,60 @@
|
||||||
!! THANK YOU! Sebastian Pipping -- Berlin, 2024-03-09 !!
|
!! THANK YOU! Sebastian Pipping -- Berlin, 2024-03-09 !!
|
||||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||||
|
|
||||||
|
Release 2.6.3 Wed September 4 2024
|
||||||
|
Security fixes:
|
||||||
|
#887 #890 CVE-2024-45490 -- Calling function XML_ParseBuffer with
|
||||||
|
len < 0 without noticing and then calling XML_GetBuffer
|
||||||
|
will have XML_ParseBuffer fail to recognize the problem
|
||||||
|
and XML_GetBuffer corrupt memory.
|
||||||
|
With the fix, XML_ParseBuffer now complains with error
|
||||||
|
XML_ERROR_INVALID_ARGUMENT just like sibling XML_Parse
|
||||||
|
has been doing since Expat 2.2.1, and now documented.
|
||||||
|
Impact is denial of service to potentially artitrary code
|
||||||
|
execution.
|
||||||
|
#888 #891 CVE-2024-45491 -- Internal function dtdCopy can have an
|
||||||
|
integer overflow for nDefaultAtts on 32-bit platforms
|
||||||
|
(where UINT_MAX equals SIZE_MAX).
|
||||||
|
Impact is denial of service to potentially artitrary code
|
||||||
|
execution.
|
||||||
|
#889 #892 CVE-2024-45492 -- Internal function nextScaffoldPart can
|
||||||
|
have an integer overflow for m_groupSize on 32-bit
|
||||||
|
platforms (where UINT_MAX equals SIZE_MAX).
|
||||||
|
Impact is denial of service to potentially artitrary code
|
||||||
|
execution.
|
||||||
|
|
||||||
|
Other changes:
|
||||||
|
#851 #879 Autotools: Sync CMake templates with CMake 3.28
|
||||||
|
#853 Autotools: Always provide path to find(1) for portability
|
||||||
|
#861 Autotools: Ensure that the m4 directory always exists.
|
||||||
|
#870 Autotools: Simplify handling of SIZEOF_VOID_P
|
||||||
|
#869 Autotools: Support non-GNU sed
|
||||||
|
#856 Autotools|CMake: Fix main() to main(void)
|
||||||
|
#865 Autotools|CMake: Fix compile tests for HAVE_SYSCALL_GETRANDOM
|
||||||
|
#863 Autotools|CMake: Stop requiring dos2unix
|
||||||
|
#854 #855 CMake: Fix check for symbols size_t and off_t
|
||||||
|
#864 docs|tests: Convert README to Markdown and update
|
||||||
|
#741 Windows: Drop support for Visual Studio <=15.0/2017
|
||||||
|
#886 Drop needless XML_DTD guards around is_param access
|
||||||
|
#885 Fix typo in a code comment
|
||||||
|
#894 #896 Version info bumped from 10:2:9 (libexpat*.so.1.9.2)
|
||||||
|
to 10:3:9 (libexpat*.so.1.9.3); see https://verbump.de/
|
||||||
|
for what these numbers do
|
||||||
|
|
||||||
|
Infrastructure:
|
||||||
|
#880 Readme: Promote the call for help
|
||||||
|
#868 CI: Fix various issues
|
||||||
|
#849 CI: Allow triggering GitHub Actions workflows manually
|
||||||
|
#851 #872 ..
|
||||||
|
#873 #879 CI: Adapt to breaking changes in GitHub Actions
|
||||||
|
|
||||||
|
Special thanks to:
|
||||||
|
Alexander Bluhm
|
||||||
|
Berkay Eren Ürün
|
||||||
|
Dag-Erling Smørgrav
|
||||||
|
Ferenc Géczi
|
||||||
|
TaiYou
|
||||||
|
|
||||||
Release 2.6.2 Wed March 13 2024
|
Release 2.6.2 Wed March 13 2024
|
||||||
Security fixes:
|
Security fixes:
|
||||||
#839 #842 CVE-2024-28757 -- Prevent billion laughs attacks with
|
#839 #842 CVE-2024-28757 -- Prevent billion laughs attacks with
|
||||||
|
|
|
@ -4,8 +4,14 @@
|
||||||
[](https://sourceforge.net/projects/expat/files/)
|
[](https://sourceforge.net/projects/expat/files/)
|
||||||
[](https://github.com/libexpat/libexpat/releases)
|
[](https://github.com/libexpat/libexpat/releases)
|
||||||
|
|
||||||
|
> [!CAUTION]
|
||||||
|
>
|
||||||
|
> Expat is **understaffed** and without funding.
|
||||||
|
> There is a [call for help with details](https://github.com/libexpat/libexpat/blob/master/expat/Changes)
|
||||||
|
> at the top of the `Changes` file.
|
||||||
|
|
||||||
# Expat, Release 2.6.2
|
|
||||||
|
# Expat, Release 2.6.3
|
||||||
|
|
||||||
This is Expat, a C99 library for parsing
|
This is Expat, a C99 library for parsing
|
||||||
[XML 1.0 Fourth Edition](https://www.w3.org/TR/2006/REC-xml-20060816/), started by
|
[XML 1.0 Fourth Edition](https://www.w3.org/TR/2006/REC-xml-20060816/), started by
|
||||||
|
@ -20,7 +26,7 @@ Expat supports the following compilers:
|
||||||
|
|
||||||
- GNU GCC >=4.5
|
- GNU GCC >=4.5
|
||||||
- LLVM Clang >=3.5
|
- LLVM Clang >=3.5
|
||||||
- Microsoft Visual Studio >=15.0/2017 (rolling `${today} minus 5 years`)
|
- Microsoft Visual Studio >=16.0/2019 (rolling `${today} minus 5 years`)
|
||||||
|
|
||||||
Windows users can use the
|
Windows users can use the
|
||||||
[`expat-win32bin-*.*.*.{exe,zip}` download](https://github.com/libexpat/libexpat/releases),
|
[`expat-win32bin-*.*.*.{exe,zip}` download](https://github.com/libexpat/libexpat/releases),
|
||||||
|
@ -158,10 +164,10 @@ support this mode of compilation (yet):
|
||||||
|
|
||||||
1. Mass-patch `Makefile.am` files to use `libexpatw.la` for a library name:
|
1. Mass-patch `Makefile.am` files to use `libexpatw.la` for a library name:
|
||||||
<br/>
|
<br/>
|
||||||
`find -name Makefile.am -exec sed
|
`find . -name Makefile.am -exec sed
|
||||||
-e 's,libexpat\.la,libexpatw.la,'
|
-e 's,libexpat\.la,libexpatw.la,'
|
||||||
-e 's,libexpat_la,libexpatw_la,'
|
-e 's,libexpat_la,libexpatw_la,'
|
||||||
-i {} +`
|
-i.bak {} +`
|
||||||
|
|
||||||
1. Run `automake` to re-write `Makefile.in` files:<br/>
|
1. Run `automake` to re-write `Makefile.in` files:<br/>
|
||||||
`automake`
|
`automake`
|
||||||
|
|
|
@ -52,7 +52,7 @@
|
||||||
<div>
|
<div>
|
||||||
<h1>
|
<h1>
|
||||||
The Expat XML Parser
|
The Expat XML Parser
|
||||||
<small>Release 2.6.2</small>
|
<small>Release 2.6.3</small>
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
|
@ -319,7 +319,7 @@ directions in the next section. Otherwise if you have Microsoft's
|
||||||
Developer Studio installed,
|
Developer Studio installed,
|
||||||
you can use CMake to generate a <code>.sln</code> file, e.g.
|
you can use CMake to generate a <code>.sln</code> file, e.g.
|
||||||
<code>
|
<code>
|
||||||
cmake -G"Visual Studio 15 2017" -DCMAKE_BUILD_TYPE=RelWithDebInfo .
|
cmake -G"Visual Studio 16 2019" -DCMAKE_BUILD_TYPE=RelWithDebInfo .
|
||||||
</code>, and build Expat using <code>msbuild /m expat.sln</code> after.</p>
|
</code>, and build Expat using <code>msbuild /m expat.sln</code> after.</p>
|
||||||
|
|
||||||
<p>Alternatively, you may download the Win32 binary package that
|
<p>Alternatively, you may download the Win32 binary package that
|
||||||
|
@ -1135,7 +1135,9 @@ containing part (or perhaps all) of the document. The number of bytes of s
|
||||||
that are part of the document is indicated by <code>len</code>. This means
|
that are part of the document is indicated by <code>len</code>. This means
|
||||||
that <code>s</code> doesn't have to be null-terminated. It also means that
|
that <code>s</code> doesn't have to be null-terminated. It also means that
|
||||||
if <code>len</code> is larger than the number of bytes in the block of
|
if <code>len</code> is larger than the number of bytes in the block of
|
||||||
memory that <code>s</code> points at, then a memory fault is likely. The
|
memory that <code>s</code> points at, then a memory fault is likely.
|
||||||
|
Negative values for <code>len</code> are rejected since Expat 2.2.1.
|
||||||
|
The
|
||||||
<code>isFinal</code> parameter informs the parser that this is the last
|
<code>isFinal</code> parameter informs the parser that this is the last
|
||||||
piece of the document. Frequently, the last piece is empty (i.e.
|
piece of the document. Frequently, the last piece is empty (i.e.
|
||||||
<code>len</code> is zero.)
|
<code>len</code> is zero.)
|
||||||
|
@ -1183,11 +1185,17 @@ XML_ParseBuffer(XML_Parser p,
|
||||||
int isFinal);
|
int isFinal);
|
||||||
</pre>
|
</pre>
|
||||||
<div class="fcndef">
|
<div class="fcndef">
|
||||||
|
<p>
|
||||||
This is just like <code><a href= "#XML_Parse" >XML_Parse</a></code>,
|
This is just like <code><a href= "#XML_Parse" >XML_Parse</a></code>,
|
||||||
except in this case Expat provides the buffer. By obtaining the
|
except in this case Expat provides the buffer. By obtaining the
|
||||||
buffer from Expat with the <code><a href= "#XML_GetBuffer"
|
buffer from Expat with the <code><a href= "#XML_GetBuffer"
|
||||||
>XML_GetBuffer</a></code> function, the application can avoid double
|
>XML_GetBuffer</a></code> function, the application can avoid double
|
||||||
copying of the input.
|
copying of the input.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Negative values for <code>len</code> are rejected since Expat 2.6.3.
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h4 id="XML_GetBuffer">XML_GetBuffer</h4>
|
<h4 id="XML_GetBuffer">XML_GetBuffer</h4>
|
||||||
|
|
|
@ -1066,7 +1066,7 @@ XML_SetReparseDeferralEnabled(XML_Parser parser, XML_Bool enabled);
|
||||||
*/
|
*/
|
||||||
#define XML_MAJOR_VERSION 2
|
#define XML_MAJOR_VERSION 2
|
||||||
#define XML_MINOR_VERSION 6
|
#define XML_MINOR_VERSION 6
|
||||||
#define XML_MICRO_VERSION 2
|
#define XML_MICRO_VERSION 3
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -126,8 +126,7 @@
|
||||||
| ((uint64_t)((p)[4]) << 32) | ((uint64_t)((p)[5]) << 40) \
|
| ((uint64_t)((p)[4]) << 32) | ((uint64_t)((p)[5]) << 40) \
|
||||||
| ((uint64_t)((p)[6]) << 48) | ((uint64_t)((p)[7]) << 56))
|
| ((uint64_t)((p)[6]) << 48) | ((uint64_t)((p)[7]) << 56))
|
||||||
|
|
||||||
#define SIPHASH_INITIALIZER \
|
#define SIPHASH_INITIALIZER {0, 0, 0, 0, {0}, 0, 0}
|
||||||
{ 0, 0, 0, 0, {0}, 0, 0 }
|
|
||||||
|
|
||||||
struct siphash {
|
struct siphash {
|
||||||
uint64_t v0, v1, v2, v3;
|
uint64_t v0, v1, v2, v3;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* 2a14271ad4d35e82bde8ba210b4edb7998794bcbae54deab114046a300f9639a (2.6.2+)
|
/* ba4cdf9bdb534f355a9def4c9e25d20ee8e72f95b0a4d930be52e563f5080196 (2.6.3+)
|
||||||
__ __ _
|
__ __ _
|
||||||
___\ \/ /_ __ __ _| |_
|
___\ \/ /_ __ __ _| |_
|
||||||
/ _ \\ /| '_ \ / _` | __|
|
/ _ \\ /| '_ \ / _` | __|
|
||||||
|
@ -39,6 +39,7 @@
|
||||||
Copyright (c) 2022 Sean McBride <sean@rogue-research.com>
|
Copyright (c) 2022 Sean McBride <sean@rogue-research.com>
|
||||||
Copyright (c) 2023 Owain Davies <owaind@bath.edu>
|
Copyright (c) 2023 Owain Davies <owaind@bath.edu>
|
||||||
Copyright (c) 2023-2024 Sony Corporation / Snild Dolkow <snild@sony.com>
|
Copyright (c) 2023-2024 Sony Corporation / Snild Dolkow <snild@sony.com>
|
||||||
|
Copyright (c) 2024 Berkay Eren Ürün <berkay.ueruen@siemens.com>
|
||||||
Licensed under the MIT license:
|
Licensed under the MIT license:
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
@ -294,7 +295,7 @@ typedef struct {
|
||||||
The name of the element is stored in both the document and API
|
The name of the element is stored in both the document and API
|
||||||
encodings. The memory buffer 'buf' is a separately-allocated
|
encodings. The memory buffer 'buf' is a separately-allocated
|
||||||
memory area which stores the name. During the XML_Parse()/
|
memory area which stores the name. During the XML_Parse()/
|
||||||
XMLParseBuffer() when the element is open, the memory for the 'raw'
|
XML_ParseBuffer() when the element is open, the memory for the 'raw'
|
||||||
version of the name (in the document encoding) is shared with the
|
version of the name (in the document encoding) is shared with the
|
||||||
document buffer. If the element is open across calls to
|
document buffer. If the element is open across calls to
|
||||||
XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to
|
XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to
|
||||||
|
@ -2038,6 +2039,12 @@ XML_ParseBuffer(XML_Parser parser, int len, int isFinal) {
|
||||||
|
|
||||||
if (parser == NULL)
|
if (parser == NULL)
|
||||||
return XML_STATUS_ERROR;
|
return XML_STATUS_ERROR;
|
||||||
|
|
||||||
|
if (len < 0) {
|
||||||
|
parser->m_errorCode = XML_ERROR_INVALID_ARGUMENT;
|
||||||
|
return XML_STATUS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
switch (parser->m_parsingStatus.parsing) {
|
switch (parser->m_parsingStatus.parsing) {
|
||||||
case XML_SUSPENDED:
|
case XML_SUSPENDED:
|
||||||
parser->m_errorCode = XML_ERROR_SUSPENDED;
|
parser->m_errorCode = XML_ERROR_SUSPENDED;
|
||||||
|
@ -5846,18 +5853,17 @@ processInternalEntity(XML_Parser parser, ENTITY *entity, XML_Bool betweenDecl) {
|
||||||
/* Set a safe default value in case 'next' does not get set */
|
/* Set a safe default value in case 'next' does not get set */
|
||||||
next = textStart;
|
next = textStart;
|
||||||
|
|
||||||
#ifdef XML_DTD
|
|
||||||
if (entity->is_param) {
|
if (entity->is_param) {
|
||||||
int tok
|
int tok
|
||||||
= XmlPrologTok(parser->m_internalEncoding, textStart, textEnd, &next);
|
= XmlPrologTok(parser->m_internalEncoding, textStart, textEnd, &next);
|
||||||
result = doProlog(parser, parser->m_internalEncoding, textStart, textEnd,
|
result = doProlog(parser, parser->m_internalEncoding, textStart, textEnd,
|
||||||
tok, next, &next, XML_FALSE, XML_FALSE,
|
tok, next, &next, XML_FALSE, XML_FALSE,
|
||||||
XML_ACCOUNT_ENTITY_EXPANSION);
|
XML_ACCOUNT_ENTITY_EXPANSION);
|
||||||
} else
|
} else {
|
||||||
#endif /* XML_DTD */
|
|
||||||
result = doContent(parser, parser->m_tagLevel, parser->m_internalEncoding,
|
result = doContent(parser, parser->m_tagLevel, parser->m_internalEncoding,
|
||||||
textStart, textEnd, &next, XML_FALSE,
|
textStart, textEnd, &next, XML_FALSE,
|
||||||
XML_ACCOUNT_ENTITY_EXPANSION);
|
XML_ACCOUNT_ENTITY_EXPANSION);
|
||||||
|
}
|
||||||
|
|
||||||
if (result == XML_ERROR_NONE) {
|
if (result == XML_ERROR_NONE) {
|
||||||
if (textEnd != next && parser->m_parsingStatus.parsing == XML_SUSPENDED) {
|
if (textEnd != next && parser->m_parsingStatus.parsing == XML_SUSPENDED) {
|
||||||
|
@ -5894,18 +5900,17 @@ internalEntityProcessor(XML_Parser parser, const char *s, const char *end,
|
||||||
/* Set a safe default value in case 'next' does not get set */
|
/* Set a safe default value in case 'next' does not get set */
|
||||||
next = textStart;
|
next = textStart;
|
||||||
|
|
||||||
#ifdef XML_DTD
|
|
||||||
if (entity->is_param) {
|
if (entity->is_param) {
|
||||||
int tok
|
int tok
|
||||||
= XmlPrologTok(parser->m_internalEncoding, textStart, textEnd, &next);
|
= XmlPrologTok(parser->m_internalEncoding, textStart, textEnd, &next);
|
||||||
result = doProlog(parser, parser->m_internalEncoding, textStart, textEnd,
|
result = doProlog(parser, parser->m_internalEncoding, textStart, textEnd,
|
||||||
tok, next, &next, XML_FALSE, XML_TRUE,
|
tok, next, &next, XML_FALSE, XML_TRUE,
|
||||||
XML_ACCOUNT_ENTITY_EXPANSION);
|
XML_ACCOUNT_ENTITY_EXPANSION);
|
||||||
} else
|
} else {
|
||||||
#endif /* XML_DTD */
|
|
||||||
result = doContent(parser, openEntity->startTagLevel,
|
result = doContent(parser, openEntity->startTagLevel,
|
||||||
parser->m_internalEncoding, textStart, textEnd, &next,
|
parser->m_internalEncoding, textStart, textEnd, &next,
|
||||||
XML_FALSE, XML_ACCOUNT_ENTITY_EXPANSION);
|
XML_FALSE, XML_ACCOUNT_ENTITY_EXPANSION);
|
||||||
|
}
|
||||||
|
|
||||||
if (result != XML_ERROR_NONE)
|
if (result != XML_ERROR_NONE)
|
||||||
return result;
|
return result;
|
||||||
|
@ -5932,7 +5937,6 @@ internalEntityProcessor(XML_Parser parser, const char *s, const char *end,
|
||||||
return XML_ERROR_NONE;
|
return XML_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef XML_DTD
|
|
||||||
if (entity->is_param) {
|
if (entity->is_param) {
|
||||||
int tok;
|
int tok;
|
||||||
parser->m_processor = prologProcessor;
|
parser->m_processor = prologProcessor;
|
||||||
|
@ -5940,9 +5944,7 @@ internalEntityProcessor(XML_Parser parser, const char *s, const char *end,
|
||||||
return doProlog(parser, parser->m_encoding, s, end, tok, next, nextPtr,
|
return doProlog(parser, parser->m_encoding, s, end, tok, next, nextPtr,
|
||||||
(XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE,
|
(XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE,
|
||||||
XML_ACCOUNT_DIRECT);
|
XML_ACCOUNT_DIRECT);
|
||||||
} else
|
} else {
|
||||||
#endif /* XML_DTD */
|
|
||||||
{
|
|
||||||
parser->m_processor = contentProcessor;
|
parser->m_processor = contentProcessor;
|
||||||
/* see externalEntityContentProcessor vs contentProcessor */
|
/* see externalEntityContentProcessor vs contentProcessor */
|
||||||
result = doContent(parser, parser->m_parentParser ? 1 : 0,
|
result = doContent(parser, parser->m_parentParser ? 1 : 0,
|
||||||
|
@ -7016,6 +7018,16 @@ dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd,
|
||||||
if (! newE)
|
if (! newE)
|
||||||
return 0;
|
return 0;
|
||||||
if (oldE->nDefaultAtts) {
|
if (oldE->nDefaultAtts) {
|
||||||
|
/* Detect and prevent integer overflow.
|
||||||
|
* The preprocessor guard addresses the "always false" warning
|
||||||
|
* from -Wtype-limits on platforms where
|
||||||
|
* sizeof(int) < sizeof(size_t), e.g. on x86_64. */
|
||||||
|
#if UINT_MAX >= SIZE_MAX
|
||||||
|
if ((size_t)oldE->nDefaultAtts
|
||||||
|
> ((size_t)(-1) / sizeof(DEFAULT_ATTRIBUTE))) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
newE->defaultAtts
|
newE->defaultAtts
|
||||||
= ms->malloc_fcn(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
|
= ms->malloc_fcn(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
|
||||||
if (! newE->defaultAtts) {
|
if (! newE->defaultAtts) {
|
||||||
|
@ -7558,6 +7570,15 @@ nextScaffoldPart(XML_Parser parser) {
|
||||||
int next;
|
int next;
|
||||||
|
|
||||||
if (! dtd->scaffIndex) {
|
if (! dtd->scaffIndex) {
|
||||||
|
/* Detect and prevent integer overflow.
|
||||||
|
* The preprocessor guard addresses the "always false" warning
|
||||||
|
* from -Wtype-limits on platforms where
|
||||||
|
* sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */
|
||||||
|
#if UINT_MAX >= SIZE_MAX
|
||||||
|
if (parser->m_groupSize > ((size_t)(-1) / sizeof(int))) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
dtd->scaffIndex = (int *)MALLOC(parser, parser->m_groupSize * sizeof(int));
|
dtd->scaffIndex = (int *)MALLOC(parser, parser->m_groupSize * sizeof(int));
|
||||||
if (! dtd->scaffIndex)
|
if (! dtd->scaffIndex)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -2804,6 +2804,61 @@ START_TEST(test_empty_parse) {
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
|
/* Test XML_Parse for len < 0 */
|
||||||
|
START_TEST(test_negative_len_parse) {
|
||||||
|
const char *const doc = "<root/>";
|
||||||
|
for (int isFinal = 0; isFinal < 2; isFinal++) {
|
||||||
|
set_subtest("isFinal=%d", isFinal);
|
||||||
|
|
||||||
|
XML_Parser parser = XML_ParserCreate(NULL);
|
||||||
|
|
||||||
|
if (XML_GetErrorCode(parser) != XML_ERROR_NONE)
|
||||||
|
fail("There was not supposed to be any initial parse error.");
|
||||||
|
|
||||||
|
const enum XML_Status status = XML_Parse(parser, doc, -1, isFinal);
|
||||||
|
|
||||||
|
if (status != XML_STATUS_ERROR)
|
||||||
|
fail("Negative len was expected to fail the parse but did not.");
|
||||||
|
|
||||||
|
if (XML_GetErrorCode(parser) != XML_ERROR_INVALID_ARGUMENT)
|
||||||
|
fail("Parse error does not match XML_ERROR_INVALID_ARGUMENT.");
|
||||||
|
|
||||||
|
XML_ParserFree(parser);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
/* Test XML_ParseBuffer for len < 0 */
|
||||||
|
START_TEST(test_negative_len_parse_buffer) {
|
||||||
|
const char *const doc = "<root/>";
|
||||||
|
for (int isFinal = 0; isFinal < 2; isFinal++) {
|
||||||
|
set_subtest("isFinal=%d", isFinal);
|
||||||
|
|
||||||
|
XML_Parser parser = XML_ParserCreate(NULL);
|
||||||
|
|
||||||
|
if (XML_GetErrorCode(parser) != XML_ERROR_NONE)
|
||||||
|
fail("There was not supposed to be any initial parse error.");
|
||||||
|
|
||||||
|
void *const buffer = XML_GetBuffer(parser, (int)strlen(doc));
|
||||||
|
|
||||||
|
if (buffer == NULL)
|
||||||
|
fail("XML_GetBuffer failed.");
|
||||||
|
|
||||||
|
memcpy(buffer, doc, strlen(doc));
|
||||||
|
|
||||||
|
const enum XML_Status status = XML_ParseBuffer(parser, -1, isFinal);
|
||||||
|
|
||||||
|
if (status != XML_STATUS_ERROR)
|
||||||
|
fail("Negative len was expected to fail the parse but did not.");
|
||||||
|
|
||||||
|
if (XML_GetErrorCode(parser) != XML_ERROR_INVALID_ARGUMENT)
|
||||||
|
fail("Parse error does not match XML_ERROR_INVALID_ARGUMENT.");
|
||||||
|
|
||||||
|
XML_ParserFree(parser);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
/* Test odd corners of the XML_GetBuffer interface */
|
/* Test odd corners of the XML_GetBuffer interface */
|
||||||
static enum XML_Status
|
static enum XML_Status
|
||||||
get_feature(enum XML_FeatureEnum feature_id, long *presult) {
|
get_feature(enum XML_FeatureEnum feature_id, long *presult) {
|
||||||
|
@ -5959,6 +6014,8 @@ make_basic_test_case(Suite *s) {
|
||||||
tcase_add_test__ifdef_xml_dtd(tc_basic, test_user_parameters);
|
tcase_add_test__ifdef_xml_dtd(tc_basic, test_user_parameters);
|
||||||
tcase_add_test__ifdef_xml_dtd(tc_basic, test_ext_entity_ref_parameter);
|
tcase_add_test__ifdef_xml_dtd(tc_basic, test_ext_entity_ref_parameter);
|
||||||
tcase_add_test(tc_basic, test_empty_parse);
|
tcase_add_test(tc_basic, test_empty_parse);
|
||||||
|
tcase_add_test(tc_basic, test_negative_len_parse);
|
||||||
|
tcase_add_test(tc_basic, test_negative_len_parse_buffer);
|
||||||
tcase_add_test(tc_basic, test_get_buffer_1);
|
tcase_add_test(tc_basic, test_get_buffer_1);
|
||||||
tcase_add_test(tc_basic, test_get_buffer_2);
|
tcase_add_test(tc_basic, test_get_buffer_2);
|
||||||
#if XML_CONTEXT_BYTES > 0
|
#if XML_CONTEXT_BYTES > 0
|
||||||
|
|
|
@ -208,7 +208,7 @@ START_TEST(test_misc_version) {
|
||||||
if (! versions_equal(&read_version, &parsed_version))
|
if (! versions_equal(&read_version, &parsed_version))
|
||||||
fail("Version mismatch");
|
fail("Version mismatch");
|
||||||
|
|
||||||
if (xcstrcmp(version_text, XCS("expat_2.6.2"))) /* needs bump on releases */
|
if (xcstrcmp(version_text, XCS("expat_2.6.3"))) /* needs bump on releases */
|
||||||
fail("XML_*_VERSION in expat.h out of sync?\n");
|
fail("XML_*_VERSION in expat.h out of sync?\n");
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
|
@ -960,7 +960,7 @@ int ZEXPORT inflate(z_streamp strm, int flush) {
|
||||||
while (state->have < 19)
|
while (state->have < 19)
|
||||||
state->lens[order[state->have++]] = 0;
|
state->lens[order[state->have++]] = 0;
|
||||||
state->next = state->codes;
|
state->next = state->codes;
|
||||||
state->lencode = (const code FAR *)(state->next);
|
state->lencode = state->distcode = (const code FAR *)(state->next);
|
||||||
state->lenbits = 7;
|
state->lenbits = 7;
|
||||||
ret = inflate_table(CODES, state->lens, 19, &(state->next),
|
ret = inflate_table(CODES, state->lens, 19, &(state->next),
|
||||||
&(state->lenbits), state->work);
|
&(state->lenbits), state->work);
|
||||||
|
|
|
@ -1,12 +1,8 @@
|
||||||
# $OpenBSD: Makefile,v 1.12 2022/10/14 17:09:43 tb Exp $
|
# $OpenBSD: Makefile,v 1.14 2024/09/04 04:35:30 tb Exp $
|
||||||
|
|
||||||
SUBDIR += libressl
|
SUBDIR += libressl
|
||||||
.if exists(/usr/local/bin/eopenssl11)
|
.if exists(/usr/local/bin/eopenssl32)
|
||||||
SUBDIR += openssl11
|
SUBDIR += openssl
|
||||||
.else
|
|
||||||
.END:
|
|
||||||
@echo 'Run "pkg_add openssl--%1.1" to run tests against OpenSSL 1.1'
|
|
||||||
@echo SKIPPED
|
|
||||||
.endif
|
.endif
|
||||||
|
|
||||||
.include <bsd.subdir.mk>
|
.include <bsd.subdir.mk>
|
||||||
|
|
10
regress/usr.sbin/rpki-client/openssl/Makefile
Normal file
10
regress/usr.sbin/rpki-client/openssl/Makefile
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
# $OpenBSD: Makefile,v 1.1 2024/09/04 04:34:14 tb Exp $
|
||||||
|
|
||||||
|
EOPENSSL = eopenssl32
|
||||||
|
|
||||||
|
LDADD += -Wl,-rpath,/usr/local/lib/${EOPENSSL} -L/usr/local/lib/${EOPENSSL}
|
||||||
|
CFLAGS += -I${.CURDIR}/ -I/usr/local/include/${EOPENSSL}/
|
||||||
|
|
||||||
|
.PATH: ${.CURDIR}/..
|
||||||
|
|
||||||
|
.include <bsd.regress.mk>
|
29
regress/usr.sbin/rpki-client/openssl/unistd.h
Normal file
29
regress/usr.sbin/rpki-client/openssl/unistd.h
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
/* $OpenBSD: unistd.h,v 1.2 2024/09/04 07:52:45 tb Exp $ */
|
||||||
|
/*
|
||||||
|
* Public domain
|
||||||
|
* compatibility shim for OpenSSL 3
|
||||||
|
* overloading unistd.h is a ugly guly hack for this issue but works here
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include_next <unistd.h>
|
||||||
|
|
||||||
|
#include <openssl/cms.h>
|
||||||
|
#include <openssl/stack.h>
|
||||||
|
|
||||||
|
#ifndef DECLARE_STACK_OF
|
||||||
|
#define DECLARE_STACK_OF DEFINE_STACK_OF
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
CMS_get_version(CMS_ContentInfo *cms, long *version)
|
||||||
|
{
|
||||||
|
*version = 3;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
CMS_SignerInfo_get_version(CMS_SignerInfo *si, long *version)
|
||||||
|
{
|
||||||
|
*version = 3;
|
||||||
|
return 1;
|
||||||
|
}
|
|
@ -1,8 +0,0 @@
|
||||||
# $OpenBSD: Makefile,v 1.18 2023/05/22 15:20:16 tb Exp $
|
|
||||||
|
|
||||||
LDADD += -Wl,-rpath,/usr/local/lib/eopenssl11 -L/usr/local/lib/eopenssl11
|
|
||||||
CFLAGS += -I${.CURDIR}/ -I/usr/local/include/eopenssl11/
|
|
||||||
|
|
||||||
.PATH: ${.CURDIR}/..
|
|
||||||
|
|
||||||
.include <bsd.regress.mk>
|
|
|
@ -1,16 +0,0 @@
|
||||||
/*
|
|
||||||
* Public domain
|
|
||||||
* compatibility shim for openssl11
|
|
||||||
* overloading unistd.h is a ugly guly hack for this issue but works here
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include_next <unistd.h>
|
|
||||||
|
|
||||||
#include <openssl/stack.h>
|
|
||||||
|
|
||||||
#define CMS_get_version(cms, version) (*(version) = 3, 1)
|
|
||||||
#define CMS_SignerInfo_get_version(si, version) (*(version) = 3, 1)
|
|
||||||
|
|
||||||
#ifndef DECLARE_STACK_OF
|
|
||||||
#define DECLARE_STACK_OF DEFINE_STACK_OF
|
|
||||||
#endif
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $OpenBSD: frontend.c,v 1.82 2024/08/09 19:43:26 florian Exp $ */
|
/* $OpenBSD: frontend.c,v 1.83 2024/09/05 08:22:46 florian Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 Florian Obser <florian@openbsd.org>
|
* 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,
|
rcode = parse_edns_from_query_pkt(pq->qbuf, &pq->edns, NULL, NULL,
|
||||||
NULL, 0, pq->region);
|
NULL, 0, pq->region, NULL);
|
||||||
if (rcode != LDNS_RCODE_NOERROR) {
|
if (rcode != LDNS_RCODE_NOERROR) {
|
||||||
error_answer(pq, rcode);
|
error_answer(pq, rcode);
|
||||||
goto send_answer;
|
goto send_answer;
|
||||||
|
@ -1059,7 +1059,7 @@ resend_dns64_query(struct pending_query *opq)
|
||||||
}
|
}
|
||||||
|
|
||||||
rcode = parse_edns_from_query_pkt(pq->qbuf, &pq->edns, NULL, NULL,
|
rcode = parse_edns_from_query_pkt(pq->qbuf, &pq->edns, NULL, NULL,
|
||||||
NULL, 0, pq->region);
|
NULL, 0, pq->region, NULL);
|
||||||
if (rcode != LDNS_RCODE_NOERROR) {
|
if (rcode != LDNS_RCODE_NOERROR) {
|
||||||
error_answer(pq, rcode);
|
error_answer(pq, rcode);
|
||||||
goto send_answer;
|
goto send_answer;
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
/* config.h. Generated from config.h.in by configure. */
|
/* config.h. Generated from config.h.in by configure. */
|
||||||
/* config.h.in. Generated from configure.ac by autoheader. */
|
/* config.h.in. Generated from configure.ac by autoheader. */
|
||||||
|
|
||||||
|
/* apply the fallthrough attribute. */
|
||||||
|
#define ATTR_FALLTHROUGH __attribute__((fallthrough));
|
||||||
|
|
||||||
/* apply the noreturn attribute to a function that exits the program */
|
/* apply the noreturn attribute to a function that exits the program */
|
||||||
#define ATTR_NORETURN __attribute__((__noreturn__))
|
#define ATTR_NORETURN __attribute__((__noreturn__))
|
||||||
|
|
||||||
|
@ -58,6 +61,9 @@
|
||||||
/* Define to 1 if you have the <arpa/inet.h> header file. */
|
/* Define to 1 if you have the <arpa/inet.h> header file. */
|
||||||
#define HAVE_ARPA_INET_H 1
|
#define HAVE_ARPA_INET_H 1
|
||||||
|
|
||||||
|
/* Whether the C compiler accepts the "fallthrough" attribute */
|
||||||
|
#define HAVE_ATTR_FALLTHROUGH 1
|
||||||
|
|
||||||
/* Whether the C compiler accepts the "format" attribute */
|
/* Whether the C compiler accepts the "format" attribute */
|
||||||
#define HAVE_ATTR_FORMAT 1
|
#define HAVE_ATTR_FORMAT 1
|
||||||
|
|
||||||
|
@ -407,6 +413,9 @@
|
||||||
/* Define to 1 if you have the <net/if.h> header file. */
|
/* Define to 1 if you have the <net/if.h> header file. */
|
||||||
#define HAVE_NET_IF_H 1
|
#define HAVE_NET_IF_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <net/pfvar.h> header file. */
|
||||||
|
/* #undef HAVE_NET_PFVAR_H */
|
||||||
|
|
||||||
/* Define this to use nghttp2 client. */
|
/* Define this to use nghttp2 client. */
|
||||||
/* #undef HAVE_NGHTTP2 */
|
/* #undef HAVE_NGHTTP2 */
|
||||||
|
|
||||||
|
@ -567,6 +576,9 @@
|
||||||
function. */
|
function. */
|
||||||
/* #undef HAVE_SSL_CTX_SET_TLSEXT_TICKET_KEY_EVP_CB */
|
/* #undef HAVE_SSL_CTX_SET_TLSEXT_TICKET_KEY_EVP_CB */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `SSL_CTX_set_tmp_ecdh' function. */
|
||||||
|
/* #undef HAVE_SSL_CTX_SET_TMP_ECDH */
|
||||||
|
|
||||||
/* Define to 1 if you have the `SSL_get0_alpn_selected' function. */
|
/* Define to 1 if you have the `SSL_get0_alpn_selected' function. */
|
||||||
#define HAVE_SSL_GET0_ALPN_SELECTED 1
|
#define HAVE_SSL_GET0_ALPN_SELECTED 1
|
||||||
|
|
||||||
|
@ -779,7 +791,7 @@
|
||||||
#define PACKAGE_NAME "unbound"
|
#define PACKAGE_NAME "unbound"
|
||||||
|
|
||||||
/* Define to the full name and version of this package. */
|
/* Define to the full name and version of this package. */
|
||||||
#define PACKAGE_STRING "unbound 1.20.0"
|
#define PACKAGE_STRING "unbound 1.21.0"
|
||||||
|
|
||||||
/* Define to the one symbol short name of this package. */
|
/* Define to the one symbol short name of this package. */
|
||||||
#define PACKAGE_TARNAME "unbound"
|
#define PACKAGE_TARNAME "unbound"
|
||||||
|
@ -788,7 +800,7 @@
|
||||||
#define PACKAGE_URL ""
|
#define PACKAGE_URL ""
|
||||||
|
|
||||||
/* Define to the version of this package. */
|
/* Define to the version of this package. */
|
||||||
#define PACKAGE_VERSION "1.20.0"
|
#define PACKAGE_VERSION "1.21.0"
|
||||||
|
|
||||||
/* default pidfile location */
|
/* default pidfile location */
|
||||||
#define PIDFILE ""
|
#define PIDFILE ""
|
||||||
|
@ -811,7 +823,7 @@
|
||||||
#define ROOT_CERT_FILE "/var/unbound/etc/icannbundle.pem"
|
#define ROOT_CERT_FILE "/var/unbound/etc/icannbundle.pem"
|
||||||
|
|
||||||
/* version number for resource files */
|
/* version number for resource files */
|
||||||
#define RSRC_PACKAGE_VERSION 1,20,0,0
|
#define RSRC_PACKAGE_VERSION 1,21,0,0
|
||||||
|
|
||||||
/* Directory to chdir to */
|
/* Directory to chdir to */
|
||||||
#define RUN_DIR "/var/unbound/etc"
|
#define RUN_DIR "/var/unbound/etc"
|
||||||
|
@ -1485,6 +1497,7 @@ struct sockaddr_storage;
|
||||||
# define calloc(n,s) unbound_stat_calloc_log(n, s, __FILE__, __LINE__, __func__)
|
# define calloc(n,s) unbound_stat_calloc_log(n, s, __FILE__, __LINE__, __func__)
|
||||||
# define free(p) unbound_stat_free_log(p, __FILE__, __LINE__, __func__)
|
# define free(p) unbound_stat_free_log(p, __FILE__, __LINE__, __func__)
|
||||||
# define realloc(p,s) unbound_stat_realloc_log(p, s, __FILE__, __LINE__, __func__)
|
# define realloc(p,s) unbound_stat_realloc_log(p, s, __FILE__, __LINE__, __func__)
|
||||||
|
# define strdup(s) unbound_stat_strdup_log(s, __FILE__, __LINE__, __func__)
|
||||||
void *unbound_stat_malloc(size_t size);
|
void *unbound_stat_malloc(size_t size);
|
||||||
void *unbound_stat_calloc(size_t nmemb, size_t size);
|
void *unbound_stat_calloc(size_t nmemb, size_t size);
|
||||||
void unbound_stat_free(void *ptr);
|
void unbound_stat_free(void *ptr);
|
||||||
|
@ -1497,6 +1510,8 @@ void unbound_stat_free_log(void *ptr, const char* file, int line,
|
||||||
const char* func);
|
const char* func);
|
||||||
void *unbound_stat_realloc_log(void *ptr, size_t size, const char* file,
|
void *unbound_stat_realloc_log(void *ptr, size_t size, const char* file,
|
||||||
int line, const char* func);
|
int line, const char* func);
|
||||||
|
char *unbound_stat_strdup_log(const char *s, const char* file, int line,
|
||||||
|
const char* func);
|
||||||
#elif defined(UNBOUND_ALLOC_LITE)
|
#elif defined(UNBOUND_ALLOC_LITE)
|
||||||
# include "util/alloc.h"
|
# include "util/alloc.h"
|
||||||
#endif /* UNBOUND_ALLOC_LITE and UNBOUND_ALLOC_STATS */
|
#endif /* UNBOUND_ALLOC_LITE and UNBOUND_ALLOC_STATS */
|
||||||
|
|
|
@ -701,6 +701,7 @@ dns64_operate(struct module_qstate* qstate, enum module_ev event, int id,
|
||||||
iq->state = DNS64_NEW_QUERY;
|
iq->state = DNS64_NEW_QUERY;
|
||||||
iq->started_no_cache_store = qstate->no_cache_store;
|
iq->started_no_cache_store = qstate->no_cache_store;
|
||||||
qstate->no_cache_store = 1;
|
qstate->no_cache_store = 1;
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
case module_event_pass:
|
case module_event_pass:
|
||||||
qstate->ext_state[id] = handle_event_pass(qstate, id);
|
qstate->ext_state[id] = handle_event_pass(qstate, id);
|
||||||
|
@ -1044,8 +1045,8 @@ dns64_get_mem(struct module_env* env, int id)
|
||||||
*/
|
*/
|
||||||
static struct module_func_block dns64_block = {
|
static struct module_func_block dns64_block = {
|
||||||
"dns64",
|
"dns64",
|
||||||
&dns64_init, &dns64_deinit, &dns64_operate, &dns64_inform_super,
|
NULL, NULL, &dns64_init, &dns64_deinit, &dns64_operate,
|
||||||
&dns64_clear, &dns64_get_mem
|
&dns64_inform_super, &dns64_clear, &dns64_get_mem
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
|
|
||||||
#ifdef USE_DNSTAP
|
#ifdef USE_DNSTAP
|
||||||
|
|
||||||
|
#include "util/locks.h"
|
||||||
struct config_file;
|
struct config_file;
|
||||||
struct sldns_buffer;
|
struct sldns_buffer;
|
||||||
struct dt_msg_queue;
|
struct dt_msg_queue;
|
||||||
|
@ -75,6 +76,13 @@ struct dt_env {
|
||||||
unsigned log_forwarder_query_messages : 1;
|
unsigned log_forwarder_query_messages : 1;
|
||||||
/** whether to log Message/FORWARDER_RESPONSE */
|
/** whether to log Message/FORWARDER_RESPONSE */
|
||||||
unsigned log_forwarder_response_messages : 1;
|
unsigned log_forwarder_response_messages : 1;
|
||||||
|
|
||||||
|
/** lock on sample count */
|
||||||
|
lock_basic_type sample_lock;
|
||||||
|
/** rate limit value from config, samples 1/N messages */
|
||||||
|
unsigned int sample_rate;
|
||||||
|
/** rate limit counter */
|
||||||
|
unsigned int sample_rate_count;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -367,6 +367,47 @@ type_allowed_in_additional_section(uint16_t tp)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Shorten RRset */
|
||||||
|
static void
|
||||||
|
shorten_rrset(sldns_buffer* pkt, struct rrset_parse* rrset, int count)
|
||||||
|
{
|
||||||
|
/* The too large NS RRset is shortened. This is so that too large
|
||||||
|
* content does not overwhelm the cache. It may make the rrset
|
||||||
|
* bogus if it was signed, and then the domain is not resolved any
|
||||||
|
* more, that is okay, the NS RRset was too large. During a referral
|
||||||
|
* it can be shortened and then the first part of the list could
|
||||||
|
* be used to resolve. The scrub continues to disallow glue for the
|
||||||
|
* removed nameserver RRs and removes that too. Because the glue
|
||||||
|
* is not marked as okay, since the RRs have been removed here. */
|
||||||
|
int i;
|
||||||
|
struct rr_parse* rr = rrset->rr_first, *prev = NULL;
|
||||||
|
if(!rr)
|
||||||
|
return;
|
||||||
|
for(i=0; i<count; i++) {
|
||||||
|
prev = rr;
|
||||||
|
rr = rr->next;
|
||||||
|
if(!rr)
|
||||||
|
return; /* The RRset is already short. */
|
||||||
|
}
|
||||||
|
if(verbosity >= VERB_QUERY
|
||||||
|
&& rrset->dname_len <= LDNS_MAX_DOMAINLEN) {
|
||||||
|
uint8_t buf[LDNS_MAX_DOMAINLEN+1];
|
||||||
|
dname_pkt_copy(pkt, buf, rrset->dname);
|
||||||
|
log_nametypeclass(VERB_QUERY, "normalize: shorten RRset:", buf,
|
||||||
|
rrset->type, ntohs(rrset->rrset_class));
|
||||||
|
}
|
||||||
|
/* remove further rrs */
|
||||||
|
rrset->rr_last = prev;
|
||||||
|
rrset->rr_count = count;
|
||||||
|
while(rr) {
|
||||||
|
rrset->size -= rr->size;
|
||||||
|
rr = rr->next;
|
||||||
|
}
|
||||||
|
if(rrset->rr_last)
|
||||||
|
rrset->rr_last->next = NULL;
|
||||||
|
else rrset->rr_first = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This routine normalizes a response. This includes removing "irrelevant"
|
* This routine normalizes a response. This includes removing "irrelevant"
|
||||||
* records from the answer and additional sections and (re)synthesizing
|
* records from the answer and additional sections and (re)synthesizing
|
||||||
|
@ -387,6 +428,7 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
|
||||||
uint8_t* sname = qinfo->qname;
|
uint8_t* sname = qinfo->qname;
|
||||||
size_t snamelen = qinfo->qname_len;
|
size_t snamelen = qinfo->qname_len;
|
||||||
struct rrset_parse* rrset, *prev, *nsset=NULL;
|
struct rrset_parse* rrset, *prev, *nsset=NULL;
|
||||||
|
int cname_length = 0; /* number of CNAMEs, or DNAMEs */
|
||||||
|
|
||||||
if(FLAGS_GET_RCODE(msg->flags) != LDNS_RCODE_NOERROR &&
|
if(FLAGS_GET_RCODE(msg->flags) != LDNS_RCODE_NOERROR &&
|
||||||
FLAGS_GET_RCODE(msg->flags) != LDNS_RCODE_NXDOMAIN)
|
FLAGS_GET_RCODE(msg->flags) != LDNS_RCODE_NXDOMAIN)
|
||||||
|
@ -401,6 +443,16 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
|
||||||
prev = NULL;
|
prev = NULL;
|
||||||
rrset = msg->rrset_first;
|
rrset = msg->rrset_first;
|
||||||
while(rrset && rrset->section == LDNS_SECTION_ANSWER) {
|
while(rrset && rrset->section == LDNS_SECTION_ANSWER) {
|
||||||
|
if(cname_length > 11 /* env->cfg.iter_scrub_cname */) {
|
||||||
|
/* Too many CNAMEs, or DNAMEs, from the authority
|
||||||
|
* server, scrub down the length to something
|
||||||
|
* shorter. This deletes everything after the limit
|
||||||
|
* is reached. The iterator is going to look up
|
||||||
|
* the content one by one anyway. */
|
||||||
|
remove_rrset("normalize: removing because too many cnames:",
|
||||||
|
pkt, msg, prev, &rrset);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if(rrset->type == LDNS_RR_TYPE_DNAME &&
|
if(rrset->type == LDNS_RR_TYPE_DNAME &&
|
||||||
pkt_strict_sub(pkt, sname, rrset->dname)) {
|
pkt_strict_sub(pkt, sname, rrset->dname)) {
|
||||||
/* check if next rrset is correct CNAME. else,
|
/* check if next rrset is correct CNAME. else,
|
||||||
|
@ -420,6 +472,7 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
|
||||||
"too long");
|
"too long");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
cname_length++;
|
||||||
if(nx && nx->type == LDNS_RR_TYPE_CNAME &&
|
if(nx && nx->type == LDNS_RR_TYPE_CNAME &&
|
||||||
dname_pkt_compare(pkt, sname, nx->dname) == 0) {
|
dname_pkt_compare(pkt, sname, nx->dname) == 0) {
|
||||||
/* check next cname */
|
/* check next cname */
|
||||||
|
@ -460,6 +513,7 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
|
||||||
if(rrset->type == LDNS_RR_TYPE_CNAME) {
|
if(rrset->type == LDNS_RR_TYPE_CNAME) {
|
||||||
struct rrset_parse* nx = rrset->rrset_all_next;
|
struct rrset_parse* nx = rrset->rrset_all_next;
|
||||||
uint8_t* oldsname = sname;
|
uint8_t* oldsname = sname;
|
||||||
|
cname_length++;
|
||||||
/* see if the next one is a DNAME, if so, swap them */
|
/* see if the next one is a DNAME, if so, swap them */
|
||||||
if(nx && nx->section == LDNS_SECTION_ANSWER &&
|
if(nx && nx->section == LDNS_SECTION_ANSWER &&
|
||||||
nx->type == LDNS_RR_TYPE_DNAME &&
|
nx->type == LDNS_RR_TYPE_DNAME &&
|
||||||
|
@ -507,6 +561,10 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
|
||||||
LDNS_SECTION_ANSWER &&
|
LDNS_SECTION_ANSWER &&
|
||||||
dname_pkt_compare(pkt, oldsname,
|
dname_pkt_compare(pkt, oldsname,
|
||||||
rrset->dname) == 0) {
|
rrset->dname) == 0) {
|
||||||
|
if(rrset->type == LDNS_RR_TYPE_NS &&
|
||||||
|
rrset->rr_count > 20 /* env->cfg->iter_scrub_ns */) {
|
||||||
|
shorten_rrset(pkt, rrset, 20 /* env->cfg->iter_scrub_ns */);
|
||||||
|
}
|
||||||
prev = rrset;
|
prev = rrset;
|
||||||
rrset = rrset->rrset_all_next;
|
rrset = rrset->rrset_all_next;
|
||||||
}
|
}
|
||||||
|
@ -522,6 +580,11 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(rrset->type == LDNS_RR_TYPE_NS &&
|
||||||
|
rrset->rr_count > 20 /* env->cfg->iter_scrub_ns */) {
|
||||||
|
shorten_rrset(pkt, rrset, 20 /* env->cfg->iter_scrub_ns */);
|
||||||
|
}
|
||||||
|
|
||||||
/* Mark the additional names from relevant rrset as OK. */
|
/* Mark the additional names from relevant rrset as OK. */
|
||||||
/* only for RRsets that match the query name, other ones
|
/* only for RRsets that match the query name, other ones
|
||||||
* will be removed by sanitize, so no additional for them */
|
* will be removed by sanitize, so no additional for them */
|
||||||
|
@ -578,6 +641,25 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
|
||||||
"RRset:", pkt, msg, prev, &rrset);
|
"RRset:", pkt, msg, prev, &rrset);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if(rrset->rr_count > 20 /* env->cfg->iter_scrub_ns */) {
|
||||||
|
/* If this is not a referral, and the NS RRset
|
||||||
|
* is signed, then remove it entirely, so
|
||||||
|
* that when it becomes bogus it does not
|
||||||
|
* make the message that is otherwise fine
|
||||||
|
* into a bogus message. */
|
||||||
|
if(!(msg->an_rrsets == 0 &&
|
||||||
|
FLAGS_GET_RCODE(msg->flags) ==
|
||||||
|
LDNS_RCODE_NOERROR &&
|
||||||
|
!soa_in_auth(msg) &&
|
||||||
|
!(msg->flags & BIT_AA)) &&
|
||||||
|
rrset->rrsig_count != 0) {
|
||||||
|
remove_rrset("normalize: removing too large NS "
|
||||||
|
"RRset:", pkt, msg, prev, &rrset);
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
shorten_rrset(pkt, rrset, 20 /* env->cfg->iter_scrub_ns */);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/* if this is type DS and we query for type DS we just got
|
/* if this is type DS and we query for type DS we just got
|
||||||
* a referral answer for our type DS query, fix packet */
|
* a referral answer for our type DS query, fix packet */
|
||||||
|
|
|
@ -279,9 +279,10 @@ iter_filter_unsuitable(struct iter_env* iter_env, struct module_env* env,
|
||||||
name, namelen, qtype, &lame, &dnsseclame, &reclame,
|
name, namelen, qtype, &lame, &dnsseclame, &reclame,
|
||||||
&rtt, now)) {
|
&rtt, now)) {
|
||||||
log_addr(VERB_ALGO, "servselect", &a->addr, a->addrlen);
|
log_addr(VERB_ALGO, "servselect", &a->addr, a->addrlen);
|
||||||
verbose(VERB_ALGO, " rtt=%d%s%s%s%s", rtt,
|
verbose(VERB_ALGO, " rtt=%d%s%s%s%s%s", rtt,
|
||||||
lame?" LAME":"",
|
lame?" LAME":"",
|
||||||
dnsseclame?" DNSSEC_LAME":"",
|
dnsseclame?" DNSSEC_LAME":"",
|
||||||
|
a->dnsseclame?" ADDR_DNSSEC_LAME":"",
|
||||||
reclame?" REC_LAME":"",
|
reclame?" REC_LAME":"",
|
||||||
a->lame?" ADDR_LAME":"");
|
a->lame?" ADDR_LAME":"");
|
||||||
if(lame)
|
if(lame)
|
||||||
|
|
|
@ -760,6 +760,14 @@ target_count_increase_nx(struct iter_qstate* iq, int num)
|
||||||
iq->target_count[TARGET_COUNT_NX] += num;
|
iq->target_count[TARGET_COUNT_NX] += num;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
target_count_increase_global_quota(struct iter_qstate* iq, int num)
|
||||||
|
{
|
||||||
|
target_count_create(iq);
|
||||||
|
if(iq->target_count)
|
||||||
|
iq->target_count[TARGET_COUNT_GLOBAL_QUOTA] += num;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate a subrequest.
|
* Generate a subrequest.
|
||||||
* Generate a local request event. Local events are tied to this module, and
|
* Generate a local request event. Local events are tied to this module, and
|
||||||
|
@ -1378,7 +1386,7 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||||
"restarts (eg. indirections)");
|
"restarts (eg. indirections)");
|
||||||
if(iq->qchase.qname)
|
if(iq->qchase.qname)
|
||||||
errinf_dname(qstate, "stop at", iq->qchase.qname);
|
errinf_dname(qstate, "stop at", iq->qchase.qname);
|
||||||
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We enforce a maximum recursion/dependency depth -- in general,
|
/* We enforce a maximum recursion/dependency depth -- in general,
|
||||||
|
@ -1560,6 +1568,11 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||||
errinf(qstate, "malloc failure for forward zone");
|
errinf(qstate, "malloc failure for forward zone");
|
||||||
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||||
}
|
}
|
||||||
|
if(!cache_fill_missing(qstate->env, iq->qchase.qclass,
|
||||||
|
qstate->region, iq->dp)) {
|
||||||
|
errinf(qstate, "malloc failure, copy extra info into delegation point");
|
||||||
|
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||||
|
}
|
||||||
if((qstate->query_flags&BIT_RD)==0) {
|
if((qstate->query_flags&BIT_RD)==0) {
|
||||||
/* If the server accepts RD=0 queries and forwards
|
/* If the server accepts RD=0 queries and forwards
|
||||||
* with RD=1, then if the server is listed as an NS
|
* with RD=1, then if the server is listed as an NS
|
||||||
|
@ -1654,7 +1667,7 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||||
if(!iq->dp) {
|
if(!iq->dp) {
|
||||||
log_err("internal error: no hints dp");
|
log_err("internal error: no hints dp");
|
||||||
errinf(qstate, "no hints for this class");
|
errinf(qstate, "no hints for this class");
|
||||||
return error_response(qstate, id,
|
return error_response_cache(qstate, id,
|
||||||
LDNS_RCODE_SERVFAIL);
|
LDNS_RCODE_SERVFAIL);
|
||||||
}
|
}
|
||||||
iq->dp = delegpt_copy(iq->dp, qstate->region);
|
iq->dp = delegpt_copy(iq->dp, qstate->region);
|
||||||
|
@ -1974,7 +1987,8 @@ generate_target_query(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||||
* if it is negative, there is no maximum number of targets.
|
* if it is negative, there is no maximum number of targets.
|
||||||
* @param num: returns the number of queries generated and processed,
|
* @param num: returns the number of queries generated and processed,
|
||||||
* which may be zero if there were no missing targets.
|
* which may be zero if there were no missing targets.
|
||||||
* @return false on error.
|
* @return 0 on success, nonzero on error. 1 means temporary failure and
|
||||||
|
* 2 means the failure can be cached.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
query_for_targets(struct module_qstate* qstate, struct iter_qstate* iq,
|
query_for_targets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||||
|
@ -1997,13 +2011,13 @@ query_for_targets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||||
else toget = maxtargets;
|
else toget = maxtargets;
|
||||||
if(toget == 0) {
|
if(toget == 0) {
|
||||||
*num = 0;
|
*num = 0;
|
||||||
return 1;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* now that we are sure that a target query is going to be made,
|
/* now that we are sure that a target query is going to be made,
|
||||||
* check the limits. */
|
* check the limits. */
|
||||||
if(iq->depth == ie->max_dependency_depth)
|
if(iq->depth == ie->max_dependency_depth)
|
||||||
return 0;
|
return 1;
|
||||||
if(iq->depth > 0 && iq->target_count &&
|
if(iq->depth > 0 && iq->target_count &&
|
||||||
iq->target_count[TARGET_COUNT_QUERIES] > MAX_TARGET_COUNT) {
|
iq->target_count[TARGET_COUNT_QUERIES] > MAX_TARGET_COUNT) {
|
||||||
char s[LDNS_MAX_DOMAINLEN+1];
|
char s[LDNS_MAX_DOMAINLEN+1];
|
||||||
|
@ -2011,7 +2025,7 @@ query_for_targets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||||
verbose(VERB_QUERY, "request %s has exceeded the maximum "
|
verbose(VERB_QUERY, "request %s has exceeded the maximum "
|
||||||
"number of glue fetches %d", s,
|
"number of glue fetches %d", s,
|
||||||
iq->target_count[TARGET_COUNT_QUERIES]);
|
iq->target_count[TARGET_COUNT_QUERIES]);
|
||||||
return 0;
|
return 2;
|
||||||
}
|
}
|
||||||
if(iq->dp_target_count > MAX_DP_TARGET_COUNT) {
|
if(iq->dp_target_count > MAX_DP_TARGET_COUNT) {
|
||||||
char s[LDNS_MAX_DOMAINLEN+1];
|
char s[LDNS_MAX_DOMAINLEN+1];
|
||||||
|
@ -2019,7 +2033,7 @@ query_for_targets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||||
verbose(VERB_QUERY, "request %s has exceeded the maximum "
|
verbose(VERB_QUERY, "request %s has exceeded the maximum "
|
||||||
"number of glue fetches %d to a single delegation point",
|
"number of glue fetches %d to a single delegation point",
|
||||||
s, iq->dp_target_count);
|
s, iq->dp_target_count);
|
||||||
return 0;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* select 'toget' items from the total of 'missing' items */
|
/* select 'toget' items from the total of 'missing' items */
|
||||||
|
@ -2048,7 +2062,7 @@ query_for_targets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||||
*num = query_count;
|
*num = query_count;
|
||||||
if(query_count > 0)
|
if(query_count > 0)
|
||||||
qstate->ext_state[id] = module_wait_subquery;
|
qstate->ext_state[id] = module_wait_subquery;
|
||||||
return 0;
|
return 1;
|
||||||
}
|
}
|
||||||
query_count++;
|
query_count++;
|
||||||
/* If the mesh query list is full, exit the loop here.
|
/* If the mesh query list is full, exit the loop here.
|
||||||
|
@ -2057,9 +2071,17 @@ query_for_targets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||||
* increase, because the spawned state uses cpu and a
|
* increase, because the spawned state uses cpu and a
|
||||||
* socket while this state waits for that spawned
|
* socket while this state waits for that spawned
|
||||||
* state. Next time we can look up further targets */
|
* state. Next time we can look up further targets */
|
||||||
if(mesh_jostle_exceeded(qstate->env->mesh))
|
if(mesh_jostle_exceeded(qstate->env->mesh)) {
|
||||||
|
/* If no ip4 query is possible, that makes
|
||||||
|
* this ns resolved. */
|
||||||
|
if(!((ie->supports_ipv4 || ie->use_nat64) &&
|
||||||
|
((ns->lame && !ns->done_pside4) ||
|
||||||
|
(!ns->lame && !ns->got4)))) {
|
||||||
|
ns->resolved = 1;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
/* Send the A request. */
|
/* Send the A request. */
|
||||||
if((ie->supports_ipv4 || ie->use_nat64) &&
|
if((ie->supports_ipv4 || ie->use_nat64) &&
|
||||||
((ns->lame && !ns->done_pside4) ||
|
((ns->lame && !ns->done_pside4) ||
|
||||||
|
@ -2070,13 +2092,18 @@ query_for_targets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||||
*num = query_count;
|
*num = query_count;
|
||||||
if(query_count > 0)
|
if(query_count > 0)
|
||||||
qstate->ext_state[id] = module_wait_subquery;
|
qstate->ext_state[id] = module_wait_subquery;
|
||||||
return 0;
|
return 1;
|
||||||
}
|
}
|
||||||
query_count++;
|
query_count++;
|
||||||
/* If the mesh query list is full, exit the loop. */
|
/* If the mesh query list is full, exit the loop. */
|
||||||
if(mesh_jostle_exceeded(qstate->env->mesh))
|
if(mesh_jostle_exceeded(qstate->env->mesh)) {
|
||||||
|
/* With the ip6 query already checked for,
|
||||||
|
* this makes the ns resolved. It is no longer
|
||||||
|
* a missing target. */
|
||||||
|
ns->resolved = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* mark this target as in progress. */
|
/* mark this target as in progress. */
|
||||||
ns->resolved = 1;
|
ns->resolved = 1;
|
||||||
|
@ -2089,7 +2116,7 @@ query_for_targets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||||
if(query_count > 0)
|
if(query_count > 0)
|
||||||
qstate->ext_state[id] = module_wait_subquery;
|
qstate->ext_state[id] = module_wait_subquery;
|
||||||
|
|
||||||
return 1;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2180,12 +2207,14 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||||
}
|
}
|
||||||
/* query for an extra name added by the parent-NS record */
|
/* query for an extra name added by the parent-NS record */
|
||||||
if(delegpt_count_missing_targets(iq->dp, NULL) > 0) {
|
if(delegpt_count_missing_targets(iq->dp, NULL) > 0) {
|
||||||
int qs = 0;
|
int qs = 0, ret;
|
||||||
verbose(VERB_ALGO, "try parent-side target name");
|
verbose(VERB_ALGO, "try parent-side target name");
|
||||||
if(!query_for_targets(qstate, iq, ie, id, 1, &qs)) {
|
if((ret=query_for_targets(qstate, iq, ie, id, 1, &qs))!=0) {
|
||||||
errinf(qstate, "could not fetch nameserver");
|
errinf(qstate, "could not fetch nameserver");
|
||||||
errinf_dname(qstate, "at zone", iq->dp->name);
|
errinf_dname(qstate, "at zone", iq->dp->name);
|
||||||
|
if(ret == 1)
|
||||||
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||||
|
return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||||
}
|
}
|
||||||
iq->num_target_queries += qs;
|
iq->num_target_queries += qs;
|
||||||
target_count_increase(iq, qs);
|
target_count_increase(iq, qs);
|
||||||
|
@ -2414,13 +2443,13 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||||
verbose(VERB_QUERY, "request has exceeded the maximum "
|
verbose(VERB_QUERY, "request has exceeded the maximum "
|
||||||
"number of referrrals with %d", iq->referral_count);
|
"number of referrrals with %d", iq->referral_count);
|
||||||
errinf(qstate, "exceeded the maximum of referrals");
|
errinf(qstate, "exceeded the maximum of referrals");
|
||||||
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||||
}
|
}
|
||||||
if(iq->sent_count > ie->max_sent_count) {
|
if(iq->sent_count > ie->max_sent_count) {
|
||||||
verbose(VERB_QUERY, "request has exceeded the maximum "
|
verbose(VERB_QUERY, "request has exceeded the maximum "
|
||||||
"number of sends with %d", iq->sent_count);
|
"number of sends with %d", iq->sent_count);
|
||||||
errinf(qstate, "exceeded the maximum number of sends");
|
errinf(qstate, "exceeded the maximum number of sends");
|
||||||
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if we reached MAX_TARGET_NX limit without a fallback activation. */
|
/* Check if we reached MAX_TARGET_NX limit without a fallback activation. */
|
||||||
|
@ -2450,7 +2479,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||||
"already present for the delegation point, no "
|
"already present for the delegation point, no "
|
||||||
"fallback possible");
|
"fallback possible");
|
||||||
errinf(qstate, "exceeded the maximum nameserver nxdomains");
|
errinf(qstate, "exceeded the maximum nameserver nxdomains");
|
||||||
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||||
}
|
}
|
||||||
verbose(VERB_ALGO, "initiating parent-side fallback for "
|
verbose(VERB_ALGO, "initiating parent-side fallback for "
|
||||||
"nxdomain nameserver lookups");
|
"nxdomain nameserver lookups");
|
||||||
|
@ -2493,7 +2522,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||||
"lookups (%d) with %d", MAX_TARGET_NX_FALLBACK,
|
"lookups (%d) with %d", MAX_TARGET_NX_FALLBACK,
|
||||||
iq->target_count[TARGET_COUNT_NX]);
|
iq->target_count[TARGET_COUNT_NX]);
|
||||||
errinf(qstate, "exceeded the maximum nameserver nxdomains");
|
errinf(qstate, "exceeded the maximum nameserver nxdomains");
|
||||||
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!iq->dp->has_parent_side_NS) {
|
if(!iq->dp->has_parent_side_NS) {
|
||||||
|
@ -2707,7 +2736,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||||
verbose(VERB_ALGO, "auth zone lookup failed, no fallback,"
|
verbose(VERB_ALGO, "auth zone lookup failed, no fallback,"
|
||||||
" servfail");
|
" servfail");
|
||||||
errinf(qstate, "auth zone lookup failed, fallback is off");
|
errinf(qstate, "auth zone lookup failed, fallback is off");
|
||||||
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||||
}
|
}
|
||||||
if(iq->dp->auth_dp) {
|
if(iq->dp->auth_dp) {
|
||||||
/* we wanted to fallback, but had no delegpt, only the
|
/* we wanted to fallback, but had no delegpt, only the
|
||||||
|
@ -2736,11 +2765,13 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||||
|
|
||||||
/* if in 0x20 fallback get as many targets as possible */
|
/* if in 0x20 fallback get as many targets as possible */
|
||||||
if(iq->caps_fallback) {
|
if(iq->caps_fallback) {
|
||||||
int extra = 0;
|
int extra = 0, ret;
|
||||||
size_t naddr, nres, navail;
|
size_t naddr, nres, navail;
|
||||||
if(!query_for_targets(qstate, iq, ie, id, -1, &extra)) {
|
if((ret=query_for_targets(qstate, iq, ie, id, -1, &extra))!=0) {
|
||||||
errinf(qstate, "could not fetch nameservers for 0x20 fallback");
|
errinf(qstate, "could not fetch nameservers for 0x20 fallback");
|
||||||
|
if(ret == 1)
|
||||||
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||||
|
return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||||
}
|
}
|
||||||
iq->num_target_queries += extra;
|
iq->num_target_queries += extra;
|
||||||
target_count_increase(iq, extra);
|
target_count_increase(iq, extra);
|
||||||
|
@ -2883,15 +2914,18 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||||
* to distinguish between generating (a) new target
|
* to distinguish between generating (a) new target
|
||||||
* query, or failing. */
|
* query, or failing. */
|
||||||
if(delegpt_count_missing_targets(iq->dp, NULL) > 0) {
|
if(delegpt_count_missing_targets(iq->dp, NULL) > 0) {
|
||||||
int qs = 0;
|
int qs = 0, ret;
|
||||||
verbose(VERB_ALGO, "querying for next "
|
verbose(VERB_ALGO, "querying for next "
|
||||||
"missing target");
|
"missing target");
|
||||||
if(!query_for_targets(qstate, iq, ie, id,
|
if((ret=query_for_targets(qstate, iq, ie, id,
|
||||||
1, &qs)) {
|
1, &qs))!=0) {
|
||||||
errinf(qstate, "could not fetch nameserver");
|
errinf(qstate, "could not fetch nameserver");
|
||||||
errinf_dname(qstate, "at zone", iq->dp->name);
|
errinf_dname(qstate, "at zone", iq->dp->name);
|
||||||
|
if(ret == 1)
|
||||||
return error_response(qstate, id,
|
return error_response(qstate, id,
|
||||||
LDNS_RCODE_SERVFAIL);
|
LDNS_RCODE_SERVFAIL);
|
||||||
|
return error_response_cache(qstate, id,
|
||||||
|
LDNS_RCODE_SERVFAIL);
|
||||||
}
|
}
|
||||||
if(qs == 0 &&
|
if(qs == 0 &&
|
||||||
delegpt_count_missing_targets(iq->dp, NULL) == 0){
|
delegpt_count_missing_targets(iq->dp, NULL) == 0){
|
||||||
|
@ -2902,6 +2936,17 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||||
* so this is not a loop. */
|
* so this is not a loop. */
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
if(qs == 0) {
|
||||||
|
/* There should be targets now, and
|
||||||
|
* if there are not, it should not
|
||||||
|
* wait for no targets. Stop it from
|
||||||
|
* waiting forever, or looping to
|
||||||
|
* here, as a safeguard. */
|
||||||
|
errinf(qstate, "could not generate nameserver lookups");
|
||||||
|
errinf_dname(qstate, "at zone", iq->dp->name);
|
||||||
|
return error_response(qstate, id,
|
||||||
|
LDNS_RCODE_SERVFAIL);
|
||||||
|
}
|
||||||
iq->num_target_queries += qs;
|
iq->num_target_queries += qs;
|
||||||
target_count_increase(iq, qs);
|
target_count_increase(iq, qs);
|
||||||
}
|
}
|
||||||
|
@ -2976,6 +3021,17 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
target_count_increase_global_quota(iq, 1);
|
||||||
|
if(iq->target_count && iq->target_count[TARGET_COUNT_GLOBAL_QUOTA]
|
||||||
|
> MAX_GLOBAL_QUOTA) {
|
||||||
|
char s[LDNS_MAX_DOMAINLEN+1];
|
||||||
|
dname_str(qstate->qinfo.qname, s);
|
||||||
|
verbose(VERB_QUERY, "request %s has exceeded the maximum "
|
||||||
|
"global quota on number of upstream queries %d", s,
|
||||||
|
iq->target_count[TARGET_COUNT_GLOBAL_QUOTA]);
|
||||||
|
return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||||
|
}
|
||||||
|
|
||||||
/* Do not check ratelimit for forwarding queries or if we already got a
|
/* Do not check ratelimit for forwarding queries or if we already got a
|
||||||
* pass. */
|
* pass. */
|
||||||
sq_check_ratelimit = (!(iq->chase_flags & BIT_RD) && !iq->ratelimit_ok);
|
sq_check_ratelimit = (!(iq->chase_flags & BIT_RD) && !iq->ratelimit_ok);
|
||||||
|
@ -3025,7 +3081,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||||
qstate->was_ratelimited = 1;
|
qstate->was_ratelimited = 1;
|
||||||
errinf_dname(qstate, "exceeded ratelimit for zone",
|
errinf_dname(qstate, "exceeded ratelimit for zone",
|
||||||
iq->dp->name);
|
iq->dp->name);
|
||||||
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||||
}
|
}
|
||||||
log_addr(VERB_QUERY, "error sending query to auth server",
|
log_addr(VERB_QUERY, "error sending query to auth server",
|
||||||
&real_addr, real_addrlen);
|
&real_addr, real_addrlen);
|
||||||
|
@ -3247,7 +3303,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||||
iter_scrub_nxdomain(iq->response);
|
iter_scrub_nxdomain(iq->response);
|
||||||
return final_state(iq);
|
return final_state(iq);
|
||||||
}
|
}
|
||||||
return error_response(qstate, id,
|
return error_response_cache(qstate, id,
|
||||||
LDNS_RCODE_SERVFAIL);
|
LDNS_RCODE_SERVFAIL);
|
||||||
}
|
}
|
||||||
/* Best effort qname-minimisation.
|
/* Best effort qname-minimisation.
|
||||||
|
@ -3582,7 +3638,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||||
" fallback possible, servfail");
|
" fallback possible, servfail");
|
||||||
errinf_dname(qstate, "response is bad, no fallback, "
|
errinf_dname(qstate, "response is bad, no fallback, "
|
||||||
"for auth zone", iq->dp->name);
|
"for auth zone", iq->dp->name);
|
||||||
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||||
}
|
}
|
||||||
verbose(VERB_ALGO, "auth zone response was bad, "
|
verbose(VERB_ALGO, "auth zone response was bad, "
|
||||||
"fallback enabled");
|
"fallback enabled");
|
||||||
|
@ -3990,7 +4046,7 @@ processCollectClass(struct module_qstate* qstate, int id)
|
||||||
if(iq->num_current_queries == 0) {
|
if(iq->num_current_queries == 0) {
|
||||||
verbose(VERB_ALGO, "No root hints or fwds, giving up "
|
verbose(VERB_ALGO, "No root hints or fwds, giving up "
|
||||||
"on qclass ANY");
|
"on qclass ANY");
|
||||||
return error_response(qstate, id, LDNS_RCODE_REFUSED);
|
return error_response_cache(qstate, id, LDNS_RCODE_REFUSED);
|
||||||
}
|
}
|
||||||
/* return false, wait for queries to return */
|
/* return false, wait for queries to return */
|
||||||
}
|
}
|
||||||
|
@ -4357,7 +4413,7 @@ process_response(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||||
"getting different replies, failed");
|
"getting different replies, failed");
|
||||||
outbound_list_remove(&iq->outlist, outbound);
|
outbound_list_remove(&iq->outlist, outbound);
|
||||||
errinf(qstate, "0x20 failed, then got different replies in fallback");
|
errinf(qstate, "0x20 failed, then got different replies in fallback");
|
||||||
(void)error_response(qstate, id,
|
(void)error_response_cache(qstate, id,
|
||||||
LDNS_RCODE_SERVFAIL);
|
LDNS_RCODE_SERVFAIL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -4457,8 +4513,8 @@ iter_get_mem(struct module_env* env, int id)
|
||||||
*/
|
*/
|
||||||
static struct module_func_block iter_block = {
|
static struct module_func_block iter_block = {
|
||||||
"iterator",
|
"iterator",
|
||||||
&iter_init, &iter_deinit, &iter_operate, &iter_inform_super,
|
NULL, NULL, &iter_init, &iter_deinit, &iter_operate,
|
||||||
&iter_clear, &iter_get_mem
|
&iter_inform_super, &iter_clear, &iter_get_mem
|
||||||
};
|
};
|
||||||
|
|
||||||
struct module_func_block*
|
struct module_func_block*
|
||||||
|
|
|
@ -55,6 +55,9 @@ struct rbtree_type;
|
||||||
|
|
||||||
/** max number of targets spawned for a query and its subqueries */
|
/** max number of targets spawned for a query and its subqueries */
|
||||||
#define MAX_TARGET_COUNT 64
|
#define MAX_TARGET_COUNT 64
|
||||||
|
/** max number of upstream queries for a query and its subqueries, it is
|
||||||
|
* never reset. */
|
||||||
|
#define MAX_GLOBAL_QUOTA 128
|
||||||
/** max number of target lookups per qstate, per delegation point */
|
/** max number of target lookups per qstate, per delegation point */
|
||||||
#define MAX_DP_TARGET_COUNT 16
|
#define MAX_DP_TARGET_COUNT 16
|
||||||
/** max number of nxdomains allowed for target lookups for a query and
|
/** max number of nxdomains allowed for target lookups for a query and
|
||||||
|
@ -248,6 +251,9 @@ enum target_count_variables {
|
||||||
TARGET_COUNT_QUERIES,
|
TARGET_COUNT_QUERIES,
|
||||||
/** Number of nxdomain responses encountered. */
|
/** Number of nxdomain responses encountered. */
|
||||||
TARGET_COUNT_NX,
|
TARGET_COUNT_NX,
|
||||||
|
/** Global quota on number of queries to upstream servers per
|
||||||
|
* client request, that is never reset. */
|
||||||
|
TARGET_COUNT_GLOBAL_QUOTA,
|
||||||
|
|
||||||
/** This should stay last here, it is used for the allocation */
|
/** This should stay last here, it is used for the allocation */
|
||||||
TARGET_COUNT_MAX,
|
TARGET_COUNT_MAX,
|
||||||
|
|
|
@ -75,7 +75,9 @@ context_finalize(struct ub_ctx* ctx)
|
||||||
ctx->pipe_pid = getpid();
|
ctx->pipe_pid = getpid();
|
||||||
cfg_apply_local_port_policy(cfg, 65536);
|
cfg_apply_local_port_policy(cfg, 65536);
|
||||||
config_apply(cfg);
|
config_apply(cfg);
|
||||||
if(!modstack_setup(&ctx->mods, cfg->module_conf, ctx->env))
|
if(!modstack_call_startup(&ctx->mods, cfg->module_conf, ctx->env))
|
||||||
|
return UB_INITFAIL;
|
||||||
|
if(!modstack_call_init(&ctx->mods, cfg->module_conf, ctx->env))
|
||||||
return UB_INITFAIL;
|
return UB_INITFAIL;
|
||||||
listen_setup_locks();
|
listen_setup_locks();
|
||||||
log_edns_known_options(VERB_ALGO, ctx->env);
|
log_edns_known_options(VERB_ALGO, ctx->env);
|
||||||
|
|
|
@ -188,7 +188,9 @@ ub_ctx_create(void)
|
||||||
int e = errno;
|
int e = errno;
|
||||||
ub_randfree(ctx->seed_rnd);
|
ub_randfree(ctx->seed_rnd);
|
||||||
config_delete(ctx->env->cfg);
|
config_delete(ctx->env->cfg);
|
||||||
modstack_desetup(&ctx->mods, ctx->env);
|
modstack_call_deinit(&ctx->mods, ctx->env);
|
||||||
|
modstack_call_destartup(&ctx->mods, ctx->env);
|
||||||
|
modstack_free(&ctx->mods);
|
||||||
listen_desetup_locks();
|
listen_desetup_locks();
|
||||||
edns_known_options_delete(ctx->env);
|
edns_known_options_delete(ctx->env);
|
||||||
edns_strings_delete(ctx->env->edns_strings);
|
edns_strings_delete(ctx->env->edns_strings);
|
||||||
|
@ -202,7 +204,9 @@ ub_ctx_create(void)
|
||||||
tube_delete(ctx->qq_pipe);
|
tube_delete(ctx->qq_pipe);
|
||||||
ub_randfree(ctx->seed_rnd);
|
ub_randfree(ctx->seed_rnd);
|
||||||
config_delete(ctx->env->cfg);
|
config_delete(ctx->env->cfg);
|
||||||
modstack_desetup(&ctx->mods, ctx->env);
|
modstack_call_deinit(&ctx->mods, ctx->env);
|
||||||
|
modstack_call_destartup(&ctx->mods, ctx->env);
|
||||||
|
modstack_free(&ctx->mods);
|
||||||
listen_desetup_locks();
|
listen_desetup_locks();
|
||||||
edns_known_options_delete(ctx->env);
|
edns_known_options_delete(ctx->env);
|
||||||
edns_strings_delete(ctx->env->edns_strings);
|
edns_strings_delete(ctx->env->edns_strings);
|
||||||
|
@ -360,7 +364,9 @@ ub_ctx_delete(struct ub_ctx* ctx)
|
||||||
}
|
}
|
||||||
libworker_delete_event(ctx->event_worker);
|
libworker_delete_event(ctx->event_worker);
|
||||||
|
|
||||||
modstack_desetup(&ctx->mods, ctx->env);
|
modstack_call_deinit(&ctx->mods, ctx->env);
|
||||||
|
modstack_call_destartup(&ctx->mods, ctx->env);
|
||||||
|
modstack_free(&ctx->mods);
|
||||||
a = ctx->alloc_list;
|
a = ctx->alloc_list;
|
||||||
while(a) {
|
while(a) {
|
||||||
na = a->super;
|
na = a->super;
|
||||||
|
@ -981,7 +987,8 @@ ub_ctx_set_fwd(struct ub_ctx* ctx, const char* addr)
|
||||||
if(!addr) {
|
if(!addr) {
|
||||||
/* disable fwd mode - the root stub should be first. */
|
/* disable fwd mode - the root stub should be first. */
|
||||||
if(ctx->env->cfg->forwards &&
|
if(ctx->env->cfg->forwards &&
|
||||||
strcmp(ctx->env->cfg->forwards->name, ".") == 0) {
|
(ctx->env->cfg->forwards->name &&
|
||||||
|
strcmp(ctx->env->cfg->forwards->name, ".") == 0)) {
|
||||||
s = ctx->env->cfg->forwards;
|
s = ctx->env->cfg->forwards;
|
||||||
ctx->env->cfg->forwards = s->next;
|
ctx->env->cfg->forwards = s->next;
|
||||||
s->next = NULL;
|
s->next = NULL;
|
||||||
|
@ -1001,7 +1008,8 @@ ub_ctx_set_fwd(struct ub_ctx* ctx, const char* addr)
|
||||||
/* it parses, add root stub in front of list */
|
/* it parses, add root stub in front of list */
|
||||||
lock_basic_lock(&ctx->cfglock);
|
lock_basic_lock(&ctx->cfglock);
|
||||||
if(!ctx->env->cfg->forwards ||
|
if(!ctx->env->cfg->forwards ||
|
||||||
strcmp(ctx->env->cfg->forwards->name, ".") != 0) {
|
(ctx->env->cfg->forwards->name &&
|
||||||
|
strcmp(ctx->env->cfg->forwards->name, ".") != 0)) {
|
||||||
s = calloc(1, sizeof(*s));
|
s = calloc(1, sizeof(*s));
|
||||||
if(!s) {
|
if(!s) {
|
||||||
lock_basic_unlock(&ctx->cfglock);
|
lock_basic_unlock(&ctx->cfglock);
|
||||||
|
@ -1019,6 +1027,7 @@ ub_ctx_set_fwd(struct ub_ctx* ctx, const char* addr)
|
||||||
ctx->env->cfg->forwards = s;
|
ctx->env->cfg->forwards = s;
|
||||||
} else {
|
} else {
|
||||||
log_assert(ctx->env->cfg->forwards);
|
log_assert(ctx->env->cfg->forwards);
|
||||||
|
log_assert(ctx->env->cfg->forwards->name);
|
||||||
s = ctx->env->cfg->forwards;
|
s = ctx->env->cfg->forwards;
|
||||||
}
|
}
|
||||||
dupl = strdup(addr);
|
dupl = strdup(addr);
|
||||||
|
|
|
@ -292,6 +292,7 @@ libworker_do_cmd(struct libworker* w, uint8_t* msg, uint32_t len)
|
||||||
log_err("unknown command for bg worker %d",
|
log_err("unknown command for bg worker %d",
|
||||||
(int)context_serial_getcmd(msg, len));
|
(int)context_serial_getcmd(msg, len));
|
||||||
/* and fall through to quit */
|
/* and fall through to quit */
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
case UB_LIBCMD_QUIT:
|
case UB_LIBCMD_QUIT:
|
||||||
free(msg);
|
free(msg);
|
||||||
|
|
|
@ -1259,8 +1259,8 @@ respip_get_mem(struct module_env* env, int id)
|
||||||
*/
|
*/
|
||||||
static struct module_func_block respip_block = {
|
static struct module_func_block respip_block = {
|
||||||
"respip",
|
"respip",
|
||||||
&respip_init, &respip_deinit, &respip_operate, &respip_inform_super,
|
NULL, NULL, &respip_init, &respip_deinit, &respip_operate,
|
||||||
&respip_clear, &respip_get_mem
|
&respip_inform_super, &respip_clear, &respip_get_mem
|
||||||
};
|
};
|
||||||
|
|
||||||
struct module_func_block*
|
struct module_func_block*
|
||||||
|
|
|
@ -7778,7 +7778,8 @@ static void auth_zone_log(uint8_t* name, enum verbosity_value level,
|
||||||
static int zonemd_dnssec_verify_rrset(struct auth_zone* z,
|
static int zonemd_dnssec_verify_rrset(struct auth_zone* z,
|
||||||
struct module_env* env, struct module_stack* mods,
|
struct module_env* env, struct module_stack* mods,
|
||||||
struct ub_packed_rrset_key* dnskey, struct auth_data* node,
|
struct ub_packed_rrset_key* dnskey, struct auth_data* node,
|
||||||
struct auth_rrset* rrset, char** why_bogus, uint8_t* sigalg)
|
struct auth_rrset* rrset, char** why_bogus, uint8_t* sigalg,
|
||||||
|
char* reasonbuf, size_t reasonlen)
|
||||||
{
|
{
|
||||||
struct ub_packed_rrset_key pk;
|
struct ub_packed_rrset_key pk;
|
||||||
enum sec_status sec;
|
enum sec_status sec;
|
||||||
|
@ -7808,7 +7809,7 @@ static int zonemd_dnssec_verify_rrset(struct auth_zone* z,
|
||||||
"zonemd: verify %s RRset with DNSKEY", typestr);
|
"zonemd: verify %s RRset with DNSKEY", typestr);
|
||||||
}
|
}
|
||||||
sec = dnskeyset_verify_rrset(env, ve, &pk, dnskey, sigalg, why_bogus, NULL,
|
sec = dnskeyset_verify_rrset(env, ve, &pk, dnskey, sigalg, why_bogus, NULL,
|
||||||
LDNS_SECTION_ANSWER, NULL, &verified);
|
LDNS_SECTION_ANSWER, NULL, &verified, reasonbuf, reasonlen);
|
||||||
if(sec == sec_status_secure) {
|
if(sec == sec_status_secure) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -7851,7 +7852,8 @@ static int nsec3_of_param_has_type(struct auth_rrset* nsec3, int algo,
|
||||||
static int zonemd_check_dnssec_absence(struct auth_zone* z,
|
static int zonemd_check_dnssec_absence(struct auth_zone* z,
|
||||||
struct module_env* env, struct module_stack* mods,
|
struct module_env* env, struct module_stack* mods,
|
||||||
struct ub_packed_rrset_key* dnskey, struct auth_data* apex,
|
struct ub_packed_rrset_key* dnskey, struct auth_data* apex,
|
||||||
char** reason, char** why_bogus, uint8_t* sigalg)
|
char** reason, char** why_bogus, uint8_t* sigalg, char* reasonbuf,
|
||||||
|
size_t reasonlen)
|
||||||
{
|
{
|
||||||
struct auth_rrset* nsec = NULL;
|
struct auth_rrset* nsec = NULL;
|
||||||
if(!apex) {
|
if(!apex) {
|
||||||
|
@ -7863,7 +7865,7 @@ static int zonemd_check_dnssec_absence(struct auth_zone* z,
|
||||||
struct ub_packed_rrset_key pk;
|
struct ub_packed_rrset_key pk;
|
||||||
/* dnssec verify the NSEC */
|
/* dnssec verify the NSEC */
|
||||||
if(!zonemd_dnssec_verify_rrset(z, env, mods, dnskey, apex,
|
if(!zonemd_dnssec_verify_rrset(z, env, mods, dnskey, apex,
|
||||||
nsec, why_bogus, sigalg)) {
|
nsec, why_bogus, sigalg, reasonbuf, reasonlen)) {
|
||||||
*reason = "DNSSEC verify failed for NSEC RRset";
|
*reason = "DNSSEC verify failed for NSEC RRset";
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -7906,7 +7908,7 @@ static int zonemd_check_dnssec_absence(struct auth_zone* z,
|
||||||
}
|
}
|
||||||
/* dnssec verify the NSEC3 */
|
/* dnssec verify the NSEC3 */
|
||||||
if(!zonemd_dnssec_verify_rrset(z, env, mods, dnskey, match,
|
if(!zonemd_dnssec_verify_rrset(z, env, mods, dnskey, match,
|
||||||
nsec3, why_bogus, sigalg)) {
|
nsec3, why_bogus, sigalg, reasonbuf, reasonlen)) {
|
||||||
*reason = "DNSSEC verify failed for NSEC3 RRset";
|
*reason = "DNSSEC verify failed for NSEC3 RRset";
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -7928,7 +7930,7 @@ static int zonemd_check_dnssec_soazonemd(struct auth_zone* z,
|
||||||
struct module_env* env, struct module_stack* mods,
|
struct module_env* env, struct module_stack* mods,
|
||||||
struct ub_packed_rrset_key* dnskey, struct auth_data* apex,
|
struct ub_packed_rrset_key* dnskey, struct auth_data* apex,
|
||||||
struct auth_rrset* zonemd_rrset, char** reason, char** why_bogus,
|
struct auth_rrset* zonemd_rrset, char** reason, char** why_bogus,
|
||||||
uint8_t* sigalg)
|
uint8_t* sigalg, char* reasonbuf, size_t reasonlen)
|
||||||
{
|
{
|
||||||
struct auth_rrset* soa;
|
struct auth_rrset* soa;
|
||||||
if(!apex) {
|
if(!apex) {
|
||||||
|
@ -7941,12 +7943,12 @@ static int zonemd_check_dnssec_soazonemd(struct auth_zone* z,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if(!zonemd_dnssec_verify_rrset(z, env, mods, dnskey, apex, soa,
|
if(!zonemd_dnssec_verify_rrset(z, env, mods, dnskey, apex, soa,
|
||||||
why_bogus, sigalg)) {
|
why_bogus, sigalg, reasonbuf, reasonlen)) {
|
||||||
*reason = "DNSSEC verify failed for SOA RRset";
|
*reason = "DNSSEC verify failed for SOA RRset";
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if(!zonemd_dnssec_verify_rrset(z, env, mods, dnskey, apex,
|
if(!zonemd_dnssec_verify_rrset(z, env, mods, dnskey, apex,
|
||||||
zonemd_rrset, why_bogus, sigalg)) {
|
zonemd_rrset, why_bogus, sigalg, reasonbuf, reasonlen)) {
|
||||||
*reason = "DNSSEC verify failed for ZONEMD RRset";
|
*reason = "DNSSEC verify failed for ZONEMD RRset";
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -8014,6 +8016,7 @@ auth_zone_verify_zonemd_with_key(struct auth_zone* z, struct module_env* env,
|
||||||
struct module_stack* mods, struct ub_packed_rrset_key* dnskey,
|
struct module_stack* mods, struct ub_packed_rrset_key* dnskey,
|
||||||
int is_insecure, char** result, uint8_t* sigalg)
|
int is_insecure, char** result, uint8_t* sigalg)
|
||||||
{
|
{
|
||||||
|
char reasonbuf[256];
|
||||||
char* reason = NULL, *why_bogus = NULL;
|
char* reason = NULL, *why_bogus = NULL;
|
||||||
struct auth_data* apex = NULL;
|
struct auth_data* apex = NULL;
|
||||||
struct auth_rrset* zonemd_rrset = NULL;
|
struct auth_rrset* zonemd_rrset = NULL;
|
||||||
|
@ -8042,7 +8045,8 @@ auth_zone_verify_zonemd_with_key(struct auth_zone* z, struct module_env* env,
|
||||||
} else if(!zonemd_rrset && dnskey && !is_insecure) {
|
} else if(!zonemd_rrset && dnskey && !is_insecure) {
|
||||||
/* fetch, DNSSEC verify, and check NSEC/NSEC3 */
|
/* fetch, DNSSEC verify, and check NSEC/NSEC3 */
|
||||||
if(!zonemd_check_dnssec_absence(z, env, mods, dnskey, apex,
|
if(!zonemd_check_dnssec_absence(z, env, mods, dnskey, apex,
|
||||||
&reason, &why_bogus, sigalg)) {
|
&reason, &why_bogus, sigalg, reasonbuf,
|
||||||
|
sizeof(reasonbuf))) {
|
||||||
auth_zone_zonemd_fail(z, env, reason, why_bogus, result);
|
auth_zone_zonemd_fail(z, env, reason, why_bogus, result);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -8050,7 +8054,8 @@ auth_zone_verify_zonemd_with_key(struct auth_zone* z, struct module_env* env,
|
||||||
} else if(zonemd_rrset && dnskey && !is_insecure) {
|
} else if(zonemd_rrset && dnskey && !is_insecure) {
|
||||||
/* check DNSSEC verify of SOA and ZONEMD */
|
/* check DNSSEC verify of SOA and ZONEMD */
|
||||||
if(!zonemd_check_dnssec_soazonemd(z, env, mods, dnskey, apex,
|
if(!zonemd_check_dnssec_soazonemd(z, env, mods, dnskey, apex,
|
||||||
zonemd_rrset, &reason, &why_bogus, sigalg)) {
|
zonemd_rrset, &reason, &why_bogus, sigalg, reasonbuf,
|
||||||
|
sizeof(reasonbuf))) {
|
||||||
auth_zone_zonemd_fail(z, env, reason, why_bogus, result);
|
auth_zone_zonemd_fail(z, env, reason, why_bogus, result);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -8107,6 +8112,8 @@ auth_zone_verify_zonemd_with_key(struct auth_zone* z, struct module_env* env,
|
||||||
* @param why_bogus: if the routine fails, returns the failure reason.
|
* @param why_bogus: if the routine fails, returns the failure reason.
|
||||||
* @param keystorage: where to store the ub_packed_rrset_key that is created
|
* @param keystorage: where to store the ub_packed_rrset_key that is created
|
||||||
* on success. A pointer to it is returned on success.
|
* on success. A pointer to it is returned on success.
|
||||||
|
* @param reasonbuf: buffer to use for fail reason string print.
|
||||||
|
* @param reasonlen: length of reasonbuf.
|
||||||
* @return the dnskey RRset, reference to zone data and keystorage, or
|
* @return the dnskey RRset, reference to zone data and keystorage, or
|
||||||
* NULL on failure.
|
* NULL on failure.
|
||||||
*/
|
*/
|
||||||
|
@ -8114,7 +8121,8 @@ static struct ub_packed_rrset_key*
|
||||||
zonemd_get_dnskey_from_anchor(struct auth_zone* z, struct module_env* env,
|
zonemd_get_dnskey_from_anchor(struct auth_zone* z, struct module_env* env,
|
||||||
struct module_stack* mods, struct trust_anchor* anchor,
|
struct module_stack* mods, struct trust_anchor* anchor,
|
||||||
int* is_insecure, char** why_bogus,
|
int* is_insecure, char** why_bogus,
|
||||||
struct ub_packed_rrset_key* keystorage)
|
struct ub_packed_rrset_key* keystorage, char* reasonbuf,
|
||||||
|
size_t reasonlen)
|
||||||
{
|
{
|
||||||
struct auth_data* apex;
|
struct auth_data* apex;
|
||||||
struct auth_rrset* dnskey_rrset;
|
struct auth_rrset* dnskey_rrset;
|
||||||
|
@ -8150,7 +8158,8 @@ zonemd_get_dnskey_from_anchor(struct auth_zone* z, struct module_env* env,
|
||||||
auth_zone_log(z->name, VERB_QUERY,
|
auth_zone_log(z->name, VERB_QUERY,
|
||||||
"zonemd: verify DNSKEY RRset with trust anchor");
|
"zonemd: verify DNSKEY RRset with trust anchor");
|
||||||
sec = val_verify_DNSKEY_with_TA(env, ve, keystorage, anchor->ds_rrset,
|
sec = val_verify_DNSKEY_with_TA(env, ve, keystorage, anchor->ds_rrset,
|
||||||
anchor->dnskey_rrset, NULL, why_bogus, NULL, NULL);
|
anchor->dnskey_rrset, NULL, why_bogus, NULL, NULL, reasonbuf,
|
||||||
|
reasonlen);
|
||||||
regional_free_all(env->scratch);
|
regional_free_all(env->scratch);
|
||||||
if(sec == sec_status_secure) {
|
if(sec == sec_status_secure) {
|
||||||
/* success */
|
/* success */
|
||||||
|
@ -8173,7 +8182,8 @@ static struct ub_packed_rrset_key*
|
||||||
auth_zone_verify_zonemd_key_with_ds(struct auth_zone* z,
|
auth_zone_verify_zonemd_key_with_ds(struct auth_zone* z,
|
||||||
struct module_env* env, struct module_stack* mods,
|
struct module_env* env, struct module_stack* mods,
|
||||||
struct ub_packed_rrset_key* ds, int* is_insecure, char** why_bogus,
|
struct ub_packed_rrset_key* ds, int* is_insecure, char** why_bogus,
|
||||||
struct ub_packed_rrset_key* keystorage, uint8_t* sigalg)
|
struct ub_packed_rrset_key* keystorage, uint8_t* sigalg,
|
||||||
|
char* reasonbuf, size_t reasonlen)
|
||||||
{
|
{
|
||||||
struct auth_data* apex;
|
struct auth_data* apex;
|
||||||
struct auth_rrset* dnskey_rrset;
|
struct auth_rrset* dnskey_rrset;
|
||||||
|
@ -8209,7 +8219,7 @@ auth_zone_verify_zonemd_key_with_ds(struct auth_zone* z,
|
||||||
keystorage->rk.rrset_class = htons(z->dclass);
|
keystorage->rk.rrset_class = htons(z->dclass);
|
||||||
auth_zone_log(z->name, VERB_QUERY, "zonemd: verify zone DNSKEY with DS");
|
auth_zone_log(z->name, VERB_QUERY, "zonemd: verify zone DNSKEY with DS");
|
||||||
sec = val_verify_DNSKEY_with_DS(env, ve, keystorage, ds, sigalg,
|
sec = val_verify_DNSKEY_with_DS(env, ve, keystorage, ds, sigalg,
|
||||||
why_bogus, NULL, NULL);
|
why_bogus, NULL, NULL, reasonbuf, reasonlen);
|
||||||
regional_free_all(env->scratch);
|
regional_free_all(env->scratch);
|
||||||
if(sec == sec_status_secure) {
|
if(sec == sec_status_secure) {
|
||||||
/* success */
|
/* success */
|
||||||
|
@ -8235,6 +8245,7 @@ void auth_zonemd_dnskey_lookup_callback(void* arg, int rcode, sldns_buffer* buf,
|
||||||
{
|
{
|
||||||
struct auth_zone* z = (struct auth_zone*)arg;
|
struct auth_zone* z = (struct auth_zone*)arg;
|
||||||
struct module_env* env;
|
struct module_env* env;
|
||||||
|
char reasonbuf[256];
|
||||||
char* reason = NULL, *ds_bogus = NULL, *typestr="DNSKEY";
|
char* reason = NULL, *ds_bogus = NULL, *typestr="DNSKEY";
|
||||||
struct ub_packed_rrset_key* dnskey = NULL, *ds = NULL;
|
struct ub_packed_rrset_key* dnskey = NULL, *ds = NULL;
|
||||||
int is_insecure = 0, downprot;
|
int is_insecure = 0, downprot;
|
||||||
|
@ -8346,7 +8357,8 @@ void auth_zonemd_dnskey_lookup_callback(void* arg, int rcode, sldns_buffer* buf,
|
||||||
if(!reason && !is_insecure && !dnskey && ds) {
|
if(!reason && !is_insecure && !dnskey && ds) {
|
||||||
dnskey = auth_zone_verify_zonemd_key_with_ds(z, env,
|
dnskey = auth_zone_verify_zonemd_key_with_ds(z, env,
|
||||||
&env->mesh->mods, ds, &is_insecure, &ds_bogus,
|
&env->mesh->mods, ds, &is_insecure, &ds_bogus,
|
||||||
&keystorage, downprot?sigalg:NULL);
|
&keystorage, downprot?sigalg:NULL, reasonbuf,
|
||||||
|
sizeof(reasonbuf));
|
||||||
if(!dnskey && !is_insecure && !reason)
|
if(!dnskey && !is_insecure && !reason)
|
||||||
reason = "DNSKEY verify with DS failed";
|
reason = "DNSKEY verify with DS failed";
|
||||||
}
|
}
|
||||||
|
@ -8354,6 +8366,7 @@ void auth_zonemd_dnskey_lookup_callback(void* arg, int rcode, sldns_buffer* buf,
|
||||||
if(reason) {
|
if(reason) {
|
||||||
auth_zone_zonemd_fail(z, env, reason, ds_bogus, NULL);
|
auth_zone_zonemd_fail(z, env, reason, ds_bogus, NULL);
|
||||||
lock_rw_unlock(&z->lock);
|
lock_rw_unlock(&z->lock);
|
||||||
|
regional_free_all(env->scratch);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8438,6 +8451,7 @@ zonemd_lookup_dnskey(struct auth_zone* z, struct module_env* env)
|
||||||
void auth_zone_verify_zonemd(struct auth_zone* z, struct module_env* env,
|
void auth_zone_verify_zonemd(struct auth_zone* z, struct module_env* env,
|
||||||
struct module_stack* mods, char** result, int offline, int only_online)
|
struct module_stack* mods, char** result, int offline, int only_online)
|
||||||
{
|
{
|
||||||
|
char reasonbuf[256];
|
||||||
char* reason = NULL, *why_bogus = NULL;
|
char* reason = NULL, *why_bogus = NULL;
|
||||||
struct trust_anchor* anchor = NULL;
|
struct trust_anchor* anchor = NULL;
|
||||||
struct ub_packed_rrset_key* dnskey = NULL;
|
struct ub_packed_rrset_key* dnskey = NULL;
|
||||||
|
@ -8472,7 +8486,8 @@ void auth_zone_verify_zonemd(struct auth_zone* z, struct module_env* env,
|
||||||
}
|
}
|
||||||
/* equal to trustanchor, no need for online lookups */
|
/* equal to trustanchor, no need for online lookups */
|
||||||
dnskey = zonemd_get_dnskey_from_anchor(z, env, mods, anchor,
|
dnskey = zonemd_get_dnskey_from_anchor(z, env, mods, anchor,
|
||||||
&is_insecure, &why_bogus, &keystorage);
|
&is_insecure, &why_bogus, &keystorage, reasonbuf,
|
||||||
|
sizeof(reasonbuf));
|
||||||
lock_basic_unlock(&anchor->lock);
|
lock_basic_unlock(&anchor->lock);
|
||||||
if(!dnskey && !reason && !is_insecure) {
|
if(!dnskey && !reason && !is_insecure) {
|
||||||
reason = "verify DNSKEY RRset with trust anchor failed";
|
reason = "verify DNSKEY RRset with trust anchor failed";
|
||||||
|
@ -8498,6 +8513,7 @@ void auth_zone_verify_zonemd(struct auth_zone* z, struct module_env* env,
|
||||||
|
|
||||||
if(reason) {
|
if(reason) {
|
||||||
auth_zone_zonemd_fail(z, env, reason, why_bogus, result);
|
auth_zone_zonemd_fail(z, env, reason, why_bogus, result);
|
||||||
|
regional_free_all(env->scratch);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
33
sbin/unwind/libunbound/services/cache/dns.c
vendored
33
sbin/unwind/libunbound/services/cache/dns.c
vendored
|
@ -96,7 +96,8 @@ store_rrsets(struct module_env* env, struct reply_info* rep, time_t now,
|
||||||
struct ub_packed_rrset_key* ck;
|
struct ub_packed_rrset_key* ck;
|
||||||
lock_rw_rdlock(&rep->ref[i].key->entry.lock);
|
lock_rw_rdlock(&rep->ref[i].key->entry.lock);
|
||||||
/* if deleted rrset, do not copy it */
|
/* if deleted rrset, do not copy it */
|
||||||
if(rep->ref[i].key->id == 0)
|
if(rep->ref[i].key->id == 0 ||
|
||||||
|
rep->ref[i].id != rep->ref[i].key->id)
|
||||||
ck = NULL;
|
ck = NULL;
|
||||||
else ck = packed_rrset_copy_region(
|
else ck = packed_rrset_copy_region(
|
||||||
rep->ref[i].key, region, now);
|
rep->ref[i].key, region, now);
|
||||||
|
@ -109,14 +110,22 @@ store_rrsets(struct module_env* env, struct reply_info* rep, time_t now,
|
||||||
/* no break: also copy key item */
|
/* no break: also copy key item */
|
||||||
/* the line below is matched by gcc regex and silences
|
/* the line below is matched by gcc regex and silences
|
||||||
* the fallthrough warning */
|
* the fallthrough warning */
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
case 1: /* ref updated, item inserted */
|
case 1: /* ref updated, item inserted */
|
||||||
rep->rrsets[i] = rep->ref[i].key;
|
rep->rrsets[i] = rep->ref[i].key;
|
||||||
}
|
/* ref was updated; make sure the message ttl is
|
||||||
/* if ref was updated make sure the message ttl is updated to
|
* updated to the minimum of the current rrsets. */
|
||||||
* the minimum of the current rrsets. */
|
lock_rw_rdlock(&rep->ref[i].key->entry.lock);
|
||||||
ttl = ((struct packed_rrset_data*)rep->rrsets[i]->entry.data)->ttl;
|
/* if deleted, skip ttl update. */
|
||||||
|
if(rep->ref[i].key->id != 0 &&
|
||||||
|
rep->ref[i].id == rep->ref[i].key->id) {
|
||||||
|
ttl = ((struct packed_rrset_data*)
|
||||||
|
rep->rrsets[i]->entry.data)->ttl;
|
||||||
if(ttl < min_ttl) min_ttl = ttl;
|
if(ttl < min_ttl) min_ttl = ttl;
|
||||||
|
}
|
||||||
|
lock_rw_unlock(&rep->ref[i].key->entry.lock);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(min_ttl < rep->ttl) {
|
if(min_ttl < rep->ttl) {
|
||||||
rep->ttl = min_ttl;
|
rep->ttl = min_ttl;
|
||||||
|
@ -337,6 +346,13 @@ find_add_addrs(struct module_env* env, uint16_t qclass,
|
||||||
* not use dns64 translation */
|
* not use dns64 translation */
|
||||||
neg = msg_cache_lookup(env, ns->name, ns->namelen,
|
neg = msg_cache_lookup(env, ns->name, ns->namelen,
|
||||||
LDNS_RR_TYPE_AAAA, qclass, 0, now, 0);
|
LDNS_RR_TYPE_AAAA, qclass, 0, now, 0);
|
||||||
|
/* Because recursion for lookup uses BIT_CD, check
|
||||||
|
* for that so it stops the recursion lookup, if a
|
||||||
|
* negative answer is cached. Because the cache uses
|
||||||
|
* the CD flag for type AAAA. */
|
||||||
|
if(!neg)
|
||||||
|
neg = msg_cache_lookup(env, ns->name, ns->namelen,
|
||||||
|
LDNS_RR_TYPE_AAAA, qclass, BIT_CD, now, 0);
|
||||||
if(neg) {
|
if(neg) {
|
||||||
delegpt_add_neg_msg(dp, neg);
|
delegpt_add_neg_msg(dp, neg);
|
||||||
lock_rw_unlock(&neg->entry.lock);
|
lock_rw_unlock(&neg->entry.lock);
|
||||||
|
@ -396,6 +412,13 @@ cache_fill_missing(struct module_env* env, uint16_t qclass,
|
||||||
* not use dns64 translation */
|
* not use dns64 translation */
|
||||||
neg = msg_cache_lookup(env, ns->name, ns->namelen,
|
neg = msg_cache_lookup(env, ns->name, ns->namelen,
|
||||||
LDNS_RR_TYPE_AAAA, qclass, 0, now, 0);
|
LDNS_RR_TYPE_AAAA, qclass, 0, now, 0);
|
||||||
|
/* Because recursion for lookup uses BIT_CD, check
|
||||||
|
* for that so it stops the recursion lookup, if a
|
||||||
|
* negative answer is cached. Because the cache uses
|
||||||
|
* the CD flag for type AAAA. */
|
||||||
|
if(!neg)
|
||||||
|
neg = msg_cache_lookup(env, ns->name, ns->namelen,
|
||||||
|
LDNS_RR_TYPE_AAAA, qclass, BIT_CD, now, 0);
|
||||||
if(neg) {
|
if(neg) {
|
||||||
delegpt_add_neg_msg(dp, neg);
|
delegpt_add_neg_msg(dp, neg);
|
||||||
lock_rw_unlock(&neg->entry.lock);
|
lock_rw_unlock(&neg->entry.lock);
|
||||||
|
|
27
sbin/unwind/libunbound/services/cache/infra.c
vendored
27
sbin/unwind/libunbound/services/cache/infra.c
vendored
|
@ -60,6 +60,16 @@
|
||||||
* can do this number of packets (until those all timeout too) */
|
* can do this number of packets (until those all timeout too) */
|
||||||
#define TIMEOUT_COUNT_MAX 3
|
#define TIMEOUT_COUNT_MAX 3
|
||||||
|
|
||||||
|
/** Minus 1000 because that is outside of the RTTBAND, so
|
||||||
|
* blacklisted servers stay blacklisted if this is chosen.
|
||||||
|
* If USEFUL_SERVER_TOP_TIMEOUT is below 1000 (configured via RTT_MAX_TIMEOUT,
|
||||||
|
* infra-cache-max-rtt) change it to just above the RTT_BAND. */
|
||||||
|
#define STILL_USEFUL_TIMEOUT ( \
|
||||||
|
USEFUL_SERVER_TOP_TIMEOUT < 1000 || \
|
||||||
|
USEFUL_SERVER_TOP_TIMEOUT - 1000 <= RTT_BAND \
|
||||||
|
?RTT_BAND + 1 \
|
||||||
|
:USEFUL_SERVER_TOP_TIMEOUT - 1000)
|
||||||
|
|
||||||
/** ratelimit value for delegation point */
|
/** ratelimit value for delegation point */
|
||||||
int infra_dp_ratelimit = 0;
|
int infra_dp_ratelimit = 0;
|
||||||
|
|
||||||
|
@ -347,6 +357,7 @@ infra_create(struct config_file* cfg)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
infra_ip_ratelimit = cfg->ip_ratelimit;
|
infra_ip_ratelimit = cfg->ip_ratelimit;
|
||||||
|
infra_ip_ratelimit_cookie = cfg->ip_ratelimit_cookie;
|
||||||
infra->client_ip_rates = slabhash_create(cfg->ip_ratelimit_slabs,
|
infra->client_ip_rates = slabhash_create(cfg->ip_ratelimit_slabs,
|
||||||
INFRA_HOST_STARTSIZE, cfg->ip_ratelimit_size, &ip_rate_sizefunc,
|
INFRA_HOST_STARTSIZE, cfg->ip_ratelimit_size, &ip_rate_sizefunc,
|
||||||
&ip_rate_compfunc, &ip_rate_delkeyfunc, &ip_rate_deldatafunc, NULL);
|
&ip_rate_compfunc, &ip_rate_delkeyfunc, &ip_rate_deldatafunc, NULL);
|
||||||
|
@ -398,6 +409,7 @@ infra_adjust(struct infra_cache* infra, struct config_file* cfg)
|
||||||
infra->infra_keep_probing = cfg->infra_keep_probing;
|
infra->infra_keep_probing = cfg->infra_keep_probing;
|
||||||
infra_dp_ratelimit = cfg->ratelimit;
|
infra_dp_ratelimit = cfg->ratelimit;
|
||||||
infra_ip_ratelimit = cfg->ip_ratelimit;
|
infra_ip_ratelimit = cfg->ip_ratelimit;
|
||||||
|
infra_ip_ratelimit_cookie = cfg->ip_ratelimit_cookie;
|
||||||
maxmem = cfg->infra_cache_numhosts * (sizeof(struct infra_key)+
|
maxmem = cfg->infra_cache_numhosts * (sizeof(struct infra_key)+
|
||||||
sizeof(struct infra_data)+INFRA_BYTES_NAME);
|
sizeof(struct infra_data)+INFRA_BYTES_NAME);
|
||||||
/* divide cachesize by slabs and multiply by slabs, because if the
|
/* divide cachesize by slabs and multiply by slabs, because if the
|
||||||
|
@ -656,7 +668,7 @@ infra_update_tcp_works(struct infra_cache* infra,
|
||||||
if(data->rtt.rto >= RTT_MAX_TIMEOUT)
|
if(data->rtt.rto >= RTT_MAX_TIMEOUT)
|
||||||
/* do not disqualify this server altogether, it is better
|
/* do not disqualify this server altogether, it is better
|
||||||
* than nothing */
|
* than nothing */
|
||||||
data->rtt.rto = RTT_MAX_TIMEOUT-1000;
|
data->rtt.rto = STILL_USEFUL_TIMEOUT;
|
||||||
lock_rw_unlock(&e->lock);
|
lock_rw_unlock(&e->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -796,7 +808,7 @@ infra_get_lame_rtt(struct infra_cache* infra,
|
||||||
&& infra->infra_keep_probing) {
|
&& infra->infra_keep_probing) {
|
||||||
/* single probe, keep probing */
|
/* single probe, keep probing */
|
||||||
if(*rtt >= USEFUL_SERVER_TOP_TIMEOUT)
|
if(*rtt >= USEFUL_SERVER_TOP_TIMEOUT)
|
||||||
*rtt = USEFUL_SERVER_TOP_TIMEOUT-1000;
|
*rtt = STILL_USEFUL_TIMEOUT;
|
||||||
} else if(host->rtt.rto >= PROBE_MAXRTO && timenow < host->probedelay
|
} else if(host->rtt.rto >= PROBE_MAXRTO && timenow < host->probedelay
|
||||||
&& rtt_notimeout(&host->rtt)*4 <= host->rtt.rto) {
|
&& rtt_notimeout(&host->rtt)*4 <= host->rtt.rto) {
|
||||||
/* single probe for this domain, and we are not probing */
|
/* single probe for this domain, and we are not probing */
|
||||||
|
@ -804,26 +816,23 @@ infra_get_lame_rtt(struct infra_cache* infra,
|
||||||
if(qtype == LDNS_RR_TYPE_A) {
|
if(qtype == LDNS_RR_TYPE_A) {
|
||||||
if(host->timeout_A >= TIMEOUT_COUNT_MAX)
|
if(host->timeout_A >= TIMEOUT_COUNT_MAX)
|
||||||
*rtt = USEFUL_SERVER_TOP_TIMEOUT;
|
*rtt = USEFUL_SERVER_TOP_TIMEOUT;
|
||||||
else *rtt = USEFUL_SERVER_TOP_TIMEOUT-1000;
|
else *rtt = STILL_USEFUL_TIMEOUT;
|
||||||
} else if(qtype == LDNS_RR_TYPE_AAAA) {
|
} else if(qtype == LDNS_RR_TYPE_AAAA) {
|
||||||
if(host->timeout_AAAA >= TIMEOUT_COUNT_MAX)
|
if(host->timeout_AAAA >= TIMEOUT_COUNT_MAX)
|
||||||
*rtt = USEFUL_SERVER_TOP_TIMEOUT;
|
*rtt = USEFUL_SERVER_TOP_TIMEOUT;
|
||||||
else *rtt = USEFUL_SERVER_TOP_TIMEOUT-1000;
|
else *rtt = STILL_USEFUL_TIMEOUT;
|
||||||
} else {
|
} else {
|
||||||
if(host->timeout_other >= TIMEOUT_COUNT_MAX)
|
if(host->timeout_other >= TIMEOUT_COUNT_MAX)
|
||||||
*rtt = USEFUL_SERVER_TOP_TIMEOUT;
|
*rtt = USEFUL_SERVER_TOP_TIMEOUT;
|
||||||
else *rtt = USEFUL_SERVER_TOP_TIMEOUT-1000;
|
else *rtt = STILL_USEFUL_TIMEOUT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* expired entry */
|
/* expired entry */
|
||||||
if(timenow > host->ttl) {
|
if(timenow > host->ttl) {
|
||||||
|
|
||||||
/* see if this can be a re-probe of an unresponsive server */
|
/* see if this can be a re-probe of an unresponsive server */
|
||||||
/* minus 1000 because that is outside of the RTTBAND, so
|
|
||||||
* blacklisted servers stay blacklisted if this is chosen */
|
|
||||||
if(host->rtt.rto >= USEFUL_SERVER_TOP_TIMEOUT) {
|
if(host->rtt.rto >= USEFUL_SERVER_TOP_TIMEOUT) {
|
||||||
lock_rw_unlock(&e->lock);
|
lock_rw_unlock(&e->lock);
|
||||||
*rtt = USEFUL_SERVER_TOP_TIMEOUT-1000;
|
*rtt = STILL_USEFUL_TIMEOUT;
|
||||||
*lame = 0;
|
*lame = 0;
|
||||||
*dnsseclame = 0;
|
*dnsseclame = 0;
|
||||||
*reclame = 0;
|
*reclame = 0;
|
||||||
|
|
|
@ -234,7 +234,7 @@ struct infra_cache* infra_adjust(struct infra_cache* infra,
|
||||||
struct config_file* cfg);
|
struct config_file* cfg);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Plain find infra data function (used by the the other functions)
|
* Plain find infra data function (used by the other functions)
|
||||||
* @param infra: infrastructure cache.
|
* @param infra: infrastructure cache.
|
||||||
* @param addr: host address.
|
* @param addr: host address.
|
||||||
* @param addrlen: length of addr.
|
* @param addrlen: length of addr.
|
||||||
|
|
|
@ -675,7 +675,7 @@ create_tcp_accept_sock(struct addrinfo *addr, int v6only, int* noproto,
|
||||||
int* reuseport, int transparent, int mss, int nodelay, int freebind,
|
int* reuseport, int transparent, int mss, int nodelay, int freebind,
|
||||||
int use_systemd, int dscp)
|
int use_systemd, int dscp)
|
||||||
{
|
{
|
||||||
int s;
|
int s = -1;
|
||||||
char* err;
|
char* err;
|
||||||
#if defined(SO_REUSEADDR) || defined(SO_REUSEPORT) || defined(IPV6_V6ONLY) || defined(IP_TRANSPARENT) || defined(IP_BINDANY) || defined(IP_FREEBIND) || defined(SO_BINDANY)
|
#if defined(SO_REUSEADDR) || defined(SO_REUSEPORT) || defined(IPV6_V6ONLY) || defined(IP_TRANSPARENT) || defined(IP_BINDANY) || defined(IP_FREEBIND) || defined(SO_BINDANY)
|
||||||
int on = 1;
|
int on = 1;
|
||||||
|
|
|
@ -242,7 +242,7 @@ lz_enter_zone_dname(struct local_zones* zones, uint8_t* nm, size_t len,
|
||||||
}
|
}
|
||||||
|
|
||||||
/** enter a new zone */
|
/** enter a new zone */
|
||||||
static struct local_zone*
|
struct local_zone*
|
||||||
lz_enter_zone(struct local_zones* zones, const char* name, const char* type,
|
lz_enter_zone(struct local_zones* zones, const char* name, const char* type,
|
||||||
uint16_t dclass)
|
uint16_t dclass)
|
||||||
{
|
{
|
||||||
|
@ -983,36 +983,39 @@ lz_enter_overrides(struct local_zones* zones, struct config_file* cfg)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** setup parent pointers, so that a lookup can be done for closest match */
|
/* return closest parent in the tree, NULL if none */
|
||||||
static void
|
static struct local_zone* find_closest_parent(struct local_zone* curr,
|
||||||
init_parents(struct local_zones* zones)
|
struct local_zone* prev)
|
||||||
{
|
{
|
||||||
struct local_zone* node, *prev = NULL, *p;
|
struct local_zone* p;
|
||||||
int m;
|
int m;
|
||||||
lock_rw_wrlock(&zones->lock);
|
if(!prev || prev->dclass != curr->dclass) return NULL;
|
||||||
RBTREE_FOR(node, struct local_zone*, &zones->ztree) {
|
(void)dname_lab_cmp(prev->name, prev->namelabs, curr->name,
|
||||||
lock_rw_wrlock(&node->lock);
|
curr->namelabs, &m); /* we know prev is smaller */
|
||||||
node->parent = NULL;
|
|
||||||
if(!prev || prev->dclass != node->dclass) {
|
|
||||||
prev = node;
|
|
||||||
lock_rw_unlock(&node->lock);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
(void)dname_lab_cmp(prev->name, prev->namelabs, node->name,
|
|
||||||
node->namelabs, &m); /* we know prev is smaller */
|
|
||||||
/* sort order like: . com. bla.com. zwb.com. net. */
|
/* sort order like: . com. bla.com. zwb.com. net. */
|
||||||
/* find the previous, or parent-parent-parent */
|
/* find the previous, or parent-parent-parent */
|
||||||
for(p = prev; p; p = p->parent)
|
for(p = prev; p; p = p->parent) {
|
||||||
/* looking for name with few labels, a parent */
|
/* looking for name with few labels, a parent */
|
||||||
if(p->namelabs <= m) {
|
if(p->namelabs <= m) {
|
||||||
/* ==: since prev matched m, this is closest*/
|
/* ==: since prev matched m, this is closest*/
|
||||||
/* <: prev matches more, but is not a parent,
|
/* <: prev matches more, but is not a parent,
|
||||||
* this one is a (grand)parent */
|
* this one is a (grand)parent */
|
||||||
node->parent = p;
|
return p;
|
||||||
break;
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
prev = node;
|
|
||||||
|
|
||||||
|
/** setup parent pointers, so that a lookup can be done for closest match */
|
||||||
|
void
|
||||||
|
lz_init_parents(struct local_zones* zones)
|
||||||
|
{
|
||||||
|
struct local_zone* node, *prev = NULL;
|
||||||
|
lock_rw_wrlock(&zones->lock);
|
||||||
|
RBTREE_FOR(node, struct local_zone*, &zones->ztree) {
|
||||||
|
lock_rw_wrlock(&node->lock);
|
||||||
|
node->parent = find_closest_parent(node, prev);
|
||||||
|
prev = node;
|
||||||
if(node->override_tree)
|
if(node->override_tree)
|
||||||
addr_tree_init_parents(node->override_tree);
|
addr_tree_init_parents(node->override_tree);
|
||||||
lock_rw_unlock(&node->lock);
|
lock_rw_unlock(&node->lock);
|
||||||
|
@ -1036,7 +1039,7 @@ lz_setup_implicit(struct local_zones* zones, struct config_file* cfg)
|
||||||
int nmlabs = 0;
|
int nmlabs = 0;
|
||||||
int match = 0; /* number of labels match count */
|
int match = 0; /* number of labels match count */
|
||||||
|
|
||||||
init_parents(zones); /* to enable local_zones_lookup() */
|
lz_init_parents(zones); /* to enable local_zones_lookup() */
|
||||||
for(p = cfg->local_data; p; p = p->next) {
|
for(p = cfg->local_data; p; p = p->next) {
|
||||||
uint8_t* rr_name;
|
uint8_t* rr_name;
|
||||||
uint16_t rr_class, rr_type;
|
uint16_t rr_class, rr_type;
|
||||||
|
@ -1202,7 +1205,7 @@ local_zones_apply_cfg(struct local_zones* zones, struct config_file* cfg)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* setup parent ptrs for lookup during data entry */
|
/* setup parent ptrs for lookup during data entry */
|
||||||
init_parents(zones);
|
lz_init_parents(zones);
|
||||||
/* insert local zone tags */
|
/* insert local zone tags */
|
||||||
if(!lz_enter_zone_tags(zones, cfg)) {
|
if(!lz_enter_zone_tags(zones, cfg)) {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -2028,7 +2031,9 @@ struct local_zone* local_zones_add_zone(struct local_zones* zones,
|
||||||
uint8_t* name, size_t len, int labs, uint16_t dclass,
|
uint8_t* name, size_t len, int labs, uint16_t dclass,
|
||||||
enum localzone_type tp)
|
enum localzone_type tp)
|
||||||
{
|
{
|
||||||
|
int exact;
|
||||||
/* create */
|
/* create */
|
||||||
|
struct local_zone *prev;
|
||||||
struct local_zone* z = local_zone_create(name, len, labs, tp, dclass);
|
struct local_zone* z = local_zone_create(name, len, labs, tp, dclass);
|
||||||
if(!z) {
|
if(!z) {
|
||||||
free(name);
|
free(name);
|
||||||
|
@ -2037,10 +2042,12 @@ struct local_zone* local_zones_add_zone(struct local_zones* zones,
|
||||||
lock_rw_wrlock(&z->lock);
|
lock_rw_wrlock(&z->lock);
|
||||||
|
|
||||||
/* find the closest parent */
|
/* find the closest parent */
|
||||||
z->parent = local_zones_find(zones, name, len, labs, dclass);
|
prev = local_zones_find_le(zones, name, len, labs, dclass, &exact);
|
||||||
|
if(!exact)
|
||||||
|
z->parent = find_closest_parent(z, prev);
|
||||||
|
|
||||||
/* insert into the tree */
|
/* insert into the tree */
|
||||||
if(!rbtree_insert(&zones->ztree, &z->node)) {
|
if(exact||!rbtree_insert(&zones->ztree, &z->node)) {
|
||||||
/* duplicate entry! */
|
/* duplicate entry! */
|
||||||
lock_rw_unlock(&z->lock);
|
lock_rw_unlock(&z->lock);
|
||||||
local_zone_delete(z);
|
local_zone_delete(z);
|
||||||
|
|
|
@ -641,4 +641,23 @@ local_zone_enter_rr(struct local_zone* z, uint8_t* nm, size_t nmlen,
|
||||||
*/
|
*/
|
||||||
struct local_data*
|
struct local_data*
|
||||||
local_zone_find_data(struct local_zone* z, uint8_t* nm, size_t nmlen, int nmlabs);
|
local_zone_find_data(struct local_zone* z, uint8_t* nm, size_t nmlen, int nmlabs);
|
||||||
|
|
||||||
|
/** Enter a new zone; returns with WRlock
|
||||||
|
* Made public for unit testing
|
||||||
|
* @param zones: the local zones tree
|
||||||
|
* @param name: name of the zone
|
||||||
|
* @param type: type of the zone
|
||||||
|
* @param dclass: class of the zone
|
||||||
|
* @return local_zone (or duplicate), NULL on parse and malloc failures
|
||||||
|
*/
|
||||||
|
struct local_zone*
|
||||||
|
lz_enter_zone(struct local_zones* zones, const char* name, const char* type,
|
||||||
|
uint16_t dclass);
|
||||||
|
|
||||||
|
/** Setup parent pointers, so that a lookup can be done for closest match
|
||||||
|
* Made public for unit testing
|
||||||
|
* @param zones: the local zones tree
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
lz_init_parents(struct local_zones* zones);
|
||||||
#endif /* SERVICES_LOCALZONE_H */
|
#endif /* SERVICES_LOCALZONE_H */
|
||||||
|
|
|
@ -413,6 +413,7 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
|
||||||
int timeout = mesh->env->cfg->serve_expired?
|
int timeout = mesh->env->cfg->serve_expired?
|
||||||
mesh->env->cfg->serve_expired_client_timeout:0;
|
mesh->env->cfg->serve_expired_client_timeout:0;
|
||||||
struct sldns_buffer* r_buffer = rep->c->buffer;
|
struct sldns_buffer* r_buffer = rep->c->buffer;
|
||||||
|
uint16_t mesh_flags = qflags&(BIT_RD|BIT_CD);
|
||||||
if(rep->c->tcp_req_info) {
|
if(rep->c->tcp_req_info) {
|
||||||
r_buffer = rep->c->tcp_req_info->spool_buffer;
|
r_buffer = rep->c->tcp_req_info->spool_buffer;
|
||||||
}
|
}
|
||||||
|
@ -425,7 +426,7 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(!unique)
|
if(!unique)
|
||||||
s = mesh_area_find(mesh, cinfo, qinfo, qflags&(BIT_RD|BIT_CD), 0, 0);
|
s = mesh_area_find(mesh, cinfo, qinfo, mesh_flags, 0, 0);
|
||||||
/* does this create a new reply state? */
|
/* does this create a new reply state? */
|
||||||
if(!s || s->list_select == mesh_no_list) {
|
if(!s || s->list_select == mesh_no_list) {
|
||||||
if(!mesh_make_new_space(mesh, rep->c->buffer)) {
|
if(!mesh_make_new_space(mesh, rep->c->buffer)) {
|
||||||
|
@ -453,7 +454,7 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
|
||||||
struct rbnode_type* n;
|
struct rbnode_type* n;
|
||||||
#endif
|
#endif
|
||||||
s = mesh_state_create(mesh->env, qinfo, cinfo,
|
s = mesh_state_create(mesh->env, qinfo, cinfo,
|
||||||
qflags&(BIT_RD|BIT_CD), 0, 0);
|
mesh_flags, 0, 0);
|
||||||
if(!s) {
|
if(!s) {
|
||||||
log_err("mesh_state_create: out of memory; SERVFAIL");
|
log_err("mesh_state_create: out of memory; SERVFAIL");
|
||||||
if(!inplace_cb_reply_servfail_call(mesh->env, qinfo, NULL, NULL,
|
if(!inplace_cb_reply_servfail_call(mesh->env, qinfo, NULL, NULL,
|
||||||
|
@ -565,6 +566,8 @@ servfail_mem:
|
||||||
edns->opt_list_inplace_cb_out = NULL;
|
edns->opt_list_inplace_cb_out = NULL;
|
||||||
error_encode(r_buffer, LDNS_RCODE_SERVFAIL,
|
error_encode(r_buffer, LDNS_RCODE_SERVFAIL,
|
||||||
qinfo, qid, qflags, edns);
|
qinfo, qid, qflags, edns);
|
||||||
|
if(rep->c->use_h2)
|
||||||
|
http2_stream_remove_mesh_state(rep->c->h2_stream);
|
||||||
comm_point_send_reply(rep);
|
comm_point_send_reply(rep);
|
||||||
if(added)
|
if(added)
|
||||||
mesh_state_delete(&s->s);
|
mesh_state_delete(&s->s);
|
||||||
|
@ -583,8 +586,9 @@ mesh_new_callback(struct mesh_area* mesh, struct query_info* qinfo,
|
||||||
int was_detached = 0;
|
int was_detached = 0;
|
||||||
int was_noreply = 0;
|
int was_noreply = 0;
|
||||||
int added = 0;
|
int added = 0;
|
||||||
|
uint16_t mesh_flags = qflags&(BIT_RD|BIT_CD);
|
||||||
if(!unique)
|
if(!unique)
|
||||||
s = mesh_area_find(mesh, NULL, qinfo, qflags&(BIT_RD|BIT_CD), 0, 0);
|
s = mesh_area_find(mesh, NULL, qinfo, mesh_flags, 0, 0);
|
||||||
|
|
||||||
/* there are no limits on the number of callbacks */
|
/* there are no limits on the number of callbacks */
|
||||||
|
|
||||||
|
@ -594,7 +598,7 @@ mesh_new_callback(struct mesh_area* mesh, struct query_info* qinfo,
|
||||||
struct rbnode_type* n;
|
struct rbnode_type* n;
|
||||||
#endif
|
#endif
|
||||||
s = mesh_state_create(mesh->env, qinfo, NULL,
|
s = mesh_state_create(mesh->env, qinfo, NULL,
|
||||||
qflags&(BIT_RD|BIT_CD), 0, 0);
|
mesh_flags, 0, 0);
|
||||||
if(!s) {
|
if(!s) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -673,8 +677,12 @@ static void mesh_schedule_prefetch(struct mesh_area* mesh,
|
||||||
struct query_info* qinfo, uint16_t qflags, time_t leeway, int run,
|
struct query_info* qinfo, uint16_t qflags, time_t leeway, int run,
|
||||||
int rpz_passthru)
|
int rpz_passthru)
|
||||||
{
|
{
|
||||||
|
/* Explicitly set the BIT_RD regardless of the client's flags. This is
|
||||||
|
* for a prefetch query (no client attached) but it needs to be treated
|
||||||
|
* as a recursion query. */
|
||||||
|
uint16_t mesh_flags = BIT_RD|(qflags&BIT_CD);
|
||||||
struct mesh_state* s = mesh_area_find(mesh, NULL, qinfo,
|
struct mesh_state* s = mesh_area_find(mesh, NULL, qinfo,
|
||||||
qflags&(BIT_RD|BIT_CD), 0, 0);
|
mesh_flags, 0, 0);
|
||||||
#ifdef UNBOUND_DEBUG
|
#ifdef UNBOUND_DEBUG
|
||||||
struct rbnode_type* n;
|
struct rbnode_type* n;
|
||||||
#endif
|
#endif
|
||||||
|
@ -694,8 +702,7 @@ static void mesh_schedule_prefetch(struct mesh_area* mesh,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
s = mesh_state_create(mesh->env, qinfo, NULL,
|
s = mesh_state_create(mesh->env, qinfo, NULL, mesh_flags, 0, 0);
|
||||||
qflags&(BIT_RD|BIT_CD), 0, 0);
|
|
||||||
if(!s) {
|
if(!s) {
|
||||||
log_err("prefetch mesh_state_create: out of memory");
|
log_err("prefetch mesh_state_create: out of memory");
|
||||||
return;
|
return;
|
||||||
|
@ -756,14 +763,17 @@ static void mesh_schedule_prefetch_subnet(struct mesh_area* mesh,
|
||||||
#ifdef UNBOUND_DEBUG
|
#ifdef UNBOUND_DEBUG
|
||||||
struct rbnode_type* n;
|
struct rbnode_type* n;
|
||||||
#endif
|
#endif
|
||||||
|
/* Explicitly set the BIT_RD regardless of the client's flags. This is
|
||||||
|
* for a prefetch query (no client attached) but it needs to be treated
|
||||||
|
* as a recursion query. */
|
||||||
|
uint16_t mesh_flags = BIT_RD|(qflags&BIT_CD);
|
||||||
if(!mesh_make_new_space(mesh, NULL)) {
|
if(!mesh_make_new_space(mesh, NULL)) {
|
||||||
verbose(VERB_ALGO, "Too many queries. dropped prefetch.");
|
verbose(VERB_ALGO, "Too many queries. dropped prefetch.");
|
||||||
mesh->stats_dropped ++;
|
mesh->stats_dropped ++;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
s = mesh_state_create(mesh->env, qinfo, NULL,
|
s = mesh_state_create(mesh->env, qinfo, NULL, mesh_flags, 0, 0);
|
||||||
qflags&(BIT_RD|BIT_CD), 0, 0);
|
|
||||||
if(!s) {
|
if(!s) {
|
||||||
log_err("prefetch_subnet mesh_state_create: out of memory");
|
log_err("prefetch_subnet mesh_state_create: out of memory");
|
||||||
return;
|
return;
|
||||||
|
@ -966,6 +976,8 @@ mesh_state_cleanup(struct mesh_state* mstate)
|
||||||
for(; rep; rep=rep->next) {
|
for(; rep; rep=rep->next) {
|
||||||
infra_wait_limit_dec(mesh->env->infra_cache,
|
infra_wait_limit_dec(mesh->env->infra_cache,
|
||||||
&rep->query_reply, mesh->env->cfg);
|
&rep->query_reply, mesh->env->cfg);
|
||||||
|
if(rep->query_reply.c->use_h2)
|
||||||
|
http2_stream_remove_mesh_state(rep->h2_stream);
|
||||||
comm_point_drop_reply(&rep->query_reply);
|
comm_point_drop_reply(&rep->query_reply);
|
||||||
log_assert(mesh->num_reply_addrs > 0);
|
log_assert(mesh->num_reply_addrs > 0);
|
||||||
mesh->num_reply_addrs--;
|
mesh->num_reply_addrs--;
|
||||||
|
@ -1522,6 +1534,8 @@ void mesh_query_done(struct mesh_state* mstate)
|
||||||
infra_wait_limit_dec(mstate->s.env->infra_cache,
|
infra_wait_limit_dec(mstate->s.env->infra_cache,
|
||||||
&r->query_reply, mstate->s.env->cfg);
|
&r->query_reply, mstate->s.env->cfg);
|
||||||
mstate->reply_list = NULL;
|
mstate->reply_list = NULL;
|
||||||
|
if(r->query_reply.c->use_h2)
|
||||||
|
http2_stream_remove_mesh_state(r->h2_stream);
|
||||||
comm_point_drop_reply(&r->query_reply);
|
comm_point_drop_reply(&r->query_reply);
|
||||||
mstate->reply_list = reply_list;
|
mstate->reply_list = reply_list;
|
||||||
mstate->s.env->mesh->stats_dropped++;
|
mstate->s.env->mesh->stats_dropped++;
|
||||||
|
@ -1554,6 +1568,9 @@ void mesh_query_done(struct mesh_state* mstate)
|
||||||
infra_wait_limit_dec(mstate->s.env->infra_cache,
|
infra_wait_limit_dec(mstate->s.env->infra_cache,
|
||||||
&r->query_reply, mstate->s.env->cfg);
|
&r->query_reply, mstate->s.env->cfg);
|
||||||
mstate->reply_list = NULL;
|
mstate->reply_list = NULL;
|
||||||
|
if(r->query_reply.c->use_h2) {
|
||||||
|
http2_stream_remove_mesh_state(r->h2_stream);
|
||||||
|
}
|
||||||
comm_point_drop_reply(&r->query_reply);
|
comm_point_drop_reply(&r->query_reply);
|
||||||
mstate->reply_list = reply_list;
|
mstate->reply_list = reply_list;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1568,6 +1585,8 @@ void mesh_query_done(struct mesh_state* mstate)
|
||||||
tcp_req_info_remove_mesh_state(r->query_reply.c->tcp_req_info, mstate);
|
tcp_req_info_remove_mesh_state(r->query_reply.c->tcp_req_info, mstate);
|
||||||
r_buffer = NULL;
|
r_buffer = NULL;
|
||||||
}
|
}
|
||||||
|
/* mesh_send_reply removed mesh state from
|
||||||
|
* http2_stream. */
|
||||||
prev = r;
|
prev = r;
|
||||||
prev_buffer = r_buffer;
|
prev_buffer = r_buffer;
|
||||||
}
|
}
|
||||||
|
@ -1720,6 +1739,7 @@ int mesh_state_add_reply(struct mesh_state* s, struct edns_data* edns,
|
||||||
return 0;
|
return 0;
|
||||||
if(rep->c->use_h2)
|
if(rep->c->use_h2)
|
||||||
r->h2_stream = rep->c->h2_stream;
|
r->h2_stream = rep->c->h2_stream;
|
||||||
|
else r->h2_stream = NULL;
|
||||||
|
|
||||||
/* Data related to local alias stored in 'qinfo' (if any) is ephemeral
|
/* Data related to local alias stored in 'qinfo' (if any) is ephemeral
|
||||||
* and can be different for different original queries (even if the
|
* and can be different for different original queries (even if the
|
||||||
|
@ -2243,6 +2263,8 @@ mesh_serve_expired_callback(void* arg)
|
||||||
infra_wait_limit_dec(mstate->s.env->infra_cache,
|
infra_wait_limit_dec(mstate->s.env->infra_cache,
|
||||||
&r->query_reply, mstate->s.env->cfg);
|
&r->query_reply, mstate->s.env->cfg);
|
||||||
mstate->reply_list = NULL;
|
mstate->reply_list = NULL;
|
||||||
|
if(r->query_reply.c->use_h2)
|
||||||
|
http2_stream_remove_mesh_state(r->h2_stream);
|
||||||
comm_point_drop_reply(&r->query_reply);
|
comm_point_drop_reply(&r->query_reply);
|
||||||
mstate->reply_list = reply_list;
|
mstate->reply_list = reply_list;
|
||||||
mstate->s.env->mesh->stats_dropped++;
|
mstate->s.env->mesh->stats_dropped++;
|
||||||
|
@ -2276,6 +2298,7 @@ mesh_serve_expired_callback(void* arg)
|
||||||
r, r_buffer, prev, prev_buffer);
|
r, r_buffer, prev, prev_buffer);
|
||||||
if(r->query_reply.c->tcp_req_info)
|
if(r->query_reply.c->tcp_req_info)
|
||||||
tcp_req_info_remove_mesh_state(r->query_reply.c->tcp_req_info, mstate);
|
tcp_req_info_remove_mesh_state(r->query_reply.c->tcp_req_info, mstate);
|
||||||
|
/* mesh_send_reply removed mesh state from http2_stream. */
|
||||||
infra_wait_limit_dec(mstate->s.env->infra_cache,
|
infra_wait_limit_dec(mstate->s.env->infra_cache,
|
||||||
&r->query_reply, mstate->s.env->cfg);
|
&r->query_reply, mstate->s.env->cfg);
|
||||||
prev = r;
|
prev = r;
|
||||||
|
|
|
@ -95,6 +95,16 @@ modstack_init(struct module_stack* stack)
|
||||||
stack->mod = NULL;
|
stack->mod = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
modstack_free(struct module_stack* stack)
|
||||||
|
{
|
||||||
|
if(!stack)
|
||||||
|
return;
|
||||||
|
stack->num = 0;
|
||||||
|
free(stack->mod);
|
||||||
|
stack->mod = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
modstack_config(struct module_stack* stack, const char* module_conf)
|
modstack_config(struct module_stack* stack, const char* module_conf)
|
||||||
{
|
{
|
||||||
|
@ -223,17 +233,58 @@ module_func_block* module_factory(const char** str)
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
modstack_setup(struct module_stack* stack, const char* module_conf,
|
modstack_call_startup(struct module_stack* stack, const char* module_conf,
|
||||||
struct module_env* env)
|
struct module_env* env)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
if(stack->num != 0)
|
if(stack->num != 0)
|
||||||
modstack_desetup(stack, env);
|
fatal_exit("unexpected already initialised modules");
|
||||||
/* fixed setup of the modules */
|
/* fixed setup of the modules */
|
||||||
if(!modstack_config(stack, module_conf)) {
|
if(!modstack_config(stack, module_conf)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
for(i=0; i<stack->num; i++) {
|
||||||
|
if(stack->mod[i]->startup == NULL)
|
||||||
|
continue;
|
||||||
|
verbose(VERB_OPS, "startup module %d: %s",
|
||||||
|
i, stack->mod[i]->name);
|
||||||
|
fptr_ok(fptr_whitelist_mod_startup(stack->mod[i]->startup));
|
||||||
|
if(!(*stack->mod[i]->startup)(env, i)) {
|
||||||
|
log_err("module startup for module %s failed",
|
||||||
|
stack->mod[i]->name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
modstack_call_init(struct module_stack* stack, const char* module_conf,
|
||||||
|
struct module_env* env)
|
||||||
|
{
|
||||||
|
int i, changed = 0;
|
||||||
env->need_to_validate = 0; /* set by module init below */
|
env->need_to_validate = 0; /* set by module init below */
|
||||||
|
for(i=0; i<stack->num; i++) {
|
||||||
|
while(*module_conf && isspace(*module_conf))
|
||||||
|
module_conf++;
|
||||||
|
if(strncmp(stack->mod[i]->name, module_conf,
|
||||||
|
strlen(stack->mod[i]->name))) {
|
||||||
|
if(stack->mod[i]->startup || stack->mod[i]->destartup) {
|
||||||
|
log_err("changed module ordering during reload not supported, for module that needs startup");
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
changed = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
module_conf += strlen(stack->mod[i]->name);
|
||||||
|
}
|
||||||
|
if(changed) {
|
||||||
|
modstack_free(stack);
|
||||||
|
if(!modstack_config(stack, module_conf)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for(i=0; i<stack->num; i++) {
|
for(i=0; i<stack->num; i++) {
|
||||||
verbose(VERB_OPS, "init module %d: %s",
|
verbose(VERB_OPS, "init module %d: %s",
|
||||||
i, stack->mod[i]->name);
|
i, stack->mod[i]->name);
|
||||||
|
@ -248,16 +299,25 @@ modstack_setup(struct module_stack* stack, const char* module_conf,
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
modstack_desetup(struct module_stack* stack, struct module_env* env)
|
modstack_call_deinit(struct module_stack* stack, struct module_env* env)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for(i=0; i<stack->num; i++) {
|
for(i=0; i<stack->num; i++) {
|
||||||
fptr_ok(fptr_whitelist_mod_deinit(stack->mod[i]->deinit));
|
fptr_ok(fptr_whitelist_mod_deinit(stack->mod[i]->deinit));
|
||||||
(*stack->mod[i]->deinit)(env, i);
|
(*stack->mod[i]->deinit)(env, i);
|
||||||
}
|
}
|
||||||
stack->num = 0;
|
}
|
||||||
free(stack->mod);
|
|
||||||
stack->mod = NULL;
|
void
|
||||||
|
modstack_call_destartup(struct module_stack* stack, struct module_env* env)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for(i=0; i<stack->num; i++) {
|
||||||
|
if(stack->mod[i]->destartup == NULL)
|
||||||
|
continue;
|
||||||
|
fptr_ok(fptr_whitelist_mod_destartup(stack->mod[i]->destartup));
|
||||||
|
(*stack->mod[i]->destartup)(env, i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
|
@ -60,6 +60,23 @@ struct module_stack {
|
||||||
*/
|
*/
|
||||||
void modstack_init(struct module_stack* stack);
|
void modstack_init(struct module_stack* stack);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Free the stack of modules
|
||||||
|
* @param stack: stack that frees up memory.
|
||||||
|
*/
|
||||||
|
void modstack_free(struct module_stack* stack);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialises modules and assignes ids. Calls module_startup().
|
||||||
|
* @param stack: Expected empty, filled according to module_conf
|
||||||
|
* @param module_conf: string what modules to initialize
|
||||||
|
* @param env: module environment which is inited by the modules.
|
||||||
|
* environment should have a superalloc, cfg,
|
||||||
|
* @return on false a module init failed.
|
||||||
|
*/
|
||||||
|
int modstack_call_startup(struct module_stack* stack, const char* module_conf,
|
||||||
|
struct module_env* env);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read config file module settings and set up the modfunc block
|
* Read config file module settings and set up the modfunc block
|
||||||
* @param stack: the stack of modules (empty before call).
|
* @param stack: the stack of modules (empty before call).
|
||||||
|
@ -83,24 +100,31 @@ struct module_func_block* module_factory(const char** str);
|
||||||
const char** module_list_avail(void);
|
const char** module_list_avail(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Setup modules. Assigns ids and calls module_init.
|
* Init modules. Calls module_init().
|
||||||
* @param stack: if not empty beforehand, it will be desetup()ed.
|
* @param stack: It is modstack_setupped().
|
||||||
* It is then modstack_configged().
|
* @param module_conf: module ordering to check against the ordering in stack.
|
||||||
* @param module_conf: string what modules to insert.
|
* fails on changed ordering.
|
||||||
* @param env: module environment which is inited by the modules.
|
* @param env: module environment which is inited by the modules.
|
||||||
* environment should have a superalloc, cfg,
|
* environment should have a superalloc, cfg,
|
||||||
* env.need_to_validate is set by the modules.
|
* env.need_to_validate is set by the modules.
|
||||||
* @return on false a module init failed.
|
* @return on false a module init failed.
|
||||||
*/
|
*/
|
||||||
int modstack_setup(struct module_stack* stack, const char* module_conf,
|
int modstack_call_init(struct module_stack* stack, const char* module_conf,
|
||||||
struct module_env* env);
|
struct module_env* env);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Desetup the modules, deinit, delete.
|
* Deinit the modules.
|
||||||
* @param stack: made empty.
|
* @param stack: made empty.
|
||||||
* @param env: module env for module deinit() calls.
|
* @param env: module env for module deinit() calls.
|
||||||
*/
|
*/
|
||||||
void modstack_desetup(struct module_stack* stack, struct module_env* env);
|
void modstack_call_deinit(struct module_stack* stack, struct module_env* env);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destartup the modules, close, delete.
|
||||||
|
* @param stack: made empty.
|
||||||
|
* @param env: module env for module destartup() calls.
|
||||||
|
*/
|
||||||
|
void modstack_call_destartup(struct module_stack* stack, struct module_env* env);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find index of module by name.
|
* Find index of module by name.
|
||||||
|
|
|
@ -2051,7 +2051,8 @@ select_id(struct outside_network* outnet, struct pending* pend,
|
||||||
}
|
}
|
||||||
|
|
||||||
/** return true is UDP connect error needs to be logged */
|
/** return true is UDP connect error needs to be logged */
|
||||||
static int udp_connect_needs_log(int err)
|
static int udp_connect_needs_log(int err, struct sockaddr_storage* addr,
|
||||||
|
socklen_t addrlen)
|
||||||
{
|
{
|
||||||
switch(err) {
|
switch(err) {
|
||||||
case ECONNREFUSED:
|
case ECONNREFUSED:
|
||||||
|
@ -2075,6 +2076,15 @@ static int udp_connect_needs_log(int err)
|
||||||
if(verbosity >= VERB_ALGO)
|
if(verbosity >= VERB_ALGO)
|
||||||
return 1;
|
return 1;
|
||||||
return 0;
|
return 0;
|
||||||
|
case EINVAL:
|
||||||
|
/* Stop 'Invalid argument for fe80::/10' addresses appearing
|
||||||
|
* in the logs, at low verbosity. They cannot be sent to. */
|
||||||
|
if(addr_is_ip6linklocal(addr, addrlen)) {
|
||||||
|
if(verbosity >= VERB_ALGO)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -2141,7 +2151,8 @@ select_ifport(struct outside_network* outnet, struct pending* pend,
|
||||||
/* connect() to the destination */
|
/* connect() to the destination */
|
||||||
if(connect(fd, (struct sockaddr*)&pend->addr,
|
if(connect(fd, (struct sockaddr*)&pend->addr,
|
||||||
pend->addrlen) < 0) {
|
pend->addrlen) < 0) {
|
||||||
if(udp_connect_needs_log(errno)) {
|
if(udp_connect_needs_log(errno,
|
||||||
|
&pend->addr, pend->addrlen)) {
|
||||||
log_err_addr("udp connect failed",
|
log_err_addr("udp connect failed",
|
||||||
strerror(errno), &pend->addr,
|
strerror(errno), &pend->addr,
|
||||||
pend->addrlen);
|
pend->addrlen);
|
||||||
|
@ -3455,7 +3466,10 @@ outnet_serviced_query(struct outside_network* outnet,
|
||||||
timenow = *env->now;
|
timenow = *env->now;
|
||||||
if(!infra_ratelimit_inc(env->infra_cache, zone,
|
if(!infra_ratelimit_inc(env->infra_cache, zone,
|
||||||
zonelen, timenow, env->cfg->ratelimit_backoff,
|
zonelen, timenow, env->cfg->ratelimit_backoff,
|
||||||
&qstate->qinfo, qstate->reply)) {
|
&qstate->qinfo,
|
||||||
|
qstate->mesh_info->reply_list
|
||||||
|
?&qstate->mesh_info->reply_list->query_reply
|
||||||
|
:NULL)) {
|
||||||
/* Can we pass through with slip factor? */
|
/* Can we pass through with slip factor? */
|
||||||
if(env->cfg->ratelimit_factor == 0 ||
|
if(env->cfg->ratelimit_factor == 0 ||
|
||||||
ub_random_max(env->rnd,
|
ub_random_max(env->rnd,
|
||||||
|
|
|
@ -242,10 +242,14 @@ rpz_action_to_localzone_type(enum rpz_action a)
|
||||||
case RPZ_NODATA_ACTION: return local_zone_always_nodata;
|
case RPZ_NODATA_ACTION: return local_zone_always_nodata;
|
||||||
case RPZ_DROP_ACTION: return local_zone_always_deny;
|
case RPZ_DROP_ACTION: return local_zone_always_deny;
|
||||||
case RPZ_PASSTHRU_ACTION: return local_zone_always_transparent;
|
case RPZ_PASSTHRU_ACTION: return local_zone_always_transparent;
|
||||||
case RPZ_LOCAL_DATA_ACTION: /* fallthrough */
|
case RPZ_LOCAL_DATA_ACTION:
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
|
/* fallthrough */
|
||||||
case RPZ_CNAME_OVERRIDE_ACTION: return local_zone_redirect;
|
case RPZ_CNAME_OVERRIDE_ACTION: return local_zone_redirect;
|
||||||
case RPZ_TCP_ONLY_ACTION: return local_zone_truncate;
|
case RPZ_TCP_ONLY_ACTION: return local_zone_truncate;
|
||||||
case RPZ_INVALID_ACTION: /* fallthrough */
|
case RPZ_INVALID_ACTION:
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
|
/* fallthrough */
|
||||||
default: return local_zone_invalid;
|
default: return local_zone_invalid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -258,10 +262,14 @@ rpz_action_to_respip_action(enum rpz_action a)
|
||||||
case RPZ_NODATA_ACTION: return respip_always_nodata;
|
case RPZ_NODATA_ACTION: return respip_always_nodata;
|
||||||
case RPZ_DROP_ACTION: return respip_always_deny;
|
case RPZ_DROP_ACTION: return respip_always_deny;
|
||||||
case RPZ_PASSTHRU_ACTION: return respip_always_transparent;
|
case RPZ_PASSTHRU_ACTION: return respip_always_transparent;
|
||||||
case RPZ_LOCAL_DATA_ACTION: /* fallthrough */
|
case RPZ_LOCAL_DATA_ACTION:
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
|
/* fallthrough */
|
||||||
case RPZ_CNAME_OVERRIDE_ACTION: return respip_redirect;
|
case RPZ_CNAME_OVERRIDE_ACTION: return respip_redirect;
|
||||||
case RPZ_TCP_ONLY_ACTION: return respip_truncate;
|
case RPZ_TCP_ONLY_ACTION: return respip_truncate;
|
||||||
case RPZ_INVALID_ACTION: /* fallthrough */
|
case RPZ_INVALID_ACTION:
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
|
/* fallthrough */
|
||||||
default: return respip_invalid;
|
default: return respip_invalid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -276,7 +284,9 @@ localzone_type_to_rpz_action(enum localzone_type lzt)
|
||||||
case local_zone_always_transparent: return RPZ_PASSTHRU_ACTION;
|
case local_zone_always_transparent: return RPZ_PASSTHRU_ACTION;
|
||||||
case local_zone_redirect: return RPZ_LOCAL_DATA_ACTION;
|
case local_zone_redirect: return RPZ_LOCAL_DATA_ACTION;
|
||||||
case local_zone_truncate: return RPZ_TCP_ONLY_ACTION;
|
case local_zone_truncate: return RPZ_TCP_ONLY_ACTION;
|
||||||
case local_zone_invalid: /* fallthrough */
|
case local_zone_invalid:
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
|
/* fallthrough */
|
||||||
default: return RPZ_INVALID_ACTION;
|
default: return RPZ_INVALID_ACTION;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -291,7 +301,9 @@ respip_action_to_rpz_action(enum respip_action a)
|
||||||
case respip_always_transparent: return RPZ_PASSTHRU_ACTION;
|
case respip_always_transparent: return RPZ_PASSTHRU_ACTION;
|
||||||
case respip_redirect: return RPZ_LOCAL_DATA_ACTION;
|
case respip_redirect: return RPZ_LOCAL_DATA_ACTION;
|
||||||
case respip_truncate: return RPZ_TCP_ONLY_ACTION;
|
case respip_truncate: return RPZ_TCP_ONLY_ACTION;
|
||||||
case respip_invalid: /* fallthrough */
|
case respip_invalid:
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
|
/* fallthrough */
|
||||||
default: return RPZ_INVALID_ACTION;
|
default: return RPZ_INVALID_ACTION;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2435,11 +2447,10 @@ rpz_callback_from_iterator_module(struct module_qstate* ms, struct iter_qstate*
|
||||||
if(ms->env == NULL || ms->env->auth_zones == NULL) { return 0; }
|
if(ms->env == NULL || ms->env->auth_zones == NULL) { return 0; }
|
||||||
|
|
||||||
az = ms->env->auth_zones;
|
az = ms->env->auth_zones;
|
||||||
|
lock_rw_rdlock(&az->rpz_lock);
|
||||||
|
|
||||||
verbose(VERB_ALGO, "rpz: iterator module callback: have_rpz=%d", az->rpz_first != NULL);
|
verbose(VERB_ALGO, "rpz: iterator module callback: have_rpz=%d", az->rpz_first != NULL);
|
||||||
|
|
||||||
lock_rw_rdlock(&az->rpz_lock);
|
|
||||||
|
|
||||||
/* precedence of RPZ works, loosely, like this:
|
/* precedence of RPZ works, loosely, like this:
|
||||||
* CNAMEs in order of the CNAME chain. rpzs in the order they are
|
* CNAMEs in order of the CNAME chain. rpzs in the order they are
|
||||||
* configured. In an RPZ: first client-IP addr, then QNAME, then
|
* configured. In an RPZ: first client-IP addr, then QNAME, then
|
||||||
|
@ -2454,6 +2465,13 @@ rpz_callback_from_iterator_module(struct module_qstate* ms, struct iter_qstate*
|
||||||
lock_rw_unlock(&a->lock);
|
lock_rw_unlock(&a->lock);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if(r->taglist && (!ms->client_info ||
|
||||||
|
!taglist_intersect(r->taglist, r->taglistlen,
|
||||||
|
ms->client_info->taglist,
|
||||||
|
ms->client_info->taglen))) {
|
||||||
|
lock_rw_unlock(&a->lock);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
/* the nsdname has precedence over the nsip triggers */
|
/* the nsdname has precedence over the nsip triggers */
|
||||||
z = rpz_delegation_point_zone_lookup(is->dp, r->nsdname_zones,
|
z = rpz_delegation_point_zone_lookup(is->dp, r->nsdname_zones,
|
||||||
|
@ -2512,6 +2530,13 @@ struct dns_msg* rpz_callback_from_iterator_cname(struct module_qstate* ms,
|
||||||
lock_rw_unlock(&a->lock);
|
lock_rw_unlock(&a->lock);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if(r->taglist && (!ms->client_info ||
|
||||||
|
!taglist_intersect(r->taglist, r->taglistlen,
|
||||||
|
ms->client_info->taglist,
|
||||||
|
ms->client_info->taglen))) {
|
||||||
|
lock_rw_unlock(&a->lock);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
z = rpz_find_zone(r->local_zones, is->qchase.qname,
|
z = rpz_find_zone(r->local_zones, is->qchase.qname,
|
||||||
is->qchase.qname_len, is->qchase.qclass, 0, 0, 0);
|
is->qchase.qname_len, is->qchase.qclass, 0, 0, 0);
|
||||||
if(z && r->action_override == RPZ_DISABLED_ACTION) {
|
if(z && r->action_override == RPZ_DISABLED_ACTION) {
|
||||||
|
|
|
@ -106,7 +106,7 @@ ssize_t sldns_bget_token(struct sldns_buffer *b, char *token, const char *delim,
|
||||||
* \param[in] k_del keyword delimiter
|
* \param[in] k_del keyword delimiter
|
||||||
* \param[out] data the data found
|
* \param[out] data the data found
|
||||||
* \param[in] d_del the data delimiter
|
* \param[in] d_del the data delimiter
|
||||||
* \param[in] data_limit maximum size the the data buffer
|
* \param[in] data_limit maximum size the data buffer
|
||||||
* \return the number of character read
|
* \return the number of character read
|
||||||
*/
|
*/
|
||||||
ssize_t sldns_fget_keyword_data(FILE *f, const char *keyword, const char *k_del, char *data, const char *d_del, size_t data_limit);
|
ssize_t sldns_fget_keyword_data(FILE *f, const char *keyword, const char *k_del, char *data, const char *d_del, size_t data_limit);
|
||||||
|
@ -119,7 +119,7 @@ ssize_t sldns_fget_keyword_data(FILE *f, const char *keyword, const char *k_del,
|
||||||
* \param[in] k_del keyword delimiter
|
* \param[in] k_del keyword delimiter
|
||||||
* \param[out] data the data found
|
* \param[out] data the data found
|
||||||
* \param[in] d_del the data delimiter
|
* \param[in] d_del the data delimiter
|
||||||
* \param[in] data_limit maximum size the the data buffer
|
* \param[in] data_limit maximum size the data buffer
|
||||||
* \param[in] line_nr pointer to an integer containing the current line number (for
|
* \param[in] line_nr pointer to an integer containing the current line number (for
|
||||||
debugging purposes)
|
debugging purposes)
|
||||||
* \return the number of character read
|
* \return the number of character read
|
||||||
|
@ -134,7 +134,7 @@ ssize_t sldns_fget_keyword_data_l(FILE *f, const char *keyword, const char *k_de
|
||||||
* \param[in] k_del keyword delimiter
|
* \param[in] k_del keyword delimiter
|
||||||
* \param[out] data the data found
|
* \param[out] data the data found
|
||||||
* \param[in] d_del the data delimiter
|
* \param[in] d_del the data delimiter
|
||||||
* \param[in] data_limit maximum size the the data buffer
|
* \param[in] data_limit maximum size the data buffer
|
||||||
* \return the number of character read
|
* \return the number of character read
|
||||||
*/
|
*/
|
||||||
ssize_t sldns_bget_keyword_data(struct sldns_buffer *b, const char *keyword, const char *k_del, char *data, const char *d_del, size_t data_limit);
|
ssize_t sldns_bget_keyword_data(struct sldns_buffer *b, const char *keyword, const char *k_del, char *data, const char *d_del, size_t data_limit);
|
||||||
|
|
|
@ -436,11 +436,13 @@ sldns_b32_ntop_base(const uint8_t* src, size_t src_sz, char* dst, size_t dst_sz,
|
||||||
|
|
||||||
/* ........ ........ ....4444 4....... ........ */
|
/* ........ ........ ....4444 4....... ........ */
|
||||||
c = src[3] >> 7 ;
|
c = src[3] >> 7 ;
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
case 3: dst[4] = b32[(src[2] & 0x0f) << 1 | c];
|
case 3: dst[4] = b32[(src[2] & 0x0f) << 1 | c];
|
||||||
|
|
||||||
/* ........ .......3 3333.... ........ ........ */
|
/* ........ .......3 3333.... ........ ........ */
|
||||||
c = src[2] >> 4 ;
|
c = src[2] >> 4 ;
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
case 2: dst[3] = b32[(src[1] & 0x01) << 4 | c];
|
case 2: dst[3] = b32[(src[1] & 0x01) << 4 | c];
|
||||||
|
|
||||||
|
@ -449,6 +451,7 @@ sldns_b32_ntop_base(const uint8_t* src, size_t src_sz, char* dst, size_t dst_sz,
|
||||||
|
|
||||||
/* .....111 11...... ........ ........ ........ */
|
/* .....111 11...... ........ ........ ........ */
|
||||||
c = src[1] >> 6 ;
|
c = src[1] >> 6 ;
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
case 1: dst[1] = b32[(src[0] & 0x07) << 2 | c];
|
case 1: dst[1] = b32[(src[0] & 0x07) << 2 | c];
|
||||||
|
|
||||||
|
@ -460,11 +463,14 @@ sldns_b32_ntop_base(const uint8_t* src, size_t src_sz, char* dst, size_t dst_sz,
|
||||||
switch (src_sz) {
|
switch (src_sz) {
|
||||||
case 1: dst[2] = '=';
|
case 1: dst[2] = '=';
|
||||||
dst[3] = '=';
|
dst[3] = '=';
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
case 2: dst[4] = '=';
|
case 2: dst[4] = '=';
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
case 3: dst[5] = '=';
|
case 3: dst[5] = '=';
|
||||||
dst[6] = '=';
|
dst[6] = '=';
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
case 4: dst[7] = '=';
|
case 4: dst[7] = '=';
|
||||||
}
|
}
|
||||||
|
@ -577,17 +583,20 @@ sldns_b32_pton_base(const char* src, size_t src_sz, uint8_t* dst, size_t dst_sz,
|
||||||
/* ........ ........ ........ .55555.. ........ */
|
/* ........ ........ ........ .55555.. ........ */
|
||||||
/* ........ ........ ....4444 4....... ........ */
|
/* ........ ........ ....4444 4....... ........ */
|
||||||
dst[3] = buf[4] << 7 | buf[5] << 2 | buf[6] >> 3;
|
dst[3] = buf[4] << 7 | buf[5] << 2 | buf[6] >> 3;
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
|
|
||||||
case 5: /* ........ ........ ....4444 4....... ........ */
|
case 5: /* ........ ........ ....4444 4....... ........ */
|
||||||
/* ........ .......3 3333.... ........ ........ */
|
/* ........ .......3 3333.... ........ ........ */
|
||||||
dst[2] = buf[3] << 4 | buf[4] >> 1;
|
dst[2] = buf[3] << 4 | buf[4] >> 1;
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
|
|
||||||
case 4: /* ........ .......3 3333.... ........ ........ */
|
case 4: /* ........ .......3 3333.... ........ ........ */
|
||||||
/* ........ ..22222. ........ ........ ........ */
|
/* ........ ..22222. ........ ........ ........ */
|
||||||
/* .....111 11...... ........ ........ ........ */
|
/* .....111 11...... ........ ........ ........ */
|
||||||
dst[1] = buf[1] << 6 | buf[2] << 1 | buf[3] >> 4;
|
dst[1] = buf[1] << 6 | buf[2] << 1 | buf[3] >> 4;
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
|
|
||||||
case 2: /* .....111 11...... ........ ........ ........ */
|
case 2: /* .....111 11...... ........ ........ ........ */
|
||||||
|
|
|
@ -470,6 +470,11 @@ enum sldns_enum_ede_code
|
||||||
LDNS_EDE_NO_REACHABLE_AUTHORITY = 22,
|
LDNS_EDE_NO_REACHABLE_AUTHORITY = 22,
|
||||||
LDNS_EDE_NETWORK_ERROR = 23,
|
LDNS_EDE_NETWORK_ERROR = 23,
|
||||||
LDNS_EDE_INVALID_DATA = 24,
|
LDNS_EDE_INVALID_DATA = 24,
|
||||||
|
LDNS_EDE_SIGNATURE_EXPIRED_BEFORE_VALID = 25,
|
||||||
|
LDNS_EDE_TOO_EARLY = 26,
|
||||||
|
LDNS_EDE_UNSUPPORTED_NSEC3_ITERATIONS = 27,
|
||||||
|
LDNS_EDE_BADPROXYPOLICY = 28,
|
||||||
|
LDNS_EDE_SYNTHESIZED = 29
|
||||||
};
|
};
|
||||||
typedef enum sldns_enum_ede_code sldns_ede_code;
|
typedef enum sldns_enum_ede_code sldns_ede_code;
|
||||||
|
|
||||||
|
|
|
@ -228,6 +228,11 @@ static sldns_lookup_table sldns_edns_ede_codes_data[] = {
|
||||||
{ LDNS_EDE_NO_REACHABLE_AUTHORITY, "No Reachable Authority" },
|
{ LDNS_EDE_NO_REACHABLE_AUTHORITY, "No Reachable Authority" },
|
||||||
{ LDNS_EDE_NETWORK_ERROR, "Network Error" },
|
{ LDNS_EDE_NETWORK_ERROR, "Network Error" },
|
||||||
{ LDNS_EDE_INVALID_DATA, "Invalid Data" },
|
{ LDNS_EDE_INVALID_DATA, "Invalid Data" },
|
||||||
|
{ LDNS_EDE_SIGNATURE_EXPIRED_BEFORE_VALID, "Signature Expired Before Valid" },
|
||||||
|
{ LDNS_EDE_TOO_EARLY, "Non-Replayable Transactions Received in 0-RTT Data" },
|
||||||
|
{ LDNS_EDE_UNSUPPORTED_NSEC3_ITERATIONS, "Unsupported NSEC3 Iterations Value" },
|
||||||
|
{ LDNS_EDE_BADPROXYPOLICY, "Unable to Conform to Policy" },
|
||||||
|
{ LDNS_EDE_SYNTHESIZED, "Synthesized Answer" },
|
||||||
{ 0, NULL}
|
{ 0, NULL}
|
||||||
};
|
};
|
||||||
sldns_lookup_table* sldns_edns_ede_codes = sldns_edns_ede_codes_data;
|
sldns_lookup_table* sldns_edns_ede_codes = sldns_edns_ede_codes_data;
|
||||||
|
@ -1236,6 +1241,7 @@ int sldns_wire2str_svcparam_scan(uint8_t** d, size_t* dlen, char** s, size_t* sl
|
||||||
r = sldns_wire2str_svcparam_ech2str(s, slen, data_len, *d);
|
r = sldns_wire2str_svcparam_ech2str(s, slen, data_len, *d);
|
||||||
break;
|
break;
|
||||||
case SVCB_KEY_DOHPATH:
|
case SVCB_KEY_DOHPATH:
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
default:
|
default:
|
||||||
r = sldns_str_print(s, slen, "=\"");
|
r = sldns_str_print(s, slen, "=\"");
|
||||||
|
|
|
@ -466,6 +466,18 @@ void *unbound_stat_realloc(void *ptr, size_t size)
|
||||||
memcpy(res+8, &mem_special, sizeof(mem_special));
|
memcpy(res+8, &mem_special, sizeof(mem_special));
|
||||||
return res+16;
|
return res+16;
|
||||||
}
|
}
|
||||||
|
/** strdup with stats */
|
||||||
|
char *unbound_stat_strdup(const char* s)
|
||||||
|
{
|
||||||
|
size_t len;
|
||||||
|
char* res;
|
||||||
|
if(!s) return NULL;
|
||||||
|
len = strlen(s);
|
||||||
|
res = unbound_stat_malloc(len+1);
|
||||||
|
if(!res) return NULL;
|
||||||
|
memmove(res, s, len+1);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
/** log to file where alloc was done */
|
/** log to file where alloc was done */
|
||||||
void *unbound_stat_malloc_log(size_t size, const char* file, int line,
|
void *unbound_stat_malloc_log(size_t size, const char* file, int line,
|
||||||
|
@ -507,6 +519,15 @@ void *unbound_stat_realloc_log(void *ptr, size_t size, const char* file,
|
||||||
return unbound_stat_realloc(ptr, size);
|
return unbound_stat_realloc(ptr, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** log to file where strdup was done */
|
||||||
|
char *unbound_stat_strdup_log(const char *s, const char* file, int line,
|
||||||
|
const char* func)
|
||||||
|
{
|
||||||
|
log_info("%s:%d %s strdup size %u", file, line, func,
|
||||||
|
(s?(unsigned)strlen(s)+1:0));
|
||||||
|
return unbound_stat_strdup(s);
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* UNBOUND_ALLOC_STATS */
|
#endif /* UNBOUND_ALLOC_STATS */
|
||||||
#ifdef UNBOUND_ALLOC_LITE
|
#ifdef UNBOUND_ALLOC_LITE
|
||||||
#undef malloc
|
#undef malloc
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#include <errno.h>
|
||||||
#ifdef HAVE_TIME_H
|
#ifdef HAVE_TIME_H
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -386,6 +387,7 @@ config_create(void)
|
||||||
memset(cfg->cookie_secret, 0, sizeof(cfg->cookie_secret));
|
memset(cfg->cookie_secret, 0, sizeof(cfg->cookie_secret));
|
||||||
cfg->cookie_secret_len = 16;
|
cfg->cookie_secret_len = 16;
|
||||||
init_cookie_secret(cfg->cookie_secret, cfg->cookie_secret_len);
|
init_cookie_secret(cfg->cookie_secret, cfg->cookie_secret_len);
|
||||||
|
cfg->cookie_secret_file = NULL;
|
||||||
#ifdef USE_CACHEDB
|
#ifdef USE_CACHEDB
|
||||||
if(!(cfg->cachedb_backend = strdup("testframe"))) goto error_exit;
|
if(!(cfg->cachedb_backend = strdup("testframe"))) goto error_exit;
|
||||||
if(!(cfg->cachedb_secret = strdup("default"))) goto error_exit;
|
if(!(cfg->cachedb_secret = strdup("default"))) goto error_exit;
|
||||||
|
@ -769,6 +771,7 @@ int config_set_option(struct config_file* cfg, const char* opt,
|
||||||
else S_YNO("dnstap-send-version:", dnstap_send_version)
|
else S_YNO("dnstap-send-version:", dnstap_send_version)
|
||||||
else S_STR("dnstap-identity:", dnstap_identity)
|
else S_STR("dnstap-identity:", dnstap_identity)
|
||||||
else S_STR("dnstap-version:", dnstap_version)
|
else S_STR("dnstap-version:", dnstap_version)
|
||||||
|
else S_NUMBER_OR_ZERO("dnstap-sample-rate:", dnstap_sample_rate)
|
||||||
else S_YNO("dnstap-log-resolver-query-messages:",
|
else S_YNO("dnstap-log-resolver-query-messages:",
|
||||||
dnstap_log_resolver_query_messages)
|
dnstap_log_resolver_query_messages)
|
||||||
else S_YNO("dnstap-log-resolver-response-messages:",
|
else S_YNO("dnstap-log-resolver-response-messages:",
|
||||||
|
@ -837,6 +840,8 @@ int config_set_option(struct config_file* cfg, const char* opt,
|
||||||
{ IS_NUMBER_OR_ZERO; cfg->ipsecmod_max_ttl = atoi(val); }
|
{ IS_NUMBER_OR_ZERO; cfg->ipsecmod_max_ttl = atoi(val); }
|
||||||
else S_YNO("ipsecmod-strict:", ipsecmod_strict)
|
else S_YNO("ipsecmod-strict:", ipsecmod_strict)
|
||||||
#endif
|
#endif
|
||||||
|
else S_YNO("answer-cookie:", do_answer_cookie)
|
||||||
|
else S_STR("cookie-secret-file:", cookie_secret_file)
|
||||||
#ifdef USE_CACHEDB
|
#ifdef USE_CACHEDB
|
||||||
else S_YNO("cachedb-no-store:", cachedb_no_store)
|
else S_YNO("cachedb-no-store:", cachedb_no_store)
|
||||||
else S_YNO("cachedb-check-when-serve-expired:", cachedb_check_when_serve_expired)
|
else S_YNO("cachedb-check-when-serve-expired:", cachedb_check_when_serve_expired)
|
||||||
|
@ -1248,6 +1253,7 @@ config_get_option(struct config_file* cfg, const char* opt,
|
||||||
else O_YNO(opt, "dnstap-send-version", dnstap_send_version)
|
else O_YNO(opt, "dnstap-send-version", dnstap_send_version)
|
||||||
else O_STR(opt, "dnstap-identity", dnstap_identity)
|
else O_STR(opt, "dnstap-identity", dnstap_identity)
|
||||||
else O_STR(opt, "dnstap-version", dnstap_version)
|
else O_STR(opt, "dnstap-version", dnstap_version)
|
||||||
|
else O_UNS(opt, "dnstap-sample-rate", dnstap_sample_rate)
|
||||||
else O_YNO(opt, "dnstap-log-resolver-query-messages",
|
else O_YNO(opt, "dnstap-log-resolver-query-messages",
|
||||||
dnstap_log_resolver_query_messages)
|
dnstap_log_resolver_query_messages)
|
||||||
else O_YNO(opt, "dnstap-log-resolver-response-messages",
|
else O_YNO(opt, "dnstap-log-resolver-response-messages",
|
||||||
|
@ -1333,6 +1339,8 @@ config_get_option(struct config_file* cfg, const char* opt,
|
||||||
else O_LST(opt, "ipsecmod-whitelist", ipsecmod_whitelist)
|
else O_LST(opt, "ipsecmod-whitelist", ipsecmod_whitelist)
|
||||||
else O_YNO(opt, "ipsecmod-strict", ipsecmod_strict)
|
else O_YNO(opt, "ipsecmod-strict", ipsecmod_strict)
|
||||||
#endif
|
#endif
|
||||||
|
else O_YNO(opt, "answer-cookie", do_answer_cookie)
|
||||||
|
else O_STR(opt, "cookie-secret-file", cookie_secret_file)
|
||||||
#ifdef USE_CACHEDB
|
#ifdef USE_CACHEDB
|
||||||
else O_STR(opt, "backend", cachedb_backend)
|
else O_STR(opt, "backend", cachedb_backend)
|
||||||
else O_STR(opt, "secret-seed", cachedb_secret)
|
else O_STR(opt, "secret-seed", cachedb_secret)
|
||||||
|
@ -1718,6 +1726,7 @@ config_delete(struct config_file* cfg)
|
||||||
free(cfg->ipsecmod_hook);
|
free(cfg->ipsecmod_hook);
|
||||||
config_delstrlist(cfg->ipsecmod_whitelist);
|
config_delstrlist(cfg->ipsecmod_whitelist);
|
||||||
#endif
|
#endif
|
||||||
|
free(cfg->cookie_secret_file);
|
||||||
#ifdef USE_CACHEDB
|
#ifdef USE_CACHEDB
|
||||||
free(cfg->cachedb_backend);
|
free(cfg->cachedb_backend);
|
||||||
free(cfg->cachedb_secret);
|
free(cfg->cachedb_secret);
|
||||||
|
@ -1772,6 +1781,39 @@ init_outgoing_availports(int* a, int num)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
extract_port_from_str(const char* str, int max_port) {
|
||||||
|
char* endptr;
|
||||||
|
long int value;
|
||||||
|
if (str == NULL || *str == '\0') {
|
||||||
|
log_err("str: '%s' is invalid", (str?str:"NULL"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
value = strtol(str, &endptr, 10);
|
||||||
|
if ((endptr == str) || (*endptr != '\0')) {
|
||||||
|
log_err("cannot parse port number '%s'", str);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (errno == ERANGE) {
|
||||||
|
log_err("overflow occurred when parsing '%s'", str);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value == 0 && strcmp(str, "0") != 0) {
|
||||||
|
log_err("cannot parse port number '%s'", str);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value < 0 || value >= max_port) {
|
||||||
|
log_err(" '%s' is out of bounds [0, %d)", str, max_port);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (int)value;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
cfg_mark_ports(const char* str, int allow, int* avail, int num)
|
cfg_mark_ports(const char* str, int allow, int* avail, int num)
|
||||||
{
|
{
|
||||||
|
@ -1782,53 +1824,45 @@ cfg_mark_ports(const char* str, int allow, int* avail, int num)
|
||||||
"options");
|
"options");
|
||||||
#endif
|
#endif
|
||||||
if(!mid) {
|
if(!mid) {
|
||||||
int port = atoi(str);
|
int port = extract_port_from_str(str, num);
|
||||||
if(port < 0) {
|
if(port < 0) {
|
||||||
log_err("port number is negative: %d", port);
|
log_err("Failed to parse the port number");
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if(port == 0 && strcmp(str, "0") != 0) {
|
|
||||||
log_err("cannot parse port number '%s'", str);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if(port < num)
|
if(port < num)
|
||||||
avail[port] = (allow?port:0);
|
avail[port] = (allow?port:0);
|
||||||
} else {
|
} else {
|
||||||
int i, low, high = atoi(mid+1);
|
|
||||||
char buf[16];
|
char buf[16];
|
||||||
|
int i, low;
|
||||||
|
int high = extract_port_from_str(mid+1, num);
|
||||||
if(high < 0) {
|
if(high < 0) {
|
||||||
log_err("port number is negative: %d", high);
|
log_err("Failed to parse the port number");
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if(high == 0 && strcmp(mid+1, "0") != 0) {
|
|
||||||
log_err("cannot parse port number '%s'", mid+1);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( (int)(mid-str)+1 >= (int)sizeof(buf) ) {
|
if( (int)(mid-str)+1 >= (int)sizeof(buf) ) {
|
||||||
log_err("cannot parse port number '%s'", str);
|
log_err("cannot parse port number '%s'", str);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(mid > str)
|
if(mid > str)
|
||||||
memcpy(buf, str, (size_t)(mid-str));
|
memcpy(buf, str, (size_t)(mid-str));
|
||||||
buf[mid-str] = 0;
|
buf[mid-str] = 0;
|
||||||
low = atoi(buf);
|
low = extract_port_from_str(buf, num);
|
||||||
if(low < 0) {
|
if(low < 0) {
|
||||||
log_err("port number is negative: %d", low);
|
log_err("Failed to parse the port number");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if(low == 0 && strcmp(buf, "0") != 0) {
|
|
||||||
log_err("cannot parse port number '%s'", buf);
|
if (low > high) {
|
||||||
|
log_err("Low value is greater than high value");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if(high > num) {
|
|
||||||
/* Stop very high values from taking a long time. */
|
|
||||||
high = num;
|
|
||||||
}
|
|
||||||
for(i=low; i<=high; i++) {
|
for(i=low; i<=high; i++) {
|
||||||
if(i < num)
|
if(i < num)
|
||||||
avail[i] = (allow?i:0);
|
avail[i] = (allow?i:0);
|
||||||
}
|
}
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -592,6 +592,8 @@ struct config_file {
|
||||||
char* dnstap_identity;
|
char* dnstap_identity;
|
||||||
/** dnstap "version", package version is used if "". */
|
/** dnstap "version", package version is used if "". */
|
||||||
char* dnstap_version;
|
char* dnstap_version;
|
||||||
|
/** dnstap sample rate */
|
||||||
|
int dnstap_sample_rate;
|
||||||
|
|
||||||
/** true to log dnstap RESOLVER_QUERY message events */
|
/** true to log dnstap RESOLVER_QUERY message events */
|
||||||
int dnstap_log_resolver_query_messages;
|
int dnstap_log_resolver_query_messages;
|
||||||
|
@ -748,6 +750,8 @@ struct config_file {
|
||||||
uint8_t cookie_secret[40];
|
uint8_t cookie_secret[40];
|
||||||
/** cookie secret length */
|
/** cookie secret length */
|
||||||
size_t cookie_secret_len;
|
size_t cookie_secret_len;
|
||||||
|
/** path to cookie secret store */
|
||||||
|
char* cookie_secret_file;
|
||||||
|
|
||||||
/* ipset module */
|
/* ipset module */
|
||||||
#ifdef USE_IPSET
|
#ifdef USE_IPSET
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -513,6 +513,7 @@ dnstap-log-forwarder-query-messages{COLON} {
|
||||||
YDVAR(1, VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES) }
|
YDVAR(1, VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES) }
|
||||||
dnstap-log-forwarder-response-messages{COLON} {
|
dnstap-log-forwarder-response-messages{COLON} {
|
||||||
YDVAR(1, VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES) }
|
YDVAR(1, VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES) }
|
||||||
|
dnstap-sample-rate { YDVAR(1, VAR_DNSTAP_SAMPLE_RATE) }
|
||||||
disable-dnssec-lame-check{COLON} { YDVAR(1, VAR_DISABLE_DNSSEC_LAME_CHECK) }
|
disable-dnssec-lame-check{COLON} { YDVAR(1, VAR_DISABLE_DNSSEC_LAME_CHECK) }
|
||||||
ip-ratelimit{COLON} { YDVAR(1, VAR_IP_RATELIMIT) }
|
ip-ratelimit{COLON} { YDVAR(1, VAR_IP_RATELIMIT) }
|
||||||
ip-ratelimit-cookie{COLON} { YDVAR(1, VAR_IP_RATELIMIT_COOKIE) }
|
ip-ratelimit-cookie{COLON} { YDVAR(1, VAR_IP_RATELIMIT_COOKIE) }
|
||||||
|
@ -581,6 +582,7 @@ udp-upstream-without-downstream{COLON} { YDVAR(1, VAR_UDP_UPSTREAM_WITHOUT_DOWNS
|
||||||
tcp-connection-limit{COLON} { YDVAR(2, VAR_TCP_CONNECTION_LIMIT) }
|
tcp-connection-limit{COLON} { YDVAR(2, VAR_TCP_CONNECTION_LIMIT) }
|
||||||
answer-cookie{COLON} { YDVAR(1, VAR_ANSWER_COOKIE ) }
|
answer-cookie{COLON} { YDVAR(1, VAR_ANSWER_COOKIE ) }
|
||||||
cookie-secret{COLON} { YDVAR(1, VAR_COOKIE_SECRET) }
|
cookie-secret{COLON} { YDVAR(1, VAR_COOKIE_SECRET) }
|
||||||
|
cookie-secret-file{COLON} { YDVAR(1, VAR_COOKIE_SECRET_FILE) }
|
||||||
edns-client-string{COLON} { YDVAR(2, VAR_EDNS_CLIENT_STRING) }
|
edns-client-string{COLON} { YDVAR(2, VAR_EDNS_CLIENT_STRING) }
|
||||||
edns-client-string-opcode{COLON} { YDVAR(1, VAR_EDNS_CLIENT_STRING_OPCODE) }
|
edns-client-string-opcode{COLON} { YDVAR(1, VAR_EDNS_CLIENT_STRING_OPCODE) }
|
||||||
nsid{COLON} { YDVAR(1, VAR_NSID ) }
|
nsid{COLON} { YDVAR(1, VAR_NSID ) }
|
||||||
|
|
|
@ -187,171 +187,173 @@
|
||||||
#define VAR_DNSTAP_LOG_CLIENT_RESPONSE_MESSAGES 443
|
#define VAR_DNSTAP_LOG_CLIENT_RESPONSE_MESSAGES 443
|
||||||
#define VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES 444
|
#define VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES 444
|
||||||
#define VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES 445
|
#define VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES 445
|
||||||
#define VAR_RESPONSE_IP_TAG 446
|
#define VAR_DNSTAP_SAMPLE_RATE 446
|
||||||
#define VAR_RESPONSE_IP 447
|
#define VAR_RESPONSE_IP_TAG 447
|
||||||
#define VAR_RESPONSE_IP_DATA 448
|
#define VAR_RESPONSE_IP 448
|
||||||
#define VAR_HARDEN_ALGO_DOWNGRADE 449
|
#define VAR_RESPONSE_IP_DATA 449
|
||||||
#define VAR_IP_TRANSPARENT 450
|
#define VAR_HARDEN_ALGO_DOWNGRADE 450
|
||||||
#define VAR_IP_DSCP 451
|
#define VAR_IP_TRANSPARENT 451
|
||||||
#define VAR_DISABLE_DNSSEC_LAME_CHECK 452
|
#define VAR_IP_DSCP 452
|
||||||
#define VAR_IP_RATELIMIT 453
|
#define VAR_DISABLE_DNSSEC_LAME_CHECK 453
|
||||||
#define VAR_IP_RATELIMIT_SLABS 454
|
#define VAR_IP_RATELIMIT 454
|
||||||
#define VAR_IP_RATELIMIT_SIZE 455
|
#define VAR_IP_RATELIMIT_SLABS 455
|
||||||
#define VAR_RATELIMIT 456
|
#define VAR_IP_RATELIMIT_SIZE 456
|
||||||
#define VAR_RATELIMIT_SLABS 457
|
#define VAR_RATELIMIT 457
|
||||||
#define VAR_RATELIMIT_SIZE 458
|
#define VAR_RATELIMIT_SLABS 458
|
||||||
#define VAR_OUTBOUND_MSG_RETRY 459
|
#define VAR_RATELIMIT_SIZE 459
|
||||||
#define VAR_MAX_SENT_COUNT 460
|
#define VAR_OUTBOUND_MSG_RETRY 460
|
||||||
#define VAR_MAX_QUERY_RESTARTS 461
|
#define VAR_MAX_SENT_COUNT 461
|
||||||
#define VAR_RATELIMIT_FOR_DOMAIN 462
|
#define VAR_MAX_QUERY_RESTARTS 462
|
||||||
#define VAR_RATELIMIT_BELOW_DOMAIN 463
|
#define VAR_RATELIMIT_FOR_DOMAIN 463
|
||||||
#define VAR_IP_RATELIMIT_FACTOR 464
|
#define VAR_RATELIMIT_BELOW_DOMAIN 464
|
||||||
#define VAR_RATELIMIT_FACTOR 465
|
#define VAR_IP_RATELIMIT_FACTOR 465
|
||||||
#define VAR_IP_RATELIMIT_BACKOFF 466
|
#define VAR_RATELIMIT_FACTOR 466
|
||||||
#define VAR_RATELIMIT_BACKOFF 467
|
#define VAR_IP_RATELIMIT_BACKOFF 467
|
||||||
#define VAR_SEND_CLIENT_SUBNET 468
|
#define VAR_RATELIMIT_BACKOFF 468
|
||||||
#define VAR_CLIENT_SUBNET_ZONE 469
|
#define VAR_SEND_CLIENT_SUBNET 469
|
||||||
#define VAR_CLIENT_SUBNET_ALWAYS_FORWARD 470
|
#define VAR_CLIENT_SUBNET_ZONE 470
|
||||||
#define VAR_CLIENT_SUBNET_OPCODE 471
|
#define VAR_CLIENT_SUBNET_ALWAYS_FORWARD 471
|
||||||
#define VAR_MAX_CLIENT_SUBNET_IPV4 472
|
#define VAR_CLIENT_SUBNET_OPCODE 472
|
||||||
#define VAR_MAX_CLIENT_SUBNET_IPV6 473
|
#define VAR_MAX_CLIENT_SUBNET_IPV4 473
|
||||||
#define VAR_MIN_CLIENT_SUBNET_IPV4 474
|
#define VAR_MAX_CLIENT_SUBNET_IPV6 474
|
||||||
#define VAR_MIN_CLIENT_SUBNET_IPV6 475
|
#define VAR_MIN_CLIENT_SUBNET_IPV4 475
|
||||||
#define VAR_MAX_ECS_TREE_SIZE_IPV4 476
|
#define VAR_MIN_CLIENT_SUBNET_IPV6 476
|
||||||
#define VAR_MAX_ECS_TREE_SIZE_IPV6 477
|
#define VAR_MAX_ECS_TREE_SIZE_IPV4 477
|
||||||
#define VAR_CAPS_WHITELIST 478
|
#define VAR_MAX_ECS_TREE_SIZE_IPV6 478
|
||||||
#define VAR_CACHE_MAX_NEGATIVE_TTL 479
|
#define VAR_CAPS_WHITELIST 479
|
||||||
#define VAR_PERMIT_SMALL_HOLDDOWN 480
|
#define VAR_CACHE_MAX_NEGATIVE_TTL 480
|
||||||
#define VAR_CACHE_MIN_NEGATIVE_TTL 481
|
#define VAR_PERMIT_SMALL_HOLDDOWN 481
|
||||||
#define VAR_QNAME_MINIMISATION 482
|
#define VAR_CACHE_MIN_NEGATIVE_TTL 482
|
||||||
#define VAR_QNAME_MINIMISATION_STRICT 483
|
#define VAR_QNAME_MINIMISATION 483
|
||||||
#define VAR_IP_FREEBIND 484
|
#define VAR_QNAME_MINIMISATION_STRICT 484
|
||||||
#define VAR_DEFINE_TAG 485
|
#define VAR_IP_FREEBIND 485
|
||||||
#define VAR_LOCAL_ZONE_TAG 486
|
#define VAR_DEFINE_TAG 486
|
||||||
#define VAR_ACCESS_CONTROL_TAG 487
|
#define VAR_LOCAL_ZONE_TAG 487
|
||||||
#define VAR_LOCAL_ZONE_OVERRIDE 488
|
#define VAR_ACCESS_CONTROL_TAG 488
|
||||||
#define VAR_ACCESS_CONTROL_TAG_ACTION 489
|
#define VAR_LOCAL_ZONE_OVERRIDE 489
|
||||||
#define VAR_ACCESS_CONTROL_TAG_DATA 490
|
#define VAR_ACCESS_CONTROL_TAG_ACTION 490
|
||||||
#define VAR_VIEW 491
|
#define VAR_ACCESS_CONTROL_TAG_DATA 491
|
||||||
#define VAR_ACCESS_CONTROL_VIEW 492
|
#define VAR_VIEW 492
|
||||||
#define VAR_VIEW_FIRST 493
|
#define VAR_ACCESS_CONTROL_VIEW 493
|
||||||
#define VAR_SERVE_EXPIRED 494
|
#define VAR_VIEW_FIRST 494
|
||||||
#define VAR_SERVE_EXPIRED_TTL 495
|
#define VAR_SERVE_EXPIRED 495
|
||||||
#define VAR_SERVE_EXPIRED_TTL_RESET 496
|
#define VAR_SERVE_EXPIRED_TTL 496
|
||||||
#define VAR_SERVE_EXPIRED_REPLY_TTL 497
|
#define VAR_SERVE_EXPIRED_TTL_RESET 497
|
||||||
#define VAR_SERVE_EXPIRED_CLIENT_TIMEOUT 498
|
#define VAR_SERVE_EXPIRED_REPLY_TTL 498
|
||||||
#define VAR_EDE_SERVE_EXPIRED 499
|
#define VAR_SERVE_EXPIRED_CLIENT_TIMEOUT 499
|
||||||
#define VAR_SERVE_ORIGINAL_TTL 500
|
#define VAR_EDE_SERVE_EXPIRED 500
|
||||||
#define VAR_FAKE_DSA 501
|
#define VAR_SERVE_ORIGINAL_TTL 501
|
||||||
#define VAR_FAKE_SHA1 502
|
#define VAR_FAKE_DSA 502
|
||||||
#define VAR_LOG_IDENTITY 503
|
#define VAR_FAKE_SHA1 503
|
||||||
#define VAR_HIDE_TRUSTANCHOR 504
|
#define VAR_LOG_IDENTITY 504
|
||||||
#define VAR_HIDE_HTTP_USER_AGENT 505
|
#define VAR_HIDE_TRUSTANCHOR 505
|
||||||
#define VAR_HTTP_USER_AGENT 506
|
#define VAR_HIDE_HTTP_USER_AGENT 506
|
||||||
#define VAR_TRUST_ANCHOR_SIGNALING 507
|
#define VAR_HTTP_USER_AGENT 507
|
||||||
#define VAR_AGGRESSIVE_NSEC 508
|
#define VAR_TRUST_ANCHOR_SIGNALING 508
|
||||||
#define VAR_USE_SYSTEMD 509
|
#define VAR_AGGRESSIVE_NSEC 509
|
||||||
#define VAR_SHM_ENABLE 510
|
#define VAR_USE_SYSTEMD 510
|
||||||
#define VAR_SHM_KEY 511
|
#define VAR_SHM_ENABLE 511
|
||||||
#define VAR_ROOT_KEY_SENTINEL 512
|
#define VAR_SHM_KEY 512
|
||||||
#define VAR_DNSCRYPT 513
|
#define VAR_ROOT_KEY_SENTINEL 513
|
||||||
#define VAR_DNSCRYPT_ENABLE 514
|
#define VAR_DNSCRYPT 514
|
||||||
#define VAR_DNSCRYPT_PORT 515
|
#define VAR_DNSCRYPT_ENABLE 515
|
||||||
#define VAR_DNSCRYPT_PROVIDER 516
|
#define VAR_DNSCRYPT_PORT 516
|
||||||
#define VAR_DNSCRYPT_SECRET_KEY 517
|
#define VAR_DNSCRYPT_PROVIDER 517
|
||||||
#define VAR_DNSCRYPT_PROVIDER_CERT 518
|
#define VAR_DNSCRYPT_SECRET_KEY 518
|
||||||
#define VAR_DNSCRYPT_PROVIDER_CERT_ROTATED 519
|
#define VAR_DNSCRYPT_PROVIDER_CERT 519
|
||||||
#define VAR_DNSCRYPT_SHARED_SECRET_CACHE_SIZE 520
|
#define VAR_DNSCRYPT_PROVIDER_CERT_ROTATED 520
|
||||||
#define VAR_DNSCRYPT_SHARED_SECRET_CACHE_SLABS 521
|
#define VAR_DNSCRYPT_SHARED_SECRET_CACHE_SIZE 521
|
||||||
#define VAR_DNSCRYPT_NONCE_CACHE_SIZE 522
|
#define VAR_DNSCRYPT_SHARED_SECRET_CACHE_SLABS 522
|
||||||
#define VAR_DNSCRYPT_NONCE_CACHE_SLABS 523
|
#define VAR_DNSCRYPT_NONCE_CACHE_SIZE 523
|
||||||
#define VAR_PAD_RESPONSES 524
|
#define VAR_DNSCRYPT_NONCE_CACHE_SLABS 524
|
||||||
#define VAR_PAD_RESPONSES_BLOCK_SIZE 525
|
#define VAR_PAD_RESPONSES 525
|
||||||
#define VAR_PAD_QUERIES 526
|
#define VAR_PAD_RESPONSES_BLOCK_SIZE 526
|
||||||
#define VAR_PAD_QUERIES_BLOCK_SIZE 527
|
#define VAR_PAD_QUERIES 527
|
||||||
#define VAR_IPSECMOD_ENABLED 528
|
#define VAR_PAD_QUERIES_BLOCK_SIZE 528
|
||||||
#define VAR_IPSECMOD_HOOK 529
|
#define VAR_IPSECMOD_ENABLED 529
|
||||||
#define VAR_IPSECMOD_IGNORE_BOGUS 530
|
#define VAR_IPSECMOD_HOOK 530
|
||||||
#define VAR_IPSECMOD_MAX_TTL 531
|
#define VAR_IPSECMOD_IGNORE_BOGUS 531
|
||||||
#define VAR_IPSECMOD_WHITELIST 532
|
#define VAR_IPSECMOD_MAX_TTL 532
|
||||||
#define VAR_IPSECMOD_STRICT 533
|
#define VAR_IPSECMOD_WHITELIST 533
|
||||||
#define VAR_CACHEDB 534
|
#define VAR_IPSECMOD_STRICT 534
|
||||||
#define VAR_CACHEDB_BACKEND 535
|
#define VAR_CACHEDB 535
|
||||||
#define VAR_CACHEDB_SECRETSEED 536
|
#define VAR_CACHEDB_BACKEND 536
|
||||||
#define VAR_CACHEDB_REDISHOST 537
|
#define VAR_CACHEDB_SECRETSEED 537
|
||||||
#define VAR_CACHEDB_REDISPORT 538
|
#define VAR_CACHEDB_REDISHOST 538
|
||||||
#define VAR_CACHEDB_REDISTIMEOUT 539
|
#define VAR_CACHEDB_REDISPORT 539
|
||||||
#define VAR_CACHEDB_REDISEXPIRERECORDS 540
|
#define VAR_CACHEDB_REDISTIMEOUT 540
|
||||||
#define VAR_CACHEDB_REDISPATH 541
|
#define VAR_CACHEDB_REDISEXPIRERECORDS 541
|
||||||
#define VAR_CACHEDB_REDISPASSWORD 542
|
#define VAR_CACHEDB_REDISPATH 542
|
||||||
#define VAR_CACHEDB_REDISLOGICALDB 543
|
#define VAR_CACHEDB_REDISPASSWORD 543
|
||||||
#define VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM 544
|
#define VAR_CACHEDB_REDISLOGICALDB 544
|
||||||
#define VAR_FOR_UPSTREAM 545
|
#define VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM 545
|
||||||
#define VAR_AUTH_ZONE 546
|
#define VAR_FOR_UPSTREAM 546
|
||||||
#define VAR_ZONEFILE 547
|
#define VAR_AUTH_ZONE 547
|
||||||
#define VAR_MASTER 548
|
#define VAR_ZONEFILE 548
|
||||||
#define VAR_URL 549
|
#define VAR_MASTER 549
|
||||||
#define VAR_FOR_DOWNSTREAM 550
|
#define VAR_URL 550
|
||||||
#define VAR_FALLBACK_ENABLED 551
|
#define VAR_FOR_DOWNSTREAM 551
|
||||||
#define VAR_TLS_ADDITIONAL_PORT 552
|
#define VAR_FALLBACK_ENABLED 552
|
||||||
#define VAR_LOW_RTT 553
|
#define VAR_TLS_ADDITIONAL_PORT 553
|
||||||
#define VAR_LOW_RTT_PERMIL 554
|
#define VAR_LOW_RTT 554
|
||||||
#define VAR_FAST_SERVER_PERMIL 555
|
#define VAR_LOW_RTT_PERMIL 555
|
||||||
#define VAR_FAST_SERVER_NUM 556
|
#define VAR_FAST_SERVER_PERMIL 556
|
||||||
#define VAR_ALLOW_NOTIFY 557
|
#define VAR_FAST_SERVER_NUM 557
|
||||||
#define VAR_TLS_WIN_CERT 558
|
#define VAR_ALLOW_NOTIFY 558
|
||||||
#define VAR_TCP_CONNECTION_LIMIT 559
|
#define VAR_TLS_WIN_CERT 559
|
||||||
#define VAR_ANSWER_COOKIE 560
|
#define VAR_TCP_CONNECTION_LIMIT 560
|
||||||
#define VAR_COOKIE_SECRET 561
|
#define VAR_ANSWER_COOKIE 561
|
||||||
#define VAR_IP_RATELIMIT_COOKIE 562
|
#define VAR_COOKIE_SECRET 562
|
||||||
#define VAR_FORWARD_NO_CACHE 563
|
#define VAR_IP_RATELIMIT_COOKIE 563
|
||||||
#define VAR_STUB_NO_CACHE 564
|
#define VAR_FORWARD_NO_CACHE 564
|
||||||
#define VAR_LOG_SERVFAIL 565
|
#define VAR_STUB_NO_CACHE 565
|
||||||
#define VAR_DENY_ANY 566
|
#define VAR_LOG_SERVFAIL 566
|
||||||
#define VAR_UNKNOWN_SERVER_TIME_LIMIT 567
|
#define VAR_DENY_ANY 567
|
||||||
#define VAR_LOG_TAG_QUERYREPLY 568
|
#define VAR_UNKNOWN_SERVER_TIME_LIMIT 568
|
||||||
#define VAR_DISCARD_TIMEOUT 569
|
#define VAR_LOG_TAG_QUERYREPLY 569
|
||||||
#define VAR_WAIT_LIMIT 570
|
#define VAR_DISCARD_TIMEOUT 570
|
||||||
#define VAR_WAIT_LIMIT_COOKIE 571
|
#define VAR_WAIT_LIMIT 571
|
||||||
#define VAR_WAIT_LIMIT_NETBLOCK 572
|
#define VAR_WAIT_LIMIT_COOKIE 572
|
||||||
#define VAR_WAIT_LIMIT_COOKIE_NETBLOCK 573
|
#define VAR_WAIT_LIMIT_NETBLOCK 573
|
||||||
#define VAR_STREAM_WAIT_SIZE 574
|
#define VAR_WAIT_LIMIT_COOKIE_NETBLOCK 574
|
||||||
#define VAR_TLS_CIPHERS 575
|
#define VAR_STREAM_WAIT_SIZE 575
|
||||||
#define VAR_TLS_CIPHERSUITES 576
|
#define VAR_TLS_CIPHERS 576
|
||||||
#define VAR_TLS_USE_SNI 577
|
#define VAR_TLS_CIPHERSUITES 577
|
||||||
#define VAR_IPSET 578
|
#define VAR_TLS_USE_SNI 578
|
||||||
#define VAR_IPSET_NAME_V4 579
|
#define VAR_IPSET 579
|
||||||
#define VAR_IPSET_NAME_V6 580
|
#define VAR_IPSET_NAME_V4 580
|
||||||
#define VAR_TLS_SESSION_TICKET_KEYS 581
|
#define VAR_IPSET_NAME_V6 581
|
||||||
#define VAR_RPZ 582
|
#define VAR_TLS_SESSION_TICKET_KEYS 582
|
||||||
#define VAR_TAGS 583
|
#define VAR_RPZ 583
|
||||||
#define VAR_RPZ_ACTION_OVERRIDE 584
|
#define VAR_TAGS 584
|
||||||
#define VAR_RPZ_CNAME_OVERRIDE 585
|
#define VAR_RPZ_ACTION_OVERRIDE 585
|
||||||
#define VAR_RPZ_LOG 586
|
#define VAR_RPZ_CNAME_OVERRIDE 586
|
||||||
#define VAR_RPZ_LOG_NAME 587
|
#define VAR_RPZ_LOG 587
|
||||||
#define VAR_DYNLIB 588
|
#define VAR_RPZ_LOG_NAME 588
|
||||||
#define VAR_DYNLIB_FILE 589
|
#define VAR_DYNLIB 589
|
||||||
#define VAR_EDNS_CLIENT_STRING 590
|
#define VAR_DYNLIB_FILE 590
|
||||||
#define VAR_EDNS_CLIENT_STRING_OPCODE 591
|
#define VAR_EDNS_CLIENT_STRING 591
|
||||||
#define VAR_NSID 592
|
#define VAR_EDNS_CLIENT_STRING_OPCODE 592
|
||||||
#define VAR_ZONEMD_PERMISSIVE_MODE 593
|
#define VAR_NSID 593
|
||||||
#define VAR_ZONEMD_CHECK 594
|
#define VAR_ZONEMD_PERMISSIVE_MODE 594
|
||||||
#define VAR_ZONEMD_REJECT_ABSENCE 595
|
#define VAR_ZONEMD_CHECK 595
|
||||||
#define VAR_RPZ_SIGNAL_NXDOMAIN_RA 596
|
#define VAR_ZONEMD_REJECT_ABSENCE 596
|
||||||
#define VAR_INTERFACE_AUTOMATIC_PORTS 597
|
#define VAR_RPZ_SIGNAL_NXDOMAIN_RA 597
|
||||||
#define VAR_EDE 598
|
#define VAR_INTERFACE_AUTOMATIC_PORTS 598
|
||||||
#define VAR_INTERFACE_ACTION 599
|
#define VAR_EDE 599
|
||||||
#define VAR_INTERFACE_VIEW 600
|
#define VAR_INTERFACE_ACTION 600
|
||||||
#define VAR_INTERFACE_TAG 601
|
#define VAR_INTERFACE_VIEW 601
|
||||||
#define VAR_INTERFACE_TAG_ACTION 602
|
#define VAR_INTERFACE_TAG 602
|
||||||
#define VAR_INTERFACE_TAG_DATA 603
|
#define VAR_INTERFACE_TAG_ACTION 603
|
||||||
#define VAR_PROXY_PROTOCOL_PORT 604
|
#define VAR_INTERFACE_TAG_DATA 604
|
||||||
#define VAR_STATISTICS_INHIBIT_ZERO 605
|
#define VAR_PROXY_PROTOCOL_PORT 605
|
||||||
#define VAR_HARDEN_UNKNOWN_ADDITIONAL 606
|
#define VAR_STATISTICS_INHIBIT_ZERO 606
|
||||||
#define VAR_DISABLE_EDNS_DO 607
|
#define VAR_HARDEN_UNKNOWN_ADDITIONAL 607
|
||||||
#define VAR_CACHEDB_NO_STORE 608
|
#define VAR_DISABLE_EDNS_DO 608
|
||||||
#define VAR_LOG_DESTADDR 609
|
#define VAR_CACHEDB_NO_STORE 609
|
||||||
#define VAR_CACHEDB_CHECK_WHEN_SERVE_EXPIRED 610
|
#define VAR_LOG_DESTADDR 610
|
||||||
|
#define VAR_CACHEDB_CHECK_WHEN_SERVE_EXPIRED 611
|
||||||
|
#define VAR_COOKIE_SECRET_FILE 612
|
||||||
#ifndef YYSTYPE_DEFINED
|
#ifndef YYSTYPE_DEFINED
|
||||||
#define YYSTYPE_DEFINED
|
#define YYSTYPE_DEFINED
|
||||||
typedef union {
|
typedef union {
|
||||||
|
|
|
@ -137,6 +137,7 @@ extern struct config_parser_state* cfg_parser;
|
||||||
%token VAR_DNSTAP_LOG_CLIENT_RESPONSE_MESSAGES
|
%token VAR_DNSTAP_LOG_CLIENT_RESPONSE_MESSAGES
|
||||||
%token VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES
|
%token VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES
|
||||||
%token VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES
|
%token VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES
|
||||||
|
%token VAR_DNSTAP_SAMPLE_RATE
|
||||||
%token VAR_RESPONSE_IP_TAG VAR_RESPONSE_IP VAR_RESPONSE_IP_DATA
|
%token VAR_RESPONSE_IP_TAG VAR_RESPONSE_IP VAR_RESPONSE_IP_DATA
|
||||||
%token VAR_HARDEN_ALGO_DOWNGRADE VAR_IP_TRANSPARENT
|
%token VAR_HARDEN_ALGO_DOWNGRADE VAR_IP_TRANSPARENT
|
||||||
%token VAR_IP_DSCP
|
%token VAR_IP_DSCP
|
||||||
|
@ -204,6 +205,7 @@ extern struct config_parser_state* cfg_parser;
|
||||||
%token VAR_PROXY_PROTOCOL_PORT VAR_STATISTICS_INHIBIT_ZERO
|
%token VAR_PROXY_PROTOCOL_PORT VAR_STATISTICS_INHIBIT_ZERO
|
||||||
%token VAR_HARDEN_UNKNOWN_ADDITIONAL VAR_DISABLE_EDNS_DO VAR_CACHEDB_NO_STORE
|
%token VAR_HARDEN_UNKNOWN_ADDITIONAL VAR_DISABLE_EDNS_DO VAR_CACHEDB_NO_STORE
|
||||||
%token VAR_LOG_DESTADDR VAR_CACHEDB_CHECK_WHEN_SERVE_EXPIRED
|
%token VAR_LOG_DESTADDR VAR_CACHEDB_CHECK_WHEN_SERVE_EXPIRED
|
||||||
|
%token VAR_COOKIE_SECRET_FILE
|
||||||
|
|
||||||
%%
|
%%
|
||||||
toplevelvars: /* empty */ | toplevelvars toplevelvar ;
|
toplevelvars: /* empty */ | toplevelvars toplevelvar ;
|
||||||
|
@ -341,7 +343,7 @@ content_server: server_num_threads | server_verbosity | server_port |
|
||||||
server_interface_automatic_ports | server_ede |
|
server_interface_automatic_ports | server_ede |
|
||||||
server_proxy_protocol_port | server_statistics_inhibit_zero |
|
server_proxy_protocol_port | server_statistics_inhibit_zero |
|
||||||
server_harden_unknown_additional | server_disable_edns_do |
|
server_harden_unknown_additional | server_disable_edns_do |
|
||||||
server_log_destaddr
|
server_log_destaddr | server_cookie_secret_file
|
||||||
;
|
;
|
||||||
stubstart: VAR_STUB_ZONE
|
stubstart: VAR_STUB_ZONE
|
||||||
{
|
{
|
||||||
|
@ -357,8 +359,14 @@ stubstart: VAR_STUB_ZONE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
contents_stub: contents_stub content_stub
|
contents_stub: content_stub contents_stub
|
||||||
| ;
|
|
|
||||||
|
{
|
||||||
|
/* stub end */
|
||||||
|
if(cfg_parser->cfg->stubs &&
|
||||||
|
!cfg_parser->cfg->stubs->name)
|
||||||
|
yyerror("stub-zone without name");
|
||||||
|
};
|
||||||
content_stub: stub_name | stub_host | stub_addr | stub_prime | stub_first |
|
content_stub: stub_name | stub_host | stub_addr | stub_prime | stub_first |
|
||||||
stub_no_cache | stub_ssl_upstream | stub_tcp_upstream
|
stub_no_cache | stub_ssl_upstream | stub_tcp_upstream
|
||||||
;
|
;
|
||||||
|
@ -376,8 +384,14 @@ forwardstart: VAR_FORWARD_ZONE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
contents_forward: contents_forward content_forward
|
contents_forward: content_forward contents_forward
|
||||||
| ;
|
|
|
||||||
|
{
|
||||||
|
/* forward end */
|
||||||
|
if(cfg_parser->cfg->forwards &&
|
||||||
|
!cfg_parser->cfg->forwards->name)
|
||||||
|
yyerror("forward-zone without name");
|
||||||
|
};
|
||||||
content_forward: forward_name | forward_host | forward_addr | forward_first |
|
content_forward: forward_name | forward_host | forward_addr | forward_first |
|
||||||
forward_no_cache | forward_ssl_upstream | forward_tcp_upstream
|
forward_no_cache | forward_ssl_upstream | forward_tcp_upstream
|
||||||
;
|
;
|
||||||
|
@ -389,16 +403,20 @@ viewstart: VAR_VIEW
|
||||||
s = (struct config_view*)calloc(1, sizeof(struct config_view));
|
s = (struct config_view*)calloc(1, sizeof(struct config_view));
|
||||||
if(s) {
|
if(s) {
|
||||||
s->next = cfg_parser->cfg->views;
|
s->next = cfg_parser->cfg->views;
|
||||||
if(s->next && !s->next->name)
|
|
||||||
yyerror("view without name");
|
|
||||||
cfg_parser->cfg->views = s;
|
cfg_parser->cfg->views = s;
|
||||||
} else {
|
} else {
|
||||||
yyerror("out of memory");
|
yyerror("out of memory");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
contents_view: contents_view content_view
|
contents_view: content_view contents_view
|
||||||
| ;
|
|
|
||||||
|
{
|
||||||
|
/* view end */
|
||||||
|
if(cfg_parser->cfg->views &&
|
||||||
|
!cfg_parser->cfg->views->name)
|
||||||
|
yyerror("view without name");
|
||||||
|
};
|
||||||
content_view: view_name | view_local_zone | view_local_data | view_first |
|
content_view: view_name | view_local_zone | view_local_data | view_first |
|
||||||
view_response_ip | view_response_ip_data | view_local_data_ptr
|
view_response_ip | view_response_ip_data | view_local_data_ptr
|
||||||
;
|
;
|
||||||
|
@ -3437,7 +3455,8 @@ content_dt: dt_dnstap_enable | dt_dnstap_socket_path | dt_dnstap_bidirectional |
|
||||||
dt_dnstap_log_client_query_messages |
|
dt_dnstap_log_client_query_messages |
|
||||||
dt_dnstap_log_client_response_messages |
|
dt_dnstap_log_client_response_messages |
|
||||||
dt_dnstap_log_forwarder_query_messages |
|
dt_dnstap_log_forwarder_query_messages |
|
||||||
dt_dnstap_log_forwarder_response_messages
|
dt_dnstap_log_forwarder_response_messages |
|
||||||
|
dt_dnstap_sample_rate
|
||||||
;
|
;
|
||||||
dt_dnstap_enable: VAR_DNSTAP_ENABLE STRING_ARG
|
dt_dnstap_enable: VAR_DNSTAP_ENABLE STRING_ARG
|
||||||
{
|
{
|
||||||
|
@ -3601,6 +3620,17 @@ dt_dnstap_log_forwarder_response_messages: VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MES
|
||||||
free($2);
|
free($2);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
dt_dnstap_sample_rate: VAR_DNSTAP_SAMPLE_RATE STRING_ARG
|
||||||
|
{
|
||||||
|
OUTYY(("P(dt_dnstap_sample_rate:%s)\n", $2));
|
||||||
|
if(atoi($2) == 0 && strcmp($2, "0") != 0)
|
||||||
|
yyerror("number expected");
|
||||||
|
else if(atoi($2) < 0)
|
||||||
|
yyerror("dnstap sample rate too small");
|
||||||
|
else cfg_parser->cfg->dnstap_sample_rate = atoi($2);
|
||||||
|
free($2);
|
||||||
|
}
|
||||||
|
;
|
||||||
pythonstart: VAR_PYTHON
|
pythonstart: VAR_PYTHON
|
||||||
{
|
{
|
||||||
OUTYY(("\nP(python:)\n"));
|
OUTYY(("\nP(python:)\n"));
|
||||||
|
@ -3969,6 +3999,13 @@ server_cookie_secret: VAR_COOKIE_SECRET STRING_ARG
|
||||||
free($2);
|
free($2);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
server_cookie_secret_file: VAR_COOKIE_SECRET_FILE STRING_ARG
|
||||||
|
{
|
||||||
|
OUTYY(("P(cookie_secret_file:%s)\n", $2));
|
||||||
|
free(cfg_parser->cfg->cookie_secret_file);
|
||||||
|
cfg_parser->cfg->cookie_secret_file = $2;
|
||||||
|
}
|
||||||
|
;
|
||||||
ipsetstart: VAR_IPSET
|
ipsetstart: VAR_IPSET
|
||||||
{
|
{
|
||||||
OUTYY(("\nP(ipset:)\n"));
|
OUTYY(("\nP(ipset:)\n"));
|
||||||
|
|
|
@ -225,7 +225,7 @@ int dname_strict_subdomain(uint8_t* d1, int labs1, uint8_t* d2, int labs2);
|
||||||
int dname_strict_subdomain_c(uint8_t* d1, uint8_t* d2);
|
int dname_strict_subdomain_c(uint8_t* d1, uint8_t* d2);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Counts labels. Tests is d1 is a subdomain of d2.
|
* Counts labels. Tests if d1 is a subdomain of d2.
|
||||||
* @param d1: domain name, uncompressed wireformat
|
* @param d1: domain name, uncompressed wireformat
|
||||||
* @param d2: domain name, uncompressed wireformat
|
* @param d2: domain name, uncompressed wireformat
|
||||||
* @return true if d1 is a subdomain of d2.
|
* @return true if d1 is a subdomain of d2.
|
||||||
|
|
|
@ -947,7 +947,8 @@ parse_packet(sldns_buffer* pkt, struct msg_parse* msg, struct regional* region)
|
||||||
static int
|
static int
|
||||||
parse_edns_options_from_query(uint8_t* rdata_ptr, size_t rdata_len,
|
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 edns_data* edns, struct config_file* cfg, struct comm_point* c,
|
||||||
struct comm_reply* repinfo, uint32_t now, struct regional* region)
|
struct comm_reply* repinfo, uint32_t now, struct regional* region,
|
||||||
|
struct cookie_secrets* cookie_secrets)
|
||||||
{
|
{
|
||||||
/* To respond with a Keepalive option, the client connection must have
|
/* To respond with a Keepalive option, the client connection must have
|
||||||
* received one message with a TCP Keepalive EDNS option, and that
|
* received one message with a TCP Keepalive EDNS option, and that
|
||||||
|
@ -1070,13 +1071,24 @@ parse_edns_options_from_query(uint8_t* rdata_ptr, size_t rdata_len,
|
||||||
&((struct sockaddr_in6*)&repinfo->remote_addr)->sin6_addr, 16);
|
&((struct sockaddr_in6*)&repinfo->remote_addr)->sin6_addr, 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(cfg->cookie_secret_file &&
|
||||||
|
cfg->cookie_secret_file[0]) {
|
||||||
|
/* Loop over the active and staging cookies. */
|
||||||
|
cookie_val_status =
|
||||||
|
cookie_secrets_server_validate(
|
||||||
|
rdata_ptr, opt_len, cookie_secrets,
|
||||||
|
cookie_is_v4, server_cookie, now);
|
||||||
|
} else {
|
||||||
|
/* Use the cookie option value to validate. */
|
||||||
cookie_val_status = edns_cookie_server_validate(
|
cookie_val_status = edns_cookie_server_validate(
|
||||||
rdata_ptr, opt_len, cfg->cookie_secret,
|
rdata_ptr, opt_len, cfg->cookie_secret,
|
||||||
cfg->cookie_secret_len, cookie_is_v4,
|
cfg->cookie_secret_len, cookie_is_v4,
|
||||||
server_cookie, now);
|
server_cookie, now);
|
||||||
|
}
|
||||||
|
if(cookie_val_status == COOKIE_STATUS_VALID_RENEW)
|
||||||
|
edns->cookie_valid = 1;
|
||||||
switch(cookie_val_status) {
|
switch(cookie_val_status) {
|
||||||
case COOKIE_STATUS_VALID:
|
case COOKIE_STATUS_VALID:
|
||||||
case COOKIE_STATUS_VALID_RENEW:
|
|
||||||
edns->cookie_valid = 1;
|
edns->cookie_valid = 1;
|
||||||
/* Reuse cookie */
|
/* Reuse cookie */
|
||||||
if(!edns_opt_list_append(
|
if(!edns_opt_list_append(
|
||||||
|
@ -1091,13 +1103,30 @@ parse_edns_options_from_query(uint8_t* rdata_ptr, size_t rdata_len,
|
||||||
break;
|
break;
|
||||||
case COOKIE_STATUS_CLIENT_ONLY:
|
case COOKIE_STATUS_CLIENT_ONLY:
|
||||||
edns->cookie_client = 1;
|
edns->cookie_client = 1;
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
|
case COOKIE_STATUS_VALID_RENEW:
|
||||||
case COOKIE_STATUS_FUTURE:
|
case COOKIE_STATUS_FUTURE:
|
||||||
case COOKIE_STATUS_EXPIRED:
|
case COOKIE_STATUS_EXPIRED:
|
||||||
case COOKIE_STATUS_INVALID:
|
case COOKIE_STATUS_INVALID:
|
||||||
default:
|
default:
|
||||||
|
if(cfg->cookie_secret_file &&
|
||||||
|
cfg->cookie_secret_file[0]) {
|
||||||
|
if(!cookie_secrets)
|
||||||
|
break;
|
||||||
|
lock_basic_lock(&cookie_secrets->lock);
|
||||||
|
if(cookie_secrets->cookie_count < 1) {
|
||||||
|
lock_basic_unlock(&cookie_secrets->lock);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
edns_cookie_server_write(server_cookie,
|
||||||
|
cookie_secrets->cookie_secrets[0].cookie_secret,
|
||||||
|
cookie_is_v4, now);
|
||||||
|
lock_basic_unlock(&cookie_secrets->lock);
|
||||||
|
} else {
|
||||||
edns_cookie_server_write(server_cookie,
|
edns_cookie_server_write(server_cookie,
|
||||||
cfg->cookie_secret, cookie_is_v4, now);
|
cfg->cookie_secret, cookie_is_v4, now);
|
||||||
|
}
|
||||||
if(!edns_opt_list_append(&edns->opt_list_out,
|
if(!edns_opt_list_append(&edns->opt_list_out,
|
||||||
LDNS_EDNS_COOKIE, 24, server_cookie,
|
LDNS_EDNS_COOKIE, 24, server_cookie,
|
||||||
region)) {
|
region)) {
|
||||||
|
@ -1239,7 +1268,8 @@ skip_pkt_rrs(sldns_buffer* pkt, int num)
|
||||||
int
|
int
|
||||||
parse_edns_from_query_pkt(sldns_buffer* pkt, struct edns_data* edns,
|
parse_edns_from_query_pkt(sldns_buffer* pkt, struct edns_data* edns,
|
||||||
struct config_file* cfg, struct comm_point* c,
|
struct config_file* cfg, struct comm_point* c,
|
||||||
struct comm_reply* repinfo, time_t now, struct regional* region)
|
struct comm_reply* repinfo, time_t now, struct regional* region,
|
||||||
|
struct cookie_secrets* cookie_secrets)
|
||||||
{
|
{
|
||||||
size_t rdata_len;
|
size_t rdata_len;
|
||||||
uint8_t* rdata_ptr;
|
uint8_t* rdata_ptr;
|
||||||
|
@ -1285,7 +1315,7 @@ parse_edns_from_query_pkt(sldns_buffer* pkt, struct edns_data* edns,
|
||||||
rdata_ptr = sldns_buffer_current(pkt);
|
rdata_ptr = sldns_buffer_current(pkt);
|
||||||
/* ignore rrsigs */
|
/* ignore rrsigs */
|
||||||
return parse_edns_options_from_query(rdata_ptr, rdata_len, edns, cfg,
|
return parse_edns_options_from_query(rdata_ptr, rdata_len, edns, cfg,
|
||||||
c, repinfo, now, region);
|
c, repinfo, now, region, cookie_secrets);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -73,6 +73,7 @@ struct edns_option;
|
||||||
struct config_file;
|
struct config_file;
|
||||||
struct comm_point;
|
struct comm_point;
|
||||||
struct comm_reply;
|
struct comm_reply;
|
||||||
|
struct cookie_secrets;
|
||||||
|
|
||||||
/** number of buckets in parse rrset hash table. Must be power of 2. */
|
/** number of buckets in parse rrset hash table. Must be power of 2. */
|
||||||
#define PARSE_TABLE_SIZE 32
|
#define PARSE_TABLE_SIZE 32
|
||||||
|
@ -322,12 +323,14 @@ int skip_pkt_rrs(struct sldns_buffer* pkt, int num);
|
||||||
* @param repinfo: commreply to determine the client address
|
* @param repinfo: commreply to determine the client address
|
||||||
* @param now: current time
|
* @param now: current time
|
||||||
* @param region: region to alloc results in (edns option contents)
|
* @param region: region to alloc results in (edns option contents)
|
||||||
|
* @param cookie_secrets: the cookie secrets for EDNS COOKIE validation.
|
||||||
* @return: 0 on success, or an RCODE on error.
|
* @return: 0 on success, or an RCODE on error.
|
||||||
* RCODE formerr if OPT is badly formatted and so on.
|
* RCODE formerr if OPT is badly formatted and so on.
|
||||||
*/
|
*/
|
||||||
int parse_edns_from_query_pkt(struct sldns_buffer* pkt, struct edns_data* edns,
|
int parse_edns_from_query_pkt(struct sldns_buffer* pkt, struct edns_data* edns,
|
||||||
struct config_file* cfg, struct comm_point* c,
|
struct config_file* cfg, struct comm_point* c,
|
||||||
struct comm_reply* repinfo, time_t now, struct regional* region);
|
struct comm_reply* repinfo, time_t now, struct regional* region,
|
||||||
|
struct cookie_secrets* cookie_secrets);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculate hash value for rrset in packet.
|
* Calculate hash value for rrset in packet.
|
||||||
|
|
|
@ -187,3 +187,189 @@ edns_cookie_server_validate(const uint8_t* cookie, size_t cookie_len,
|
||||||
return COOKIE_STATUS_VALID_RENEW;
|
return COOKIE_STATUS_VALID_RENEW;
|
||||||
return COOKIE_STATUS_VALID;
|
return COOKIE_STATUS_VALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct cookie_secrets*
|
||||||
|
cookie_secrets_create(void)
|
||||||
|
{
|
||||||
|
struct cookie_secrets* cookie_secrets = calloc(1,
|
||||||
|
sizeof(*cookie_secrets));
|
||||||
|
if(!cookie_secrets)
|
||||||
|
return NULL;
|
||||||
|
lock_basic_init(&cookie_secrets->lock);
|
||||||
|
lock_protect(&cookie_secrets->lock, &cookie_secrets->cookie_count,
|
||||||
|
sizeof(cookie_secrets->cookie_count));
|
||||||
|
lock_protect(&cookie_secrets->lock, cookie_secrets->cookie_secrets,
|
||||||
|
sizeof(cookie_secret_type)*UNBOUND_COOKIE_HISTORY_SIZE);
|
||||||
|
return cookie_secrets;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cookie_secrets_delete(struct cookie_secrets* cookie_secrets)
|
||||||
|
{
|
||||||
|
if(!cookie_secrets)
|
||||||
|
return;
|
||||||
|
lock_basic_destroy(&cookie_secrets->lock);
|
||||||
|
explicit_bzero(cookie_secrets->cookie_secrets,
|
||||||
|
sizeof(cookie_secret_type)*UNBOUND_COOKIE_HISTORY_SIZE);
|
||||||
|
free(cookie_secrets);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Read the cookie secret file */
|
||||||
|
static int
|
||||||
|
cookie_secret_file_read(struct cookie_secrets* cookie_secrets,
|
||||||
|
char* cookie_secret_file)
|
||||||
|
{
|
||||||
|
char secret[UNBOUND_COOKIE_SECRET_SIZE * 2 + 2/*'\n' and '\0'*/];
|
||||||
|
FILE* f;
|
||||||
|
int corrupt = 0;
|
||||||
|
size_t count;
|
||||||
|
|
||||||
|
log_assert(cookie_secret_file != NULL);
|
||||||
|
cookie_secrets->cookie_count = 0;
|
||||||
|
f = fopen(cookie_secret_file, "r");
|
||||||
|
/* a non-existing cookie file is not an error */
|
||||||
|
if( f == NULL ) {
|
||||||
|
if(errno != EPERM) {
|
||||||
|
log_err("Could not read cookie-secret-file '%s': %s",
|
||||||
|
cookie_secret_file, strerror(errno));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/* cookie secret file exists and is readable */
|
||||||
|
for( count = 0; count < UNBOUND_COOKIE_HISTORY_SIZE; count++ ) {
|
||||||
|
size_t secret_len = 0;
|
||||||
|
ssize_t decoded_len = 0;
|
||||||
|
if( fgets(secret, sizeof(secret), f) == NULL ) { break; }
|
||||||
|
secret_len = strlen(secret);
|
||||||
|
if( secret_len == 0 ) { break; }
|
||||||
|
log_assert( secret_len <= sizeof(secret) );
|
||||||
|
secret_len = secret[secret_len - 1] == '\n' ? secret_len - 1 : secret_len;
|
||||||
|
if( secret_len != UNBOUND_COOKIE_SECRET_SIZE * 2 ) { corrupt++; break; }
|
||||||
|
/* needed for `hex_pton`; stripping potential `\n` */
|
||||||
|
secret[secret_len] = '\0';
|
||||||
|
decoded_len = hex_pton(secret, cookie_secrets->cookie_secrets[count].cookie_secret,
|
||||||
|
UNBOUND_COOKIE_SECRET_SIZE);
|
||||||
|
if( decoded_len != UNBOUND_COOKIE_SECRET_SIZE ) { corrupt++; break; }
|
||||||
|
cookie_secrets->cookie_count++;
|
||||||
|
}
|
||||||
|
fclose(f);
|
||||||
|
return corrupt == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
cookie_secrets_apply_cfg(struct cookie_secrets* cookie_secrets,
|
||||||
|
char* cookie_secret_file)
|
||||||
|
{
|
||||||
|
if(!cookie_secrets) {
|
||||||
|
if(!cookie_secret_file || !cookie_secret_file[0])
|
||||||
|
return 1; /* There is nothing to read anyway */
|
||||||
|
log_err("Could not read cookie secrets, no structure alloced");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if(!cookie_secret_file_read(cookie_secrets, cookie_secret_file))
|
||||||
|
return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum edns_cookie_val_status
|
||||||
|
cookie_secrets_server_validate(const uint8_t* cookie, size_t cookie_len,
|
||||||
|
struct cookie_secrets* cookie_secrets, int v4,
|
||||||
|
const uint8_t* hash_input, uint32_t now)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
enum edns_cookie_val_status cookie_val_status,
|
||||||
|
last = COOKIE_STATUS_INVALID;
|
||||||
|
if(!cookie_secrets)
|
||||||
|
return COOKIE_STATUS_INVALID; /* There are no cookie secrets.*/
|
||||||
|
lock_basic_lock(&cookie_secrets->lock);
|
||||||
|
if(cookie_secrets->cookie_count == 0) {
|
||||||
|
lock_basic_unlock(&cookie_secrets->lock);
|
||||||
|
return COOKIE_STATUS_INVALID; /* There are no cookie secrets.*/
|
||||||
|
}
|
||||||
|
for(i=0; i<cookie_secrets->cookie_count; i++) {
|
||||||
|
cookie_val_status = edns_cookie_server_validate(cookie,
|
||||||
|
cookie_len,
|
||||||
|
cookie_secrets->cookie_secrets[i].cookie_secret,
|
||||||
|
UNBOUND_COOKIE_SECRET_SIZE, v4, hash_input, now);
|
||||||
|
if(cookie_val_status == COOKIE_STATUS_VALID ||
|
||||||
|
cookie_val_status == COOKIE_STATUS_VALID_RENEW) {
|
||||||
|
lock_basic_unlock(&cookie_secrets->lock);
|
||||||
|
/* For staging cookies, write a fresh cookie. */
|
||||||
|
if(i != 0)
|
||||||
|
return COOKIE_STATUS_VALID_RENEW;
|
||||||
|
return cookie_val_status;
|
||||||
|
}
|
||||||
|
if(last == COOKIE_STATUS_INVALID)
|
||||||
|
last = cookie_val_status; /* Store more interesting
|
||||||
|
failure to return. */
|
||||||
|
}
|
||||||
|
lock_basic_unlock(&cookie_secrets->lock);
|
||||||
|
return last;
|
||||||
|
}
|
||||||
|
|
||||||
|
void add_cookie_secret(struct cookie_secrets* cookie_secrets,
|
||||||
|
uint8_t* secret, size_t secret_len)
|
||||||
|
{
|
||||||
|
log_assert(secret_len == UNBOUND_COOKIE_SECRET_SIZE);
|
||||||
|
(void)secret_len;
|
||||||
|
if(!cookie_secrets)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* New cookie secret becomes the staging secret (position 1)
|
||||||
|
* unless there is no active cookie yet, then it becomes the active
|
||||||
|
* secret. If the UNBOUND_COOKIE_HISTORY_SIZE > 2 then all staging cookies
|
||||||
|
* are moved one position down.
|
||||||
|
*/
|
||||||
|
if(cookie_secrets->cookie_count == 0) {
|
||||||
|
memcpy( cookie_secrets->cookie_secrets->cookie_secret
|
||||||
|
, secret, UNBOUND_COOKIE_SECRET_SIZE);
|
||||||
|
cookie_secrets->cookie_count = 1;
|
||||||
|
explicit_bzero(secret, UNBOUND_COOKIE_SECRET_SIZE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#if UNBOUND_COOKIE_HISTORY_SIZE > 2
|
||||||
|
memmove( &cookie_secrets->cookie_secrets[2], &cookie_secrets->cookie_secrets[1]
|
||||||
|
, sizeof(struct cookie_secret) * (UNBOUND_COOKIE_HISTORY_SIZE - 2));
|
||||||
|
#endif
|
||||||
|
memcpy( cookie_secrets->cookie_secrets[1].cookie_secret
|
||||||
|
, secret, UNBOUND_COOKIE_SECRET_SIZE);
|
||||||
|
cookie_secrets->cookie_count = cookie_secrets->cookie_count < UNBOUND_COOKIE_HISTORY_SIZE
|
||||||
|
? cookie_secrets->cookie_count + 1 : UNBOUND_COOKIE_HISTORY_SIZE;
|
||||||
|
explicit_bzero(secret, UNBOUND_COOKIE_SECRET_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void activate_cookie_secret(struct cookie_secrets* cookie_secrets)
|
||||||
|
{
|
||||||
|
uint8_t active_secret[UNBOUND_COOKIE_SECRET_SIZE];
|
||||||
|
if(!cookie_secrets)
|
||||||
|
return;
|
||||||
|
/* The staging secret becomes the active secret.
|
||||||
|
* The active secret becomes a staging secret.
|
||||||
|
* If the UNBOUND_COOKIE_HISTORY_SIZE > 2 then all staging secrets are moved
|
||||||
|
* one position up and the previously active secret becomes the last
|
||||||
|
* staging secret.
|
||||||
|
*/
|
||||||
|
if(cookie_secrets->cookie_count < 2)
|
||||||
|
return;
|
||||||
|
memcpy( active_secret, cookie_secrets->cookie_secrets[0].cookie_secret
|
||||||
|
, UNBOUND_COOKIE_SECRET_SIZE);
|
||||||
|
memmove( &cookie_secrets->cookie_secrets[0], &cookie_secrets->cookie_secrets[1]
|
||||||
|
, sizeof(struct cookie_secret) * (UNBOUND_COOKIE_HISTORY_SIZE - 1));
|
||||||
|
memcpy( cookie_secrets->cookie_secrets[cookie_secrets->cookie_count - 1].cookie_secret
|
||||||
|
, active_secret, UNBOUND_COOKIE_SECRET_SIZE);
|
||||||
|
explicit_bzero(active_secret, UNBOUND_COOKIE_SECRET_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void drop_cookie_secret(struct cookie_secrets* cookie_secrets)
|
||||||
|
{
|
||||||
|
if(!cookie_secrets)
|
||||||
|
return;
|
||||||
|
/* Drops a staging cookie secret. If there are more than one, it will
|
||||||
|
* drop the last staging secret. */
|
||||||
|
if(cookie_secrets->cookie_count < 2)
|
||||||
|
return;
|
||||||
|
explicit_bzero( cookie_secrets->cookie_secrets[cookie_secrets->cookie_count - 1].cookie_secret
|
||||||
|
, UNBOUND_COOKIE_SECRET_SIZE);
|
||||||
|
cookie_secrets->cookie_count -= 1;
|
||||||
|
}
|
||||||
|
|
|
@ -43,6 +43,7 @@
|
||||||
#define UTIL_EDNS_H
|
#define UTIL_EDNS_H
|
||||||
|
|
||||||
#include "util/storage/dnstree.h"
|
#include "util/storage/dnstree.h"
|
||||||
|
#include "util/locks.h"
|
||||||
|
|
||||||
struct edns_data;
|
struct edns_data;
|
||||||
struct config_file;
|
struct config_file;
|
||||||
|
@ -75,6 +76,31 @@ struct edns_string_addr {
|
||||||
size_t string_len;
|
size_t string_len;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define UNBOUND_COOKIE_HISTORY_SIZE 2
|
||||||
|
#define UNBOUND_COOKIE_SECRET_SIZE 16
|
||||||
|
|
||||||
|
typedef struct cookie_secret cookie_secret_type;
|
||||||
|
struct cookie_secret {
|
||||||
|
/** cookie secret */
|
||||||
|
uint8_t cookie_secret[UNBOUND_COOKIE_SECRET_SIZE];
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The cookie secrets from the cookie-secret-file.
|
||||||
|
*/
|
||||||
|
struct cookie_secrets {
|
||||||
|
/** lock on the structure, in case there are modifications
|
||||||
|
* from remote control, this avoids race conditions. */
|
||||||
|
lock_basic_type lock;
|
||||||
|
|
||||||
|
/** how many cookies are there in the cookies array */
|
||||||
|
size_t cookie_count;
|
||||||
|
|
||||||
|
/* keep track of the last `UNBOUND_COOKIE_HISTORY_SIZE`
|
||||||
|
* cookies as per rfc requirement .*/
|
||||||
|
cookie_secret_type cookie_secrets[UNBOUND_COOKIE_HISTORY_SIZE];
|
||||||
|
};
|
||||||
|
|
||||||
enum edns_cookie_val_status {
|
enum edns_cookie_val_status {
|
||||||
COOKIE_STATUS_CLIENT_ONLY = -3,
|
COOKIE_STATUS_CLIENT_ONLY = -3,
|
||||||
COOKIE_STATUS_FUTURE = -2,
|
COOKIE_STATUS_FUTURE = -2,
|
||||||
|
@ -165,4 +191,63 @@ 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,
|
size_t cookie_len, const uint8_t* secret, size_t secret_len, int v4,
|
||||||
const uint8_t* hash_input, uint32_t now);
|
const uint8_t* hash_input, uint32_t now);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the cookie secrets structure.
|
||||||
|
* @return the structure or NULL on failure.
|
||||||
|
*/
|
||||||
|
struct cookie_secrets* cookie_secrets_create(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete the cookie secrets.
|
||||||
|
* @param cookie_secrets: the cookie secrets.
|
||||||
|
*/
|
||||||
|
void cookie_secrets_delete(struct cookie_secrets* cookie_secrets);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply configuration to cookie secrets, read them from file.
|
||||||
|
* @param cookie_secrets: the cookie secrets structure.
|
||||||
|
* @param cookie_secret_file: the file name, it is read.
|
||||||
|
* @return false on failure.
|
||||||
|
*/
|
||||||
|
int cookie_secrets_apply_cfg(struct cookie_secrets* cookie_secrets,
|
||||||
|
char* cookie_secret_file);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate the cookie secrets, try all of them.
|
||||||
|
* @param cookie: pointer to the cookie data.
|
||||||
|
* @param cookie_len: the length of the cookie data.
|
||||||
|
* @param cookie_secrets: struct of cookie secrets.
|
||||||
|
* @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 cookie_secrets_server_validate(
|
||||||
|
const uint8_t* cookie, size_t cookie_len,
|
||||||
|
struct cookie_secrets* cookie_secrets, int v4,
|
||||||
|
const uint8_t* hash_input, uint32_t now);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a cookie secret. If there are no secrets yet, the secret will become
|
||||||
|
* the active secret. Otherwise it will become the staging secret.
|
||||||
|
* Active secrets are used to both verify and create new DNS Cookies.
|
||||||
|
* Staging secrets are only used to verify DNS Cookies. Caller has to lock.
|
||||||
|
*/
|
||||||
|
void add_cookie_secret(struct cookie_secrets* cookie_secrets, uint8_t* secret,
|
||||||
|
size_t secret_len);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Makes the staging cookie secret active and the active secret staging.
|
||||||
|
* Caller has to lock.
|
||||||
|
*/
|
||||||
|
void activate_cookie_secret(struct cookie_secrets* cookie_secrets);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Drop a cookie secret. Drops the staging secret. An active secret will not
|
||||||
|
* be dropped. Caller has to lock.
|
||||||
|
*/
|
||||||
|
void drop_cookie_secret(struct cookie_secrets* cookie_secrets);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -448,6 +448,28 @@ fptr_whitelist_mod_deinit(void (*fptr)(struct module_env* env, int id))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fptr_whitelist_mod_startup(int (*fptr)(struct module_env* env, int id))
|
||||||
|
{
|
||||||
|
#ifdef USE_IPSET
|
||||||
|
if(fptr == &ipset_startup) return 1;
|
||||||
|
#else
|
||||||
|
(void)fptr;
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fptr_whitelist_mod_destartup(void (*fptr)(struct module_env* env, int id))
|
||||||
|
{
|
||||||
|
#ifdef USE_IPSET
|
||||||
|
if(fptr == &ipset_destartup) return 1;
|
||||||
|
#else
|
||||||
|
(void)fptr;
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
fptr_whitelist_mod_operate(void (*fptr)(struct module_qstate* qstate,
|
fptr_whitelist_mod_operate(void (*fptr)(struct module_qstate* qstate,
|
||||||
enum module_ev event, int id, struct outbound_entry* outbound))
|
enum module_ev event, int id, struct outbound_entry* outbound))
|
||||||
|
|
|
@ -278,6 +278,22 @@ int fptr_whitelist_mod_init(int (*fptr)(struct module_env* env, int id));
|
||||||
*/
|
*/
|
||||||
int fptr_whitelist_mod_deinit(void (*fptr)(struct module_env* env, int id));
|
int fptr_whitelist_mod_deinit(void (*fptr)(struct module_env* env, int id));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check function pointer whitelist for module startup call values.
|
||||||
|
*
|
||||||
|
* @param fptr: function pointer to check.
|
||||||
|
* @return false if not in whitelist.
|
||||||
|
*/
|
||||||
|
int fptr_whitelist_mod_startup(int (*fptr)(struct module_env* env, int id));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check function pointer whitelist for module destartup call values.
|
||||||
|
*
|
||||||
|
* @param fptr: function pointer to check.
|
||||||
|
* @return false if not in whitelist.
|
||||||
|
*/
|
||||||
|
int fptr_whitelist_mod_destartup(void (*fptr)(struct module_env* env, int id));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check function pointer whitelist for module operate call values.
|
* Check function pointer whitelist for module operate call values.
|
||||||
*
|
*
|
||||||
|
|
|
@ -143,7 +143,7 @@
|
||||||
* also contain an rcode that is nonzero, but in this case additional
|
* also contain an rcode that is nonzero, but in this case additional
|
||||||
* information (query, additional) can be passed along.
|
* information (query, additional) can be passed along.
|
||||||
*
|
*
|
||||||
* The rcode and dns_msg are used to pass the result from the the rightmost
|
* The rcode and dns_msg are used to pass the result from the rightmost
|
||||||
* module towards the leftmost modules and then towards the user.
|
* module towards the leftmost modules and then towards the user.
|
||||||
*
|
*
|
||||||
* If you want to avoid recursion-cycles where queries need other queries
|
* If you want to avoid recursion-cycles where queries need other queries
|
||||||
|
@ -713,7 +713,28 @@ struct module_func_block {
|
||||||
const char* name;
|
const char* name;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* init the module. Called once for the global state.
|
* Set up the module for start. This is called only once at startup.
|
||||||
|
* Privileged operations like opening device files may be done here.
|
||||||
|
* The function ptr can be NULL, if it is not used.
|
||||||
|
* @param env: module environment.
|
||||||
|
* @param id: module id number.
|
||||||
|
* return: 0 on error
|
||||||
|
*/
|
||||||
|
int (*startup)(struct module_env* env, int id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close down the module for stop. This is called only once before
|
||||||
|
* shutdown to free resources allocated during startup().
|
||||||
|
* Closing privileged ports or files must be done here.
|
||||||
|
* The function ptr can be NULL, if it is not used.
|
||||||
|
* @param env: module environment.
|
||||||
|
* @param id: module id number.
|
||||||
|
*/
|
||||||
|
void (*destartup)(struct module_env* env, int id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialise the module. Called when restarting or reloading the
|
||||||
|
* daemon.
|
||||||
* This is the place to apply settings from the config file.
|
* This is the place to apply settings from the config file.
|
||||||
* @param env: module environment.
|
* @param env: module environment.
|
||||||
* @param id: module id number.
|
* @param id: module id number.
|
||||||
|
@ -722,7 +743,8 @@ struct module_func_block {
|
||||||
int (*init)(struct module_env* env, int id);
|
int (*init)(struct module_env* env, int id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* de-init, delete, the module. Called once for the global state.
|
* Deinitialise the module, undo stuff done during init().
|
||||||
|
* Called before reloading the daemon.
|
||||||
* @param env: module environment.
|
* @param env: module environment.
|
||||||
* @param id: module id number.
|
* @param id: module id number.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -47,6 +47,7 @@
|
||||||
#ifdef HAVE_NETIOAPI_H
|
#ifdef HAVE_NETIOAPI_H
|
||||||
#include <netioapi.h>
|
#include <netioapi.h>
|
||||||
#endif
|
#endif
|
||||||
|
#include <ctype.h>
|
||||||
#include "util/net_help.h"
|
#include "util/net_help.h"
|
||||||
#include "util/log.h"
|
#include "util/log.h"
|
||||||
#include "util/data/dname.h"
|
#include "util/data/dname.h"
|
||||||
|
@ -862,6 +863,20 @@ addr_is_ip4mapped(struct sockaddr_storage* addr, socklen_t addrlen)
|
||||||
return (memcmp(s, map_prefix, 12) == 0);
|
return (memcmp(s, map_prefix, 12) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int addr_is_ip6linklocal(struct sockaddr_storage* addr, socklen_t addrlen)
|
||||||
|
{
|
||||||
|
const uint8_t prefix[2] = {0xfe, 0x80};
|
||||||
|
int af = (int)((struct sockaddr_in6*)addr)->sin6_family;
|
||||||
|
void* sin6addr = &((struct sockaddr_in6*)addr)->sin6_addr;
|
||||||
|
uint8_t start[2];
|
||||||
|
if(af != AF_INET6 || addrlen<(socklen_t)sizeof(struct sockaddr_in6))
|
||||||
|
return 0;
|
||||||
|
/* Put the first 10 bits of sin6addr in start, match fe80::/10. */
|
||||||
|
memmove(start, sin6addr, 2);
|
||||||
|
start[1] &= 0xc0;
|
||||||
|
return memcmp(start, prefix, 2) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
int addr_is_broadcast(struct sockaddr_storage* addr, socklen_t addrlen)
|
int addr_is_broadcast(struct sockaddr_storage* addr, socklen_t addrlen)
|
||||||
{
|
{
|
||||||
int af = (int)((struct sockaddr_in*)addr)->sin_family;
|
int af = (int)((struct sockaddr_in*)addr)->sin_family;
|
||||||
|
@ -1206,7 +1221,7 @@ listen_sslctx_setup_2(void* ctxt)
|
||||||
if(!SSL_CTX_set_ecdh_auto(ctx,1)) {
|
if(!SSL_CTX_set_ecdh_auto(ctx,1)) {
|
||||||
log_crypto_err("Error in SSL_CTX_ecdh_auto, not enabling ECDHE");
|
log_crypto_err("Error in SSL_CTX_ecdh_auto, not enabling ECDHE");
|
||||||
}
|
}
|
||||||
#elif defined(USE_ECDSA)
|
#elif defined(USE_ECDSA) && defined(HAVE_SSL_CTX_SET_TMP_ECDH)
|
||||||
if(1) {
|
if(1) {
|
||||||
EC_KEY *ecdh = EC_KEY_new_by_curve_name (NID_X9_62_prime256v1);
|
EC_KEY *ecdh = EC_KEY_new_by_curve_name (NID_X9_62_prime256v1);
|
||||||
if (!ecdh) {
|
if (!ecdh) {
|
||||||
|
@ -1857,3 +1872,42 @@ sock_close(int socket)
|
||||||
closesocket(socket);
|
closesocket(socket);
|
||||||
}
|
}
|
||||||
# endif /* USE_WINSOCK */
|
# endif /* USE_WINSOCK */
|
||||||
|
|
||||||
|
ssize_t
|
||||||
|
hex_ntop(uint8_t const *src, size_t srclength, char *target, size_t targsize)
|
||||||
|
{
|
||||||
|
static char hexdigits[] = {
|
||||||
|
'0', '1', '2', '3', '4', '5', '6', '7',
|
||||||
|
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
|
||||||
|
};
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
if (targsize < srclength * 2 + 1) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < srclength; ++i) {
|
||||||
|
*target++ = hexdigits[src[i] >> 4U];
|
||||||
|
*target++ = hexdigits[src[i] & 0xfU];
|
||||||
|
}
|
||||||
|
*target = '\0';
|
||||||
|
return 2 * srclength;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t
|
||||||
|
hex_pton(const char* src, uint8_t* target, size_t targsize)
|
||||||
|
{
|
||||||
|
uint8_t *t = target;
|
||||||
|
if(strlen(src) % 2 != 0 || strlen(src)/2 > targsize) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
while(*src) {
|
||||||
|
if(!isxdigit((unsigned char)src[0]) ||
|
||||||
|
!isxdigit((unsigned char)src[1]))
|
||||||
|
return -1;
|
||||||
|
*t++ = sldns_hexdigit_to_int(src[0]) * 16 +
|
||||||
|
sldns_hexdigit_to_int(src[1]) ;
|
||||||
|
src += 2;
|
||||||
|
}
|
||||||
|
return t-target;
|
||||||
|
}
|
||||||
|
|
|
@ -362,6 +362,14 @@ void addr_to_nat64(const struct sockaddr_storage* addr,
|
||||||
*/
|
*/
|
||||||
int addr_is_ip4mapped(struct sockaddr_storage* addr, socklen_t addrlen);
|
int addr_is_ip4mapped(struct sockaddr_storage* addr, socklen_t addrlen);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See if sockaddr is an ipv6 fe80::/10 link local address.
|
||||||
|
* @param addr: address
|
||||||
|
* @param addrlen: length of address
|
||||||
|
* @return true if so
|
||||||
|
*/
|
||||||
|
int addr_is_ip6linklocal(struct sockaddr_storage* addr, socklen_t addrlen);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See if sockaddr is 255.255.255.255.
|
* See if sockaddr is 255.255.255.255.
|
||||||
* @param addr: address
|
* @param addr: address
|
||||||
|
@ -564,4 +572,13 @@ char* sock_strerror(int errn);
|
||||||
/** close the socket with close, or wsa closesocket */
|
/** close the socket with close, or wsa closesocket */
|
||||||
void sock_close(int socket);
|
void sock_close(int socket);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert binary data to a string of hexadecimal characters.
|
||||||
|
*/
|
||||||
|
ssize_t hex_ntop(uint8_t const *src, size_t srclength, char *target,
|
||||||
|
size_t targsize);
|
||||||
|
|
||||||
|
/** Convert hexadecimal data to binary. */
|
||||||
|
ssize_t hex_pton(const char* src, uint8_t* target, size_t targsize);
|
||||||
|
|
||||||
#endif /* NET_HELP_H */
|
#endif /* NET_HELP_H */
|
||||||
|
|
|
@ -329,6 +329,7 @@ udp_send_errno_needs_log(struct sockaddr* addr, socklen_t addrlen)
|
||||||
case EACCES:
|
case EACCES:
|
||||||
if(verbosity < VERB_ALGO)
|
if(verbosity < VERB_ALGO)
|
||||||
return 0;
|
return 0;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -2365,11 +2366,11 @@ recv_error:
|
||||||
#ifndef USE_WINSOCK
|
#ifndef USE_WINSOCK
|
||||||
if(errno == EINTR || errno == EAGAIN)
|
if(errno == EINTR || errno == EAGAIN)
|
||||||
return 1;
|
return 1;
|
||||||
if(recv_initial) {
|
|
||||||
#ifdef ECONNRESET
|
#ifdef ECONNRESET
|
||||||
if(errno == ECONNRESET && verbosity < 2)
|
if(errno == ECONNRESET && verbosity < 2)
|
||||||
return 0; /* silence reset by peer */
|
return 0; /* silence reset by peer */
|
||||||
#endif
|
#endif
|
||||||
|
if(recv_initial) {
|
||||||
#ifdef ECONNREFUSED
|
#ifdef ECONNREFUSED
|
||||||
if(errno == ECONNREFUSED && verbosity < 2)
|
if(errno == ECONNREFUSED && verbosity < 2)
|
||||||
return 0; /* silence reset by peer */
|
return 0; /* silence reset by peer */
|
||||||
|
@ -2396,7 +2397,7 @@ recv_error:
|
||||||
#endif
|
#endif
|
||||||
#ifdef ENOTCONN
|
#ifdef ENOTCONN
|
||||||
if(errno == ENOTCONN) {
|
if(errno == ENOTCONN) {
|
||||||
log_err_addr("read (in tcp s) failed and this "
|
log_err_addr("read (in tcp initial) failed and this "
|
||||||
"could be because TCP Fast Open is "
|
"could be because TCP Fast Open is "
|
||||||
"enabled [--disable-tfo-client "
|
"enabled [--disable-tfo-client "
|
||||||
"--disable-tfo-server] but does not "
|
"--disable-tfo-server] but does not "
|
||||||
|
@ -2430,8 +2431,9 @@ recv_error:
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
log_err_addr("read (in tcp s)", sock_strerror(errno),
|
log_err_addr((recv_initial?"read (in tcp initial)":"read (in tcp)"),
|
||||||
&c->repinfo.remote_addr, c->repinfo.remote_addrlen);
|
sock_strerror(errno), &c->repinfo.remote_addr,
|
||||||
|
c->repinfo.remote_addrlen);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3306,6 +3308,13 @@ void http2_stream_add_meshstate(struct http2_stream* h2_stream,
|
||||||
h2_stream->mesh_state = m;
|
h2_stream->mesh_state = m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void http2_stream_remove_mesh_state(struct http2_stream* h2_stream)
|
||||||
|
{
|
||||||
|
if(!h2_stream)
|
||||||
|
return;
|
||||||
|
h2_stream->mesh_state = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/** delete http2 session server. After closing connection. */
|
/** delete http2 session server. After closing connection. */
|
||||||
static void http2_session_server_delete(struct http2_session* h2_session)
|
static void http2_session_server_delete(struct http2_session* h2_session)
|
||||||
{
|
{
|
||||||
|
|
|
@ -955,6 +955,9 @@ void http2_session_add_stream(struct http2_session* h2_session,
|
||||||
void http2_stream_add_meshstate(struct http2_stream* h2_stream,
|
void http2_stream_add_meshstate(struct http2_stream* h2_stream,
|
||||||
struct mesh_area* mesh, struct mesh_state* m);
|
struct mesh_area* mesh, struct mesh_state* m);
|
||||||
|
|
||||||
|
/** Remove mesh state from stream. When the mesh state has been removed. */
|
||||||
|
void http2_stream_remove_mesh_state(struct http2_stream* h2_stream);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This routine is published for checks and tests, and is only used internally.
|
* This routine is published for checks and tests, and is only used internally.
|
||||||
* handle libevent callback for timer comm.
|
* handle libevent callback for timer comm.
|
||||||
|
|
|
@ -153,6 +153,7 @@ pp2_write_to_buf(uint8_t* buf, size_t buflen,
|
||||||
break;
|
break;
|
||||||
#endif /* INET6 */
|
#endif /* INET6 */
|
||||||
case AF_UNIX:
|
case AF_UNIX:
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -128,26 +128,32 @@ int siphash(const uint8_t *in, const size_t inlen, const uint8_t *k,
|
||||||
case 7:
|
case 7:
|
||||||
b |= ((uint64_t)in[6]) << 48;
|
b |= ((uint64_t)in[6]) << 48;
|
||||||
/** EDIT annotate case statement fallthrough for gcc */
|
/** EDIT annotate case statement fallthrough for gcc */
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
case 6:
|
case 6:
|
||||||
b |= ((uint64_t)in[5]) << 40;
|
b |= ((uint64_t)in[5]) << 40;
|
||||||
/** EDIT annotate case statement fallthrough for gcc */
|
/** EDIT annotate case statement fallthrough for gcc */
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
case 5:
|
case 5:
|
||||||
b |= ((uint64_t)in[4]) << 32;
|
b |= ((uint64_t)in[4]) << 32;
|
||||||
/** EDIT annotate case statement fallthrough for gcc */
|
/** EDIT annotate case statement fallthrough for gcc */
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
case 4:
|
case 4:
|
||||||
b |= ((uint64_t)in[3]) << 24;
|
b |= ((uint64_t)in[3]) << 24;
|
||||||
/** EDIT annotate case statement fallthrough for gcc */
|
/** EDIT annotate case statement fallthrough for gcc */
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
case 3:
|
case 3:
|
||||||
b |= ((uint64_t)in[2]) << 16;
|
b |= ((uint64_t)in[2]) << 16;
|
||||||
/** EDIT annotate case statement fallthrough for gcc */
|
/** EDIT annotate case statement fallthrough for gcc */
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
case 2:
|
case 2:
|
||||||
b |= ((uint64_t)in[1]) << 8;
|
b |= ((uint64_t)in[1]) << 8;
|
||||||
/** EDIT annotate case statement fallthrough for gcc */
|
/** EDIT annotate case statement fallthrough for gcc */
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
case 1:
|
case 1:
|
||||||
b |= ((uint64_t)in[0]);
|
b |= ((uint64_t)in[0]);
|
||||||
|
|
|
@ -254,11 +254,15 @@ uint32_t initval) /* the previous hash, or an arbitrary value */
|
||||||
switch(length) /* all the case statements fall through */
|
switch(length) /* all the case statements fall through */
|
||||||
{
|
{
|
||||||
case 3 : c+=k[2];
|
case 3 : c+=k[2];
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
case 2 : b+=k[1];
|
case 2 : b+=k[1];
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
case 1 : a+=k[0];
|
case 1 : a+=k[0];
|
||||||
final(a,b,c);
|
final(a,b,c);
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
|
/* fallthrough */
|
||||||
case 0: /* case 0: nothing left to add */
|
case 0: /* case 0: nothing left to add */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -304,9 +308,15 @@ uint32_t *pb) /* IN: more seed OUT: secondary hash value */
|
||||||
switch(length) /* all the case statements fall through */
|
switch(length) /* all the case statements fall through */
|
||||||
{
|
{
|
||||||
case 3 : c+=k[2];
|
case 3 : c+=k[2];
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
|
/* fallthrough */
|
||||||
case 2 : b+=k[1];
|
case 2 : b+=k[1];
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
|
/* fallthrough */
|
||||||
case 1 : a+=k[0];
|
case 1 : a+=k[0];
|
||||||
final(a,b,c);
|
final(a,b,c);
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
|
/* fallthrough */
|
||||||
case 0: /* case 0: nothing left to add */
|
case 0: /* case 0: nothing left to add */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -404,16 +414,32 @@ uint32_t hashlittle( const void *key, size_t length, uint32_t initval)
|
||||||
switch(length)
|
switch(length)
|
||||||
{
|
{
|
||||||
case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;
|
case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;
|
||||||
case 11: c+=((uint32_t)k8[10])<<16; /* fall through */
|
case 11: c+=((uint32_t)k8[10])<<16;
|
||||||
case 10: c+=((uint32_t)k8[9])<<8; /* fall through */
|
ATTR_FALLTHROUGH
|
||||||
case 9 : c+=k8[8]; /* fall through */
|
/* fallthrough */
|
||||||
|
case 10: c+=((uint32_t)k8[9])<<8;
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
|
/* fallthrough */
|
||||||
|
case 9 : c+=k8[8];
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
|
/* fallthrough */
|
||||||
case 8 : b+=k[1]; a+=k[0]; break;
|
case 8 : b+=k[1]; a+=k[0]; break;
|
||||||
case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */
|
case 7 : b+=((uint32_t)k8[6])<<16;
|
||||||
case 6 : b+=((uint32_t)k8[5])<<8; /* fall through */
|
ATTR_FALLTHROUGH
|
||||||
case 5 : b+=k8[4]; /* fall through */
|
/* fallthrough */
|
||||||
|
case 6 : b+=((uint32_t)k8[5])<<8;
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
|
/* fallthrough */
|
||||||
|
case 5 : b+=k8[4];
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
|
/* fallthrough */
|
||||||
case 4 : a+=k[0]; break;
|
case 4 : a+=k[0]; break;
|
||||||
case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */
|
case 3 : a+=((uint32_t)k8[2])<<16;
|
||||||
case 2 : a+=((uint32_t)k8[1])<<8; /* fall through */
|
ATTR_FALLTHROUGH
|
||||||
|
/* fallthrough */
|
||||||
|
case 2 : a+=((uint32_t)k8[1])<<8;
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
|
/* fallthrough */
|
||||||
case 1 : a+=k8[0]; break;
|
case 1 : a+=k8[0]; break;
|
||||||
case 0 : return c;
|
case 0 : return c;
|
||||||
}
|
}
|
||||||
|
@ -443,23 +469,33 @@ uint32_t hashlittle( const void *key, size_t length, uint32_t initval)
|
||||||
b+=k[2]+(((uint32_t)k[3])<<16);
|
b+=k[2]+(((uint32_t)k[3])<<16);
|
||||||
a+=k[0]+(((uint32_t)k[1])<<16);
|
a+=k[0]+(((uint32_t)k[1])<<16);
|
||||||
break;
|
break;
|
||||||
case 11: c+=((uint32_t)k8[10])<<16; /* fall through */
|
case 11: c+=((uint32_t)k8[10])<<16;
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
|
/* fallthrough */
|
||||||
case 10: c+=k[4];
|
case 10: c+=k[4];
|
||||||
b+=k[2]+(((uint32_t)k[3])<<16);
|
b+=k[2]+(((uint32_t)k[3])<<16);
|
||||||
a+=k[0]+(((uint32_t)k[1])<<16);
|
a+=k[0]+(((uint32_t)k[1])<<16);
|
||||||
break;
|
break;
|
||||||
case 9 : c+=k8[8]; /* fall through */
|
case 9 : c+=k8[8];
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
|
/* fallthrough */
|
||||||
case 8 : b+=k[2]+(((uint32_t)k[3])<<16);
|
case 8 : b+=k[2]+(((uint32_t)k[3])<<16);
|
||||||
a+=k[0]+(((uint32_t)k[1])<<16);
|
a+=k[0]+(((uint32_t)k[1])<<16);
|
||||||
break;
|
break;
|
||||||
case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */
|
case 7 : b+=((uint32_t)k8[6])<<16;
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
|
/* fallthrough */
|
||||||
case 6 : b+=k[2];
|
case 6 : b+=k[2];
|
||||||
a+=k[0]+(((uint32_t)k[1])<<16);
|
a+=k[0]+(((uint32_t)k[1])<<16);
|
||||||
break;
|
break;
|
||||||
case 5 : b+=k8[4]; /* fall through */
|
case 5 : b+=k8[4];
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
|
/* fallthrough */
|
||||||
case 4 : a+=k[0]+(((uint32_t)k[1])<<16);
|
case 4 : a+=k[0]+(((uint32_t)k[1])<<16);
|
||||||
break;
|
break;
|
||||||
case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */
|
case 3 : a+=((uint32_t)k8[2])<<16;
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
|
/* fallthrough */
|
||||||
case 2 : a+=k[0];
|
case 2 : a+=k[0];
|
||||||
break;
|
break;
|
||||||
case 1 : a+=k8[0];
|
case 1 : a+=k8[0];
|
||||||
|
@ -494,26 +530,37 @@ uint32_t hashlittle( const void *key, size_t length, uint32_t initval)
|
||||||
switch(length) /* all the case statements fall through */
|
switch(length) /* all the case statements fall through */
|
||||||
{
|
{
|
||||||
case 12: c+=((uint32_t)k[11])<<24;
|
case 12: c+=((uint32_t)k[11])<<24;
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
case 11: c+=((uint32_t)k[10])<<16;
|
case 11: c+=((uint32_t)k[10])<<16;
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
case 10: c+=((uint32_t)k[9])<<8;
|
case 10: c+=((uint32_t)k[9])<<8;
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
case 9 : c+=k[8];
|
case 9 : c+=k[8];
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
case 8 : b+=((uint32_t)k[7])<<24;
|
case 8 : b+=((uint32_t)k[7])<<24;
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
case 7 : b+=((uint32_t)k[6])<<16;
|
case 7 : b+=((uint32_t)k[6])<<16;
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
case 6 : b+=((uint32_t)k[5])<<8;
|
case 6 : b+=((uint32_t)k[5])<<8;
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
case 5 : b+=k[4];
|
case 5 : b+=k[4];
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
case 4 : a+=((uint32_t)k[3])<<24;
|
case 4 : a+=((uint32_t)k[3])<<24;
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
case 3 : a+=((uint32_t)k[2])<<16;
|
case 3 : a+=((uint32_t)k[2])<<16;
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
case 2 : a+=((uint32_t)k[1])<<8;
|
case 2 : a+=((uint32_t)k[1])<<8;
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
case 1 : a+=k[0];
|
case 1 : a+=k[0];
|
||||||
break;
|
break;
|
||||||
|
@ -603,16 +650,32 @@ void hashlittle2(
|
||||||
switch(length)
|
switch(length)
|
||||||
{
|
{
|
||||||
case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;
|
case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;
|
||||||
case 11: c+=((uint32_t)k8[10])<<16; /* fall through */
|
case 11: c+=((uint32_t)k8[10])<<16;
|
||||||
case 10: c+=((uint32_t)k8[9])<<8; /* fall through */
|
ATTR_FALLTHROUGH
|
||||||
case 9 : c+=k8[8]; /* fall through */
|
/* fallthrough */
|
||||||
|
case 10: c+=((uint32_t)k8[9])<<8;
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
|
/* fallthrough */
|
||||||
|
case 9 : c+=k8[8];
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
|
/* fallthrough */
|
||||||
case 8 : b+=k[1]; a+=k[0]; break;
|
case 8 : b+=k[1]; a+=k[0]; break;
|
||||||
case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */
|
case 7 : b+=((uint32_t)k8[6])<<16;
|
||||||
case 6 : b+=((uint32_t)k8[5])<<8; /* fall through */
|
ATTR_FALLTHROUGH
|
||||||
case 5 : b+=k8[4]; /* fall through */
|
/* fallthrough */
|
||||||
|
case 6 : b+=((uint32_t)k8[5])<<8;
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
|
/* fallthrough */
|
||||||
|
case 5 : b+=k8[4];
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
|
/* fallthrough */
|
||||||
case 4 : a+=k[0]; break;
|
case 4 : a+=k[0]; break;
|
||||||
case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */
|
case 3 : a+=((uint32_t)k8[2])<<16;
|
||||||
case 2 : a+=((uint32_t)k8[1])<<8; /* fall through */
|
ATTR_FALLTHROUGH
|
||||||
|
/* fallthrough */
|
||||||
|
case 2 : a+=((uint32_t)k8[1])<<8;
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
|
/* fallthrough */
|
||||||
case 1 : a+=k8[0]; break;
|
case 1 : a+=k8[0]; break;
|
||||||
case 0 : *pc=c; *pb=b; return; /* zero length strings require no mixing */
|
case 0 : *pc=c; *pb=b; return; /* zero length strings require no mixing */
|
||||||
}
|
}
|
||||||
|
@ -642,23 +705,33 @@ void hashlittle2(
|
||||||
b+=k[2]+(((uint32_t)k[3])<<16);
|
b+=k[2]+(((uint32_t)k[3])<<16);
|
||||||
a+=k[0]+(((uint32_t)k[1])<<16);
|
a+=k[0]+(((uint32_t)k[1])<<16);
|
||||||
break;
|
break;
|
||||||
case 11: c+=((uint32_t)k8[10])<<16; /* fall through */
|
case 11: c+=((uint32_t)k8[10])<<16;
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
|
/* fallthrough */
|
||||||
case 10: c+=k[4];
|
case 10: c+=k[4];
|
||||||
b+=k[2]+(((uint32_t)k[3])<<16);
|
b+=k[2]+(((uint32_t)k[3])<<16);
|
||||||
a+=k[0]+(((uint32_t)k[1])<<16);
|
a+=k[0]+(((uint32_t)k[1])<<16);
|
||||||
break;
|
break;
|
||||||
case 9 : c+=k8[8]; /* fall through */
|
case 9 : c+=k8[8];
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
|
/* fallthrough */
|
||||||
case 8 : b+=k[2]+(((uint32_t)k[3])<<16);
|
case 8 : b+=k[2]+(((uint32_t)k[3])<<16);
|
||||||
a+=k[0]+(((uint32_t)k[1])<<16);
|
a+=k[0]+(((uint32_t)k[1])<<16);
|
||||||
break;
|
break;
|
||||||
case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */
|
case 7 : b+=((uint32_t)k8[6])<<16;
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
|
/* fallthrough */
|
||||||
case 6 : b+=k[2];
|
case 6 : b+=k[2];
|
||||||
a+=k[0]+(((uint32_t)k[1])<<16);
|
a+=k[0]+(((uint32_t)k[1])<<16);
|
||||||
break;
|
break;
|
||||||
case 5 : b+=k8[4]; /* fall through */
|
case 5 : b+=k8[4];
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
|
/* fallthrough */
|
||||||
case 4 : a+=k[0]+(((uint32_t)k[1])<<16);
|
case 4 : a+=k[0]+(((uint32_t)k[1])<<16);
|
||||||
break;
|
break;
|
||||||
case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */
|
case 3 : a+=((uint32_t)k8[2])<<16;
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
|
/* fallthrough */
|
||||||
case 2 : a+=k[0];
|
case 2 : a+=k[0];
|
||||||
break;
|
break;
|
||||||
case 1 : a+=k8[0];
|
case 1 : a+=k8[0];
|
||||||
|
@ -693,16 +766,38 @@ void hashlittle2(
|
||||||
switch(length) /* all the case statements fall through */
|
switch(length) /* all the case statements fall through */
|
||||||
{
|
{
|
||||||
case 12: c+=((uint32_t)k[11])<<24;
|
case 12: c+=((uint32_t)k[11])<<24;
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
|
/* fallthrough */
|
||||||
case 11: c+=((uint32_t)k[10])<<16;
|
case 11: c+=((uint32_t)k[10])<<16;
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
|
/* fallthrough */
|
||||||
case 10: c+=((uint32_t)k[9])<<8;
|
case 10: c+=((uint32_t)k[9])<<8;
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
|
/* fallthrough */
|
||||||
case 9 : c+=k[8];
|
case 9 : c+=k[8];
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
|
/* fallthrough */
|
||||||
case 8 : b+=((uint32_t)k[7])<<24;
|
case 8 : b+=((uint32_t)k[7])<<24;
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
|
/* fallthrough */
|
||||||
case 7 : b+=((uint32_t)k[6])<<16;
|
case 7 : b+=((uint32_t)k[6])<<16;
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
|
/* fallthrough */
|
||||||
case 6 : b+=((uint32_t)k[5])<<8;
|
case 6 : b+=((uint32_t)k[5])<<8;
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
|
/* fallthrough */
|
||||||
case 5 : b+=k[4];
|
case 5 : b+=k[4];
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
|
/* fallthrough */
|
||||||
case 4 : a+=((uint32_t)k[3])<<24;
|
case 4 : a+=((uint32_t)k[3])<<24;
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
|
/* fallthrough */
|
||||||
case 3 : a+=((uint32_t)k[2])<<16;
|
case 3 : a+=((uint32_t)k[2])<<16;
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
|
/* fallthrough */
|
||||||
case 2 : a+=((uint32_t)k[1])<<8;
|
case 2 : a+=((uint32_t)k[1])<<8;
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
|
/* fallthrough */
|
||||||
case 1 : a+=k[0];
|
case 1 : a+=k[0];
|
||||||
break;
|
break;
|
||||||
case 0 : *pc=c; *pb=b; return; /* zero length strings require no mixing */
|
case 0 : *pc=c; *pb=b; return; /* zero length strings require no mixing */
|
||||||
|
@ -784,16 +879,32 @@ uint32_t hashbig( const void *key, size_t length, uint32_t initval)
|
||||||
switch(length) /* all the case statements fall through */
|
switch(length) /* all the case statements fall through */
|
||||||
{
|
{
|
||||||
case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;
|
case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;
|
||||||
case 11: c+=((uint32_t)k8[10])<<8; /* fall through */
|
case 11: c+=((uint32_t)k8[10])<<8;
|
||||||
case 10: c+=((uint32_t)k8[9])<<16; /* fall through */
|
ATTR_FALLTHROUGH
|
||||||
case 9 : c+=((uint32_t)k8[8])<<24; /* fall through */
|
/* fallthrough */
|
||||||
|
case 10: c+=((uint32_t)k8[9])<<16;
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
|
/* fallthrough */
|
||||||
|
case 9 : c+=((uint32_t)k8[8])<<24;
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
|
/* fallthrough */
|
||||||
case 8 : b+=k[1]; a+=k[0]; break;
|
case 8 : b+=k[1]; a+=k[0]; break;
|
||||||
case 7 : b+=((uint32_t)k8[6])<<8; /* fall through */
|
case 7 : b+=((uint32_t)k8[6])<<8;
|
||||||
case 6 : b+=((uint32_t)k8[5])<<16; /* fall through */
|
ATTR_FALLTHROUGH
|
||||||
case 5 : b+=((uint32_t)k8[4])<<24; /* fall through */
|
/* fallthrough */
|
||||||
|
case 6 : b+=((uint32_t)k8[5])<<16;
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
|
/* fallthrough */
|
||||||
|
case 5 : b+=((uint32_t)k8[4])<<24;
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
|
/* fallthrough */
|
||||||
case 4 : a+=k[0]; break;
|
case 4 : a+=k[0]; break;
|
||||||
case 3 : a+=((uint32_t)k8[2])<<8; /* fall through */
|
case 3 : a+=((uint32_t)k8[2])<<8;
|
||||||
case 2 : a+=((uint32_t)k8[1])<<16; /* fall through */
|
ATTR_FALLTHROUGH
|
||||||
|
/* fallthrough */
|
||||||
|
case 2 : a+=((uint32_t)k8[1])<<16;
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
|
/* fallthrough */
|
||||||
case 1 : a+=((uint32_t)k8[0])<<24; break;
|
case 1 : a+=((uint32_t)k8[0])<<24; break;
|
||||||
case 0 : return c;
|
case 0 : return c;
|
||||||
}
|
}
|
||||||
|
@ -827,16 +938,38 @@ uint32_t hashbig( const void *key, size_t length, uint32_t initval)
|
||||||
switch(length) /* all the case statements fall through */
|
switch(length) /* all the case statements fall through */
|
||||||
{
|
{
|
||||||
case 12: c+=k[11];
|
case 12: c+=k[11];
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
|
/* fallthrough */
|
||||||
case 11: c+=((uint32_t)k[10])<<8;
|
case 11: c+=((uint32_t)k[10])<<8;
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
|
/* fallthrough */
|
||||||
case 10: c+=((uint32_t)k[9])<<16;
|
case 10: c+=((uint32_t)k[9])<<16;
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
|
/* fallthrough */
|
||||||
case 9 : c+=((uint32_t)k[8])<<24;
|
case 9 : c+=((uint32_t)k[8])<<24;
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
|
/* fallthrough */
|
||||||
case 8 : b+=k[7];
|
case 8 : b+=k[7];
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
|
/* fallthrough */
|
||||||
case 7 : b+=((uint32_t)k[6])<<8;
|
case 7 : b+=((uint32_t)k[6])<<8;
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
|
/* fallthrough */
|
||||||
case 6 : b+=((uint32_t)k[5])<<16;
|
case 6 : b+=((uint32_t)k[5])<<16;
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
|
/* fallthrough */
|
||||||
case 5 : b+=((uint32_t)k[4])<<24;
|
case 5 : b+=((uint32_t)k[4])<<24;
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
|
/* fallthrough */
|
||||||
case 4 : a+=k[3];
|
case 4 : a+=k[3];
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
|
/* fallthrough */
|
||||||
case 3 : a+=((uint32_t)k[2])<<8;
|
case 3 : a+=((uint32_t)k[2])<<8;
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
|
/* fallthrough */
|
||||||
case 2 : a+=((uint32_t)k[1])<<16;
|
case 2 : a+=((uint32_t)k[1])<<16;
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
|
/* fallthrough */
|
||||||
case 1 : a+=((uint32_t)k[0])<<24;
|
case 1 : a+=((uint32_t)k[0])<<24;
|
||||||
break;
|
break;
|
||||||
case 0 : return c;
|
case 0 : return c;
|
||||||
|
|
|
@ -1266,12 +1266,13 @@ verify_dnskey(struct module_env* env, struct val_env* ve,
|
||||||
struct trust_anchor* tp, struct ub_packed_rrset_key* rrset,
|
struct trust_anchor* tp, struct ub_packed_rrset_key* rrset,
|
||||||
struct module_qstate* qstate)
|
struct module_qstate* qstate)
|
||||||
{
|
{
|
||||||
|
char reasonbuf[256];
|
||||||
char* reason = NULL;
|
char* reason = NULL;
|
||||||
uint8_t sigalg[ALGO_NEEDS_MAX+1];
|
uint8_t sigalg[ALGO_NEEDS_MAX+1];
|
||||||
int downprot = env->cfg->harden_algo_downgrade;
|
int downprot = env->cfg->harden_algo_downgrade;
|
||||||
enum sec_status sec = val_verify_DNSKEY_with_TA(env, ve, rrset,
|
enum sec_status sec = val_verify_DNSKEY_with_TA(env, ve, rrset,
|
||||||
tp->ds_rrset, tp->dnskey_rrset, downprot?sigalg:NULL, &reason,
|
tp->ds_rrset, tp->dnskey_rrset, downprot?sigalg:NULL, &reason,
|
||||||
NULL, qstate);
|
NULL, qstate, reasonbuf, sizeof(reasonbuf));
|
||||||
/* sigalg is ignored, it returns algorithms signalled to exist, but
|
/* sigalg is ignored, it returns algorithms signalled to exist, but
|
||||||
* in 5011 there are no other rrsets to check. if downprot is
|
* in 5011 there are no other rrsets to check. if downprot is
|
||||||
* enabled, then it checks that the DNSKEY is signed with all
|
* enabled, then it checks that the DNSKEY is signed with all
|
||||||
|
|
|
@ -177,7 +177,7 @@ static int
|
||||||
nsec_verify_rrset(struct module_env* env, struct val_env* ve,
|
nsec_verify_rrset(struct module_env* env, struct val_env* ve,
|
||||||
struct ub_packed_rrset_key* nsec, struct key_entry_key* kkey,
|
struct ub_packed_rrset_key* nsec, struct key_entry_key* kkey,
|
||||||
char** reason, sldns_ede_code* reason_bogus,
|
char** reason, sldns_ede_code* reason_bogus,
|
||||||
struct module_qstate* qstate)
|
struct module_qstate* qstate, char* reasonbuf, size_t reasonlen)
|
||||||
{
|
{
|
||||||
struct packed_rrset_data* d = (struct packed_rrset_data*)
|
struct packed_rrset_data* d = (struct packed_rrset_data*)
|
||||||
nsec->entry.data;
|
nsec->entry.data;
|
||||||
|
@ -189,7 +189,8 @@ nsec_verify_rrset(struct module_env* env, struct val_env* ve,
|
||||||
if(d->security == sec_status_secure)
|
if(d->security == sec_status_secure)
|
||||||
return 1;
|
return 1;
|
||||||
d->security = val_verify_rrset_entry(env, ve, nsec, kkey, reason,
|
d->security = val_verify_rrset_entry(env, ve, nsec, kkey, reason,
|
||||||
reason_bogus, LDNS_SECTION_AUTHORITY, qstate, &verified);
|
reason_bogus, LDNS_SECTION_AUTHORITY, qstate, &verified,
|
||||||
|
reasonbuf, reasonlen);
|
||||||
if(d->security == sec_status_secure) {
|
if(d->security == sec_status_secure) {
|
||||||
rrset_update_sec_status(env->rrset_cache, nsec, *env->now);
|
rrset_update_sec_status(env->rrset_cache, nsec, *env->now);
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -201,7 +202,8 @@ enum sec_status
|
||||||
val_nsec_prove_nodata_dsreply(struct module_env* env, struct val_env* ve,
|
val_nsec_prove_nodata_dsreply(struct module_env* env, struct val_env* ve,
|
||||||
struct query_info* qinfo, struct reply_info* rep,
|
struct query_info* qinfo, struct reply_info* rep,
|
||||||
struct key_entry_key* kkey, time_t* proof_ttl, char** reason,
|
struct key_entry_key* kkey, time_t* proof_ttl, char** reason,
|
||||||
sldns_ede_code* reason_bogus, struct module_qstate* qstate)
|
sldns_ede_code* reason_bogus, struct module_qstate* qstate,
|
||||||
|
char* reasonbuf, size_t reasonlen)
|
||||||
{
|
{
|
||||||
struct ub_packed_rrset_key* nsec = reply_find_rrset_section_ns(
|
struct ub_packed_rrset_key* nsec = reply_find_rrset_section_ns(
|
||||||
rep, qinfo->qname, qinfo->qname_len, LDNS_RR_TYPE_NSEC,
|
rep, qinfo->qname, qinfo->qname_len, LDNS_RR_TYPE_NSEC,
|
||||||
|
@ -219,7 +221,7 @@ val_nsec_prove_nodata_dsreply(struct module_env* env, struct val_env* ve,
|
||||||
* 2) this is not a delegation point */
|
* 2) this is not a delegation point */
|
||||||
if(nsec) {
|
if(nsec) {
|
||||||
if(!nsec_verify_rrset(env, ve, nsec, kkey, reason,
|
if(!nsec_verify_rrset(env, ve, nsec, kkey, reason,
|
||||||
reason_bogus, qstate)) {
|
reason_bogus, qstate, reasonbuf, reasonlen)) {
|
||||||
verbose(VERB_ALGO, "NSEC RRset for the "
|
verbose(VERB_ALGO, "NSEC RRset for the "
|
||||||
"referral did not verify.");
|
"referral did not verify.");
|
||||||
return sec_status_bogus;
|
return sec_status_bogus;
|
||||||
|
@ -250,7 +252,7 @@ val_nsec_prove_nodata_dsreply(struct module_env* env, struct val_env* ve,
|
||||||
if(rep->rrsets[i]->rk.type != htons(LDNS_RR_TYPE_NSEC))
|
if(rep->rrsets[i]->rk.type != htons(LDNS_RR_TYPE_NSEC))
|
||||||
continue;
|
continue;
|
||||||
if(!nsec_verify_rrset(env, ve, rep->rrsets[i], kkey, reason,
|
if(!nsec_verify_rrset(env, ve, rep->rrsets[i], kkey, reason,
|
||||||
reason_bogus, qstate)) {
|
reason_bogus, qstate, reasonbuf, reasonlen)) {
|
||||||
verbose(VERB_ALGO, "NSEC for empty non-terminal "
|
verbose(VERB_ALGO, "NSEC for empty non-terminal "
|
||||||
"did not verify.");
|
"did not verify.");
|
||||||
*reason = "NSEC for empty non-terminal "
|
*reason = "NSEC for empty non-terminal "
|
||||||
|
|
|
@ -68,6 +68,8 @@ struct key_entry_key;
|
||||||
* @param reason: string explaining why bogus.
|
* @param reason: string explaining why bogus.
|
||||||
* @param reason_bogus: relevant EDE code for validation failure.
|
* @param reason_bogus: relevant EDE code for validation failure.
|
||||||
* @param qstate: qstate with region.
|
* @param qstate: qstate with region.
|
||||||
|
* @param reasonbuf: buffer to use for fail reason string print.
|
||||||
|
* @param reasonlen: length of reasonbuf.
|
||||||
* @return security status.
|
* @return security status.
|
||||||
* SECURE: proved absence of DS.
|
* SECURE: proved absence of DS.
|
||||||
* INSECURE: proved that this was not a delegation point.
|
* INSECURE: proved that this was not a delegation point.
|
||||||
|
@ -78,7 +80,7 @@ enum sec_status val_nsec_prove_nodata_dsreply(struct module_env* env,
|
||||||
struct val_env* ve, struct query_info* qinfo,
|
struct val_env* ve, struct query_info* qinfo,
|
||||||
struct reply_info* rep, struct key_entry_key* kkey,
|
struct reply_info* rep, struct key_entry_key* kkey,
|
||||||
time_t* proof_ttl, char** reason, sldns_ede_code* reason_bogus,
|
time_t* proof_ttl, char** reason, sldns_ede_code* reason_bogus,
|
||||||
struct module_qstate* qstate);
|
struct module_qstate* qstate, char* reasonbuf, size_t reasonlen);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* nsec typemap check, takes an NSEC-type bitmap as argument, checks for type.
|
* nsec typemap check, takes an NSEC-type bitmap as argument, checks for type.
|
||||||
|
|
|
@ -1445,7 +1445,7 @@ static int
|
||||||
list_is_secure(struct module_env* env, struct val_env* ve,
|
list_is_secure(struct module_env* env, struct val_env* ve,
|
||||||
struct ub_packed_rrset_key** list, size_t num,
|
struct ub_packed_rrset_key** list, size_t num,
|
||||||
struct key_entry_key* kkey, char** reason, sldns_ede_code *reason_bogus,
|
struct key_entry_key* kkey, char** reason, sldns_ede_code *reason_bogus,
|
||||||
struct module_qstate* qstate)
|
struct module_qstate* qstate, char* reasonbuf, size_t reasonlen)
|
||||||
{
|
{
|
||||||
struct packed_rrset_data* d;
|
struct packed_rrset_data* d;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
@ -1461,7 +1461,7 @@ list_is_secure(struct module_env* env, struct val_env* ve,
|
||||||
continue;
|
continue;
|
||||||
d->security = val_verify_rrset_entry(env, ve, list[i], kkey,
|
d->security = val_verify_rrset_entry(env, ve, list[i], kkey,
|
||||||
reason, reason_bogus, LDNS_SECTION_AUTHORITY, qstate,
|
reason, reason_bogus, LDNS_SECTION_AUTHORITY, qstate,
|
||||||
&verified);
|
&verified, reasonbuf, reasonlen);
|
||||||
if(d->security != sec_status_secure) {
|
if(d->security != sec_status_secure) {
|
||||||
verbose(VERB_ALGO, "NSEC3 did not verify");
|
verbose(VERB_ALGO, "NSEC3 did not verify");
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1476,7 +1476,7 @@ nsec3_prove_nods(struct module_env* env, struct val_env* ve,
|
||||||
struct ub_packed_rrset_key** list, size_t num,
|
struct ub_packed_rrset_key** list, size_t num,
|
||||||
struct query_info* qinfo, struct key_entry_key* kkey, char** reason,
|
struct query_info* qinfo, struct key_entry_key* kkey, char** reason,
|
||||||
sldns_ede_code* reason_bogus, struct module_qstate* qstate,
|
sldns_ede_code* reason_bogus, struct module_qstate* qstate,
|
||||||
struct nsec3_cache_table* ct)
|
struct nsec3_cache_table* ct, char* reasonbuf, size_t reasonlen)
|
||||||
{
|
{
|
||||||
struct nsec3_filter flt;
|
struct nsec3_filter flt;
|
||||||
struct ce_response ce;
|
struct ce_response ce;
|
||||||
|
@ -1491,7 +1491,8 @@ nsec3_prove_nods(struct module_env* env, struct val_env* ve,
|
||||||
*reason = "no valid NSEC3s";
|
*reason = "no valid NSEC3s";
|
||||||
return sec_status_bogus; /* no valid NSEC3s, bogus */
|
return sec_status_bogus; /* no valid NSEC3s, bogus */
|
||||||
}
|
}
|
||||||
if(!list_is_secure(env, ve, list, num, kkey, reason, reason_bogus, qstate)) {
|
if(!list_is_secure(env, ve, list, num, kkey, reason, reason_bogus,
|
||||||
|
qstate, reasonbuf, reasonlen)) {
|
||||||
*reason = "not all NSEC3 records secure";
|
*reason = "not all NSEC3 records secure";
|
||||||
return sec_status_bogus; /* not all NSEC3 records secure */
|
return sec_status_bogus; /* not all NSEC3 records secure */
|
||||||
}
|
}
|
||||||
|
|
|
@ -210,6 +210,8 @@ nsec3_prove_wildcard(struct module_env* env, struct val_env* ve,
|
||||||
* @param reason_bogus: EDE (RFC8914) code paired with the reason of failure.
|
* @param reason_bogus: EDE (RFC8914) code paired with the reason of failure.
|
||||||
* @param qstate: qstate with region.
|
* @param qstate: qstate with region.
|
||||||
* @param ct: cached hashes table.
|
* @param ct: cached hashes table.
|
||||||
|
* @param reasonbuf: buffer to use for fail reason string print.
|
||||||
|
* @param reasonlen: length of reasonbuf.
|
||||||
* @return:
|
* @return:
|
||||||
* sec_status SECURE of the proposition is proven by the NSEC3 RRs,
|
* sec_status SECURE of the proposition is proven by the NSEC3 RRs,
|
||||||
* BOGUS if not, INSECURE if all of the NSEC3s could be validly ignored.
|
* BOGUS if not, INSECURE if all of the NSEC3s could be validly ignored.
|
||||||
|
@ -222,7 +224,7 @@ nsec3_prove_nods(struct module_env* env, struct val_env* ve,
|
||||||
struct ub_packed_rrset_key** list, size_t num,
|
struct ub_packed_rrset_key** list, size_t num,
|
||||||
struct query_info* qinfo, struct key_entry_key* kkey, char** reason,
|
struct query_info* qinfo, struct key_entry_key* kkey, char** reason,
|
||||||
sldns_ede_code* reason_bogus, struct module_qstate* qstate,
|
sldns_ede_code* reason_bogus, struct module_qstate* qstate,
|
||||||
struct nsec3_cache_table* ct);
|
struct nsec3_cache_table* ct, char* reasonbuf, size_t reasonlen);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prove NXDOMAIN or NODATA.
|
* Prove NXDOMAIN or NODATA.
|
||||||
|
|
|
@ -423,7 +423,10 @@ setup_dsa_sig(unsigned char** sig, unsigned int* len)
|
||||||
if(!dsasig) return 0;
|
if(!dsasig) return 0;
|
||||||
|
|
||||||
#ifdef HAVE_DSA_SIG_SET0
|
#ifdef HAVE_DSA_SIG_SET0
|
||||||
if(!DSA_SIG_set0(dsasig, R, S)) return 0;
|
if(!DSA_SIG_set0(dsasig, R, S)) {
|
||||||
|
DSA_SIG_free(dsasig);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
# ifndef S_SPLINT_S
|
# ifndef S_SPLINT_S
|
||||||
dsasig->r = R;
|
dsasig->r = R;
|
||||||
|
@ -2057,11 +2060,13 @@ verify_canonrrset(sldns_buffer* buf, int algo, unsigned char* sigblock,
|
||||||
digest_size = (digest_size ? digest_size : SHA1_DIGEST_SIZE);
|
digest_size = (digest_size ? digest_size : SHA1_DIGEST_SIZE);
|
||||||
#endif
|
#endif
|
||||||
/* double fallthrough annotation to please gcc parser */
|
/* double fallthrough annotation to please gcc parser */
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
#ifdef USE_SHA2
|
#ifdef USE_SHA2
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
case LDNS_RSASHA256:
|
case LDNS_RSASHA256:
|
||||||
digest_size = (digest_size ? digest_size : SHA256_DIGEST_SIZE);
|
digest_size = (digest_size ? digest_size : SHA256_DIGEST_SIZE);
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
case LDNS_RSASHA512:
|
case LDNS_RSASHA512:
|
||||||
digest_size = (digest_size ? digest_size : SHA512_DIGEST_SIZE);
|
digest_size = (digest_size ? digest_size : SHA512_DIGEST_SIZE);
|
||||||
|
@ -2077,6 +2082,7 @@ verify_canonrrset(sldns_buffer* buf, int algo, unsigned char* sigblock,
|
||||||
#ifdef USE_ECDSA
|
#ifdef USE_ECDSA
|
||||||
case LDNS_ECDSAP256SHA256:
|
case LDNS_ECDSAP256SHA256:
|
||||||
digest_size = (digest_size ? digest_size : SHA256_DIGEST_SIZE);
|
digest_size = (digest_size ? digest_size : SHA256_DIGEST_SIZE);
|
||||||
|
ATTR_FALLTHROUGH
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
case LDNS_ECDSAP384SHA384:
|
case LDNS_ECDSAP384SHA384:
|
||||||
digest_size = (digest_size ? digest_size : SHA384_DIGEST_SIZE);
|
digest_size = (digest_size ? digest_size : SHA384_DIGEST_SIZE);
|
||||||
|
|
|
@ -623,7 +623,8 @@ enum sec_status
|
||||||
dnskeyset_verify_rrset(struct module_env* env, struct val_env* ve,
|
dnskeyset_verify_rrset(struct module_env* env, struct val_env* ve,
|
||||||
struct ub_packed_rrset_key* rrset, struct ub_packed_rrset_key* dnskey,
|
struct ub_packed_rrset_key* rrset, struct ub_packed_rrset_key* dnskey,
|
||||||
uint8_t* sigalg, char** reason, sldns_ede_code *reason_bogus,
|
uint8_t* sigalg, char** reason, sldns_ede_code *reason_bogus,
|
||||||
sldns_pkt_section section, struct module_qstate* qstate, int* verified)
|
sldns_pkt_section section, struct module_qstate* qstate, int* verified,
|
||||||
|
char* reasonbuf, size_t reasonlen)
|
||||||
{
|
{
|
||||||
enum sec_status sec;
|
enum sec_status sec;
|
||||||
size_t i, num;
|
size_t i, num;
|
||||||
|
@ -680,7 +681,8 @@ dnskeyset_verify_rrset(struct module_env* env, struct val_env* ve,
|
||||||
verbose(VERB_ALGO, "rrset failed to verify: "
|
verbose(VERB_ALGO, "rrset failed to verify: "
|
||||||
"no valid signatures for %d algorithms",
|
"no valid signatures for %d algorithms",
|
||||||
(int)algo_needs_num_missing(&needs));
|
(int)algo_needs_num_missing(&needs));
|
||||||
algo_needs_reason(env, alg, reason, "no signatures");
|
algo_needs_reason(alg, reason, "no signatures", reasonbuf,
|
||||||
|
reasonlen);
|
||||||
} else {
|
} else {
|
||||||
verbose(VERB_ALGO, "rrset failed to verify: "
|
verbose(VERB_ALGO, "rrset failed to verify: "
|
||||||
"no valid signatures");
|
"no valid signatures");
|
||||||
|
@ -688,17 +690,16 @@ dnskeyset_verify_rrset(struct module_env* env, struct val_env* ve,
|
||||||
return sec_status_bogus;
|
return sec_status_bogus;
|
||||||
}
|
}
|
||||||
|
|
||||||
void algo_needs_reason(struct module_env* env, int alg, char** reason, char* s)
|
void algo_needs_reason(int alg, char** reason, char* s, char* reasonbuf,
|
||||||
|
size_t reasonlen)
|
||||||
{
|
{
|
||||||
char buf[256];
|
|
||||||
sldns_lookup_table *t = sldns_lookup_by_id(sldns_algorithms, alg);
|
sldns_lookup_table *t = sldns_lookup_by_id(sldns_algorithms, alg);
|
||||||
if(t&&t->name)
|
if(t&&t->name)
|
||||||
snprintf(buf, sizeof(buf), "%s with algorithm %s", s, t->name);
|
snprintf(reasonbuf, reasonlen, "%s with algorithm %s", s,
|
||||||
else snprintf(buf, sizeof(buf), "%s with algorithm ALG%u", s,
|
t->name);
|
||||||
|
else snprintf(reasonbuf, reasonlen, "%s with algorithm ALG%u", s,
|
||||||
(unsigned)alg);
|
(unsigned)alg);
|
||||||
*reason = regional_strdup(env->scratch, buf);
|
*reason = reasonbuf;
|
||||||
if(!*reason)
|
|
||||||
*reason = s;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enum sec_status
|
enum sec_status
|
||||||
|
|
|
@ -134,12 +134,14 @@ int algo_needs_missing(struct algo_needs* n);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Format error reason for algorithm missing.
|
* Format error reason for algorithm missing.
|
||||||
* @param env: module env with scratch for temp storage of string.
|
|
||||||
* @param alg: DNSKEY-algorithm missing.
|
* @param alg: DNSKEY-algorithm missing.
|
||||||
* @param reason: destination.
|
* @param reason: destination.
|
||||||
* @param s: string, appended with 'with algorithm ..'.
|
* @param s: string, appended with 'with algorithm ..'.
|
||||||
|
* @param reasonbuf: buffer to use for fail reason string print.
|
||||||
|
* @param reasonlen: length of reasonbuf.
|
||||||
*/
|
*/
|
||||||
void algo_needs_reason(struct module_env* env, int alg, char** reason, char* s);
|
void algo_needs_reason(int alg, char** reason, char* s, char* reasonbuf,
|
||||||
|
size_t reasonlen);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if dnskey matches a DS digest
|
* Check if dnskey matches a DS digest
|
||||||
|
@ -261,6 +263,8 @@ uint16_t dnskey_get_flags(struct ub_packed_rrset_key* k, size_t idx);
|
||||||
* @param section: section of packet where this rrset comes from.
|
* @param section: section of packet where this rrset comes from.
|
||||||
* @param qstate: qstate with region.
|
* @param qstate: qstate with region.
|
||||||
* @param verified: if not NULL the number of RRSIG validations is returned.
|
* @param verified: if not NULL the number of RRSIG validations is returned.
|
||||||
|
* @param reasonbuf: buffer to use for fail reason string print.
|
||||||
|
* @param reasonlen: length of reasonbuf.
|
||||||
* @return SECURE if one key in the set verifies one rrsig.
|
* @return SECURE if one key in the set verifies one rrsig.
|
||||||
* UNCHECKED on allocation errors, unsupported algorithms, malformed data,
|
* UNCHECKED on allocation errors, unsupported algorithms, malformed data,
|
||||||
* and BOGUS on verification failures (no keys match any signatures).
|
* and BOGUS on verification failures (no keys match any signatures).
|
||||||
|
@ -269,8 +273,8 @@ enum sec_status dnskeyset_verify_rrset(struct module_env* env,
|
||||||
struct val_env* ve, struct ub_packed_rrset_key* rrset,
|
struct val_env* ve, struct ub_packed_rrset_key* rrset,
|
||||||
struct ub_packed_rrset_key* dnskey, uint8_t* sigalg,
|
struct ub_packed_rrset_key* dnskey, uint8_t* sigalg,
|
||||||
char** reason, sldns_ede_code *reason_bogus,
|
char** reason, sldns_ede_code *reason_bogus,
|
||||||
sldns_pkt_section section, struct module_qstate* qstate, int* verified);
|
sldns_pkt_section section, struct module_qstate* qstate, int* verified,
|
||||||
|
char* reasonbuf, size_t reasonlen);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* verify rrset against one specific dnskey (from rrset)
|
* verify rrset against one specific dnskey (from rrset)
|
||||||
|
|
|
@ -240,6 +240,26 @@ val_find_best_signer(struct ub_packed_rrset_key* rrset,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Detect if the, unsigned, CNAME is under a previous DNAME RR in the
|
||||||
|
* message, and thus it was generated from that previous DNAME.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
cname_under_previous_dname(struct reply_info* rep, size_t cname_idx,
|
||||||
|
size_t* ret)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
for(i=0; i<cname_idx; i++) {
|
||||||
|
if(ntohs(rep->rrsets[i]->rk.type) == LDNS_RR_TYPE_DNAME &&
|
||||||
|
dname_strict_subdomain_c(rep->rrsets[cname_idx]->
|
||||||
|
rk.dname, rep->rrsets[i]->rk.dname)) {
|
||||||
|
*ret = i;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*ret = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
val_find_signer(enum val_classification subtype, struct query_info* qinf,
|
val_find_signer(enum val_classification subtype, struct query_info* qinf,
|
||||||
struct reply_info* rep, size_t skip, uint8_t** signer_name,
|
struct reply_info* rep, size_t skip, uint8_t** signer_name,
|
||||||
|
@ -275,12 +295,19 @@ val_find_signer(enum val_classification subtype, struct query_info* qinf,
|
||||||
*signer_name = NULL;
|
*signer_name = NULL;
|
||||||
*signer_len = 0;
|
*signer_len = 0;
|
||||||
} else if(subtype == VAL_CLASS_CNAME) {
|
} else if(subtype == VAL_CLASS_CNAME) {
|
||||||
|
size_t j;
|
||||||
/* check for the first signed cname/dname rrset */
|
/* check for the first signed cname/dname rrset */
|
||||||
for(i=skip; i<rep->an_numrrsets; i++) {
|
for(i=skip; i<rep->an_numrrsets; i++) {
|
||||||
val_find_rrset_signer(rep->rrsets[i],
|
val_find_rrset_signer(rep->rrsets[i],
|
||||||
signer_name, signer_len);
|
signer_name, signer_len);
|
||||||
if(*signer_name)
|
if(*signer_name)
|
||||||
return;
|
return;
|
||||||
|
if(ntohs(rep->rrsets[i]->rk.type) == LDNS_RR_TYPE_CNAME
|
||||||
|
&& cname_under_previous_dname(rep, i, &j)) {
|
||||||
|
val_find_rrset_signer(rep->rrsets[j],
|
||||||
|
signer_name, signer_len);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if(ntohs(rep->rrsets[i]->rk.type) != LDNS_RR_TYPE_DNAME)
|
if(ntohs(rep->rrsets[i]->rk.type) != LDNS_RR_TYPE_DNAME)
|
||||||
break; /* only check CNAME after a DNAME */
|
break; /* only check CNAME after a DNAME */
|
||||||
}
|
}
|
||||||
|
@ -379,7 +406,7 @@ val_verify_rrset(struct module_env* env, struct val_env* ve,
|
||||||
struct ub_packed_rrset_key* rrset, struct ub_packed_rrset_key* keys,
|
struct ub_packed_rrset_key* rrset, struct ub_packed_rrset_key* keys,
|
||||||
uint8_t* sigalg, char** reason, sldns_ede_code *reason_bogus,
|
uint8_t* sigalg, char** reason, sldns_ede_code *reason_bogus,
|
||||||
sldns_pkt_section section, struct module_qstate* qstate,
|
sldns_pkt_section section, struct module_qstate* qstate,
|
||||||
int *verified)
|
int *verified, char* reasonbuf, size_t reasonlen)
|
||||||
{
|
{
|
||||||
enum sec_status sec;
|
enum sec_status sec;
|
||||||
struct packed_rrset_data* d = (struct packed_rrset_data*)rrset->
|
struct packed_rrset_data* d = (struct packed_rrset_data*)rrset->
|
||||||
|
@ -404,7 +431,7 @@ val_verify_rrset(struct module_env* env, struct val_env* ve,
|
||||||
log_nametypeclass(VERB_ALGO, "verify rrset", rrset->rk.dname,
|
log_nametypeclass(VERB_ALGO, "verify rrset", rrset->rk.dname,
|
||||||
ntohs(rrset->rk.type), ntohs(rrset->rk.rrset_class));
|
ntohs(rrset->rk.type), ntohs(rrset->rk.rrset_class));
|
||||||
sec = dnskeyset_verify_rrset(env, ve, rrset, keys, sigalg, reason,
|
sec = dnskeyset_verify_rrset(env, ve, rrset, keys, sigalg, reason,
|
||||||
reason_bogus, section, qstate, verified);
|
reason_bogus, section, qstate, verified, reasonbuf, reasonlen);
|
||||||
verbose(VERB_ALGO, "verify result: %s", sec_status_to_string(sec));
|
verbose(VERB_ALGO, "verify result: %s", sec_status_to_string(sec));
|
||||||
regional_free_all(env->scratch);
|
regional_free_all(env->scratch);
|
||||||
|
|
||||||
|
@ -439,7 +466,7 @@ val_verify_rrset_entry(struct module_env* env, struct val_env* ve,
|
||||||
struct ub_packed_rrset_key* rrset, struct key_entry_key* kkey,
|
struct ub_packed_rrset_key* rrset, struct key_entry_key* kkey,
|
||||||
char** reason, sldns_ede_code *reason_bogus,
|
char** reason, sldns_ede_code *reason_bogus,
|
||||||
sldns_pkt_section section, struct module_qstate* qstate,
|
sldns_pkt_section section, struct module_qstate* qstate,
|
||||||
int* verified)
|
int* verified, char* reasonbuf, size_t reasonlen)
|
||||||
{
|
{
|
||||||
/* temporary dnskey rrset-key */
|
/* temporary dnskey rrset-key */
|
||||||
struct ub_packed_rrset_key dnskey;
|
struct ub_packed_rrset_key dnskey;
|
||||||
|
@ -453,7 +480,7 @@ val_verify_rrset_entry(struct module_env* env, struct val_env* ve,
|
||||||
dnskey.entry.key = &dnskey;
|
dnskey.entry.key = &dnskey;
|
||||||
dnskey.entry.data = kd->rrset_data;
|
dnskey.entry.data = kd->rrset_data;
|
||||||
sec = val_verify_rrset(env, ve, rrset, &dnskey, kd->algo, reason,
|
sec = val_verify_rrset(env, ve, rrset, &dnskey, kd->algo, reason,
|
||||||
reason_bogus, section, qstate, verified);
|
reason_bogus, section, qstate, verified, reasonbuf, reasonlen);
|
||||||
return sec;
|
return sec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -463,7 +490,7 @@ verify_dnskeys_with_ds_rr(struct module_env* env, struct val_env* ve,
|
||||||
struct ub_packed_rrset_key* dnskey_rrset,
|
struct ub_packed_rrset_key* dnskey_rrset,
|
||||||
struct ub_packed_rrset_key* ds_rrset, size_t ds_idx, char** reason,
|
struct ub_packed_rrset_key* ds_rrset, size_t ds_idx, char** reason,
|
||||||
sldns_ede_code *reason_bogus, struct module_qstate* qstate,
|
sldns_ede_code *reason_bogus, struct module_qstate* qstate,
|
||||||
int *nonechecked)
|
int *nonechecked, char* reasonbuf, size_t reasonlen)
|
||||||
{
|
{
|
||||||
enum sec_status sec = sec_status_bogus;
|
enum sec_status sec = sec_status_bogus;
|
||||||
size_t i, num, numchecked = 0, numhashok = 0, numsizesupp = 0;
|
size_t i, num, numchecked = 0, numhashok = 0, numsizesupp = 0;
|
||||||
|
@ -517,8 +544,8 @@ verify_dnskeys_with_ds_rr(struct module_env* env, struct val_env* ve,
|
||||||
return sec_status_insecure;
|
return sec_status_insecure;
|
||||||
}
|
}
|
||||||
if(numchecked == 0) {
|
if(numchecked == 0) {
|
||||||
algo_needs_reason(env, ds_get_key_algo(ds_rrset, ds_idx),
|
algo_needs_reason(ds_get_key_algo(ds_rrset, ds_idx),
|
||||||
reason, "no keys have a DS");
|
reason, "no keys have a DS", reasonbuf, reasonlen);
|
||||||
*nonechecked = 1;
|
*nonechecked = 1;
|
||||||
} else if(numhashok == 0) {
|
} else if(numhashok == 0) {
|
||||||
*reason = "DS hash mismatches key";
|
*reason = "DS hash mismatches key";
|
||||||
|
@ -549,7 +576,8 @@ enum sec_status
|
||||||
val_verify_DNSKEY_with_DS(struct module_env* env, struct val_env* ve,
|
val_verify_DNSKEY_with_DS(struct module_env* env, struct val_env* ve,
|
||||||
struct ub_packed_rrset_key* dnskey_rrset,
|
struct ub_packed_rrset_key* dnskey_rrset,
|
||||||
struct ub_packed_rrset_key* ds_rrset, uint8_t* sigalg, char** reason,
|
struct ub_packed_rrset_key* ds_rrset, uint8_t* sigalg, char** reason,
|
||||||
sldns_ede_code *reason_bogus, struct module_qstate* qstate)
|
sldns_ede_code *reason_bogus, struct module_qstate* qstate,
|
||||||
|
char* reasonbuf, size_t reasonlen)
|
||||||
{
|
{
|
||||||
/* as long as this is false, we can consider this DS rrset to be
|
/* as long as this is false, we can consider this DS rrset to be
|
||||||
* equivalent to no DS rrset. */
|
* equivalent to no DS rrset. */
|
||||||
|
@ -588,7 +616,7 @@ val_verify_DNSKEY_with_DS(struct module_env* env, struct val_env* ve,
|
||||||
|
|
||||||
sec = verify_dnskeys_with_ds_rr(env, ve, dnskey_rrset,
|
sec = verify_dnskeys_with_ds_rr(env, ve, dnskey_rrset,
|
||||||
ds_rrset, i, reason, reason_bogus, qstate,
|
ds_rrset, i, reason, reason_bogus, qstate,
|
||||||
&nonechecked);
|
&nonechecked, reasonbuf, reasonlen);
|
||||||
if(sec == sec_status_insecure) {
|
if(sec == sec_status_insecure) {
|
||||||
/* DNSKEY too large unsupported or algo refused by
|
/* DNSKEY too large unsupported or algo refused by
|
||||||
* crypto lib. */
|
* crypto lib. */
|
||||||
|
@ -639,8 +667,8 @@ val_verify_DNSKEY_with_DS(struct module_env* env, struct val_env* ve,
|
||||||
/* If any were understandable, then it is bad. */
|
/* If any were understandable, then it is bad. */
|
||||||
verbose(VERB_QUERY, "Failed to match any usable DS to a DNSKEY.");
|
verbose(VERB_QUERY, "Failed to match any usable DS to a DNSKEY.");
|
||||||
if(sigalg && (alg=algo_needs_missing(&needs)) != 0) {
|
if(sigalg && (alg=algo_needs_missing(&needs)) != 0) {
|
||||||
algo_needs_reason(env, alg, reason, "missing verification of "
|
algo_needs_reason(alg, reason, "missing verification of "
|
||||||
"DNSKEY signature");
|
"DNSKEY signature", reasonbuf, reasonlen);
|
||||||
}
|
}
|
||||||
return sec_status_bogus;
|
return sec_status_bogus;
|
||||||
}
|
}
|
||||||
|
@ -649,12 +677,13 @@ struct key_entry_key*
|
||||||
val_verify_new_DNSKEYs(struct regional* region, struct module_env* env,
|
val_verify_new_DNSKEYs(struct regional* region, struct module_env* env,
|
||||||
struct val_env* ve, struct ub_packed_rrset_key* dnskey_rrset,
|
struct val_env* ve, struct ub_packed_rrset_key* dnskey_rrset,
|
||||||
struct ub_packed_rrset_key* ds_rrset, int downprot, char** reason,
|
struct ub_packed_rrset_key* ds_rrset, int downprot, char** reason,
|
||||||
sldns_ede_code *reason_bogus, struct module_qstate* qstate)
|
sldns_ede_code *reason_bogus, struct module_qstate* qstate,
|
||||||
|
char* reasonbuf, size_t reasonlen)
|
||||||
{
|
{
|
||||||
uint8_t sigalg[ALGO_NEEDS_MAX+1];
|
uint8_t sigalg[ALGO_NEEDS_MAX+1];
|
||||||
enum sec_status sec = val_verify_DNSKEY_with_DS(env, ve,
|
enum sec_status sec = val_verify_DNSKEY_with_DS(env, ve,
|
||||||
dnskey_rrset, ds_rrset, downprot?sigalg:NULL, reason,
|
dnskey_rrset, ds_rrset, downprot?sigalg:NULL, reason,
|
||||||
reason_bogus, qstate);
|
reason_bogus, qstate, reasonbuf, reasonlen);
|
||||||
|
|
||||||
if(sec == sec_status_secure) {
|
if(sec == sec_status_secure) {
|
||||||
return key_entry_create_rrset(region,
|
return key_entry_create_rrset(region,
|
||||||
|
@ -679,7 +708,8 @@ val_verify_DNSKEY_with_TA(struct module_env* env, struct val_env* ve,
|
||||||
struct ub_packed_rrset_key* dnskey_rrset,
|
struct ub_packed_rrset_key* dnskey_rrset,
|
||||||
struct ub_packed_rrset_key* ta_ds,
|
struct ub_packed_rrset_key* ta_ds,
|
||||||
struct ub_packed_rrset_key* ta_dnskey, uint8_t* sigalg, char** reason,
|
struct ub_packed_rrset_key* ta_dnskey, uint8_t* sigalg, char** reason,
|
||||||
sldns_ede_code *reason_bogus, struct module_qstate* qstate)
|
sldns_ede_code *reason_bogus, struct module_qstate* qstate,
|
||||||
|
char* reasonbuf, size_t reasonlen)
|
||||||
{
|
{
|
||||||
/* as long as this is false, we can consider this anchor to be
|
/* as long as this is false, we can consider this anchor to be
|
||||||
* equivalent to no anchor. */
|
* equivalent to no anchor. */
|
||||||
|
@ -730,7 +760,8 @@ val_verify_DNSKEY_with_TA(struct module_env* env, struct val_env* ve,
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
sec = verify_dnskeys_with_ds_rr(env, ve, dnskey_rrset,
|
sec = verify_dnskeys_with_ds_rr(env, ve, dnskey_rrset,
|
||||||
ta_ds, i, reason, reason_bogus, qstate, &nonechecked);
|
ta_ds, i, reason, reason_bogus, qstate, &nonechecked,
|
||||||
|
reasonbuf, reasonlen);
|
||||||
if(sec == sec_status_insecure) {
|
if(sec == sec_status_insecure) {
|
||||||
has_algo_refusal = 1;
|
has_algo_refusal = 1;
|
||||||
continue;
|
continue;
|
||||||
|
@ -810,8 +841,8 @@ val_verify_DNSKEY_with_TA(struct module_env* env, struct val_env* ve,
|
||||||
/* If any were understandable, then it is bad. */
|
/* If any were understandable, then it is bad. */
|
||||||
verbose(VERB_QUERY, "Failed to match any usable anchor to a DNSKEY.");
|
verbose(VERB_QUERY, "Failed to match any usable anchor to a DNSKEY.");
|
||||||
if(sigalg && (alg=algo_needs_missing(&needs)) != 0) {
|
if(sigalg && (alg=algo_needs_missing(&needs)) != 0) {
|
||||||
algo_needs_reason(env, alg, reason, "missing verification of "
|
algo_needs_reason(alg, reason, "missing verification of "
|
||||||
"DNSKEY signature");
|
"DNSKEY signature", reasonbuf, reasonlen);
|
||||||
}
|
}
|
||||||
return sec_status_bogus;
|
return sec_status_bogus;
|
||||||
}
|
}
|
||||||
|
@ -821,12 +852,14 @@ val_verify_new_DNSKEYs_with_ta(struct regional* region, struct module_env* env,
|
||||||
struct val_env* ve, struct ub_packed_rrset_key* dnskey_rrset,
|
struct val_env* ve, struct ub_packed_rrset_key* dnskey_rrset,
|
||||||
struct ub_packed_rrset_key* ta_ds_rrset,
|
struct ub_packed_rrset_key* ta_ds_rrset,
|
||||||
struct ub_packed_rrset_key* ta_dnskey_rrset, int downprot,
|
struct ub_packed_rrset_key* ta_dnskey_rrset, int downprot,
|
||||||
char** reason, sldns_ede_code *reason_bogus, struct module_qstate* qstate)
|
char** reason, sldns_ede_code *reason_bogus,
|
||||||
|
struct module_qstate* qstate, char* reasonbuf, size_t reasonlen)
|
||||||
{
|
{
|
||||||
uint8_t sigalg[ALGO_NEEDS_MAX+1];
|
uint8_t sigalg[ALGO_NEEDS_MAX+1];
|
||||||
enum sec_status sec = val_verify_DNSKEY_with_TA(env, ve,
|
enum sec_status sec = val_verify_DNSKEY_with_TA(env, ve,
|
||||||
dnskey_rrset, ta_ds_rrset, ta_dnskey_rrset,
|
dnskey_rrset, ta_ds_rrset, ta_dnskey_rrset,
|
||||||
downprot?sigalg:NULL, reason, reason_bogus, qstate);
|
downprot?sigalg:NULL, reason, reason_bogus, qstate,
|
||||||
|
reasonbuf, reasonlen);
|
||||||
|
|
||||||
if(sec == sec_status_secure) {
|
if(sec == sec_status_secure) {
|
||||||
return key_entry_create_rrset(region,
|
return key_entry_create_rrset(region,
|
||||||
|
@ -979,7 +1012,7 @@ void
|
||||||
val_fill_reply(struct reply_info* chase, struct reply_info* orig,
|
val_fill_reply(struct reply_info* chase, struct reply_info* orig,
|
||||||
size_t skip, uint8_t* name, size_t len, uint8_t* signer)
|
size_t skip, uint8_t* name, size_t len, uint8_t* signer)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i, j;
|
||||||
int seen_dname = 0;
|
int seen_dname = 0;
|
||||||
chase->rrset_count = 0;
|
chase->rrset_count = 0;
|
||||||
chase->an_numrrsets = 0;
|
chase->an_numrrsets = 0;
|
||||||
|
@ -1002,6 +1035,13 @@ val_fill_reply(struct reply_info* chase, struct reply_info* orig,
|
||||||
LDNS_RR_TYPE_DNAME) {
|
LDNS_RR_TYPE_DNAME) {
|
||||||
seen_dname = 1;
|
seen_dname = 1;
|
||||||
}
|
}
|
||||||
|
} else if(ntohs(orig->rrsets[i]->rk.type) == LDNS_RR_TYPE_CNAME
|
||||||
|
&& ((struct packed_rrset_data*)orig->rrsets[i]->
|
||||||
|
entry.data)->rrsig_count == 0 &&
|
||||||
|
cname_under_previous_dname(orig, i, &j) &&
|
||||||
|
rrset_has_signer(orig->rrsets[j], name, len)) {
|
||||||
|
chase->rrsets[chase->an_numrrsets++] = orig->rrsets[j];
|
||||||
|
chase->rrsets[chase->an_numrrsets++] = orig->rrsets[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* AUTHORITY section */
|
/* AUTHORITY section */
|
||||||
|
|
|
@ -125,13 +125,15 @@ void val_find_signer(enum val_classification subtype,
|
||||||
* @param section: section of packet where this rrset comes from.
|
* @param section: section of packet where this rrset comes from.
|
||||||
* @param qstate: qstate with region.
|
* @param qstate: qstate with region.
|
||||||
* @param verified: if not NULL, the number of RRSIG validations is returned.
|
* @param verified: if not NULL, the number of RRSIG validations is returned.
|
||||||
|
* @param reasonbuf: buffer to use for fail reason string print.
|
||||||
|
* @param reasonlen: length of reasonbuf.
|
||||||
* @return security status of verification.
|
* @return security status of verification.
|
||||||
*/
|
*/
|
||||||
enum sec_status val_verify_rrset_entry(struct module_env* env,
|
enum sec_status val_verify_rrset_entry(struct module_env* env,
|
||||||
struct val_env* ve, struct ub_packed_rrset_key* rrset,
|
struct val_env* ve, struct ub_packed_rrset_key* rrset,
|
||||||
struct key_entry_key* kkey, char** reason, sldns_ede_code *reason_bogus,
|
struct key_entry_key* kkey, char** reason, sldns_ede_code *reason_bogus,
|
||||||
sldns_pkt_section section, struct module_qstate* qstate,
|
sldns_pkt_section section, struct module_qstate* qstate,
|
||||||
int* verified);
|
int* verified, char* reasonbuf, size_t reasonlen);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify DNSKEYs with DS rrset. Like val_verify_new_DNSKEYs but
|
* Verify DNSKEYs with DS rrset. Like val_verify_new_DNSKEYs but
|
||||||
|
@ -146,6 +148,8 @@ enum sec_status val_verify_rrset_entry(struct module_env* env,
|
||||||
* @param reason: reason of failure. Fixed string or alloced in scratch.
|
* @param reason: reason of failure. Fixed string or alloced in scratch.
|
||||||
* @param reason_bogus: EDE (RFC8914) code paired with the reason of failure.
|
* @param reason_bogus: EDE (RFC8914) code paired with the reason of failure.
|
||||||
* @param qstate: qstate with region.
|
* @param qstate: qstate with region.
|
||||||
|
* @param reasonbuf: buffer to use for fail reason string print.
|
||||||
|
* @param reasonlen: length of reasonbuf.
|
||||||
* @return: sec_status_secure if a DS matches.
|
* @return: sec_status_secure if a DS matches.
|
||||||
* sec_status_insecure if end of trust (i.e., unknown algorithms).
|
* sec_status_insecure if end of trust (i.e., unknown algorithms).
|
||||||
* sec_status_bogus if it fails.
|
* sec_status_bogus if it fails.
|
||||||
|
@ -153,7 +157,8 @@ enum sec_status val_verify_rrset_entry(struct module_env* env,
|
||||||
enum sec_status val_verify_DNSKEY_with_DS(struct module_env* env,
|
enum sec_status val_verify_DNSKEY_with_DS(struct module_env* env,
|
||||||
struct val_env* ve, struct ub_packed_rrset_key* dnskey_rrset,
|
struct val_env* ve, struct ub_packed_rrset_key* dnskey_rrset,
|
||||||
struct ub_packed_rrset_key* ds_rrset, uint8_t* sigalg, char** reason,
|
struct ub_packed_rrset_key* ds_rrset, uint8_t* sigalg, char** reason,
|
||||||
sldns_ede_code *reason_bogus, struct module_qstate* qstate);
|
sldns_ede_code *reason_bogus, struct module_qstate* qstate,
|
||||||
|
char* reasonbuf, size_t reasonlen);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify DNSKEYs with DS and DNSKEY rrset. Like val_verify_DNSKEY_with_DS
|
* Verify DNSKEYs with DS and DNSKEY rrset. Like val_verify_DNSKEY_with_DS
|
||||||
|
@ -169,6 +174,8 @@ enum sec_status val_verify_DNSKEY_with_DS(struct module_env* env,
|
||||||
* @param reason: reason of failure. Fixed string or alloced in scratch.
|
* @param reason: reason of failure. Fixed string or alloced in scratch.
|
||||||
* @param reason_bogus: EDE (RFC8914) code paired with the reason of failure.
|
* @param reason_bogus: EDE (RFC8914) code paired with the reason of failure.
|
||||||
* @param qstate: qstate with region.
|
* @param qstate: qstate with region.
|
||||||
|
* @param reasonbuf: buffer to use for fail reason string print.
|
||||||
|
* @param reasonlen: length of reasonbuf.
|
||||||
* @return: sec_status_secure if a DS matches.
|
* @return: sec_status_secure if a DS matches.
|
||||||
* sec_status_insecure if end of trust (i.e., unknown algorithms).
|
* sec_status_insecure if end of trust (i.e., unknown algorithms).
|
||||||
* sec_status_bogus if it fails.
|
* sec_status_bogus if it fails.
|
||||||
|
@ -177,7 +184,8 @@ enum sec_status val_verify_DNSKEY_with_TA(struct module_env* env,
|
||||||
struct val_env* ve, struct ub_packed_rrset_key* dnskey_rrset,
|
struct val_env* ve, struct ub_packed_rrset_key* dnskey_rrset,
|
||||||
struct ub_packed_rrset_key* ta_ds,
|
struct ub_packed_rrset_key* ta_ds,
|
||||||
struct ub_packed_rrset_key* ta_dnskey, uint8_t* sigalg, char** reason,
|
struct ub_packed_rrset_key* ta_dnskey, uint8_t* sigalg, char** reason,
|
||||||
sldns_ede_code *reason_bogus, struct module_qstate* qstate);
|
sldns_ede_code *reason_bogus, struct module_qstate* qstate,
|
||||||
|
char* reasonbuf, size_t reasonlen);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify new DNSKEYs with DS rrset. The DS contains hash values that should
|
* Verify new DNSKEYs with DS rrset. The DS contains hash values that should
|
||||||
|
@ -194,6 +202,8 @@ enum sec_status val_verify_DNSKEY_with_TA(struct module_env* env,
|
||||||
* @param reason: reason of failure. Fixed string or alloced in scratch.
|
* @param reason: reason of failure. Fixed string or alloced in scratch.
|
||||||
* @param reason_bogus: EDE (RFC8914) code paired with the reason of failure.
|
* @param reason_bogus: EDE (RFC8914) code paired with the reason of failure.
|
||||||
* @param qstate: qstate with region.
|
* @param qstate: qstate with region.
|
||||||
|
* @param reasonbuf: buffer to use for fail reason string print.
|
||||||
|
* @param reasonlen: length of reasonbuf.
|
||||||
* @return a KeyEntry. This will either contain the now trusted
|
* @return a KeyEntry. This will either contain the now trusted
|
||||||
* dnskey_rrset, a "null" key entry indicating that this DS
|
* dnskey_rrset, a "null" key entry indicating that this DS
|
||||||
* rrset/DNSKEY pair indicate an secure end to the island of trust
|
* rrset/DNSKEY pair indicate an secure end to the island of trust
|
||||||
|
@ -208,7 +218,8 @@ struct key_entry_key* val_verify_new_DNSKEYs(struct regional* region,
|
||||||
struct module_env* env, struct val_env* ve,
|
struct module_env* env, struct val_env* ve,
|
||||||
struct ub_packed_rrset_key* dnskey_rrset,
|
struct ub_packed_rrset_key* dnskey_rrset,
|
||||||
struct ub_packed_rrset_key* ds_rrset, int downprot, char** reason,
|
struct ub_packed_rrset_key* ds_rrset, int downprot, char** reason,
|
||||||
sldns_ede_code *reason_bogus, struct module_qstate* qstate);
|
sldns_ede_code *reason_bogus, struct module_qstate* qstate,
|
||||||
|
char* reasonbuf, size_t reasonlen);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify rrset with trust anchor: DS and DNSKEY rrset.
|
* Verify rrset with trust anchor: DS and DNSKEY rrset.
|
||||||
|
@ -224,6 +235,8 @@ struct key_entry_key* val_verify_new_DNSKEYs(struct regional* region,
|
||||||
* @param reason: reason of failure. Fixed string or alloced in scratch.
|
* @param reason: reason of failure. Fixed string or alloced in scratch.
|
||||||
* @param reason_bogus: EDE (RFC8914) code paired with the reason of failure.
|
* @param reason_bogus: EDE (RFC8914) code paired with the reason of failure.
|
||||||
* @param qstate: qstate with region.
|
* @param qstate: qstate with region.
|
||||||
|
* @param reasonbuf: buffer to use for fail reason string print.
|
||||||
|
* @param reasonlen: length of reasonbuf.
|
||||||
* @return a KeyEntry. This will either contain the now trusted
|
* @return a KeyEntry. This will either contain the now trusted
|
||||||
* dnskey_rrset, a "null" key entry indicating that this DS
|
* dnskey_rrset, a "null" key entry indicating that this DS
|
||||||
* rrset/DNSKEY pair indicate an secure end to the island of trust
|
* rrset/DNSKEY pair indicate an secure end to the island of trust
|
||||||
|
@ -239,7 +252,8 @@ struct key_entry_key* val_verify_new_DNSKEYs_with_ta(struct regional* region,
|
||||||
struct ub_packed_rrset_key* dnskey_rrset,
|
struct ub_packed_rrset_key* dnskey_rrset,
|
||||||
struct ub_packed_rrset_key* ta_ds_rrset,
|
struct ub_packed_rrset_key* ta_ds_rrset,
|
||||||
struct ub_packed_rrset_key* ta_dnskey_rrset, int downprot,
|
struct ub_packed_rrset_key* ta_dnskey_rrset, int downprot,
|
||||||
char** reason, sldns_ede_code *reason_bogus, struct module_qstate* qstate);
|
char** reason, sldns_ede_code *reason_bogus, struct module_qstate* qstate,
|
||||||
|
char* reasonbuf, size_t reasonlen);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine if DS rrset is usable for validator or not.
|
* Determine if DS rrset is usable for validator or not.
|
||||||
|
|
|
@ -72,7 +72,8 @@
|
||||||
/* forward decl for cache response and normal super inform calls of a DS */
|
/* forward decl for cache response and normal super inform calls of a DS */
|
||||||
static void process_ds_response(struct module_qstate* qstate,
|
static void process_ds_response(struct module_qstate* qstate,
|
||||||
struct val_qstate* vq, int id, int rcode, struct dns_msg* msg,
|
struct val_qstate* vq, int id, int rcode, struct dns_msg* msg,
|
||||||
struct query_info* qinfo, struct sock_list* origin, int* suspend);
|
struct query_info* qinfo, struct sock_list* origin, int* suspend,
|
||||||
|
struct module_qstate* sub_qstate);
|
||||||
|
|
||||||
|
|
||||||
/* Updates the suplied EDE (RFC8914) code selectively so we don't lose
|
/* Updates the suplied EDE (RFC8914) code selectively so we don't lose
|
||||||
|
@ -273,11 +274,17 @@ val_new_getmsg(struct module_qstate* qstate, struct val_qstate* vq)
|
||||||
return NULL;
|
return NULL;
|
||||||
if(vq->orig_msg->rep->rrset_count > RR_COUNT_MAX)
|
if(vq->orig_msg->rep->rrset_count > RR_COUNT_MAX)
|
||||||
return NULL; /* protect against integer overflow */
|
return NULL; /* protect against integer overflow */
|
||||||
vq->chase_reply->rrsets = regional_alloc_init(qstate->region,
|
/* Over allocate (+an_numrrsets) in case we need to put extra DNAME
|
||||||
vq->orig_msg->rep->rrsets, sizeof(struct ub_packed_rrset_key*)
|
* records for unsigned CNAME repetitions */
|
||||||
* vq->orig_msg->rep->rrset_count);
|
vq->chase_reply->rrsets = regional_alloc(qstate->region,
|
||||||
|
sizeof(struct ub_packed_rrset_key*) *
|
||||||
|
(vq->orig_msg->rep->rrset_count
|
||||||
|
+ vq->orig_msg->rep->an_numrrsets));
|
||||||
if(!vq->chase_reply->rrsets)
|
if(!vq->chase_reply->rrsets)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
memmove(vq->chase_reply->rrsets, vq->orig_msg->rep->rrsets,
|
||||||
|
sizeof(struct ub_packed_rrset_key*) *
|
||||||
|
vq->orig_msg->rep->rrset_count);
|
||||||
vq->rrset_skip = 0;
|
vq->rrset_skip = 0;
|
||||||
return vq;
|
return vq;
|
||||||
}
|
}
|
||||||
|
@ -640,6 +647,7 @@ validate_msg_signatures(struct module_qstate* qstate, struct val_qstate* vq,
|
||||||
struct ub_packed_rrset_key* s;
|
struct ub_packed_rrset_key* s;
|
||||||
enum sec_status sec;
|
enum sec_status sec;
|
||||||
int num_verifies = 0, verified, have_state = 0;
|
int num_verifies = 0, verified, have_state = 0;
|
||||||
|
char reasonbuf[256];
|
||||||
char* reason = NULL;
|
char* reason = NULL;
|
||||||
sldns_ede_code reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
|
sldns_ede_code reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
|
||||||
*suspend = 0;
|
*suspend = 0;
|
||||||
|
@ -675,7 +683,8 @@ validate_msg_signatures(struct module_qstate* qstate, struct val_qstate* vq,
|
||||||
|
|
||||||
/* Verify the answer rrset */
|
/* Verify the answer rrset */
|
||||||
sec = val_verify_rrset_entry(env, ve, s, key_entry, &reason,
|
sec = val_verify_rrset_entry(env, ve, s, key_entry, &reason,
|
||||||
&reason_bogus, LDNS_SECTION_ANSWER, qstate, &verified);
|
&reason_bogus, LDNS_SECTION_ANSWER, qstate, &verified,
|
||||||
|
reasonbuf, sizeof(reasonbuf));
|
||||||
/* If the (answer) rrset failed to validate, then this
|
/* If the (answer) rrset failed to validate, then this
|
||||||
* message is BAD. */
|
* message is BAD. */
|
||||||
if(sec != sec_status_secure) {
|
if(sec != sec_status_secure) {
|
||||||
|
@ -720,7 +729,7 @@ validate_msg_signatures(struct module_qstate* qstate, struct val_qstate* vq,
|
||||||
s = chase_reply->rrsets[i];
|
s = chase_reply->rrsets[i];
|
||||||
sec = val_verify_rrset_entry(env, ve, s, key_entry, &reason,
|
sec = val_verify_rrset_entry(env, ve, s, key_entry, &reason,
|
||||||
&reason_bogus, LDNS_SECTION_AUTHORITY, qstate,
|
&reason_bogus, LDNS_SECTION_AUTHORITY, qstate,
|
||||||
&verified);
|
&verified, reasonbuf, sizeof(reasonbuf));
|
||||||
/* If anything in the authority section fails to be secure,
|
/* If anything in the authority section fails to be secure,
|
||||||
* we have a bad message. */
|
* we have a bad message. */
|
||||||
if(sec != sec_status_secure) {
|
if(sec != sec_status_secure) {
|
||||||
|
@ -766,7 +775,7 @@ validate_msg_signatures(struct module_qstate* qstate, struct val_qstate* vq,
|
||||||
if(sname && query_dname_compare(sname, key_entry->name)==0)
|
if(sname && query_dname_compare(sname, key_entry->name)==0)
|
||||||
(void)val_verify_rrset_entry(env, ve, s, key_entry,
|
(void)val_verify_rrset_entry(env, ve, s, key_entry,
|
||||||
&reason, NULL, LDNS_SECTION_ADDITIONAL, qstate,
|
&reason, NULL, LDNS_SECTION_ADDITIONAL, qstate,
|
||||||
&verified);
|
&verified, reasonbuf, sizeof(reasonbuf));
|
||||||
/* the additional section can fail to be secure,
|
/* the additional section can fail to be secure,
|
||||||
* it is optional, check signature in case we need
|
* it is optional, check signature in case we need
|
||||||
* to clean the additional section later. */
|
* to clean the additional section later. */
|
||||||
|
@ -1462,9 +1471,9 @@ validate_any_response(struct module_env* env, struct val_env* ve,
|
||||||
* DNAME+CNAME. Possible wildcard proof.
|
* DNAME+CNAME. Possible wildcard proof.
|
||||||
* Difference with positive proof is that this routine refuses
|
* Difference with positive proof is that this routine refuses
|
||||||
* wildcarded DNAMEs.
|
* wildcarded DNAMEs.
|
||||||
*
|
*
|
||||||
* The answer and authority rrsets must already be verified as secure.
|
* The answer and authority rrsets must already be verified as secure.
|
||||||
*
|
*
|
||||||
* @param env: module env for verify.
|
* @param env: module env for verify.
|
||||||
* @param ve: validator env for verify.
|
* @param ve: validator env for verify.
|
||||||
* @param qchase: query that was made.
|
* @param qchase: query that was made.
|
||||||
|
@ -2060,7 +2069,7 @@ processFindKey(struct module_qstate* qstate, struct val_qstate* vq, int id)
|
||||||
verbose(VERB_ALGO, "Process suspended sub DS response");
|
verbose(VERB_ALGO, "Process suspended sub DS response");
|
||||||
msg = vq->sub_ds_msg;
|
msg = vq->sub_ds_msg;
|
||||||
process_ds_response(qstate, vq, id, LDNS_RCODE_NOERROR,
|
process_ds_response(qstate, vq, id, LDNS_RCODE_NOERROR,
|
||||||
msg, &msg->qinfo, NULL, &suspend);
|
msg, &msg->qinfo, NULL, &suspend, NULL);
|
||||||
if(suspend) {
|
if(suspend) {
|
||||||
/* we'll come back here later to continue */
|
/* we'll come back here later to continue */
|
||||||
if(!validate_suspend_setup_timer(qstate, vq,
|
if(!validate_suspend_setup_timer(qstate, vq,
|
||||||
|
@ -2076,7 +2085,7 @@ processFindKey(struct module_qstate* qstate, struct val_qstate* vq, int id)
|
||||||
vq->key_entry->name)) ) {
|
vq->key_entry->name)) ) {
|
||||||
verbose(VERB_ALGO, "Process cached DS response");
|
verbose(VERB_ALGO, "Process cached DS response");
|
||||||
process_ds_response(qstate, vq, id, LDNS_RCODE_NOERROR,
|
process_ds_response(qstate, vq, id, LDNS_RCODE_NOERROR,
|
||||||
msg, &msg->qinfo, NULL, &suspend);
|
msg, &msg->qinfo, NULL, &suspend, NULL);
|
||||||
if(suspend) {
|
if(suspend) {
|
||||||
/* we'll come back here later to continue */
|
/* we'll come back here later to continue */
|
||||||
if(!validate_suspend_setup_timer(qstate, vq,
|
if(!validate_suspend_setup_timer(qstate, vq,
|
||||||
|
@ -2658,6 +2667,8 @@ val_operate(struct module_qstate* qstate, enum module_ev event, int id,
|
||||||
* @param ta: trust anchor.
|
* @param ta: trust anchor.
|
||||||
* @param qstate: qstate that needs key.
|
* @param qstate: qstate that needs key.
|
||||||
* @param id: module id.
|
* @param id: module id.
|
||||||
|
* @param sub_qstate: the sub query state, that is the lookup that fetched
|
||||||
|
* the trust anchor data, it contains error information for the answer.
|
||||||
* @return new key entry or NULL on allocation failure.
|
* @return new key entry or NULL on allocation failure.
|
||||||
* The key entry will either contain a validated DNSKEY rrset, or
|
* The key entry will either contain a validated DNSKEY rrset, or
|
||||||
* represent a Null key (query failed, but validation did not), or a
|
* represent a Null key (query failed, but validation did not), or a
|
||||||
|
@ -2665,31 +2676,38 @@ val_operate(struct module_qstate* qstate, enum module_ev event, int id,
|
||||||
*/
|
*/
|
||||||
static struct key_entry_key*
|
static struct key_entry_key*
|
||||||
primeResponseToKE(struct ub_packed_rrset_key* dnskey_rrset,
|
primeResponseToKE(struct ub_packed_rrset_key* dnskey_rrset,
|
||||||
struct trust_anchor* ta, struct module_qstate* qstate, int id)
|
struct trust_anchor* ta, struct module_qstate* qstate, int id,
|
||||||
|
struct module_qstate* sub_qstate)
|
||||||
{
|
{
|
||||||
struct val_env* ve = (struct val_env*)qstate->env->modinfo[id];
|
struct val_env* ve = (struct val_env*)qstate->env->modinfo[id];
|
||||||
struct key_entry_key* kkey = NULL;
|
struct key_entry_key* kkey = NULL;
|
||||||
enum sec_status sec = sec_status_unchecked;
|
enum sec_status sec = sec_status_unchecked;
|
||||||
|
char reasonbuf[256];
|
||||||
char* reason = NULL;
|
char* reason = NULL;
|
||||||
sldns_ede_code reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
|
sldns_ede_code reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
|
||||||
int downprot = qstate->env->cfg->harden_algo_downgrade;
|
int downprot = qstate->env->cfg->harden_algo_downgrade;
|
||||||
|
|
||||||
if(!dnskey_rrset) {
|
if(!dnskey_rrset) {
|
||||||
|
char* err = errinf_to_str_misc(sub_qstate);
|
||||||
|
char rstr[1024];
|
||||||
log_nametypeclass(VERB_OPS, "failed to prime trust anchor -- "
|
log_nametypeclass(VERB_OPS, "failed to prime trust anchor -- "
|
||||||
"could not fetch DNSKEY rrset",
|
"could not fetch DNSKEY rrset",
|
||||||
ta->name, LDNS_RR_TYPE_DNSKEY, ta->dclass);
|
ta->name, LDNS_RR_TYPE_DNSKEY, ta->dclass);
|
||||||
reason_bogus = LDNS_EDE_DNSKEY_MISSING;
|
reason_bogus = LDNS_EDE_DNSKEY_MISSING;
|
||||||
reason = "no DNSKEY rrset";
|
if(!err) {
|
||||||
|
snprintf(rstr, sizeof(rstr), "no DNSKEY rrset");
|
||||||
|
} else {
|
||||||
|
snprintf(rstr, sizeof(rstr), "no DNSKEY rrset "
|
||||||
|
"[%s]", err);
|
||||||
|
}
|
||||||
if(qstate->env->cfg->harden_dnssec_stripped) {
|
if(qstate->env->cfg->harden_dnssec_stripped) {
|
||||||
errinf_ede(qstate, reason, reason_bogus);
|
errinf_ede(qstate, rstr, reason_bogus);
|
||||||
kkey = key_entry_create_bad(qstate->region, ta->name,
|
kkey = key_entry_create_bad(qstate->region, ta->name,
|
||||||
ta->namelen, ta->dclass, BOGUS_KEY_TTL,
|
ta->namelen, ta->dclass, BOGUS_KEY_TTL,
|
||||||
reason_bogus, reason,
|
reason_bogus, rstr, *qstate->env->now);
|
||||||
*qstate->env->now);
|
|
||||||
} else kkey = key_entry_create_null(qstate->region, ta->name,
|
} else kkey = key_entry_create_null(qstate->region, ta->name,
|
||||||
ta->namelen, ta->dclass, NULL_KEY_TTL,
|
ta->namelen, ta->dclass, NULL_KEY_TTL,
|
||||||
reason_bogus, reason,
|
reason_bogus, rstr, *qstate->env->now);
|
||||||
*qstate->env->now);
|
|
||||||
if(!kkey) {
|
if(!kkey) {
|
||||||
log_err("out of memory: allocate fail prime key");
|
log_err("out of memory: allocate fail prime key");
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -2699,7 +2717,7 @@ primeResponseToKE(struct ub_packed_rrset_key* dnskey_rrset,
|
||||||
/* attempt to verify with trust anchor DS and DNSKEY */
|
/* attempt to verify with trust anchor DS and DNSKEY */
|
||||||
kkey = val_verify_new_DNSKEYs_with_ta(qstate->region, qstate->env, ve,
|
kkey = val_verify_new_DNSKEYs_with_ta(qstate->region, qstate->env, ve,
|
||||||
dnskey_rrset, ta->ds_rrset, ta->dnskey_rrset, downprot,
|
dnskey_rrset, ta->ds_rrset, ta->dnskey_rrset, downprot,
|
||||||
&reason, &reason_bogus, qstate);
|
&reason, &reason_bogus, qstate, reasonbuf, sizeof(reasonbuf));
|
||||||
if(!kkey) {
|
if(!kkey) {
|
||||||
log_err("out of memory: verifying prime TA");
|
log_err("out of memory: verifying prime TA");
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -2754,6 +2772,9 @@ primeResponseToKE(struct ub_packed_rrset_key* dnskey_rrset,
|
||||||
* DS response indicated an end to secure space, is_good if the DS
|
* DS response indicated an end to secure space, is_good if the DS
|
||||||
* validated. It returns ke=NULL if the DS response indicated that the
|
* validated. It returns ke=NULL if the DS response indicated that the
|
||||||
* request wasn't a delegation point.
|
* request wasn't a delegation point.
|
||||||
|
* @param sub_qstate: the sub query state, that is the lookup that fetched
|
||||||
|
* the trust anchor data, it contains error information for the answer.
|
||||||
|
* Can be NULL.
|
||||||
* @return
|
* @return
|
||||||
* 0 on success,
|
* 0 on success,
|
||||||
* 1 on servfail error (malloc failure),
|
* 1 on servfail error (malloc failure),
|
||||||
|
@ -2762,9 +2783,10 @@ primeResponseToKE(struct ub_packed_rrset_key* dnskey_rrset,
|
||||||
static int
|
static int
|
||||||
ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
|
ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
|
||||||
int id, int rcode, struct dns_msg* msg, struct query_info* qinfo,
|
int id, int rcode, struct dns_msg* msg, struct query_info* qinfo,
|
||||||
struct key_entry_key** ke)
|
struct key_entry_key** ke, struct module_qstate* sub_qstate)
|
||||||
{
|
{
|
||||||
struct val_env* ve = (struct val_env*)qstate->env->modinfo[id];
|
struct val_env* ve = (struct val_env*)qstate->env->modinfo[id];
|
||||||
|
char reasonbuf[256];
|
||||||
char* reason = NULL;
|
char* reason = NULL;
|
||||||
sldns_ede_code reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
|
sldns_ede_code reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
|
||||||
enum val_classification subtype;
|
enum val_classification subtype;
|
||||||
|
@ -2777,6 +2799,14 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
|
||||||
verbose(VERB_DETAIL, "DS response was error, thus bogus");
|
verbose(VERB_DETAIL, "DS response was error, thus bogus");
|
||||||
errinf(qstate, rc);
|
errinf(qstate, rc);
|
||||||
reason = "no DS";
|
reason = "no DS";
|
||||||
|
if(sub_qstate) {
|
||||||
|
char* err = errinf_to_str_misc(sub_qstate);
|
||||||
|
if(err) {
|
||||||
|
char buf[1024];
|
||||||
|
snprintf(buf, sizeof(buf), "[%s]", err);
|
||||||
|
errinf(qstate, buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
reason_bogus = LDNS_EDE_NETWORK_ERROR;
|
reason_bogus = LDNS_EDE_NETWORK_ERROR;
|
||||||
errinf_ede(qstate, reason, reason_bogus);
|
errinf_ede(qstate, reason, reason_bogus);
|
||||||
goto return_bogus;
|
goto return_bogus;
|
||||||
|
@ -2799,7 +2829,9 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
|
||||||
/* Verify only returns BOGUS or SECURE. If the rrset is
|
/* Verify only returns BOGUS or SECURE. If the rrset is
|
||||||
* bogus, then we are done. */
|
* bogus, then we are done. */
|
||||||
sec = val_verify_rrset_entry(qstate->env, ve, ds,
|
sec = val_verify_rrset_entry(qstate->env, ve, ds,
|
||||||
vq->key_entry, &reason, &reason_bogus, LDNS_SECTION_ANSWER, qstate, &verified);
|
vq->key_entry, &reason, &reason_bogus,
|
||||||
|
LDNS_SECTION_ANSWER, qstate, &verified, reasonbuf,
|
||||||
|
sizeof(reasonbuf));
|
||||||
if(sec != sec_status_secure) {
|
if(sec != sec_status_secure) {
|
||||||
verbose(VERB_DETAIL, "DS rrset in DS response did "
|
verbose(VERB_DETAIL, "DS rrset in DS response did "
|
||||||
"not verify");
|
"not verify");
|
||||||
|
@ -2849,7 +2881,8 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
|
||||||
/* Try to prove absence of the DS with NSEC */
|
/* Try to prove absence of the DS with NSEC */
|
||||||
sec = val_nsec_prove_nodata_dsreply(
|
sec = val_nsec_prove_nodata_dsreply(
|
||||||
qstate->env, ve, qinfo, msg->rep, vq->key_entry,
|
qstate->env, ve, qinfo, msg->rep, vq->key_entry,
|
||||||
&proof_ttl, &reason, &reason_bogus, qstate);
|
&proof_ttl, &reason, &reason_bogus, qstate,
|
||||||
|
reasonbuf, sizeof(reasonbuf));
|
||||||
switch(sec) {
|
switch(sec) {
|
||||||
case sec_status_secure:
|
case sec_status_secure:
|
||||||
verbose(VERB_DETAIL, "NSEC RRset for the "
|
verbose(VERB_DETAIL, "NSEC RRset for the "
|
||||||
|
@ -2886,7 +2919,8 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
|
||||||
sec = nsec3_prove_nods(qstate->env, ve,
|
sec = nsec3_prove_nods(qstate->env, ve,
|
||||||
msg->rep->rrsets + msg->rep->an_numrrsets,
|
msg->rep->rrsets + msg->rep->an_numrrsets,
|
||||||
msg->rep->ns_numrrsets, qinfo, vq->key_entry, &reason,
|
msg->rep->ns_numrrsets, qinfo, vq->key_entry, &reason,
|
||||||
&reason_bogus, qstate, &vq->nsec3_cache_table);
|
&reason_bogus, qstate, &vq->nsec3_cache_table,
|
||||||
|
reasonbuf, sizeof(reasonbuf));
|
||||||
switch(sec) {
|
switch(sec) {
|
||||||
case sec_status_insecure:
|
case sec_status_insecure:
|
||||||
/* case insecure also continues to unsigned
|
/* case insecure also continues to unsigned
|
||||||
|
@ -2953,7 +2987,8 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
|
||||||
}
|
}
|
||||||
sec = val_verify_rrset_entry(qstate->env, ve, cname,
|
sec = val_verify_rrset_entry(qstate->env, ve, cname,
|
||||||
vq->key_entry, &reason, &reason_bogus,
|
vq->key_entry, &reason, &reason_bogus,
|
||||||
LDNS_SECTION_ANSWER, qstate, &verified);
|
LDNS_SECTION_ANSWER, qstate, &verified, reasonbuf,
|
||||||
|
sizeof(reasonbuf));
|
||||||
if(sec == sec_status_secure) {
|
if(sec == sec_status_secure) {
|
||||||
verbose(VERB_ALGO, "CNAME validated, "
|
verbose(VERB_ALGO, "CNAME validated, "
|
||||||
"proof that DS does not exist");
|
"proof that DS does not exist");
|
||||||
|
@ -3002,11 +3037,15 @@ return_bogus:
|
||||||
* @param origin: the origin of msg.
|
* @param origin: the origin of msg.
|
||||||
* @param suspend: returned true if the task takes too long and needs to
|
* @param suspend: returned true if the task takes too long and needs to
|
||||||
* suspend to continue the effort later.
|
* suspend to continue the effort later.
|
||||||
|
* @param sub_qstate: the sub query state, that is the lookup that fetched
|
||||||
|
* the trust anchor data, it contains error information for the answer.
|
||||||
|
* Can be NULL.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
process_ds_response(struct module_qstate* qstate, struct val_qstate* vq,
|
process_ds_response(struct module_qstate* qstate, struct val_qstate* vq,
|
||||||
int id, int rcode, struct dns_msg* msg, struct query_info* qinfo,
|
int id, int rcode, struct dns_msg* msg, struct query_info* qinfo,
|
||||||
struct sock_list* origin, int* suspend)
|
struct sock_list* origin, int* suspend,
|
||||||
|
struct module_qstate* sub_qstate)
|
||||||
{
|
{
|
||||||
struct val_env* ve = (struct val_env*)qstate->env->modinfo[id];
|
struct val_env* ve = (struct val_env*)qstate->env->modinfo[id];
|
||||||
struct key_entry_key* dske = NULL;
|
struct key_entry_key* dske = NULL;
|
||||||
|
@ -3014,7 +3053,8 @@ process_ds_response(struct module_qstate* qstate, struct val_qstate* vq,
|
||||||
int ret;
|
int ret;
|
||||||
*suspend = 0;
|
*suspend = 0;
|
||||||
vq->empty_DS_name = NULL;
|
vq->empty_DS_name = NULL;
|
||||||
ret = ds_response_to_ke(qstate, vq, id, rcode, msg, qinfo, &dske);
|
ret = ds_response_to_ke(qstate, vq, id, rcode, msg, qinfo, &dske,
|
||||||
|
sub_qstate);
|
||||||
if(ret != 0) {
|
if(ret != 0) {
|
||||||
switch(ret) {
|
switch(ret) {
|
||||||
case 1:
|
case 1:
|
||||||
|
@ -3090,16 +3130,19 @@ process_ds_response(struct module_qstate* qstate, struct val_qstate* vq,
|
||||||
* @param msg: result message (if rcode is OK).
|
* @param msg: result message (if rcode is OK).
|
||||||
* @param qinfo: from the sub query state, query info.
|
* @param qinfo: from the sub query state, query info.
|
||||||
* @param origin: the origin of msg.
|
* @param origin: the origin of msg.
|
||||||
|
* @param sub_qstate: the sub query state, that is the lookup that fetched
|
||||||
|
* the trust anchor data, it contains error information for the answer.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
process_dnskey_response(struct module_qstate* qstate, struct val_qstate* vq,
|
process_dnskey_response(struct module_qstate* qstate, struct val_qstate* vq,
|
||||||
int id, int rcode, struct dns_msg* msg, struct query_info* qinfo,
|
int id, int rcode, struct dns_msg* msg, struct query_info* qinfo,
|
||||||
struct sock_list* origin)
|
struct sock_list* origin, struct module_qstate* sub_qstate)
|
||||||
{
|
{
|
||||||
struct val_env* ve = (struct val_env*)qstate->env->modinfo[id];
|
struct val_env* ve = (struct val_env*)qstate->env->modinfo[id];
|
||||||
struct key_entry_key* old = vq->key_entry;
|
struct key_entry_key* old = vq->key_entry;
|
||||||
struct ub_packed_rrset_key* dnskey = NULL;
|
struct ub_packed_rrset_key* dnskey = NULL;
|
||||||
int downprot;
|
int downprot;
|
||||||
|
char reasonbuf[256];
|
||||||
char* reason = NULL;
|
char* reason = NULL;
|
||||||
sldns_ede_code reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
|
sldns_ede_code reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
|
||||||
|
|
||||||
|
@ -3107,6 +3150,8 @@ process_dnskey_response(struct module_qstate* qstate, struct val_qstate* vq,
|
||||||
dnskey = reply_find_answer_rrset(qinfo, msg->rep);
|
dnskey = reply_find_answer_rrset(qinfo, msg->rep);
|
||||||
|
|
||||||
if(dnskey == NULL) {
|
if(dnskey == NULL) {
|
||||||
|
char* err;
|
||||||
|
char rstr[1024];
|
||||||
/* bad response */
|
/* bad response */
|
||||||
verbose(VERB_DETAIL, "Missing DNSKEY RRset in response to "
|
verbose(VERB_DETAIL, "Missing DNSKEY RRset in response to "
|
||||||
"DNSKEY query.");
|
"DNSKEY query.");
|
||||||
|
@ -3118,17 +3163,22 @@ process_dnskey_response(struct module_qstate* qstate, struct val_qstate* vq,
|
||||||
vq->restart_count++;
|
vq->restart_count++;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
reason = "No DNSKEY record";
|
err = errinf_to_str_misc(sub_qstate);
|
||||||
|
if(!err) {
|
||||||
|
snprintf(rstr, sizeof(rstr), "No DNSKEY record");
|
||||||
|
} else {
|
||||||
|
snprintf(rstr, sizeof(rstr), "No DNSKEY record "
|
||||||
|
"[%s]", err);
|
||||||
|
}
|
||||||
reason_bogus = LDNS_EDE_DNSKEY_MISSING;
|
reason_bogus = LDNS_EDE_DNSKEY_MISSING;
|
||||||
vq->key_entry = key_entry_create_bad(qstate->region,
|
vq->key_entry = key_entry_create_bad(qstate->region,
|
||||||
qinfo->qname, qinfo->qname_len, qinfo->qclass,
|
qinfo->qname, qinfo->qname_len, qinfo->qclass,
|
||||||
BOGUS_KEY_TTL, reason_bogus, reason,
|
BOGUS_KEY_TTL, reason_bogus, rstr, *qstate->env->now);
|
||||||
*qstate->env->now);
|
|
||||||
if(!vq->key_entry) {
|
if(!vq->key_entry) {
|
||||||
log_err("alloc failure in missing dnskey response");
|
log_err("alloc failure in missing dnskey response");
|
||||||
/* key_entry is NULL for failure in Validate */
|
/* key_entry is NULL for failure in Validate */
|
||||||
}
|
}
|
||||||
errinf_ede(qstate, reason, reason_bogus);
|
errinf_ede(qstate, rstr, reason_bogus);
|
||||||
errinf_origin(qstate, origin);
|
errinf_origin(qstate, origin);
|
||||||
errinf_dname(qstate, "for key", qinfo->qname);
|
errinf_dname(qstate, "for key", qinfo->qname);
|
||||||
vq->state = VAL_VALIDATE_STATE;
|
vq->state = VAL_VALIDATE_STATE;
|
||||||
|
@ -3142,7 +3192,8 @@ process_dnskey_response(struct module_qstate* qstate, struct val_qstate* vq,
|
||||||
}
|
}
|
||||||
downprot = qstate->env->cfg->harden_algo_downgrade;
|
downprot = qstate->env->cfg->harden_algo_downgrade;
|
||||||
vq->key_entry = val_verify_new_DNSKEYs(qstate->region, qstate->env,
|
vq->key_entry = val_verify_new_DNSKEYs(qstate->region, qstate->env,
|
||||||
ve, dnskey, vq->ds_rrset, downprot, &reason, &reason_bogus, qstate);
|
ve, dnskey, vq->ds_rrset, downprot, &reason, &reason_bogus,
|
||||||
|
qstate, reasonbuf, sizeof(reasonbuf));
|
||||||
|
|
||||||
if(!vq->key_entry) {
|
if(!vq->key_entry) {
|
||||||
log_err("out of memory in verify new DNSKEYs");
|
log_err("out of memory in verify new DNSKEYs");
|
||||||
|
@ -3192,10 +3243,13 @@ process_dnskey_response(struct module_qstate* qstate, struct val_qstate* vq,
|
||||||
* @param rcode: rcode result value.
|
* @param rcode: rcode result value.
|
||||||
* @param msg: result message (if rcode is OK).
|
* @param msg: result message (if rcode is OK).
|
||||||
* @param origin: the origin of msg.
|
* @param origin: the origin of msg.
|
||||||
|
* @param sub_qstate: the sub query state, that is the lookup that fetched
|
||||||
|
* the trust anchor data, it contains error information for the answer.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
process_prime_response(struct module_qstate* qstate, struct val_qstate* vq,
|
process_prime_response(struct module_qstate* qstate, struct val_qstate* vq,
|
||||||
int id, int rcode, struct dns_msg* msg, struct sock_list* origin)
|
int id, int rcode, struct dns_msg* msg, struct sock_list* origin,
|
||||||
|
struct module_qstate* sub_qstate)
|
||||||
{
|
{
|
||||||
struct val_env* ve = (struct val_env*)qstate->env->modinfo[id];
|
struct val_env* ve = (struct val_env*)qstate->env->modinfo[id];
|
||||||
struct ub_packed_rrset_key* dnskey_rrset = NULL;
|
struct ub_packed_rrset_key* dnskey_rrset = NULL;
|
||||||
|
@ -3227,7 +3281,8 @@ process_prime_response(struct module_qstate* qstate, struct val_qstate* vq,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
vq->key_entry = primeResponseToKE(dnskey_rrset, ta, qstate, id);
|
vq->key_entry = primeResponseToKE(dnskey_rrset, ta, qstate, id,
|
||||||
|
sub_qstate);
|
||||||
lock_basic_unlock(&ta->lock);
|
lock_basic_unlock(&ta->lock);
|
||||||
if(vq->key_entry) {
|
if(vq->key_entry) {
|
||||||
if(key_entry_isbad(vq->key_entry)
|
if(key_entry_isbad(vq->key_entry)
|
||||||
|
@ -3278,14 +3333,14 @@ val_inform_super(struct module_qstate* qstate, int id,
|
||||||
if(vq->wait_prime_ta) {
|
if(vq->wait_prime_ta) {
|
||||||
vq->wait_prime_ta = 0;
|
vq->wait_prime_ta = 0;
|
||||||
process_prime_response(super, vq, id, qstate->return_rcode,
|
process_prime_response(super, vq, id, qstate->return_rcode,
|
||||||
qstate->return_msg, qstate->reply_origin);
|
qstate->return_msg, qstate->reply_origin, qstate);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(qstate->qinfo.qtype == LDNS_RR_TYPE_DS) {
|
if(qstate->qinfo.qtype == LDNS_RR_TYPE_DS) {
|
||||||
int suspend;
|
int suspend;
|
||||||
process_ds_response(super, vq, id, qstate->return_rcode,
|
process_ds_response(super, vq, id, qstate->return_rcode,
|
||||||
qstate->return_msg, &qstate->qinfo,
|
qstate->return_msg, &qstate->qinfo,
|
||||||
qstate->reply_origin, &suspend);
|
qstate->reply_origin, &suspend, qstate);
|
||||||
/* If NSEC3 was needed during validation, NULL the NSEC3 cache;
|
/* If NSEC3 was needed during validation, NULL the NSEC3 cache;
|
||||||
* it will be re-initiated if needed later on.
|
* it will be re-initiated if needed later on.
|
||||||
* Validation (and the cache table) are happening/allocated in
|
* Validation (and the cache table) are happening/allocated in
|
||||||
|
@ -3306,7 +3361,7 @@ val_inform_super(struct module_qstate* qstate, int id,
|
||||||
} else if(qstate->qinfo.qtype == LDNS_RR_TYPE_DNSKEY) {
|
} else if(qstate->qinfo.qtype == LDNS_RR_TYPE_DNSKEY) {
|
||||||
process_dnskey_response(super, vq, id, qstate->return_rcode,
|
process_dnskey_response(super, vq, id, qstate->return_rcode,
|
||||||
qstate->return_msg, &qstate->qinfo,
|
qstate->return_msg, &qstate->qinfo,
|
||||||
qstate->reply_origin);
|
qstate->reply_origin, qstate);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
log_err("internal error in validator: no inform_supers possible");
|
log_err("internal error in validator: no inform_supers possible");
|
||||||
|
@ -3344,8 +3399,8 @@ val_get_mem(struct module_env* env, int id)
|
||||||
*/
|
*/
|
||||||
static struct module_func_block val_block = {
|
static struct module_func_block val_block = {
|
||||||
"validator",
|
"validator",
|
||||||
&val_init, &val_deinit, &val_operate, &val_inform_super, &val_clear,
|
NULL, NULL, &val_init, &val_deinit, &val_operate, &val_inform_super,
|
||||||
&val_get_mem
|
&val_clear, &val_get_mem
|
||||||
};
|
};
|
||||||
|
|
||||||
struct module_func_block*
|
struct module_func_block*
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# $OpenBSD: Makefile,v 1.850 2024/08/31 04:21:45 dlg Exp $
|
# $OpenBSD: Makefile,v 1.851 2024/09/04 11:12:53 jsg Exp $
|
||||||
|
|
||||||
MAN= aac.4 abcrtc.4 abl.4 ac97.4 acphy.4 acrtc.4 \
|
MAN= aac.4 abcrtc.4 abl.4 ac97.4 acphy.4 acrtc.4 \
|
||||||
acpi.4 acpiac.4 acpials.4 acpiasus.4 acpibat.4 \
|
acpi.4 acpiac.4 acpials.4 acpiasus.4 acpibat.4 \
|
||||||
|
@ -72,7 +72,7 @@ MAN= aac.4 abcrtc.4 abl.4 ac97.4 acphy.4 acrtc.4 \
|
||||||
pcmcia.4 pcn.4 pcppi.4 pcscp.4 pcxrtc.4 pcyrtc.4 \
|
pcmcia.4 pcn.4 pcppi.4 pcscp.4 pcxrtc.4 pcyrtc.4 \
|
||||||
pf.4 pflog.4 pflow.4 pfsync.4 \
|
pf.4 pflog.4 pflow.4 pfsync.4 \
|
||||||
pgt.4 piixpm.4 pijuice.4 pinctrl.4 pipex.4 plgpio.4 plrtc.4 pluart.4 \
|
pgt.4 piixpm.4 pijuice.4 pinctrl.4 pipex.4 plgpio.4 plrtc.4 pluart.4 \
|
||||||
pms.4 ppb.4 ppp.4 pppoe.4 pppx.4 psci.4 pty.4 puc.4 pvbus.4 \
|
pms.4 ppb.4 ppp.4 pppoe.4 pppx.4 psci.4 psp.4 pty.4 puc.4 pvbus.4 \
|
||||||
pvclock.4 pwdog.4 pwmbl.4 pwmfan.4 pwmleds.4 pwmreg.4 \
|
pvclock.4 pwdog.4 pwmbl.4 pwmfan.4 pwmleds.4 pwmreg.4 \
|
||||||
qccpu.4 qcdwusb.4 qcgpio.4 qciic.4 qcpdc.4 qcpmic.4 qcpmicgpio.4 \
|
qccpu.4 qcdwusb.4 qcgpio.4 qciic.4 qcpdc.4 qcpmic.4 qcpmicgpio.4 \
|
||||||
qcpon.4 qcpwm.4 qcrng.4 qcrtc.4 qcspmi.4 \
|
qcpon.4 qcpwm.4 qcrng.4 qcrtc.4 qcspmi.4 \
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
.\" $OpenBSD: ccp.4,v 1.5 2024/09/01 19:32:48 bluhm Exp $
|
.\" $OpenBSD: ccp.4,v 1.6 2024/09/04 11:12:53 jsg Exp $
|
||||||
.\"
|
.\"
|
||||||
.\" Copyright (c) 2018 David Gwynne <dlg@openbsd.org>
|
.\" Copyright (c) 2018 David Gwynne <dlg@openbsd.org>
|
||||||
.\"
|
.\"
|
||||||
|
@ -14,7 +14,7 @@
|
||||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
.\"
|
.\"
|
||||||
.Dd $Mdocdate: September 1 2024 $
|
.Dd $Mdocdate: September 4 2024 $
|
||||||
.Dt CCP 4
|
.Dt CCP 4
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
|
@ -33,14 +33,9 @@ The
|
||||||
.Nm
|
.Nm
|
||||||
driver supports feeding output of the random number generator into
|
driver supports feeding output of the random number generator into
|
||||||
the kernel entropy pool.
|
the kernel entropy pool.
|
||||||
.Pp
|
|
||||||
On amd64
|
|
||||||
.Nm
|
|
||||||
provides
|
|
||||||
.Xr ioctl 2
|
|
||||||
access to the platform security processor (PSP).
|
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
.Xr intro 4 ,
|
.Xr intro 4 ,
|
||||||
|
.Xr psp 4 ,
|
||||||
.Xr random 4 ,
|
.Xr random 4 ,
|
||||||
.Xr arc4random 9
|
.Xr arc4random 9
|
||||||
.Sh HISTORY
|
.Sh HISTORY
|
||||||
|
@ -54,5 +49,3 @@ The
|
||||||
.Nm
|
.Nm
|
||||||
driver was written by
|
driver was written by
|
||||||
.An David Gwynne Aq Mt dlg@openbsd.org .
|
.An David Gwynne Aq Mt dlg@openbsd.org .
|
||||||
PSP support was implemented by
|
|
||||||
.An Hans-Joerg Hoexer Aq Mt hshoexer@genua.de .
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
.\" $OpenBSD: ddb.4,v 1.107 2024/02/05 21:33:00 jmc Exp $
|
.\" $OpenBSD: ddb.4,v 1.108 2024/09/05 08:52:27 bluhm Exp $
|
||||||
.\" $NetBSD: ddb.4,v 1.5 1994/11/30 16:22:09 jtc Exp $
|
.\" $NetBSD: ddb.4,v 1.5 1994/11/30 16:22:09 jtc Exp $
|
||||||
.\"
|
.\"
|
||||||
.\" Mach Operating System
|
.\" Mach Operating System
|
||||||
|
@ -25,7 +25,7 @@
|
||||||
.\" any improvements or extensions that they make and grant Carnegie Mellon
|
.\" any improvements or extensions that they make and grant Carnegie Mellon
|
||||||
.\" the rights to redistribute these changes.
|
.\" the rights to redistribute these changes.
|
||||||
.\"
|
.\"
|
||||||
.Dd $Mdocdate: February 5 2024 $
|
.Dd $Mdocdate: September 5 2024 $
|
||||||
.Dt DDB 4
|
.Dt DDB 4
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
|
@ -658,7 +658,11 @@ If the
|
||||||
.Cm /f
|
.Cm /f
|
||||||
modifier is specified, the complete map is printed.
|
modifier is specified, the complete map is printed.
|
||||||
.\" --------------------
|
.\" --------------------
|
||||||
.It Ic show mbuf Ar addr
|
.It Xo
|
||||||
|
.Ic show mbuf
|
||||||
|
.Op Cm /cp
|
||||||
|
.Ar addr
|
||||||
|
.Xc
|
||||||
Prints the
|
Prints the
|
||||||
.Vt struct mbuf
|
.Vt struct mbuf
|
||||||
header at
|
header at
|
||||||
|
@ -668,6 +672,13 @@ Depending on the mbuf flags
|
||||||
and
|
and
|
||||||
.Vt struct m_ext
|
.Vt struct m_ext
|
||||||
are printed as well.
|
are printed as well.
|
||||||
|
If the
|
||||||
|
.Cm /c
|
||||||
|
modifier is specified, print the mbuf chain linked with the m_next
|
||||||
|
pointer.
|
||||||
|
.Cm /p
|
||||||
|
does the same using m_nextpkt.
|
||||||
|
Both can be combined.
|
||||||
.\" --------------------
|
.\" --------------------
|
||||||
.It Xo
|
.It Xo
|
||||||
.Ic show mount
|
.Ic show mount
|
||||||
|
|
54
share/man/man4/psp.4
Normal file
54
share/man/man4/psp.4
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
.\" $OpenBSD: psp.4,v 1.2 2024/09/04 14:24:10 jsg Exp $
|
||||||
|
.\"
|
||||||
|
.\" Copyright (c) 2024 Jonathan Gray <jsg@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.
|
||||||
|
.\"
|
||||||
|
.Dd $Mdocdate: September 4 2024 $
|
||||||
|
.Dt PSP 4
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm psp
|
||||||
|
.Nd AMD Platform Security Processor
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.Cd "psp* at ccp?"
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
The
|
||||||
|
.Nm
|
||||||
|
driver provides an interface to the AMD Platform Security Processor.
|
||||||
|
.Sh FILES
|
||||||
|
.Bl -tag -width /dev/psp
|
||||||
|
.It Pa /dev/psp
|
||||||
|
.El
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr ccp 4 ,
|
||||||
|
.Xr vmd 8
|
||||||
|
.Rs
|
||||||
|
.%T Secure Encrypted Virtualization API
|
||||||
|
.%O Publication #55766
|
||||||
|
.Re
|
||||||
|
.Rs
|
||||||
|
.%T SEV Secure Nested Paging Firmware ABI Specification
|
||||||
|
.%O Publication #56860
|
||||||
|
.Re
|
||||||
|
.Sh HISTORY
|
||||||
|
The
|
||||||
|
.Nm
|
||||||
|
device driver first appeared in
|
||||||
|
.Ox 7.6 .
|
||||||
|
.Sh AUTHORS
|
||||||
|
.An -nosplit
|
||||||
|
The
|
||||||
|
.Nm
|
||||||
|
driver was written by
|
||||||
|
.An Hans-Joerg Hoexer Aq Mt hshoexer@genua.de .
|
|
@ -1,4 +1,4 @@
|
||||||
.\" $OpenBSD: bsd.port.mk.5,v 1.646 2024/08/15 09:46:39 tb Exp $
|
.\" $OpenBSD: bsd.port.mk.5,v 1.647 2024/09/04 09:07:03 sthen Exp $
|
||||||
.\"
|
.\"
|
||||||
.\" Copyright (c) 2000-2008 Marc Espie
|
.\" Copyright (c) 2000-2008 Marc Espie
|
||||||
.\"
|
.\"
|
||||||
|
@ -24,7 +24,7 @@
|
||||||
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
.\"
|
.\"
|
||||||
.Dd $Mdocdate: August 15 2024 $
|
.Dd $Mdocdate: September 4 2024 $
|
||||||
.Dt BSD.PORT.MK 5
|
.Dt BSD.PORT.MK 5
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
|
@ -1731,12 +1731,7 @@ checksummed and extracted (see
|
||||||
.Cm checksum ,
|
.Cm checksum ,
|
||||||
.Cm extract ) .
|
.Cm extract ) .
|
||||||
.Ev DISTFILES
|
.Ev DISTFILES
|
||||||
normally holds a list of files, possibly with
|
normally holds a list of files.
|
||||||
.Sq :0
|
|
||||||
to
|
|
||||||
.Sq :9
|
|
||||||
appended to select a different
|
|
||||||
.Ev SITES .
|
|
||||||
.Pp
|
.Pp
|
||||||
Preferably, adding a suffix to
|
Preferably, adding a suffix to
|
||||||
.Ev DISTFILES ,
|
.Ev DISTFILES ,
|
||||||
|
|
|
@ -1,65 +0,0 @@
|
||||||
.\" $OpenBSD: forward.5,v 1.11 2015/12/28 23:30:59 mmcc Exp $
|
|
||||||
.\"
|
|
||||||
.\" Copyright (c) 2001 Marco S. Hyman
|
|
||||||
.\"
|
|
||||||
.\" Permission to copy all or part of this material with or without
|
|
||||||
.\" modification for any purpose is granted provided that the above
|
|
||||||
.\" copyright notice and this paragraph are duplicated in all copies.
|
|
||||||
.\"
|
|
||||||
.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
|
||||||
.\" IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
|
||||||
.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
.\"
|
|
||||||
.Dd $Mdocdate: December 28 2015 $
|
|
||||||
.Dt FORWARD 5
|
|
||||||
.Os
|
|
||||||
.Sh NAME
|
|
||||||
.Nm forward
|
|
||||||
.Nd email forwarding information file
|
|
||||||
.Sh DESCRIPTION
|
|
||||||
Users may put a file named
|
|
||||||
.Pa .forward
|
|
||||||
in their home directory.
|
|
||||||
If this file exists,
|
|
||||||
.Xr sendmail 8
|
|
||||||
(and sendmail-like mailers) will redirect mail for the user to the list of
|
|
||||||
addresses found in the
|
|
||||||
.Pa .forward
|
|
||||||
file.
|
|
||||||
.Pp
|
|
||||||
A
|
|
||||||
.Pa .forward
|
|
||||||
file contains one or more lines where each line is an email address
|
|
||||||
or the name of a private incoming mailer where incoming mail will be
|
|
||||||
forwarded.
|
|
||||||
Multiple entries may be specified on one line, comma separated.
|
|
||||||
Additionally, a copy of all mail may be retained
|
|
||||||
on the local machine using a
|
|
||||||
.Dq \euser
|
|
||||||
entry.
|
|
||||||
.Pp
|
|
||||||
.Pa .forward
|
|
||||||
files must not be group or world writable.
|
|
||||||
The user's home directory should not be group writable.
|
|
||||||
The
|
|
||||||
.Pa .forward
|
|
||||||
file must be owned by and readable by the indicated user.
|
|
||||||
.Sh FILES
|
|
||||||
.Bl -tag -width $HOME/.forward -compact
|
|
||||||
.It Pa $HOME/.forward
|
|
||||||
email forwarding information
|
|
||||||
.El
|
|
||||||
.Sh EXAMPLES
|
|
||||||
.Bd -literal -offset indent
|
|
||||||
# lines with # in the first column are ignored
|
|
||||||
# empty lines are ignored
|
|
||||||
# #@# with whitespace on both sides may be used to start a comment
|
|
||||||
|
|
||||||
foo@bar.baz.com, \euser #@# is a comment anywhere
|
|
||||||
"| /usr/local/libexec/slocal -user foo"
|
|
||||||
.Ed
|
|
||||||
.Sh SEE ALSO
|
|
||||||
.Xr aliases 5 ,
|
|
||||||
.Xr sendmail 8
|
|
||||||
.Pp
|
|
||||||
.Lk http://www.sendmail.org/
|
|
|
@ -1,10 +1,10 @@
|
||||||
.\" $OpenBSD: MAKEDEV.8,v 1.97 2023/01/14 12:19:11 kettenis Exp $
|
.\" $OpenBSD: MAKEDEV.8,v 1.98 2024/09/04 13:45:25 jsg Exp $
|
||||||
.\"
|
.\"
|
||||||
.\" THIS FILE AUTOMATICALLY GENERATED. DO NOT EDIT.
|
.\" THIS FILE AUTOMATICALLY GENERATED. DO NOT EDIT.
|
||||||
.\" generated from:
|
.\" generated from:
|
||||||
.\"
|
.\"
|
||||||
.\" OpenBSD: etc.amd64/MAKEDEV.md,v 1.82 2023/01/14 12:15:12 kettenis Exp
|
.\" OpenBSD: etc.amd64/MAKEDEV.md,v 1.83 2024/09/03 09:35:46 bluhm Exp
|
||||||
.\" OpenBSD: MAKEDEV.common,v 1.119 2023/01/14 12:15:12 kettenis Exp
|
.\" OpenBSD: MAKEDEV.common,v 1.121 2024/09/03 09:35:46 bluhm Exp
|
||||||
.\" OpenBSD: MAKEDEV.man,v 1.9 2017/06/06 08:11:23 tb Exp
|
.\" OpenBSD: MAKEDEV.man,v 1.9 2017/06/06 08:11:23 tb Exp
|
||||||
.\" OpenBSD: MAKEDEV.mansub,v 1.2 2004/02/20 19:13:01 miod Exp
|
.\" OpenBSD: MAKEDEV.mansub,v 1.2 2004/02/20 19:13:01 miod Exp
|
||||||
.\"
|
.\"
|
||||||
|
@ -23,7 +23,7 @@
|
||||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
.\"
|
.\"
|
||||||
.Dd $Mdocdate: January 14 2023 $
|
.Dd $Mdocdate: September 4 2024 $
|
||||||
.Dt MAKEDEV 8 amd64
|
.Dt MAKEDEV 8 amd64
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
|
@ -299,6 +299,9 @@ paravirtual device tree root, see
|
||||||
.It Ar kstat
|
.It Ar kstat
|
||||||
Kernel Statistics, see
|
Kernel Statistics, see
|
||||||
.Xr kstat 4 .
|
.Xr kstat 4 .
|
||||||
|
.It Ar psp
|
||||||
|
Platform Security Processor, see
|
||||||
|
.Xr psp 4 .
|
||||||
.El
|
.El
|
||||||
.Sh FILES
|
.Sh FILES
|
||||||
.Bl -tag -width /dev -compact
|
.Bl -tag -width /dev -compact
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# $OpenBSD: Makefile,v 1.6 2024/08/23 15:13:58 nicm Exp $
|
# $OpenBSD: Makefile,v 1.7 2024/09/04 14:18:36 deraadt Exp $
|
||||||
# from: @(#)Makefile 5.3 (Berkeley) 10/22/90
|
# from: @(#)Makefile 5.3 (Berkeley) 10/22/90
|
||||||
|
|
||||||
FILES= std stdcrt vt100 vt300
|
FILES= std stdcrt vt100 vt300
|
||||||
|
@ -7,7 +7,7 @@ CLEANFILES+= ${FILES}
|
||||||
all: ${FILES}
|
all: ${FILES}
|
||||||
|
|
||||||
${FILES}:
|
${FILES}:
|
||||||
sh ${.CURDIR}/gentabset.sh ${.CURDIR}/obj
|
sh ${.CURDIR}/gentabset.sh ${.OBJDIR}
|
||||||
|
|
||||||
realinstall: ${FILES}
|
realinstall: ${FILES}
|
||||||
install -c -o ${BINOWN} -g ${BINGRP} -m 444 ${FILES} \
|
install -c -o ${BINOWN} -g ${BINGRP} -m 444 ${FILES} \
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $OpenBSD: conf.c,v 1.81 2024/06/12 12:54:54 bluhm Exp $ */
|
/* $OpenBSD: conf.c,v 1.82 2024/09/04 07:45:08 jsg Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1994, 1995 Charles M. Hannum. All rights reserved.
|
* Copyright (c) 1994, 1995 Charles M. Hannum. All rights reserved.
|
||||||
|
@ -152,8 +152,6 @@ cdev_decl(nvram);
|
||||||
#include "drm.h"
|
#include "drm.h"
|
||||||
#include "viocon.h"
|
#include "viocon.h"
|
||||||
cdev_decl(viocon);
|
cdev_decl(viocon);
|
||||||
#include "ccp.h"
|
|
||||||
cdev_decl(psp);
|
|
||||||
|
|
||||||
#include "wsdisplay.h"
|
#include "wsdisplay.h"
|
||||||
#include "wskbd.h"
|
#include "wskbd.h"
|
||||||
|
@ -292,7 +290,7 @@ struct cdevsw cdevsw[] =
|
||||||
cdev_fido_init(NFIDO,fido), /* 98: FIDO/U2F security keys */
|
cdev_fido_init(NFIDO,fido), /* 98: FIDO/U2F security keys */
|
||||||
cdev_pppx_init(NPPPX,pppac), /* 99: PPP Access Concentrator */
|
cdev_pppx_init(NPPPX,pppac), /* 99: PPP Access Concentrator */
|
||||||
cdev_ujoy_init(NUJOY,ujoy), /* 100: USB joystick/gamecontroller */
|
cdev_ujoy_init(NUJOY,ujoy), /* 100: USB joystick/gamecontroller */
|
||||||
cdev_psp_init(NCCP,psp), /* 101: PSP */
|
cdev_psp_init(NPSP,psp), /* 101: PSP */
|
||||||
};
|
};
|
||||||
int nchrdev = nitems(cdevsw);
|
int nchrdev = nitems(cdevsw);
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $OpenBSD: trap.c,v 1.105 2024/02/21 15:53:07 deraadt Exp $ */
|
/* $OpenBSD: trap.c,v 1.106 2024/09/04 07:54:51 mglocker Exp $ */
|
||||||
/* $NetBSD: trap.c,v 1.2 2003/05/04 23:51:56 fvdl Exp $ */
|
/* $NetBSD: trap.c,v 1.2 2003/05/04 23:51:56 fvdl Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
|
@ -182,7 +182,7 @@ upageflttrap(struct trapframe *frame, uint64_t cr2)
|
||||||
int signal, sicode, error;
|
int signal, sicode, error;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If NX is not enabled, we cant distinguish between PROT_READ
|
* If NX is not enabled, we can't distinguish between PROT_READ
|
||||||
* and PROT_EXEC access, so try both.
|
* and PROT_EXEC access, so try both.
|
||||||
*/
|
*/
|
||||||
error = uvm_fault(&p->p_vmspace->vm_map, va, 0, access_type);
|
error = uvm_fault(&p->p_vmspace->vm_map, va, 0, access_type);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $OpenBSD: vmm_machdep.c,v 1.34 2024/09/03 13:36:19 dv Exp $ */
|
/* $OpenBSD: vmm_machdep.c,v 1.36 2024/09/04 16:12:40 dv Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014 Mike Larkin <mlarkin@openbsd.org>
|
* Copyright (c) 2014 Mike Larkin <mlarkin@openbsd.org>
|
||||||
*
|
*
|
||||||
|
@ -4181,7 +4181,8 @@ vcpu_run_vmx(struct vcpu *vcpu, struct vm_run_params *vrp)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!(exitinfo & VMX_EXIT_INFO_HAVE_REASON)) {
|
if (!(exitinfo & VMX_EXIT_INFO_HAVE_REASON)) {
|
||||||
printf("%s: cant read exit reason\n", __func__);
|
printf("%s: can't read exit reason\n",
|
||||||
|
__func__);
|
||||||
ret = EINVAL;
|
ret = EINVAL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -6281,7 +6282,8 @@ vmm_handle_cpuid(struct vcpu *vcpu)
|
||||||
*rdx = 0;
|
*rdx = 0;
|
||||||
break;
|
break;
|
||||||
case 0x80000000: /* Extended function level */
|
case 0x80000000: /* Extended function level */
|
||||||
*rax = 0x8000001f; /* curcpu()->ci_pnfeatset */
|
/* We don't emulate past 0x8000001f currently. */
|
||||||
|
*rax = min(curcpu()->ci_pnfeatset, 0x8000001f);
|
||||||
*rbx = 0;
|
*rbx = 0;
|
||||||
*rcx = 0;
|
*rcx = 0;
|
||||||
*rdx = 0;
|
*rdx = 0;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# $OpenBSD: GENERIC,v 1.525 2024/08/14 14:40:45 patrick Exp $
|
# $OpenBSD: GENERIC,v 1.526 2024/09/04 07:45:08 jsg Exp $
|
||||||
#
|
#
|
||||||
# For further information on compiling SecBSD kernels, see the config(8)
|
# For further information on compiling SecBSD kernels, see the config(8)
|
||||||
# man page.
|
# man page.
|
||||||
|
@ -123,6 +123,7 @@ ksmn* at pci? # AMD K17 temperature sensor
|
||||||
amas* at pci? disable # AMD memory configuration
|
amas* at pci? disable # AMD memory configuration
|
||||||
pchtemp* at pci? # Intel C610 temperature sensor
|
pchtemp* at pci? # Intel C610 temperature sensor
|
||||||
ccp* at pci? # AMD Cryptographic Co-processor
|
ccp* at pci? # AMD Cryptographic Co-processor
|
||||||
|
psp* at ccp? # AMD Platform Security Processor
|
||||||
|
|
||||||
# National Semiconductor LM7[89] and compatible hardware monitors
|
# National Semiconductor LM7[89] and compatible hardware monitors
|
||||||
lm0 at isa? port 0x290
|
lm0 at isa? port 0x290
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# $OpenBSD: files.amd64,v 1.110 2024/09/03 00:23:05 jsg Exp $
|
# $OpenBSD: files.amd64,v 1.111 2024/09/04 07:45:08 jsg Exp $
|
||||||
|
|
||||||
maxpartitions 16
|
maxpartitions 16
|
||||||
maxusers 2 16 128
|
maxusers 2 16 128
|
||||||
|
@ -65,8 +65,6 @@ file arch/amd64/amd64/powernow-k8.c !small_kernel
|
||||||
file arch/amd64/amd64/est.c !small_kernel
|
file arch/amd64/amd64/est.c !small_kernel
|
||||||
file arch/amd64/amd64/k1x-pstate.c !small_kernel
|
file arch/amd64/amd64/k1x-pstate.c !small_kernel
|
||||||
|
|
||||||
file dev/ic/psp.c ccp
|
|
||||||
|
|
||||||
include "dev/rasops/files.rasops"
|
include "dev/rasops/files.rasops"
|
||||||
include "dev/wsfont/files.wsfont"
|
include "dev/wsfont/files.wsfont"
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $OpenBSD: conf.h,v 1.10 2024/09/01 17:13:46 bluhm Exp $ */
|
/* $OpenBSD: conf.h,v 1.11 2024/09/04 07:45:08 jsg Exp $ */
|
||||||
/* $NetBSD: conf.h,v 1.2 1996/05/05 19:28:34 christos Exp $ */
|
/* $NetBSD: conf.h,v 1.2 1996/05/05 19:28:34 christos Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -55,5 +55,5 @@ cdev_decl(pctr);
|
||||||
#include "vmm.h"
|
#include "vmm.h"
|
||||||
cdev_decl(vmm);
|
cdev_decl(vmm);
|
||||||
|
|
||||||
#include "ccp.h"
|
#include "psp.h"
|
||||||
cdev_decl(psp);
|
cdev_decl(psp);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $OpenBSD: trap.c,v 1.164 2023/12/13 15:57:22 miod Exp $ */
|
/* $OpenBSD: trap.c,v 1.165 2024/09/04 07:54:51 mglocker Exp $ */
|
||||||
/* $NetBSD: trap.c,v 1.95 1996/05/05 06:50:02 mycroft Exp $ */
|
/* $NetBSD: trap.c,v 1.95 1996/05/05 06:50:02 mycroft Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
|
@ -121,7 +121,7 @@ upageflttrap(struct trapframe *frame, uint32_t cr2)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* cpu_pae is true if system has PAE + NX.
|
* cpu_pae is true if system has PAE + NX.
|
||||||
* If NX is not enabled, we cant distinguish between PROT_READ
|
* If NX is not enabled, we can't distinguish between PROT_READ
|
||||||
* and PROT_EXEC access, so try both.
|
* and PROT_EXEC access, so try both.
|
||||||
*/
|
*/
|
||||||
error = uvm_fault(&p->p_vmspace->vm_map, va, 0, access_type);
|
error = uvm_fault(&p->p_vmspace->vm_map, va, 0, access_type);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# $OpenBSD: files,v 1.736 2024/08/31 04:17:14 dlg Exp $
|
# $OpenBSD: files,v 1.737 2024/09/04 07:45:08 jsg Exp $
|
||||||
# $NetBSD: files,v 1.87 1996/05/19 17:17:50 jonathan Exp $
|
# $NetBSD: files,v 1.87 1996/05/19 17:17:50 jonathan Exp $
|
||||||
|
|
||||||
# @(#)files.newconf 7.5 (Berkeley) 5/10/93
|
# @(#)files.newconf 7.5 (Berkeley) 5/10/93
|
||||||
|
@ -470,9 +470,14 @@ device xhci: usbus
|
||||||
file dev/usb/xhci.c xhci needs-flag
|
file dev/usb/xhci.c xhci needs-flag
|
||||||
|
|
||||||
# AMD Cryptographic Co-processor
|
# AMD Cryptographic Co-processor
|
||||||
device ccp
|
device ccp {}
|
||||||
file dev/ic/ccp.c ccp needs-flag
|
file dev/ic/ccp.c ccp needs-flag
|
||||||
|
|
||||||
|
# AMD Platform Security Processor
|
||||||
|
device psp
|
||||||
|
attach psp at ccp
|
||||||
|
file dev/ic/psp.c psp needs-flag
|
||||||
|
|
||||||
# SDHC SD/MMC controller
|
# SDHC SD/MMC controller
|
||||||
define sdhc
|
define sdhc
|
||||||
device sdhc: sdmmcbus
|
device sdhc: sdmmcbus
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $OpenBSD: siphash.h,v 1.5 2015/02/20 11:51:03 tedu Exp $ */
|
/* $OpenBSD: siphash.h,v 1.6 2024/09/04 07:54:52 mglocker Exp $ */
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2013 Andre Oppermann <andre@FreeBSD.org>
|
* Copyright (c) 2013 Andre Oppermann <andre@FreeBSD.org>
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
|
@ -35,7 +35,7 @@
|
||||||
* optimized for speed on short messages returning a 64bit hash/digest value.
|
* optimized for speed on short messages returning a 64bit hash/digest value.
|
||||||
*
|
*
|
||||||
* The number of rounds is defined during the initialization:
|
* The number of rounds is defined during the initialization:
|
||||||
* SipHash24_Init() for the fast and resonable strong version
|
* SipHash24_Init() for the fast and reasonably strong version
|
||||||
* SipHash48_Init() for the strong version (half as fast)
|
* SipHash48_Init() for the strong version (half as fast)
|
||||||
*
|
*
|
||||||
* struct SIPHASH_CTX ctx;
|
* struct SIPHASH_CTX ctx;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $OpenBSD: db_command.c,v 1.101 2024/05/13 01:15:50 jsg Exp $ */
|
/* $OpenBSD: db_command.c,v 1.102 2024/09/05 08:52:27 bluhm Exp $ */
|
||||||
/* $NetBSD: db_command.c,v 1.20 1996/03/30 22:30:05 christos Exp $ */
|
/* $NetBSD: db_command.c,v 1.20 1996/03/30 22:30:05 christos Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -340,7 +340,15 @@ db_malloc_print_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
|
||||||
void
|
void
|
||||||
db_mbuf_print_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
|
db_mbuf_print_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
|
||||||
{
|
{
|
||||||
m_print((void *)addr, db_printf);
|
if ((modif[0] == 'c' && modif[1] == 'p') ||
|
||||||
|
(modif[0] == 'p' && modif[1] == 'c'))
|
||||||
|
m_print_packet((void *)addr, 1, db_printf);
|
||||||
|
else if (modif[0] == 'c')
|
||||||
|
m_print_chain((void *)addr, 0, db_printf);
|
||||||
|
else if (modif[0] == 'p')
|
||||||
|
m_print_packet((void *)addr, 0, db_printf);
|
||||||
|
else
|
||||||
|
m_print((void *)addr, db_printf);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $OpenBSD: db_elf.c,v 1.32 2021/03/12 10:22:46 jsg Exp $ */
|
/* $OpenBSD: db_elf.c,v 1.33 2024/09/04 07:54:52 mglocker Exp $ */
|
||||||
/* $NetBSD: db_elf.c,v 1.13 2000/07/07 21:55:18 jhawk Exp $ */
|
/* $NetBSD: db_elf.c,v 1.13 2000/07/07 21:55:18 jhawk Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
|
@ -280,7 +280,7 @@ db_elf_sym_search(vaddr_t off, db_strategy_t strategy, db_expr_t *diffp)
|
||||||
if (symp->st_name == 0)
|
if (symp->st_name == 0)
|
||||||
continue;
|
continue;
|
||||||
#if 0
|
#if 0
|
||||||
/* This prevents me from seeing anythin in locore.s -- eeh */
|
/* This prevents me from seeing anything in locore.s -- eeh */
|
||||||
if (ELF_SYM_TYPE(symp->st_info) != Elf_estt_object &&
|
if (ELF_SYM_TYPE(symp->st_info) != Elf_estt_object &&
|
||||||
ELF_SYM_TYPE(symp->st_info) != Elf_estt_func)
|
ELF_SYM_TYPE(symp->st_info) != Elf_estt_func)
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $OpenBSD: db_interface.h,v 1.27 2024/02/03 18:51:58 beck Exp $ */
|
/* $OpenBSD: db_interface.h,v 1.28 2024/09/05 08:52:27 bluhm Exp $ */
|
||||||
/* $NetBSD: db_interface.h,v 1.1 1996/02/05 01:57:03 christos Exp $ */
|
/* $NetBSD: db_interface.h,v 1.1 1996/02/05 01:57:03 christos Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -61,6 +61,8 @@ void db_show_all_pools(db_expr_t, int, db_expr_t, char *);
|
||||||
|
|
||||||
/* kern/uipc_mbuf.c */
|
/* kern/uipc_mbuf.c */
|
||||||
void m_print(void *, int (*)(const char *, ...));
|
void m_print(void *, int (*)(const char *, ...));
|
||||||
|
void m_print_chain(void *, int, int (*)(const char *, ...));
|
||||||
|
void m_print_packet(void *, int, int (*)(const char *, ...));
|
||||||
|
|
||||||
/* kern/uipc_socket.c */
|
/* kern/uipc_socket.c */
|
||||||
void so_print(void *, int (*)(const char *, ...));
|
void so_print(void *, int (*)(const char *, ...));
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $OpenBSD: acpi.c,v 1.438 2024/08/18 02:53:08 deraadt Exp $ */
|
/* $OpenBSD: acpi.c,v 1.439 2024/09/04 21:39:18 hastings Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com>
|
* Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com>
|
||||||
* Copyright (c) 2005 Jordan Hargrave <jordan@openbsd.org>
|
* Copyright (c) 2005 Jordan Hargrave <jordan@openbsd.org>
|
||||||
|
@ -3249,7 +3249,6 @@ acpi_foundhid(struct aml_node *node, void *arg)
|
||||||
aaa.aaa_node = node->parent;
|
aaa.aaa_node = node->parent;
|
||||||
aaa.aaa_dev = dev;
|
aaa.aaa_dev = dev;
|
||||||
aaa.aaa_cdev = cdev;
|
aaa.aaa_cdev = cdev;
|
||||||
acpi_parse_crs(sc, &aaa);
|
|
||||||
|
|
||||||
#ifndef SMALL_KERNEL
|
#ifndef SMALL_KERNEL
|
||||||
if (!strcmp(cdev, ACPI_DEV_MOUSE)) {
|
if (!strcmp(cdev, ACPI_DEV_MOUSE)) {
|
||||||
|
@ -3266,6 +3265,8 @@ acpi_foundhid(struct aml_node *node, void *arg)
|
||||||
acpi_matchhids(&aaa, acpi_isa_hids, "none"))
|
acpi_matchhids(&aaa, acpi_isa_hids, "none"))
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
|
acpi_parse_crs(sc, &aaa);
|
||||||
|
|
||||||
aaa.aaa_dmat = acpi_iommu_device_map(node->parent, aaa.aaa_dmat);
|
aaa.aaa_dmat = acpi_iommu_device_map(node->parent, aaa.aaa_dmat);
|
||||||
|
|
||||||
if (!node->parent->attached) {
|
if (!node->parent->attached) {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $OpenBSD: atk0110.c,v 1.19 2022/04/06 18:59:27 naddy Exp $ */
|
/* $OpenBSD: atk0110.c,v 1.20 2024/09/04 07:54:52 mglocker Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2009 Constantine A. Murenin <cnst+openbsd@bugmail.mojo.ru>
|
* Copyright (c) 2009 Constantine A. Murenin <cnst+openbsd@bugmail.mojo.ru>
|
||||||
|
@ -215,7 +215,7 @@ aibs_attach_sif(struct aibs_softc *sc, enum sensor_type st)
|
||||||
aml_freevalue(&res);
|
aml_freevalue(&res);
|
||||||
return;
|
return;
|
||||||
} else if (res.length - 1 > n) {
|
} else if (res.length - 1 > n) {
|
||||||
printf("%s: %s: misformed package: %i/%i",
|
printf("%s: %s: malformed package: %i/%i",
|
||||||
DEVNAME(sc), name, n, res.length - 1);
|
DEVNAME(sc), name, n, res.length - 1);
|
||||||
#ifdef AIBS_MORE_SENSORS
|
#ifdef AIBS_MORE_SENSORS
|
||||||
n = res.length - 1;
|
n = res.length - 1;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $OpenBSD: atascsi.c,v 1.155 2024/05/26 10:01:01 jsg Exp $ */
|
/* $OpenBSD: atascsi.c,v 1.156 2024/09/04 07:54:52 mglocker Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 David Gwynne <dlg@openbsd.org>
|
* Copyright (c) 2007 David Gwynne <dlg@openbsd.org>
|
||||||
|
@ -418,7 +418,7 @@ atascsi_probe(struct scsi_link *link)
|
||||||
xa->pmp_port = ap->ap_pmp_port;
|
xa->pmp_port = ap->ap_pmp_port;
|
||||||
xa->atascsi_private = &ahp->ahp_iopool;
|
xa->atascsi_private = &ahp->ahp_iopool;
|
||||||
ata_exec(as, xa);
|
ata_exec(as, xa);
|
||||||
ata_polled(xa); /* we dont care if it doesnt work */
|
ata_polled(xa); /* we don't care if it doesn't work */
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
error:
|
error:
|
||||||
|
@ -1797,7 +1797,7 @@ ata_polled(struct ata_xfer *xa)
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
if (!ISSET(xa->flags, ATA_F_DONE))
|
if (!ISSET(xa->flags, ATA_F_DONE))
|
||||||
panic("ata_polled: xa isnt complete");
|
panic("ata_polled: xa isn't complete");
|
||||||
|
|
||||||
switch (xa->state) {
|
switch (xa->state) {
|
||||||
case ATA_S_COMPLETE:
|
case ATA_S_COMPLETE:
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $OpenBSD: com_cardbus.c,v 1.45 2024/05/24 06:26:47 jsg Exp $ */
|
/* $OpenBSD: com_cardbus.c,v 1.46 2024/09/04 07:54:52 mglocker Exp $ */
|
||||||
/* $NetBSD: com_cardbus.c,v 1.4 2000/04/17 09:21:59 joda Exp $ */
|
/* $NetBSD: com_cardbus.c,v 1.4 2000/04/17 09:21:59 joda Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -36,7 +36,7 @@
|
||||||
/* This is a driver for CardBus based serial devices. It is less
|
/* This is a driver for CardBus based serial devices. It is less
|
||||||
generic than it could be, but it keeps the complexity down. So far
|
generic than it could be, but it keeps the complexity down. So far
|
||||||
it assumes that anything that reports itself as a `serial' device
|
it assumes that anything that reports itself as a `serial' device
|
||||||
is infact a 16x50 or 8250, which is not necessarily true (in
|
is in fact a 16x50 or 8250, which is not necessarily true (in
|
||||||
practice this shouldn't be a problem). It also does not handle
|
practice this shouldn't be a problem). It also does not handle
|
||||||
devices in the `multiport serial' or `modem' sub-classes, I've
|
devices in the `multiport serial' or `modem' sub-classes, I've
|
||||||
never seen any of these, so I don't know what they might look like.
|
never seen any of these, so I don't know what they might look like.
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $OpenBSD: i2c_scan.c,v 1.146 2019/12/16 19:17:04 claudio Exp $ */
|
/* $OpenBSD: i2c_scan.c,v 1.147 2024/09/04 07:54:52 mglocker Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2005 Theo de Raadt <deraadt@openbsd.org>
|
* Copyright (c) 2005 Theo de Raadt <deraadt@openbsd.org>
|
||||||
|
@ -657,7 +657,7 @@ iic_probe_sensor(struct device *self, u_int8_t addr)
|
||||||
(iicprobe(0x03) & 0x3f) == 0x00 && iicprobe(0x04) <= 0x08)
|
(iicprobe(0x03) & 0x3f) == 0x00 && iicprobe(0x04) <= 0x08)
|
||||||
/*
|
/*
|
||||||
* Genesys Logic doesn't make the datasheet
|
* Genesys Logic doesn't make the datasheet
|
||||||
* for the GL523SM publically available, so
|
* for the GL523SM publicly available, so
|
||||||
* the checks above are nothing more than a
|
* the checks above are nothing more than a
|
||||||
* (conservative) educated guess.
|
* (conservative) educated guess.
|
||||||
*/
|
*/
|
||||||
|
|
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