Merge pull request #1542 from pi-hole/development

Release v5.22
This commit is contained in:
Adam Warner 2023-03-22 21:21:35 +00:00 committed by GitHub
commit eb1978910d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
29 changed files with 4987 additions and 1930 deletions

View File

@ -1,4 +0,0 @@
ede
edn
nd
tre

4
.github/.codespellignore vendored Normal file
View File

@ -0,0 +1,4 @@
ssudo
tre
ede
nd

View File

@ -24,7 +24,7 @@ jobs:
steps:
-
name: Checkout code
uses: actions/checkout@v3.3.0
uses: actions/checkout@v3.4.0
-
name: "Calculate required variables"
id: variables
@ -53,7 +53,7 @@ jobs:
needs: smoke-tests
container: ghcr.io/pi-hole/ftl-build:v1.23-${{ matrix.arch }}
container: ghcr.io/pi-hole/ftl-build:v1.26-${{ matrix.arch }}
strategy:
fail-fast: false
@ -81,6 +81,8 @@ jobs:
bin_name: pihole-FTL-armv8-linux-gnueabihf
- arch: aarch64
bin_name: pihole-FTL-aarch64-linux-gnu
- arch: riscv64
bin_name: pihole-FTL-riscv64-linux-gnu
env:
CI_ARCH: ${{ matrix.arch }}${{ matrix.arch_extra }}
@ -88,7 +90,7 @@ jobs:
steps:
-
name: Checkout code
uses: actions/checkout@v3.3.0
uses: actions/checkout@v3.4.0
-
name: "Fix ownership of repository"
run: chown -R root .
@ -131,7 +133,7 @@ jobs:
steps:
-
name: Checkout code
uses: actions/checkout@v3.3.0
uses: actions/checkout@v3.4.0
-
name: Get Binaries built in previous jobs
uses: actions/download-artifact@v3.0.2

View File

@ -10,10 +10,10 @@ jobs:
steps:
-
name: Checkout repository
uses: actions/checkout@v3.3.0
uses: actions/checkout@v3.4.0
-
name: Spell-Checking
uses: codespell-project/actions-codespell@master
with:
ignore_words_file: .codespellignore
skip: ./src/database/sqlite3.c,./src/database/sqlite3.h,./src/database/shell.c,./src/lua,./src/dnsmasq,./src/tre-regex
ignore_words_file: .github/.codespellignore
skip: ./src/database/sqlite3.c,./src/database/sqlite3.h,./src/database/shell.c,./src/lua,./src/dnsmasq,./src/tre-regex,./.git,./test/libs

View File

@ -11,7 +11,7 @@ jobs:
name: Syncing branches
steps:
- name: Checkout
uses: actions/checkout@v3.3.0
uses: actions/checkout@v3.4.0
- name: Opening pull request
run: gh pr create -B development -H master --title 'Sync master back into development' --body 'Created by Github action' --label 'internal'
env:

View File

@ -11,6 +11,6 @@
cmake_minimum_required(VERSION 2.8.12)
project(PIHOLE_FTL C)
set(DNSMASQ_VERSION pi-hole-v2.89)
set(DNSMASQ_VERSION pi-hole-v2.89-9461807)
add_subdirectory(src)

View File

