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 !!
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
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
|
||||
Security fixes:
|
||||
#839 #842 CVE-2024-28757 -- Prevent billion laughs attacks with
|
||||
|
|
|
@ -4,8 +4,14 @@
|
|||
[](https://sourceforge.net/projects/expat/files/)
|
||||
[](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
|
||||
[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
|
||||
- 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
|
||||
[`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:
|
||||
<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,'
|
||||
-i {} +`
|
||||
-i.bak {} +`
|
||||
|
||||
1. Run `automake` to re-write `Makefile.in` files:<br/>
|
||||
`automake`
|
||||
|
|
|
@ -52,7 +52,7 @@
|
|||
<div>
|
||||
<h1>
|
||||
The Expat XML Parser
|
||||
<small>Release 2.6.2</small>
|
||||
<small>Release 2.6.3</small>
|
||||
</h1>
|
||||
</div>
|
||||
<div class="content">
|
||||
|
@ -319,7 +319,7 @@ directions in the next section. Otherwise if you have Microsoft's
|
|||
Developer Studio installed,
|
||||
you can use CMake to generate a <code>.sln</code> file, e.g.
|
||||
<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>
|
||||
|
||||
<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 <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
|
||||
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
|
||||
piece of the document. Frequently, the last piece is empty (i.e.
|
||||
<code>len</code> is zero.)
|
||||
|
@ -1183,11 +1185,17 @@ XML_ParseBuffer(XML_Parser p,
|
|||
int isFinal);
|
||||
</pre>
|
||||
<div class="fcndef">
|
||||
<p>
|
||||
This is just like <code><a href= "#XML_Parse" >XML_Parse</a></code>,
|
||||
except in this case Expat provides the buffer. By obtaining the
|
||||
buffer from Expat with the <code><a href= "#XML_GetBuffer"
|
||||
>XML_GetBuffer</a></code> function, the application can avoid double
|
||||
copying of the input.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Negative values for <code>len</code> are rejected since Expat 2.6.3.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<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_MINOR_VERSION 6
|
||||
#define XML_MICRO_VERSION 2
|
||||
#define XML_MICRO_VERSION 3
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -126,8 +126,7 @@
|
|||
| ((uint64_t)((p)[4]) << 32) | ((uint64_t)((p)[5]) << 40) \
|
||||
| ((uint64_t)((p)[6]) << 48) | ((uint64_t)((p)[7]) << 56))
|
||||
|
||||
#define SIPHASH_INITIALIZER \
|
||||
{ 0, 0, 0, 0, {0}, 0, 0 }
|
||||
#define SIPHASH_INITIALIZER {0, 0, 0, 0, {0}, 0, 0}
|
||||
|
||||
struct siphash {
|
||||
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) 2023 Owain Davies <owaind@bath.edu>
|
||||
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:
|
||||
|
||||
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
|
||||
encodings. The memory buffer 'buf' is a separately-allocated
|
||||
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
|
||||
document buffer. If the element is open across calls 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)
|
||||
return XML_STATUS_ERROR;
|
||||
|
||||
if (len < 0) {
|
||||
parser->m_errorCode = XML_ERROR_INVALID_ARGUMENT;
|
||||
return XML_STATUS_ERROR;
|
||||
}
|
||||
|
||||
switch (parser->m_parsingStatus.parsing) {
|
||||
case XML_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 */
|
||||
next = textStart;
|
||||
|
||||
#ifdef XML_DTD
|
||||
if (entity->is_param) {
|
||||
int tok
|
||||
= XmlPrologTok(parser->m_internalEncoding, textStart, textEnd, &next);
|
||||
result = doProlog(parser, parser->m_internalEncoding, textStart, textEnd,
|
||||
tok, next, &next, XML_FALSE, XML_FALSE,
|
||||
XML_ACCOUNT_ENTITY_EXPANSION);
|
||||
} else
|
||||
#endif /* XML_DTD */
|
||||
} else {
|
||||
result = doContent(parser, parser->m_tagLevel, parser->m_internalEncoding,
|
||||
textStart, textEnd, &next, XML_FALSE,
|
||||
XML_ACCOUNT_ENTITY_EXPANSION);
|
||||
}
|
||||
|
||||
if (result == XML_ERROR_NONE) {
|
||||
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 */
|
||||
next = textStart;
|
||||
|
||||
#ifdef XML_DTD
|
||||
if (entity->is_param) {
|
||||
int tok
|
||||
= XmlPrologTok(parser->m_internalEncoding, textStart, textEnd, &next);
|
||||
result = doProlog(parser, parser->m_internalEncoding, textStart, textEnd,
|
||||
tok, next, &next, XML_FALSE, XML_TRUE,
|
||||
XML_ACCOUNT_ENTITY_EXPANSION);
|
||||
} else
|
||||
#endif /* XML_DTD */
|
||||
} else {
|
||||
result = doContent(parser, openEntity->startTagLevel,
|
||||
parser->m_internalEncoding, textStart, textEnd, &next,
|
||||
XML_FALSE, XML_ACCOUNT_ENTITY_EXPANSION);
|
||||
}
|
||||
|
||||
if (result != XML_ERROR_NONE)
|
||||
return result;
|
||||
|
@ -5932,7 +5937,6 @@ internalEntityProcessor(XML_Parser parser, const char *s, const char *end,
|
|||
return XML_ERROR_NONE;
|
||||
}
|
||||
|
||||
#ifdef XML_DTD
|
||||
if (entity->is_param) {
|
||||
int tok;
|
||||
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,
|
||||
(XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE,
|
||||
XML_ACCOUNT_DIRECT);
|
||||
} else
|
||||
#endif /* XML_DTD */
|
||||
{
|
||||
} else {
|
||||
parser->m_processor = contentProcessor;
|
||||
/* see externalEntityContentProcessor vs contentProcessor */
|
||||
result = doContent(parser, parser->m_parentParser ? 1 : 0,
|
||||
|
@ -7016,6 +7018,16 @@ dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd,
|
|||
if (! newE)
|
||||
return 0;
|
||||
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
|
||||
= ms->malloc_fcn(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
|
||||
if (! newE->defaultAtts) {
|
||||
|
@ -7558,6 +7570,15 @@ nextScaffoldPart(XML_Parser parser) {
|
|||
int next;
|
||||
|
||||
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));
|
||||
if (! dtd->scaffIndex)
|
||||
return -1;
|
||||
|
|
|
@ -2804,6 +2804,61 @@ START_TEST(test_empty_parse) {
|
|||
}
|
||||
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 */
|
||||
static enum XML_Status
|
||||
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_ext_entity_ref_parameter);
|
||||
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_2);
|
||||
#if XML_CONTEXT_BYTES > 0
|
||||
|
|
|
@ -208,7 +208,7 @@ START_TEST(test_misc_version) {
|
|||
if (! versions_equal(&read_version, &parsed_version))
|
||||
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");
|
||||
}
|
||||
END_TEST
|
||||
|
|
|
@ -960,7 +960,7 @@ int ZEXPORT inflate(z_streamp strm, int flush) {
|
|||
while (state->have < 19)
|
||||
state->lens[order[state->have++]] = 0;
|
||||
state->next = state->codes;
|
||||
state->lencode = (const code FAR *)(state->next);
|
||||
state->lencode = state->distcode = (const code FAR *)(state->next);
|
||||
state->lenbits = 7;
|
||||
ret = inflate_table(CODES, state->lens, 19, &(state->next),
|
||||
&(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
|
||||
.if exists(/usr/local/bin/eopenssl11)
|
||||
SUBDIR += openssl11
|
||||
.else
|
||||
.END:
|
||||
@echo 'Run "pkg_add openssl--%1.1" to run tests against OpenSSL 1.1'
|
||||
@echo SKIPPED
|
||||
.if exists(/usr/local/bin/eopenssl32)
|
||||
SUBDIR += openssl
|
||||
.endif
|
||||
|
||||
.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>
|
||||
|
@ -773,7 +773,7 @@ handle_query(struct pending_query *pq)
|
|||
}
|
||||
|
||||
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) {
|
||||
error_answer(pq, rcode);
|
||||
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,
|
||||
NULL, 0, pq->region);
|
||||
NULL, 0, pq->region, NULL);
|
||||
if (rcode != LDNS_RCODE_NOERROR) {
|
||||
error_answer(pq, rcode);
|
||||
goto send_answer;
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
/* config.h. Generated from config.h.in by configure. */
|
||||
/* 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 */
|
||||
#define ATTR_NORETURN __attribute__((__noreturn__))
|
||||
|
||||
|
@ -58,6 +61,9 @@
|
|||
/* Define to 1 if you have the <arpa/inet.h> header file. */
|
||||
#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 */
|
||||
#define HAVE_ATTR_FORMAT 1
|
||||
|
||||
|
@ -407,6 +413,9 @@
|
|||
/* Define to 1 if you have the <net/if.h> header file. */
|
||||
#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. */
|
||||
/* #undef HAVE_NGHTTP2 */
|
||||
|
||||
|
@ -567,6 +576,9 @@
|
|||
function. */
|
||||
/* #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 HAVE_SSL_GET0_ALPN_SELECTED 1
|
||||
|
||||
|
@ -779,7 +791,7 @@
|
|||
#define PACKAGE_NAME "unbound"
|
||||
|
||||
/* 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 PACKAGE_TARNAME "unbound"
|
||||
|
@ -788,7 +800,7 @@
|
|||
#define PACKAGE_URL ""
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#define PACKAGE_VERSION "1.20.0"
|
||||
#define PACKAGE_VERSION "1.21.0"
|
||||
|
||||
/* default pidfile location */
|
||||
#define PIDFILE ""
|
||||
|
@ -811,7 +823,7 @@
|
|||
#define ROOT_CERT_FILE "/var/unbound/etc/icannbundle.pem"
|
||||
|
||||
/* 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 */
|
||||
#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 free(p) unbound_stat_free_log(p, __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_calloc(size_t nmemb, size_t size);
|
||||
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);
|
||||
void *unbound_stat_realloc_log(void *ptr, size_t size, const char* file,
|
||||
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)
|
||||
# include "util/alloc.h"
|
||||
#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->started_no_cache_store = qstate->no_cache_store;
|
||||
qstate->no_cache_store = 1;
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case module_event_pass:
|
||||
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 = {
|
||||
"dns64",
|
||||
&dns64_init, &dns64_deinit, &dns64_operate, &dns64_inform_super,
|
||||
&dns64_clear, &dns64_get_mem
|
||||
NULL, NULL, &dns64_init, &dns64_deinit, &dns64_operate,
|
||||
&dns64_inform_super, &dns64_clear, &dns64_get_mem
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
|
||||
#ifdef USE_DNSTAP
|
||||
|
||||
#include "util/locks.h"
|
||||
struct config_file;
|
||||
struct sldns_buffer;
|
||||
struct dt_msg_queue;
|
||||
|
@ -75,6 +76,13 @@ struct dt_env {
|
|||
unsigned log_forwarder_query_messages : 1;
|
||||
/** whether to log Message/FORWARDER_RESPONSE */
|
||||
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;
|
||||
}
|
||||
|
||||
/** 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"
|
||||
* 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;
|
||||
size_t snamelen = qinfo->qname_len;
|
||||
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 &&
|
||||
FLAGS_GET_RCODE(msg->flags) != LDNS_RCODE_NXDOMAIN)
|
||||
|
@ -401,6 +443,16 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
|
|||
prev = NULL;
|
||||
rrset = msg->rrset_first;
|
||||
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 &&
|
||||
pkt_strict_sub(pkt, sname, rrset->dname)) {
|
||||
/* check if next rrset is correct CNAME. else,
|
||||
|
@ -420,6 +472,7 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
|
|||
"too long");
|
||||
return 0;
|
||||
}
|
||||
cname_length++;
|
||||
if(nx && nx->type == LDNS_RR_TYPE_CNAME &&
|
||||
dname_pkt_compare(pkt, sname, nx->dname) == 0) {
|
||||
/* check next cname */
|
||||
|
@ -460,6 +513,7 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
|
|||
if(rrset->type == LDNS_RR_TYPE_CNAME) {
|
||||
struct rrset_parse* nx = rrset->rrset_all_next;
|
||||
uint8_t* oldsname = sname;
|
||||
cname_length++;
|
||||
/* see if the next one is a DNAME, if so, swap them */
|
||||
if(nx && nx->section == LDNS_SECTION_ANSWER &&
|
||||
nx->type == LDNS_RR_TYPE_DNAME &&
|
||||
|
@ -507,6 +561,10 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
|
|||
LDNS_SECTION_ANSWER &&
|
||||
dname_pkt_compare(pkt, oldsname,
|
||||
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;
|
||||
rrset = rrset->rrset_all_next;
|
||||
}
|
||||
|
@ -522,6 +580,11 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
|
|||
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. */
|
||||
/* only for RRsets that match the query name, other ones
|
||||
* 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);
|
||||
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
|
||||
* 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,
|
||||
&rtt, now)) {
|
||||
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":"",
|
||||
dnsseclame?" DNSSEC_LAME":"",
|
||||
a->dnsseclame?" ADDR_DNSSEC_LAME":"",
|
||||
reclame?" REC_LAME":"",
|
||||
a->lame?" ADDR_LAME":"");
|
||||
if(lame)
|
||||
|
|
|
@ -760,6 +760,14 @@ target_count_increase_nx(struct iter_qstate* iq, int 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 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)");
|
||||
if(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,
|
||||
|
@ -1560,6 +1568,11 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
|
|||
errinf(qstate, "malloc failure for forward zone");
|
||||
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
if(!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 the server accepts RD=0 queries and forwards
|
||||
* 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) {
|
||||
log_err("internal error: no hints dp");
|
||||
errinf(qstate, "no hints for this class");
|
||||
return error_response(qstate, id,
|
||||
return error_response_cache(qstate, id,
|
||||
LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
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.
|
||||
* @param num: returns the number of queries generated and processed,
|
||||
* 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
|
||||
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;
|
||||
if(toget == 0) {
|
||||
*num = 0;
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* now that we are sure that a target query is going to be made,
|
||||
* check the limits. */
|
||||
if(iq->depth == ie->max_dependency_depth)
|
||||
return 0;
|
||||
return 1;
|
||||
if(iq->depth > 0 && iq->target_count &&
|
||||
iq->target_count[TARGET_COUNT_QUERIES] > MAX_TARGET_COUNT) {
|
||||
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 "
|
||||
"number of glue fetches %d", s,
|
||||
iq->target_count[TARGET_COUNT_QUERIES]);
|
||||
return 0;
|
||||
return 2;
|
||||
}
|
||||
if(iq->dp_target_count > MAX_DP_TARGET_COUNT) {
|
||||
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 "
|
||||
"number of glue fetches %d to a single delegation point",
|
||||
s, iq->dp_target_count);
|
||||
return 0;
|
||||
return 2;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
if(query_count > 0)
|
||||
qstate->ext_state[id] = module_wait_subquery;
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
query_count++;
|
||||
/* 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
|
||||
* socket while this state waits for that spawned
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
/* Send the A request. */
|
||||
if((ie->supports_ipv4 || ie->use_nat64) &&
|
||||
((ns->lame && !ns->done_pside4) ||
|
||||
|
@ -2070,13 +2092,18 @@ query_for_targets(struct module_qstate* qstate, struct iter_qstate* iq,
|
|||
*num = query_count;
|
||||
if(query_count > 0)
|
||||
qstate->ext_state[id] = module_wait_subquery;
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
query_count++;
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
|
||||
/* mark this target as in progress. */
|
||||
ns->resolved = 1;
|
||||
|
@ -2089,7 +2116,7 @@ query_for_targets(struct module_qstate* qstate, struct iter_qstate* iq,
|
|||
if(query_count > 0)
|
||||
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 */
|
||||
if(delegpt_count_missing_targets(iq->dp, NULL) > 0) {
|
||||
int qs = 0;
|
||||
int qs = 0, ret;
|
||||
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_dname(qstate, "at zone", iq->dp->name);
|
||||
if(ret == 1)
|
||||
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
iq->num_target_queries += 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 "
|
||||
"number of referrrals with %d", iq->referral_count);
|
||||
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) {
|
||||
verbose(VERB_QUERY, "request has exceeded the maximum "
|
||||
"number of sends with %d", iq->sent_count);
|
||||
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. */
|
||||
|
@ -2450,7 +2479,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
|||
"already present for the delegation point, no "
|
||||
"fallback possible");
|
||||
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 "
|
||||
"nxdomain nameserver lookups");
|
||||
|
@ -2493,7 +2522,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
|||
"lookups (%d) with %d", MAX_TARGET_NX_FALLBACK,
|
||||
iq->target_count[TARGET_COUNT_NX]);
|
||||
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) {
|
||||
|
@ -2707,7 +2736,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
|||
verbose(VERB_ALGO, "auth zone lookup failed, no fallback,"
|
||||
" servfail");
|
||||
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) {
|
||||
/* 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(iq->caps_fallback) {
|
||||
int extra = 0;
|
||||
int extra = 0, ret;
|
||||
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");
|
||||
if(ret == 1)
|
||||
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
iq->num_target_queries += 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
|
||||
* query, or failing. */
|
||||
if(delegpt_count_missing_targets(iq->dp, NULL) > 0) {
|
||||
int qs = 0;
|
||||
int qs = 0, ret;
|
||||
verbose(VERB_ALGO, "querying for next "
|
||||
"missing target");
|
||||
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_dname(qstate, "at zone", iq->dp->name);
|
||||
if(ret == 1)
|
||||
return error_response(qstate, id,
|
||||
LDNS_RCODE_SERVFAIL);
|
||||
return error_response_cache(qstate, id,
|
||||
LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
if(qs == 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. */
|
||||
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;
|
||||
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
|
||||
* pass. */
|
||||
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;
|
||||
errinf_dname(qstate, "exceeded ratelimit for zone",
|
||||
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",
|
||||
&real_addr, real_addrlen);
|
||||
|
@ -3247,7 +3303,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
|||
iter_scrub_nxdomain(iq->response);
|
||||
return final_state(iq);
|
||||
}
|
||||
return error_response(qstate, id,
|
||||
return error_response_cache(qstate, id,
|
||||
LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
/* Best effort qname-minimisation.
|
||||
|
@ -3582,7 +3638,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
|||
" fallback possible, servfail");
|
||||
errinf_dname(qstate, "response is bad, no fallback, "
|
||||
"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, "
|
||||
"fallback enabled");
|
||||
|
@ -3990,7 +4046,7 @@ processCollectClass(struct module_qstate* qstate, int id)
|
|||
if(iq->num_current_queries == 0) {
|
||||
verbose(VERB_ALGO, "No root hints or fwds, giving up "
|
||||
"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 */
|
||||
}
|
||||
|
@ -4357,7 +4413,7 @@ process_response(struct module_qstate* qstate, struct iter_qstate* iq,
|
|||
"getting different replies, failed");
|
||||
outbound_list_remove(&iq->outlist, outbound);
|
||||
errinf(qstate, "0x20 failed, then got different replies in fallback");
|
||||
(void)error_response(qstate, id,
|
||||
(void)error_response_cache(qstate, id,
|
||||
LDNS_RCODE_SERVFAIL);
|
||||
return;
|
||||
}
|
||||
|
@ -4457,8 +4513,8 @@ iter_get_mem(struct module_env* env, int id)
|
|||
*/
|
||||
static struct module_func_block iter_block = {
|
||||
"iterator",
|
||||
&iter_init, &iter_deinit, &iter_operate, &iter_inform_super,
|
||||
&iter_clear, &iter_get_mem
|
||||
NULL, NULL, &iter_init, &iter_deinit, &iter_operate,
|
||||
&iter_inform_super, &iter_clear, &iter_get_mem
|
||||
};
|
||||
|
||||
struct module_func_block*
|
||||
|
|
|
@ -55,6 +55,9 @@ struct rbtree_type;
|
|||
|
||||
/** max number of targets spawned for a query and its subqueries */
|
||||
#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 */
|
||||
#define MAX_DP_TARGET_COUNT 16
|
||||
/** max number of nxdomains allowed for target lookups for a query and
|
||||
|
@ -248,6 +251,9 @@ enum target_count_variables {
|
|||
TARGET_COUNT_QUERIES,
|
||||
/** Number of nxdomain responses encountered. */
|
||||
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 */
|
||||
TARGET_COUNT_MAX,
|
||||
|
|
|
@ -75,7 +75,9 @@ context_finalize(struct ub_ctx* ctx)
|
|||
ctx->pipe_pid = getpid();
|
||||
cfg_apply_local_port_policy(cfg, 65536);
|
||||
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;
|
||||
listen_setup_locks();
|
||||
log_edns_known_options(VERB_ALGO, ctx->env);
|
||||
|
|
|
@ -188,7 +188,9 @@ ub_ctx_create(void)
|
|||
int e = errno;
|
||||
ub_randfree(ctx->seed_rnd);
|
||||
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();
|
||||
edns_known_options_delete(ctx->env);
|
||||
edns_strings_delete(ctx->env->edns_strings);
|
||||
|
@ -202,7 +204,9 @@ ub_ctx_create(void)
|
|||
tube_delete(ctx->qq_pipe);
|
||||
ub_randfree(ctx->seed_rnd);
|
||||
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();
|
||||
edns_known_options_delete(ctx->env);
|
||||
edns_strings_delete(ctx->env->edns_strings);
|
||||
|
@ -360,7 +364,9 @@ ub_ctx_delete(struct ub_ctx* ctx)
|
|||
}
|
||||
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;
|
||||
while(a) {
|
||||
na = a->super;
|
||||
|
@ -981,7 +987,8 @@ ub_ctx_set_fwd(struct ub_ctx* ctx, const char* addr)
|
|||
if(!addr) {
|
||||
/* disable fwd mode - the root stub should be first. */
|
||||
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;
|
||||
ctx->env->cfg->forwards = s->next;
|
||||
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 */
|
||||
lock_basic_lock(&ctx->cfglock);
|
||||
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));
|
||||
if(!s) {
|
||||
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;
|
||||
} else {
|
||||
log_assert(ctx->env->cfg->forwards);
|
||||
log_assert(ctx->env->cfg->forwards->name);
|
||||
s = ctx->env->cfg->forwards;
|
||||
}
|
||||
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",
|
||||
(int)context_serial_getcmd(msg, len));
|
||||
/* and fall through to quit */
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case UB_LIBCMD_QUIT:
|
||||
free(msg);
|
||||
|
|
|
@ -1259,8 +1259,8 @@ respip_get_mem(struct module_env* env, int id)
|
|||
*/
|
||||
static struct module_func_block respip_block = {
|
||||
"respip",
|
||||
&respip_init, &respip_deinit, &respip_operate, &respip_inform_super,
|
||||
&respip_clear, &respip_get_mem
|
||||
NULL, NULL, &respip_init, &respip_deinit, &respip_operate,
|
||||
&respip_inform_super, &respip_clear, &respip_get_mem
|
||||
};
|
||||
|
||||
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,
|
||||
struct module_env* env, struct module_stack* mods,
|
||||
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;
|
||||
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);
|
||||
}
|
||||
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) {
|
||||
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,
|
||||
struct module_env* env, struct module_stack* mods,
|
||||
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;
|
||||
if(!apex) {
|
||||
|
@ -7863,7 +7865,7 @@ static int zonemd_check_dnssec_absence(struct auth_zone* z,
|
|||
struct ub_packed_rrset_key pk;
|
||||
/* dnssec verify the NSEC */
|
||||
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";
|
||||
return 0;
|
||||
}
|
||||
|
@ -7906,7 +7908,7 @@ static int zonemd_check_dnssec_absence(struct auth_zone* z,
|
|||
}
|
||||
/* dnssec verify the NSEC3 */
|
||||
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";
|
||||
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 ub_packed_rrset_key* dnskey, struct auth_data* apex,
|
||||
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;
|
||||
if(!apex) {
|
||||
|
@ -7941,12 +7943,12 @@ static int zonemd_check_dnssec_soazonemd(struct auth_zone* z,
|
|||
return 0;
|
||||
}
|
||||
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";
|
||||
return 0;
|
||||
}
|
||||
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";
|
||||
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,
|
||||
int is_insecure, char** result, uint8_t* sigalg)
|
||||
{
|
||||
char reasonbuf[256];
|
||||
char* reason = NULL, *why_bogus = NULL;
|
||||
struct auth_data* apex = 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) {
|
||||
/* fetch, DNSSEC verify, and check NSEC/NSEC3 */
|
||||
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);
|
||||
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) {
|
||||
/* check DNSSEC verify of SOA and ZONEMD */
|
||||
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);
|
||||
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 keystorage: where to store the ub_packed_rrset_key that is created
|
||||
* 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
|
||||
* 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,
|
||||
struct module_stack* mods, struct trust_anchor* anchor,
|
||||
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_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,
|
||||
"zonemd: verify DNSKEY RRset with trust anchor");
|
||||
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);
|
||||
if(sec == sec_status_secure) {
|
||||
/* success */
|
||||
|
@ -8173,7 +8182,8 @@ static struct ub_packed_rrset_key*
|
|||
auth_zone_verify_zonemd_key_with_ds(struct auth_zone* z,
|
||||
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* keystorage, uint8_t* sigalg)
|
||||
struct ub_packed_rrset_key* keystorage, uint8_t* sigalg,
|
||||
char* reasonbuf, size_t reasonlen)
|
||||
{
|
||||
struct auth_data* apex;
|
||||
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);
|
||||
auth_zone_log(z->name, VERB_QUERY, "zonemd: verify zone DNSKEY with DS");
|
||||
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);
|
||||
if(sec == sec_status_secure) {
|
||||
/* 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 module_env* env;
|
||||
char reasonbuf[256];
|
||||
char* reason = NULL, *ds_bogus = NULL, *typestr="DNSKEY";
|
||||
struct ub_packed_rrset_key* dnskey = NULL, *ds = NULL;
|
||||
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) {
|
||||
dnskey = auth_zone_verify_zonemd_key_with_ds(z, env,
|
||||
&env->mesh->mods, ds, &is_insecure, &ds_bogus,
|
||||
&keystorage, downprot?sigalg:NULL);
|
||||
&keystorage, downprot?sigalg:NULL, reasonbuf,
|
||||
sizeof(reasonbuf));
|
||||
if(!dnskey && !is_insecure && !reason)
|
||||
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) {
|
||||
auth_zone_zonemd_fail(z, env, reason, ds_bogus, NULL);
|
||||
lock_rw_unlock(&z->lock);
|
||||
regional_free_all(env->scratch);
|
||||
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,
|
||||
struct module_stack* mods, char** result, int offline, int only_online)
|
||||
{
|
||||
char reasonbuf[256];
|
||||
char* reason = NULL, *why_bogus = NULL;
|
||||
struct trust_anchor* anchor = 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 */
|
||||
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);
|
||||
if(!dnskey && !reason && !is_insecure) {
|
||||
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) {
|
||||
auth_zone_zonemd_fail(z, env, reason, why_bogus, result);
|
||||
regional_free_all(env->scratch);
|
||||
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;
|
||||
lock_rw_rdlock(&rep->ref[i].key->entry.lock);
|
||||
/* 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;
|
||||
else ck = packed_rrset_copy_region(
|
||||
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 */
|
||||
/* the line below is matched by gcc regex and silences
|
||||
* the fallthrough warning */
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case 1: /* ref updated, item inserted */
|
||||
rep->rrsets[i] = rep->ref[i].key;
|
||||
}
|
||||
/* if ref was updated make sure the message ttl is updated to
|
||||
* the minimum of the current rrsets. */
|
||||
ttl = ((struct packed_rrset_data*)rep->rrsets[i]->entry.data)->ttl;
|
||||
/* ref was updated; make sure the message ttl is
|
||||
* updated to the minimum of the current rrsets. */
|
||||
lock_rw_rdlock(&rep->ref[i].key->entry.lock);
|
||||
/* 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;
|
||||
}
|
||||
lock_rw_unlock(&rep->ref[i].key->entry.lock);
|
||||
}
|
||||
}
|
||||
if(min_ttl < rep->ttl) {
|
||||
rep->ttl = min_ttl;
|
||||
|
@ -337,6 +346,13 @@ find_add_addrs(struct module_env* env, uint16_t qclass,
|
|||
* not use dns64 translation */
|
||||
neg = msg_cache_lookup(env, ns->name, ns->namelen,
|
||||
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) {
|
||||
delegpt_add_neg_msg(dp, neg);
|
||||
lock_rw_unlock(&neg->entry.lock);
|
||||
|
@ -396,6 +412,13 @@ cache_fill_missing(struct module_env* env, uint16_t qclass,
|
|||
* not use dns64 translation */
|
||||
neg = msg_cache_lookup(env, ns->name, ns->namelen,
|
||||
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) {
|
||||
delegpt_add_neg_msg(dp, neg);
|
||||
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) */
|
||||
#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 */
|
||||
int infra_dp_ratelimit = 0;
|
||||
|
||||
|
@ -347,6 +357,7 @@ infra_create(struct config_file* cfg)
|
|||
return NULL;
|
||||
}
|
||||
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_HOST_STARTSIZE, cfg->ip_ratelimit_size, &ip_rate_sizefunc,
|
||||
&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_dp_ratelimit = cfg->ratelimit;
|
||||
infra_ip_ratelimit = cfg->ip_ratelimit;
|
||||
infra_ip_ratelimit_cookie = cfg->ip_ratelimit_cookie;
|
||||
maxmem = cfg->infra_cache_numhosts * (sizeof(struct infra_key)+
|
||||
sizeof(struct infra_data)+INFRA_BYTES_NAME);
|
||||
/* 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)
|
||||
/* do not disqualify this server altogether, it is better
|
||||
* than nothing */
|
||||
data->rtt.rto = RTT_MAX_TIMEOUT-1000;
|
||||
data->rtt.rto = STILL_USEFUL_TIMEOUT;
|
||||
lock_rw_unlock(&e->lock);
|
||||
}
|
||||
|
||||
|
@ -796,7 +808,7 @@ infra_get_lame_rtt(struct infra_cache* infra,
|
|||
&& infra->infra_keep_probing) {
|
||||
/* single probe, keep probing */
|
||||
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
|
||||
&& rtt_notimeout(&host->rtt)*4 <= host->rtt.rto) {
|
||||
/* 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(host->timeout_A >= TIMEOUT_COUNT_MAX)
|
||||
*rtt = USEFUL_SERVER_TOP_TIMEOUT;
|
||||
else *rtt = USEFUL_SERVER_TOP_TIMEOUT-1000;
|
||||
else *rtt = STILL_USEFUL_TIMEOUT;
|
||||
} else if(qtype == LDNS_RR_TYPE_AAAA) {
|
||||
if(host->timeout_AAAA >= TIMEOUT_COUNT_MAX)
|
||||
*rtt = USEFUL_SERVER_TOP_TIMEOUT;
|
||||
else *rtt = USEFUL_SERVER_TOP_TIMEOUT-1000;
|
||||
else *rtt = STILL_USEFUL_TIMEOUT;
|
||||
} else {
|
||||
if(host->timeout_other >= TIMEOUT_COUNT_MAX)
|
||||
*rtt = USEFUL_SERVER_TOP_TIMEOUT;
|
||||
else *rtt = USEFUL_SERVER_TOP_TIMEOUT-1000;
|
||||
else *rtt = STILL_USEFUL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
/* expired entry */
|
||||
if(timenow > host->ttl) {
|
||||
|
||||
/* 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) {
|
||||
lock_rw_unlock(&e->lock);
|
||||
*rtt = USEFUL_SERVER_TOP_TIMEOUT-1000;
|
||||
*rtt = STILL_USEFUL_TIMEOUT;
|
||||
*lame = 0;
|
||||
*dnsseclame = 0;
|
||||
*reclame = 0;
|
||||
|
|
|
@ -234,7 +234,7 @@ struct infra_cache* infra_adjust(struct infra_cache* infra,
|
|||
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 addr: host address.
|
||||
* @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 use_systemd, int dscp)
|
||||
{
|
||||
int s;
|
||||
int s = -1;
|
||||
char* err;
|
||||
#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;
|
||||
|
|
|
@ -242,7 +242,7 @@ lz_enter_zone_dname(struct local_zones* zones, uint8_t* nm, size_t len,
|
|||
}
|
||||
|
||||
/** enter a new zone */
|
||||
static struct local_zone*
|
||||
struct local_zone*
|
||||
lz_enter_zone(struct local_zones* zones, const char* name, const char* type,
|
||||
uint16_t dclass)
|
||||
{
|
||||
|
@ -983,36 +983,39 @@ lz_enter_overrides(struct local_zones* zones, struct config_file* cfg)
|
|||
return 1;
|
||||
}
|
||||
|
||||
/** setup parent pointers, so that a lookup can be done for closest match */
|
||||
static void
|
||||
init_parents(struct local_zones* zones)
|
||||
/* return closest parent in the tree, NULL if none */
|
||||
static struct local_zone* find_closest_parent(struct local_zone* curr,
|
||||
struct local_zone* prev)
|
||||
{
|
||||
struct local_zone* node, *prev = NULL, *p;
|
||||
struct local_zone* p;
|
||||
int m;
|
||||
lock_rw_wrlock(&zones->lock);
|
||||
RBTREE_FOR(node, struct local_zone*, &zones->ztree) {
|
||||
lock_rw_wrlock(&node->lock);
|
||||
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 */
|
||||
if(!prev || prev->dclass != curr->dclass) return NULL;
|
||||
(void)dname_lab_cmp(prev->name, prev->namelabs, curr->name,
|
||||
curr->namelabs, &m); /* we know prev is smaller */
|
||||
/* sort order like: . com. bla.com. zwb.com. net. */
|
||||
/* 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 */
|
||||
if(p->namelabs <= m) {
|
||||
/* ==: since prev matched m, this is closest*/
|
||||
/* <: prev matches more, but is not a parent,
|
||||
* this one is a (grand)parent */
|
||||
node->parent = p;
|
||||
break;
|
||||
return p;
|
||||
}
|
||||
}
|
||||
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)
|
||||
addr_tree_init_parents(node->override_tree);
|
||||
lock_rw_unlock(&node->lock);
|
||||
|
@ -1036,7 +1039,7 @@ lz_setup_implicit(struct local_zones* zones, struct config_file* cfg)
|
|||
int nmlabs = 0;
|
||||
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) {
|
||||
uint8_t* rr_name;
|
||||
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 */
|
||||
init_parents(zones);
|
||||
lz_init_parents(zones);
|
||||
/* insert local zone tags */
|
||||
if(!lz_enter_zone_tags(zones, cfg)) {
|
||||
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,
|
||||
enum localzone_type tp)
|
||||
{
|
||||
int exact;
|
||||
/* create */
|
||||
struct local_zone *prev;
|
||||
struct local_zone* z = local_zone_create(name, len, labs, tp, dclass);
|
||||
if(!z) {
|
||||
free(name);
|
||||
|
@ -2037,10 +2042,12 @@ struct local_zone* local_zones_add_zone(struct local_zones* zones,
|
|||
lock_rw_wrlock(&z->lock);
|
||||
|
||||
/* 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 */
|
||||
if(!rbtree_insert(&zones->ztree, &z->node)) {
|
||||
if(exact||!rbtree_insert(&zones->ztree, &z->node)) {
|
||||
/* duplicate entry! */
|
||||
lock_rw_unlock(&z->lock);
|
||||
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*
|
||||
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 */
|
||||
|
|
|
@ -413,6 +413,7 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
|
|||
int timeout = mesh->env->cfg->serve_expired?
|
||||
mesh->env->cfg->serve_expired_client_timeout:0;
|
||||
struct sldns_buffer* r_buffer = rep->c->buffer;
|
||||
uint16_t mesh_flags = qflags&(BIT_RD|BIT_CD);
|
||||
if(rep->c->tcp_req_info) {
|
||||
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;
|
||||
}
|
||||
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? */
|
||||
if(!s || s->list_select == mesh_no_list) {
|
||||
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;
|
||||
#endif
|
||||
s = mesh_state_create(mesh->env, qinfo, cinfo,
|
||||
qflags&(BIT_RD|BIT_CD), 0, 0);
|
||||
mesh_flags, 0, 0);
|
||||
if(!s) {
|
||||
log_err("mesh_state_create: out of memory; SERVFAIL");
|
||||
if(!inplace_cb_reply_servfail_call(mesh->env, qinfo, NULL, NULL,
|
||||
|
@ -565,6 +566,8 @@ servfail_mem:
|
|||
edns->opt_list_inplace_cb_out = NULL;
|
||||
error_encode(r_buffer, LDNS_RCODE_SERVFAIL,
|
||||
qinfo, qid, qflags, edns);
|
||||
if(rep->c->use_h2)
|
||||
http2_stream_remove_mesh_state(rep->c->h2_stream);
|
||||
comm_point_send_reply(rep);
|
||||
if(added)
|
||||
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_noreply = 0;
|
||||
int added = 0;
|
||||
uint16_t mesh_flags = qflags&(BIT_RD|BIT_CD);
|
||||
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 */
|
||||
|
||||
|
@ -594,7 +598,7 @@ mesh_new_callback(struct mesh_area* mesh, struct query_info* qinfo,
|
|||
struct rbnode_type* n;
|
||||
#endif
|
||||
s = mesh_state_create(mesh->env, qinfo, NULL,
|
||||
qflags&(BIT_RD|BIT_CD), 0, 0);
|
||||
mesh_flags, 0, 0);
|
||||
if(!s) {
|
||||
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,
|
||||
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,
|
||||
qflags&(BIT_RD|BIT_CD), 0, 0);
|
||||
mesh_flags, 0, 0);
|
||||
#ifdef UNBOUND_DEBUG
|
||||
struct rbnode_type* n;
|
||||
#endif
|
||||
|
@ -694,8 +702,7 @@ static void mesh_schedule_prefetch(struct mesh_area* mesh,
|
|||
return;
|
||||
}
|
||||
|
||||
s = mesh_state_create(mesh->env, qinfo, NULL,
|
||||
qflags&(BIT_RD|BIT_CD), 0, 0);
|
||||
s = mesh_state_create(mesh->env, qinfo, NULL, mesh_flags, 0, 0);
|
||||
if(!s) {
|
||||
log_err("prefetch mesh_state_create: out of memory");
|
||||
return;
|
||||
|
@ -756,14 +763,17 @@ static void mesh_schedule_prefetch_subnet(struct mesh_area* mesh,
|
|||
#ifdef UNBOUND_DEBUG
|
||||
struct rbnode_type* n;
|
||||
#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)) {
|
||||
verbose(VERB_ALGO, "Too many queries. dropped prefetch.");
|
||||
mesh->stats_dropped ++;
|
||||
return;
|
||||
}
|
||||
|
||||
s = mesh_state_create(mesh->env, qinfo, NULL,
|
||||
qflags&(BIT_RD|BIT_CD), 0, 0);
|
||||
s = mesh_state_create(mesh->env, qinfo, NULL, mesh_flags, 0, 0);
|
||||
if(!s) {
|
||||
log_err("prefetch_subnet mesh_state_create: out of memory");
|
||||
return;
|
||||
|
@ -966,6 +976,8 @@ mesh_state_cleanup(struct mesh_state* mstate)
|
|||
for(; rep; rep=rep->next) {
|
||||
infra_wait_limit_dec(mesh->env->infra_cache,
|
||||
&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);
|
||||
log_assert(mesh->num_reply_addrs > 0);
|
||||
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,
|
||||
&r->query_reply, mstate->s.env->cfg);
|
||||
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);
|
||||
mstate->reply_list = reply_list;
|
||||
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,
|
||||
&r->query_reply, mstate->s.env->cfg);
|
||||
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);
|
||||
mstate->reply_list = reply_list;
|
||||
} 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);
|
||||
r_buffer = NULL;
|
||||
}
|
||||
/* mesh_send_reply removed mesh state from
|
||||
* http2_stream. */
|
||||
prev = r;
|
||||
prev_buffer = r_buffer;
|
||||
}
|
||||
|
@ -1720,6 +1739,7 @@ int mesh_state_add_reply(struct mesh_state* s, struct edns_data* edns,
|
|||
return 0;
|
||||
if(rep->c->use_h2)
|
||||
r->h2_stream = rep->c->h2_stream;
|
||||
else r->h2_stream = NULL;
|
||||
|
||||
/* Data related to local alias stored in 'qinfo' (if any) is ephemeral
|
||||
* 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,
|
||||
&r->query_reply, mstate->s.env->cfg);
|
||||
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);
|
||||
mstate->reply_list = reply_list;
|
||||
mstate->s.env->mesh->stats_dropped++;
|
||||
|
@ -2276,6 +2298,7 @@ mesh_serve_expired_callback(void* arg)
|
|||
r, r_buffer, prev, prev_buffer);
|
||||
if(r->query_reply.c->tcp_req_info)
|
||||
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,
|
||||
&r->query_reply, mstate->s.env->cfg);
|
||||
prev = r;
|
||||
|
|
|
@ -95,6 +95,16 @@ modstack_init(struct module_stack* stack)
|
|||
stack->mod = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
modstack_free(struct module_stack* stack)
|
||||
{
|
||||
if(!stack)
|
||||
return;
|
||||
stack->num = 0;
|
||||
free(stack->mod);
|
||||
stack->mod = NULL;
|
||||
}
|
||||
|
||||
int
|
||||
modstack_config(struct module_stack* stack, const char* module_conf)
|
||||
{
|
||||
|
@ -223,17 +233,58 @@ module_func_block* module_factory(const char** str)
|
|||
}
|
||||
|
||||
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)
|
||||
{
|
||||
int i;
|
||||
if(stack->num != 0)
|
||||
modstack_desetup(stack, env);
|
||||
fatal_exit("unexpected already initialised modules");
|
||||
/* fixed setup of the modules */
|
||||
if(!modstack_config(stack, module_conf)) {
|
||||
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 */
|
||||
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++) {
|
||||
verbose(VERB_OPS, "init module %d: %s",
|
||||
i, stack->mod[i]->name);
|
||||
|
@ -248,16 +299,25 @@ modstack_setup(struct module_stack* stack, const char* module_conf,
|
|||
}
|
||||
|
||||
void
|
||||
modstack_desetup(struct module_stack* stack, struct module_env* env)
|
||||
modstack_call_deinit(struct module_stack* stack, struct module_env* env)
|
||||
{
|
||||
int i;
|
||||
for(i=0; i<stack->num; i++) {
|
||||
fptr_ok(fptr_whitelist_mod_deinit(stack->mod[i]->deinit));
|
||||
(*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
|
||||
|
|
|
@ -60,6 +60,23 @@ struct module_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
|
||||
* @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);
|
||||
|
||||
/**
|
||||
* Setup modules. Assigns ids and calls module_init.
|
||||
* @param stack: if not empty beforehand, it will be desetup()ed.
|
||||
* It is then modstack_configged().
|
||||
* @param module_conf: string what modules to insert.
|
||||
* Init modules. Calls module_init().
|
||||
* @param stack: It is modstack_setupped().
|
||||
* @param module_conf: module ordering to check against the ordering in stack.
|
||||
* fails on changed ordering.
|
||||
* @param env: module environment which is inited by the modules.
|
||||
* environment should have a superalloc, cfg,
|
||||
* env.need_to_validate is set by the modules.
|
||||
* @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);
|
||||
|
||||
/**
|
||||
* Desetup the modules, deinit, delete.
|
||||
* Deinit the modules.
|
||||
* @param stack: made empty.
|
||||
* @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.
|
||||
|
|
|
@ -2051,7 +2051,8 @@ select_id(struct outside_network* outnet, struct pending* pend,
|
|||
}
|
||||
|
||||
/** 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) {
|
||||
case ECONNREFUSED:
|
||||
|
@ -2075,6 +2076,15 @@ static int udp_connect_needs_log(int err)
|
|||
if(verbosity >= VERB_ALGO)
|
||||
return 1;
|
||||
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:
|
||||
break;
|
||||
}
|
||||
|
@ -2141,7 +2151,8 @@ select_ifport(struct outside_network* outnet, struct pending* pend,
|
|||
/* connect() to the destination */
|
||||
if(connect(fd, (struct sockaddr*)&pend->addr,
|
||||
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",
|
||||
strerror(errno), &pend->addr,
|
||||
pend->addrlen);
|
||||
|
@ -3455,7 +3466,10 @@ outnet_serviced_query(struct outside_network* outnet,
|
|||
timenow = *env->now;
|
||||
if(!infra_ratelimit_inc(env->infra_cache, zone,
|
||||
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? */
|
||||
if(env->cfg->ratelimit_factor == 0 ||
|
||||
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_DROP_ACTION: return local_zone_always_deny;
|
||||
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_TCP_ONLY_ACTION: return local_zone_truncate;
|
||||
case RPZ_INVALID_ACTION: /* fallthrough */
|
||||
case RPZ_INVALID_ACTION:
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
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_DROP_ACTION: return respip_always_deny;
|
||||
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_TCP_ONLY_ACTION: return respip_truncate;
|
||||
case RPZ_INVALID_ACTION: /* fallthrough */
|
||||
case RPZ_INVALID_ACTION:
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
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_redirect: return RPZ_LOCAL_DATA_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;
|
||||
}
|
||||
}
|
||||
|
@ -291,7 +301,9 @@ respip_action_to_rpz_action(enum respip_action a)
|
|||
case respip_always_transparent: return RPZ_PASSTHRU_ACTION;
|
||||
case respip_redirect: return RPZ_LOCAL_DATA_ACTION;
|
||||
case respip_truncate: return RPZ_TCP_ONLY_ACTION;
|
||||
case respip_invalid: /* fallthrough */
|
||||
case respip_invalid:
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
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; }
|
||||
|
||||
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);
|
||||
|
||||
lock_rw_rdlock(&az->rpz_lock);
|
||||
|
||||
/* precedence of RPZ works, loosely, like this:
|
||||
* CNAMEs in order of the CNAME chain. rpzs in the order they are
|
||||
* 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);
|
||||
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 */
|
||||
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);
|
||||
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,
|
||||
is->qchase.qname_len, is->qchase.qclass, 0, 0, 0);
|
||||
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[out] data the data found
|
||||
* \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
|
||||
*/
|
||||
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[out] data the data found
|
||||
* \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
|
||||
debugging purposes)
|
||||
* \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[out] data the data found
|
||||
* \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
|
||||
*/
|
||||
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....... ........ */
|
||||
c = src[3] >> 7 ;
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case 3: dst[4] = b32[(src[2] & 0x0f) << 1 | c];
|
||||
|
||||
/* ........ .......3 3333.... ........ ........ */
|
||||
c = src[2] >> 4 ;
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
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...... ........ ........ ........ */
|
||||
c = src[1] >> 6 ;
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
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) {
|
||||
case 1: dst[2] = '=';
|
||||
dst[3] = '=';
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case 2: dst[4] = '=';
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case 3: dst[5] = '=';
|
||||
dst[6] = '=';
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
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.. ........ */
|
||||
/* ........ ........ ....4444 4....... ........ */
|
||||
dst[3] = buf[4] << 7 | buf[5] << 2 | buf[6] >> 3;
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
|
||||
case 5: /* ........ ........ ....4444 4....... ........ */
|
||||
/* ........ .......3 3333.... ........ ........ */
|
||||
dst[2] = buf[3] << 4 | buf[4] >> 1;
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
|
||||
case 4: /* ........ .......3 3333.... ........ ........ */
|
||||
/* ........ ..22222. ........ ........ ........ */
|
||||
/* .....111 11...... ........ ........ ........ */
|
||||
dst[1] = buf[1] << 6 | buf[2] << 1 | buf[3] >> 4;
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
|
||||
case 2: /* .....111 11...... ........ ........ ........ */
|
||||
|
|
|
@ -470,6 +470,11 @@ enum sldns_enum_ede_code
|
|||
LDNS_EDE_NO_REACHABLE_AUTHORITY = 22,
|
||||
LDNS_EDE_NETWORK_ERROR = 23,
|
||||
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;
|
||||
|
||||
|
|
|
@ -228,6 +228,11 @@ static sldns_lookup_table sldns_edns_ede_codes_data[] = {
|
|||
{ LDNS_EDE_NO_REACHABLE_AUTHORITY, "No Reachable Authority" },
|
||||
{ LDNS_EDE_NETWORK_ERROR, "Network Error" },
|
||||
{ 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}
|
||||
};
|
||||
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);
|
||||
break;
|
||||
case SVCB_KEY_DOHPATH:
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
default:
|
||||
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));
|
||||
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 */
|
||||
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);
|
||||
}
|
||||
|
||||
/** 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 */
|
||||
#ifdef UNBOUND_ALLOC_LITE
|
||||
#undef malloc
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include "config.h"
|
||||
#include <ctype.h>
|
||||
#include <stdarg.h>
|
||||
#include <errno.h>
|
||||
#ifdef HAVE_TIME_H
|
||||
#include <time.h>
|
||||
#endif
|
||||
|
@ -386,6 +387,7 @@ config_create(void)
|
|||
memset(cfg->cookie_secret, 0, sizeof(cfg->cookie_secret));
|
||||
cfg->cookie_secret_len = 16;
|
||||
init_cookie_secret(cfg->cookie_secret, cfg->cookie_secret_len);
|
||||
cfg->cookie_secret_file = NULL;
|
||||
#ifdef USE_CACHEDB
|
||||
if(!(cfg->cachedb_backend = strdup("testframe"))) 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_STR("dnstap-identity:", dnstap_identity)
|
||||
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:",
|
||||
dnstap_log_resolver_query_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); }
|
||||
else S_YNO("ipsecmod-strict:", ipsecmod_strict)
|
||||
#endif
|
||||
else S_YNO("answer-cookie:", do_answer_cookie)
|
||||
else S_STR("cookie-secret-file:", cookie_secret_file)
|
||||
#ifdef USE_CACHEDB
|
||||
else S_YNO("cachedb-no-store:", cachedb_no_store)
|
||||
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_STR(opt, "dnstap-identity", dnstap_identity)
|
||||
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",
|
||||
dnstap_log_resolver_query_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_YNO(opt, "ipsecmod-strict", ipsecmod_strict)
|
||||
#endif
|
||||
else O_YNO(opt, "answer-cookie", do_answer_cookie)
|
||||
else O_STR(opt, "cookie-secret-file", cookie_secret_file)
|
||||
#ifdef USE_CACHEDB
|
||||
else O_STR(opt, "backend", cachedb_backend)
|
||||
else O_STR(opt, "secret-seed", cachedb_secret)
|
||||
|
@ -1718,6 +1726,7 @@ config_delete(struct config_file* cfg)
|
|||
free(cfg->ipsecmod_hook);
|
||||
config_delstrlist(cfg->ipsecmod_whitelist);
|
||||
#endif
|
||||
free(cfg->cookie_secret_file);
|
||||
#ifdef USE_CACHEDB
|
||||
free(cfg->cachedb_backend);
|
||||
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
|
||||
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");
|
||||
#endif
|
||||
if(!mid) {
|
||||
int port = atoi(str);
|
||||
int port = extract_port_from_str(str, num);
|
||||
if(port < 0) {
|
||||
log_err("port number is negative: %d", port);
|
||||
return 0;
|
||||
}
|
||||
if(port == 0 && strcmp(str, "0") != 0) {
|
||||
log_err("cannot parse port number '%s'", str);
|
||||
log_err("Failed to parse the port number");
|
||||
return 0;
|
||||
}
|
||||
if(port < num)
|
||||
avail[port] = (allow?port:0);
|
||||
} else {
|
||||
int i, low, high = atoi(mid+1);
|
||||
char buf[16];
|
||||
int i, low;
|
||||
int high = extract_port_from_str(mid+1, num);
|
||||
if(high < 0) {
|
||||
log_err("port number is negative: %d", high);
|
||||
return 0;
|
||||
}
|
||||
if(high == 0 && strcmp(mid+1, "0") != 0) {
|
||||
log_err("cannot parse port number '%s'", mid+1);
|
||||
log_err("Failed to parse the port number");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( (int)(mid-str)+1 >= (int)sizeof(buf) ) {
|
||||
log_err("cannot parse port number '%s'", str);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(mid > str)
|
||||
memcpy(buf, str, (size_t)(mid-str));
|
||||
buf[mid-str] = 0;
|
||||
low = atoi(buf);
|
||||
low = extract_port_from_str(buf, num);
|
||||
if(low < 0) {
|
||||
log_err("port number is negative: %d", low);
|
||||
log_err("Failed to parse the port number");
|
||||
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;
|
||||
}
|
||||
if(high > num) {
|
||||
/* Stop very high values from taking a long time. */
|
||||
high = num;
|
||||
}
|
||||
|
||||
for(i=low; i<=high; i++) {
|
||||
if(i < num)
|
||||
avail[i] = (allow?i:0);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -592,6 +592,8 @@ struct config_file {
|
|||
char* dnstap_identity;
|
||||
/** dnstap "version", package version is used if "". */
|
||||
char* dnstap_version;
|
||||
/** dnstap sample rate */
|
||||
int dnstap_sample_rate;
|
||||
|
||||
/** true to log dnstap RESOLVER_QUERY message events */
|
||||
int dnstap_log_resolver_query_messages;
|
||||
|
@ -748,6 +750,8 @@ struct config_file {
|
|||
uint8_t cookie_secret[40];
|
||||
/** cookie secret length */
|
||||
size_t cookie_secret_len;
|
||||
/** path to cookie secret store */
|
||||
char* cookie_secret_file;
|
||||
|
||||
/* ipset module */
|
||||
#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) }
|
||||
dnstap-log-forwarder-response-messages{COLON} {
|
||||
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) }
|
||||
ip-ratelimit{COLON} { YDVAR(1, VAR_IP_RATELIMIT) }
|
||||
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) }
|
||||
answer-cookie{COLON} { YDVAR(1, VAR_ANSWER_COOKIE ) }
|
||||
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-opcode{COLON} { YDVAR(1, VAR_EDNS_CLIENT_STRING_OPCODE) }
|
||||
nsid{COLON} { YDVAR(1, VAR_NSID ) }
|
||||
|
|
|
@ -187,171 +187,173 @@
|
|||
#define VAR_DNSTAP_LOG_CLIENT_RESPONSE_MESSAGES 443
|
||||
#define VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES 444
|
||||
#define VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES 445
|
||||
#define VAR_RESPONSE_IP_TAG 446
|
||||
#define VAR_RESPONSE_IP 447
|
||||
#define VAR_RESPONSE_IP_DATA 448
|
||||
#define VAR_HARDEN_ALGO_DOWNGRADE 449
|
||||
#define VAR_IP_TRANSPARENT 450
|
||||
#define VAR_IP_DSCP 451
|
||||
#define VAR_DISABLE_DNSSEC_LAME_CHECK 452
|
||||
#define VAR_IP_RATELIMIT 453
|
||||
#define VAR_IP_RATELIMIT_SLABS 454
|
||||
#define VAR_IP_RATELIMIT_SIZE 455
|
||||
#define VAR_RATELIMIT 456
|
||||
#define VAR_RATELIMIT_SLABS 457
|
||||
#define VAR_RATELIMIT_SIZE 458
|
||||
#define VAR_OUTBOUND_MSG_RETRY 459
|
||||
#define VAR_MAX_SENT_COUNT 460
|
||||
#define VAR_MAX_QUERY_RESTARTS 461
|
||||
#define VAR_RATELIMIT_FOR_DOMAIN 462
|
||||
#define VAR_RATELIMIT_BELOW_DOMAIN 463
|
||||
#define VAR_IP_RATELIMIT_FACTOR 464
|
||||
#define VAR_RATELIMIT_FACTOR 465
|
||||
#define VAR_IP_RATELIMIT_BACKOFF 466
|
||||
#define VAR_RATELIMIT_BACKOFF 467
|
||||
#define VAR_SEND_CLIENT_SUBNET 468
|
||||
#define VAR_CLIENT_SUBNET_ZONE 469
|
||||
#define VAR_CLIENT_SUBNET_ALWAYS_FORWARD 470
|
||||
#define VAR_CLIENT_SUBNET_OPCODE 471
|
||||
#define VAR_MAX_CLIENT_SUBNET_IPV4 472
|
||||
#define VAR_MAX_CLIENT_SUBNET_IPV6 473
|
||||
#define VAR_MIN_CLIENT_SUBNET_IPV4 474
|
||||
#define VAR_MIN_CLIENT_SUBNET_IPV6 475
|
||||
#define VAR_MAX_ECS_TREE_SIZE_IPV4 476
|
||||
#define VAR_MAX_ECS_TREE_SIZE_IPV6 477
|
||||
#define VAR_CAPS_WHITELIST 478
|
||||
#define VAR_CACHE_MAX_NEGATIVE_TTL 479
|
||||
#define VAR_PERMIT_SMALL_HOLDDOWN 480
|
||||
#define VAR_CACHE_MIN_NEGATIVE_TTL 481
|
||||
#define VAR_QNAME_MINIMISATION 482
|
||||
#define VAR_QNAME_MINIMISATION_STRICT 483
|
||||
#define VAR_IP_FREEBIND 484
|
||||
#define VAR_DEFINE_TAG 485
|
||||
#define VAR_LOCAL_ZONE_TAG 486
|
||||
#define VAR_ACCESS_CONTROL_TAG 487
|
||||
#define VAR_LOCAL_ZONE_OVERRIDE 488
|
||||
#define VAR_ACCESS_CONTROL_TAG_ACTION 489
|
||||
#define VAR_ACCESS_CONTROL_TAG_DATA 490
|
||||
#define VAR_VIEW 491
|
||||
#define VAR_ACCESS_CONTROL_VIEW 492
|
||||
#define VAR_VIEW_FIRST 493
|
||||
#define VAR_SERVE_EXPIRED 494
|
||||
#define VAR_SERVE_EXPIRED_TTL 495
|
||||
#define VAR_SERVE_EXPIRED_TTL_RESET 496
|
||||
#define VAR_SERVE_EXPIRED_REPLY_TTL 497
|
||||
#define VAR_SERVE_EXPIRED_CLIENT_TIMEOUT 498
|
||||
#define VAR_EDE_SERVE_EXPIRED 499
|
||||
#define VAR_SERVE_ORIGINAL_TTL 500
|
||||
#define VAR_FAKE_DSA 501
|
||||
#define VAR_FAKE_SHA1 502
|
||||
#define VAR_LOG_IDENTITY 503
|
||||
#define VAR_HIDE_TRUSTANCHOR 504
|
||||
#define VAR_HIDE_HTTP_USER_AGENT 505
|
||||
#define VAR_HTTP_USER_AGENT 506
|
||||
#define VAR_TRUST_ANCHOR_SIGNALING 507
|
||||
#define VAR_AGGRESSIVE_NSEC 508
|
||||
#define VAR_USE_SYSTEMD 509
|
||||
#define VAR_SHM_ENABLE 510
|
||||
#define VAR_SHM_KEY 511
|
||||
#define VAR_ROOT_KEY_SENTINEL 512
|
||||
#define VAR_DNSCRYPT 513
|
||||
#define VAR_DNSCRYPT_ENABLE 514
|
||||
#define VAR_DNSCRYPT_PORT 515
|
||||
#define VAR_DNSCRYPT_PROVIDER 516
|
||||
#define VAR_DNSCRYPT_SECRET_KEY 517
|
||||
#define VAR_DNSCRYPT_PROVIDER_CERT 518
|
||||
#define VAR_DNSCRYPT_PROVIDER_CERT_ROTATED 519
|
||||
#define VAR_DNSCRYPT_SHARED_SECRET_CACHE_SIZE 520
|
||||
#define VAR_DNSCRYPT_SHARED_SECRET_CACHE_SLABS 521
|
||||
#define VAR_DNSCRYPT_NONCE_CACHE_SIZE 522
|
||||
#define VAR_DNSCRYPT_NONCE_CACHE_SLABS 523
|
||||
#define VAR_PAD_RESPONSES 524
|
||||
#define VAR_PAD_RESPONSES_BLOCK_SIZE 525
|
||||
#define VAR_PAD_QUERIES 526
|
||||
#define VAR_PAD_QUERIES_BLOCK_SIZE 527
|
||||
#define VAR_IPSECMOD_ENABLED 528
|
||||
#define VAR_IPSECMOD_HOOK 529
|
||||
#define VAR_IPSECMOD_IGNORE_BOGUS 530
|
||||
#define VAR_IPSECMOD_MAX_TTL 531
|
||||
#define VAR_IPSECMOD_WHITELIST 532
|
||||
#define VAR_IPSECMOD_STRICT 533
|
||||
#define VAR_CACHEDB 534
|
||||
#define VAR_CACHEDB_BACKEND 535
|
||||
#define VAR_CACHEDB_SECRETSEED 536
|
||||
#define VAR_CACHEDB_REDISHOST 537
|
||||
#define VAR_CACHEDB_REDISPORT 538
|
||||
#define VAR_CACHEDB_REDISTIMEOUT 539
|
||||
#define VAR_CACHEDB_REDISEXPIRERECORDS 540
|
||||
#define VAR_CACHEDB_REDISPATH 541
|
||||
#define VAR_CACHEDB_REDISPASSWORD 542
|
||||
#define VAR_CACHEDB_REDISLOGICALDB 543
|
||||
#define VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM 544
|
||||
#define VAR_FOR_UPSTREAM 545
|
||||
#define VAR_AUTH_ZONE 546
|
||||
#define VAR_ZONEFILE 547
|
||||
#define VAR_MASTER 548
|
||||
#define VAR_URL 549
|
||||
#define VAR_FOR_DOWNSTREAM 550
|
||||
#define VAR_FALLBACK_ENABLED 551
|
||||
#define VAR_TLS_ADDITIONAL_PORT 552
|
||||
#define VAR_LOW_RTT 553
|
||||
#define VAR_LOW_RTT_PERMIL 554
|
||||
#define VAR_FAST_SERVER_PERMIL 555
|
||||
#define VAR_FAST_SERVER_NUM 556
|
||||
#define VAR_ALLOW_NOTIFY 557
|
||||
#define VAR_TLS_WIN_CERT 558
|
||||
#define VAR_TCP_CONNECTION_LIMIT 559
|
||||
#define VAR_ANSWER_COOKIE 560
|
||||
#define VAR_COOKIE_SECRET 561
|
||||
#define VAR_IP_RATELIMIT_COOKIE 562
|
||||
#define VAR_FORWARD_NO_CACHE 563
|
||||
#define VAR_STUB_NO_CACHE 564
|
||||
#define VAR_LOG_SERVFAIL 565
|
||||
#define VAR_DENY_ANY 566
|
||||
#define VAR_UNKNOWN_SERVER_TIME_LIMIT 567
|
||||
#define VAR_LOG_TAG_QUERYREPLY 568
|
||||
#define VAR_DISCARD_TIMEOUT 569
|
||||
#define VAR_WAIT_LIMIT 570
|
||||
#define VAR_WAIT_LIMIT_COOKIE 571
|
||||
#define VAR_WAIT_LIMIT_NETBLOCK 572
|
||||
#define VAR_WAIT_LIMIT_COOKIE_NETBLOCK 573
|
||||
#define VAR_STREAM_WAIT_SIZE 574
|
||||
#define VAR_TLS_CIPHERS 575
|
||||
#define VAR_TLS_CIPHERSUITES 576
|
||||
#define VAR_TLS_USE_SNI 577
|
||||
#define VAR_IPSET 578
|
||||
#define VAR_IPSET_NAME_V4 579
|
||||
#define VAR_IPSET_NAME_V6 580
|
||||
#define VAR_TLS_SESSION_TICKET_KEYS 581
|
||||
#define VAR_RPZ 582
|
||||
#define VAR_TAGS 583
|
||||
#define VAR_RPZ_ACTION_OVERRIDE 584
|
||||
#define VAR_RPZ_CNAME_OVERRIDE 585
|
||||
#define VAR_RPZ_LOG 586
|
||||
#define VAR_RPZ_LOG_NAME 587
|
||||
#define VAR_DYNLIB 588
|
||||
#define VAR_DYNLIB_FILE 589
|
||||
#define VAR_EDNS_CLIENT_STRING 590
|
||||
#define VAR_EDNS_CLIENT_STRING_OPCODE 591
|
||||
#define VAR_NSID 592
|
||||
#define VAR_ZONEMD_PERMISSIVE_MODE 593
|
||||
#define VAR_ZONEMD_CHECK 594
|
||||
#define VAR_ZONEMD_REJECT_ABSENCE 595
|
||||
#define VAR_RPZ_SIGNAL_NXDOMAIN_RA 596
|
||||
#define VAR_INTERFACE_AUTOMATIC_PORTS 597
|
||||
#define VAR_EDE 598
|
||||
#define VAR_INTERFACE_ACTION 599
|
||||
#define VAR_INTERFACE_VIEW 600
|
||||
#define VAR_INTERFACE_TAG 601
|
||||
#define VAR_INTERFACE_TAG_ACTION 602
|
||||
#define VAR_INTERFACE_TAG_DATA 603
|
||||
#define VAR_PROXY_PROTOCOL_PORT 604
|
||||
#define VAR_STATISTICS_INHIBIT_ZERO 605
|
||||
#define VAR_HARDEN_UNKNOWN_ADDITIONAL 606
|
||||
#define VAR_DISABLE_EDNS_DO 607
|
||||
#define VAR_CACHEDB_NO_STORE 608
|
||||
#define VAR_LOG_DESTADDR 609
|
||||
#define VAR_CACHEDB_CHECK_WHEN_SERVE_EXPIRED 610
|
||||
#define VAR_DNSTAP_SAMPLE_RATE 446
|
||||
#define VAR_RESPONSE_IP_TAG 447
|
||||
#define VAR_RESPONSE_IP 448
|
||||
#define VAR_RESPONSE_IP_DATA 449
|
||||
#define VAR_HARDEN_ALGO_DOWNGRADE 450
|
||||
#define VAR_IP_TRANSPARENT 451
|
||||
#define VAR_IP_DSCP 452
|
||||
#define VAR_DISABLE_DNSSEC_LAME_CHECK 453
|
||||
#define VAR_IP_RATELIMIT 454
|
||||
#define VAR_IP_RATELIMIT_SLABS 455
|
||||
#define VAR_IP_RATELIMIT_SIZE 456
|
||||
#define VAR_RATELIMIT 457
|
||||
#define VAR_RATELIMIT_SLABS 458
|
||||
#define VAR_RATELIMIT_SIZE 459
|
||||
#define VAR_OUTBOUND_MSG_RETRY 460
|
||||
#define VAR_MAX_SENT_COUNT 461
|
||||
#define VAR_MAX_QUERY_RESTARTS 462
|
||||
#define VAR_RATELIMIT_FOR_DOMAIN 463
|
||||
#define VAR_RATELIMIT_BELOW_DOMAIN 464
|
||||
#define VAR_IP_RATELIMIT_FACTOR 465
|
||||
#define VAR_RATELIMIT_FACTOR 466
|
||||
#define VAR_IP_RATELIMIT_BACKOFF 467
|
||||
#define VAR_RATELIMIT_BACKOFF 468
|
||||
#define VAR_SEND_CLIENT_SUBNET 469
|
||||
#define VAR_CLIENT_SUBNET_ZONE 470
|
||||
#define VAR_CLIENT_SUBNET_ALWAYS_FORWARD 471
|
||||
#define VAR_CLIENT_SUBNET_OPCODE 472
|
||||
#define VAR_MAX_CLIENT_SUBNET_IPV4 473
|
||||
#define VAR_MAX_CLIENT_SUBNET_IPV6 474
|
||||
#define VAR_MIN_CLIENT_SUBNET_IPV4 475
|
||||
#define VAR_MIN_CLIENT_SUBNET_IPV6 476
|
||||
#define VAR_MAX_ECS_TREE_SIZE_IPV4 477
|
||||
#define VAR_MAX_ECS_TREE_SIZE_IPV6 478
|
||||
#define VAR_CAPS_WHITELIST 479
|
||||
#define VAR_CACHE_MAX_NEGATIVE_TTL 480
|
||||
#define VAR_PERMIT_SMALL_HOLDDOWN 481
|
||||
#define VAR_CACHE_MIN_NEGATIVE_TTL 482
|
||||
#define VAR_QNAME_MINIMISATION 483
|
||||
#define VAR_QNAME_MINIMISATION_STRICT 484
|
||||
#define VAR_IP_FREEBIND 485
|
||||
#define VAR_DEFINE_TAG 486
|
||||
#define VAR_LOCAL_ZONE_TAG 487
|
||||
#define VAR_ACCESS_CONTROL_TAG 488
|
||||
#define VAR_LOCAL_ZONE_OVERRIDE 489
|
||||
#define VAR_ACCESS_CONTROL_TAG_ACTION 490
|
||||
#define VAR_ACCESS_CONTROL_TAG_DATA 491
|
||||
#define VAR_VIEW 492
|
||||
#define VAR_ACCESS_CONTROL_VIEW 493
|
||||
#define VAR_VIEW_FIRST 494
|
||||
#define VAR_SERVE_EXPIRED 495
|
||||
#define VAR_SERVE_EXPIRED_TTL 496
|
||||
#define VAR_SERVE_EXPIRED_TTL_RESET 497
|
||||
#define VAR_SERVE_EXPIRED_REPLY_TTL 498
|
||||
#define VAR_SERVE_EXPIRED_CLIENT_TIMEOUT 499
|
||||
#define VAR_EDE_SERVE_EXPIRED 500
|
||||
#define VAR_SERVE_ORIGINAL_TTL 501
|
||||
#define VAR_FAKE_DSA 502
|
||||
#define VAR_FAKE_SHA1 503
|
||||
#define VAR_LOG_IDENTITY 504
|
||||
#define VAR_HIDE_TRUSTANCHOR 505
|
||||
#define VAR_HIDE_HTTP_USER_AGENT 506
|
||||
#define VAR_HTTP_USER_AGENT 507
|
||||
#define VAR_TRUST_ANCHOR_SIGNALING 508
|
||||
#define VAR_AGGRESSIVE_NSEC 509
|
||||
#define VAR_USE_SYSTEMD 510
|
||||
#define VAR_SHM_ENABLE 511
|
||||
#define VAR_SHM_KEY 512
|
||||
#define VAR_ROOT_KEY_SENTINEL 513
|
||||
#define VAR_DNSCRYPT 514
|
||||
#define VAR_DNSCRYPT_ENABLE 515
|
||||
#define VAR_DNSCRYPT_PORT 516
|
||||
#define VAR_DNSCRYPT_PROVIDER 517
|
||||
#define VAR_DNSCRYPT_SECRET_KEY 518
|
||||
#define VAR_DNSCRYPT_PROVIDER_CERT 519
|
||||
#define VAR_DNSCRYPT_PROVIDER_CERT_ROTATED 520
|
||||
#define VAR_DNSCRYPT_SHARED_SECRET_CACHE_SIZE 521
|
||||
#define VAR_DNSCRYPT_SHARED_SECRET_CACHE_SLABS 522
|
||||
#define VAR_DNSCRYPT_NONCE_CACHE_SIZE 523
|
||||
#define VAR_DNSCRYPT_NONCE_CACHE_SLABS 524
|
||||
#define VAR_PAD_RESPONSES 525
|
||||
#define VAR_PAD_RESPONSES_BLOCK_SIZE 526
|
||||
#define VAR_PAD_QUERIES 527
|
||||
#define VAR_PAD_QUERIES_BLOCK_SIZE 528
|
||||
#define VAR_IPSECMOD_ENABLED 529
|
||||
#define VAR_IPSECMOD_HOOK 530
|
||||
#define VAR_IPSECMOD_IGNORE_BOGUS 531
|
||||
#define VAR_IPSECMOD_MAX_TTL 532
|
||||
#define VAR_IPSECMOD_WHITELIST 533
|
||||
#define VAR_IPSECMOD_STRICT 534
|
||||
#define VAR_CACHEDB 535
|
||||
#define VAR_CACHEDB_BACKEND 536
|
||||
#define VAR_CACHEDB_SECRETSEED 537
|
||||
#define VAR_CACHEDB_REDISHOST 538
|
||||
#define VAR_CACHEDB_REDISPORT 539
|
||||
#define VAR_CACHEDB_REDISTIMEOUT 540
|
||||
#define VAR_CACHEDB_REDISEXPIRERECORDS 541
|
||||
#define VAR_CACHEDB_REDISPATH 542
|
||||
#define VAR_CACHEDB_REDISPASSWORD 543
|
||||
#define VAR_CACHEDB_REDISLOGICALDB 544
|
||||
#define VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM 545
|
||||
#define VAR_FOR_UPSTREAM 546
|
||||
#define VAR_AUTH_ZONE 547
|
||||
#define VAR_ZONEFILE 548
|
||||
#define VAR_MASTER 549
|
||||
#define VAR_URL 550
|
||||
#define VAR_FOR_DOWNSTREAM 551
|
||||
#define VAR_FALLBACK_ENABLED 552
|
||||
#define VAR_TLS_ADDITIONAL_PORT 553
|
||||
#define VAR_LOW_RTT 554
|
||||
#define VAR_LOW_RTT_PERMIL 555
|
||||
#define VAR_FAST_SERVER_PERMIL 556
|
||||
#define VAR_FAST_SERVER_NUM 557
|
||||
#define VAR_ALLOW_NOTIFY 558
|
||||
#define VAR_TLS_WIN_CERT 559
|
||||
#define VAR_TCP_CONNECTION_LIMIT 560
|
||||
#define VAR_ANSWER_COOKIE 561
|
||||
#define VAR_COOKIE_SECRET 562
|
||||
#define VAR_IP_RATELIMIT_COOKIE 563
|
||||
#define VAR_FORWARD_NO_CACHE 564
|
||||
#define VAR_STUB_NO_CACHE 565
|
||||
#define VAR_LOG_SERVFAIL 566
|
||||
#define VAR_DENY_ANY 567
|
||||
#define VAR_UNKNOWN_SERVER_TIME_LIMIT 568
|
||||
#define VAR_LOG_TAG_QUERYREPLY 569
|
||||
#define VAR_DISCARD_TIMEOUT 570
|
||||
#define VAR_WAIT_LIMIT 571
|
||||
#define VAR_WAIT_LIMIT_COOKIE 572
|
||||
#define VAR_WAIT_LIMIT_NETBLOCK 573
|
||||
#define VAR_WAIT_LIMIT_COOKIE_NETBLOCK 574
|
||||
#define VAR_STREAM_WAIT_SIZE 575
|
||||
#define VAR_TLS_CIPHERS 576
|
||||
#define VAR_TLS_CIPHERSUITES 577
|
||||
#define VAR_TLS_USE_SNI 578
|
||||
#define VAR_IPSET 579
|
||||
#define VAR_IPSET_NAME_V4 580
|
||||
#define VAR_IPSET_NAME_V6 581
|
||||
#define VAR_TLS_SESSION_TICKET_KEYS 582
|
||||
#define VAR_RPZ 583
|
||||
#define VAR_TAGS 584
|
||||
#define VAR_RPZ_ACTION_OVERRIDE 585
|
||||
#define VAR_RPZ_CNAME_OVERRIDE 586
|
||||
#define VAR_RPZ_LOG 587
|
||||
#define VAR_RPZ_LOG_NAME 588
|
||||
#define VAR_DYNLIB 589
|
||||
#define VAR_DYNLIB_FILE 590
|
||||
#define VAR_EDNS_CLIENT_STRING 591
|
||||
#define VAR_EDNS_CLIENT_STRING_OPCODE 592
|
||||
#define VAR_NSID 593
|
||||
#define VAR_ZONEMD_PERMISSIVE_MODE 594
|
||||
#define VAR_ZONEMD_CHECK 595
|
||||
#define VAR_ZONEMD_REJECT_ABSENCE 596
|
||||
#define VAR_RPZ_SIGNAL_NXDOMAIN_RA 597
|
||||
#define VAR_INTERFACE_AUTOMATIC_PORTS 598
|
||||
#define VAR_EDE 599
|
||||
#define VAR_INTERFACE_ACTION 600
|
||||
#define VAR_INTERFACE_VIEW 601
|
||||
#define VAR_INTERFACE_TAG 602
|
||||
#define VAR_INTERFACE_TAG_ACTION 603
|
||||
#define VAR_INTERFACE_TAG_DATA 604
|
||||
#define VAR_PROXY_PROTOCOL_PORT 605
|
||||
#define VAR_STATISTICS_INHIBIT_ZERO 606
|
||||
#define VAR_HARDEN_UNKNOWN_ADDITIONAL 607
|
||||
#define VAR_DISABLE_EDNS_DO 608
|
||||
#define VAR_CACHEDB_NO_STORE 609
|
||||
#define VAR_LOG_DESTADDR 610
|
||||
#define VAR_CACHEDB_CHECK_WHEN_SERVE_EXPIRED 611
|
||||
#define VAR_COOKIE_SECRET_FILE 612
|
||||
#ifndef YYSTYPE_DEFINED
|
||||
#define YYSTYPE_DEFINED
|
||||
typedef union {
|
||||
|
|
|
@ -137,6 +137,7 @@ extern struct config_parser_state* cfg_parser;
|
|||
%token VAR_DNSTAP_LOG_CLIENT_RESPONSE_MESSAGES
|
||||
%token VAR_DNSTAP_LOG_FORWARDER_QUERY_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_HARDEN_ALGO_DOWNGRADE VAR_IP_TRANSPARENT
|
||||
%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_HARDEN_UNKNOWN_ADDITIONAL VAR_DISABLE_EDNS_DO VAR_CACHEDB_NO_STORE
|
||||
%token VAR_LOG_DESTADDR VAR_CACHEDB_CHECK_WHEN_SERVE_EXPIRED
|
||||
%token VAR_COOKIE_SECRET_FILE
|
||||
|
||||
%%
|
||||
toplevelvars: /* empty */ | toplevelvars toplevelvar ;
|
||||
|
@ -341,7 +343,7 @@ content_server: server_num_threads | server_verbosity | server_port |
|
|||
server_interface_automatic_ports | server_ede |
|
||||
server_proxy_protocol_port | server_statistics_inhibit_zero |
|
||||
server_harden_unknown_additional | server_disable_edns_do |
|
||||
server_log_destaddr
|
||||
server_log_destaddr | server_cookie_secret_file
|
||||
;
|
||||
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 |
|
||||
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 |
|
||||
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));
|
||||
if(s) {
|
||||
s->next = cfg_parser->cfg->views;
|
||||
if(s->next && !s->next->name)
|
||||
yyerror("view without name");
|
||||
cfg_parser->cfg->views = s;
|
||||
} else {
|
||||
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 |
|
||||
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_response_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
|
||||
{
|
||||
|
@ -3601,6 +3620,17 @@ dt_dnstap_log_forwarder_response_messages: VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MES
|
|||
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
|
||||
{
|
||||
OUTYY(("\nP(python:)\n"));
|
||||
|
@ -3969,6 +3999,13 @@ server_cookie_secret: VAR_COOKIE_SECRET STRING_ARG
|
|||
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
|
||||
{
|
||||
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);
|
||||
|
||||
/**
|
||||
* 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 d2: domain name, uncompressed wireformat
|
||||
* @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
|
||||
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 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
|
||||
* 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);
|
||||
}
|
||||
|
||||
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(
|
||||
rdata_ptr, opt_len, cfg->cookie_secret,
|
||||
cfg->cookie_secret_len, cookie_is_v4,
|
||||
server_cookie, now);
|
||||
}
|
||||
if(cookie_val_status == COOKIE_STATUS_VALID_RENEW)
|
||||
edns->cookie_valid = 1;
|
||||
switch(cookie_val_status) {
|
||||
case COOKIE_STATUS_VALID:
|
||||
case COOKIE_STATUS_VALID_RENEW:
|
||||
edns->cookie_valid = 1;
|
||||
/* Reuse cookie */
|
||||
if(!edns_opt_list_append(
|
||||
|
@ -1091,13 +1103,30 @@ parse_edns_options_from_query(uint8_t* rdata_ptr, size_t rdata_len,
|
|||
break;
|
||||
case COOKIE_STATUS_CLIENT_ONLY:
|
||||
edns->cookie_client = 1;
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case COOKIE_STATUS_VALID_RENEW:
|
||||
case COOKIE_STATUS_FUTURE:
|
||||
case COOKIE_STATUS_EXPIRED:
|
||||
case COOKIE_STATUS_INVALID:
|
||||
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,
|
||||
cfg->cookie_secret, cookie_is_v4, now);
|
||||
}
|
||||
if(!edns_opt_list_append(&edns->opt_list_out,
|
||||
LDNS_EDNS_COOKIE, 24, server_cookie,
|
||||
region)) {
|
||||
|
@ -1239,7 +1268,8 @@ skip_pkt_rrs(sldns_buffer* pkt, int num)
|
|||
int
|
||||
parse_edns_from_query_pkt(sldns_buffer* pkt, struct edns_data* edns,
|
||||
struct config_file* cfg, struct comm_point* c,
|
||||
struct 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;
|
||||
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);
|
||||
/* ignore rrsigs */
|
||||
return parse_edns_options_from_query(rdata_ptr, rdata_len, edns, cfg,
|
||||
c, repinfo, now, region);
|
||||
c, repinfo, now, region, cookie_secrets);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -73,6 +73,7 @@ struct edns_option;
|
|||
struct config_file;
|
||||
struct comm_point;
|
||||
struct comm_reply;
|
||||
struct cookie_secrets;
|
||||
|
||||
/** number of buckets in parse rrset hash table. Must be power of 2. */
|
||||
#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 now: current time
|
||||
* @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.
|
||||
* RCODE formerr if OPT is badly formatted and so on.
|
||||
*/
|
||||
int parse_edns_from_query_pkt(struct sldns_buffer* pkt, struct edns_data* edns,
|
||||
struct config_file* cfg, struct comm_point* c,
|
||||
struct 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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
#include "util/storage/dnstree.h"
|
||||
#include "util/locks.h"
|
||||
|
||||
struct edns_data;
|
||||
struct config_file;
|
||||
|
@ -75,6 +76,31 @@ struct edns_string_addr {
|
|||
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 {
|
||||
COOKIE_STATUS_CLIENT_ONLY = -3,
|
||||
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,
|
||||
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
|
||||
|
|
|
@ -448,6 +448,28 @@ fptr_whitelist_mod_deinit(void (*fptr)(struct module_env* env, int id))
|
|||
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
|
||||
fptr_whitelist_mod_operate(void (*fptr)(struct module_qstate* qstate,
|
||||
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));
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
|
|
|
@ -143,7 +143,7 @@
|
|||
* also contain an rcode that is nonzero, but in this case additional
|
||||
* 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.
|
||||
*
|
||||
* If you want to avoid recursion-cycles where queries need other queries
|
||||
|
@ -713,7 +713,28 @@ struct module_func_block {
|
|||
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.
|
||||
* @param env: module environment.
|
||||
* @param id: module id number.
|
||||
|
@ -722,7 +743,8 @@ struct module_func_block {
|
|||
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 id: module id number.
|
||||
*/
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
#ifdef HAVE_NETIOAPI_H
|
||||
#include <netioapi.h>
|
||||
#endif
|
||||
#include <ctype.h>
|
||||
#include "util/net_help.h"
|
||||
#include "util/log.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);
|
||||
}
|
||||
|
||||
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 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)) {
|
||||
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) {
|
||||
EC_KEY *ecdh = EC_KEY_new_by_curve_name (NID_X9_62_prime256v1);
|
||||
if (!ecdh) {
|
||||
|
@ -1857,3 +1872,42 @@ sock_close(int socket)
|
|||
closesocket(socket);
|
||||
}
|
||||
# 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);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* @param addr: address
|
||||
|
@ -564,4 +572,13 @@ char* sock_strerror(int errn);
|
|||
/** close the socket with close, or wsa closesocket */
|
||||
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 */
|
||||
|
|
|
@ -329,6 +329,7 @@ udp_send_errno_needs_log(struct sockaddr* addr, socklen_t addrlen)
|
|||
case EACCES:
|
||||
if(verbosity < VERB_ALGO)
|
||||
return 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -2365,11 +2366,11 @@ recv_error:
|
|||
#ifndef USE_WINSOCK
|
||||
if(errno == EINTR || errno == EAGAIN)
|
||||
return 1;
|
||||
if(recv_initial) {
|
||||
#ifdef ECONNRESET
|
||||
if(errno == ECONNRESET && verbosity < 2)
|
||||
return 0; /* silence reset by peer */
|
||||
#endif
|
||||
if(recv_initial) {
|
||||
#ifdef ECONNREFUSED
|
||||
if(errno == ECONNREFUSED && verbosity < 2)
|
||||
return 0; /* silence reset by peer */
|
||||
|
@ -2396,7 +2397,7 @@ recv_error:
|
|||
#endif
|
||||
#ifdef 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 "
|
||||
"enabled [--disable-tfo-client "
|
||||
"--disable-tfo-server] but does not "
|
||||
|
@ -2430,8 +2431,9 @@ recv_error:
|
|||
return 1;
|
||||
}
|
||||
#endif
|
||||
log_err_addr("read (in tcp s)", sock_strerror(errno),
|
||||
&c->repinfo.remote_addr, c->repinfo.remote_addrlen);
|
||||
log_err_addr((recv_initial?"read (in tcp initial)":"read (in tcp)"),
|
||||
sock_strerror(errno), &c->repinfo.remote_addr,
|
||||
c->repinfo.remote_addrlen);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -3306,6 +3308,13 @@ void http2_stream_add_meshstate(struct http2_stream* h2_stream,
|
|||
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. */
|
||||
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,
|
||||
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.
|
||||
* handle libevent callback for timer comm.
|
||||
|
|
|
@ -153,6 +153,7 @@ pp2_write_to_buf(uint8_t* buf, size_t buflen,
|
|||
break;
|
||||
#endif /* INET6 */
|
||||
case AF_UNIX:
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
default:
|
||||
return 0;
|
||||
|
|
|
@ -128,26 +128,32 @@ int siphash(const uint8_t *in, const size_t inlen, const uint8_t *k,
|
|||
case 7:
|
||||
b |= ((uint64_t)in[6]) << 48;
|
||||
/** EDIT annotate case statement fallthrough for gcc */
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case 6:
|
||||
b |= ((uint64_t)in[5]) << 40;
|
||||
/** EDIT annotate case statement fallthrough for gcc */
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case 5:
|
||||
b |= ((uint64_t)in[4]) << 32;
|
||||
/** EDIT annotate case statement fallthrough for gcc */
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case 4:
|
||||
b |= ((uint64_t)in[3]) << 24;
|
||||
/** EDIT annotate case statement fallthrough for gcc */
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case 3:
|
||||
b |= ((uint64_t)in[2]) << 16;
|
||||
/** EDIT annotate case statement fallthrough for gcc */
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case 2:
|
||||
b |= ((uint64_t)in[1]) << 8;
|
||||
/** EDIT annotate case statement fallthrough for gcc */
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case 1:
|
||||
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 */
|
||||
{
|
||||
case 3 : c+=k[2];
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case 2 : b+=k[1];
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case 1 : a+=k[0];
|
||||
final(a,b,c);
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case 0: /* case 0: nothing left to add */
|
||||
break;
|
||||
}
|
||||
|
@ -304,9 +308,15 @@ uint32_t *pb) /* IN: more seed OUT: secondary hash value */
|
|||
switch(length) /* all the case statements fall through */
|
||||
{
|
||||
case 3 : c+=k[2];
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case 2 : b+=k[1];
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case 1 : a+=k[0];
|
||||
final(a,b,c);
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case 0: /* case 0: nothing left to add */
|
||||
break;
|
||||
}
|
||||
|
@ -404,16 +414,32 @@ uint32_t hashlittle( const void *key, size_t length, uint32_t initval)
|
|||
switch(length)
|
||||
{
|
||||
case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;
|
||||
case 11: c+=((uint32_t)k8[10])<<16; /* fall through */
|
||||
case 10: c+=((uint32_t)k8[9])<<8; /* fall through */
|
||||
case 9 : c+=k8[8]; /* fall through */
|
||||
case 11: c+=((uint32_t)k8[10])<<16;
|
||||
ATTR_FALLTHROUGH
|
||||
/* 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 7 : b+=((uint32_t)k8[6])<<16; /* fall through */
|
||||
case 6 : b+=((uint32_t)k8[5])<<8; /* fall through */
|
||||
case 5 : b+=k8[4]; /* fall through */
|
||||
case 7 : b+=((uint32_t)k8[6])<<16;
|
||||
ATTR_FALLTHROUGH
|
||||
/* 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 3 : a+=((uint32_t)k8[2])<<16; /* fall through */
|
||||
case 2 : a+=((uint32_t)k8[1])<<8; /* fall through */
|
||||
case 3 : a+=((uint32_t)k8[2])<<16;
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case 2 : a+=((uint32_t)k8[1])<<8;
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case 1 : a+=k8[0]; break;
|
||||
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);
|
||||
a+=k[0]+(((uint32_t)k[1])<<16);
|
||||
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];
|
||||
b+=k[2]+(((uint32_t)k[3])<<16);
|
||||
a+=k[0]+(((uint32_t)k[1])<<16);
|
||||
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);
|
||||
a+=k[0]+(((uint32_t)k[1])<<16);
|
||||
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];
|
||||
a+=k[0]+(((uint32_t)k[1])<<16);
|
||||
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);
|
||||
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];
|
||||
break;
|
||||
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 */
|
||||
{
|
||||
case 12: c+=((uint32_t)k[11])<<24;
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case 11: c+=((uint32_t)k[10])<<16;
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case 10: c+=((uint32_t)k[9])<<8;
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case 9 : c+=k[8];
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case 8 : b+=((uint32_t)k[7])<<24;
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case 7 : b+=((uint32_t)k[6])<<16;
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case 6 : b+=((uint32_t)k[5])<<8;
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case 5 : b+=k[4];
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case 4 : a+=((uint32_t)k[3])<<24;
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case 3 : a+=((uint32_t)k[2])<<16;
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case 2 : a+=((uint32_t)k[1])<<8;
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case 1 : a+=k[0];
|
||||
break;
|
||||
|
@ -603,16 +650,32 @@ void hashlittle2(
|
|||
switch(length)
|
||||
{
|
||||
case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;
|
||||
case 11: c+=((uint32_t)k8[10])<<16; /* fall through */
|
||||
case 10: c+=((uint32_t)k8[9])<<8; /* fall through */
|
||||
case 9 : c+=k8[8]; /* fall through */
|
||||
case 11: c+=((uint32_t)k8[10])<<16;
|
||||
ATTR_FALLTHROUGH
|
||||
/* 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 7 : b+=((uint32_t)k8[6])<<16; /* fall through */
|
||||
case 6 : b+=((uint32_t)k8[5])<<8; /* fall through */
|
||||
case 5 : b+=k8[4]; /* fall through */
|
||||
case 7 : b+=((uint32_t)k8[6])<<16;
|
||||
ATTR_FALLTHROUGH
|
||||
/* 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 3 : a+=((uint32_t)k8[2])<<16; /* fall through */
|
||||
case 2 : a+=((uint32_t)k8[1])<<8; /* fall through */
|
||||
case 3 : a+=((uint32_t)k8[2])<<16;
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case 2 : a+=((uint32_t)k8[1])<<8;
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case 1 : a+=k8[0]; break;
|
||||
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);
|
||||
a+=k[0]+(((uint32_t)k[1])<<16);
|
||||
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];
|
||||
b+=k[2]+(((uint32_t)k[3])<<16);
|
||||
a+=k[0]+(((uint32_t)k[1])<<16);
|
||||
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);
|
||||
a+=k[0]+(((uint32_t)k[1])<<16);
|
||||
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];
|
||||
a+=k[0]+(((uint32_t)k[1])<<16);
|
||||
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);
|
||||
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];
|
||||
break;
|
||||
case 1 : a+=k8[0];
|
||||
|
@ -693,16 +766,38 @@ void hashlittle2(
|
|||
switch(length) /* all the case statements fall through */
|
||||
{
|
||||
case 12: c+=((uint32_t)k[11])<<24;
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case 11: c+=((uint32_t)k[10])<<16;
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case 10: c+=((uint32_t)k[9])<<8;
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case 9 : c+=k[8];
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case 8 : b+=((uint32_t)k[7])<<24;
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case 7 : b+=((uint32_t)k[6])<<16;
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case 6 : b+=((uint32_t)k[5])<<8;
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case 5 : b+=k[4];
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case 4 : a+=((uint32_t)k[3])<<24;
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case 3 : a+=((uint32_t)k[2])<<16;
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case 2 : a+=((uint32_t)k[1])<<8;
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case 1 : a+=k[0];
|
||||
break;
|
||||
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 */
|
||||
{
|
||||
case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;
|
||||
case 11: c+=((uint32_t)k8[10])<<8; /* fall through */
|
||||
case 10: c+=((uint32_t)k8[9])<<16; /* fall through */
|
||||
case 9 : c+=((uint32_t)k8[8])<<24; /* fall through */
|
||||
case 11: c+=((uint32_t)k8[10])<<8;
|
||||
ATTR_FALLTHROUGH
|
||||
/* 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 7 : b+=((uint32_t)k8[6])<<8; /* fall through */
|
||||
case 6 : b+=((uint32_t)k8[5])<<16; /* fall through */
|
||||
case 5 : b+=((uint32_t)k8[4])<<24; /* fall through */
|
||||
case 7 : b+=((uint32_t)k8[6])<<8;
|
||||
ATTR_FALLTHROUGH
|
||||
/* 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 3 : a+=((uint32_t)k8[2])<<8; /* fall through */
|
||||
case 2 : a+=((uint32_t)k8[1])<<16; /* fall through */
|
||||
case 3 : a+=((uint32_t)k8[2])<<8;
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case 2 : a+=((uint32_t)k8[1])<<16;
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case 1 : a+=((uint32_t)k8[0])<<24; break;
|
||||
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 */
|
||||
{
|
||||
case 12: c+=k[11];
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case 11: c+=((uint32_t)k[10])<<8;
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case 10: c+=((uint32_t)k[9])<<16;
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case 9 : c+=((uint32_t)k[8])<<24;
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case 8 : b+=k[7];
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case 7 : b+=((uint32_t)k[6])<<8;
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case 6 : b+=((uint32_t)k[5])<<16;
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case 5 : b+=((uint32_t)k[4])<<24;
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case 4 : a+=k[3];
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case 3 : a+=((uint32_t)k[2])<<8;
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case 2 : a+=((uint32_t)k[1])<<16;
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case 1 : a+=((uint32_t)k[0])<<24;
|
||||
break;
|
||||
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 module_qstate* qstate)
|
||||
{
|
||||
char reasonbuf[256];
|
||||
char* reason = NULL;
|
||||
uint8_t sigalg[ALGO_NEEDS_MAX+1];
|
||||
int downprot = env->cfg->harden_algo_downgrade;
|
||||
enum sec_status sec = val_verify_DNSKEY_with_TA(env, ve, rrset,
|
||||
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
|
||||
* in 5011 there are no other rrsets to check. if downprot is
|
||||
* 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,
|
||||
struct ub_packed_rrset_key* nsec, 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*)
|
||||
nsec->entry.data;
|
||||
|
@ -189,7 +189,8 @@ nsec_verify_rrset(struct module_env* env, struct val_env* ve,
|
|||
if(d->security == sec_status_secure)
|
||||
return 1;
|
||||
d->security = val_verify_rrset_entry(env, ve, nsec, kkey, reason,
|
||||
reason_bogus, LDNS_SECTION_AUTHORITY, qstate, &verified);
|
||||
reason_bogus, LDNS_SECTION_AUTHORITY, qstate, &verified,
|
||||
reasonbuf, reasonlen);
|
||||
if(d->security == sec_status_secure) {
|
||||
rrset_update_sec_status(env->rrset_cache, nsec, *env->now);
|
||||
return 1;
|
||||
|
@ -201,7 +202,8 @@ enum sec_status
|
|||
val_nsec_prove_nodata_dsreply(struct module_env* env, struct val_env* ve,
|
||||
struct query_info* qinfo, struct reply_info* rep,
|
||||
struct key_entry_key* kkey, time_t* proof_ttl, char** reason,
|
||||
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(
|
||||
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 */
|
||||
if(nsec) {
|
||||
if(!nsec_verify_rrset(env, ve, nsec, kkey, reason,
|
||||
reason_bogus, qstate)) {
|
||||
reason_bogus, qstate, reasonbuf, reasonlen)) {
|
||||
verbose(VERB_ALGO, "NSEC RRset for the "
|
||||
"referral did not verify.");
|
||||
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))
|
||||
continue;
|
||||
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 "
|
||||
"did not verify.");
|
||||
*reason = "NSEC for empty non-terminal "
|
||||
|
|
|
@ -68,6 +68,8 @@ struct key_entry_key;
|
|||
* @param reason: string explaining why bogus.
|
||||
* @param reason_bogus: relevant EDE code for validation failure.
|
||||
* @param qstate: qstate with region.
|
||||
* @param reasonbuf: buffer to use for fail reason string print.
|
||||
* @param reasonlen: length of reasonbuf.
|
||||
* @return security status.
|
||||
* SECURE: proved absence of DS.
|
||||
* 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 reply_info* rep, struct key_entry_key* kkey,
|
||||
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.
|
||||
|
|
|
@ -1445,7 +1445,7 @@ static int
|
|||
list_is_secure(struct module_env* env, struct val_env* ve,
|
||||
struct ub_packed_rrset_key** list, size_t num,
|
||||
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;
|
||||
size_t i;
|
||||
|
@ -1461,7 +1461,7 @@ list_is_secure(struct module_env* env, struct val_env* ve,
|
|||
continue;
|
||||
d->security = val_verify_rrset_entry(env, ve, list[i], kkey,
|
||||
reason, reason_bogus, LDNS_SECTION_AUTHORITY, qstate,
|
||||
&verified);
|
||||
&verified, reasonbuf, reasonlen);
|
||||
if(d->security != sec_status_secure) {
|
||||
verbose(VERB_ALGO, "NSEC3 did not verify");
|
||||
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 query_info* qinfo, struct key_entry_key* kkey, char** reason,
|
||||
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 ce_response ce;
|
||||
|
@ -1491,7 +1491,8 @@ nsec3_prove_nods(struct module_env* env, struct val_env* ve,
|
|||
*reason = "no valid NSEC3s";
|
||||
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";
|
||||
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 qstate: qstate with region.
|
||||
* @param ct: cached hashes table.
|
||||
* @param reasonbuf: buffer to use for fail reason string print.
|
||||
* @param reasonlen: length of reasonbuf.
|
||||
* @return:
|
||||
* 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.
|
||||
|
@ -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 query_info* qinfo, struct key_entry_key* kkey, char** reason,
|
||||
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.
|
||||
|
|
|
@ -423,7 +423,10 @@ setup_dsa_sig(unsigned char** sig, unsigned int* len)
|
|||
if(!dsasig) return 0;
|
||||
|
||||
#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
|
||||
# ifndef S_SPLINT_S
|
||||
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);
|
||||
#endif
|
||||
/* double fallthrough annotation to please gcc parser */
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
#ifdef USE_SHA2
|
||||
/* fallthrough */
|
||||
case LDNS_RSASHA256:
|
||||
digest_size = (digest_size ? digest_size : SHA256_DIGEST_SIZE);
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case LDNS_RSASHA512:
|
||||
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
|
||||
case LDNS_ECDSAP256SHA256:
|
||||
digest_size = (digest_size ? digest_size : SHA256_DIGEST_SIZE);
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case LDNS_ECDSAP384SHA384:
|
||||
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,
|
||||
struct ub_packed_rrset_key* rrset, struct ub_packed_rrset_key* dnskey,
|
||||
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;
|
||||
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: "
|
||||
"no valid signatures for %d algorithms",
|
||||
(int)algo_needs_num_missing(&needs));
|
||||
algo_needs_reason(env, alg, reason, "no signatures");
|
||||
algo_needs_reason(alg, reason, "no signatures", reasonbuf,
|
||||
reasonlen);
|
||||
} else {
|
||||
verbose(VERB_ALGO, "rrset failed to verify: "
|
||||
"no valid signatures");
|
||||
|
@ -688,17 +690,16 @@ dnskeyset_verify_rrset(struct module_env* env, struct val_env* ve,
|
|||
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);
|
||||
if(t&&t->name)
|
||||
snprintf(buf, sizeof(buf), "%s with algorithm %s", s, t->name);
|
||||
else snprintf(buf, sizeof(buf), "%s with algorithm ALG%u", s,
|
||||
snprintf(reasonbuf, reasonlen, "%s with algorithm %s", s,
|
||||
t->name);
|
||||
else snprintf(reasonbuf, reasonlen, "%s with algorithm ALG%u", s,
|
||||
(unsigned)alg);
|
||||
*reason = regional_strdup(env->scratch, buf);
|
||||
if(!*reason)
|
||||
*reason = s;
|
||||
*reason = reasonbuf;
|
||||
}
|
||||
|
||||
enum sec_status
|
||||
|
|
|
@ -134,12 +134,14 @@ int algo_needs_missing(struct algo_needs* n);
|
|||
|
||||
/**
|
||||
* Format error reason for algorithm missing.
|
||||
* @param env: module env with scratch for temp storage of string.
|
||||
* @param alg: DNSKEY-algorithm missing.
|
||||
* @param reason: destination.
|
||||
* @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
|
||||
|
@ -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 qstate: qstate with region.
|
||||
* @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.
|
||||
* UNCHECKED on allocation errors, unsupported algorithms, malformed data,
|
||||
* 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 ub_packed_rrset_key* dnskey, 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);
|
||||
|
||||
/**
|
||||
* 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
|
||||
val_find_signer(enum val_classification subtype, struct query_info* qinf,
|
||||
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_len = 0;
|
||||
} else if(subtype == VAL_CLASS_CNAME) {
|
||||
size_t j;
|
||||
/* check for the first signed cname/dname rrset */
|
||||
for(i=skip; i<rep->an_numrrsets; i++) {
|
||||
val_find_rrset_signer(rep->rrsets[i],
|
||||
signer_name, signer_len);
|
||||
if(*signer_name)
|
||||
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)
|
||||
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,
|
||||
uint8_t* sigalg, char** reason, sldns_ede_code *reason_bogus,
|
||||
sldns_pkt_section section, struct module_qstate* qstate,
|
||||
int *verified)
|
||||
int *verified, char* reasonbuf, size_t reasonlen)
|
||||
{
|
||||
enum sec_status sec;
|
||||
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,
|
||||
ntohs(rrset->rk.type), ntohs(rrset->rk.rrset_class));
|
||||
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));
|
||||
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,
|
||||
char** reason, sldns_ede_code *reason_bogus,
|
||||
sldns_pkt_section section, struct module_qstate* qstate,
|
||||
int* verified)
|
||||
int* verified, char* reasonbuf, size_t reasonlen)
|
||||
{
|
||||
/* temporary dnskey rrset-key */
|
||||
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.data = kd->rrset_data;
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -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* ds_rrset, size_t ds_idx, char** reason,
|
||||
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;
|
||||
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;
|
||||
}
|
||||
if(numchecked == 0) {
|
||||
algo_needs_reason(env, ds_get_key_algo(ds_rrset, ds_idx),
|
||||
reason, "no keys have a DS");
|
||||
algo_needs_reason(ds_get_key_algo(ds_rrset, ds_idx),
|
||||
reason, "no keys have a DS", reasonbuf, reasonlen);
|
||||
*nonechecked = 1;
|
||||
} else if(numhashok == 0) {
|
||||
*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,
|
||||
struct ub_packed_rrset_key* dnskey_rrset,
|
||||
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
|
||||
* 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,
|
||||
ds_rrset, i, reason, reason_bogus, qstate,
|
||||
&nonechecked);
|
||||
&nonechecked, reasonbuf, reasonlen);
|
||||
if(sec == sec_status_insecure) {
|
||||
/* DNSKEY too large unsupported or algo refused by
|
||||
* 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. */
|
||||
verbose(VERB_QUERY, "Failed to match any usable DS to a DNSKEY.");
|
||||
if(sigalg && (alg=algo_needs_missing(&needs)) != 0) {
|
||||
algo_needs_reason(env, alg, reason, "missing verification of "
|
||||
"DNSKEY signature");
|
||||
algo_needs_reason(alg, reason, "missing verification of "
|
||||
"DNSKEY signature", reasonbuf, reasonlen);
|
||||
}
|
||||
return sec_status_bogus;
|
||||
}
|
||||
|
@ -649,12 +677,13 @@ struct key_entry_key*
|
|||
val_verify_new_DNSKEYs(struct regional* region, struct module_env* env,
|
||||
struct val_env* ve, struct ub_packed_rrset_key* dnskey_rrset,
|
||||
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];
|
||||
enum sec_status sec = val_verify_DNSKEY_with_DS(env, ve,
|
||||
dnskey_rrset, ds_rrset, downprot?sigalg:NULL, reason,
|
||||
reason_bogus, qstate);
|
||||
reason_bogus, qstate, reasonbuf, reasonlen);
|
||||
|
||||
if(sec == sec_status_secure) {
|
||||
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* ta_ds,
|
||||
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
|
||||
* equivalent to no anchor. */
|
||||
|
@ -730,7 +760,8 @@ val_verify_DNSKEY_with_TA(struct module_env* env, struct val_env* ve,
|
|||
continue;
|
||||
|
||||
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) {
|
||||
has_algo_refusal = 1;
|
||||
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. */
|
||||
verbose(VERB_QUERY, "Failed to match any usable anchor to a DNSKEY.");
|
||||
if(sigalg && (alg=algo_needs_missing(&needs)) != 0) {
|
||||
algo_needs_reason(env, alg, reason, "missing verification of "
|
||||
"DNSKEY signature");
|
||||
algo_needs_reason(alg, reason, "missing verification of "
|
||||
"DNSKEY signature", reasonbuf, reasonlen);
|
||||
}
|
||||
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 ub_packed_rrset_key* ta_ds_rrset,
|
||||
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];
|
||||
enum sec_status sec = val_verify_DNSKEY_with_TA(env, ve,
|
||||
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) {
|
||||
return key_entry_create_rrset(region,
|
||||
|
@ -979,7 +1012,7 @@ void
|
|||
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 i;
|
||||
size_t i, j;
|
||||
int seen_dname = 0;
|
||||
chase->rrset_count = 0;
|
||||
chase->an_numrrsets = 0;
|
||||
|
@ -1002,6 +1035,13 @@ val_fill_reply(struct reply_info* chase, struct reply_info* orig,
|
|||
LDNS_RR_TYPE_DNAME) {
|
||||
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 */
|
||||
|
|
|
@ -125,13 +125,15 @@ void val_find_signer(enum val_classification subtype,
|
|||
* @param section: section of packet where this rrset comes from.
|
||||
* @param qstate: qstate with region.
|
||||
* @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.
|
||||
*/
|
||||
enum sec_status val_verify_rrset_entry(struct module_env* env,
|
||||
struct val_env* ve, struct ub_packed_rrset_key* rrset,
|
||||
struct key_entry_key* kkey, char** reason, sldns_ede_code *reason_bogus,
|
||||
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
|
||||
|
@ -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_bogus: EDE (RFC8914) code paired with the reason of failure.
|
||||
* @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.
|
||||
* sec_status_insecure if end of trust (i.e., unknown algorithms).
|
||||
* 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,
|
||||
struct val_env* ve, struct ub_packed_rrset_key* dnskey_rrset,
|
||||
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
|
||||
|
@ -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_bogus: EDE (RFC8914) code paired with the reason of failure.
|
||||
* @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.
|
||||
* sec_status_insecure if end of trust (i.e., unknown algorithms).
|
||||
* 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 ub_packed_rrset_key* ta_ds,
|
||||
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
|
||||
|
@ -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_bogus: EDE (RFC8914) code paired with the reason of failure.
|
||||
* @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
|
||||
* dnskey_rrset, a "null" key entry indicating that this DS
|
||||
* 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 ub_packed_rrset_key* dnskey_rrset,
|
||||
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.
|
||||
|
@ -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_bogus: EDE (RFC8914) code paired with the reason of failure.
|
||||
* @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
|
||||
* dnskey_rrset, a "null" key entry indicating that this DS
|
||||
* 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* ta_ds_rrset,
|
||||
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.
|
||||
|
|
|
@ -72,7 +72,8 @@
|
|||
/* forward decl for cache response and normal super inform calls of a DS */
|
||||
static void process_ds_response(struct module_qstate* qstate,
|
||||
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
|
||||
|
@ -273,11 +274,17 @@ val_new_getmsg(struct module_qstate* qstate, struct val_qstate* vq)
|
|||
return NULL;
|
||||
if(vq->orig_msg->rep->rrset_count > RR_COUNT_MAX)
|
||||
return NULL; /* protect against integer overflow */
|
||||
vq->chase_reply->rrsets = regional_alloc_init(qstate->region,
|
||||
vq->orig_msg->rep->rrsets, sizeof(struct ub_packed_rrset_key*)
|
||||
* vq->orig_msg->rep->rrset_count);
|
||||
/* Over allocate (+an_numrrsets) in case we need to put extra DNAME
|
||||
* records for unsigned CNAME repetitions */
|
||||
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)
|
||||
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;
|
||||
return vq;
|
||||
}
|
||||
|
@ -640,6 +647,7 @@ validate_msg_signatures(struct module_qstate* qstate, struct val_qstate* vq,
|
|||
struct ub_packed_rrset_key* s;
|
||||
enum sec_status sec;
|
||||
int num_verifies = 0, verified, have_state = 0;
|
||||
char reasonbuf[256];
|
||||
char* reason = NULL;
|
||||
sldns_ede_code reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
|
||||
*suspend = 0;
|
||||
|
@ -675,7 +683,8 @@ validate_msg_signatures(struct module_qstate* qstate, struct val_qstate* vq,
|
|||
|
||||
/* Verify the answer rrset */
|
||||
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
|
||||
* message is BAD. */
|
||||
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];
|
||||
sec = val_verify_rrset_entry(env, ve, s, key_entry, &reason,
|
||||
&reason_bogus, LDNS_SECTION_AUTHORITY, qstate,
|
||||
&verified);
|
||||
&verified, reasonbuf, sizeof(reasonbuf));
|
||||
/* If anything in the authority section fails to be secure,
|
||||
* we have a bad message. */
|
||||
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)
|
||||
(void)val_verify_rrset_entry(env, ve, s, key_entry,
|
||||
&reason, NULL, LDNS_SECTION_ADDITIONAL, qstate,
|
||||
&verified);
|
||||
&verified, reasonbuf, sizeof(reasonbuf));
|
||||
/* the additional section can fail to be secure,
|
||||
* it is optional, check signature in case we need
|
||||
* 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.
|
||||
* Difference with positive proof is that this routine refuses
|
||||
* wildcarded DNAMEs.
|
||||
*
|
||||
*
|
||||
* The answer and authority rrsets must already be verified as secure.
|
||||
*
|
||||
*
|
||||
* @param env: module env for verify.
|
||||
* @param ve: validator env for verify.
|
||||
* @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");
|
||||
msg = vq->sub_ds_msg;
|
||||
process_ds_response(qstate, vq, id, LDNS_RCODE_NOERROR,
|
||||
msg, &msg->qinfo, NULL, &suspend);
|
||||
msg, &msg->qinfo, NULL, &suspend, NULL);
|
||||
if(suspend) {
|
||||
/* we'll come back here later to continue */
|
||||
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)) ) {
|
||||
verbose(VERB_ALGO, "Process cached DS response");
|
||||
process_ds_response(qstate, vq, id, LDNS_RCODE_NOERROR,
|
||||
msg, &msg->qinfo, NULL, &suspend);
|
||||
msg, &msg->qinfo, NULL, &suspend, NULL);
|
||||
if(suspend) {
|
||||
/* we'll come back here later to continue */
|
||||
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 qstate: qstate that needs key.
|
||||
* @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.
|
||||
* The key entry will either contain a validated DNSKEY rrset, or
|
||||
* 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*
|
||||
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 key_entry_key* kkey = NULL;
|
||||
enum sec_status sec = sec_status_unchecked;
|
||||
char reasonbuf[256];
|
||||
char* reason = NULL;
|
||||
sldns_ede_code reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
|
||||
int downprot = qstate->env->cfg->harden_algo_downgrade;
|
||||
|
||||
if(!dnskey_rrset) {
|
||||
char* err = errinf_to_str_misc(sub_qstate);
|
||||
char rstr[1024];
|
||||
log_nametypeclass(VERB_OPS, "failed to prime trust anchor -- "
|
||||
"could not fetch DNSKEY rrset",
|
||||
ta->name, LDNS_RR_TYPE_DNSKEY, ta->dclass);
|
||||
reason_bogus = LDNS_EDE_DNSKEY_MISSING;
|
||||
reason = "no DNSKEY rrset";
|
||||
if(!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) {
|
||||
errinf_ede(qstate, reason, reason_bogus);
|
||||
errinf_ede(qstate, rstr, reason_bogus);
|
||||
kkey = key_entry_create_bad(qstate->region, ta->name,
|
||||
ta->namelen, ta->dclass, BOGUS_KEY_TTL,
|
||||
reason_bogus, reason,
|
||||
*qstate->env->now);
|
||||
reason_bogus, rstr, *qstate->env->now);
|
||||
} else kkey = key_entry_create_null(qstate->region, ta->name,
|
||||
ta->namelen, ta->dclass, NULL_KEY_TTL,
|
||||
reason_bogus, reason,
|
||||
*qstate->env->now);
|
||||
reason_bogus, rstr, *qstate->env->now);
|
||||
if(!kkey) {
|
||||
log_err("out of memory: allocate fail prime key");
|
||||
return NULL;
|
||||
|
@ -2699,7 +2717,7 @@ primeResponseToKE(struct ub_packed_rrset_key* dnskey_rrset,
|
|||
/* attempt to verify with trust anchor DS and DNSKEY */
|
||||
kkey = val_verify_new_DNSKEYs_with_ta(qstate->region, qstate->env, ve,
|
||||
dnskey_rrset, ta->ds_rrset, ta->dnskey_rrset, downprot,
|
||||
&reason, &reason_bogus, qstate);
|
||||
&reason, &reason_bogus, qstate, reasonbuf, sizeof(reasonbuf));
|
||||
if(!kkey) {
|
||||
log_err("out of memory: verifying prime TA");
|
||||
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
|
||||
* validated. It returns ke=NULL if the DS response indicated that the
|
||||
* 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
|
||||
* 0 on success,
|
||||
* 1 on servfail error (malloc failure),
|
||||
|
@ -2762,9 +2783,10 @@ primeResponseToKE(struct ub_packed_rrset_key* dnskey_rrset,
|
|||
static int
|
||||
ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
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];
|
||||
char reasonbuf[256];
|
||||
char* reason = NULL;
|
||||
sldns_ede_code reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
|
||||
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");
|
||||
errinf(qstate, rc);
|
||||
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;
|
||||
errinf_ede(qstate, reason, reason_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
|
||||
* bogus, then we are done. */
|
||||
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) {
|
||||
verbose(VERB_DETAIL, "DS rrset in DS response did "
|
||||
"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 */
|
||||
sec = val_nsec_prove_nodata_dsreply(
|
||||
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) {
|
||||
case sec_status_secure:
|
||||
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,
|
||||
msg->rep->rrsets + msg->rep->an_numrrsets,
|
||||
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) {
|
||||
case sec_status_insecure:
|
||||
/* 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,
|
||||
vq->key_entry, &reason, &reason_bogus,
|
||||
LDNS_SECTION_ANSWER, qstate, &verified);
|
||||
LDNS_SECTION_ANSWER, qstate, &verified, reasonbuf,
|
||||
sizeof(reasonbuf));
|
||||
if(sec == sec_status_secure) {
|
||||
verbose(VERB_ALGO, "CNAME validated, "
|
||||
"proof that DS does not exist");
|
||||
|
@ -3002,11 +3037,15 @@ return_bogus:
|
|||
* @param origin: the origin of msg.
|
||||
* @param suspend: returned true if the task takes too long and needs to
|
||||
* 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
|
||||
process_ds_response(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
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 key_entry_key* dske = NULL;
|
||||
|
@ -3014,7 +3053,8 @@ process_ds_response(struct module_qstate* qstate, struct val_qstate* vq,
|
|||
int ret;
|
||||
*suspend = 0;
|
||||
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) {
|
||||
switch(ret) {
|
||||
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 qinfo: from the sub query state, query info.
|
||||
* @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
|
||||
process_dnskey_response(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
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 key_entry_key* old = vq->key_entry;
|
||||
struct ub_packed_rrset_key* dnskey = NULL;
|
||||
int downprot;
|
||||
char reasonbuf[256];
|
||||
char* reason = NULL;
|
||||
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);
|
||||
|
||||
if(dnskey == NULL) {
|
||||
char* err;
|
||||
char rstr[1024];
|
||||
/* bad response */
|
||||
verbose(VERB_DETAIL, "Missing DNSKEY RRset in response to "
|
||||
"DNSKEY query.");
|
||||
|
@ -3118,17 +3163,22 @@ process_dnskey_response(struct module_qstate* qstate, struct val_qstate* vq,
|
|||
vq->restart_count++;
|
||||
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;
|
||||
vq->key_entry = key_entry_create_bad(qstate->region,
|
||||
qinfo->qname, qinfo->qname_len, qinfo->qclass,
|
||||
BOGUS_KEY_TTL, reason_bogus, reason,
|
||||
*qstate->env->now);
|
||||
BOGUS_KEY_TTL, reason_bogus, rstr, *qstate->env->now);
|
||||
if(!vq->key_entry) {
|
||||
log_err("alloc failure in missing dnskey response");
|
||||
/* key_entry is NULL for failure in Validate */
|
||||
}
|
||||
errinf_ede(qstate, reason, reason_bogus);
|
||||
errinf_ede(qstate, rstr, reason_bogus);
|
||||
errinf_origin(qstate, origin);
|
||||
errinf_dname(qstate, "for key", qinfo->qname);
|
||||
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;
|
||||
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) {
|
||||
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 msg: result message (if rcode is OK).
|
||||
* @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
|
||||
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 ub_packed_rrset_key* dnskey_rrset = NULL;
|
||||
|
@ -3227,7 +3281,8 @@ process_prime_response(struct module_qstate* qstate, struct val_qstate* vq,
|
|||
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);
|
||||
if(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) {
|
||||
vq->wait_prime_ta = 0;
|
||||
process_prime_response(super, vq, id, qstate->return_rcode,
|
||||
qstate->return_msg, qstate->reply_origin);
|
||||
qstate->return_msg, qstate->reply_origin, qstate);
|
||||
return;
|
||||
}
|
||||
if(qstate->qinfo.qtype == LDNS_RR_TYPE_DS) {
|
||||
int suspend;
|
||||
process_ds_response(super, vq, id, qstate->return_rcode,
|
||||
qstate->return_msg, &qstate->qinfo,
|
||||
qstate->reply_origin, &suspend);
|
||||
qstate->reply_origin, &suspend, qstate);
|
||||
/* If NSEC3 was needed during validation, NULL the NSEC3 cache;
|
||||
* it will be re-initiated if needed later on.
|
||||
* 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) {
|
||||
process_dnskey_response(super, vq, id, qstate->return_rcode,
|
||||
qstate->return_msg, &qstate->qinfo,
|
||||
qstate->reply_origin);
|
||||
qstate->reply_origin, qstate);
|
||||
return;
|
||||
}
|
||||
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 = {
|
||||
"validator",
|
||||
&val_init, &val_deinit, &val_operate, &val_inform_super, &val_clear,
|
||||
&val_get_mem
|
||||
NULL, NULL, &val_init, &val_deinit, &val_operate, &val_inform_super,
|
||||
&val_clear, &val_get_mem
|
||||
};
|
||||
|
||||
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 \
|
||||
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 \
|
||||
pf.4 pflog.4 pflow.4 pfsync.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 \
|
||||
qccpu.4 qcdwusb.4 qcgpio.4 qciic.4 qcpdc.4 qcpmic.4 qcpmicgpio.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>
|
||||
.\"
|
||||
|
@ -14,7 +14,7 @@
|
|||
.\" 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 1 2024 $
|
||||
.Dd $Mdocdate: September 4 2024 $
|
||||
.Dt CCP 4
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -33,14 +33,9 @@ The
|
|||
.Nm
|
||||
driver supports feeding output of the random number generator into
|
||||
the kernel entropy pool.
|
||||
.Pp
|
||||
On amd64
|
||||
.Nm
|
||||
provides
|
||||
.Xr ioctl 2
|
||||
access to the platform security processor (PSP).
|
||||
.Sh SEE ALSO
|
||||
.Xr intro 4 ,
|
||||
.Xr psp 4 ,
|
||||
.Xr random 4 ,
|
||||
.Xr arc4random 9
|
||||
.Sh HISTORY
|
||||
|
@ -54,5 +49,3 @@ The
|
|||
.Nm
|
||||
driver was written by
|
||||
.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 $
|
||||
.\"
|
||||
.\" Mach Operating System
|
||||
|
@ -25,7 +25,7 @@
|
|||
.\" any improvements or extensions that they make and grant Carnegie Mellon
|
||||
.\" the rights to redistribute these changes.
|
||||
.\"
|
||||
.Dd $Mdocdate: February 5 2024 $
|
||||
.Dd $Mdocdate: September 5 2024 $
|
||||
.Dt DDB 4
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -658,7 +658,11 @@ If the
|
|||
.Cm /f
|
||||
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
|
||||
.Vt struct mbuf
|
||||
header at
|
||||
|
@ -668,6 +672,13 @@ Depending on the mbuf flags
|
|||
and
|
||||
.Vt struct m_ext
|
||||
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
|
||||
.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
|
||||
.\"
|
||||
|
@ -24,7 +24,7 @@
|
|||
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd $Mdocdate: August 15 2024 $
|
||||
.Dd $Mdocdate: September 4 2024 $
|
||||
.Dt BSD.PORT.MK 5
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -1731,12 +1731,7 @@ checksummed and extracted (see
|
|||
.Cm checksum ,
|
||||
.Cm extract ) .
|
||||
.Ev DISTFILES
|
||||
normally holds a list of files, possibly with
|
||||
.Sq :0
|
||||
to
|
||||
.Sq :9
|
||||
appended to select a different
|
||||
.Ev SITES .
|
||||
normally holds a list of files.
|
||||
.Pp
|
||||
Preferably, adding a suffix to
|
||||
.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.
|
||||
.\" generated from:
|
||||
.\"
|
||||
.\" OpenBSD: etc.amd64/MAKEDEV.md,v 1.82 2023/01/14 12:15:12 kettenis Exp
|
||||
.\" OpenBSD: MAKEDEV.common,v 1.119 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.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.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
|
||||
.\" 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
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -299,6 +299,9 @@ paravirtual device tree root, see
|
|||
.It Ar kstat
|
||||
Kernel Statistics, see
|
||||
.Xr kstat 4 .
|
||||
.It Ar psp
|
||||
Platform Security Processor, see
|
||||
.Xr psp 4 .
|
||||
.El
|
||||
.Sh FILES
|
||||
.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
|
||||
|
||||
FILES= std stdcrt vt100 vt300
|
||||
|
@ -7,7 +7,7 @@ CLEANFILES+= ${FILES}
|
|||
all: ${FILES}
|
||||
|
||||
${FILES}:
|
||||
sh ${.CURDIR}/gentabset.sh ${.CURDIR}/obj
|
||||
sh ${.CURDIR}/gentabset.sh ${.OBJDIR}
|
||||
|
||||
realinstall: ${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.
|
||||
|
@ -152,8 +152,6 @@ cdev_decl(nvram);
|
|||
#include "drm.h"
|
||||
#include "viocon.h"
|
||||
cdev_decl(viocon);
|
||||
#include "ccp.h"
|
||||
cdev_decl(psp);
|
||||
|
||||
#include "wsdisplay.h"
|
||||
#include "wskbd.h"
|
||||
|
@ -292,7 +290,7 @@ struct cdevsw cdevsw[] =
|
|||
cdev_fido_init(NFIDO,fido), /* 98: FIDO/U2F security keys */
|
||||
cdev_pppx_init(NPPPX,pppac), /* 99: PPP Access Concentrator */
|
||||
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);
|
||||
|
||||
|
|
|
@ -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 $ */
|
||||
|
||||
/*-
|
||||
|
@ -182,7 +182,7 @@ upageflttrap(struct trapframe *frame, uint64_t cr2)
|
|||
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.
|
||||
*/
|
||||
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>
|
||||
*
|
||||
|
@ -4181,7 +4181,8 @@ vcpu_run_vmx(struct vcpu *vcpu, struct vm_run_params *vrp)
|
|||
break;
|
||||
}
|
||||
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;
|
||||
break;
|
||||
}
|
||||
|
@ -6281,7 +6282,8 @@ vmm_handle_cpuid(struct vcpu *vcpu)
|
|||
*rdx = 0;
|
||||
break;
|
||||
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;
|
||||
*rcx = 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)
|
||||
# man page.
|
||||
|
@ -123,6 +123,7 @@ ksmn* at pci? # AMD K17 temperature sensor
|
|||
amas* at pci? disable # AMD memory configuration
|
||||
pchtemp* at pci? # Intel C610 temperature sensor
|
||||
ccp* at pci? # AMD Cryptographic Co-processor
|
||||
psp* at ccp? # AMD Platform Security Processor
|
||||
|
||||
# National Semiconductor LM7[89] and compatible hardware monitors
|
||||
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
|
||||
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/k1x-pstate.c !small_kernel
|
||||
|
||||
file dev/ic/psp.c ccp
|
||||
|
||||
include "dev/rasops/files.rasops"
|
||||
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 $ */
|
||||
|
||||
/*
|
||||
|
@ -55,5 +55,5 @@ cdev_decl(pctr);
|
|||
#include "vmm.h"
|
||||
cdev_decl(vmm);
|
||||
|
||||
#include "ccp.h"
|
||||
#include "psp.h"
|
||||
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 $ */
|
||||
|
||||
/*-
|
||||
|
@ -121,7 +121,7 @@ upageflttrap(struct trapframe *frame, uint32_t cr2)
|
|||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
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 $
|
||||
|
||||
# @(#)files.newconf 7.5 (Berkeley) 5/10/93
|
||||
|
@ -470,9 +470,14 @@ device xhci: usbus
|
|||
file dev/usb/xhci.c xhci needs-flag
|
||||
|
||||
# AMD Cryptographic Co-processor
|
||||
device ccp
|
||||
device ccp {}
|
||||
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
|
||||
define sdhc
|
||||
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>
|
||||
* All rights reserved.
|
||||
|
@ -35,7 +35,7 @@
|
|||
* optimized for speed on short messages returning a 64bit hash/digest value.
|
||||
*
|
||||
* 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)
|
||||
*
|
||||
* 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 $ */
|
||||
|
||||
/*
|
||||
|
@ -340,7 +340,15 @@ db_malloc_print_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
|
|||
void
|
||||
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
|
||||
|
|
|
@ -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 $ */
|
||||
|
||||
/*-
|
||||
|
@ -280,7 +280,7 @@ db_elf_sym_search(vaddr_t off, db_strategy_t strategy, db_expr_t *diffp)
|
|||
if (symp->st_name == 0)
|
||||
continue;
|
||||
#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 &&
|
||||
ELF_SYM_TYPE(symp->st_info) != Elf_estt_func)
|
||||
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 $ */
|
||||
|
||||
/*
|
||||
|
@ -61,6 +61,8 @@ void db_show_all_pools(db_expr_t, int, db_expr_t, char *);
|
|||
|
||||
/* kern/uipc_mbuf.c */
|
||||
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 */
|
||||
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 Jordan Hargrave <jordan@openbsd.org>
|
||||
|
@ -3249,7 +3249,6 @@ acpi_foundhid(struct aml_node *node, void *arg)
|
|||
aaa.aaa_node = node->parent;
|
||||
aaa.aaa_dev = dev;
|
||||
aaa.aaa_cdev = cdev;
|
||||
acpi_parse_crs(sc, &aaa);
|
||||
|
||||
#ifndef SMALL_KERNEL
|
||||
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"))
|
||||
return (0);
|
||||
|
||||
acpi_parse_crs(sc, &aaa);
|
||||
|
||||
aaa.aaa_dmat = acpi_iommu_device_map(node->parent, aaa.aaa_dmat);
|
||||
|
||||
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>
|
||||
|
@ -215,7 +215,7 @@ aibs_attach_sif(struct aibs_softc *sc, enum sensor_type st)
|
|||
aml_freevalue(&res);
|
||||
return;
|
||||
} 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);
|
||||
#ifdef AIBS_MORE_SENSORS
|
||||
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>
|
||||
|
@ -418,7 +418,7 @@ atascsi_probe(struct scsi_link *link)
|
|||
xa->pmp_port = ap->ap_pmp_port;
|
||||
xa->atascsi_private = &ahp->ahp_iopool;
|
||||
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);
|
||||
error:
|
||||
|
@ -1797,7 +1797,7 @@ ata_polled(struct ata_xfer *xa)
|
|||
int rv;
|
||||
|
||||
if (!ISSET(xa->flags, ATA_F_DONE))
|
||||
panic("ata_polled: xa isnt complete");
|
||||
panic("ata_polled: xa isn't complete");
|
||||
|
||||
switch (xa->state) {
|
||||
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 $ */
|
||||
|
||||
/*
|
||||
|
@ -36,7 +36,7 @@
|
|||
/* 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
|
||||
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
|
||||
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.
|
||||
|
|
|
@ -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>
|
||||
|
@ -657,7 +657,7 @@ iic_probe_sensor(struct device *self, u_int8_t addr)
|
|||
(iicprobe(0x03) & 0x3f) == 0x00 && iicprobe(0x04) <= 0x08)
|
||||
/*
|
||||
* 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
|
||||
* (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