mirror of
https://github.com/pi-hole/FTL.git
synced 2025-12-24 14:48:22 +00:00
Merge branch 'development' into tweak/remove_global_objects
Signed-off-by: DL6ER <dl6er@dl6er.de>
This commit is contained in:
10
FTL.h
10
FTL.h
@@ -80,6 +80,14 @@
|
|||||||
// can be 24 hours + 59 minutes
|
// can be 24 hours + 59 minutes
|
||||||
#define OVERTIME_SLOTS ((MAXLOGAGE+1)*3600/OVERTIME_INTERVAL)
|
#define OVERTIME_SLOTS ((MAXLOGAGE+1)*3600/OVERTIME_INTERVAL)
|
||||||
|
|
||||||
|
// Interval for resolving NEW client and upstream server host names [seconds]
|
||||||
|
// Default: 60 (once every minute)
|
||||||
|
#define RESOLVE_INTERVAL 60
|
||||||
|
|
||||||
|
// Interval for re-resolving ALL known host names [seconds]
|
||||||
|
// Default: 3600 (once every hour)
|
||||||
|
#define RERESOLVE_INTERVAL 3600
|
||||||
|
|
||||||
// FTLDNS enums
|
// FTLDNS enums
|
||||||
enum { DATABASE_WRITE_TIMER, EXIT_TIMER, GC_TIMER, LISTS_TIMER, REGEX_TIMER, ARP_TIMER, LAST_TIMER };
|
enum { DATABASE_WRITE_TIMER, EXIT_TIMER, GC_TIMER, LISTS_TIMER, REGEX_TIMER, ARP_TIMER, LAST_TIMER };
|
||||||
enum { QUERIES, FORWARDED, CLIENTS, DOMAINS, OVERTIME, WILDCARD };
|
enum { QUERIES, FORWARDED, CLIENTS, DOMAINS, OVERTIME, WILDCARD };
|
||||||
@@ -103,6 +111,8 @@ enum {
|
|||||||
DEBUG_REGEX = (1 << 8), /* 00000001 00000000 */
|
DEBUG_REGEX = (1 << 8), /* 00000001 00000000 */
|
||||||
DEBUG_API = (1 << 9), /* 00000010 00000000 */
|
DEBUG_API = (1 << 9), /* 00000010 00000000 */
|
||||||
DEBUG_OVERTIME = (1 << 10), /* 00000100 00000000 */
|
DEBUG_OVERTIME = (1 << 10), /* 00000100 00000000 */
|
||||||
|
DEBUG_EXTBLOCKED = (1 << 11), /* 00001000 00000000 */
|
||||||
|
DEBUG_CAPS = (1 << 12), /* 00010000 00000000 */
|
||||||
};
|
};
|
||||||
|
|
||||||
// Database table "ftl"
|
// Database table "ftl"
|
||||||
|
|||||||
2
Makefile
2
Makefile
@@ -98,7 +98,7 @@ CCFLAGS=-std=gnu11 -I$(IDIR) $(WARNFLAGS) -D_FILE_OFFSET_BITS=64 $(HARDENING_FLA
|
|||||||
# for dnsmasq we need the nettle crypto library and the gmp maths library
|
# for dnsmasq we need the nettle crypto library and the gmp maths library
|
||||||
# We link the two libraries statically. Although this increases the binary file size by about 1 MB, it saves about 5 MB of shared libraries and makes deployment easier
|
# We link the two libraries statically. Although this increases the binary file size by about 1 MB, it saves about 5 MB of shared libraries and makes deployment easier
|
||||||
#LIBS=-pthread -lnettle -lgmp -lhogweed
|
#LIBS=-pthread -lnettle -lgmp -lhogweed
|
||||||
LIBS=-pthread -lrt -lcap -Wl,-Bstatic -L/usr/local/lib -lhogweed -lgmp -lnettle -Wl,-Bdynamic
|
LIBS=-pthread -lrt -Wl,-Bstatic -L/usr/local/lib -lhogweed -lgmp -lnettle -Wl,-Bdynamic
|
||||||
# Flags for compiling with libidn : -lidn
|
# Flags for compiling with libidn : -lidn
|
||||||
# Flags for compiling with libidn2: -lidn2
|
# Flags for compiling with libidn2: -lidn2
|
||||||
|
|
||||||
|
|||||||
66
api.c
66
api.c
@@ -19,8 +19,8 @@
|
|||||||
/* qsort comparision function (count field), sort ASC */
|
/* qsort comparision function (count field), sort ASC */
|
||||||
static int __attribute__((pure)) cmpasc(const void *a, const void *b)
|
static int __attribute__((pure)) cmpasc(const void *a, const void *b)
|
||||||
{
|
{
|
||||||
int *elem1 = (int*)a;
|
const int *elem1 = (int*)a;
|
||||||
int *elem2 = (int*)b;
|
const int *elem2 = (int*)b;
|
||||||
|
|
||||||
if (elem1[1] < elem2[1])
|
if (elem1[1] < elem2[1])
|
||||||
return -1;
|
return -1;
|
||||||
@@ -33,8 +33,8 @@ static int __attribute__((pure)) cmpasc(const void *a, const void *b)
|
|||||||
// qsort subroutine, sort DESC
|
// qsort subroutine, sort DESC
|
||||||
static int __attribute__((pure)) cmpdesc(const void *a, const void *b)
|
static int __attribute__((pure)) cmpdesc(const void *a, const void *b)
|
||||||
{
|
{
|
||||||
int *elem1 = (int*)a;
|
const int *elem1 = (int*)a;
|
||||||
int *elem2 = (int*)b;
|
const int *elem2 = (int*)b;
|
||||||
|
|
||||||
if (elem1[1] > elem2[1])
|
if (elem1[1] > elem2[1])
|
||||||
return -1;
|
return -1;
|
||||||
@@ -44,10 +44,10 @@ static int __attribute__((pure)) cmpdesc(const void *a, const void *b)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void getStats(int *sock)
|
void getStats(const int *sock)
|
||||||
{
|
{
|
||||||
int blocked = counters->blocked;
|
const int blocked = counters->blocked;
|
||||||
int total = counters->queries;
|
const int total = counters->queries;
|
||||||
float percentage = 0.0f;
|
float percentage = 0.0f;
|
||||||
|
|
||||||
// Avoid 1/0 condition
|
// Avoid 1/0 condition
|
||||||
@@ -112,7 +112,7 @@ void getStats(int *sock)
|
|||||||
pack_uint8(*sock, blockingstatus);
|
pack_uint8(*sock, blockingstatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
void getOverTime(int *sock)
|
void getOverTime(const int *sock)
|
||||||
{
|
{
|
||||||
int from = 0, until = OVERTIME_SLOTS;
|
int from = 0, until = OVERTIME_SLOTS;
|
||||||
bool found = false;
|
bool found = false;
|
||||||
@@ -175,12 +175,12 @@ void getOverTime(int *sock)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void getTopDomains(const char *client_message, int *sock)
|
void getTopDomains(const char *client_message, const int *sock)
|
||||||
{
|
{
|
||||||
int temparray[counters->domains][2], count=10, num;
|
int temparray[counters->domains][2], count=10, num;
|
||||||
bool blocked, audit = false, asc = false;
|
bool audit = false, asc = false;
|
||||||
|
|
||||||
blocked = command(client_message, ">top-ads");
|
const bool blocked = command(client_message, ">top-ads");
|
||||||
|
|
||||||
// Exit before processing any data if requested via config setting
|
// Exit before processing any data if requested via config setting
|
||||||
get_privacy_level(NULL);
|
get_privacy_level(NULL);
|
||||||
@@ -230,7 +230,7 @@ void getTopDomains(const char *client_message, int *sock)
|
|||||||
|
|
||||||
|
|
||||||
// Get filter
|
// Get filter
|
||||||
char * filter = read_setupVarsconf("API_QUERY_LOG_SHOW");
|
const char* filter = read_setupVarsconf("API_QUERY_LOG_SHOW");
|
||||||
bool showpermitted = true, showblocked = true;
|
bool showpermitted = true, showblocked = true;
|
||||||
if(filter != NULL)
|
if(filter != NULL)
|
||||||
{
|
{
|
||||||
@@ -270,8 +270,7 @@ void getTopDomains(const char *client_message, int *sock)
|
|||||||
for(int i=0; i < counters->domains; i++)
|
for(int i=0; i < counters->domains; i++)
|
||||||
{
|
{
|
||||||
// Get sorted index
|
// Get sorted index
|
||||||
int domainID = temparray[i][0];
|
const int domainID = temparray[i][0];
|
||||||
|
|
||||||
// Get domain pointer
|
// Get domain pointer
|
||||||
const domainsData* domain = getDomain(domainID, true);
|
const domainsData* domain = getDomain(domainID, true);
|
||||||
|
|
||||||
@@ -341,7 +340,7 @@ void getTopDomains(const char *client_message, int *sock)
|
|||||||
clearSetupVarsArray();
|
clearSetupVarsArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
void getTopClients(const char *client_message, int *sock)
|
void getTopClients(const char *client_message, const int *sock)
|
||||||
{
|
{
|
||||||
int temparray[counters->clients][2], count=10, num;
|
int temparray[counters->clients][2], count=10, num;
|
||||||
|
|
||||||
@@ -398,7 +397,7 @@ void getTopClients(const char *client_message, int *sock)
|
|||||||
qsort(temparray, counters->clients, sizeof(int[2]), cmpdesc);
|
qsort(temparray, counters->clients, sizeof(int[2]), cmpdesc);
|
||||||
|
|
||||||
// Get clients which the user doesn't want to see
|
// Get clients which the user doesn't want to see
|
||||||
char* excludeclients = read_setupVarsconf("API_EXCLUDE_CLIENTS");
|
const char* excludeclients = read_setupVarsconf("API_EXCLUDE_CLIENTS");
|
||||||
if(excludeclients != NULL)
|
if(excludeclients != NULL)
|
||||||
{
|
{
|
||||||
getSetupVarsArray(excludeclients);
|
getSetupVarsArray(excludeclients);
|
||||||
@@ -414,8 +413,8 @@ void getTopClients(const char *client_message, int *sock)
|
|||||||
for(int i=0; i < counters->clients; i++)
|
for(int i=0; i < counters->clients; i++)
|
||||||
{
|
{
|
||||||
// Get sorted indices and counter values (may be either total or blocked count)
|
// Get sorted indices and counter values (may be either total or blocked count)
|
||||||
int clientID = temparray[i][0];
|
const int clientID = temparray[i][0];
|
||||||
int ccount = temparray[i][1];
|
const int ccount = temparray[i][1];
|
||||||
// Get client pointer
|
// Get client pointer
|
||||||
const clientsData* client = getClient(clientID, true);
|
const clientsData* client = getClient(clientID, true);
|
||||||
|
|
||||||
@@ -458,7 +457,7 @@ void getTopClients(const char *client_message, int *sock)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void getForwardDestinations(const char *client_message, int *sock)
|
void getForwardDestinations(const char *client_message, const int *sock)
|
||||||
{
|
{
|
||||||
bool sort = true;
|
bool sort = true;
|
||||||
int temparray[counters->forwarded][2], totalqueries = 0;
|
int temparray[counters->forwarded][2], totalqueries = 0;
|
||||||
@@ -554,7 +553,7 @@ void getForwardDestinations(const char *client_message, int *sock)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void getQueryTypes(int *sock)
|
void getQueryTypes(const int *sock)
|
||||||
{
|
{
|
||||||
int total = 0;
|
int total = 0;
|
||||||
for(int i=0; i < TYPE_MAX-1; i++)
|
for(int i=0; i < TYPE_MAX-1; i++)
|
||||||
@@ -598,7 +597,7 @@ void getQueryTypes(int *sock)
|
|||||||
|
|
||||||
const char *querytypes[8] = {"A","AAAA","ANY","SRV","SOA","PTR","TXT","UNKN"};
|
const char *querytypes[8] = {"A","AAAA","ANY","SRV","SOA","PTR","TXT","UNKN"};
|
||||||
|
|
||||||
void getAllQueries(const char *client_message, int *sock)
|
void getAllQueries(const char *client_message, const int *sock)
|
||||||
{
|
{
|
||||||
// Exit before processing any data if requested via config setting
|
// Exit before processing any data if requested via config setting
|
||||||
get_privacy_level(NULL);
|
get_privacy_level(NULL);
|
||||||
@@ -872,7 +871,7 @@ void getAllQueries(const char *client_message, int *sock)
|
|||||||
free(forwarddest);
|
free(forwarddest);
|
||||||
}
|
}
|
||||||
|
|
||||||
void getRecentBlocked(const char *client_message, int *sock)
|
void getRecentBlocked(const char *client_message, const int *sock)
|
||||||
{
|
{
|
||||||
int num=1;
|
int num=1;
|
||||||
|
|
||||||
@@ -910,7 +909,7 @@ void getRecentBlocked(const char *client_message, int *sock)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void getClientID(int *sock)
|
void getClientID(const int *sock)
|
||||||
{
|
{
|
||||||
if(istelnet[*sock])
|
if(istelnet[*sock])
|
||||||
ssend(*sock,"%i\n", *sock);
|
ssend(*sock,"%i\n", *sock);
|
||||||
@@ -918,10 +917,11 @@ void getClientID(int *sock)
|
|||||||
pack_int32(*sock, *sock);
|
pack_int32(*sock, *sock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void getQueryTypesOverTime(int *sock)
|
void getQueryTypesOverTime(const int *sock)
|
||||||
{
|
{
|
||||||
int from = -1, until = OVERTIME_SLOTS;
|
int from = -1, until = OVERTIME_SLOTS;
|
||||||
time_t mintime = overTime[0].timestamp;
|
const time_t mintime = overTime[0].timestamp;
|
||||||
|
|
||||||
for(int slot = 0; slot < OVERTIME_SLOTS; slot++)
|
for(int slot = 0; slot < OVERTIME_SLOTS; slot++)
|
||||||
{
|
{
|
||||||
if((overTime[slot].total > 0 || overTime[slot].blocked > 0) && overTime[slot].timestamp >= mintime)
|
if((overTime[slot].total > 0 || overTime[slot].blocked > 0) && overTime[slot].timestamp >= mintime)
|
||||||
@@ -965,7 +965,7 @@ void getQueryTypesOverTime(int *sock)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void getVersion(int *sock)
|
void getVersion(const int *sock)
|
||||||
{
|
{
|
||||||
const char * commit = GIT_HASH;
|
const char * commit = GIT_HASH;
|
||||||
const char * tag = GIT_TAG;
|
const char * tag = GIT_TAG;
|
||||||
@@ -1014,7 +1014,7 @@ void getVersion(int *sock)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void getDBstats(int *sock)
|
void getDBstats(const int *sock)
|
||||||
{
|
{
|
||||||
// Get file details
|
// Get file details
|
||||||
struct stat st;
|
struct stat st;
|
||||||
@@ -1041,7 +1041,7 @@ void getDBstats(int *sock)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void getClientsOverTime(int *sock)
|
void getClientsOverTime(const int *sock)
|
||||||
{
|
{
|
||||||
int sendit = -1, until = OVERTIME_SLOTS;
|
int sendit = -1, until = OVERTIME_SLOTS;
|
||||||
|
|
||||||
@@ -1112,8 +1112,7 @@ void getClientsOverTime(int *sock)
|
|||||||
|
|
||||||
// Get client pointer
|
// Get client pointer
|
||||||
const clientsData* client = getClient(clientID, true);
|
const clientsData* client = getClient(clientID, true);
|
||||||
|
const int thisclient = client->overTime[slot];
|
||||||
int thisclient = client->overTime[slot];
|
|
||||||
|
|
||||||
if(istelnet[*sock])
|
if(istelnet[*sock])
|
||||||
ssend(*sock, " %i", thisclient);
|
ssend(*sock, " %i", thisclient);
|
||||||
@@ -1131,7 +1130,7 @@ void getClientsOverTime(int *sock)
|
|||||||
clearSetupVarsArray();
|
clearSetupVarsArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
void getClientNames(int *sock)
|
void getClientNames(const int *sock)
|
||||||
{
|
{
|
||||||
// Exit before processing any data if requested via config setting
|
// Exit before processing any data if requested via config setting
|
||||||
get_privacy_level(NULL);
|
get_privacy_level(NULL);
|
||||||
@@ -1169,7 +1168,6 @@ void getClientNames(int *sock)
|
|||||||
|
|
||||||
// Get client pointer
|
// Get client pointer
|
||||||
const clientsData* client = getClient(clientID, true);
|
const clientsData* client = getClient(clientID, true);
|
||||||
|
|
||||||
const char *client_ip = getstr(client->ippos);
|
const char *client_ip = getstr(client->ippos);
|
||||||
const char *client_name = getstr(client->namepos);
|
const char *client_name = getstr(client->namepos);
|
||||||
|
|
||||||
@@ -1185,7 +1183,7 @@ void getClientNames(int *sock)
|
|||||||
clearSetupVarsArray();
|
clearSetupVarsArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
void getUnknownQueries(int *sock)
|
void getUnknownQueries(const int *sock)
|
||||||
{
|
{
|
||||||
// Exit before processing any data if requested via config setting
|
// Exit before processing any data if requested via config setting
|
||||||
get_privacy_level(NULL);
|
get_privacy_level(NULL);
|
||||||
@@ -1236,7 +1234,7 @@ void getUnknownQueries(int *sock)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void getDomainDetails(const char *client_message, int *sock)
|
void getDomainDetails(const char *client_message, const int *sock)
|
||||||
{
|
{
|
||||||
// Get domain name
|
// Get domain name
|
||||||
char domainString[128];
|
char domainString[128];
|
||||||
|
|||||||
54
api.h
54
api.h
@@ -9,36 +9,36 @@
|
|||||||
* Please see LICENSE file for your rights under this license. */
|
* Please see LICENSE file for your rights under this license. */
|
||||||
|
|
||||||
// Statistic methods
|
// Statistic methods
|
||||||
void getStats(int *sock);
|
void getStats(const int *sock);
|
||||||
void getOverTime(int *sock);
|
void getOverTime(const int *sock);
|
||||||
void getTopDomains(const char *client_message, int *sock);
|
void getTopDomains(const char *client_message, const int *sock);
|
||||||
void getTopClients(const char *client_message, int *sock);
|
void getTopClients(const char *client_message, const int *sock);
|
||||||
void getForwardDestinations(const char *client_message, int *sock);
|
void getForwardDestinations(const char *client_message, const int *sock);
|
||||||
void getQueryTypes(int *sock);
|
void getQueryTypes(const int *sock);
|
||||||
void getAllQueries(const char *client_message, int *sock);
|
void getAllQueries(const char *client_message, const int *sock);
|
||||||
void getRecentBlocked(const char *client_message, int *sock);
|
void getRecentBlocked(const char *client_message, const int *sock);
|
||||||
void getQueryTypesOverTime(int *sock);
|
void getQueryTypesOverTime(const int *sock);
|
||||||
void getClientsOverTime(int *sock);
|
void getClientsOverTime(const int *sock);
|
||||||
void getClientNames(int *sock);
|
void getClientNames(const int *sock);
|
||||||
void getDomainDetails(const char *client_message, int *sock);
|
void getDomainDetails(const char *client_message, const int *sock);
|
||||||
|
|
||||||
// FTL methods
|
// FTL methods
|
||||||
void getClientID(int *sock);
|
void getClientID(const int *sock);
|
||||||
void getVersion(int *sock);
|
void getVersion(const int *sock);
|
||||||
void getDBstats(int *sock);
|
void getDBstats(const int *sock);
|
||||||
void getUnknownQueries(int *sock);
|
void getUnknownQueries(const int *sock);
|
||||||
|
|
||||||
// DNS resolver methods (dnsmasq_interface.c)
|
// DNS resolver methods (dnsmasq_interface.c)
|
||||||
void getCacheInformation(int *sock);
|
void getCacheInformation(const int *sock);
|
||||||
|
|
||||||
// MessagePack serialization helpers
|
// MessagePack serialization helpers
|
||||||
void pack_eom(int sock);
|
void pack_eom(const int sock);
|
||||||
void pack_bool(int sock, bool value);
|
void pack_bool(const int sock, const bool value);
|
||||||
void pack_uint8(int sock, uint8_t value);
|
void pack_uint8(const int sock, const uint8_t value);
|
||||||
void pack_uint64(int sock, uint64_t value);
|
void pack_uint64(const int sock, const uint64_t value);
|
||||||
void pack_int32(int sock, int32_t value);
|
void pack_int32(const int sock, const int32_t value);
|
||||||
void pack_int64(int sock, int64_t value);
|
void pack_int64(const int sock, const int64_t value);
|
||||||
void pack_float(int sock, float value);
|
void pack_float(const int sock, const float value);
|
||||||
bool pack_fixstr(int sock, const char *string);
|
bool pack_fixstr(const int sock, const char *string);
|
||||||
bool pack_str32(int sock, const char *string);
|
bool pack_str32(const int sock, const char *string);
|
||||||
void pack_map16_start(int sock, uint16_t length);
|
void pack_map16_start(const int sock, const uint16_t length);
|
||||||
|
|||||||
2
args.c
2
args.c
@@ -52,7 +52,6 @@ void parse_args(int argc, char* argv[])
|
|||||||
strcmp(argv[i], "version") == 0 ||
|
strcmp(argv[i], "version") == 0 ||
|
||||||
strcmp(argv[i], "--version") == 0)
|
strcmp(argv[i], "--version") == 0)
|
||||||
{
|
{
|
||||||
const char * commit = GIT_HASH;
|
|
||||||
const char * tag = GIT_TAG;
|
const char * tag = GIT_TAG;
|
||||||
if(strlen(tag) > 1)
|
if(strlen(tag) > 1)
|
||||||
{
|
{
|
||||||
@@ -60,6 +59,7 @@ void parse_args(int argc, char* argv[])
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
const char * commit = GIT_HASH;
|
||||||
char hash[8];
|
char hash[8];
|
||||||
// Extract first 7 characters of the hash
|
// Extract first 7 characters of the hash
|
||||||
strncpy(hash, commit, 7); hash[7] = 0;
|
strncpy(hash, commit, 7); hash[7] = 0;
|
||||||
|
|||||||
101
capabilities.c
101
capabilities.c
@@ -8,36 +8,99 @@
|
|||||||
* This file is copyright under the latest version of the EUPL.
|
* This file is copyright under the latest version of the EUPL.
|
||||||
* Please see LICENSE file for your rights under this license. */
|
* Please see LICENSE file for your rights under this license. */
|
||||||
|
|
||||||
|
// Definition of LINUX_CAPABILITY_VERSION_*
|
||||||
|
#define FTLDNS
|
||||||
|
#include "dnsmasq/dnsmasq.h"
|
||||||
|
#undef __USE_XOPEN
|
||||||
#include "FTL.h"
|
#include "FTL.h"
|
||||||
#include <sys/capability.h>
|
|
||||||
|
|
||||||
bool check_capabilities()
|
static const unsigned int capabilityIDs[] = { CAP_CHOWN , CAP_DAC_OVERRIDE , CAP_DAC_READ_SEARCH , CAP_FOWNER , CAP_FSETID , CAP_KILL , CAP_SETGID , CAP_SETUID , CAP_SETPCAP , CAP_LINUX_IMMUTABLE , CAP_NET_BIND_SERVICE , CAP_NET_BROADCAST , CAP_NET_ADMIN , CAP_NET_RAW , CAP_IPC_LOCK , CAP_IPC_OWNER , CAP_SYS_MODULE , CAP_SYS_RAWIO , CAP_SYS_CHROOT , CAP_SYS_PTRACE , CAP_SYS_PACCT , CAP_SYS_ADMIN , CAP_SYS_BOOT , CAP_SYS_NICE , CAP_SYS_RESOURCE , CAP_SYS_TIME , CAP_SYS_TTY_CONFIG , CAP_MKNOD , CAP_LEASE , CAP_AUDIT_WRITE , CAP_AUDIT_CONTROL , CAP_SETFCAP , CAP_MAC_OVERRIDE , CAP_MAC_ADMIN , CAP_SYSLOG , CAP_WAKE_ALARM , CAP_BLOCK_SUSPEND , CAP_AUDIT_READ };
|
||||||
|
static const char* capabilityNames[] = {"CAP_CHOWN", "CAP_DAC_OVERRIDE", "CAP_DAC_READ_SEARCH", "CAP_FOWNER", "CAP_FSETID", "CAP_KILL", "CAP_SETGID", "CAP_SETUID", "CAP_SETPCAP", "CAP_LINUX_IMMUTABLE", "CAP_NET_BIND_SERVICE", "CAP_NET_BROADCAST", "CAP_NET_ADMIN", "CAP_NET_RAW", "CAP_IPC_LOCK", "CAP_IPC_OWNER", "CAP_SYS_MODULE", "CAP_SYS_RAWIO", "CAP_SYS_CHROOT", "CAP_SYS_PTRACE", "CAP_SYS_PACCT", "CAP_SYS_ADMIN", "CAP_SYS_BOOT", "CAP_SYS_NICE", "CAP_SYS_RESOURCE", "CAP_SYS_TIME", "CAP_SYS_TTY_CONFIG", "CAP_MKNOD", "CAP_LEASE", "CAP_AUDIT_WRITE", "CAP_AUDIT_CONTROL", "CAP_SETFCAP", "CAP_MAC_OVERRIDE", "CAP_MAC_ADMIN", "CAP_SYSLOG", "CAP_WAKE_ALARM", "CAP_BLOCK_SUSPEND", "CAP_AUDIT_READ"};
|
||||||
|
static const unsigned int numCaps = sizeof(capabilityIDs) / sizeof(const unsigned int);
|
||||||
|
|
||||||
|
bool check_capabilities(void)
|
||||||
{
|
{
|
||||||
if(!cap_get_bound(CAP_NET_ADMIN))
|
// First assume header version 1
|
||||||
|
int capsize = 1; // VFS_CAP_U32_1
|
||||||
|
cap_user_data_t data = NULL;
|
||||||
|
cap_user_header_t hdr = calloc(sizeof(*hdr), capsize);
|
||||||
|
|
||||||
|
// Determine capabilities version used by the current kernel
|
||||||
|
capget(hdr, NULL);
|
||||||
|
|
||||||
|
// Check version
|
||||||
|
if (hdr->version != LINUX_CAPABILITY_VERSION_1)
|
||||||
|
{
|
||||||
|
// If unknown version, use largest supported version (3)
|
||||||
|
// Version 2 is deprecated according to linux/capability.h
|
||||||
|
if (hdr->version != LINUX_CAPABILITY_VERSION_2)
|
||||||
|
{
|
||||||
|
hdr->version = LINUX_CAPABILITY_VERSION_3;
|
||||||
|
capsize = 2; // VFS_CAP_U32_3
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Use version 2
|
||||||
|
capsize = 2; // VFS_CAP_U32_2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get current capabilities
|
||||||
|
data = calloc(sizeof(*data), capsize);
|
||||||
|
capget(hdr, data);
|
||||||
|
|
||||||
|
if(config.debug & DEBUG_CAPS)
|
||||||
|
{
|
||||||
|
logg("***************************************");
|
||||||
|
logg("* Linux capability debugging enabled *");
|
||||||
|
for(unsigned int i = 0u; i < numCaps; i++)
|
||||||
|
{
|
||||||
|
const unsigned int capid = capabilityIDs[i];
|
||||||
|
|
||||||
|
// Check if capability is valid for the current kernel
|
||||||
|
// If not, exit loop early
|
||||||
|
if(!cap_valid(capid))
|
||||||
|
break;
|
||||||
|
|
||||||
|
logg("* %-24s (%02u) = %s%s%s *",
|
||||||
|
capabilityNames[capid], capid,
|
||||||
|
((data->permitted & (1 << capid)) ? "P":"-"),
|
||||||
|
((data->inheritable & (1 << capid)) ? "I":"-"),
|
||||||
|
((data->effective & (1 << capid)) ? "E":"-"));
|
||||||
|
}
|
||||||
|
logg("***************************************");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool capabilities_okay = true;
|
||||||
|
if (!(data->permitted & (1 << CAP_NET_ADMIN)))
|
||||||
{
|
{
|
||||||
// Needed for ARP-injection (used when we're the DHCP server)
|
// Needed for ARP-injection (used when we're the DHCP server)
|
||||||
logg("**************************************************************");
|
logg("*************************************************************************");
|
||||||
logg("WARNING: Required linux capability CAP_NET_ADMIN not available");
|
logg("* WARNING: Required Linux capability CAP_NET_ADMIN not available *");
|
||||||
logg("**************************************************************");
|
logg("*************************************************************************");
|
||||||
return false;
|
capabilities_okay = false;
|
||||||
}
|
}
|
||||||
if(!cap_get_bound(CAP_NET_RAW))
|
if (!(data->permitted & (1 << CAP_NET_RAW)))
|
||||||
{
|
{
|
||||||
// Needed for raw socket access (necessary for ICMP)
|
// Needed for raw socket access (necessary for ICMP)
|
||||||
logg("************************************************************");
|
logg("*************************************************************************");
|
||||||
logg("WARNING: Required linux capability CAP_NET_RAW not available");
|
logg("* WARNING: Required Linux capability CAP_NET_RAW not available *");
|
||||||
logg("************************************************************");
|
logg("*************************************************************************");
|
||||||
return false;
|
capabilities_okay = false;
|
||||||
}
|
}
|
||||||
if(!cap_get_bound(CAP_NET_BIND_SERVICE))
|
if (!(data->permitted & (1 << CAP_NET_BIND_SERVICE)))
|
||||||
{
|
{
|
||||||
// Necessary for dynamic port binding
|
// Necessary for dynamic port binding
|
||||||
logg("*********************************************************************");
|
logg("*************************************************************************");
|
||||||
logg("WARNING: Required linux capability CAP_NET_BIND_SERVICE not available");
|
logg("* WARNING: Required Linux capability CAP_NET_BIND_SERVICE not available *");
|
||||||
logg("*********************************************************************");
|
logg("*************************************************************************");
|
||||||
return false;
|
capabilities_okay = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// All okay!
|
// Free allocated memory
|
||||||
return true;
|
free(hdr);
|
||||||
|
free(data);
|
||||||
|
|
||||||
|
// Return whether capabilities are all okay
|
||||||
|
return capabilities_okay;
|
||||||
}
|
}
|
||||||
|
|||||||
18
config.c
18
config.c
@@ -13,7 +13,7 @@
|
|||||||
ConfigStruct config;
|
ConfigStruct config;
|
||||||
static char *parse_FTLconf(FILE *fp, const char * key);
|
static char *parse_FTLconf(FILE *fp, const char * key);
|
||||||
static void release_config_memory(void);
|
static void release_config_memory(void);
|
||||||
void getpath(FILE* fp, const char *option, const char *defaultloc, char **pointer);
|
static void getpath(FILE* fp, const char *option, const char *defaultloc, char **pointer);
|
||||||
|
|
||||||
char *conflinebuffer = NULL;
|
char *conflinebuffer = NULL;
|
||||||
|
|
||||||
@@ -334,7 +334,7 @@ void read_FTLconf(void)
|
|||||||
fclose(fp);
|
fclose(fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void getpath(FILE* fp, const char *option, const char *defaultloc, char **pointer)
|
static void getpath(FILE* fp, const char *option, const char *defaultloc, char **pointer)
|
||||||
{
|
{
|
||||||
// This subroutine is used to read paths from pihole-FTL.conf
|
// This subroutine is used to read paths from pihole-FTL.conf
|
||||||
// fp: File pointer to opened and readable config file
|
// fp: File pointer to opened and readable config file
|
||||||
@@ -588,6 +588,18 @@ void read_debuging_settings(FILE *fp)
|
|||||||
if(buffer != NULL && strcasecmp(buffer, "true") == 0)
|
if(buffer != NULL && strcasecmp(buffer, "true") == 0)
|
||||||
config.debug |= DEBUG_OVERTIME;
|
config.debug |= DEBUG_OVERTIME;
|
||||||
|
|
||||||
|
// DEBUG_EXTBLOCKED
|
||||||
|
// defaults to: false
|
||||||
|
buffer = parse_FTLconf(fp, "DEBUG_EXTBLOCKED");
|
||||||
|
if(buffer != NULL && strcasecmp(buffer, "true") == 0)
|
||||||
|
config.debug |= DEBUG_EXTBLOCKED;
|
||||||
|
|
||||||
|
// DEBUG_CAPS
|
||||||
|
// defaults to: false
|
||||||
|
buffer = parse_FTLconf(fp, "DEBUG_CAPS");
|
||||||
|
if(buffer != NULL && strcasecmp(buffer, "true") == 0)
|
||||||
|
config.debug |= DEBUG_CAPS;
|
||||||
|
|
||||||
// DEBUG_ALL
|
// DEBUG_ALL
|
||||||
// defaults to: false
|
// defaults to: false
|
||||||
buffer = parse_FTLconf(fp, "DEBUG_ALL");
|
buffer = parse_FTLconf(fp, "DEBUG_ALL");
|
||||||
@@ -609,6 +621,8 @@ void read_debuging_settings(FILE *fp)
|
|||||||
logg("* DEBUG_REGEX %s *", (config.debug & DEBUG_REGEX)? "YES":"NO ");
|
logg("* DEBUG_REGEX %s *", (config.debug & DEBUG_REGEX)? "YES":"NO ");
|
||||||
logg("* DEBUG_API %s *", (config.debug & DEBUG_API)? "YES":"NO ");
|
logg("* DEBUG_API %s *", (config.debug & DEBUG_API)? "YES":"NO ");
|
||||||
logg("* DEBUG_OVERTIME %s *", (config.debug & DEBUG_OVERTIME)? "YES":"NO ");
|
logg("* DEBUG_OVERTIME %s *", (config.debug & DEBUG_OVERTIME)? "YES":"NO ");
|
||||||
|
logg("* DEBUG_EXTBLOCKED %s *", (config.debug & DEBUG_EXTBLOCKED)? "YES":"NO ");
|
||||||
|
logg("* DEBUG_CAPS %s *", (config.debug & DEBUG_CAPS)? "YES":"NO ");
|
||||||
logg("************************");
|
logg("************************");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
19
daemon.c
19
daemon.c
@@ -14,11 +14,8 @@ struct timeval t0[NUMTIMERS];
|
|||||||
|
|
||||||
void go_daemon(void)
|
void go_daemon(void)
|
||||||
{
|
{
|
||||||
pid_t process_id = 0;
|
|
||||||
pid_t sid = 0;
|
|
||||||
|
|
||||||
// Create child process
|
// Create child process
|
||||||
process_id = fork();
|
pid_t process_id = fork();
|
||||||
|
|
||||||
// Indication of fork() failure
|
// Indication of fork() failure
|
||||||
if (process_id < 0)
|
if (process_id < 0)
|
||||||
@@ -41,7 +38,7 @@ void go_daemon(void)
|
|||||||
|
|
||||||
//set new session
|
//set new session
|
||||||
// creates a session and sets the process group ID
|
// creates a session and sets the process group ID
|
||||||
sid = setsid();
|
const pid_t sid = setsid();
|
||||||
if(sid < 0)
|
if(sid < 0)
|
||||||
{
|
{
|
||||||
// Return failure
|
// Return failure
|
||||||
@@ -80,7 +77,7 @@ void go_daemon(void)
|
|||||||
// Closing stdin, stdout and stderr is handled by dnsmasq
|
// Closing stdin, stdout and stderr is handled by dnsmasq
|
||||||
}
|
}
|
||||||
|
|
||||||
void timer_start(int i)
|
void timer_start(const int i)
|
||||||
{
|
{
|
||||||
if(i >= NUMTIMERS)
|
if(i >= NUMTIMERS)
|
||||||
{
|
{
|
||||||
@@ -90,7 +87,7 @@ void timer_start(int i)
|
|||||||
gettimeofday(&t0[i], 0);
|
gettimeofday(&t0[i], 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
double timer_elapsed_msec(int i)
|
double timer_elapsed_msec(const int i)
|
||||||
{
|
{
|
||||||
if(i >= NUMTIMERS)
|
if(i >= NUMTIMERS)
|
||||||
{
|
{
|
||||||
@@ -102,7 +99,7 @@ double timer_elapsed_msec(int i)
|
|||||||
return (t1.tv_sec - t0[i].tv_sec) * 1000.0f + (t1.tv_usec - t0[i].tv_usec) / 1000.0f;
|
return (t1.tv_sec - t0[i].tv_sec) * 1000.0f + (t1.tv_usec - t0[i].tv_usec) / 1000.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sleepms(int milliseconds)
|
void sleepms(const int milliseconds)
|
||||||
{
|
{
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
tv.tv_sec = milliseconds / 1000;
|
tv.tv_sec = milliseconds / 1000;
|
||||||
@@ -113,7 +110,7 @@ void sleepms(int milliseconds)
|
|||||||
void savepid(void)
|
void savepid(void)
|
||||||
{
|
{
|
||||||
FILE *f;
|
FILE *f;
|
||||||
pid_t pid = getpid();
|
const pid_t pid = getpid();
|
||||||
if((f = fopen(FTLfiles.pid, "w+")) == NULL)
|
if((f = fopen(FTLfiles.pid, "w+")) == NULL)
|
||||||
{
|
{
|
||||||
logg("WARNING: Unable to write PID to file.");
|
logg("WARNING: Unable to write PID to file.");
|
||||||
@@ -143,8 +140,8 @@ char *getUserName(void)
|
|||||||
char * name;
|
char * name;
|
||||||
// the getpwuid() function shall search the user database for an entry with a matching uid
|
// the getpwuid() function shall search the user database for an entry with a matching uid
|
||||||
// the geteuid() function shall return the effective user ID of the calling process - this is used as the search criteria for the getpwuid() function
|
// the geteuid() function shall return the effective user ID of the calling process - this is used as the search criteria for the getpwuid() function
|
||||||
uid_t euid = geteuid();
|
const uid_t euid = geteuid();
|
||||||
struct passwd *pw = getpwuid(euid);
|
const struct passwd *pw = getpwuid(euid);
|
||||||
if(pw)
|
if(pw)
|
||||||
{
|
{
|
||||||
name = strdup(pw->pw_name);
|
name = strdup(pw->pw_name);
|
||||||
|
|||||||
38
database.c
38
database.c
@@ -19,8 +19,8 @@ long int lastdbindex = 0;
|
|||||||
|
|
||||||
static pthread_mutex_t dblock;
|
static pthread_mutex_t dblock;
|
||||||
|
|
||||||
bool db_set_counter(unsigned int ID, int value);
|
static bool db_set_counter(const unsigned int ID, const int value);
|
||||||
int db_get_FTL_property(unsigned int ID);
|
static int db_get_FTL_property(const unsigned int ID);
|
||||||
|
|
||||||
static void check_database(int rc)
|
static void check_database(int rc)
|
||||||
{
|
{
|
||||||
@@ -265,7 +265,7 @@ void db_init(void)
|
|||||||
database = true;
|
database = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int db_get_FTL_property(unsigned int ID)
|
static int db_get_FTL_property(const unsigned int ID)
|
||||||
{
|
{
|
||||||
// Prepare SQL statement
|
// Prepare SQL statement
|
||||||
char* querystr = NULL;
|
char* querystr = NULL;
|
||||||
@@ -283,17 +283,17 @@ int db_get_FTL_property(unsigned int ID)
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool db_set_FTL_property(unsigned int ID, int value)
|
bool db_set_FTL_property(const unsigned int ID, const int value)
|
||||||
{
|
{
|
||||||
return dbquery("INSERT OR REPLACE INTO ftl (id, value) VALUES ( %u, %i );", ID, value);
|
return dbquery("INSERT OR REPLACE INTO ftl (id, value) VALUES ( %u, %i );", ID, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool db_set_counter(unsigned int ID, int value)
|
static bool db_set_counter(const unsigned int ID, const int value)
|
||||||
{
|
{
|
||||||
return dbquery("INSERT OR REPLACE INTO counters (id, value) VALUES ( %u, %i );", ID, value);
|
return dbquery("INSERT OR REPLACE INTO counters (id, value) VALUES ( %u, %i );", ID, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool db_update_counters(int total, int blocked)
|
static bool db_update_counters(const int total, const int blocked)
|
||||||
{
|
{
|
||||||
if(!dbquery("UPDATE counters SET value = value + %i WHERE id = %i;", total, DB_TOTALQUERIES))
|
if(!dbquery("UPDATE counters SET value = value + %i WHERE id = %i;", total, DB_TOTALQUERIES))
|
||||||
return false;
|
return false;
|
||||||
@@ -428,7 +428,7 @@ void save_to_DB(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsigned int saved = 0, saved_error = 0;
|
unsigned int saved = 0, saved_error = 0;
|
||||||
sqlite3_stmt* stmt;
|
sqlite3_stmt* stmt = NULL;
|
||||||
|
|
||||||
// Get last ID stored in the database
|
// Get last ID stored in the database
|
||||||
sqlite3_int64 lastID = last_ID_in_DB();
|
sqlite3_int64 lastID = last_ID_in_DB();
|
||||||
@@ -597,7 +597,7 @@ static void delete_old_queries_in_DB(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get how many rows have been affected (deleted)
|
// Get how many rows have been affected (deleted)
|
||||||
int affected = sqlite3_changes(db);
|
const int affected = sqlite3_changes(db);
|
||||||
|
|
||||||
// Print final message only if there is a difference
|
// Print final message only if there is a difference
|
||||||
if((config.debug & DEBUG_DATABASE) || affected)
|
if((config.debug & DEBUG_DATABASE) || affected)
|
||||||
@@ -672,8 +672,8 @@ void read_data_from_DB(void)
|
|||||||
// Prepare request
|
// Prepare request
|
||||||
char *rstr = NULL;
|
char *rstr = NULL;
|
||||||
// Get time stamp 24 hours in the past
|
// Get time stamp 24 hours in the past
|
||||||
time_t now = time(NULL);
|
const time_t now = time(NULL);
|
||||||
time_t mintime = now - config.maxlogage;
|
const time_t mintime = now - config.maxlogage;
|
||||||
int rc = asprintf(&rstr, "SELECT * FROM queries WHERE timestamp >= %li", mintime);
|
int rc = asprintf(&rstr, "SELECT * FROM queries WHERE timestamp >= %li", mintime);
|
||||||
if(rc < 1)
|
if(rc < 1)
|
||||||
{
|
{
|
||||||
@@ -684,7 +684,7 @@ void read_data_from_DB(void)
|
|||||||
if(config.debug & DEBUG_DATABASE) logg("%s", rstr);
|
if(config.debug & DEBUG_DATABASE) logg("%s", rstr);
|
||||||
|
|
||||||
// Prepare SQLite3 statement
|
// Prepare SQLite3 statement
|
||||||
sqlite3_stmt* stmt;
|
sqlite3_stmt* stmt = NULL;
|
||||||
rc = sqlite3_prepare_v2(db, rstr, -1, &stmt, NULL);
|
rc = sqlite3_prepare_v2(db, rstr, -1, &stmt, NULL);
|
||||||
if( rc ){
|
if( rc ){
|
||||||
logg("read_data_from_DB() - SQL error prepare (%i): %s", rc, sqlite3_errmsg(db));
|
logg("read_data_from_DB() - SQL error prepare (%i): %s", rc, sqlite3_errmsg(db));
|
||||||
@@ -696,8 +696,8 @@ void read_data_from_DB(void)
|
|||||||
// Loop through returned database rows
|
// Loop through returned database rows
|
||||||
while((rc = sqlite3_step(stmt)) == SQLITE_ROW)
|
while((rc = sqlite3_step(stmt)) == SQLITE_ROW)
|
||||||
{
|
{
|
||||||
sqlite3_int64 dbid = sqlite3_column_int64(stmt, 0);
|
const sqlite3_int64 dbid = sqlite3_column_int64(stmt, 0);
|
||||||
time_t queryTimeStamp = sqlite3_column_int(stmt, 1);
|
const time_t queryTimeStamp = sqlite3_column_int(stmt, 1);
|
||||||
// 1483228800 = 01/01/2017 @ 12:00am (UTC)
|
// 1483228800 = 01/01/2017 @ 12:00am (UTC)
|
||||||
if(queryTimeStamp < 1483228800)
|
if(queryTimeStamp < 1483228800)
|
||||||
{
|
{
|
||||||
@@ -710,7 +710,7 @@ void read_data_from_DB(void)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
int type = sqlite3_column_int(stmt, 2);
|
const int type = sqlite3_column_int(stmt, 2);
|
||||||
if(type < TYPE_A || type >= TYPE_MAX)
|
if(type < TYPE_A || type >= TYPE_MAX)
|
||||||
{
|
{
|
||||||
logg("DB warn: TYPE should not be %i", type);
|
logg("DB warn: TYPE should not be %i", type);
|
||||||
@@ -723,7 +723,7 @@ void read_data_from_DB(void)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
int status = sqlite3_column_int(stmt, 3);
|
const int status = sqlite3_column_int(stmt, 3);
|
||||||
if(status < QUERY_UNKNOWN || status > QUERY_EXTERNAL_BLOCKED_NXRA)
|
if(status < QUERY_UNKNOWN || status > QUERY_EXTERNAL_BLOCKED_NXRA)
|
||||||
{
|
{
|
||||||
logg("DB warn: STATUS should be within [%i,%i] but is %i", QUERY_UNKNOWN, QUERY_EXTERNAL_BLOCKED_NXRA, status);
|
logg("DB warn: STATUS should be within [%i,%i] but is %i", QUERY_UNKNOWN, QUERY_EXTERNAL_BLOCKED_NXRA, status);
|
||||||
@@ -766,15 +766,15 @@ void read_data_from_DB(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Obtain IDs only after filtering which queries we want to keep
|
// Obtain IDs only after filtering which queries we want to keep
|
||||||
int timeidx = getOverTimeID(queryTimeStamp);
|
const int timeidx = getOverTimeID(queryTimeStamp);
|
||||||
int domainID = findDomainID(domainname);
|
const int domainID = findDomainID(domainname);
|
||||||
int clientID = findClientID(clientIP, true);
|
const int clientID = findClientID(clientIP, true);
|
||||||
|
|
||||||
// Ensure we have enough space in the queries struct
|
// Ensure we have enough space in the queries struct
|
||||||
memory_check(QUERIES);
|
memory_check(QUERIES);
|
||||||
|
|
||||||
// Set index for this query
|
// Set index for this query
|
||||||
int queryIndex = counters->queries;
|
const int queryIndex = counters->queries;
|
||||||
|
|
||||||
// Store this query in memory
|
// Store this query in memory
|
||||||
queriesData* query = getQuery(queryIndex, false);
|
queriesData* query = getQuery(queryIndex, false);
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ void strtolower(char *str)
|
|||||||
while(str[i]){ str[i] = tolower(str[i]); i++; }
|
while(str[i]){ str[i] = tolower(str[i]); i++; }
|
||||||
}
|
}
|
||||||
|
|
||||||
int findForwardID(const char * forwardString, bool count)
|
int findForwardID(const char * forwardString, const bool count)
|
||||||
{
|
{
|
||||||
// Go through already knows forward servers and see if we used one of those
|
// Go through already knows forward servers and see if we used one of those
|
||||||
for(int forwardID=0; forwardID < counters->forwarded; forwardID++)
|
for(int forwardID=0; forwardID < counters->forwarded; forwardID++)
|
||||||
@@ -109,7 +109,7 @@ int findDomainID(const char *domainString)
|
|||||||
return domainID;
|
return domainID;
|
||||||
}
|
}
|
||||||
|
|
||||||
int findClientID(const char *clientIP, bool count)
|
int findClientID(const char *clientIP, const bool count)
|
||||||
{
|
{
|
||||||
// Compare content of client against known client IP addresses
|
// Compare content of client against known client IP addresses
|
||||||
for(int clientID=0; clientID < counters->clients; clientID++)
|
for(int clientID=0; clientID < counters->clients; clientID++)
|
||||||
@@ -187,7 +187,7 @@ bool isValidIPv6(const char *addr)
|
|||||||
|
|
||||||
// Privacy-level sensitive subroutine that returns the domain name
|
// Privacy-level sensitive subroutine that returns the domain name
|
||||||
// only when appropriate for the requested query
|
// only when appropriate for the requested query
|
||||||
const char *getDomainString(int queryID)
|
const char *getDomainString(const int queryID)
|
||||||
{
|
{
|
||||||
const queriesData* query = getQuery(queryID, true);
|
const queriesData* query = getQuery(queryID, true);
|
||||||
if(query->privacylevel < PRIVACY_HIDE_DOMAINS)
|
if(query->privacylevel < PRIVACY_HIDE_DOMAINS)
|
||||||
@@ -204,7 +204,7 @@ const char *getDomainString(int queryID)
|
|||||||
|
|
||||||
// Privacy-level sensitive subroutine that returns the client IP
|
// Privacy-level sensitive subroutine that returns the client IP
|
||||||
// only when appropriate for the requested query
|
// only when appropriate for the requested query
|
||||||
const char *getClientIPString(int queryID)
|
const char *getClientIPString(const int queryID)
|
||||||
{
|
{
|
||||||
const queriesData* query = getQuery(queryID, false);
|
const queriesData* query = getQuery(queryID, false);
|
||||||
if(query->privacylevel < PRIVACY_HIDE_DOMAINS_CLIENTS)
|
if(query->privacylevel < PRIVACY_HIDE_DOMAINS_CLIENTS)
|
||||||
@@ -221,7 +221,7 @@ const char *getClientIPString(int queryID)
|
|||||||
|
|
||||||
// Privacy-level sensitive subroutine that returns the client host name
|
// Privacy-level sensitive subroutine that returns the client host name
|
||||||
// only when appropriate for the requested query
|
// only when appropriate for the requested query
|
||||||
const char *getClientNameString(int queryID)
|
const char *getClientNameString(const int queryID)
|
||||||
{
|
{
|
||||||
const queriesData* query = getQuery(queryID, true);
|
const queriesData* query = getQuery(queryID, true);
|
||||||
if(query->privacylevel < PRIVACY_HIDE_DOMAINS_CLIENTS)
|
if(query->privacylevel < PRIVACY_HIDE_DOMAINS_CLIENTS)
|
||||||
|
|||||||
@@ -17,18 +17,20 @@
|
|||||||
// Prototype of getCacheInformation()
|
// Prototype of getCacheInformation()
|
||||||
#include "api.h"
|
#include "api.h"
|
||||||
|
|
||||||
void print_flags(unsigned int flags);
|
static void print_flags(const unsigned int flags);
|
||||||
void save_reply_type(unsigned int flags, int queryID, struct timeval response);
|
static void save_reply_type(const unsigned int flags, const int queryID, const struct timeval response);
|
||||||
static unsigned long converttimeval(struct timeval time) __attribute__((const));
|
static unsigned long converttimeval(const struct timeval time) __attribute__((const));
|
||||||
static void block_single_domain_regex(char *domain);
|
static void block_single_domain_regex(const char *domain);
|
||||||
static void detect_blocked_IP(unsigned short flags, const char* answer, int queryID);
|
static void detect_blocked_IP(const unsigned short flags, const char* answer, const int queryID);
|
||||||
static void query_externally_blocked(int i, unsigned char status);
|
static void query_externally_blocked(const int queryID, const unsigned char status);
|
||||||
static int findQueryID(int id);
|
static int findQueryID(const int id);
|
||||||
|
|
||||||
unsigned char* pihole_privacylevel = &config.privacylevel;
|
unsigned char* pihole_privacylevel = &config.privacylevel;
|
||||||
char flagnames[28][12] = {"F_IMMORTAL ", "F_NAMEP ", "F_REVERSE ", "F_FORWARD ", "F_DHCP ", "F_NEG ", "F_HOSTS ", "F_IPV4 ", "F_IPV6 ", "F_BIGNAME ", "F_NXDOMAIN ", "F_CNAME ", "F_DNSKEY ", "F_CONFIG ", "F_DS ", "F_DNSSECOK ", "F_UPSTREAM ", "F_RRNAME ", "F_SERVER ", "F_QUERY ", "F_NOERR ", "F_AUTH ", "F_DNSSEC ", "F_KEYTAG ", "F_SECSTAT ", "F_NO_RR ", "F_IPSET ", "F_NOEXTRA "};
|
const char flagnames[28][12] = {"F_IMMORTAL ", "F_NAMEP ", "F_REVERSE ", "F_FORWARD ", "F_DHCP ", "F_NEG ", "F_HOSTS ", "F_IPV4 ", "F_IPV6 ", "F_BIGNAME ", "F_NXDOMAIN ", "F_CNAME ", "F_DNSKEY ", "F_CONFIG ", "F_DS ", "F_DNSSECOK ", "F_UPSTREAM ", "F_RRNAME ", "F_SERVER ", "F_QUERY ", "F_NOERR ", "F_AUTH ", "F_DNSSEC ", "F_KEYTAG ", "F_SECSTAT ", "F_NO_RR ", "F_IPSET ", "F_NOEXTRA "};
|
||||||
|
|
||||||
void _FTL_new_query(unsigned int flags, char *name, struct all_addr *addr, char *types, int id, char type, const char* file, const int line)
|
void _FTL_new_query(const unsigned int flags, const char *name, const struct all_addr *addr,
|
||||||
|
const char *types, const int id, const char type,
|
||||||
|
const char* file, const int line)
|
||||||
{
|
{
|
||||||
// Don't analyze anything if in PRIVACY_NOSTATS mode
|
// Don't analyze anything if in PRIVACY_NOSTATS mode
|
||||||
if(config.privacylevel >= PRIVACY_NOSTATS)
|
if(config.privacylevel >= PRIVACY_NOSTATS)
|
||||||
@@ -38,7 +40,7 @@ void _FTL_new_query(unsigned int flags, char *name, struct all_addr *addr, char
|
|||||||
lock_shm();
|
lock_shm();
|
||||||
|
|
||||||
// Get timestamp
|
// Get timestamp
|
||||||
time_t querytimestamp = time(NULL);
|
const time_t querytimestamp = time(NULL);
|
||||||
|
|
||||||
// Save request time
|
// Save request time
|
||||||
struct timeval request;
|
struct timeval request;
|
||||||
@@ -78,7 +80,7 @@ void _FTL_new_query(unsigned int flags, char *name, struct all_addr *addr, char
|
|||||||
|
|
||||||
// Ensure we have enough space in the queries struct
|
// Ensure we have enough space in the queries struct
|
||||||
memory_check(QUERIES);
|
memory_check(QUERIES);
|
||||||
int queryID = counters->queries;
|
const int queryID = counters->queries;
|
||||||
|
|
||||||
// If domain is "pi.hole" we skip this query
|
// If domain is "pi.hole" we skip this query
|
||||||
if(strcasecmp(name, "pi.hole") == 0)
|
if(strcasecmp(name, "pi.hole") == 0)
|
||||||
@@ -111,14 +113,15 @@ void _FTL_new_query(unsigned int flags, char *name, struct all_addr *addr, char
|
|||||||
const char *proto = (type == UDP) ? "UDP" : "TCP";
|
const char *proto = (type == UDP) ? "UDP" : "TCP";
|
||||||
if(config.debug & DEBUG_QUERIES)
|
if(config.debug & DEBUG_QUERIES)
|
||||||
{
|
{
|
||||||
logg("**** new %s %s \"%s\" from %s (ID %i, %s:%i)", proto, types, domainString, clientIP, id, file, line);
|
logg("**** new %s %s \"%s\" from %s (ID %i, FTL %i, %s:%i)",
|
||||||
|
proto, types, domainString, clientIP, id, queryID, file, line);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update counters
|
// Update counters
|
||||||
counters->querytype[querytype-1]++;
|
counters->querytype[querytype-1]++;
|
||||||
|
|
||||||
// Update overTime
|
// Update overTime
|
||||||
unsigned int timeidx = getOverTimeID(querytimestamp);
|
const unsigned int timeidx = getOverTimeID(querytimestamp);
|
||||||
overTime[timeidx].querytypedata[querytype-1]++;
|
overTime[timeidx].querytypedata[querytype-1]++;
|
||||||
|
|
||||||
// Skip rest of the analysis if this query is not of type A or AAAA
|
// Skip rest of the analysis if this query is not of type A or AAAA
|
||||||
@@ -134,10 +137,10 @@ void _FTL_new_query(unsigned int flags, char *name, struct all_addr *addr, char
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Go through already knows domains and see if it is one of them
|
// Go through already knows domains and see if it is one of them
|
||||||
int domainID = findDomainID(domainString);
|
const int domainID = findDomainID(domainString);
|
||||||
|
|
||||||
// Go through already knows clients and see if it is one of them
|
// Go through already knows clients and see if it is one of them
|
||||||
int clientID = findClientID(clientIP, true);
|
const int clientID = findClientID(clientIP, true);
|
||||||
|
|
||||||
// Save everything
|
// Save everything
|
||||||
queriesData* query = getQuery(queryID, false);
|
queriesData* query = getQuery(queryID, false);
|
||||||
@@ -220,7 +223,7 @@ void _FTL_new_query(unsigned int flags, char *name, struct all_addr *addr, char
|
|||||||
unlock_shm();
|
unlock_shm();
|
||||||
}
|
}
|
||||||
|
|
||||||
static int findQueryID(int id)
|
static int findQueryID(const int id)
|
||||||
{
|
{
|
||||||
// Loop over all queries - we loop in reverse order (start from the most recent query and
|
// Loop over all queries - we loop in reverse order (start from the most recent query and
|
||||||
// continuously walk older queries while trying to find a match. Ideally, we should always
|
// continuously walk older queries while trying to find a match. Ideally, we should always
|
||||||
@@ -229,8 +232,8 @@ static int findQueryID(int id)
|
|||||||
// We iterate from the most recent query down to at most MAXITER queries in the past to avoid
|
// We iterate from the most recent query down to at most MAXITER queries in the past to avoid
|
||||||
// iterating through the entire array of queries
|
// iterating through the entire array of queries
|
||||||
// MAX(0, a) is used to return 0 in case a is negative (negative array indices are harmful)
|
// MAX(0, a) is used to return 0 in case a is negative (negative array indices are harmful)
|
||||||
int until = MAX(0, counters->queries-MAXITER);
|
const int until = MAX(0, counters->queries-MAXITER);
|
||||||
int start = MAX(0, counters->queries-1);
|
const int start = MAX(0, counters->queries-1);
|
||||||
|
|
||||||
// Check UUIDs of queries
|
// Check UUIDs of queries
|
||||||
for(int i = start; i >= until; i--)
|
for(int i = start; i >= until; i--)
|
||||||
@@ -244,7 +247,8 @@ static int findQueryID(int id)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _FTL_forwarded(unsigned int flags, char *name, struct all_addr *addr, int id, const char* file, const int line)
|
void _FTL_forwarded(const unsigned int flags, const char *name, const struct all_addr *addr, const int id,
|
||||||
|
const char* file, const int line)
|
||||||
{
|
{
|
||||||
// Don't analyze anything if in PRIVACY_NOSTATS mode
|
// Don't analyze anything if in PRIVACY_NOSTATS mode
|
||||||
if(config.privacylevel >= PRIVACY_NOSTATS)
|
if(config.privacylevel >= PRIVACY_NOSTATS)
|
||||||
@@ -267,7 +271,7 @@ void _FTL_forwarded(unsigned int flags, char *name, struct all_addr *addr, int i
|
|||||||
if(config.debug & DEBUG_QUERIES) logg("**** forwarded %s to %s (ID %i, %s:%i)", name, forward, id, file, line);
|
if(config.debug & DEBUG_QUERIES) logg("**** forwarded %s to %s (ID %i, %s:%i)", name, forward, id, file, line);
|
||||||
|
|
||||||
// Save status and forwardID in corresponding query identified by dnsmasq's ID
|
// Save status and forwardID in corresponding query identified by dnsmasq's ID
|
||||||
int queryID = findQueryID(id);
|
const int queryID = findQueryID(id);
|
||||||
if(queryID < 0)
|
if(queryID < 0)
|
||||||
{
|
{
|
||||||
// This may happen e.g. if the original query was a PTR query or "pi.hole"
|
// This may happen e.g. if the original query was a PTR query or "pi.hole"
|
||||||
@@ -295,10 +299,10 @@ void _FTL_forwarded(unsigned int flags, char *name, struct all_addr *addr, int i
|
|||||||
|
|
||||||
// Get ID of forward destination, create new forward destination record
|
// Get ID of forward destination, create new forward destination record
|
||||||
// if not found in current data structure
|
// if not found in current data structure
|
||||||
int forwardID = findForwardID(forward, true);
|
const int forwardID = findForwardID(forward, true);
|
||||||
query->forwardID = forwardID;
|
query->forwardID = forwardID;
|
||||||
|
|
||||||
unsigned int timeidx = query->timeidx;
|
const unsigned int timeidx = query->timeidx;
|
||||||
|
|
||||||
if(query->status == QUERY_CACHE)
|
if(query->status == QUERY_CACHE)
|
||||||
{
|
{
|
||||||
@@ -361,6 +365,8 @@ void FTL_dnsmasq_reload(void)
|
|||||||
// *before* clearing the cache and rereading the lists
|
// *before* clearing the cache and rereading the lists
|
||||||
// This is the only hook that is not skipped in PRIVACY_NOSTATS mode
|
// This is the only hook that is not skipped in PRIVACY_NOSTATS mode
|
||||||
|
|
||||||
|
logg("Received SIGHUP, reloading cache");
|
||||||
|
|
||||||
// Called when dnsmasq re-reads its config and hosts files
|
// Called when dnsmasq re-reads its config and hosts files
|
||||||
// Reset number of blocked domains
|
// Reset number of blocked domains
|
||||||
counters->gravity = 0;
|
counters->gravity = 0;
|
||||||
@@ -382,9 +388,14 @@ void FTL_dnsmasq_reload(void)
|
|||||||
|
|
||||||
// Reread pihole-FTL.conf to see which debugging flags are set
|
// Reread pihole-FTL.conf to see which debugging flags are set
|
||||||
read_debuging_settings(NULL);
|
read_debuging_settings(NULL);
|
||||||
|
|
||||||
|
// Print current set of capabilities if requested via debug flag
|
||||||
|
if(config.debug & DEBUG_CAPS)
|
||||||
|
check_capabilities();
|
||||||
}
|
}
|
||||||
|
|
||||||
void _FTL_reply(unsigned short flags, char *name, struct all_addr *addr, int id, const char* file, const int line)
|
void _FTL_reply(const unsigned short flags, const char *name, const struct all_addr *addr, const int id,
|
||||||
|
const char* file, const int line)
|
||||||
{
|
{
|
||||||
// Don't analyze anything if in PRIVACY_NOSTATS mode
|
// Don't analyze anything if in PRIVACY_NOSTATS mode
|
||||||
if(config.privacylevel >= PRIVACY_NOSTATS)
|
if(config.privacylevel >= PRIVACY_NOSTATS)
|
||||||
@@ -420,7 +431,7 @@ void _FTL_reply(unsigned short flags, char *name, struct all_addr *addr, int id,
|
|||||||
gettimeofday(&response, 0);
|
gettimeofday(&response, 0);
|
||||||
|
|
||||||
// Save status in corresponding query identified by dnsmasq's ID
|
// Save status in corresponding query identified by dnsmasq's ID
|
||||||
int i = findQueryID(id);
|
const int i = findQueryID(id);
|
||||||
if(i < 0)
|
if(i < 0)
|
||||||
{
|
{
|
||||||
// This may happen e.g. if the original query was "pi.hole"
|
// This may happen e.g. if the original query was "pi.hole"
|
||||||
@@ -440,13 +451,13 @@ void _FTL_reply(unsigned short flags, char *name, struct all_addr *addr, int id,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Determine if this reply is an exact match for the queried domain
|
// Determine if this reply is an exact match for the queried domain
|
||||||
int domainID = query->domainID;
|
const int domainID = query->domainID;
|
||||||
|
|
||||||
// Get domain pointer
|
// Get domain pointer
|
||||||
domainsData* domain = getDomain(domainID, true);
|
domainsData* domain = getDomain(domainID, true);
|
||||||
|
|
||||||
// Check if this domain matches exactly
|
// Check if this domain matches exactly
|
||||||
bool isExactMatch = (name != NULL && strcmp(getstr(domain->domainpos), name) == 0);
|
const bool isExactMatch = (name != NULL && strcmp(getstr(domain->domainpos), name) == 0);
|
||||||
|
|
||||||
if((flags & F_CONFIG) && isExactMatch && !query->complete)
|
if((flags & F_CONFIG) && isExactMatch && !query->complete)
|
||||||
{
|
{
|
||||||
@@ -455,7 +466,7 @@ void _FTL_reply(unsigned short flags, char *name, struct all_addr *addr, int id,
|
|||||||
counters->unknown--;
|
counters->unknown--;
|
||||||
|
|
||||||
// Get time index
|
// Get time index
|
||||||
unsigned int timeidx = query->timeidx;
|
const unsigned int timeidx = query->timeidx;
|
||||||
|
|
||||||
if(strcmp(answer, "(NXDOMAIN)") == 0 ||
|
if(strcmp(answer, "(NXDOMAIN)") == 0 ||
|
||||||
strcmp(answer, "0.0.0.0") == 0 ||
|
strcmp(answer, "0.0.0.0") == 0 ||
|
||||||
@@ -530,12 +541,25 @@ void _FTL_reply(unsigned short flags, char *name, struct all_addr *addr, int id,
|
|||||||
unlock_shm();
|
unlock_shm();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void detect_blocked_IP(unsigned short flags, const char* answer, int queryID)
|
static void detect_blocked_IP(const unsigned short flags, const char* answer, const int queryID)
|
||||||
{
|
{
|
||||||
// Skip replies which originated locally. Otherwise, we would count
|
|
||||||
// gravity.list blocked queries as externally blocked.
|
|
||||||
if(flags & F_HOSTS)
|
if(flags & F_HOSTS)
|
||||||
{
|
{
|
||||||
|
// Skip replies which originated locally. Otherwise, we would
|
||||||
|
// count gravity.list blocked queries as externally blocked.
|
||||||
|
if(config.debug & DEBUG_EXTBLOCKED)
|
||||||
|
{
|
||||||
|
logg("Skipping detection of external blocking IP for ID %i as origin is HOSTS", queryID);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if(flags & F_REVERSE)
|
||||||
|
{
|
||||||
|
// Do not mark responses of PTR requests as externally blocked.
|
||||||
|
if(config.debug & DEBUG_EXTBLOCKED)
|
||||||
|
{
|
||||||
|
logg("Skipping detection of external blocking IP for ID %i as query is PTR", queryID);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -552,7 +576,16 @@ static void detect_blocked_IP(unsigned short flags, const char* answer, int quer
|
|||||||
strcmp("146.112.61.109", answer) == 0 ||
|
strcmp("146.112.61.109", answer) == 0 ||
|
||||||
strcmp("146.112.61.110", answer) == 0 ))
|
strcmp("146.112.61.110", answer) == 0 ))
|
||||||
{
|
{
|
||||||
query_externally_blocked(queryID, QUERY_EXTERNAL_BLOCKED_IP);
|
if(config.debug & DEBUG_EXTBLOCKED)
|
||||||
|
{
|
||||||
|
const queriesData* query = getQuery(queryID, true);
|
||||||
|
const domainsData* domain = getDomain(query->domainID, true);
|
||||||
|
logg("Upstream responded with known blocking page (IPv4), ID %i:\n\t\"%s\" -> \"%s\"",
|
||||||
|
queryID, getstr(domain->domainpos), answer);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update status
|
||||||
|
query_externally_blocked(queryID, QUERY_EXTERNAL_BLOCKED_IP);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if(flags & F_IPV6 && answer != NULL &&
|
else if(flags & F_IPV6 && answer != NULL &&
|
||||||
@@ -564,7 +597,16 @@ static void detect_blocked_IP(unsigned short flags, const char* answer, int quer
|
|||||||
strcmp("::ffff:146.112.61.109", answer) == 0 ||
|
strcmp("::ffff:146.112.61.109", answer) == 0 ||
|
||||||
strcmp("::ffff:146.112.61.110", answer) == 0 ))
|
strcmp("::ffff:146.112.61.110", answer) == 0 ))
|
||||||
{
|
{
|
||||||
query_externally_blocked(queryID, QUERY_EXTERNAL_BLOCKED_IP);
|
if(config.debug & DEBUG_EXTBLOCKED)
|
||||||
|
{
|
||||||
|
const queriesData* query = getQuery(queryID, true);
|
||||||
|
const domainsData* domain = getDomain(query->domainID, true);
|
||||||
|
logg("Upstream responded with known blocking page (IPv6), ID %i:\n\t\"%s\" -> \"%s\"",
|
||||||
|
queryID, getstr(domain->domainpos), answer);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update status
|
||||||
|
query_externally_blocked(queryID, QUERY_EXTERNAL_BLOCKED_IP);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If upstream replied with 0.0.0.0 or ::,
|
// If upstream replied with 0.0.0.0 or ::,
|
||||||
@@ -573,23 +615,41 @@ static void detect_blocked_IP(unsigned short flags, const char* answer, int quer
|
|||||||
else if(flags & F_IPV4 && answer != NULL &&
|
else if(flags & F_IPV4 && answer != NULL &&
|
||||||
strcmp("0.0.0.0", answer) == 0)
|
strcmp("0.0.0.0", answer) == 0)
|
||||||
{
|
{
|
||||||
query_externally_blocked(queryID, QUERY_EXTERNAL_BLOCKED_NULL);
|
if(config.debug & DEBUG_EXTBLOCKED)
|
||||||
|
{
|
||||||
|
const queriesData* query = getQuery(queryID, true);
|
||||||
|
const domainsData* domain = getDomain(query->domainID, true);
|
||||||
|
logg("Upstream responded with 0.0.0.0, ID %i:\n\t\"%s\" -> \"%s\"",
|
||||||
|
queryID, getstr(domain->domainpos), answer);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update status
|
||||||
|
query_externally_blocked(queryID, QUERY_EXTERNAL_BLOCKED_NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if(flags & F_IPV6 && answer != NULL &&
|
else if(flags & F_IPV6 && answer != NULL &&
|
||||||
strcmp("::", answer) == 0)
|
strcmp("::", answer) == 0)
|
||||||
{
|
{
|
||||||
query_externally_blocked(queryID, QUERY_EXTERNAL_BLOCKED_NULL);
|
if(config.debug & DEBUG_EXTBLOCKED)
|
||||||
|
{
|
||||||
|
const queriesData* query = getQuery(queryID, true);
|
||||||
|
const domainsData* domain = getDomain(query->domainID, true);
|
||||||
|
logg("Upstream responded with ::, ID %i:\n\t\"%s\" -> \"%s\"",
|
||||||
|
queryID, getstr(domain->domainpos), answer);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update status
|
||||||
|
query_externally_blocked(queryID, QUERY_EXTERNAL_BLOCKED_NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void query_externally_blocked(int i, unsigned char status)
|
static void query_externally_blocked(const int queryID, const unsigned char status)
|
||||||
{
|
{
|
||||||
// Get query pointer
|
// Get query pointer
|
||||||
queriesData* query = getQuery(i, true);
|
queriesData* query = getQuery(queryID, true);
|
||||||
|
|
||||||
// Get time index
|
// Get time index
|
||||||
unsigned int timeidx = query->timeidx;
|
const unsigned int timeidx = query->timeidx;
|
||||||
|
|
||||||
// If query is already known to be externally blocked,
|
// If query is already known to be externally blocked,
|
||||||
// then we have nothing to do here
|
// then we have nothing to do here
|
||||||
@@ -624,7 +684,8 @@ static void query_externally_blocked(int i, unsigned char status)
|
|||||||
query->status = status;
|
query->status = status;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _FTL_cache(unsigned int flags, char *name, struct all_addr *addr, char *arg, int id, const char* file, const int line)
|
void _FTL_cache(const unsigned int flags, const char *name, const struct all_addr *addr,
|
||||||
|
const char *arg, const int id, const char* file, const int line)
|
||||||
{
|
{
|
||||||
// Don't analyze anything if in PRIVACY_NOSTATS mode
|
// Don't analyze anything if in PRIVACY_NOSTATS mode
|
||||||
if(config.privacylevel >= PRIVACY_NOSTATS)
|
if(config.privacylevel >= PRIVACY_NOSTATS)
|
||||||
@@ -696,8 +757,8 @@ void _FTL_cache(unsigned int flags, char *name, struct all_addr *addr, char *arg
|
|||||||
print_flags(flags);
|
print_flags(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
int i = findQueryID(id);
|
const int queryID = findQueryID(id);
|
||||||
if(i < 0)
|
if(queryID < 0)
|
||||||
{
|
{
|
||||||
// This may happen e.g. if the original query was a PTR query or "pi.hole"
|
// This may happen e.g. if the original query was a PTR query or "pi.hole"
|
||||||
// as we ignore them altogether
|
// as we ignore them altogether
|
||||||
@@ -706,7 +767,7 @@ void _FTL_cache(unsigned int flags, char *name, struct all_addr *addr, char *arg
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get query pointer
|
// Get query pointer
|
||||||
queriesData* query = getQuery(i, true);
|
queriesData* query = getQuery(queryID, true);
|
||||||
|
|
||||||
if(query->complete)
|
if(query->complete)
|
||||||
{
|
{
|
||||||
@@ -719,7 +780,7 @@ void _FTL_cache(unsigned int flags, char *name, struct all_addr *addr, char *arg
|
|||||||
counters->unknown--;
|
counters->unknown--;
|
||||||
|
|
||||||
// Get time index
|
// Get time index
|
||||||
unsigned int timeidx = query->timeidx;
|
const unsigned int timeidx = query->timeidx;
|
||||||
|
|
||||||
// Get domain pointer
|
// Get domain pointer
|
||||||
domainsData* domain = getDomain(query->domainID, true);
|
domainsData* domain = getDomain(query->domainID, true);
|
||||||
@@ -734,7 +795,7 @@ void _FTL_cache(unsigned int flags, char *name, struct all_addr *addr, char *arg
|
|||||||
query->status = requesttype;
|
query->status = requesttype;
|
||||||
|
|
||||||
// Detect if returned IP indicates that this query was blocked
|
// Detect if returned IP indicates that this query was blocked
|
||||||
detect_blocked_IP(flags, dest, i);
|
detect_blocked_IP(flags, dest, queryID);
|
||||||
|
|
||||||
// Re-read requesttype as detect_blocked_IP() might have changed it
|
// Re-read requesttype as detect_blocked_IP() might have changed it
|
||||||
requesttype = query->status;
|
requesttype = query->status;
|
||||||
@@ -763,7 +824,7 @@ void _FTL_cache(unsigned int flags, char *name, struct all_addr *addr, char *arg
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Save reply type and update individual reply counters
|
// Save reply type and update individual reply counters
|
||||||
save_reply_type(flags, i, response);
|
save_reply_type(flags, queryID, response);
|
||||||
|
|
||||||
// Hereby, this query is now fully determined
|
// Hereby, this query is now fully determined
|
||||||
query->complete = true;
|
query->complete = true;
|
||||||
@@ -776,7 +837,7 @@ void _FTL_cache(unsigned int flags, char *name, struct all_addr *addr, char *arg
|
|||||||
unlock_shm();
|
unlock_shm();
|
||||||
}
|
}
|
||||||
|
|
||||||
void _FTL_dnssec(int status, int id, const char* file, const int line)
|
void _FTL_dnssec(const int status, const int id, const char* file, const int line)
|
||||||
{
|
{
|
||||||
// Don't analyze anything if in PRIVACY_NOSTATS mode
|
// Don't analyze anything if in PRIVACY_NOSTATS mode
|
||||||
if(config.privacylevel >= PRIVACY_NOSTATS)
|
if(config.privacylevel >= PRIVACY_NOSTATS)
|
||||||
@@ -785,8 +846,8 @@ void _FTL_dnssec(int status, int id, const char* file, const int line)
|
|||||||
// Process DNSSEC result for a domain
|
// Process DNSSEC result for a domain
|
||||||
lock_shm();
|
lock_shm();
|
||||||
// Search for corresponding query identified by ID
|
// Search for corresponding query identified by ID
|
||||||
int i = findQueryID(id);
|
const int queryID = findQueryID(id);
|
||||||
if(i < 0)
|
if(queryID < 0)
|
||||||
{
|
{
|
||||||
// This may happen e.g. if the original query was an unhandled query type
|
// This may happen e.g. if the original query was an unhandled query type
|
||||||
unlock_shm();
|
unlock_shm();
|
||||||
@@ -794,7 +855,7 @@ void _FTL_dnssec(int status, int id, const char* file, const int line)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get query pointer
|
// Get query pointer
|
||||||
queriesData* query = getQuery(i, true);
|
queriesData* query = getQuery(queryID, true);
|
||||||
|
|
||||||
// Debug logging
|
// Debug logging
|
||||||
if(config.debug & DEBUG_QUERIES)
|
if(config.debug & DEBUG_QUERIES)
|
||||||
@@ -816,7 +877,7 @@ void _FTL_dnssec(int status, int id, const char* file, const int line)
|
|||||||
unlock_shm();
|
unlock_shm();
|
||||||
}
|
}
|
||||||
|
|
||||||
void _FTL_upstream_error(unsigned int rcode, int id, const char* file, const int line)
|
void _FTL_upstream_error(const unsigned int rcode, const int id, const char* file, const int line)
|
||||||
{
|
{
|
||||||
// Process upstream errors
|
// Process upstream errors
|
||||||
// Queries with error are those where the RCODE
|
// Queries with error are those where the RCODE
|
||||||
@@ -829,8 +890,8 @@ void _FTL_upstream_error(unsigned int rcode, int id, const char* file, const int
|
|||||||
// Process DNSSEC result for a domain
|
// Process DNSSEC result for a domain
|
||||||
lock_shm();
|
lock_shm();
|
||||||
// Search for corresponding query identified by ID
|
// Search for corresponding query identified by ID
|
||||||
int i = findQueryID(id);
|
const int queryID = findQueryID(id);
|
||||||
if(i < 0)
|
if(queryID < 0)
|
||||||
{
|
{
|
||||||
// This may happen e.g. if the original query was an unhandled query type
|
// This may happen e.g. if the original query was an unhandled query type
|
||||||
unlock_shm();
|
unlock_shm();
|
||||||
@@ -838,7 +899,7 @@ void _FTL_upstream_error(unsigned int rcode, int id, const char* file, const int
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get query pointer
|
// Get query pointer
|
||||||
queriesData* query = getQuery(i, true);
|
queriesData* query = getQuery(queryID, true);
|
||||||
|
|
||||||
// Translate dnsmasq's rcode into something we can use
|
// Translate dnsmasq's rcode into something we can use
|
||||||
const char *rcodestr = NULL;
|
const char *rcodestr = NULL;
|
||||||
@@ -901,7 +962,7 @@ void _FTL_header_analysis(const unsigned char header4, const unsigned int rcode,
|
|||||||
lock_shm();
|
lock_shm();
|
||||||
|
|
||||||
// Search for corresponding query identified by ID
|
// Search for corresponding query identified by ID
|
||||||
int queryID = findQueryID(id);
|
const int queryID = findQueryID(id);
|
||||||
if(queryID < 0)
|
if(queryID < 0)
|
||||||
{
|
{
|
||||||
// This may happen e.g. if the original query was an unhandled query type
|
// This may happen e.g. if the original query was an unhandled query type
|
||||||
@@ -932,7 +993,7 @@ void _FTL_header_analysis(const unsigned char header4, const unsigned int rcode,
|
|||||||
unlock_shm();
|
unlock_shm();
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_flags(unsigned int flags)
|
void print_flags(const unsigned int flags)
|
||||||
{
|
{
|
||||||
// Debug function, listing resolver flags in clear text
|
// Debug function, listing resolver flags in clear text
|
||||||
// e.g. "Flags: F_FORWARD F_NEG F_IPV6"
|
// e.g. "Flags: F_FORWARD F_NEG F_IPV6"
|
||||||
@@ -941,16 +1002,15 @@ void print_flags(unsigned int flags)
|
|||||||
if(!(config.debug & DEBUG_FLAGS))
|
if(!(config.debug & DEBUG_FLAGS))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
unsigned int i;
|
|
||||||
char *flagstr = calloc(256,sizeof(char));
|
char *flagstr = calloc(256,sizeof(char));
|
||||||
for(i = 0; i < sizeof(flags)*8; i++)
|
for(unsigned int i = 0; i < sizeof(flags)*8; i++)
|
||||||
if(flags & (1u << i))
|
if(flags & (1u << i))
|
||||||
strcat(flagstr, flagnames[i]);
|
strcat(flagstr, flagnames[i]);
|
||||||
logg(" Flags: %s", flagstr);
|
logg(" Flags: %s", flagstr);
|
||||||
free(flagstr);
|
free(flagstr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void save_reply_type(unsigned int flags, int queryID, struct timeval response)
|
void save_reply_type(const unsigned int flags, const int queryID, const struct timeval response)
|
||||||
{
|
{
|
||||||
// Get query pointer
|
// Get query pointer
|
||||||
queriesData* query = getQuery(queryID, true);
|
queriesData* query = getQuery(queryID, true);
|
||||||
@@ -1079,7 +1139,7 @@ void FTL_fork_and_bind_sockets(struct passwd *ent_pw)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// int cache_inserted, cache_live_freed are defined in dnsmasq/cache.c
|
// int cache_inserted, cache_live_freed are defined in dnsmasq/cache.c
|
||||||
void getCacheInformation(int *sock)
|
void getCacheInformation(const int *sock)
|
||||||
{
|
{
|
||||||
ssend(*sock,"cache-size: %i\ncache-live-freed: %i\ncache-inserted: %i\n",
|
ssend(*sock,"cache-size: %i\ncache-live-freed: %i\ncache-inserted: %i\n",
|
||||||
daemon->cachesize,
|
daemon->cachesize,
|
||||||
@@ -1095,7 +1155,7 @@ void getCacheInformation(int *sock)
|
|||||||
// which hasn't been looked up for the longest time is evicted.
|
// which hasn't been looked up for the longest time is evicted.
|
||||||
}
|
}
|
||||||
|
|
||||||
void _FTL_forwarding_failed(struct server *server, const char* file, const int line)
|
void _FTL_forwarding_failed(const struct server *server, const char* file, const int line)
|
||||||
{
|
{
|
||||||
// Don't analyze anything if in PRIVACY_NOSTATS mode
|
// Don't analyze anything if in PRIVACY_NOSTATS mode
|
||||||
if(config.privacylevel >= PRIVACY_NOSTATS)
|
if(config.privacylevel >= PRIVACY_NOSTATS)
|
||||||
@@ -1112,7 +1172,7 @@ void _FTL_forwarding_failed(struct server *server, const char* file, const int l
|
|||||||
// Convert forward to lower case
|
// Convert forward to lower case
|
||||||
char *forwarddest = strdup(dest);
|
char *forwarddest = strdup(dest);
|
||||||
strtolower(forwarddest);
|
strtolower(forwarddest);
|
||||||
int forwardID = findForwardID(forwarddest, false);
|
const int forwardID = findForwardID(forwarddest, false);
|
||||||
|
|
||||||
if(config.debug & DEBUG_QUERIES) logg("**** forwarding to %s (ID %i, %s:%i) failed", dest, forwardID, file, line);
|
if(config.debug & DEBUG_QUERIES) logg("**** forwarding to %s (ID %i, %s:%i) failed", dest, forwardID, file, line);
|
||||||
|
|
||||||
@@ -1127,7 +1187,7 @@ void _FTL_forwarding_failed(struct server *server, const char* file, const int l
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned long __attribute__((const)) converttimeval(struct timeval time)
|
static unsigned long __attribute__((const)) converttimeval(const struct timeval time)
|
||||||
{
|
{
|
||||||
// Convert time from struct timeval into units
|
// Convert time from struct timeval into units
|
||||||
// of 10*milliseconds
|
// of 10*milliseconds
|
||||||
@@ -1191,8 +1251,8 @@ void rehash(int size);
|
|||||||
// This routine adds one domain to the resolver's cache. Depending on the configured blocking mode it may create
|
// This routine adds one domain to the resolver's cache. Depending on the configured blocking mode it may create
|
||||||
// a single entry valid for IPv4 & IPv6 or two entries one for IPv4 and one for IPv6.
|
// a single entry valid for IPv4 & IPv6 or two entries one for IPv4 and one for IPv6.
|
||||||
// When IPv6 is not available on the machine, we do not add IPv6 cache entries (likewise for IPv4)
|
// When IPv6 is not available on the machine, we do not add IPv6 cache entries (likewise for IPv4)
|
||||||
static int add_blocked_domain(struct all_addr *addr4, struct all_addr *addr6, bool has_IPv4, bool has_IPv6,
|
static int add_blocked_domain(struct all_addr *addr4, struct all_addr *addr6, const bool has_IPv4, const bool has_IPv6,
|
||||||
char *domain, int len, struct crec **rhash, int hashsz, unsigned int index)
|
const char *domain, const int len, struct crec **rhash, int hashsz, unsigned int index)
|
||||||
{
|
{
|
||||||
int name_count = 0;
|
int name_count = 0;
|
||||||
struct crec *cache4,*cache6;
|
struct crec *cache4,*cache6;
|
||||||
@@ -1246,7 +1306,7 @@ static int add_blocked_domain(struct all_addr *addr4, struct all_addr *addr6, bo
|
|||||||
// Add a single domain to resolver's cache. This respects the configured blocking mode
|
// Add a single domain to resolver's cache. This respects the configured blocking mode
|
||||||
// Note: This routine is meant for adding a single domain at a time. It should not be
|
// Note: This routine is meant for adding a single domain at a time. It should not be
|
||||||
// invoked for batch processing
|
// invoked for batch processing
|
||||||
static void block_single_domain_regex(char *domain)
|
static void block_single_domain_regex(const char *domain)
|
||||||
{
|
{
|
||||||
struct all_addr addr4 = {{{ 0 }}}, addr6 = {{{ 0 }}};
|
struct all_addr addr4 = {{{ 0 }}}, addr6 = {{{ 0 }}};
|
||||||
bool has_IPv4 = false, has_IPv6 = false;
|
bool has_IPv4 = false, has_IPv6 = false;
|
||||||
@@ -1261,7 +1321,7 @@ static void block_single_domain_regex(char *domain)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int FTL_listsfile(char* filename, unsigned int index, FILE *f, int cache_size, struct crec **rhash, int hashsz)
|
int FTL_listsfile(const char* filename, unsigned int index, FILE *f, int cache_size, struct crec **rhash, int hashsz)
|
||||||
{
|
{
|
||||||
int name_count = cache_size;
|
int name_count = cache_size;
|
||||||
int added = 0;
|
int added = 0;
|
||||||
|
|||||||
@@ -12,29 +12,29 @@ extern unsigned char* pihole_privacylevel;
|
|||||||
enum { TCP, UDP };
|
enum { TCP, UDP };
|
||||||
|
|
||||||
#define FTL_new_query(flags, name, addr, types, id, type) _FTL_new_query(flags, name, addr, types, id, type, __FILE__, __LINE__)
|
#define FTL_new_query(flags, name, addr, types, id, type) _FTL_new_query(flags, name, addr, types, id, type, __FILE__, __LINE__)
|
||||||
void _FTL_new_query(unsigned int flags, char *name, struct all_addr *addr, char *types, int id, char type, const char* file, const int line);
|
void _FTL_new_query(const unsigned int flags, const char *name, const struct all_addr *addr, const char *types, const int id, const char type, const char* file, const int line);
|
||||||
|
|
||||||
#define FTL_forwarded(flags, name, addr, id) _FTL_forwarded(flags, name, addr, id, __FILE__, __LINE__)
|
#define FTL_forwarded(flags, name, addr, id) _FTL_forwarded(flags, name, addr, id, __FILE__, __LINE__)
|
||||||
void _FTL_forwarded(unsigned int flags, char *name, struct all_addr *addr, int id, const char* file, const int line);
|
void _FTL_forwarded(const unsigned int flags, const char *name, const struct all_addr *addr, const int id, const char* file, const int line);
|
||||||
|
|
||||||
#define FTL_reply(flags, name, addr, id) _FTL_reply(flags, name, addr, id, __FILE__, __LINE__)
|
#define FTL_reply(flags, name, addr, id) _FTL_reply(flags, name, addr, id, __FILE__, __LINE__)
|
||||||
void _FTL_reply(unsigned short flags, char *name, struct all_addr *addr, int id, const char* file, const int line);
|
void _FTL_reply(const unsigned short flags, const char *name, const struct all_addr *addr, const int id, const char* file, const int line);
|
||||||
|
|
||||||
#define FTL_cache(flags, name, addr, arg, id) _FTL_cache(flags, name, addr, arg, id, __FILE__, __LINE__)
|
#define FTL_cache(flags, name, addr, arg, id) _FTL_cache(flags, name, addr, arg, id, __FILE__, __LINE__)
|
||||||
void _FTL_cache(unsigned int flags, char *name, struct all_addr *addr, char * arg, int id, const char* file, const int line);
|
void _FTL_cache(const unsigned int flags, const char *name, const struct all_addr *addr, const char * arg, const int id, const char* file, const int line);
|
||||||
|
|
||||||
#define FTL_dnssec(status, id) _FTL_dnssec(status, id, __FILE__, __LINE__)
|
#define FTL_dnssec(status, id) _FTL_dnssec(status, id, __FILE__, __LINE__)
|
||||||
void _FTL_dnssec(int status, int id, const char* file, const int line);
|
void _FTL_dnssec(const int status, const int id, const char* file, const int line);
|
||||||
|
|
||||||
#define FTL_header_analysis(header4, rcode, id) _FTL_header_analysis(header4, rcode, id, __FILE__, __LINE__)
|
#define FTL_header_analysis(header4, rcode, id) _FTL_header_analysis(header4, rcode, id, __FILE__, __LINE__)
|
||||||
void _FTL_header_analysis(unsigned char header4, unsigned int rcode, int id, const char* file, const int line);
|
void _FTL_header_analysis(const unsigned char header4, const unsigned int rcode, const int id, const char* file, const int line);
|
||||||
|
|
||||||
#define FTL_forwarding_failed(server) _FTL_forwarding_failed(server, __FILE__, __LINE__)
|
#define FTL_forwarding_failed(server) _FTL_forwarding_failed(server, __FILE__, __LINE__)
|
||||||
void _FTL_forwarding_failed(struct server *server, const char* file, const int line);
|
void _FTL_forwarding_failed(const struct server *server, const char* file, const int line);
|
||||||
|
|
||||||
#define FTL_upstream_error(rcode, id) _FTL_upstream_error(rcode, id, __FILE__, __LINE__)
|
#define FTL_upstream_error(rcode, id) _FTL_upstream_error(rcode, id, __FILE__, __LINE__)
|
||||||
void _FTL_upstream_error(unsigned int rcode, int id, const char* file, const int line);
|
void _FTL_upstream_error(const unsigned int rcode, const int id, const char* file, const int line);
|
||||||
|
|
||||||
void FTL_dnsmasq_reload(void);
|
void FTL_dnsmasq_reload(void);
|
||||||
void FTL_fork_and_bind_sockets(struct passwd *ent_pw);
|
void FTL_fork_and_bind_sockets(struct passwd *ent_pw);
|
||||||
int FTL_listsfile(char* filename, unsigned int index, FILE *f, int cache_size, struct crec **rhash, int hashsz);
|
int FTL_listsfile(const char* filename, unsigned int index, FILE *f, int cache_size, struct crec **rhash, int hashsz);
|
||||||
|
|||||||
8
gc.c
8
gc.c
@@ -44,12 +44,11 @@ void *GC_thread(void *val)
|
|||||||
|
|
||||||
if(config.debug & DEBUG_GC) timer_start(GC_TIMER);
|
if(config.debug & DEBUG_GC) timer_start(GC_TIMER);
|
||||||
|
|
||||||
long int i;
|
|
||||||
int removed = 0;
|
int removed = 0;
|
||||||
if(config.debug & DEBUG_GC) logg("GC starting, mintime: %lu %s", mintime, ctime(&mintime));
|
if(config.debug & DEBUG_GC) logg("GC starting, mintime: %lu %s", mintime, ctime(&mintime));
|
||||||
|
|
||||||
// Process all queries
|
// Process all queries
|
||||||
for(i=0; i < counters->queries; i++)
|
for(long int i=0; i < counters->queries; i++)
|
||||||
{
|
{
|
||||||
queriesData* query = getQuery(i, true);
|
queriesData* query = getQuery(i, true);
|
||||||
// Test if this query is too new
|
// Test if this query is too new
|
||||||
@@ -61,7 +60,7 @@ void *GC_thread(void *val)
|
|||||||
client->count--;
|
client->count--;
|
||||||
|
|
||||||
// Adjust total counters and total over time data
|
// Adjust total counters and total over time data
|
||||||
int timeidx = query->timeidx;
|
const int timeidx = query->timeidx;
|
||||||
overTime[timeidx].total--;
|
overTime[timeidx].total--;
|
||||||
// Adjust corresponding overTime counters
|
// Adjust corresponding overTime counters
|
||||||
client->overTime[timeidx]--;
|
client->overTime[timeidx]--;
|
||||||
@@ -169,7 +168,8 @@ void *GC_thread(void *val)
|
|||||||
// Determine if overTime memory needs to get moved
|
// Determine if overTime memory needs to get moved
|
||||||
moveOverTimeMemory(mintime);
|
moveOverTimeMemory(mintime);
|
||||||
|
|
||||||
if(config.debug & DEBUG_GC) logg("Notice: GC removed %i queries (took %.2f ms)", removed, timer_elapsed_msec(GC_TIMER));
|
if(config.debug & DEBUG_GC)
|
||||||
|
logg("Notice: GC removed %i queries (took %.2f ms)", removed, timer_elapsed_msec(GC_TIMER));
|
||||||
|
|
||||||
// Release thread lock
|
// Release thread lock
|
||||||
unlock_shm();
|
unlock_shm();
|
||||||
|
|||||||
2
grep.c
2
grep.c
@@ -105,7 +105,7 @@ int countlineswith(const char* str, const char* fname)
|
|||||||
|
|
||||||
void check_blocking_status(void)
|
void check_blocking_status(void)
|
||||||
{
|
{
|
||||||
char* blocking = read_setupVarsconf("BLOCKING_ENABLED");
|
const char* blocking = read_setupVarsconf("BLOCKING_ENABLED");
|
||||||
const char* message;
|
const char* message;
|
||||||
|
|
||||||
if(blocking == NULL || getSetupVarsBool(blocking))
|
if(blocking == NULL || getSetupVarsBool(blocking))
|
||||||
|
|||||||
23
log.c
23
log.c
@@ -11,8 +11,8 @@
|
|||||||
#include "FTL.h"
|
#include "FTL.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
|
|
||||||
pthread_mutex_t lock;
|
static pthread_mutex_t lock;
|
||||||
FILE *logfile = NULL;
|
static FILE *logfile = NULL;
|
||||||
|
|
||||||
static void close_FTL_log(void)
|
static void close_FTL_log(void)
|
||||||
{
|
{
|
||||||
@@ -20,7 +20,7 @@ static void close_FTL_log(void)
|
|||||||
fclose(logfile);
|
fclose(logfile);
|
||||||
}
|
}
|
||||||
|
|
||||||
void open_FTL_log(bool test)
|
void open_FTL_log(const bool test)
|
||||||
{
|
{
|
||||||
if(test)
|
if(test)
|
||||||
{
|
{
|
||||||
@@ -52,11 +52,11 @@ void open_FTL_log(bool test)
|
|||||||
|
|
||||||
static void get_timestr(char *timestring)
|
static void get_timestr(char *timestring)
|
||||||
{
|
{
|
||||||
time_t t = time(NULL);
|
const time_t t = time(NULL);
|
||||||
struct tm tm = *localtime(&t);
|
const struct tm tm = *localtime(&t);
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
gettimeofday(&tv, NULL);
|
gettimeofday(&tv, NULL);
|
||||||
int millisec = tv.tv_usec/1000;
|
const int millisec = tv.tv_usec/1000;
|
||||||
|
|
||||||
sprintf(timestring,"%d-%02d-%02d %02d:%02d:%02d.%03i", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, millisec);
|
sprintf(timestring,"%d-%02d-%02d %02d:%02d:%02d.%03i", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, millisec);
|
||||||
}
|
}
|
||||||
@@ -72,7 +72,7 @@ void __attribute__ ((format (gnu_printf, 1, 2))) logg(const char *format, ...)
|
|||||||
|
|
||||||
// Get and log PID of current process to avoid ambiguities when more than one
|
// Get and log PID of current process to avoid ambiguities when more than one
|
||||||
// pihole-FTL instance is logging into the same file
|
// pihole-FTL instance is logging into the same file
|
||||||
long pid = (long)getpid();
|
const long pid = (long)getpid();
|
||||||
|
|
||||||
// Print to stdout before writing to file
|
// Print to stdout before writing to file
|
||||||
if(!daemonmode)
|
if(!daemonmode)
|
||||||
@@ -108,7 +108,7 @@ void __attribute__ ((format (gnu_printf, 1, 2))) logg(const char *format, ...)
|
|||||||
pthread_mutex_unlock(&lock);
|
pthread_mutex_unlock(&lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void format_memory_size(char *prefix, unsigned long int bytes, double *formated)
|
void format_memory_size(char *prefix, const unsigned long int bytes, double *formated)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
*formated = bytes;
|
*formated = bytes;
|
||||||
@@ -124,11 +124,6 @@ void format_memory_size(char *prefix, unsigned long int bytes, double *formated)
|
|||||||
strcpy(prefix, prefixes[i]);
|
strcpy(prefix, prefixes[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void logg_struct_resize(const char* str, int to, int step)
|
|
||||||
{
|
|
||||||
logg("Notice: Increasing %s struct size from %i to %i", str, (to-step), to);
|
|
||||||
}
|
|
||||||
|
|
||||||
void log_counter_info(void)
|
void log_counter_info(void)
|
||||||
{
|
{
|
||||||
logg(" -> Total DNS queries: %i", counters->queries);
|
logg(" -> Total DNS queries: %i", counters->queries);
|
||||||
@@ -141,7 +136,7 @@ void log_counter_info(void)
|
|||||||
logg(" -> Known forward destinations: %i", counters->forwarded);
|
logg(" -> Known forward destinations: %i", counters->forwarded);
|
||||||
}
|
}
|
||||||
|
|
||||||
void log_FTL_version(bool crashreport)
|
void log_FTL_version(const bool crashreport)
|
||||||
{
|
{
|
||||||
logg("FTL branch: %s", GIT_BRANCH);
|
logg("FTL branch: %s", GIT_BRANCH);
|
||||||
logg("FTL version: %s", GIT_TAG);
|
logg("FTL version: %s", GIT_TAG);
|
||||||
|
|||||||
10
memory.c
10
memory.c
@@ -44,7 +44,7 @@ ConfigStruct config;
|
|||||||
// not be protected by our (error logging) functions!
|
// not be protected by our (error logging) functions!
|
||||||
|
|
||||||
#undef strdup
|
#undef strdup
|
||||||
char* __attribute__((malloc)) FTLstrdup(const char *src, const char * file, const char * function, int line)
|
char* __attribute__((malloc)) FTLstrdup(const char *src, const char * file, const char * function, const int line)
|
||||||
{
|
{
|
||||||
// The FTLstrdup() function returns a pointer to a new string which is a
|
// The FTLstrdup() function returns a pointer to a new string which is a
|
||||||
// duplicate of the string s. Memory for the new string is obtained with
|
// duplicate of the string s. Memory for the new string is obtained with
|
||||||
@@ -54,7 +54,7 @@ char* __attribute__((malloc)) FTLstrdup(const char *src, const char * file, cons
|
|||||||
logg("WARN: Trying to copy a NULL string in %s() (%s:%i)", function, file, line);
|
logg("WARN: Trying to copy a NULL string in %s() (%s:%i)", function, file, line);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
size_t len = strlen(src);
|
const size_t len = strlen(src);
|
||||||
char *dest = calloc(len+1, sizeof(char));
|
char *dest = calloc(len+1, sizeof(char));
|
||||||
if(dest == NULL)
|
if(dest == NULL)
|
||||||
{
|
{
|
||||||
@@ -69,7 +69,7 @@ char* __attribute__((malloc)) FTLstrdup(const char *src, const char * file, cons
|
|||||||
}
|
}
|
||||||
|
|
||||||
#undef calloc
|
#undef calloc
|
||||||
void* __attribute__((malloc)) __attribute__((alloc_size(1,2))) FTLcalloc(size_t nmemb, size_t size, const char * file, const char * function, int line)
|
void* __attribute__((malloc)) __attribute__((alloc_size(1,2))) FTLcalloc(const size_t nmemb, const size_t size, const char * file, const char * function, const int line)
|
||||||
{
|
{
|
||||||
// The FTLcalloc() function allocates memory for an array of nmemb elements
|
// The FTLcalloc() function allocates memory for an array of nmemb elements
|
||||||
// of size bytes each and returns a pointer to the allocated memory. The
|
// of size bytes each and returns a pointer to the allocated memory. The
|
||||||
@@ -85,7 +85,7 @@ void* __attribute__((malloc)) __attribute__((alloc_size(1,2))) FTLcalloc(size_t
|
|||||||
}
|
}
|
||||||
|
|
||||||
#undef realloc
|
#undef realloc
|
||||||
void __attribute__((alloc_size(2))) *FTLrealloc(void *ptr_in, size_t size, const char * file, const char * function, int line)
|
void __attribute__((alloc_size(2))) *FTLrealloc(void *ptr_in, const size_t size, const char * file, const char * function, const int line)
|
||||||
{
|
{
|
||||||
// The FTLrealloc() function changes the size of the memory block pointed to
|
// The FTLrealloc() function changes the size of the memory block pointed to
|
||||||
// by ptr to size bytes. The contents will be unchanged in the range from
|
// by ptr to size bytes. The contents will be unchanged in the range from
|
||||||
@@ -106,7 +106,7 @@ void __attribute__((alloc_size(2))) *FTLrealloc(void *ptr_in, size_t size, const
|
|||||||
}
|
}
|
||||||
|
|
||||||
#undef free
|
#undef free
|
||||||
void FTLfree(void *ptr, const char * file, const char * function, int line)
|
void FTLfree(void *ptr, const char * file, const char * function, const int line)
|
||||||
{
|
{
|
||||||
// The free() function frees the memory space pointed to by ptr, which
|
// The free() function frees the memory space pointed to by ptr, which
|
||||||
// must have been returned by a previous call to malloc(), calloc(), or
|
// must have been returned by a previous call to malloc(), calloc(), or
|
||||||
|
|||||||
44
msgpack.c
44
msgpack.c
@@ -11,19 +11,19 @@
|
|||||||
#include "FTL.h"
|
#include "FTL.h"
|
||||||
#include "api.h"
|
#include "api.h"
|
||||||
|
|
||||||
void pack_eom(int sock) {
|
void pack_eom(const int sock) {
|
||||||
// This byte is explicitly never used in the MessagePack spec, so it is perfect to use as an EOM for this API.
|
// This byte is explicitly never used in the MessagePack spec, so it is perfect to use as an EOM for this API.
|
||||||
uint8_t eom = 0xc1;
|
uint8_t eom = 0xc1;
|
||||||
swrite(sock, &eom, sizeof(eom));
|
swrite(sock, &eom, sizeof(eom));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pack_basic(int sock, uint8_t format, void *value, size_t size) {
|
static void pack_basic(const int sock, const uint8_t format, const void *value, const size_t size) {
|
||||||
swrite(sock, &format, sizeof(format));
|
swrite(sock, &format, sizeof(format));
|
||||||
swrite(sock, value, size);
|
swrite(sock, value, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint64_t __attribute__((const)) leToBe64(uint64_t value) {
|
static uint64_t __attribute__((const)) leToBe64(const uint64_t value) {
|
||||||
char *ptr = (char *) &value;
|
const char *ptr = (char *) &value;
|
||||||
uint32_t part1, part2;
|
uint32_t part1, part2;
|
||||||
|
|
||||||
// Copy the two halves of the 64 bit input into uint32_t's so we can use htonl
|
// Copy the two halves of the 64 bit input into uint32_t's so we can use htonl
|
||||||
@@ -38,26 +38,26 @@ static uint64_t __attribute__((const)) leToBe64(uint64_t value) {
|
|||||||
return (uint64_t) part1 << 32 | part2;
|
return (uint64_t) part1 << 32 | part2;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pack_bool(int sock, bool value) {
|
void pack_bool(const int sock, const bool value) {
|
||||||
uint8_t packed = (uint8_t) (value ? 0xc3 : 0xc2);
|
uint8_t packed = (uint8_t) (value ? 0xc3 : 0xc2);
|
||||||
swrite(sock, &packed, sizeof(packed));
|
swrite(sock, &packed, sizeof(packed));
|
||||||
}
|
}
|
||||||
|
|
||||||
void pack_uint8(int sock, uint8_t value) {
|
void pack_uint8(const int sock, const uint8_t value) {
|
||||||
pack_basic(sock, 0xcc, &value, sizeof(value));
|
pack_basic(sock, 0xcc, &value, sizeof(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
void pack_uint64(int sock, uint64_t value) {
|
void pack_uint64(const int sock, const uint64_t value) {
|
||||||
uint64_t bigEValue = leToBe64(value);
|
const uint64_t bigEValue = leToBe64(value);
|
||||||
pack_basic(sock, 0xcf, &bigEValue, sizeof(bigEValue));
|
pack_basic(sock, 0xcf, &bigEValue, sizeof(bigEValue));
|
||||||
}
|
}
|
||||||
|
|
||||||
void pack_int32(int sock, int32_t value) {
|
void pack_int32(const int sock, const int32_t value) {
|
||||||
uint32_t bigEValue = htonl((uint32_t) value);
|
const uint32_t bigEValue = htonl((uint32_t) value);
|
||||||
pack_basic(sock, 0xd2, &bigEValue, sizeof(bigEValue));
|
pack_basic(sock, 0xd2, &bigEValue, sizeof(bigEValue));
|
||||||
}
|
}
|
||||||
|
|
||||||
void pack_int64(int sock, int64_t value) {
|
void pack_int64(const int sock, const int64_t value) {
|
||||||
// Need to use memcpy to do a direct copy without reinterpreting the bytes (making negatives into positives).
|
// Need to use memcpy to do a direct copy without reinterpreting the bytes (making negatives into positives).
|
||||||
// It should get optimized away.
|
// It should get optimized away.
|
||||||
uint64_t bigEValue;
|
uint64_t bigEValue;
|
||||||
@@ -66,7 +66,7 @@ void pack_int64(int sock, int64_t value) {
|
|||||||
pack_basic(sock, 0xd3, &bigEValue, sizeof(bigEValue));
|
pack_basic(sock, 0xd3, &bigEValue, sizeof(bigEValue));
|
||||||
}
|
}
|
||||||
|
|
||||||
void pack_float(int sock, float value) {
|
void pack_float(const int sock, const float value) {
|
||||||
// Need to use memcpy to do a direct copy without reinterpreting the bytes. It should get optimized away.
|
// Need to use memcpy to do a direct copy without reinterpreting the bytes. It should get optimized away.
|
||||||
uint32_t bigEValue;
|
uint32_t bigEValue;
|
||||||
memcpy(&bigEValue, &value, sizeof(bigEValue));
|
memcpy(&bigEValue, &value, sizeof(bigEValue));
|
||||||
@@ -75,16 +75,16 @@ void pack_float(int sock, float value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Return true if successful
|
// Return true if successful
|
||||||
bool pack_fixstr(int sock, const char *string) {
|
bool pack_fixstr(const int sock, const char *string) {
|
||||||
// Make sure that the length is less than 32
|
// Make sure that the length is less than 32
|
||||||
size_t length = strlen(string);
|
const size_t length = strlen(string);
|
||||||
|
|
||||||
if(length >= 32) {
|
if(length >= 32) {
|
||||||
logg("Tried to send a fixstr longer than 31 bytes!");
|
logg("Tried to send a fixstr longer than 31 bytes!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t format = (uint8_t) (0xA0 | length);
|
const uint8_t format = (uint8_t) (0xA0 | length);
|
||||||
swrite(sock, &format, sizeof(format));
|
swrite(sock, &format, sizeof(format));
|
||||||
swrite(sock, string, length);
|
swrite(sock, string, length);
|
||||||
|
|
||||||
@@ -92,27 +92,27 @@ bool pack_fixstr(int sock, const char *string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Return true if successful
|
// Return true if successful
|
||||||
bool pack_str32(int sock, const char *string) {
|
bool pack_str32(const int sock, const char *string) {
|
||||||
// Make sure that the length is less than 4294967296
|
// Make sure that the length is less than 4294967296
|
||||||
size_t length = strlen(string);
|
const size_t length = strlen(string);
|
||||||
|
|
||||||
if(length >= 2147483648u) {
|
if(length >= 2147483648u) {
|
||||||
logg("Tried to send a str32 longer than 2147483647 bytes!");
|
logg("Tried to send a str32 longer than 2147483647 bytes!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t format = 0xdb;
|
const uint8_t format = 0xdb;
|
||||||
swrite(sock, &format, sizeof(format));
|
swrite(sock, &format, sizeof(format));
|
||||||
uint32_t bigELength = htonl((uint32_t) length);
|
const uint32_t bigELength = htonl((uint32_t) length);
|
||||||
swrite(sock, &bigELength, sizeof(bigELength));
|
swrite(sock, &bigELength, sizeof(bigELength));
|
||||||
swrite(sock, string, length);
|
swrite(sock, string, length);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pack_map16_start(int sock, uint16_t length) {
|
void pack_map16_start(const int sock, const uint16_t length) {
|
||||||
uint8_t format = 0xde;
|
const uint8_t format = 0xde;
|
||||||
swrite(sock, &format, sizeof(format));
|
swrite(sock, &format, sizeof(format));
|
||||||
uint16_t bigELength = htons(length);
|
const uint16_t bigELength = htons(length);
|
||||||
swrite(sock, &bigELength, sizeof(bigELength));
|
swrite(sock, &bigELength, sizeof(bigELength));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ void parse_arp_cache(void)
|
|||||||
char * linebuffer = NULL;
|
char * linebuffer = NULL;
|
||||||
size_t linebuffersize = 0;
|
size_t linebuffersize = 0;
|
||||||
char ip[100], mask[100], hwaddr[100], iface[100];
|
char ip[100], mask[100], hwaddr[100], iface[100];
|
||||||
int type, flags, entries = 0;
|
unsigned int type, flags, entries = 0;
|
||||||
time_t now = time(NULL);
|
time_t now = time(NULL);
|
||||||
|
|
||||||
// Start collecting database commands
|
// Start collecting database commands
|
||||||
@@ -102,7 +102,7 @@ void parse_arp_cache(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Perform SQL query
|
// Perform SQL query
|
||||||
int dbID = db_query_int(querystr);
|
const int dbID = db_query_int(querystr);
|
||||||
free(querystr);
|
free(querystr);
|
||||||
|
|
||||||
if(dbID == DB_FAILED)
|
if(dbID == DB_FAILED)
|
||||||
@@ -122,6 +122,8 @@ void parse_arp_cache(void)
|
|||||||
// Get client pointer
|
// Get client pointer
|
||||||
clientsData* client = NULL;
|
clientsData* client = NULL;
|
||||||
|
|
||||||
|
// This client is known (by its IP address) to pihole-FTL if
|
||||||
|
// findClientID() returned a non-negative index
|
||||||
if(clientID >= 0)
|
if(clientID >= 0)
|
||||||
{
|
{
|
||||||
client = getClient(clientID, true);
|
client = getClient(clientID, true);
|
||||||
@@ -184,7 +186,8 @@ void parse_arp_cache(void)
|
|||||||
unlock_shm();
|
unlock_shm();
|
||||||
|
|
||||||
// Debug logging
|
// Debug logging
|
||||||
if(config.debug & DEBUG_ARP) logg("ARP table processing (%i entries) took %.1f ms", entries, timer_elapsed_msec(ARP_TIMER));
|
if(config.debug & DEBUG_ARP)
|
||||||
|
logg("ARP table processing (%i entries) took %.1f ms", entries, timer_elapsed_msec(ARP_TIMER));
|
||||||
|
|
||||||
// Close file handle
|
// Close file handle
|
||||||
fclose(arpfp);
|
fclose(arpfp);
|
||||||
@@ -199,13 +202,15 @@ static char* getMACVendor(const char* hwaddr)
|
|||||||
if(stat(FTLfiles.macvendordb, &st) != 0)
|
if(stat(FTLfiles.macvendordb, &st) != 0)
|
||||||
{
|
{
|
||||||
// File does not exist
|
// File does not exist
|
||||||
if(config.debug & DEBUG_ARP) logg("getMACVenor(%s): %s does not exist", hwaddr, FTLfiles.macvendordb);
|
if(config.debug & DEBUG_ARP)
|
||||||
|
logg("getMACVenor(%s): %s does not exist", hwaddr, FTLfiles.macvendordb);
|
||||||
return strdup("");
|
return strdup("");
|
||||||
}
|
}
|
||||||
else if(strlen(hwaddr) != 17)
|
else if(strlen(hwaddr) != 17)
|
||||||
{
|
{
|
||||||
// MAC address is incomplete
|
// MAC address is incomplete
|
||||||
if(config.debug & DEBUG_ARP) logg("getMACVenor(%s): MAC invalid (length %zu)", hwaddr, strlen(hwaddr));
|
if(config.debug & DEBUG_ARP)
|
||||||
|
logg("getMACVenor(%s): MAC invalid (length %zu)", hwaddr, strlen(hwaddr));
|
||||||
return strdup("");
|
return strdup("");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -269,7 +274,8 @@ void updateMACVendorRecords()
|
|||||||
if(stat(FTLfiles.macvendordb, &st) != 0)
|
if(stat(FTLfiles.macvendordb, &st) != 0)
|
||||||
{
|
{
|
||||||
// File does not exist
|
// File does not exist
|
||||||
if(config.debug & DEBUG_ARP) logg("updateMACVendorRecords(): %s does not exist", FTLfiles.macvendordb);
|
if(config.debug & DEBUG_ARP)
|
||||||
|
logg("updateMACVendorRecords(): %s does not exist", FTLfiles.macvendordb);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
16
overTime.c
16
overTime.c
@@ -16,7 +16,7 @@
|
|||||||
* @param index The overTime slot index
|
* @param index The overTime slot index
|
||||||
* @param timestamp The timestamp of the slot
|
* @param timestamp The timestamp of the slot
|
||||||
*/
|
*/
|
||||||
static void initSlot(unsigned int index, time_t timestamp)
|
static void initSlot(const unsigned int index, const time_t timestamp)
|
||||||
{
|
{
|
||||||
// Possible debug printing
|
// Possible debug printing
|
||||||
if(config.debug & DEBUG_OVERTIME)
|
if(config.debug & DEBUG_OVERTIME)
|
||||||
@@ -77,10 +77,10 @@ unsigned int getOverTimeID(time_t timestamp)
|
|||||||
timestamp += OVERTIME_INTERVAL/2;
|
timestamp += OVERTIME_INTERVAL/2;
|
||||||
|
|
||||||
// Get timestamp of first interval
|
// Get timestamp of first interval
|
||||||
time_t firstTimestamp = overTime[0].timestamp;
|
const time_t firstTimestamp = overTime[0].timestamp;
|
||||||
|
|
||||||
// Compute overTime ID
|
// Compute overTime ID
|
||||||
int id = (int) ((timestamp - firstTimestamp) / OVERTIME_INTERVAL);
|
const int id = (int) ((timestamp - firstTimestamp) / OVERTIME_INTERVAL);
|
||||||
|
|
||||||
// Check bounds manually
|
// Check bounds manually
|
||||||
if(id < 0)
|
if(id < 0)
|
||||||
@@ -106,9 +106,9 @@ unsigned int getOverTimeID(time_t timestamp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// This routine is called by garbage collection to rearrange the overTime structure for the next hour
|
// This routine is called by garbage collection to rearrange the overTime structure for the next hour
|
||||||
void moveOverTimeMemory(time_t mintime)
|
void moveOverTimeMemory(const time_t mintime)
|
||||||
{
|
{
|
||||||
time_t oldestOverTimeIS = overTime[0].timestamp;
|
const time_t oldestOverTimeIS = overTime[0].timestamp;
|
||||||
// Shift SHOULD timestemp into the future by the amount GC is running earlier
|
// Shift SHOULD timestemp into the future by the amount GC is running earlier
|
||||||
time_t oldestOverTimeSHOULD = mintime;
|
time_t oldestOverTimeSHOULD = mintime;
|
||||||
|
|
||||||
@@ -118,10 +118,10 @@ void moveOverTimeMemory(time_t mintime)
|
|||||||
|
|
||||||
// Calculate the number of slots to be garbage collected, which is also the
|
// Calculate the number of slots to be garbage collected, which is also the
|
||||||
// ID of the slot to move to the zero position
|
// ID of the slot to move to the zero position
|
||||||
unsigned int moveOverTime = (unsigned int) ((oldestOverTimeSHOULD - oldestOverTimeIS) / OVERTIME_INTERVAL);
|
const unsigned int moveOverTime = (unsigned int) ((oldestOverTimeSHOULD - oldestOverTimeIS) / OVERTIME_INTERVAL);
|
||||||
|
|
||||||
// The number of slots which will be moved (not garbage collected)
|
// The number of slots which will be moved (not garbage collected)
|
||||||
unsigned int remainingSlots = OVERTIME_SLOTS - moveOverTime;
|
const unsigned int remainingSlots = OVERTIME_SLOTS - moveOverTime;
|
||||||
|
|
||||||
if(config.debug & DEBUG_OVERTIME)
|
if(config.debug & DEBUG_OVERTIME)
|
||||||
{
|
{
|
||||||
@@ -176,7 +176,7 @@ void moveOverTimeMemory(time_t mintime)
|
|||||||
for(unsigned int timeidx = remainingSlots; timeidx < OVERTIME_SLOTS ; timeidx++)
|
for(unsigned int timeidx = remainingSlots; timeidx < OVERTIME_SLOTS ; timeidx++)
|
||||||
{
|
{
|
||||||
// This slot is OVERTIME_INTERVAL seconds after the previous slot
|
// This slot is OVERTIME_INTERVAL seconds after the previous slot
|
||||||
time_t timestamp = overTime[timeidx-1].timestamp + OVERTIME_INTERVAL;
|
const time_t timestamp = overTime[timeidx-1].timestamp + OVERTIME_INTERVAL;
|
||||||
initSlot(timeidx, timestamp);
|
initSlot(timeidx, timestamp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
15
regex.c
15
regex.c
@@ -17,22 +17,22 @@ static bool *regexconfigured = NULL;
|
|||||||
static char **regexbuffer = NULL;
|
static char **regexbuffer = NULL;
|
||||||
static whitelistStruct whitelist = { NULL, 0 };
|
static whitelistStruct whitelist = { NULL, 0 };
|
||||||
|
|
||||||
static void log_regex_error(const char *where, int errcode, int index)
|
static void log_regex_error(const char *where, const int errcode, const int index)
|
||||||
{
|
{
|
||||||
// Regex failed for some reason (probably user syntax error)
|
// Regex failed for some reason (probably user syntax error)
|
||||||
// Get error string and log it
|
// Get error string and log it
|
||||||
size_t length = regerror(errcode, ®ex[index], NULL, 0);
|
const size_t length = regerror(errcode, ®ex[index], NULL, 0);
|
||||||
char *buffer = calloc(length,sizeof(char));
|
char *buffer = calloc(length,sizeof(char));
|
||||||
(void) regerror (errcode, ®ex[index], buffer, length);
|
(void) regerror (errcode, ®ex[index], buffer, length);
|
||||||
logg("ERROR %s regex on line %i: %s (%i)", where, index+1, buffer, errcode);
|
logg("ERROR %s regex on line %i: %s (%i)", where, index+1, buffer, errcode);
|
||||||
free(buffer);
|
free(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool init_regex(const char *regexin, int index)
|
static bool init_regex(const char *regexin, const int index)
|
||||||
{
|
{
|
||||||
// compile regular expressions into data structures that
|
// compile regular expressions into data structures that
|
||||||
// can be used with regexec to match against a string
|
// can be used with regexec to match against a string
|
||||||
int errcode = regcomp(®ex[index], regexin, REG_EXTENDED);
|
const int errcode = regcomp(®ex[index], regexin, REG_EXTENDED);
|
||||||
if(errcode != 0)
|
if(errcode != 0)
|
||||||
{
|
{
|
||||||
log_regex_error("compiling", errcode, index);
|
log_regex_error("compiling", errcode, index);
|
||||||
@@ -47,7 +47,7 @@ static bool init_regex(const char *regexin, int index)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool __attribute__((pure)) in_whitelist(char *domain)
|
bool __attribute__((pure)) in_whitelist(const char *domain)
|
||||||
{
|
{
|
||||||
bool found = false;
|
bool found = false;
|
||||||
for(int i=0; i < whitelist.count; i++)
|
for(int i=0; i < whitelist.count; i++)
|
||||||
@@ -77,14 +77,13 @@ static void free_whitelist_domains(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool match_regex(char *input)
|
bool match_regex(const char *input)
|
||||||
{
|
{
|
||||||
int index;
|
|
||||||
bool matched = false;
|
bool matched = false;
|
||||||
|
|
||||||
// Start matching timer
|
// Start matching timer
|
||||||
timer_start(REGEX_TIMER);
|
timer_start(REGEX_TIMER);
|
||||||
for(index = 0; index < num_regex; index++)
|
for(int index = 0; index < num_regex; index++)
|
||||||
{
|
{
|
||||||
// Only check regex which have been successfully compiled
|
// Only check regex which have been successfully compiled
|
||||||
if(!regexconfigured[index])
|
if(!regexconfigured[index])
|
||||||
|
|||||||
116
resolve.c
116
resolve.c
@@ -11,15 +11,7 @@
|
|||||||
#include "FTL.h"
|
#include "FTL.h"
|
||||||
#include "shmem.h"
|
#include "shmem.h"
|
||||||
|
|
||||||
// Resolve new client and upstream server host names
|
static char *resolveHostname(const char *addr)
|
||||||
// once every minute
|
|
||||||
#define RESOLVE_INTERVAL 60
|
|
||||||
|
|
||||||
// Re-resolve client names
|
|
||||||
// once every hour
|
|
||||||
#define RERESOLVE_INTERVAL 3600
|
|
||||||
|
|
||||||
static const char *resolveHostname(const char *addr)
|
|
||||||
{
|
{
|
||||||
// Get host name
|
// Get host name
|
||||||
struct hostent *he = NULL;
|
struct hostent *he = NULL;
|
||||||
@@ -71,63 +63,109 @@ static const char *resolveHostname(const char *addr)
|
|||||||
return hostname;
|
return hostname;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resolve client host names
|
// Resolve upstream destination host names
|
||||||
void resolveClients(bool onlynew)
|
static size_t resolveAndAddHostname(size_t ippos, size_t oldnamepos)
|
||||||
{
|
{
|
||||||
for(int clientID = 0; clientID < counters->clients; clientID++)
|
// Get IP and host name strings
|
||||||
|
lock_shm();
|
||||||
|
const char* ipaddr = getstr(ippos);
|
||||||
|
const char* oldname = getstr(oldnamepos);
|
||||||
|
unlock_shm();
|
||||||
|
|
||||||
|
// Important: Don't hold a lock while resolving as the main thread
|
||||||
|
// (dnsmasq) needs to be operable during the call to resolveHostname()
|
||||||
|
char* newname = resolveHostname(ipaddr);
|
||||||
|
|
||||||
|
// Only store new newname if it is valid and differs from oldname
|
||||||
|
// We do not need to check for oldname == NULL as names are
|
||||||
|
// always initialized with an empty string at position 0
|
||||||
|
if(newname != NULL && strcmp(oldname, newname) != 0)
|
||||||
|
{
|
||||||
|
lock_shm();
|
||||||
|
size_t newnamepos = addstr(newname);
|
||||||
|
// newname has already been checked against NULL
|
||||||
|
// so we can safely free it
|
||||||
|
free(newname);
|
||||||
|
unlock_shm();
|
||||||
|
return newnamepos;
|
||||||
|
}
|
||||||
|
else if(config.debug & DEBUG_SHMEM)
|
||||||
|
{
|
||||||
|
// Debugging output
|
||||||
|
logg("Not adding \"%s\" to buffer (unchanged)", oldname);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Not changed, return old namepos
|
||||||
|
return oldnamepos;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Resolve client host names
|
||||||
|
void resolveClients(const bool onlynew)
|
||||||
|
{
|
||||||
|
// Lock counter access here, we use a copy in the following loop
|
||||||
|
lock_shm();
|
||||||
|
int clientscount = counters->clients;
|
||||||
|
unlock_shm();
|
||||||
|
for(int clientID = 0; clientID < clientscount; clientID++)
|
||||||
{
|
{
|
||||||
// Get client pointer
|
// Get client pointer
|
||||||
clientsData* client = getClient(clientID, true);
|
clientsData* client = getClient(clientID, true);
|
||||||
|
|
||||||
// If onlynew flag is set, we will only resolve new clients
|
// Memory access needs to get locked
|
||||||
// If not, we will try to re-resolve all known clients
|
|
||||||
if(onlynew && !client->new)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Lock data when obtaining IP of this client
|
|
||||||
lock_shm();
|
lock_shm();
|
||||||
const char* ipaddr = getstr(client->ippos);
|
bool newflag = client->new;
|
||||||
|
size_t ippos = client->ippos;
|
||||||
|
size_t oldnamepos = client->namepos;
|
||||||
unlock_shm();
|
unlock_shm();
|
||||||
|
|
||||||
// Important: Don't hold a lock while resolving as the main thread
|
// If onlynew flag is set, we will only resolve new clients
|
||||||
// (dnsmasq) needs to be operable during the call to resolveHostname()
|
// If not, we will try to re-resolve all known clients
|
||||||
const char* hostname = resolveHostname(ipaddr);
|
if(onlynew && !newflag)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Obtain/update hostname of this client
|
||||||
|
size_t newnamepos = resolveAndAddHostname(ippos, oldnamepos);
|
||||||
|
|
||||||
// Finally, lock data when storing obtained hostname
|
|
||||||
lock_shm();
|
lock_shm();
|
||||||
client->namepos = addstr(hostname);
|
// Store obtained host name (may be unchanged)
|
||||||
|
client->namepos = newnamepos;
|
||||||
|
// Mark entry as not new
|
||||||
client->new = false;
|
client->new = false;
|
||||||
unlock_shm();
|
unlock_shm();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resolve upstream destination host names
|
// Resolve upstream destination host names
|
||||||
void resolveForwardDestinations(bool onlynew)
|
void resolveForwardDestinations(const bool onlynew)
|
||||||
{
|
{
|
||||||
int forwardID;
|
// Lock counter access here, we use a copy in the following loop
|
||||||
for(forwardID = 0; forwardID < counters->forwarded; forwardID++)
|
lock_shm();
|
||||||
|
int forwardedcount = counters->forwarded;
|
||||||
|
unlock_shm();
|
||||||
|
for(int forwardID = 0; forwardID < forwardedcount; forwardID++)
|
||||||
{
|
{
|
||||||
// Get forward pointer
|
// Get forward pointer
|
||||||
forwardedData* forward = getForward(forwardID, true);
|
forwardedData* forward = getForward(forwardID, true);
|
||||||
|
|
||||||
// If onlynew flag is set, we will only resolve new upstream destinations
|
// Memory access needs to get locked
|
||||||
// If not, we will try to re-resolve all known upstream destinations
|
|
||||||
if(onlynew && !forward->new)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Lock data when obtaining IP of this forward destination
|
|
||||||
lock_shm();
|
lock_shm();
|
||||||
const char* ipaddr = getstr(forward->ippos);
|
bool newflag = forward->new;
|
||||||
|
size_t ippos = forward->ippos;
|
||||||
|
size_t oldnamepos = forward->namepos;
|
||||||
unlock_shm();
|
unlock_shm();
|
||||||
|
|
||||||
|
// If onlynew flag is set, we will only resolve new upstream destinations
|
||||||
|
// If not, we will try to re-resolve all known upstream destinations
|
||||||
|
if(onlynew && !newflag)
|
||||||
|
continue;
|
||||||
|
|
||||||
// Important: Don't hold a lock while resolving as the main thread
|
// Obtain/update hostname of this client
|
||||||
// (dnsmasq) needs to be operable during the call to resolveHostname()
|
size_t newnamepos = resolveAndAddHostname(ippos, oldnamepos);
|
||||||
const char* hostname = resolveHostname(ipaddr);
|
|
||||||
|
|
||||||
// Finally, lock data when storing obtained hostname
|
|
||||||
lock_shm();
|
lock_shm();
|
||||||
forward->namepos = addstr(hostname);
|
// Store obtained host name (may be unchanged)
|
||||||
|
forward->namepos = newnamepos;
|
||||||
|
// Mark entry as not new
|
||||||
forward->new = false;
|
forward->new = false;
|
||||||
unlock_shm();
|
unlock_shm();
|
||||||
}
|
}
|
||||||
|
|||||||
56
routines.h
56
routines.h
@@ -9,36 +9,35 @@
|
|||||||
* Please see LICENSE file for your rights under this license. */
|
* Please see LICENSE file for your rights under this license. */
|
||||||
|
|
||||||
void go_daemon(void);
|
void go_daemon(void);
|
||||||
void timer_start(int i);
|
void timer_start(const int i);
|
||||||
double timer_elapsed_msec(int i);
|
double timer_elapsed_msec(const int i);
|
||||||
void sleepms(int milliseconds);
|
void sleepms(const int milliseconds);
|
||||||
void savepid(void);
|
void savepid(void);
|
||||||
char * getUserName(void);
|
char * getUserName(void);
|
||||||
void removepid(void);
|
void removepid(void);
|
||||||
|
|
||||||
void open_FTL_log(bool test);
|
void open_FTL_log(const bool test);
|
||||||
void logg(const char* format, ...) __attribute__ ((format (gnu_printf, 1, 2)));
|
void logg(const char* format, ...) __attribute__ ((format (gnu_printf, 1, 2)));
|
||||||
void logg_struct_resize(const char* str, int to, int step);
|
|
||||||
void log_counter_info(void);
|
void log_counter_info(void);
|
||||||
void format_memory_size(char *prefix, unsigned long int bytes, double *formated);
|
void format_memory_size(char *prefix, unsigned long int bytes, double *formated);
|
||||||
void log_FTL_version(bool crashreport);
|
void log_FTL_version(bool crashreport);
|
||||||
|
|
||||||
// datastructure.c
|
// datastructure.c
|
||||||
void strtolower(char *str);
|
void strtolower(char *str);
|
||||||
int findForwardID(const char * forward, bool count);
|
int findForwardID(const char * forward, const bool count);
|
||||||
int findDomainID(const char *domain);
|
int findDomainID(const char *domain);
|
||||||
int findClientID(const char *client, bool addNew);
|
int findClientID(const char *client, const bool count);
|
||||||
bool isValidIPv4(const char *addr);
|
bool isValidIPv4(const char *addr);
|
||||||
bool isValidIPv6(const char *addr);
|
bool isValidIPv6(const char *addr);
|
||||||
const char *getDomainString(int queryID);
|
const char *getDomainString(const int queryID);
|
||||||
const char *getClientIPString(int queryID);
|
const char *getClientIPString(const int queryID);
|
||||||
const char *getClientNameString(int queryID);
|
const char *getClientNameString(const int queryID);
|
||||||
|
|
||||||
void close_telnet_socket(void);
|
void close_telnet_socket(void);
|
||||||
void close_unix_socket(void);
|
void close_unix_socket(void);
|
||||||
void seom(int sock);
|
void seom(const int sock);
|
||||||
void ssend(int sock, const char *format, ...) __attribute__ ((format (gnu_printf, 2, 3)));
|
void ssend(const int sock, const char *format, ...) __attribute__ ((format (gnu_printf, 2, 3)));
|
||||||
void swrite(int sock, const void* value, size_t size);
|
void swrite(const int sock, const void* value, const size_t size);
|
||||||
void *telnet_listening_thread_IPv4(void *args);
|
void *telnet_listening_thread_IPv4(void *args);
|
||||||
void *telnet_listening_thread_IPv6(void *args);
|
void *telnet_listening_thread_IPv6(void *args);
|
||||||
|
|
||||||
@@ -48,7 +47,6 @@ void bind_sockets(void);
|
|||||||
|
|
||||||
void process_request(const char *client_message, int *sock);
|
void process_request(const char *client_message, int *sock);
|
||||||
bool command(const char *client_message, const char* cmd) __attribute__((pure));
|
bool command(const char *client_message, const char* cmd) __attribute__((pure));
|
||||||
bool matchesEndpoint(char *client_message, const char *cmd);
|
|
||||||
|
|
||||||
// grep.c
|
// grep.c
|
||||||
int countlines(const char* fname);
|
int countlines(const char* fname);
|
||||||
@@ -84,7 +82,7 @@ void *DB_thread(void *val);
|
|||||||
int get_number_of_queries_in_DB(void);
|
int get_number_of_queries_in_DB(void);
|
||||||
void save_to_DB(void);
|
void save_to_DB(void);
|
||||||
void read_data_from_DB(void);
|
void read_data_from_DB(void);
|
||||||
bool db_set_FTL_property(unsigned int ID, int value);
|
bool db_set_FTL_property(const unsigned int ID, const int value);
|
||||||
bool dbquery(const char *format, ...);
|
bool dbquery(const char *format, ...);
|
||||||
bool dbopen(void);
|
bool dbopen(void);
|
||||||
void dbclose(void);
|
void dbclose(void);
|
||||||
@@ -92,11 +90,11 @@ int db_query_int(const char*);
|
|||||||
void SQLite3LogCallback(void *pArg, int iErrCode, const char *zMsg);
|
void SQLite3LogCallback(void *pArg, int iErrCode, const char *zMsg);
|
||||||
|
|
||||||
// memory.c
|
// memory.c
|
||||||
void memory_check(int which);
|
void memory_check(const int which);
|
||||||
char *FTLstrdup(const char *src, const char *file, const char *function, int line) __attribute__((malloc));
|
char *FTLstrdup(const char *src, const char *file, const char *function, const int line) __attribute__((malloc));
|
||||||
void *FTLcalloc(size_t nmemb, size_t size, const char *file, const char *function, int line) __attribute__((malloc)) __attribute__((alloc_size(1,2)));
|
void *FTLcalloc(size_t nmemb, size_t size, const char *file, const char *function, const int line) __attribute__((malloc)) __attribute__((alloc_size(1,2)));
|
||||||
void *FTLrealloc(void *ptr_in, size_t size, const char *file, const char *function, int line) __attribute__((alloc_size(2)));
|
void *FTLrealloc(void *ptr_in, size_t size, const char *file, const char *function, const int line) __attribute__((alloc_size(2)));
|
||||||
void FTLfree(void *ptr, const char* file, const char *function, int line);
|
void FTLfree(void *ptr, const char* file, const char *function, const int line);
|
||||||
|
|
||||||
int main_dnsmasq(int argc, const char ** argv);
|
int main_dnsmasq(int argc, const char ** argv);
|
||||||
|
|
||||||
@@ -105,27 +103,27 @@ void handle_signals(void);
|
|||||||
|
|
||||||
// resolve.c
|
// resolve.c
|
||||||
void *DNSclient_thread(void *val);
|
void *DNSclient_thread(void *val);
|
||||||
void resolveClients(bool onlynew);
|
void resolveClients(const bool onlynew);
|
||||||
void resolveForwardDestinations(bool onlynew);
|
void resolveForwardDestinations(const bool onlynew);
|
||||||
|
|
||||||
// regex.c
|
// regex.c
|
||||||
bool match_regex(char *input);
|
bool match_regex(const char *input);
|
||||||
void free_regex(void);
|
void free_regex(void);
|
||||||
void read_regex_from_file(void);
|
void read_regex_from_file(void);
|
||||||
bool in_whitelist(char *domain) __attribute__((pure));
|
bool in_whitelist(const char *domain) __attribute__((pure));
|
||||||
|
|
||||||
// shmem.c
|
// shmem.c
|
||||||
bool init_shmem(void);
|
bool init_shmem(void);
|
||||||
void destroy_shmem(void);
|
void destroy_shmem(void);
|
||||||
size_t addstr(const char *str);
|
size_t addstr(const char *str);
|
||||||
const char *getstr(size_t pos);
|
const char *getstr(const size_t pos);
|
||||||
void *enlarge_shmem_struct(char type);
|
void *enlarge_shmem_struct(const char type);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new overTime client shared memory block.
|
* Create a new overTime client shared memory block.
|
||||||
* This also updates `overTimeClientData`.
|
* This also updates `overTimeClientData`.
|
||||||
*/
|
*/
|
||||||
void newOverTimeClient(int clientID);
|
void newOverTimeClient(const int clientID);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a new overTime slot to each overTime client shared memory block.
|
* Add a new overTime slot to each overTime client shared memory block.
|
||||||
@@ -135,7 +133,7 @@ void addOverTimeClientSlot(void);
|
|||||||
|
|
||||||
// overTime.c
|
// overTime.c
|
||||||
void initOverTime(void);
|
void initOverTime(void);
|
||||||
unsigned int getOverTimeID(time_t timestamp);
|
unsigned int getOverTimeID(const time_t timestamp);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Move the overTime slots so the oldest interval starts with mintime. The time
|
* Move the overTime slots so the oldest interval starts with mintime. The time
|
||||||
@@ -143,7 +141,7 @@ unsigned int getOverTimeID(time_t timestamp);
|
|||||||
*
|
*
|
||||||
* @param mintime The start of the oldest interval
|
* @param mintime The start of the oldest interval
|
||||||
*/
|
*/
|
||||||
void moveOverTimeMemory(time_t mintime);
|
void moveOverTimeMemory(const time_t mintime);
|
||||||
|
|
||||||
// capabilities.c
|
// capabilities.c
|
||||||
bool check_capabilities(void);
|
bool check_capabilities(void);
|
||||||
|
|||||||
37
shmem.c
37
shmem.c
@@ -52,7 +52,7 @@ static ShmSettings *shmSettings = NULL;
|
|||||||
static int pagesize;
|
static int pagesize;
|
||||||
static unsigned int local_shm_counter = 0;
|
static unsigned int local_shm_counter = 0;
|
||||||
|
|
||||||
static size_t get_optimal_object_size(size_t objsize, size_t minsize);
|
static size_t get_optimal_object_size(const size_t objsize, const size_t minsize);
|
||||||
|
|
||||||
size_t addstr(const char *str)
|
size_t addstr(const char *str)
|
||||||
{
|
{
|
||||||
@@ -96,7 +96,7 @@ size_t addstr(const char *str)
|
|||||||
return (shmSettings->next_str_pos - (len + 1));
|
return (shmSettings->next_str_pos - (len + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *getstr(size_t pos)
|
const char *getstr(const size_t pos)
|
||||||
{
|
{
|
||||||
// Only access the string memory if this memory region has already been set
|
// Only access the string memory if this memory region has already been set
|
||||||
if(pos < shmSettings->next_str_pos)
|
if(pos < shmSettings->next_str_pos)
|
||||||
@@ -149,17 +149,17 @@ static void remap_shm(void)
|
|||||||
local_shm_counter = shmSettings->global_shm_counter;
|
local_shm_counter = shmSettings->global_shm_counter;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _lock_shm(const char* function, const int line, const char * file) {
|
void _lock_shm(const char* func, const int line, const char * file) {
|
||||||
// Signal that FTL is waiting for a lock
|
// Signal that FTL is waiting for a lock
|
||||||
shmLock->waitingForLock = true;
|
shmLock->waitingForLock = true;
|
||||||
|
|
||||||
if(config.debug & DEBUG_LOCKS)
|
if(config.debug & DEBUG_LOCKS)
|
||||||
logg("Waiting for lock in %s() (%s:%i)", function, file, line);
|
logg("Waiting for lock in %s() (%s:%i)", func, file, line);
|
||||||
|
|
||||||
int result = pthread_mutex_lock(&shmLock->lock);
|
int result = pthread_mutex_lock(&shmLock->lock);
|
||||||
|
|
||||||
if(config.debug & DEBUG_LOCKS)
|
if(config.debug & DEBUG_LOCKS)
|
||||||
logg("Obtained lock for %s() (%s:%i)", function, file, line);
|
logg("Obtained lock for %s() (%s:%i)", func, file, line);
|
||||||
|
|
||||||
// Check if this process needs to remap the shared memory objects
|
// Check if this process needs to remap the shared memory objects
|
||||||
if(shmSettings != NULL &&
|
if(shmSettings != NULL &&
|
||||||
@@ -185,11 +185,11 @@ void _lock_shm(const char* function, const int line, const char * file) {
|
|||||||
logg("Failed to obtain SHM lock: %s", strerror(result));
|
logg("Failed to obtain SHM lock: %s", strerror(result));
|
||||||
}
|
}
|
||||||
|
|
||||||
void _unlock_shm(const char* function, const int line, const char * file) {
|
void _unlock_shm(const char* func, const int line, const char * file) {
|
||||||
int result = pthread_mutex_unlock(&shmLock->lock);
|
int result = pthread_mutex_unlock(&shmLock->lock);
|
||||||
|
|
||||||
if(config.debug & DEBUG_LOCKS)
|
if(config.debug & DEBUG_LOCKS)
|
||||||
logg("Removed lock in %s() (%s:%i)", function, file, line);
|
logg("Removed lock in %s() (%s:%i)", func, file, line);
|
||||||
|
|
||||||
if(result != 0)
|
if(result != 0)
|
||||||
logg("Failed to unlock SHM lock: %s", strerror(result));
|
logg("Failed to unlock SHM lock: %s", strerror(result));
|
||||||
@@ -280,7 +280,7 @@ void destroy_shmem(void)
|
|||||||
delete_shm(&shm_settings);
|
delete_shm(&shm_settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
SharedMemory create_shm(const char *name, size_t size)
|
SharedMemory create_shm(const char *name, const size_t size)
|
||||||
{
|
{
|
||||||
if(config.debug & DEBUG_SHMEM)
|
if(config.debug & DEBUG_SHMEM)
|
||||||
logg("Creating shared memory with name \"%s\" and size %zu", name, size);
|
logg("Creating shared memory with name \"%s\" and size %zu", name, size);
|
||||||
@@ -313,10 +313,10 @@ SharedMemory create_shm(const char *name, size_t size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Resize shared memory file
|
// Resize shared memory file
|
||||||
int result = ftruncate(fd, size);
|
ret = ftruncate(fd, size);
|
||||||
|
|
||||||
// Check for `ftruncate` error
|
// Check for `ftruncate` error
|
||||||
if(result == -1)
|
if(ret == -1)
|
||||||
{
|
{
|
||||||
logg("FATAL: create_shm(): ftruncate(%i, %zu): Failed to resize shared memory object \"%s\": %s",
|
logg("FATAL: create_shm(): ftruncate(%i, %zu): Failed to resize shared memory object \"%s\": %s",
|
||||||
fd, size, sharedMemory.name, strerror(errno));
|
fd, size, sharedMemory.name, strerror(errno));
|
||||||
@@ -342,7 +342,7 @@ SharedMemory create_shm(const char *name, size_t size)
|
|||||||
return sharedMemory;
|
return sharedMemory;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *enlarge_shmem_struct(char type)
|
void *enlarge_shmem_struct(const char type)
|
||||||
{
|
{
|
||||||
SharedMemory *sharedMemory = NULL;
|
SharedMemory *sharedMemory = NULL;
|
||||||
size_t sizeofobj, allocation_step;
|
size_t sizeofobj, allocation_step;
|
||||||
@@ -389,7 +389,7 @@ void *enlarge_shmem_struct(char type)
|
|||||||
return sharedMemory->ptr;
|
return sharedMemory->ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool realloc_shm(SharedMemory *sharedMemory, size_t size, bool resize)
|
bool realloc_shm(SharedMemory *sharedMemory, const size_t size, const bool resize)
|
||||||
{
|
{
|
||||||
// Check if we can skip this routine as nothing is to be done
|
// Check if we can skip this routine as nothing is to be done
|
||||||
// when an object is not to be resized and its size didn't
|
// when an object is not to be resized and its size didn't
|
||||||
@@ -407,7 +407,7 @@ bool realloc_shm(SharedMemory *sharedMemory, size_t size, bool resize)
|
|||||||
if(resize)
|
if(resize)
|
||||||
{
|
{
|
||||||
// Open shared memory object
|
// Open shared memory object
|
||||||
int fd = shm_open(sharedMemory->name, O_RDWR, S_IRUSR | S_IWUSR);
|
const int fd = shm_open(sharedMemory->name, O_RDWR, S_IRUSR | S_IWUSR);
|
||||||
if(fd == -1)
|
if(fd == -1)
|
||||||
{
|
{
|
||||||
logg("FATAL: realloc_shm(): Failed to open shared memory object \"%s\": %s",
|
logg("FATAL: realloc_shm(): Failed to open shared memory object \"%s\": %s",
|
||||||
@@ -416,7 +416,7 @@ bool realloc_shm(SharedMemory *sharedMemory, size_t size, bool resize)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Truncate shared memory object to specified size
|
// Truncate shared memory object to specified size
|
||||||
int result = ftruncate(fd, size);
|
const int result = ftruncate(fd, size);
|
||||||
if(result == -1) {
|
if(result == -1) {
|
||||||
logg("FATAL: realloc_shm(): ftruncate(%i, %zu): Failed to resize \"%s\": %s",
|
logg("FATAL: realloc_shm(): ftruncate(%i, %zu): Failed to resize \"%s\": %s",
|
||||||
fd, size, sharedMemory->name, strerror(errno));
|
fd, size, sharedMemory->name, strerror(errno));
|
||||||
@@ -450,8 +450,7 @@ bool realloc_shm(SharedMemory *sharedMemory, size_t size, bool resize)
|
|||||||
void delete_shm(SharedMemory *sharedMemory)
|
void delete_shm(SharedMemory *sharedMemory)
|
||||||
{
|
{
|
||||||
// Unmap shared memory
|
// Unmap shared memory
|
||||||
int ret;
|
int ret = munmap(sharedMemory->ptr, sharedMemory->size);
|
||||||
ret = munmap(sharedMemory->ptr, sharedMemory->size);
|
|
||||||
if(ret != 0)
|
if(ret != 0)
|
||||||
logg("delete_shm(): munmap(%p, %zu) failed: %s", sharedMemory->ptr, sharedMemory->size, strerror(errno));
|
logg("delete_shm(): munmap(%p, %zu) failed: %s", sharedMemory->ptr, sharedMemory->size, strerror(errno));
|
||||||
|
|
||||||
@@ -478,9 +477,9 @@ static size_t __attribute__((const)) gcd(size_t a, size_t b)
|
|||||||
// shared memory objects. This routine works by computing the LCM
|
// shared memory objects. This routine works by computing the LCM
|
||||||
// of two numbers, the pagesize and the size of a single element
|
// of two numbers, the pagesize and the size of a single element
|
||||||
// in the shared memory object
|
// in the shared memory object
|
||||||
static size_t get_optimal_object_size(size_t objsize, size_t minsize)
|
static size_t get_optimal_object_size(const size_t objsize, const size_t minsize)
|
||||||
{
|
{
|
||||||
size_t optsize = pagesize / gcd(pagesize, objsize);
|
const size_t optsize = pagesize / gcd(pagesize, objsize);
|
||||||
if(optsize < minsize)
|
if(optsize < minsize)
|
||||||
{
|
{
|
||||||
if(config.debug & DEBUG_SHMEM)
|
if(config.debug & DEBUG_SHMEM)
|
||||||
@@ -496,7 +495,7 @@ static size_t get_optimal_object_size(size_t objsize, size_t minsize)
|
|||||||
// First part: Integer division, may cause clipping, e.g., 5/3 = 1
|
// First part: Integer division, may cause clipping, e.g., 5/3 = 1
|
||||||
// Second part: Catch a possibly happened clipping event by adding
|
// Second part: Catch a possibly happened clipping event by adding
|
||||||
// one to the number: (5 % 3 != 0) is 1
|
// one to the number: (5 % 3 != 0) is 1
|
||||||
size_t multiplier = (minsize/optsize) + ((minsize % optsize != 0) ? 1u : 0u);
|
const size_t multiplier = (minsize/optsize) + ((minsize % optsize != 0) ? 1u : 0u);
|
||||||
if(config.debug & DEBUG_SHMEM)
|
if(config.debug & DEBUG_SHMEM)
|
||||||
{
|
{
|
||||||
logg("DEBUG: Using %zu*%zu == %zu >= %zu",
|
logg("DEBUG: Using %zu*%zu == %zu >= %zu",
|
||||||
|
|||||||
4
shmem.h
4
shmem.h
@@ -27,7 +27,7 @@ typedef struct {
|
|||||||
/// \param size the size to allocate
|
/// \param size the size to allocate
|
||||||
/// \return a structure with a pointer to the mounted shared memory. The pointer
|
/// \return a structure with a pointer to the mounted shared memory. The pointer
|
||||||
/// will always be valid, because if it failed FTL will have exited.
|
/// will always be valid, because if it failed FTL will have exited.
|
||||||
SharedMemory create_shm(const char *name, size_t size);
|
SharedMemory create_shm(const char *name, const size_t size);
|
||||||
|
|
||||||
/// Reallocate shared memory
|
/// Reallocate shared memory
|
||||||
///
|
///
|
||||||
@@ -35,7 +35,7 @@ SharedMemory create_shm(const char *name, size_t size);
|
|||||||
/// \param size the new size
|
/// \param size the new size
|
||||||
/// \param resize whether the object should be resized or only remapped
|
/// \param resize whether the object should be resized or only remapped
|
||||||
/// \return if reallocation was successful
|
/// \return if reallocation was successful
|
||||||
bool realloc_shm(SharedMemory *sharedMemory, size_t size, bool resize);
|
bool realloc_shm(SharedMemory *sharedMemory, const size_t size, const bool resize);
|
||||||
|
|
||||||
/// Disconnect from shared memory. If there are no other connections to shared memory, it will be deleted.
|
/// Disconnect from shared memory. If there are no other connections to shared memory, it will be deleted.
|
||||||
///
|
///
|
||||||
|
|||||||
20
socket.c
20
socket.c
@@ -201,7 +201,7 @@ static void removeport(void)
|
|||||||
fclose(f);
|
fclose(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void seom(int sock)
|
void seom(const int sock)
|
||||||
{
|
{
|
||||||
if(istelnet[sock])
|
if(istelnet[sock])
|
||||||
ssend(sock, "---EOM---\n\n");
|
ssend(sock, "---EOM---\n\n");
|
||||||
@@ -209,7 +209,7 @@ void seom(int sock)
|
|||||||
pack_eom(sock);
|
pack_eom(sock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void __attribute__ ((format (gnu_printf, 2, 3))) ssend(int sock, const char *format, ...)
|
void __attribute__ ((format (gnu_printf, 2, 3))) ssend(const int sock, const char *format, ...)
|
||||||
{
|
{
|
||||||
char *buffer;
|
char *buffer;
|
||||||
va_list args;
|
va_list args;
|
||||||
@@ -224,12 +224,12 @@ void __attribute__ ((format (gnu_printf, 2, 3))) ssend(int sock, const char *for
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void swrite(int sock, const void *value, size_t size) {
|
void swrite(const int sock, const void *value, size_t size) {
|
||||||
if(write(sock, value, size) == -1)
|
if(write(sock, value, size) == -1)
|
||||||
logg("WARNING: Socket write returned error code %i", errno);
|
logg("WARNING: Socket write returned error code %i", errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int checkClientLimit(int socket) {
|
static inline int checkClientLimit(const int socket) {
|
||||||
if(socket < MAXCONNS)
|
if(socket < MAXCONNS)
|
||||||
{
|
{
|
||||||
return socket;
|
return socket;
|
||||||
@@ -243,7 +243,7 @@ static inline int checkClientLimit(int socket) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int listener(int sockfd, char type)
|
static int listener(const int sockfd, const char type)
|
||||||
{
|
{
|
||||||
struct sockaddr_un un_addr;
|
struct sockaddr_un un_addr;
|
||||||
struct sockaddr_in in4_addr;
|
struct sockaddr_in in4_addr;
|
||||||
@@ -430,7 +430,7 @@ void *telnet_listening_thread_IPv4(void *args)
|
|||||||
while(!killed)
|
while(!killed)
|
||||||
{
|
{
|
||||||
// Look for new clients that want to connect
|
// Look for new clients that want to connect
|
||||||
int csck = listener(telnetfd4, 4);
|
const int csck = listener(telnetfd4, 4);
|
||||||
if(csck == -1)
|
if(csck == -1)
|
||||||
{
|
{
|
||||||
logg("IPv4 telnet error: %s (%i)", strerror(errno), errno);
|
logg("IPv4 telnet error: %s (%i)", strerror(errno), errno);
|
||||||
@@ -471,7 +471,7 @@ void *telnet_listening_thread_IPv6(void *args)
|
|||||||
while(!killed)
|
while(!killed)
|
||||||
{
|
{
|
||||||
// Look for new clients that want to connect
|
// Look for new clients that want to connect
|
||||||
int csck = listener(telnetfd6, 6);
|
const int csck = listener(telnetfd6, 6);
|
||||||
if(csck == -1)
|
if(csck == -1)
|
||||||
{
|
{
|
||||||
logg("IPv6 telnet error: %s (%i)", strerror(errno), errno);
|
logg("IPv6 telnet error: %s (%i)", strerror(errno), errno);
|
||||||
@@ -512,7 +512,7 @@ void *socket_listening_thread(void *args)
|
|||||||
while(!killed)
|
while(!killed)
|
||||||
{
|
{
|
||||||
// Look for new clients that want to connect
|
// Look for new clients that want to connect
|
||||||
int csck = listener(socketfd, 0);
|
const int csck = listener(socketfd, 0);
|
||||||
if(csck < 0) continue;
|
if(csck < 0) continue;
|
||||||
|
|
||||||
// Allocate memory used to transport client socket ID to client listening thread
|
// Allocate memory used to transport client socket ID to client listening thread
|
||||||
@@ -544,8 +544,8 @@ bool ipv6_available(void)
|
|||||||
// Loop over interfaces
|
// Loop over interfaces
|
||||||
for (interface = allInterfaces; interface != NULL; interface = interface->ifa_next)
|
for (interface = allInterfaces; interface != NULL; interface = interface->ifa_next)
|
||||||
{
|
{
|
||||||
unsigned int flags = interface->ifa_flags;
|
const unsigned int flags = interface->ifa_flags;
|
||||||
struct sockaddr *addr = interface->ifa_addr;
|
const struct sockaddr *addr = interface->ifa_addr;
|
||||||
|
|
||||||
// Check only for up and running IPv4, IPv6 interfaces
|
// Check only for up and running IPv4, IPv6 interfaces
|
||||||
if ((flags & (IFF_UP|IFF_RUNNING)) && addr != NULL)
|
if ((flags & (IFF_UP|IFF_RUNNING)) && addr != NULL)
|
||||||
|
|||||||
Reference in New Issue
Block a user