@ -47,6 +47,7 @@ static sqlite3 *gravity_db = NULL;
static sqlite3_stmt* table_stmt = NULL;
static sqlite3_stmt* auditlist_stmt = NULL;
bool gravityDB_opened = false;
static bool gravity_abp_format = false;
// Table names corresponding to the enum defined in gravity-db.h
static const char* tablename[] = { "vw_gravity", "vw_blacklist", "vw_whitelist", "vw_regex_blacklist", "vw_regex_whitelist" , "" };
@ -95,6 +96,40 @@ void gravityDB_forked(void)
gravityDB_open();
}
static void gravity_check_ABP_format(void)
{
// Check if we have a valid ABP format
// We do this by checking the "abp_domains" property in the "info" table
// Prepare statement
sqlite3_stmt *stmt = NULL;
int rc = sqlite3_prepare_v2(gravity_db,
"SELECT value FROM info WHERE property = 'abp_domains';",
-1, &stmt, NULL);
if( rc != SQLITE_OK )
{
logg("gravity_check_ABP_format() - SQL error prepare: %s", sqlite3_errstr(rc));
return;
}
// Execute statement
rc = sqlite3_step(stmt);
if( rc != SQLITE_ROW )
{
// No result
gravity_abp_format = false;
sqlite3_finalize(stmt);
return;
}
// Get result (SQLite3 stores 1 for TRUE, 0 for FALSE)
gravity_abp_format = sqlite3_column_int(stmt, 0) != 0;
// Finalize statement
sqlite3_finalize(stmt);
}
// Open gravity database
bool gravityDB_open(void)
{
@ -194,6 +229,10 @@ bool gravityDB_open(void)
logg("gravityDB_open() - Cannot set busy handler: %s", sqlite3_errstr(rc));
}
// Check (and remember in global variable) if there are any ABP-style
// entries in the database
gravity_check_ABP_format();
if(config.debug & DEBUG_DATABASE)
logg("gravityDB_open(): Successfully opened gravity.db");
return true;
@ -1290,7 +1329,102 @@ enum db_result in_gravity(const char *domain, clientsData *client)
if(stmt == NULL)
stmt = gravity_stmt->get(gravity_stmt, client->id);
return domain_in_list(domain, stmt, "gravity", NULL);
// Check if domain is exactly in gravity list
const enum db_result exact_match = domain_in_list(domain, stmt, "gravity", NULL);
if(config.debug & DEBUG_QUERIES)
logg("Checking if \"%s\" is in gravity: %s",
domain, exact_match == FOUND ? "yes" : "no");
// Return for anything else than "not found" (e.g. "found" or "list not available")
if(exact_match != NOT_FOUND)
return exact_match;
// Return early if we are not supposed to check for ABP-style regex
// matches. This needs to be enabled in the config file as it is
// computationally expensive and not needed in most cases (HOSTS lists).
if(!gravity_abp_format)
return NOT_FOUND;
// Make a copy of the domain we will slowly truncate
// while extracting the individual components below
char *domainBuf = strdup(domain);
// Buffer to hold the constructed (sub)domain in ABP format
char *abpDomain = calloc(strlen(domain) + 4, sizeof(char));
// Prime abp matcher with minimal content
strcpy(abpDomain, "||^");
// Get number of domain parts (equals the number of dots + 1)
unsigned int N = 1u;
for(const char *p = domain; *p != '\0'; p++)
if(*p == '.')
N++;
// Loop over domain parts, building matcher from the TLD
// going down into domain and subdomains one by one
while(N-- > 0)
{
// Get domain to the *last* occurrence of '.'
char *ptr = strrchr(domainBuf, '.');
// If there are no '.' left in the domain buffer, we use the
// remainder which is the left-most domain component
if(ptr == NULL)
ptr = domainBuf;
// Get size of this component...
const size_t component_size = strlen(ptr);
// ... and use it to create a "gap" of the right size in our ABP
// format buffer
// Insert the domain component into the gap
if(ptr[0] == '.')
{
// If the component starts with a dot, we need
// to skip it when copying it into the ABP buffer
// Move excluding initial "||" but including final \0 (strlen-2+1 = strlen-1)
memmove(abpDomain+2+component_size-1, abpDomain+2, strlen(abpDomain)-1);
// Copy component bytes (excl. trailing null-byte)
memcpy(abpDomain+2, ptr+1, component_size-1);
}
else
{
// Otherwise, we copy the component as-is
memmove(abpDomain+2+component_size, abpDomain+2, strlen(abpDomain)-1);
// Copy component bytes (excl. trailing null-byte)
memcpy(abpDomain+2, ptr, component_size);
}
// Check if the constructed ABP-style domain is in the gravity list
const enum db_result abp_match = domain_in_list(abpDomain, stmt, "gravity", NULL);
if(config.debug & DEBUG_QUERIES)
logg("Checking if \"%s\" is in gravity: %s",
abpDomain, abp_match == FOUND ? "yes" : "no");
// Return for anything else than "not found" (e.g. "found" or "list not available")
if(abp_match != NOT_FOUND)
{
free(domainBuf);
free(abpDomain);
return abp_match;
}
// Truncate the domain buffer to the left of the
// last dot, effectively removing the last component
const ssize_t truncate_pos = strlen(domainBuf)-component_size;
if(truncate_pos < 1)
// This was already the last iteration
break;
// Put a null-byte at the truncation position
domainBuf[truncate_pos] = '\0';
// Move the ABP buffer to the right by one byte ...
memmove(abpDomain+3, abpDomain+2, strlen(abpDomain));
// ... and insert '.' for the next iteration
abpDomain[2] = '.';
}
free(domainBuf);
free(abpDomain);
// Domain not found in gravity list
return NOT_FOUND;
}
enum db_result in_blacklist(const char *domain, DNSCacheData *dns_cache, clientsData *client)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -146,9 +146,9 @@ extern "C" {
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
#define SQLITE_VERSION "3.40.0"
#define SQLITE_VERSION_NUMBER 3040000
#define SQLITE_SOURCE_ID "2022-11-16 12:10:08 89c459e766ea7e9165d0beeb124708b955a4950d0f4792f457465d71b158d318"
#define SQLITE_VERSION "3.41.1"
#define SQLITE_VERSION_NUMBER 3041001
#define SQLITE_SOURCE_ID "2023-03-10 12:13:52 20399f3eda5ec249d147ba9e48da6e87f969d7966a9a896764ca437ff7e737ff"
/*
** CAPI3REF: Run-Time Library Version Numbers
@ -563,6 +563,7 @@ SQLITE_API int sqlite3_exec(
#define SQLITE_CONSTRAINT_DATATYPE (SQLITE_CONSTRAINT |(12<<8))
#define SQLITE_NOTICE_RECOVER_WAL (SQLITE_NOTICE | (1<<8))
#define SQLITE_NOTICE_RECOVER_ROLLBACK (SQLITE_NOTICE | (2<<8))
#define SQLITE_NOTICE_RBU (SQLITE_NOTICE | (3<<8))
#define SQLITE_WARNING_AUTOINDEX (SQLITE_WARNING | (1<<8))
#define SQLITE_AUTH_USER (SQLITE_AUTH | (1<<8))
#define SQLITE_OK_LOAD_PERMANENTLY (SQLITE_OK | (1<<8))
@ -1175,7 +1176,6 @@ struct sqlite3_io_methods {
** in wal mode after the client has finished copying pages from the wal
** file to the database file, but before the *-shm file is updated to
** record the fact that the pages have been checkpointed.
** </ul>
**
** <li>[[SQLITE_FCNTL_EXTERNAL_READER]]
** The EXPERIMENTAL [SQLITE_FCNTL_EXTERNAL_READER] opcode is used to detect
@ -1188,10 +1188,16 @@ struct sqlite3_io_methods {
** the database is not a wal-mode db, or if there is no such connection in any
** other process. This opcode cannot be used to detect transactions opened
** by clients within the current process, only within other processes.
** </ul>
**
** <li>[[SQLITE_FCNTL_CKSM_FILE]]
** Used by the cksmvfs VFS module only.
** The [SQLITE_FCNTL_CKSM_FILE] opcode is for use interally by the
** [checksum VFS shim] only.
**
** <li>[[SQLITE_FCNTL_RESET_CACHE]]
** If there is currently no transaction open on the database, and the
** database is not a temp db, then the [SQLITE_FCNTL_RESET_CACHE] file-control
** purges the contents of the in-memory page cache. If there is an open
** transaction, or if the db is a temp-db, this opcode is a no-op, not an error.
** </ul>
*/
#define SQLITE_FCNTL_LOCKSTATE 1
@ -1234,6 +1240,7 @@ struct sqlite3_io_methods {
#define SQLITE_FCNTL_CKPT_START 39
#define SQLITE_FCNTL_EXTERNAL_READER 40
#define SQLITE_FCNTL_CKSM_FILE 41
#define SQLITE_FCNTL_RESET_CACHE 42
/* deprecated names */
#define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE
@ -2177,7 +2184,7 @@ struct sqlite3_mem_methods {
** configuration for a database connection can only be changed when that
** connection is not currently using lookaside memory, or in other words
** when the "current value" returned by
** [sqlite3_db_status](D,[SQLITE_CONFIG_LOOKASIDE],...) is zero.
** [sqlite3_db_status](D,[SQLITE_DBSTATUS_LOOKASIDE_USED],...) is zero.
** Any attempt to change the lookaside memory configuration when lookaside
** memory is in use leaves the configuration unchanged and returns
** [SQLITE_BUSY].)^</dd>
@ -2327,8 +2334,12 @@ struct sqlite3_mem_methods {
** <li> sqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 0, 0);
** </ol>
** Because resetting a database is destructive and irreversible, the
** process requires the use of this obscure API and multiple steps to help
** ensure that it does not happen by accident.
** process requires the use of this obscure API and multiple steps to
** help ensure that it does not happen by accident. Because this
** feature must be capable of resetting corrupt databases, and
** shutting down virtual tables may require access to that corrupt
** storage, the library must abandon any installed virtual tables
** without calling their xDestroy() methods.
**
** [[SQLITE_DBCONFIG_DEFENSIVE]] <dt>SQLITE_DBCONFIG_DEFENSIVE</dt>
** <dd>The SQLITE_DBCONFIG_DEFENSIVE option activates or deactivates the
@ -2667,8 +2678,12 @@ SQLITE_API sqlite3_int64 sqlite3_total_changes64(sqlite3*);
** ^A call to sqlite3_interrupt(D) that occurs when there are no running
** SQL statements is a no-op and has no effect on SQL statements
** that are started after the sqlite3_interrupt() call returns.
**
** ^The [sqlite3_is_interrupted(D)] interface can be used to determine whether
** or not an interrupt is currently in effect for [database connection] D.
*/
SQLITE_API void sqlite3_interrupt(sqlite3*);
SQLITE_API int sqlite3_is_interrupted(sqlite3*);
/*
** CAPI3REF: Determine If An SQL Statement Is Complete
@ -3286,8 +3301,8 @@ SQLITE_API SQLITE_DEPRECATED void *sqlite3_profile(sqlite3*,
** <dd>^An SQLITE_TRACE_PROFILE callback provides approximately the same
** information as is provided by the [sqlite3_profile()] callback.
** ^The P argument is a pointer to the [prepared statement] and the
** X argument points to a 64-bit integer which is the estimated of
** the number of nanosecond that the prepared statement took to run.
** X argument points to a 64-bit integer which is approximately
** the number of nanoseconds that the prepared statement took to run.
** ^The SQLITE_TRACE_PROFILE callback is invoked when the statement finishes.
**
** [[SQLITE_TRACE_ROW]] <dt>SQLITE_TRACE_ROW</dt>
@ -3350,7 +3365,7 @@ SQLITE_API int sqlite3_trace_v2(
**
** ^The sqlite3_progress_handler(D,N,X,P) interface causes the callback
** function X to be invoked periodically during long running calls to
** [sqlite3_exec()], [sqlite3_step()] and [sqlite3_get_table()] for
** [sqlite3_step()] and [sqlite3_prepare()] and similar for
** database connection D. An example use for this
** interface is to keep a GUI updated during a large query.
**
@ -3375,6 +3390,13 @@ SQLITE_API int sqlite3_trace_v2(
** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their
** database connections for the meaning of "modify" in this paragraph.
**
** The progress handler callback would originally only be invoked from the
** bytecode engine. It still might be invoked during [sqlite3_prepare()]
** and similar because those routines might force a reparse of the schema
** which involves running the bytecode engine. However, beginning with
** SQLite version 3.41.0, the progress handler callback might also be
** invoked directly from [sqlite3_prepare()] while analyzing and generating
** code for complex queries.
*/
SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
@ -3411,13 +3433,18 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
**
** <dl>
** ^(<dt>[SQLITE_OPEN_READONLY]</dt>
** <dd>The database is opened in read-only mode. If the database does not
** already exist, an error is returned.</dd>)^
** <dd>The database is opened in read-only mode. If the database does
** not already exist, an error is returned.</dd>)^
**
** ^(<dt>[SQLITE_OPEN_READWRITE]</dt>
** <dd>The database is opened for reading and writing if possible, or reading
** only if the file is write protected by the operating system. In either
** case the database must already exist, otherwise an error is returned.</dd>)^
** <dd>The database is opened for reading and writing if possible, or
** reading only if the file is write protected by the operating
** system. In either case the database must already exist, otherwise
** an error is returned. For historical reasons, if opening in
** read-write mode fails due to OS-level permissions, an attempt is
** made to open it in read-only mode. [sqlite3_db_readonly()] can be
** used to determine whether the database is actually
** read-write.</dd>)^
**
** ^(<dt>[SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE]</dt>
** <dd>The database is opened for reading and writing, and is created if
@ -5398,10 +5425,21 @@ SQLITE_API int sqlite3_create_window_function(
** from top-level SQL, and cannot be used in VIEWs or TRIGGERs nor in
** schema structures such as [CHECK constraints], [DEFAULT clauses],
** [expression indexes], [partial indexes], or [generated columns].
** The SQLITE_DIRECTONLY flags is a security feature which is recommended
** for all [application-defined SQL functions], and especially for functions
** that have side-effects or that could potentially leak sensitive
** information.
** <p>
** The SQLITE_DIRECTONLY flag is recommended for any
** [application-defined SQL function]
** that has side-effects or that could potentially leak sensitive information.
** This will prevent attacks in which an application is tricked
** into using a database file that has had its schema surreptiously
** modified to invoke the application-defined function in ways that are
** harmful.
** <p>
** Some people say it is good practice to set SQLITE_DIRECTONLY on all
** [application-defined SQL functions], regardless of whether or not they
** are security sensitive, as doing so prevents those functions from being used
** inside of the database schema, and thus ensures that the database
** can be inspected and modified using generic tools (such as the [CLI])
** that do not have access to the application-defined functions.
** </dd>
**
** [[SQLITE_INNOCUOUS]] <dt>SQLITE_INNOCUOUS</dt><dd>
@ -5542,16 +5580,6 @@ SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int6
** then the conversion is performed. Otherwise no conversion occurs.
** The [SQLITE_INTEGER | datatype] after conversion is returned.)^
**
** ^(The sqlite3_value_encoding(X) interface returns one of [SQLITE_UTF8],
** [SQLITE_UTF16BE], or [SQLITE_UTF16LE] according to the current encoding
** of the value X, assuming that X has type TEXT.)^ If sqlite3_value_type(X)
** returns something other than SQLITE_TEXT, then the return value from
** sqlite3_value_encoding(X) is meaningless. ^Calls to
** sqlite3_value_text(X), sqlite3_value_text16(X), sqlite3_value_text16be(X),
** sqlite3_value_text16le(X), sqlite3_value_bytes(X), or
** sqlite3_value_bytes16(X) might change the encoding of the value X and
** thus change the return from subsequent calls to sqlite3_value_encoding(X).
**
** ^Within the [xUpdate] method of a [virtual table], the
** sqlite3_value_nochange(X) interface returns true if and only if
** the column corresponding to X is unchanged by the UPDATE operation
@ -5616,6 +5644,27 @@ SQLITE_API int sqlite3_value_type(sqlite3_value*);
SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*);
SQLITE_API int sqlite3_value_nochange(sqlite3_value*);
SQLITE_API int sqlite3_value_frombind(sqlite3_value*);
/*
** CAPI3REF: Report the internal text encoding state of an sqlite3_value object
** METHOD: sqlite3_value
**
** ^(The sqlite3_value_encoding(X) interface returns one of [SQLITE_UTF8],
** [SQLITE_UTF16BE], or [SQLITE_UTF16LE] according to the current text encoding
** of the value X, assuming that X has type TEXT.)^ If sqlite3_value_type(X)
** returns something other than SQLITE_TEXT, then the return value from
** sqlite3_value_encoding(X) is meaningless. ^Calls to
** [sqlite3_value_text(X)], [sqlite3_value_text16(X)], [sqlite3_value_text16be(X)],
** [sqlite3_value_text16le(X)], [sqlite3_value_bytes(X)], or
** [sqlite3_value_bytes16(X)] might change the encoding of the value X and
** thus change the return from subsequent calls to sqlite3_value_encoding(X).
**
** This routine is intended for used by applications that test and validate
** the SQLite implementation. This routine is inquiring about the opaque
** internal state of an [sqlite3_value] object. Ordinary applications should
** not need to know what the internal state of an sqlite3_value object is and
** hence should not need to use this interface.
*/
SQLITE_API int sqlite3_value_encoding(sqlite3_value*);
/*
@ -6996,15 +7045,6 @@ SQLITE_API int sqlite3_cancel_auto_extension(void(*xEntryPoint)(void));
*/
SQLITE_API void sqlite3_reset_auto_extension(void);
/*
** The interface to the virtual-table mechanism is currently considered
** to be experimental. The interface might change in incompatible ways.
** If this is a problem for you, do not use the interface at this time.
**
** When the virtual-table mechanism stabilizes, we will declare the
** interface fixed, support it indefinitely, and remove this comment.
*/
/*
** Structures used by the virtual table interface
*/
@ -7123,10 +7163,10 @@ struct sqlite3_module {
** when the omit flag is true there is no guarantee that the constraint will
** not be checked again using byte code.)^
**
** ^The idxNum and idxPtr values are recorded and passed into the
** ^The idxNum and idxStr values are recorded and passed into the
** [xFilter] method.
** ^[sqlite3_free()] is used to free idxPtr if and only if
** needToFreeIdxPtr is true.
** ^[sqlite3_free()] is used to free idxStr if and only if
** needToFreeIdxStr is true.
**
** ^The orderByConsumed means that output from [xFilter]/[xNext] will occur in
** the correct order to satisfy the ORDER BY clause so that no separate
@ -7246,7 +7286,7 @@ struct sqlite3_index_info {
** the [sqlite3_vtab_collation()] interface. For most real-world virtual
** tables, the collating sequence of constraints does not matter (for example
** because the constraints are numeric) and so the sqlite3_vtab_collation()
** interface is no commonly needed.
** interface is not commonly needed.
*/
#define SQLITE_INDEX_CONSTRAINT_EQ 2
#define SQLITE_INDEX_CONSTRAINT_GT 4
@ -7405,16 +7445,6 @@ SQLITE_API int sqlite3_declare_vtab(sqlite3*, const char *zSQL);
*/
SQLITE_API int sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg);
/*
** The interface to the virtual-table mechanism defined above (back up
** to a comment remarkably similar to this one) is currently considered
** to be experimental. The interface might change in incompatible ways.
** If this is a problem for you, do not use the interface at this time.
**
** When the virtual-table mechanism stabilizes, we will declare the
** interface fixed, support it indefinitely, and remove this comment.
*/
/*
** CAPI3REF: A Handle To An Open BLOB
** KEYWORDS: {BLOB handle} {BLOB handles}
@ -9618,7 +9648,7 @@ SQLITE_API int sqlite3_vtab_nochange(sqlite3_context*);
** <li><p> Otherwise, "BINARY" is returned.
** </ol>
*/
SQLITE_API SQLITE_EXPERIMENTAL const char *sqlite3_vtab_collation(sqlite3_index_info*,int);
SQLITE_API const char *sqlite3_vtab_collation(sqlite3_index_info*,int);
/*
** CAPI3REF: Determine if a virtual table query is DISTINCT
@ -9775,21 +9805,20 @@ SQLITE_API int sqlite3_vtab_in(sqlite3_index_info*, int iCons, int bHandle);
** is undefined and probably harmful.
**
** The X parameter in a call to sqlite3_vtab_in_first(X,P) or
** sqlite3_vtab_in_next(X,P) must be one of the parameters to the
** sqlite3_vtab_in_next(X,P) should be one of the parameters to the
** xFilter method which invokes these routines, and specifically
** a parameter that was previously selected for all-at-once IN constraint
** processing use the [sqlite3_vtab_in()] interface in the
** [xBestIndex|xBestIndex method]. ^(If the X parameter is not
** an xFilter argument that was selected for all-at-once IN constraint
** processing, then these routines return [SQLITE_MISUSE])^ or perhaps
** exhibit some other undefined or harmful behavior.
** processing, then these routines return [SQLITE_ERROR].)^
**
** ^(Use these routines to access all values on the right-hand side
** of the IN constraint using code like the following:
**
** <blockquote><pre>
** &nbsp; for(rc=sqlite3_vtab_in_first(pList, &pVal);
** &nbsp; rc==SQLITE_OK && pVal
** &nbsp; rc==SQLITE_OK && pVal;
** &nbsp; rc=sqlite3_vtab_in_next(pList, &pVal)
** &nbsp; ){
** &nbsp; // do something with pVal
@ -9887,6 +9916,10 @@ SQLITE_API int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value **
** managed by the prepared statement S and will be automatically freed when
** S is finalized.
**
** Not all values are available for all query elements. When a value is
** not available, the output variable is set to -1 if the value is numeric,
** or to NULL if it is a string (SQLITE_SCANSTAT_NAME).
**
** <dl>
** [[SQLITE_SCANSTAT_NLOOP]] <dt>SQLITE_SCANSTAT_NLOOP</dt>
** <dd>^The [sqlite3_int64] variable pointed to by the V parameter will be
@ -9914,12 +9947,24 @@ SQLITE_API int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value **
** to a zero-terminated UTF-8 string containing the [EXPLAIN QUERY PLAN]
** description for the X-th loop.
**
** [[SQLITE_SCANSTAT_SELECTID]] <dt>SQLITE_SCANSTAT_SELECT</dt>
** [[SQLITE_SCANSTAT_SELECTID]] <dt>SQLITE_SCANSTAT_SELECTID</dt>
** <dd>^The "int" variable pointed to by the V parameter will be set to the
** "select-id" for the X-th loop. The select-id identifies which query or
** subquery the loop is part of. The main query has a select-id of zero.
** The select-id is the same value as is output in the first column
** of an [EXPLAIN QUERY PLAN] query.
** id for the X-th query plan element. The id value is unique within the
** statement. The select-id is the same value as is output in the first
** column of an [EXPLAIN QUERY PLAN] query.
**
** [[SQLITE_SCANSTAT_PARENTID]] <dt>SQLITE_SCANSTAT_PARENTID</dt>
** <dd>The "int" variable pointed to by the V parameter will be set to the
** the id of the parent of the current query element, if applicable, or
** to zero if the query element has no parent. This is the same value as
** returned in the second column of an [EXPLAIN QUERY PLAN] query.
**
** [[SQLITE_SCANSTAT_NCYCLE]] <dt>SQLITE_SCANSTAT_NCYCLE</dt>
** <dd>The sqlite3_int64 output value is set to the number of cycles,
** according to the processor time-stamp counter, that elapsed while the
** query element was being processed. This value is not available for
** all query elements - if it is unavailable the output variable is
** set to -1.
** </dl>
*/
#define SQLITE_SCANSTAT_NLOOP 0
@ -9928,12 +9973,14 @@ SQLITE_API int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value **
#define SQLITE_SCANSTAT_NAME 3
#define SQLITE_SCANSTAT_EXPLAIN 4
#define SQLITE_SCANSTAT_SELECTID 5
#define SQLITE_SCANSTAT_PARENTID 6
#define SQLITE_SCANSTAT_NCYCLE 7
/*
** CAPI3REF: Prepared Statement Scan Status
** METHOD: sqlite3_stmt
**
** This interface returns information about the predicted and measured
** These interfaces return information about the predicted and measured
** performance for pStmt. Advanced applications can use this
** interface to compare the predicted and the measured performance and
** issue warnings and/or rerun [ANALYZE] if discrepancies are found.
@ -9944,19 +9991,25 @@ SQLITE_API int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value **
**
** The "iScanStatusOp" parameter determines which status information to return.
** The "iScanStatusOp" must be one of the [scanstatus options] or the behavior
** of this interface is undefined.
** ^The requested measurement is written into a variable pointed to by
** the "pOut" parameter.
** Parameter "idx" identifies the specific loop to retrieve statistics for.
** Loops are numbered starting from zero. ^If idx is out of range - less than
** zero or greater than or equal to the total number of loops used to implement
** the statement - a non-zero value is returned and the variable that pOut
** points to is unchanged.
** of this interface is undefined. ^The requested measurement is written into
** a variable pointed to by the "pOut" parameter.
**
** ^Statistics might not be available for all loops in all statements. ^In cases
** where there exist loops with no available statistics, this function behaves
** as if the loop did not exist - it returns non-zero and leave the variable
** that pOut points to unchanged.
** The "flags" parameter must be passed a mask of flags. At present only
** one flag is defined - SQLITE_SCANSTAT_COMPLEX. If SQLITE_SCANSTAT_COMPLEX
** is specified, then status information is available for all elements
** of a query plan that are reported by "EXPLAIN QUERY PLAN" output. If
** SQLITE_SCANSTAT_COMPLEX is not specified, then only query plan elements
** that correspond to query loops (the "SCAN..." and "SEARCH..." elements of
** the EXPLAIN QUERY PLAN output) are available. Invoking API
** sqlite3_stmt_scanstatus() is equivalent to calling
** sqlite3_stmt_scanstatus_v2() with a zeroed flags parameter.
**
** Parameter "idx" identifies the specific query element to retrieve statistics
** for. Query elements are numbered starting from zero. A value of -1 may be
** to query for statistics regarding the entire query. ^If idx is out of range
** - less than -1 or greater than or equal to the total number of query
** elements used to implement the statement - a non-zero value is returned and
** the variable that pOut points to is unchanged.
**
** See also: [sqlite3_stmt_scanstatus_reset()]
*/
@ -9966,6 +10019,19 @@ SQLITE_API int sqlite3_stmt_scanstatus(
int iScanStatusOp, /* Information desired. SQLITE_SCANSTAT_* */
void *pOut /* Result written here */
);
SQLITE_API int sqlite3_stmt_scanstatus_v2(
sqlite3_stmt *pStmt, /* Prepared statement for which info desired */
int idx, /* Index of loop to report on */
int iScanStatusOp, /* Information desired. SQLITE_SCANSTAT_* */
int flags, /* Mask of flags defined below */
void *pOut /* Result written here */
);
/*
** CAPI3REF: Prepared Statement Scan Status
** KEYWORDS: {scan status flags}
*/
#define SQLITE_SCANSTAT_COMPLEX 0x0001
/*
** CAPI3REF: Zero Scan-Status Counters
@ -10056,6 +10122,10 @@ SQLITE_API int sqlite3_db_cacheflush(sqlite3*);
** function is not defined for operations on WITHOUT ROWID tables, or for
** DELETE operations on rowid tables.
**
** ^The sqlite3_preupdate_hook(D,C,P) function returns the P argument from
** the previous call on the same [database connection] D, or NULL for
** the first call on D.
**
** The [sqlite3_preupdate_old()], [sqlite3_preupdate_new()],
** [sqlite3_preupdate_count()], and [sqlite3_preupdate_depth()] interfaces
** provide additional information about a preupdate event. These routines
@ -10461,6 +10531,19 @@ SQLITE_API int sqlite3_deserialize(
# undef double
#endif
#if defined(__wasi__)
# undef SQLITE_WASI
# define SQLITE_WASI 1
# undef SQLITE_OMIT_WAL
# define SQLITE_OMIT_WAL 1/* because it requires shared memory APIs */
# ifndef SQLITE_OMIT_LOAD_EXTENSION
# define SQLITE_OMIT_LOAD_EXTENSION
# endif
# ifndef SQLITE_THREADSAFE
# define SQLITE_THREADSAFE 0
# endif
#endif
#ifdef __cplusplus
} /* End of the 'extern "C"' block */
#endif

