diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 6e21b3f71..2f025b2e1 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -13,6 +13,11 @@ updates: pull-request-branch-name: # Separate sections of the branch name with a hyphen separator: "-" + groups: + github_action-dependencies: + patterns: + - "*" + # As above, but for development-v6 - package-ecosystem: github-actions directory: "/" @@ -27,3 +32,8 @@ updates: pull-request-branch-name: # Separate sections of the branch name with a hyphen separator: "-" + groups: + github_action-dependencies: + patterns: + - "*" + diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 824b16e95..15a935516 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -24,7 +24,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v3.5.2 + uses: actions/checkout@v3.6.0 - name: "Calculate required variables" id: variables @@ -90,7 +90,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v3.5.2 + uses: actions/checkout@v3.6.0 - name: "Fix ownership of repository" run: chown -R root . @@ -121,7 +121,7 @@ jobs: - name: Upload artifacts to job for later processing if: github.event_name != 'pull_request' - uses: actions/upload-artifact@v3.1.2 + uses: actions/upload-artifact@v3.1.3 with: name: tmp-binary-storage path: '${{ matrix.bin_name }}*' @@ -133,7 +133,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v3.5.2 + uses: actions/checkout@v3.6.0 - name: Get Binaries built in previous jobs uses: actions/download-artifact@v3.0.2 diff --git a/.github/workflows/codespell.yml b/.github/workflows/codespell.yml index bf2bcb45d..93529cbb7 100644 --- a/.github/workflows/codespell.yml +++ b/.github/workflows/codespell.yml @@ -10,7 +10,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v3.5.2 + uses: actions/checkout@v3.6.0 - name: Spell-Checking uses: codespell-project/actions-codespell@master diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 1946e5400..35abcc2c0 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -17,7 +17,7 @@ jobs: issues: write steps: - - uses: actions/stale@v8.0.0 + - uses: actions/stale@v9.0.0 with: repo-token: ${{ secrets.GITHUB_TOKEN }} days-before-stale: 30 @@ -40,7 +40,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v3.4.0 + uses: actions/checkout@v3.6.0 - name: Remove 'stale' label run: gh issue edit ${{ github.event.issue.number }} --remove-label ${{ env.stale_label }} env: diff --git a/.github/workflows/stale_pr.yml b/.github/workflows/stale_pr.yml index e9230b2c7..584bc71ef 100644 --- a/.github/workflows/stale_pr.yml +++ b/.github/workflows/stale_pr.yml @@ -17,7 +17,7 @@ jobs: pull-requests: write steps: - - uses: actions/stale@v8.0.0 + - uses: actions/stale@v9.0.0 with: repo-token: ${{ secrets.GITHUB_TOKEN }} # Do not automatically mark PR/issue as stale diff --git a/.github/workflows/sync-back-to-dev.yml b/.github/workflows/sync-back-to-dev.yml index a9e3a1642..62acaabe6 100644 --- a/.github/workflows/sync-back-to-dev.yml +++ b/.github/workflows/sync-back-to-dev.yml @@ -11,7 +11,7 @@ jobs: name: Syncing branches steps: - name: Checkout - uses: actions/checkout@v3.5.2 + uses: actions/checkout@v3.6.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: diff --git a/src/args.c b/src/args.c index fc49a68c2..2a5701143 100644 --- a/src/args.c +++ b/src/args.c @@ -248,6 +248,21 @@ void parse_args(int argc, char* argv[]) argv2[5 + j] = argv[i + 2 + j]; exit(sqlite3_shell_main(argc2, argv2)); } + // Special non-interative mode + else if(i+1 < argc && strcmp(argv[i+1], "-ni") == 0) + { + int argc2 = argc - i + 4 - 2; + char **argv2 = calloc(argc2, sizeof(char*)); + argv2[0] = argv[0]; // Application name + argv2[1] = (char*)"-batch"; + argv2[2] = (char*)"-init"; + argv2[3] = (char*)"/dev/null"; + // i = "sqlite3" + // i+1 = "-ni" + for(int j = 0; j < argc - i - 2; j++) + argv2[4 + j] = argv[i + 2 + j]; + exit(sqlite3_shell_main(argc2, argv2)); + } else exit(sqlite3_shell_main(argc - i, &argv[i])); } @@ -511,19 +526,30 @@ void parse_args(int argc, char* argv[]) printf(" the script.\n\n"); printf("%sEmbedded SQLite3 shell:%s\n", yellow, normal); - printf("\t%ssql %s[-h]%s, %ssqlite3 %s[-h]%s FTL's SQLite3 shell\n", green, purple, normal, green, purple, normal); - printf("\t%s-h%s starts a special %shuman-readable mode%s\n\n", purple, normal, bold, normal); + printf("\t%ssql%s, %ssqlite3%s FTL's SQLite3 shell\n", green, normal, green, normal); - printf(" Usage: %spihole-FTL sqlite3 %s[-h] %s[OPTIONS] [FILENAME] [SQL]%s\n\n", green, purple, cyan, normal); + printf(" Usage: %spihole-FTL sqlite3 %s[OPTIONS] [FILENAME] [SQL]%s\n\n", green, cyan, normal); printf(" Options:\n\n"); printf(" - %s[OPTIONS]%s is an optional set of options. All available\n", cyan, normal); - printf(" options can be found in %spihole-FTL sqlite3 --help%s\n", green, normal); + printf(" options can be found in %spihole-FTL sqlite3 --help%s.\n", green, normal); + printf(" The first option can be either %s-h%s or %s-ni%s, see below.\n", purple, normal, purple, normal); printf(" - %s[FILENAME]%s is the optional name of an SQLite database.\n", cyan, normal); printf(" A new database is created if the file does not previously\n"); printf(" exist. If this argument is omitted, SQLite3 will use a\n"); printf(" transient in-memory database instead.\n"); printf(" - %s[SQL]%s is an optional SQL statement to be executed. If\n", cyan, normal); printf(" omitted, an interactive shell is started instead.\n\n"); + printf(" There are two special %spihole-FTL sqlite3%s mode switches:\n", green, normal); + printf(" %s-h%s %shuman-readable%s mode:\n", purple, normal, bold, normal); + printf(" In this mode, the output of the shell is formatted in\n"); + printf(" a human-readable way. This is especially useful for\n"); + printf(" debugging purposes. %s-h%s is a shortcut for\n", purple, normal); + printf(" %spihole-FTL sqlite3 %s-column -header -nullvalue '(null)'%s\n\n", green, purple, normal); + printf(" %s-ni%s %snon-interative%s mode\n", purple, normal, bold, normal); + printf(" In this mode, batch mode is enforced and any possibly\n"); + printf(" existing .sqliterc file is ignored. %s-ni%s is a shortcut\n", purple, normal); + printf(" for %spihole-FTL sqlite3 %s-batch -init /dev/null%s\n\n", green, purple, normal); + printf(" Usage: %spihole-FTL sqlite3 %s-ni %s[OPTIONS] [FILENAME] [SQL]%s\n\n", green, purple, cyan, normal); printf("%sEmbedded dnsmasq options:%s\n", yellow, normal); printf("\t%sdnsmasq-test%s Test syntax of dnsmasq's config\n", green, normal); diff --git a/src/database/network-table.c b/src/database/network-table.c index 85c0b8d39..94c34775c 100644 --- a/src/database/network-table.c +++ b/src/database/network-table.c @@ -760,7 +760,7 @@ static int update_netDB_interface(sqlite3 *db, const int network_id, const char // Loop over all clients known to FTL and ensure we add them all to the database static bool add_FTL_clients_to_network_table(sqlite3 *db, enum arp_status *client_status, time_t now, - unsigned int *additional_entries) + unsigned int *additional_entries, int num_clients) { // Return early if database is known to be broken if(FTLDBerror()) @@ -768,7 +768,7 @@ static bool add_FTL_clients_to_network_table(sqlite3 *db, enum arp_status *clien int rc = SQLITE_OK; char hwaddr[128]; - for(int clientID = 0; clientID < counters->clients; clientID++) + for(int clientID = 0; clientID < num_clients; clientID++) { // Check thread cancellation if(killed) @@ -1536,7 +1536,7 @@ void parse_neighbor_cache(sqlite3* db) // Loop over all clients known to FTL and ensure we add them all to the // database - if(!add_FTL_clients_to_network_table(db, client_status, now, &additional_entries)) + if(!add_FTL_clients_to_network_table(db, client_status, now, &additional_entries, clients)) return; // Check thread cancellation diff --git a/src/dnsmasq_interface.c b/src/dnsmasq_interface.c index 3a4be64a5..9f2adca1a 100644 --- a/src/dnsmasq_interface.c +++ b/src/dnsmasq_interface.c @@ -1392,23 +1392,6 @@ static bool _FTL_check_blocking(int queryID, int domainID, int clientID, const c break; } - // Not in FTL's cache. Check if this is a special domain - if(special_domain(query, domainstr)) - { - // Set DNS cache properties - dns_cache->blocking_status = SPECIAL_DOMAIN; - dns_cache->force_reply = force_next_DNS_reply; - - // Adjust counters - query_blocked(query, domain, client, QUERY_SPECIAL_DOMAIN); - - // Debug output - if(config.debug & DEBUG_QUERIES) - logg("Special domain: %s is %s", domainstr, blockingreason); - - return true; - } - // Skip all checks and continue if we hit already at least one whitelist in the chain if(query->flags.whitelisted) { @@ -1419,6 +1402,8 @@ static bool _FTL_check_blocking(int queryID, int domainID, int clientID, const c return false; } + // when we reach this point: the query is not in FTL's cache (for this client) + // Make a local copy of the domain string. The string memory may get // reorganized in the following. We cannot expect domainstr to remain // valid for all time. @@ -1432,6 +1417,23 @@ static bool _FTL_check_blocking(int queryID, int domainID, int clientID, const c if(!query->flags.whitelisted) query->flags.whitelisted = in_regex(domainstr, dns_cache, client->id, REGEX_WHITELIST); + // Check if this is a special domain + if(!query->flags.whitelisted && special_domain(query, domainstr)) + { + // Set DNS cache properties + dns_cache->blocking_status = SPECIAL_DOMAIN; + dns_cache->force_reply = force_next_DNS_reply; + + // Adjust counters + query_blocked(query, domain, client, QUERY_SPECIAL_DOMAIN); + + // Debug output + if(config.debug & DEBUG_QUERIES) + logg("Special domain: %s is %s", domainstr, blockingreason); + + return true; + } + // Check blacklist (exact + regex) and gravity for queried domain unsigned char new_status = QUERY_UNKNOWN; bool db_okay = true;