View File

@ -19,7 +19,7 @@
#define CHILD_LIFETIME 300 /* secs 'till terminated (RFC1035 suggests > 120s) */
#define TCP_MAX_QUERIES 100 /* Maximum number of queries per incoming TCP connection */
#define TCP_BACKLOG 32 /* kernel backlog limit for TCP connections */
#define EDNS_PKTSZ 4096 /* default max EDNS.0 UDP packet from RFC5625 */
#define EDNS_PKTSZ 1232 /* default max EDNS.0 UDP packet from from /dnsflagday.net/2020 */
#define SAFE_PKTSZ 1232 /* "go anywhere" UDP packet size, see https://dnsflagday.net/2020/ */
#define KEYBLOCK_LEN 40 /* choose to minimise fragmentation when storing DNSSEC keys */
#define DNSSEC_WORK 50 /* Max number of queries to validate one question */

View File

@ -52,6 +52,12 @@ const char* introspection_xml_template =
" <method name=\"SetFilterWin2KOption\">\n"
" <arg name=\"filterwin2k\" direction=\"in\" type=\"b\"/>\n"
" </method>\n"
" <method name=\"SetFilterA\">\n"
" <arg name=\"filter-a\" direction=\"in\" type=\"b\"/>\n"
" </method>\n"
" <method name=\"SetFilterAAAA\">\n"
" <arg name=\"filter-aaaa\" direction=\"in\" type=\"b\"/>\n"
" </method>\n"
" <method name=\"SetLocaliseQueriesOption\">\n"
" <arg name=\"localise-queries\" direction=\"in\" type=\"b\"/>\n"
" </method>\n"
@ -817,6 +823,14 @@ DBusHandlerResult message_handler(DBusConnection *connection,
{
reply = dbus_set_bool(message, OPT_FILTER, "filterwin2k");
}
else if (strcmp(method, "SetFilterA") == 0)
{
reply = dbus_set_bool(message, OPT_FILTER_A, "filter-A");
}
else if (strcmp(method, "SetFilterAAAA") == 0)
{
reply = dbus_set_bool(message, OPT_FILTER_AAAA, "filter-AAAA");
}
else if (strcmp(method, "SetLocaliseQueriesOption") == 0)
{
reply = dbus_set_bool(message, OPT_LOCALISE, "localise-queries");

View File

@ -838,7 +838,7 @@ char *option_string(int prot, unsigned int opt, unsigned char *val, int opt_len,
for (i = 0, j = 0; i < opt_len && j < buf_len ; i++)
{
char c = val[i];
if (isprint((int)c))
if (isprint((unsigned char)c))
buf[j++] = c;
}
#ifdef HAVE_DHCP6
@ -852,7 +852,7 @@ char *option_string(int prot, unsigned int opt, unsigned char *val, int opt_len,
for (k = i + 1; k < opt_len && k < l && j < buf_len ; k++)
{
char c = val[k];
if (isprint((int)c))
if (isprint((unsigned char)c))
buf[j++] = c;
}
i = l;
@ -873,7 +873,7 @@ char *option_string(int prot, unsigned int opt, unsigned char *val, int opt_len,
for (k = 0; k < len && j < buf_len; k++)
{
char c = *p++;
if (isprint((int)c))
if (isprint((unsigned char)c))
buf[j++] = c;
}
i += len +2;

View File

@ -916,14 +916,14 @@ void dhcp_read_ethers(void)
lineno++;
while (strlen(buff) > 0 && isspace((int)buff[strlen(buff)-1]))
while (strlen(buff) > 0 && isspace((unsigned char)buff[strlen(buff)-1]))
buff[strlen(buff)-1] = 0;
if ((*buff == '#') || (*buff == '+') || (*buff == 0))
continue;
for (ip = buff; *ip && !isspace((int)*ip); ip++);
for(; *ip && isspace((int)*ip); ip++)
for (ip = buff; *ip && !isspace((unsigned char)*ip); ip++);
for(; *ip && isspace((unsigned char)*ip); ip++)
*ip = 0;
if (!*ip || parse_hex(buff, hwaddr, ETHER_ADDR_LEN, NULL, NULL) != ETHER_ADDR_LEN)
{

View File

@ -253,9 +253,10 @@ int lookup_domain(char *domain, int flags, int *lowout, int *highout)
if (highout)
*highout = nhigh;
if (nlow == nhigh)
/* qlen == -1 when we failed to match even an empty query, if there are no default servers. */
if (nlow == nhigh || qlen == -1)
return 0;
return 1;
}

View File

@ -92,7 +92,7 @@ int detect_loop(char *query, int type)
return 0;
for (i = 0; i < 8; i++)
if (!isxdigit(query[i]))
if (!isxdigit((unsigned char)query[i]))
return 0;
uid = strtol(query, NULL, 16);

View File

@ -361,13 +361,8 @@ static int iface_allowed(struct iface_param *param, int if_index, char *label,
struct in_addr newaddr = addr->in.sin_addr;
if (int_name->flags & INP4)
{
if (netmask.s_addr == 0xffffffff)
continue;
newaddr.s_addr = (addr->in.sin_addr.s_addr & netmask.s_addr) |
(int_name->proto4.s_addr & ~netmask.s_addr);
}
newaddr.s_addr = (addr->in.sin_addr.s_addr & netmask.s_addr) |
(int_name->proto4.s_addr & ~netmask.s_addr);
/* check for duplicates. */
for (lp = int_name->addr; lp; lp = lp->next)
@ -400,10 +395,6 @@ static int iface_allowed(struct iface_param *param, int if_index, char *label,
{
int i;
/* No sense in doing /128. */
if (prefixlen == 128)
continue;
for (i = 0; i < 16; i++)
{
int bits = ((i+1)*8) - prefixlen;

View File

@ -1163,6 +1163,9 @@ static char *domain_rev4(int from_file, char *server, struct in_addr *addr4, int
}
else
{
/* Always reset server as valid here, so we can add the same upstream
server address multiple times for each x.y.z.in-addr.arpa */
sdetails.valid = 1;
while (parse_server_next(&sdetails))
{
if ((string = parse_server_addr(&sdetails)))
@ -1248,6 +1251,9 @@ static char *domain_rev6(int from_file, char *server, struct in6_addr *addr6, in
}
else
{
/* Always reset server as valid here, so we can add the same upstream
server address multiple times for each x.y.z.ip6.arpa */
sdetails.valid = 1;
while (parse_server_next(&sdetails))
{
if ((string = parse_server_addr(&sdetails)))
@ -2755,7 +2761,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
ret_err(gen_err);
for (p = arg; *p; p++)
if (!isxdigit((int)*p))
if (!isxdigit((unsigned char)*p))
ret_err(gen_err);
set_option_bool(OPT_UMBRELLA_DEVID);
@ -4840,7 +4846,7 @@ err:
new->target = target;
new->ttl = ttl;
for (arg += arglen+1; *arg && isspace(*arg); arg++);
for (arg += arglen+1; *arg && isspace((unsigned char)*arg); arg++);
}
break;
@ -5231,7 +5237,7 @@ err:
unhide_metas(keyhex);
/* 4034: "Whitespace is allowed within digits" */
for (cp = keyhex; *cp; )
if (isspace(*cp))
if (isspace((unsigned char)*cp))
for (cp1 = cp; *cp1; cp1++)
*cp1 = *(cp1+1);
else
@ -5319,7 +5325,7 @@ static void read_file(char *file, FILE *f, int hard_opt, int from_script)
memmove(p, p+1, strlen(p+1)+1);
}
if (isspace(*p))
if (isspace((unsigned char)*p))
{
*p = ' ';
white = 1;
@ -5879,12 +5885,10 @@ void read_opts(int argc, char **argv, char *compile_opts)
add_txt("servers.bind", NULL, TXT_STAT_SERVERS);
/* Pi-hole modification */
add_txt("privacylevel.pihole", NULL, TXT_PRIVACYLEVEL);
add_txt("version.FTL", (char*)get_FTL_version(), 0 );
/************************/
}
#endif
/******** Pi-hole modification ********/
add_txt("version.FTL", (char*)get_FTL_version(), 0 );
/**************************************/
/* port might not be known when the address is parsed - fill in here */
if (daemon->servers)

View File

@ -520,7 +520,7 @@ static int print_txt(struct dns_header *header, const size_t qlen, char *name,
/* make counted string zero-term and sanitise */
for (i = 0; i < len; i++)
{
if (!isprint((int)*(p3+1)))
if (!isprint((unsigned char)*(p3+1)))
break;
*p3 = *(p3+1);
p3++;
@ -907,9 +907,8 @@ int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t
{
flags &= ~(F_IPV4 | F_IPV6 | F_SRV);
/* Can store NXDOMAIN reply to CNAME or ANY query. */
if (qtype == T_CNAME || qtype == T_ANY)
insert = 1;
/* Can store NXDOMAIN reply for any qtype. */
insert = 1;
}
log_query(F_UPSTREAM | F_FORWARD | F_NEG | flags | (secure ? F_DNSSECOK : 0), name, NULL, NULL, 0);
@ -2109,7 +2108,22 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
}
if (!ans)
return 0; /* failed to answer a question */
{
/* We may know that the domain doesn't exist for any RRtype. */
if ((crecp = cache_find_by_name(NULL, name, now, F_NXDOMAIN)))
{
ans = nxdomain = 1;
auth = 0;
if (!(crecp->flags & F_DNSSECOK))
sec_data = 0;
if (!dryrun)
log_query(F_NXDOMAIN | F_NEG, name, NULL, NULL, 0);
}
else
return 0; /* failed to answer a question */
}
}
if (dryrun)

View File

@ -1678,7 +1678,7 @@ static int sanitise(unsigned char *opt, char *buf)
for (i = option_len(opt); i > 0; i--)
{
char c = *p++;
if (isprint((int)c))
if (isprint((unsigned char)c))
*buf++ = c;
}
*buf = 0; /* add terminator */

View File

@ -353,7 +353,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, unsigned char *inbu
put_opt6_short(DHCP6USEMULTI);
put_opt6_string("Use multicast");
end_opt6(o1);
return 1;
goto done;
}
/* match vendor and user class options */
@ -1277,12 +1277,14 @@ static int dhcp6_no_relay(struct state *state, int msg_type, unsigned char *inbu
}
log_tags(tagif, state->xid);
done:
/* Fill in the message type. Note that we store the offset,
not a direct pointer, since the packet memory may have been
reallocated. */
((unsigned char *)(daemon->outpacket.iov_base))[start_msg] = outmsgtype;
log_tags(tagif, state->xid);
log6_opts(0, state->xid, daemon->outpacket.iov_base + start_opts, daemon->outpacket.iov_base + save_counter(-1));
return 1;

View File

@ -405,7 +405,7 @@ void tftp_request(struct listener *listen, time_t now)
if (*p == '\\')
*p = '/';
else if (option_bool(OPT_TFTP_LC))
*p = tolower(*p);
*p = tolower((unsigned char)*p);
strcpy(daemon->namebuff, "/");
if (prefix)

View File

@ -21,7 +21,7 @@
// EDNS(0) Client Subnet [Optional, RFC7871]
#define EDNS0_ECS EDNS0_OPTION_CLIENT_SUBNET
// EDN(0) COOKIE [Standard, RFC7873]
// EDNS(0) COOKIE [Standard, RFC7873]
#define EDNS0_COOKIE 10
// EDNS(0) MAC address [NOT STANDARDIZED]

View File

@ -333,13 +333,13 @@ const char __attribute__ ((const)) *get_ordinal_suffix(unsigned int number)
// If the tens digit is not equal to 1, then the following table could be used:
switch (number % 10)
{
case 1: // If the units digit is 1: This is written after the number "st"
case 1: // If the units digit is 1: This is written after the number "1st"
return "st";
case 2: // If the units digit is 2: This is written after the number "nd"
case 2: // If the units digit is 2: This is written after the number "2nd"
return "nd";
case 3: // If the units digit is 3: This is written after the number "rd"
case 3: // If the units digit is 3: This is written after the number "3rd"
return "rd";
default: // If the units digit is 0 or 4-9: This is written after the number "th"
default: // If the units digit is 0 or 4-9: This is written after the number "9th"
return "th";
}
// For example: 2nd, 7th, 20th, 23rd, 52nd, 135th, 301st BUT 311th (covered above)

View File

@ -15,7 +15,7 @@
extern const char *regextype[];
// Use TRE instead of GNU regex library (compiled into FTL itself)
// Use TRE-Engine instead of GNU/MUSL regex libraries
#define USE_TRE_REGEX
#ifdef USE_TRE_REGEX

View File

@ -29,6 +29,9 @@ int check_one_struct(const char *struct_name, const size_t found_size, const siz
#elif defined(__arm__)
const size_t expected_size = size32;
const char *arch = "arm";
#elif defined(__riscv) && __riscv_xlen == 64
const size_t expected_size = size64;
const char *arch = "riscv64";
#else
const size_t expected_size = 0;
const char *arch = NULL;

View File

@ -147,6 +147,12 @@ elif [[ "${CI_ARCH}" == "armv8a" ]]; then
check_CPU_arch "v8"
check_FP_arch "VFPv3-D16"
elif [[ "${CI_ARCH}" == "riscv64" ]]; then
check_machine "ELF64" "RISC-V"
check_libs "[libm.so.6] [libc.so.6] [ld-linux-riscv64-lp64d.so.1]"
check_file "ELF 64-bit LSB pie executable, UCB RISC-V, RVC, double-float ABI, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-riscv64-lp64d.so.1, for GNU/Linux 4.15.0, with debug_info, not stripped"
else
echo "Invalid job ${CI_ARCH}"

View File

@ -220,7 +220,9 @@ INSERT INTO gravity VALUES('whitelisted.ftl',1);
INSERT INTO gravity VALUES('gravity.ftl',1);
INSERT INTO gravity VALUES('gravity-aaaa.ftl',1);
INSERT INTO gravity VALUES('gravity-whitelisted.ftl',1);
INSERT INTO info VALUES('gravity_count',4);
INSERT INTO gravity VALUES('||special.gravity.ftl^',1);
INSERT INTO info VALUES('gravity_count',5);
INSERT INTO info VALUES('abp_domains',1);
INSERT INTO "group" VALUES(1,0,'Test group',1559928803,1559928803,'A disabled test group');
INSERT INTO domainlist_by_group VALUES(15,1);

View File

@ -426,14 +426,25 @@
[[ ${lines[@]} == *"status: SERVFAIL"* ]]
}
@test "ABP-style matching working as expected" {
run bash -c "dig A special.gravity.ftl @127.0.0.1 +short"
printf "%s\n" "${lines[@]}"
[[ ${lines[0]} == "0.0.0.0" ]]
[[ ${lines[1]} == "" ]]
run bash -c "dig A a.b.c.d.special.gravity.ftl @127.0.0.1 +short"
printf "%s\n" "${lines[@]}"
[[ ${lines[0]} == "0.0.0.0" ]]
[[ ${lines[1]} == "" ]]
}
@test "Statistics as expected" {
run bash -c 'echo ">stats >quit" | nc -v 127.0.0.1 4711'
printf "%s\n" "${lines[@]}"
[[ ${lines[1]} == "domains_being_blocked 4" ]]
[[ ${lines[2]} == "dns_queries_today 52" ]]
[[ ${lines[3]} == "ads_blocked_today 13" ]]
[[ ${lines[1]} == "domains_being_blocked 5" ]]
[[ ${lines[2]} == "dns_queries_today 54" ]]
[[ ${lines[3]} == "ads_blocked_today 15" ]]
#[[ ${lines[4]} == "ads_percentage_today 7.792208" ]]
[[ ${lines[5]} == "unique_domains 37" ]]
[[ ${lines[5]} == "unique_domains 39" ]]
[[ ${lines[6]} == "queries_forwarded 27" ]]
[[ ${lines[7]} == "queries_cached 12" ]]
# Clients ever seen is commented out as the CI may have
@ -441,12 +452,12 @@
# number of clients may not work in all cases
#[[ ${lines[8]} == "clients_ever_seen 8" ]]
#[[ ${lines[9]} == "unique_clients 8" ]]
[[ ${lines[10]} == "dns_queries_all_types 52" ]]
[[ ${lines[10]} == "dns_queries_all_types 54" ]]
[[ ${lines[11]} == "reply_UNKNOWN 0" ]]
[[ ${lines[12]} == "reply_NODATA 0" ]]
[[ ${lines[13]} == "reply_NXDOMAIN 1" ]]
[[ ${lines[14]} == "reply_CNAME 7" ]]
[[ ${lines[15]} == "reply_IP 23" ]]
[[ ${lines[15]} == "reply_IP 25" ]]
[[ ${lines[16]} == "reply_DOMAIN 0" ]]
[[ ${lines[17]} == "reply_RRNAME 5" ]]
[[ ${lines[18]} == "reply_SERVFAIL 0" ]]
@ -456,7 +467,7 @@
[[ ${lines[22]} == "reply_DNSSEC 6" ]]
[[ ${lines[23]} == "reply_NONE 0" ]]
[[ ${lines[24]} == "reply_BLOB 10" ]]
[[ ${lines[25]} == "dns_queries_all_replies 52" ]]
[[ ${lines[25]} == "dns_queries_all_replies 54" ]]
[[ ${lines[26]} == "privacy_level 0" ]]
[[ ${lines[27]} == "status enabled" ]]
[[ ${lines[28]} == "" ]]
@ -471,7 +482,7 @@
@test "Top Clients" {
run bash -c 'echo ">top-clients >quit" | nc -v 127.0.0.1 4711'
printf "%s\n" "${lines[@]}"
[[ ${lines[1]} == "0 36 127.0.0.1 "* ]]
[[ ${lines[1]} == "0 38 127.0.0.1 "* ]]
[[ ${lines[2]} == "1 6 :: "* ]]
[[ ${lines[3]} == "2 4 127.0.0.3 "* ]]
[[ ${lines[4]} == "3 3 127.0.0.2 "* ]]
@ -519,12 +530,14 @@
[[ "${lines[@]}" == *" 2 gravity-aaaa.ftl"* ]]
[[ "${lines[@]}" == *" 1 blacklisted.ftl"* ]]
[[ "${lines[@]}" == *" 1 whitelisted.ftl"* ]]
[[ "${lines[@]}" == *" 1 special.gravity.ftl"* ]]
[[ "${lines[@]}" == *" 1 a.b.c.d.special.gravity.ftl"* ]]
[[ "${lines[@]}" == *" 1 regex5.ftl"* ]]
[[ "${lines[@]}" == *" 1 regex1.ftl"* ]]
[[ "${lines[@]}" == *" 1 cname-1.ftl"* ]]
[[ "${lines[@]}" == *" 1 cname-7.ftl"* ]]
[[ "${lines[@]}" == *" 1 use-application-dns.net"* ]]
[[ ${lines[12]} == "" ]]
[[ ${lines[14]} == "" ]]
}
@test "Domain auditing, approved domains are not shown" {
@ -542,33 +555,33 @@
@test "Upstream Destinations reported correctly" {
run bash -c 'echo ">forward-dest >quit" | nc -v 127.0.0.1 4711'
printf "%s\n" "${lines[@]}"
[[ ${lines[1]} == "-3 25.00 blocked blocked" ]]
[[ ${lines[2]} == "-2 23.08 cached cached" ]]
[[ ${lines[1]} == "-3 27.78 blocked blocked" ]]
[[ ${lines[2]} == "-2 22.22 cached cached" ]]
[[ ${lines[3]} == "-1 0.00 other other" ]]
[[ ${lines[4]} == "0 48.08 127.0.0.1#5555 127.0.0.1#5555" ]]
[[ ${lines[5]} == "1 3.85 127.0.0.1#5554 127.0.0.1#5554" ]]
[[ ${lines[4]} == "0 46.30 127.0.0.1#5555 127.0.0.1#5555" ]]
[[ ${lines[5]} == "1 3.70 127.0.0.1#5554 127.0.0.1#5554" ]]
[[ ${lines[6]} == "" ]]
}
@test "Query Types reported correctly" {
run bash -c 'echo ">querytypes >quit" | nc -v 127.0.0.1 4711'
printf "%s\n" "${lines[@]}"
[[ ${lines[1]} == "A (IPv4): 50.00" ]]
[[ ${lines[2]} == "AAAA (IPv6): 7.69" ]]
[[ ${lines[3]} == "ANY: 1.92" ]]
[[ ${lines[4]} == "SRV: 1.92" ]]
[[ ${lines[5]} == "SOA: 1.92" ]]
[[ ${lines[6]} == "PTR: 1.92" ]]
[[ ${lines[7]} == "TXT: 11.54" ]]
[[ ${lines[8]} == "NAPTR: 1.92" ]]
[[ ${lines[9]} == "MX: 1.92" ]]
[[ ${lines[10]} == "DS: 5.77" ]]
[[ ${lines[1]} == "A (IPv4): 51.85" ]]
[[ ${lines[2]} == "AAAA (IPv6): 7.41" ]]
[[ ${lines[3]} == "ANY: 1.85" ]]
[[ ${lines[4]} == "SRV: 1.85" ]]
[[ ${lines[5]} == "SOA: 1.85" ]]
[[ ${lines[6]} == "PTR: 1.85" ]]
[[ ${lines[7]} == "TXT: 11.11" ]]
[[ ${lines[8]} == "NAPTR: 1.85" ]]
[[ ${lines[9]} == "MX: 1.85" ]]
[[ ${lines[10]} == "DS: 5.56" ]]
[[ ${lines[11]} == "RRSIG: 0.00" ]]
[[ ${lines[12]} == "DNSKEY: 5.77" ]]
[[ ${lines[13]} == "NS: 1.92" ]]
[[ ${lines[14]} == "OTHER: 1.92" ]]
[[ ${lines[15]} == "SVCB: 1.92" ]]
[[ ${lines[16]} == "HTTPS: 1.92" ]]
[[ ${lines[12]} == "DNSKEY: 5.56" ]]
[[ ${lines[13]} == "NS: 1.85" ]]
[[ ${lines[14]} == "OTHER: 1.85" ]]
[[ ${lines[15]} == "SVCB: 1.85" ]]
[[ ${lines[16]} == "HTTPS: 1.85" ]]
[[ ${lines[17]} == "" ]]
}
@ -629,7 +642,9 @@
[[ ${lines[50]} == *" DNSKEY dnssec.works :: 2 1 11 "*" N/A -1 127.0.0.1#5555 \"\" \"49\""* ]]
[[ ${lines[51]} == *" A fail01.dnssec.works 127.0.0.1 2 3 4 "*" N/A -1 127.0.0.1#5555 \"RRSIG missing\" \"50\""* ]]
[[ ${lines[52]} == *" DS fail01.dnssec.works :: 2 1 11 "*" N/A -1 127.0.0.1#5555 \"\" \"51\""* ]]
[[ ${lines[53]} == "" ]]
[[ ${lines[53]} == *" A special.gravity.ftl 127.0.0.1 1 2 4 "*" N/A -1 N/A#0 \"\" \"52\""* ]]
[[ ${lines[54]} == *" A a.b.c.d.special.gravity.ftl 127.0.0.1 1 2 4 "*" N/A -1 N/A#0 \"\" \"53\""* ]]
[[ ${lines[55]} == "" ]]
}
@test "Get all queries (domain filtered) shows expected content" {
@ -642,7 +657,7 @@
@test "Recent blocked shows expected content" {
run bash -c 'echo ">recentBlocked >quit" | nc -v 127.0.0.1 4711'
printf "%s\n" "${lines[@]}"
[[ ${lines[1]} == "aaaa-cname.ftl" ]]
[[ ${lines[1]} == "a.b.c.d.special.gravity.ftl" ]]
[[ ${lines[2]} == "" ]]
}