mirror of
https://github.com/pi-hole/FTL.git
synced 2024-10-26 16:52:18 +02:00
Remove globally defined queries array.
Signed-off-by: DL6ER <dl6er@dl6er.de>
This commit is contained in:
@@ -261,7 +261,6 @@ extern FTLFileNamesStruct FTLfiles;
|
||||
extern countersStruct *counters;
|
||||
extern ConfigStruct config;
|
||||
|
||||
extern queriesDataStruct *queries;
|
||||
extern forwardedDataStruct *forwarded;
|
||||
extern clientsDataStruct *clients;
|
||||
extern domainsDataStruct *domains;
|
||||
@@ -315,3 +314,7 @@ extern pthread_t socket_listenthread;
|
||||
extern pthread_t DBthread;
|
||||
extern pthread_t GCthread;
|
||||
extern pthread_t DNSclientthread;
|
||||
|
||||
// Pointer getter functions
|
||||
#define getQuery(queryID) _getQuery(queryID, __LINE__, __FUNCTION__, __FILE__)
|
||||
queriesDataStruct* _getQuery(int queryID, int line, const char * function, const char * file);
|
||||
|
||||
@@ -745,53 +745,53 @@ void getAllQueries(char *client_message, int *sock)
|
||||
int i;
|
||||
for(i=ibeg; i < counters->queries; i++)
|
||||
{
|
||||
validate_access("queries", i, true, __LINE__, __FUNCTION__, __FILE__);
|
||||
queriesDataStruct* query = getQuery(i);
|
||||
// Check if this query has been create while in maximum privacy mode
|
||||
if(queries[i].privacylevel >= PRIVACY_MAXIMUM) continue;
|
||||
if(query->privacylevel >= PRIVACY_MAXIMUM) continue;
|
||||
|
||||
validate_access("domains", queries[i].domainID, true, __LINE__, __FUNCTION__, __FILE__);
|
||||
validate_access("clients", queries[i].clientID, true, __LINE__, __FUNCTION__, __FILE__);
|
||||
validate_access("domains", query->domainID, true, __LINE__, __FUNCTION__, __FILE__);
|
||||
validate_access("clients", query->clientID, true, __LINE__, __FUNCTION__, __FILE__);
|
||||
|
||||
char *qtype = querytypes[queries[i].type - TYPE_A];
|
||||
char *qtype = querytypes[query->type - TYPE_A];
|
||||
|
||||
// 1 = gravity.list, 4 = wildcard, 5 = black.list
|
||||
if((queries[i].status == QUERY_GRAVITY ||
|
||||
queries[i].status == QUERY_WILDCARD ||
|
||||
queries[i].status == QUERY_BLACKLIST) && !showblocked)
|
||||
if((query->status == QUERY_GRAVITY ||
|
||||
query->status == QUERY_WILDCARD ||
|
||||
query->status == QUERY_BLACKLIST) && !showblocked)
|
||||
continue;
|
||||
// 2 = forwarded, 3 = cached
|
||||
if((queries[i].status == QUERY_FORWARDED ||
|
||||
queries[i].status == QUERY_CACHE) && !showpermitted)
|
||||
if((query->status == QUERY_FORWARDED ||
|
||||
query->status == QUERY_CACHE) && !showpermitted)
|
||||
continue;
|
||||
|
||||
// Skip those entries which so not meet the requested timeframe
|
||||
if((from > queries[i].timestamp && from != 0) || (queries[i].timestamp > until && until != 0))
|
||||
if((from > query->timestamp && from != 0) || (query->timestamp > until && until != 0))
|
||||
continue;
|
||||
|
||||
// Skip if domain is not identical with what the user wants to see
|
||||
if(filterdomainname && queries[i].domainID != domainid)
|
||||
if(filterdomainname && query->domainID != domainid)
|
||||
continue;
|
||||
|
||||
// Skip if client name and IP are not identical with what the user wants to see
|
||||
if(filterclientname && queries[i].clientID != clientid)
|
||||
if(filterclientname && query->clientID != clientid)
|
||||
continue;
|
||||
|
||||
// Skip if query type is not identical with what the user wants to see
|
||||
if(querytype != 0 && querytype != queries[i].type)
|
||||
if(querytype != 0 && querytype != query->type)
|
||||
continue;
|
||||
|
||||
if(filterforwarddest)
|
||||
{
|
||||
// Does the user want to see queries answered from blocking lists?
|
||||
if(forwarddestid == -2 && queries[i].status != QUERY_GRAVITY
|
||||
&& queries[i].status != QUERY_WILDCARD
|
||||
&& queries[i].status != QUERY_BLACKLIST)
|
||||
if(forwarddestid == -2 && query->status != QUERY_GRAVITY
|
||||
&& query->status != QUERY_WILDCARD
|
||||
&& query->status != QUERY_BLACKLIST)
|
||||
continue;
|
||||
// Does the user want to see queries answered from local cache?
|
||||
else if(forwarddestid == -1 && queries[i].status != QUERY_CACHE)
|
||||
else if(forwarddestid == -1 && query->status != QUERY_CACHE)
|
||||
continue;
|
||||
// Does the user want to see queries answered by an upstream server?
|
||||
else if(forwarddestid >= 0 && forwarddestid != queries[i].forwardID)
|
||||
else if(forwarddestid >= 0 && forwarddestid != query->forwardID)
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -800,23 +800,23 @@ void getAllQueries(char *client_message, int *sock)
|
||||
char *domain = getDomainString(i);
|
||||
// Similarly for the client
|
||||
char *client;
|
||||
if(strlen(getstr(clients[queries[i].clientID].namepos)) > 0)
|
||||
if(strlen(getstr(clients[query->clientID].namepos)) > 0)
|
||||
client = getClientNameString(i);
|
||||
else
|
||||
client = getClientIPString(i);
|
||||
|
||||
unsigned long delay = queries[i].response;
|
||||
unsigned long delay = query->response;
|
||||
// Check if received (delay should be smaller than 30min)
|
||||
if(delay > 1.8e7)
|
||||
delay = 0;
|
||||
|
||||
if(istelnet[*sock])
|
||||
{
|
||||
ssend(*sock,"%i %s %s %s %i %i %i %lu\n",queries[i].timestamp,qtype,domain,client,queries[i].status,queries[i].dnssec,queries[i].reply,delay);
|
||||
ssend(*sock,"%i %s %s %s %i %i %i %lu\n",query->timestamp,qtype,domain,client,query->status,query->dnssec,query->reply,delay);
|
||||
}
|
||||
else
|
||||
{
|
||||
pack_int32(*sock, queries[i].timestamp);
|
||||
pack_int32(*sock, query->timestamp);
|
||||
|
||||
// Use a fixstr because the length of qtype is always 4 (max is 31 for fixstr)
|
||||
if(!pack_fixstr(*sock, qtype))
|
||||
@@ -826,8 +826,8 @@ void getAllQueries(char *client_message, int *sock)
|
||||
if(!pack_str32(*sock, domain) || !pack_str32(*sock, client))
|
||||
return;
|
||||
|
||||
pack_uint8(*sock, queries[i].status);
|
||||
pack_uint8(*sock, queries[i].dnssec);
|
||||
pack_uint8(*sock, query->status);
|
||||
pack_uint8(*sock, query->dnssec);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -857,11 +857,11 @@ void getRecentBlocked(char *client_message, int *sock)
|
||||
int found = 0;
|
||||
for(i = counters->queries - 1; i > 0 ; i--)
|
||||
{
|
||||
validate_access("queries", i, true, __LINE__, __FUNCTION__, __FILE__);
|
||||
queriesDataStruct* query = getQuery(i);
|
||||
|
||||
if(queries[i].status == QUERY_GRAVITY ||
|
||||
queries[i].status == QUERY_WILDCARD ||
|
||||
queries[i].status == QUERY_BLACKLIST)
|
||||
if(query->status == QUERY_GRAVITY ||
|
||||
query->status == QUERY_WILDCARD ||
|
||||
query->status == QUERY_BLACKLIST)
|
||||
{
|
||||
found++;
|
||||
|
||||
@@ -1160,11 +1160,12 @@ void getUnknownQueries(int *sock)
|
||||
int i;
|
||||
for(i=0; i < counters->queries; i++)
|
||||
{
|
||||
validate_access("queries", i, true, __LINE__, __FUNCTION__, __FILE__);
|
||||
if(queries[i].status != QUERY_UNKNOWN && queries[i].complete) continue;
|
||||
queriesDataStruct* query = getQuery(i);
|
||||
|
||||
if(query->status != QUERY_UNKNOWN && query->complete) continue;
|
||||
|
||||
char type[5];
|
||||
if(queries[i].type == TYPE_A)
|
||||
if(query->type == TYPE_A)
|
||||
{
|
||||
strcpy(type,"IPv4");
|
||||
}
|
||||
@@ -1173,28 +1174,28 @@ void getUnknownQueries(int *sock)
|
||||
strcpy(type,"IPv6");
|
||||
}
|
||||
|
||||
validate_access("domains", queries[i].domainID, true, __LINE__, __FUNCTION__, __FILE__);
|
||||
validate_access("clients", queries[i].clientID, true, __LINE__, __FUNCTION__, __FILE__);
|
||||
validate_access("domains", query->domainID, true, __LINE__, __FUNCTION__, __FILE__);
|
||||
validate_access("clients", query->clientID, true, __LINE__, __FUNCTION__, __FILE__);
|
||||
|
||||
|
||||
char *client = getstr(clients[queries[i].clientID].ippos);
|
||||
char *client = getstr(clients[query->clientID].ippos);
|
||||
|
||||
if(istelnet[*sock])
|
||||
ssend(*sock, "%i %i %i %s %s %s %i %s\n", queries[i].timestamp, i, queries[i].id, type, getstr(domains[queries[i].domainID].domainpos), client, queries[i].status, queries[i].complete ? "true" : "false");
|
||||
ssend(*sock, "%i %i %i %s %s %s %i %s\n", query->timestamp, i, query->id, type, getstr(domains[query->domainID].domainpos), client, query->status, query->complete ? "true" : "false");
|
||||
else {
|
||||
pack_int32(*sock, queries[i].timestamp);
|
||||
pack_int32(*sock, queries[i].id);
|
||||
pack_int32(*sock, query->timestamp);
|
||||
pack_int32(*sock, query->id);
|
||||
|
||||
// Use a fixstr because the length of qtype is always 4 (max is 31 for fixstr)
|
||||
if(!pack_fixstr(*sock, type))
|
||||
return;
|
||||
|
||||
// Use str32 for domain and client because we have no idea how long they will be (max is 4294967295 for str32)
|
||||
if(!pack_str32(*sock, getstr(domains[queries[i].domainID].domainpos)) || !pack_str32(*sock, client))
|
||||
if(!pack_str32(*sock, getstr(domains[query->domainID].domainpos)) || !pack_str32(*sock, client))
|
||||
return;
|
||||
|
||||
pack_uint8(*sock, queries[i].status);
|
||||
pack_bool(*sock, queries[i].complete);
|
||||
pack_uint8(*sock, query->status);
|
||||
pack_bool(*sock, query->complete);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+34
-34
@@ -456,14 +456,14 @@ void save_to_DB(void)
|
||||
time_t newlasttimestamp = 0;
|
||||
for(i = MAX(0, lastdbindex); i < counters->queries; i++)
|
||||
{
|
||||
validate_access("queries", i, true, __LINE__, __FUNCTION__, __FILE__);
|
||||
if(queries[i].db != 0)
|
||||
queriesDataStruct* query = getQuery(i);
|
||||
if(query->db != 0)
|
||||
{
|
||||
// Skip, already saved in database
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!queries[i].complete && queries[i].timestamp > currenttimestamp-2)
|
||||
if(!query->complete && query->timestamp > currenttimestamp-2)
|
||||
{
|
||||
// Break if a brand new query (age < 2 seconds) is not yet completed
|
||||
// giving it a chance to be stored next time
|
||||
@@ -473,7 +473,7 @@ void save_to_DB(void)
|
||||
// Memory checks
|
||||
validate_access("queries", i, true, __LINE__, __FUNCTION__, __FILE__);
|
||||
|
||||
if(queries[i].privacylevel >= PRIVACY_MAXIMUM)
|
||||
if(query->privacylevel >= PRIVACY_MAXIMUM)
|
||||
{
|
||||
// Skip, we never store nor count queries recorded
|
||||
// while have been in maximum privacy mode in the database
|
||||
@@ -481,13 +481,13 @@ void save_to_DB(void)
|
||||
}
|
||||
|
||||
// TIMESTAMP
|
||||
sqlite3_bind_int(stmt, 1, queries[i].timestamp);
|
||||
sqlite3_bind_int(stmt, 1, query->timestamp);
|
||||
|
||||
// TYPE
|
||||
sqlite3_bind_int(stmt, 2, queries[i].type);
|
||||
sqlite3_bind_int(stmt, 2, query->type);
|
||||
|
||||
// STATUS
|
||||
sqlite3_bind_int(stmt, 3, queries[i].status);
|
||||
sqlite3_bind_int(stmt, 3, query->status);
|
||||
|
||||
// DOMAIN
|
||||
char *domain = getDomainString(i);
|
||||
@@ -498,10 +498,10 @@ void save_to_DB(void)
|
||||
sqlite3_bind_text(stmt, 5, client, -1, SQLITE_TRANSIENT);
|
||||
|
||||
// FORWARD
|
||||
if(queries[i].status == QUERY_FORWARDED && queries[i].forwardID > -1)
|
||||
if(query->status == QUERY_FORWARDED && query->forwardID > -1)
|
||||
{
|
||||
validate_access("forwarded", queries[i].forwardID, true, __LINE__, __FUNCTION__, __FILE__);
|
||||
sqlite3_bind_text(stmt, 6, getstr(forwarded[queries[i].forwardID].ippos), -1, SQLITE_TRANSIENT);
|
||||
validate_access("forwarded", query->forwardID, true, __LINE__, __FUNCTION__, __FILE__);
|
||||
sqlite3_bind_text(stmt, 6, getstr(forwarded[query->forwardID].ippos), -1, SQLITE_TRANSIENT);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -531,19 +531,19 @@ void save_to_DB(void)
|
||||
|
||||
saved++;
|
||||
// Mark this query as saved in the database by setting the corresponding ID
|
||||
queries[i].db = ++lastID;
|
||||
query->db = ++lastID;
|
||||
|
||||
// Total counter information (delta computation)
|
||||
total++;
|
||||
if(queries[i].status == QUERY_GRAVITY ||
|
||||
queries[i].status == QUERY_BLACKLIST ||
|
||||
queries[i].status == QUERY_WILDCARD ||
|
||||
queries[i].status == QUERY_EXTERNAL_BLOCKED)
|
||||
if(query->status == QUERY_GRAVITY ||
|
||||
query->status == QUERY_BLACKLIST ||
|
||||
query->status == QUERY_WILDCARD ||
|
||||
query->status == QUERY_EXTERNAL_BLOCKED)
|
||||
blocked++;
|
||||
|
||||
// Update lasttimestamp variable with timestamp of the latest stored query
|
||||
if(queries[i].timestamp > newlasttimestamp)
|
||||
newlasttimestamp = queries[i].timestamp;
|
||||
if(query->timestamp > newlasttimestamp)
|
||||
newlasttimestamp = query->timestamp;
|
||||
}
|
||||
|
||||
// Finish prepared statement
|
||||
@@ -777,25 +777,25 @@ void read_data_from_DB(void)
|
||||
int queryIndex = counters->queries;
|
||||
|
||||
// Store this query in memory
|
||||
validate_access("queries", queryIndex, false, __LINE__, __FUNCTION__, __FILE__);
|
||||
validate_access("clients", clientID, true, __LINE__, __FUNCTION__, __FILE__);
|
||||
queries[queryIndex].magic = MAGICBYTE;
|
||||
queries[queryIndex].timestamp = queryTimeStamp;
|
||||
queries[queryIndex].type = type;
|
||||
queries[queryIndex].status = status;
|
||||
queries[queryIndex].domainID = domainID;
|
||||
queries[queryIndex].clientID = clientID;
|
||||
queries[queryIndex].forwardID = forwardID;
|
||||
queries[queryIndex].timeidx = timeidx;
|
||||
queries[queryIndex].db = dbid;
|
||||
queries[queryIndex].id = 0;
|
||||
queries[queryIndex].complete = true; // Mark as all information is available
|
||||
queries[queryIndex].response = 0;
|
||||
queries[queryIndex].AD = false;
|
||||
queries[queryIndex].dnssec = DNSSEC_UNKNOWN;
|
||||
queries[queryIndex].reply = REPLY_UNKNOWN;
|
||||
queriesDataStruct* query = getQuery(queryIndex);
|
||||
query->magic = MAGICBYTE;
|
||||
query->timestamp = queryTimeStamp;
|
||||
query->type = type;
|
||||
query->status = status;
|
||||
query->domainID = domainID;
|
||||
query->clientID = clientID;
|
||||
query->forwardID = forwardID;
|
||||
query->timeidx = timeidx;
|
||||
query->db = dbid;
|
||||
query->id = 0;
|
||||
query->complete = true; // Mark as all information is available
|
||||
query->response = 0;
|
||||
query->AD = false;
|
||||
query->dnssec = DNSSEC_UNKNOWN;
|
||||
query->reply = REPLY_UNKNOWN;
|
||||
|
||||
// Set lastQuery timer and add one query for network table
|
||||
validate_access("clients", clientID, true, __LINE__, __FUNCTION__, __FILE__);
|
||||
clients[clientID].lastQuery = queryTimeStamp;
|
||||
clients[clientID].numQueriesARP++;
|
||||
|
||||
|
||||
+12
-9
@@ -184,10 +184,11 @@ bool isValidIPv6(const char *addr)
|
||||
// only when appropriate for the requested query
|
||||
char *getDomainString(int queryID)
|
||||
{
|
||||
if(queries[queryID].privacylevel < PRIVACY_HIDE_DOMAINS)
|
||||
queriesDataStruct* query = getQuery(queryID);
|
||||
if(query->privacylevel < PRIVACY_HIDE_DOMAINS)
|
||||
{
|
||||
validate_access("domains", queries[queryID].domainID, true, __LINE__, __FUNCTION__, __FILE__);
|
||||
return getstr(domains[queries[queryID].domainID].domainpos);
|
||||
validate_access("domains", query->domainID, true, __LINE__, __FUNCTION__, __FILE__);
|
||||
return getstr(domains[query->domainID].domainpos);
|
||||
}
|
||||
else
|
||||
return HIDDEN_DOMAIN;
|
||||
@@ -197,10 +198,11 @@ char *getDomainString(int queryID)
|
||||
// only when appropriate for the requested query
|
||||
char *getClientIPString(int queryID)
|
||||
{
|
||||
if(queries[queryID].privacylevel < PRIVACY_HIDE_DOMAINS_CLIENTS)
|
||||
queriesDataStruct* query = getQuery(queryID);
|
||||
if(query->privacylevel < PRIVACY_HIDE_DOMAINS_CLIENTS)
|
||||
{
|
||||
validate_access("clients", queries[queryID].clientID, true, __LINE__, __FUNCTION__, __FILE__);
|
||||
return getstr(clients[queries[queryID].clientID].ippos);
|
||||
validate_access("clients", query->clientID, true, __LINE__, __FUNCTION__, __FILE__);
|
||||
return getstr(clients[query->clientID].ippos);
|
||||
}
|
||||
else
|
||||
return HIDDEN_CLIENT;
|
||||
@@ -210,10 +212,11 @@ char *getClientIPString(int queryID)
|
||||
// only when appropriate for the requested query
|
||||
char *getClientNameString(int queryID)
|
||||
{
|
||||
if(queries[queryID].privacylevel < PRIVACY_HIDE_DOMAINS_CLIENTS)
|
||||
queriesDataStruct* query = getQuery(queryID);
|
||||
if(query->privacylevel < PRIVACY_HIDE_DOMAINS_CLIENTS)
|
||||
{
|
||||
validate_access("clients", queries[queryID].clientID, true, __LINE__, __FUNCTION__, __FILE__);
|
||||
return getstr(clients[queries[queryID].clientID].namepos);
|
||||
validate_access("clients", query->clientID, true, __LINE__, __FUNCTION__, __FILE__);
|
||||
return getstr(clients[query->clientID].namepos);
|
||||
}
|
||||
else
|
||||
return HIDDEN_CLIENT;
|
||||
|
||||
+110
-78
@@ -140,31 +140,31 @@ void _FTL_new_query(unsigned int flags, char *name, struct all_addr *addr, char
|
||||
int clientID = findClientID(client, true);
|
||||
|
||||
// Save everything
|
||||
validate_access("queries", queryID, false, __LINE__, __FUNCTION__, __FILE__);
|
||||
queries[queryID].magic = MAGICBYTE;
|
||||
queries[queryID].timestamp = querytimestamp;
|
||||
queries[queryID].type = querytype;
|
||||
queries[queryID].status = QUERY_UNKNOWN;
|
||||
queries[queryID].domainID = domainID;
|
||||
queries[queryID].clientID = clientID;
|
||||
queries[queryID].timeidx = timeidx;
|
||||
queriesDataStruct* query = getQuery(queryID);
|
||||
query->magic = MAGICBYTE;
|
||||
query->timestamp = querytimestamp;
|
||||
query->type = querytype;
|
||||
query->status = QUERY_UNKNOWN;
|
||||
query->domainID = domainID;
|
||||
query->clientID = clientID;
|
||||
query->timeidx = timeidx;
|
||||
// Initialize database rowID with zero, will be set when the query is stored in the long-term DB
|
||||
queries[queryID].db = 0;
|
||||
queries[queryID].id = id;
|
||||
queries[queryID].complete = false;
|
||||
queries[queryID].response = converttimeval(request);
|
||||
query->db = 0;
|
||||
query->id = id;
|
||||
query->complete = false;
|
||||
query->response = converttimeval(request);
|
||||
// Initialize reply type
|
||||
queries[queryID].reply = REPLY_UNKNOWN;
|
||||
query->reply = REPLY_UNKNOWN;
|
||||
// Store DNSSEC result for this domain
|
||||
queries[queryID].dnssec = DNSSEC_UNSPECIFIED;
|
||||
query->dnssec = DNSSEC_UNSPECIFIED;
|
||||
// AD has not yet been received for this query
|
||||
queries[queryID].AD = false;
|
||||
query->AD = false;
|
||||
|
||||
// Check and apply possible privacy level rules
|
||||
// The currently set privacy level (at the time the query is
|
||||
// generated) is stored in the queries structure
|
||||
get_privacy_level(NULL);
|
||||
queries[queryID].privacylevel = config.privacylevel;
|
||||
query->privacylevel = config.privacylevel;
|
||||
|
||||
// Increase DNS queries counter
|
||||
counters->queries++;
|
||||
@@ -227,16 +227,16 @@ static int findQueryID(int id)
|
||||
// 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
|
||||
// MAX(0, a) is used to return 0 in case a is negative (negative array indices are harmful)
|
||||
|
||||
// Validate access only once for the maximum index (all lower will work)
|
||||
int until = MAX(0, counters->queries-MAXITER);
|
||||
int start = MAX(0, counters->queries-1);
|
||||
validate_access("queries", until, false, __LINE__, __FUNCTION__, __FILE__);
|
||||
|
||||
// Check UUIDs of queries
|
||||
for(int i = start; i >= until; i--)
|
||||
if(queries[i].id == id)
|
||||
{
|
||||
queriesDataStruct* query = getQuery(i);
|
||||
if(query->id == id)
|
||||
return i;
|
||||
}
|
||||
|
||||
// If not found
|
||||
return -1;
|
||||
@@ -275,13 +275,16 @@ void _FTL_forwarded(unsigned int flags, char *name, struct all_addr *addr, int i
|
||||
return;
|
||||
}
|
||||
|
||||
// Get query pointer
|
||||
queriesDataStruct* query = getQuery(i);
|
||||
|
||||
// Proceed only if
|
||||
// - current query has not been marked as replied to so far
|
||||
// (it could be that answers from multiple forward
|
||||
// destinations are coming in for the same query)
|
||||
// - the query was formally known as cached but had to be forwarded
|
||||
// (this is a special case further described below)
|
||||
if(queries[i].complete && queries[i].status != QUERY_CACHE)
|
||||
if(query->complete && query->status != QUERY_CACHE)
|
||||
{
|
||||
free(forward);
|
||||
unlock_shm();
|
||||
@@ -291,11 +294,11 @@ void _FTL_forwarded(unsigned int flags, char *name, struct all_addr *addr, int i
|
||||
// Get ID of forward destination, create new forward destination record
|
||||
// if not found in current data structure
|
||||
int forwardID = findForwardID(forward, true);
|
||||
queries[i].forwardID = forwardID;
|
||||
query->forwardID = forwardID;
|
||||
|
||||
unsigned int timeidx = queries[i].timeidx;
|
||||
unsigned int timeidx = query->timeidx;
|
||||
|
||||
if(queries[i].status == QUERY_CACHE)
|
||||
if(query->status == QUERY_CACHE)
|
||||
{
|
||||
// Detect if we cached the <CNAME> but need to ask the upstream
|
||||
// servers for the actual IPs now, we remove this query from the
|
||||
@@ -322,7 +325,7 @@ void _FTL_forwarded(unsigned int flags, char *name, struct all_addr *addr, int i
|
||||
gettimeofday(&response, 0);
|
||||
// Reset timer, shift slightly into the past to acknowledge the time
|
||||
// FTLDNS needed to look up the CNAME in its cache
|
||||
queries[i].response = converttimeval(response) - queries[i].response;
|
||||
query->response = converttimeval(response) - query->response;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -330,14 +333,14 @@ void _FTL_forwarded(unsigned int flags, char *name, struct all_addr *addr, int i
|
||||
// Query is no longer unknown
|
||||
counters->unknown--;
|
||||
// Hereby, this query is now fully determined
|
||||
queries[i].complete = true;
|
||||
query->complete = true;
|
||||
}
|
||||
|
||||
// Set query status to forwarded only after the
|
||||
// if(queries[i].status == QUERY_CACHE) { ... }
|
||||
// if(query->status == QUERY_CACHE) { ... }
|
||||
// from above as otherwise this check will always
|
||||
// be negative
|
||||
queries[i].status = QUERY_FORWARDED;
|
||||
query->status = QUERY_FORWARDED;
|
||||
|
||||
// Update overTime data
|
||||
overTime[timeidx].forwarded++;
|
||||
@@ -424,7 +427,10 @@ void _FTL_reply(unsigned short flags, char *name, struct all_addr *addr, int id,
|
||||
return;
|
||||
}
|
||||
|
||||
if(queries[i].reply != REPLY_UNKNOWN)
|
||||
// Get query pointer
|
||||
queriesDataStruct* query = getQuery(i);
|
||||
|
||||
if(query->reply != REPLY_UNKNOWN)
|
||||
{
|
||||
// Nothing to be done here
|
||||
unlock_shm();
|
||||
@@ -432,18 +438,18 @@ 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
|
||||
int domainID = queries[i].domainID;
|
||||
int domainID = query->domainID;
|
||||
validate_access("domains", domainID, true, __LINE__, __FUNCTION__, __FILE__);
|
||||
bool isExactMatch = (name != NULL && strcmp(getstr(domains[domainID].domainpos), name) == 0);
|
||||
|
||||
if((flags & F_CONFIG) && isExactMatch && !queries[i].complete)
|
||||
if((flags & F_CONFIG) && isExactMatch && !query->complete)
|
||||
{
|
||||
// Answered from local configuration, might be a wildcard or user-provided
|
||||
// This query is no longer unknown
|
||||
counters->unknown--;
|
||||
|
||||
// Get time index
|
||||
unsigned int timeidx = queries[i].timeidx;
|
||||
unsigned int timeidx = query->timeidx;
|
||||
|
||||
if(strcmp(answer, "(NXDOMAIN)") == 0 ||
|
||||
strcmp(answer, "0.0.0.0") == 0 ||
|
||||
@@ -453,13 +459,13 @@ void _FTL_reply(unsigned short flags, char *name, struct all_addr *addr, int id,
|
||||
counters->blocked++;
|
||||
overTime[timeidx].blocked++;
|
||||
|
||||
validate_access("domains", queries[i].domainID, true, __LINE__, __FUNCTION__, __FILE__);
|
||||
domains[queries[i].domainID].blockedcount++;
|
||||
validate_access("domains", query->domainID, true, __LINE__, __FUNCTION__, __FILE__);
|
||||
domains[query->domainID].blockedcount++;
|
||||
|
||||
validate_access("clients", queries[i].clientID, true, __LINE__, __FUNCTION__, __FILE__);
|
||||
clients[queries[i].clientID].blockedcount++;
|
||||
validate_access("clients", query->clientID, true, __LINE__, __FUNCTION__, __FILE__);
|
||||
clients[query->clientID].blockedcount++;
|
||||
|
||||
queries[i].status = QUERY_WILDCARD;
|
||||
query->status = QUERY_WILDCARD;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -467,14 +473,14 @@ void _FTL_reply(unsigned short flags, char *name, struct all_addr *addr, int id,
|
||||
counters->cached++;
|
||||
overTime[timeidx].cached++;
|
||||
|
||||
queries[i].status = QUERY_CACHE;
|
||||
query->status = QUERY_CACHE;
|
||||
}
|
||||
|
||||
// Save reply type and update individual reply counters
|
||||
save_reply_type(flags, i, response);
|
||||
|
||||
// Hereby, this query is now fully determined
|
||||
queries[i].complete = true;
|
||||
query->complete = true;
|
||||
}
|
||||
else if((flags & F_FORWARD) && isExactMatch)
|
||||
{
|
||||
@@ -482,7 +488,7 @@ void _FTL_reply(unsigned short flags, char *name, struct all_addr *addr, int id,
|
||||
save_reply_type(flags, i, response);
|
||||
|
||||
// If received NXDOMAIN and AD bit is set, Quad9 may have blocked this query
|
||||
if(flags & F_NXDOMAIN && queries[i].AD)
|
||||
if(flags & F_NXDOMAIN && query->AD)
|
||||
{
|
||||
query_externally_blocked(i);
|
||||
}
|
||||
@@ -504,7 +510,7 @@ void _FTL_reply(unsigned short flags, char *name, struct all_addr *addr, int id,
|
||||
// Save reply type and update individual reply counters
|
||||
save_reply_type(flags, i, response);
|
||||
}
|
||||
else if(isExactMatch && !queries[i].complete)
|
||||
else if(isExactMatch && !query->complete)
|
||||
{
|
||||
logg("*************************** unknown REPLY ***************************");
|
||||
print_flags(flags);
|
||||
@@ -568,26 +574,30 @@ static void detect_blocked_IP(unsigned short flags, char* answer, int queryID)
|
||||
|
||||
static void query_externally_blocked(int i)
|
||||
{
|
||||
unsigned int timeidx = queries[i].timeidx;
|
||||
// Get query pointer
|
||||
queriesDataStruct* query = getQuery(i);
|
||||
|
||||
// Get time index
|
||||
unsigned int timeidx = query->timeidx;
|
||||
|
||||
// Correct counters if necessary ...
|
||||
if(queries[i].status == QUERY_FORWARDED)
|
||||
if(query->status == QUERY_FORWARDED)
|
||||
{
|
||||
counters->forwardedqueries--;
|
||||
overTime[timeidx].forwarded--;
|
||||
validate_access("forwarded", queries[i].forwardID, true, __LINE__, __FUNCTION__, __FILE__);
|
||||
forwarded[queries[i].forwardID].count--;
|
||||
validate_access("forwarded", query->forwardID, true, __LINE__, __FUNCTION__, __FILE__);
|
||||
forwarded[query->forwardID].count--;
|
||||
}
|
||||
|
||||
// ... but as blocked
|
||||
counters->blocked++;
|
||||
overTime[timeidx].blocked++;
|
||||
validate_access("domains", queries[i].domainID, true, __LINE__, __FUNCTION__, __FILE__);
|
||||
domains[queries[i].domainID].blockedcount++;
|
||||
validate_access("clients", queries[i].clientID, true, __LINE__, __FUNCTION__, __FILE__);
|
||||
clients[queries[i].clientID].blockedcount++;
|
||||
validate_access("domains", query->domainID, true, __LINE__, __FUNCTION__, __FILE__);
|
||||
domains[query->domainID].blockedcount++;
|
||||
validate_access("clients", query->clientID, true, __LINE__, __FUNCTION__, __FILE__);
|
||||
clients[query->clientID].blockedcount++;
|
||||
|
||||
queries[i].status = QUERY_EXTERNAL_BLOCKED;
|
||||
query->status = QUERY_EXTERNAL_BLOCKED;
|
||||
}
|
||||
|
||||
void _FTL_cache(unsigned int flags, char *name, struct all_addr *addr, char *arg, int id, const char* file, const int line)
|
||||
@@ -669,10 +679,20 @@ void _FTL_cache(unsigned int flags, char *name, struct all_addr *addr, char *arg
|
||||
}
|
||||
|
||||
int i = findQueryID(id);
|
||||
if(i < 0 || queries[i].complete)
|
||||
if(i < 0)
|
||||
{
|
||||
// This may happen e.g. if the original query was a PTR query or "pi.hole"
|
||||
// as we ignore them altogether or if the query is already complete
|
||||
// as we ignore them altogether
|
||||
unlock_shm();
|
||||
return;
|
||||
}
|
||||
|
||||
// Get query pointer
|
||||
queriesDataStruct* query = getQuery(i);
|
||||
|
||||
if(query->complete)
|
||||
{
|
||||
// Skip query if already complete
|
||||
unlock_shm();
|
||||
return;
|
||||
}
|
||||
@@ -681,25 +701,25 @@ void _FTL_cache(unsigned int flags, char *name, struct all_addr *addr, char *arg
|
||||
counters->unknown--;
|
||||
|
||||
// Get time index
|
||||
unsigned int timeidx = queries[i].timeidx;
|
||||
unsigned int timeidx = query->timeidx;
|
||||
|
||||
int domainID = queries[i].domainID;
|
||||
int domainID = query->domainID;
|
||||
validate_access("domains", domainID, true, __LINE__, __FUNCTION__, __FILE__);
|
||||
|
||||
int clientID = queries[i].clientID;
|
||||
int clientID = query->clientID;
|
||||
validate_access("clients", clientID, true, __LINE__, __FUNCTION__, __FILE__);
|
||||
|
||||
// Mark this query as blocked if domain was matched by a regex
|
||||
if(domains[domainID].regexmatch == REGEX_BLOCKED)
|
||||
requesttype = QUERY_WILDCARD;
|
||||
|
||||
queries[i].status = requesttype;
|
||||
query->status = requesttype;
|
||||
|
||||
// Detect if returned IP indicates that this query was blocked
|
||||
detect_blocked_IP(flags, dest, i);
|
||||
|
||||
// Re-read requesttype as detect_blocked_IP() might have changed it
|
||||
requesttype = queries[i].status;
|
||||
requesttype = query->status;
|
||||
|
||||
// Handle counters accordingly
|
||||
switch(requesttype)
|
||||
@@ -726,7 +746,7 @@ void _FTL_cache(unsigned int flags, char *name, struct all_addr *addr, char *arg
|
||||
save_reply_type(flags, i, response);
|
||||
|
||||
// Hereby, this query is now fully determined
|
||||
queries[i].complete = true;
|
||||
query->complete = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -753,21 +773,24 @@ void _FTL_dnssec(int status, int id, const char* file, const int line)
|
||||
return;
|
||||
}
|
||||
|
||||
// Get query pointer
|
||||
queriesDataStruct* query = getQuery(i);
|
||||
|
||||
// Debug logging
|
||||
if(config.debug & DEBUG_QUERIES)
|
||||
{
|
||||
int domainID = queries[i].domainID;
|
||||
int domainID = query->domainID;
|
||||
validate_access("domains", domainID, true, __LINE__, __FUNCTION__, __FILE__);
|
||||
logg("**** got DNSSEC details for %s: %i (ID %i, %s:%i)", getstr(domains[domainID].domainpos), status, id, file, line);
|
||||
}
|
||||
|
||||
// Iterate through possible values
|
||||
if(status == STAT_SECURE)
|
||||
queries[i].dnssec = DNSSEC_SECURE;
|
||||
query->dnssec = DNSSEC_SECURE;
|
||||
else if(status == STAT_INSECURE)
|
||||
queries[i].dnssec = DNSSEC_INSECURE;
|
||||
query->dnssec = DNSSEC_INSECURE;
|
||||
else
|
||||
queries[i].dnssec = DNSSEC_BOGUS;
|
||||
query->dnssec = DNSSEC_BOGUS;
|
||||
|
||||
unlock_shm();
|
||||
}
|
||||
@@ -792,6 +815,10 @@ void _FTL_upstream_error(unsigned int rcode, int id, const char* file, const int
|
||||
unlock_shm();
|
||||
return;
|
||||
}
|
||||
|
||||
// Get query pointer
|
||||
queriesDataStruct* query = getQuery(i);
|
||||
|
||||
// Translate dnsmasq's rcode into something we can use
|
||||
char *rcodestr = NULL;
|
||||
bool alloc = false;
|
||||
@@ -799,27 +826,27 @@ void _FTL_upstream_error(unsigned int rcode, int id, const char* file, const int
|
||||
{
|
||||
case SERVFAIL:
|
||||
rcodestr = "SERVFAIL";
|
||||
queries[i].reply = REPLY_SERVFAIL;
|
||||
query->reply = REPLY_SERVFAIL;
|
||||
break;
|
||||
case REFUSED:
|
||||
rcodestr = "REFUSED";
|
||||
queries[i].reply = REPLY_REFUSED;
|
||||
query->reply = REPLY_REFUSED;
|
||||
break;
|
||||
case NOTIMP:
|
||||
rcodestr = "NOT IMPLEMENTED";
|
||||
queries[i].reply = REPLY_NOTIMP;
|
||||
query->reply = REPLY_NOTIMP;
|
||||
break;
|
||||
default:
|
||||
if(asprintf(&rcodestr, "Unknown error type (%u)", rcode) > -1)
|
||||
alloc = true;
|
||||
queries[i].reply = REPLY_OTHER;
|
||||
query->reply = REPLY_OTHER;
|
||||
break;
|
||||
}
|
||||
|
||||
// Debug logging
|
||||
if(config.debug & DEBUG_QUERIES)
|
||||
{
|
||||
int domainID = queries[i].domainID;
|
||||
int domainID = query->domainID;
|
||||
validate_access("domains", domainID, true, __LINE__, __FUNCTION__, __FILE__);
|
||||
logg("**** got error report for %s: %s (ID %i, %s:%i)", getstr(domains[domainID].domainpos), rcodestr, id, file, line);
|
||||
}
|
||||
@@ -855,15 +882,18 @@ void _FTL_header_ADbit(unsigned char header4, unsigned int rcode, int id, const
|
||||
return;
|
||||
}
|
||||
|
||||
// Get query pointer
|
||||
queriesDataStruct* query = getQuery(i);
|
||||
|
||||
if(config.debug & DEBUG_QUERIES)
|
||||
{
|
||||
int domainID = queries[i].domainID;
|
||||
int domainID = query->domainID;
|
||||
validate_access("domains", domainID, true, __LINE__, __FUNCTION__, __FILE__);
|
||||
logg("**** AD bit set for %s (ID %i, RCODE %u, %s:%i)", getstr(domains[domainID].domainpos), id, rcode, file, line);
|
||||
}
|
||||
|
||||
// Store AD bit in query data
|
||||
queries[i].AD = true;
|
||||
query->AD = true;
|
||||
|
||||
// If the response code (rcode) is NXDOMAIN, we may be seeing a response from
|
||||
// an externally blocked query. As they are not always accompany a necessary
|
||||
@@ -907,50 +937,52 @@ void print_flags(unsigned int flags)
|
||||
|
||||
void save_reply_type(unsigned int flags, int queryID, struct timeval response)
|
||||
{
|
||||
// Get query pointer
|
||||
queriesDataStruct* query = getQuery(queryID);
|
||||
|
||||
// Iterate through possible values
|
||||
validate_access("queries", queryID, false, __LINE__, __FUNCTION__, __FILE__);
|
||||
if(flags & F_NEG)
|
||||
{
|
||||
if(flags & F_NXDOMAIN)
|
||||
{
|
||||
// NXDOMAIN
|
||||
queries[queryID].reply = REPLY_NXDOMAIN;
|
||||
query->reply = REPLY_NXDOMAIN;
|
||||
counters->reply_NXDOMAIN++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// NODATA(-IPv6)
|
||||
queries[queryID].reply = REPLY_NODATA;
|
||||
query->reply = REPLY_NODATA;
|
||||
counters->reply_NODATA++;
|
||||
}
|
||||
}
|
||||
else if(flags & F_CNAME)
|
||||
{
|
||||
// <CNAME>
|
||||
queries[queryID].reply = REPLY_CNAME;
|
||||
query->reply = REPLY_CNAME;
|
||||
counters->reply_CNAME++;
|
||||
}
|
||||
else if(flags & F_REVERSE)
|
||||
{
|
||||
// reserve lookup
|
||||
queries[queryID].reply = REPLY_DOMAIN;
|
||||
query->reply = REPLY_DOMAIN;
|
||||
counters->reply_domain++;
|
||||
}
|
||||
else if(flags & F_RRNAME)
|
||||
{
|
||||
// TXT query
|
||||
queries[queryID].reply = REPLY_RRNAME;
|
||||
query->reply = REPLY_RRNAME;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Valid IP
|
||||
queries[queryID].reply = REPLY_IP;
|
||||
query->reply = REPLY_IP;
|
||||
counters->reply_IP++;
|
||||
}
|
||||
|
||||
// Save response time (relative time)
|
||||
queries[queryID].response = converttimeval(response) -
|
||||
queries[queryID].response;
|
||||
query->response = converttimeval(response) -
|
||||
query->response;
|
||||
}
|
||||
|
||||
pthread_t telnet_listenthreadv4;
|
||||
|
||||
@@ -51,29 +51,29 @@ void *GC_thread(void *val)
|
||||
// Process all queries
|
||||
for(i=0; i < counters->queries; i++)
|
||||
{
|
||||
validate_access("queries", i, true, __LINE__, __FUNCTION__, __FILE__);
|
||||
queriesDataStruct* query = getQuery(i);
|
||||
// Test if this query is too new
|
||||
if(queries[i].timestamp > mintime)
|
||||
if(query->timestamp > mintime)
|
||||
break;
|
||||
|
||||
// Adjust client counter
|
||||
int clientID = queries[i].clientID;
|
||||
int clientID = query->clientID;
|
||||
validate_access("clients", clientID, true, __LINE__, __FUNCTION__, __FILE__);
|
||||
clients[clientID].count--;
|
||||
|
||||
// Adjust total counters and total over time data
|
||||
int timeidx = queries[i].timeidx;
|
||||
int timeidx = query->timeidx;
|
||||
overTime[timeidx].total--;
|
||||
// Adjust corresponding overTime counters
|
||||
clients[clientID].overTime[timeidx]--;
|
||||
|
||||
// Adjust domain counter (no overTime information)
|
||||
int domainID = queries[i].domainID;
|
||||
int domainID = query->domainID;
|
||||
validate_access("domains", domainID, true, __LINE__, __FUNCTION__, __FILE__);
|
||||
domains[domainID].count--;
|
||||
|
||||
// Change other counters according to status of this query
|
||||
switch(queries[i].status)
|
||||
switch(query->status)
|
||||
{
|
||||
case QUERY_UNKNOWN:
|
||||
// Unknown (?)
|
||||
@@ -82,8 +82,8 @@ void *GC_thread(void *val)
|
||||
case QUERY_FORWARDED:
|
||||
// Forwarded to an upstream DNS server
|
||||
counters->forwardedqueries--;
|
||||
validate_access("forwarded", queries[i].forwardID, true, __LINE__, __FUNCTION__, __FILE__);
|
||||
forwarded[queries[i].forwardID].count--;
|
||||
validate_access("forwarded", query->forwardID, true, __LINE__, __FUNCTION__, __FILE__);
|
||||
forwarded[query->forwardID].count--;
|
||||
overTime[timeidx].forwarded--;
|
||||
break;
|
||||
case QUERY_CACHE:
|
||||
@@ -106,7 +106,7 @@ void *GC_thread(void *val)
|
||||
}
|
||||
|
||||
// Update reply counters
|
||||
switch(queries[i].reply)
|
||||
switch(query->reply)
|
||||
{
|
||||
case REPLY_NODATA: // NODATA(-IPv6)
|
||||
counters->reply_NODATA--;
|
||||
@@ -133,10 +133,10 @@ void *GC_thread(void *val)
|
||||
}
|
||||
|
||||
// Update type counters
|
||||
if(queries[i].type >= TYPE_A && queries[i].type < TYPE_MAX)
|
||||
if(query->type >= TYPE_A && query->type < TYPE_MAX)
|
||||
{
|
||||
counters->querytype[queries[i].type-1]--;
|
||||
overTime[timeidx].querytypedata[queries[i].type-1]--;
|
||||
counters->querytype[query->type-1]--;
|
||||
overTime[timeidx].querytypedata[query->type-1]--;
|
||||
}
|
||||
|
||||
// Count removed queries
|
||||
@@ -149,7 +149,7 @@ void *GC_thread(void *val)
|
||||
// Example: (I = now invalid, X = still valid queries, F = free space)
|
||||
// Before: IIIIIIXXXXFF
|
||||
// After: XXXXFFFFFFFF
|
||||
memmove(&queries[0], &queries[removed], (counters->queries - removed)*sizeof(*queries));
|
||||
memmove(getQuery(0), getQuery(removed), (counters->queries - removed)*sizeof(queriesDataStruct));
|
||||
|
||||
// Update queries counter
|
||||
counters->queries -= removed;
|
||||
@@ -157,7 +157,7 @@ void *GC_thread(void *val)
|
||||
lastdbindex -= removed;
|
||||
|
||||
// Zero out remaining memory (marked as "F" in the above example)
|
||||
memset(&queries[counters->queries], 0, (counters->queries_MAX - counters->queries)*sizeof(*queries));
|
||||
memset(getQuery(counters->queries), 0, (counters->queries_MAX - counters->queries)*sizeof(queriesDataStruct));
|
||||
|
||||
// Determine if overTime memory needs to get moved
|
||||
moveOverTimeMemory(mintime);
|
||||
|
||||
@@ -38,78 +38,16 @@ countersStruct *counters = NULL;
|
||||
ConfigStruct config;
|
||||
|
||||
// Variable size array structs
|
||||
queriesDataStruct *queries = NULL;
|
||||
forwardedDataStruct *forwarded = NULL;
|
||||
clientsDataStruct *clients = NULL;
|
||||
domainsDataStruct *domains = NULL;
|
||||
overTimeDataStruct *overTime = NULL;
|
||||
|
||||
void memory_check(int which)
|
||||
{
|
||||
switch(which)
|
||||
{
|
||||
case QUERIES:
|
||||
if(counters->queries >= counters->queries_MAX-1)
|
||||
{
|
||||
// Have to reallocate shared memory
|
||||
queries = enlarge_shmem_struct(QUERIES);
|
||||
if(queries == NULL)
|
||||
{
|
||||
logg("FATAL: Memory allocation failed! Exiting");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case FORWARDED:
|
||||
if(counters->forwarded >= counters->forwarded_MAX-1)
|
||||
{
|
||||
// Have to reallocate shared memory
|
||||
forwarded = enlarge_shmem_struct(FORWARDED);
|
||||
if(forwarded == NULL)
|
||||
{
|
||||
logg("FATAL: Memory allocation failed! Exiting");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CLIENTS:
|
||||
if(counters->clients >= counters->clients_MAX-1)
|
||||
{
|
||||
// Have to reallocate shared memory
|
||||
clients = enlarge_shmem_struct(CLIENTS);
|
||||
if(clients == NULL)
|
||||
{
|
||||
logg("FATAL: Memory allocation failed! Exiting");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case DOMAINS:
|
||||
if(counters->domains >= counters->domains_MAX-1)
|
||||
{
|
||||
// Have to reallocate shared memory
|
||||
domains = enlarge_shmem_struct(DOMAINS);
|
||||
if(domains == NULL)
|
||||
{
|
||||
logg("FATAL: Memory allocation failed! Exiting");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* That cannot happen */
|
||||
logg("Fatal error in memory_check(%i)", which);
|
||||
exit(EXIT_FAILURE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void validate_access(const char * name, int pos, bool testmagic, int line, const char * function, const char * file)
|
||||
{
|
||||
int limit = 0;
|
||||
if(name[0] == 'c') limit = counters->clients_MAX;
|
||||
else if(name[0] == 'd') limit = counters->domains_MAX;
|
||||
else if(name[0] == 'q') limit = counters->queries_MAX;
|
||||
else if(name[0] == 'f') limit = counters->forwarded_MAX;
|
||||
else { logg("Validator error (range)"); killed = 1; }
|
||||
|
||||
@@ -124,7 +62,6 @@ void validate_access(const char * name, int pos, bool testmagic, int line, const
|
||||
unsigned char magic = 0x00;
|
||||
if(name[0] == 'c') magic = clients[pos].magic;
|
||||
else if(name[0] == 'd') magic = domains[pos].magic;
|
||||
else if(name[0] == 'q') magic = queries[pos].magic;
|
||||
else if(name[0] == 'f') magic = forwarded[pos].magic;
|
||||
else { logg("Validator error (magic byte)"); killed = 1; }
|
||||
if(magic != MAGICBYTE)
|
||||
|
||||
+5
-3
@@ -125,16 +125,18 @@ void moveOverTimeMemory(time_t mintime)
|
||||
// Correct time indices of queries. This is necessary because we just moved the slot this index points to
|
||||
for(int queryID = 0; queryID < counters->queries; queryID++)
|
||||
{
|
||||
// Get query pointer
|
||||
queriesDataStruct* query = getQuery(queryID);
|
||||
// Check if the index would become negative if we adjusted it
|
||||
if(((int)queries[queryID].timeidx - (int)moveOverTime) < 0)
|
||||
if(((int)query->timeidx - (int)moveOverTime) < 0)
|
||||
{
|
||||
// This should never happen, but we print a warning if it still happens
|
||||
// We don't do anything in this case
|
||||
logg("WARN: moveOverTimeMemory(): overTime time index correction failed (%i: %u / %u)", queryID, queries[queryID].timeidx, moveOverTime);
|
||||
logg("WARN: moveOverTimeMemory(): overTime time index correction failed (%i: %u / %u)", queryID, query->timeidx, moveOverTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
queries[queryID].timeidx -= moveOverTime;
|
||||
query->timeidx -= moveOverTime;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -36,6 +36,9 @@ static SharedMemory shm_forwarded = { 0 };
|
||||
static SharedMemory shm_overTime = { 0 };
|
||||
static SharedMemory shm_settings = { 0 };
|
||||
|
||||
// Variable size array structs
|
||||
static queriesDataStruct *queries = NULL;
|
||||
|
||||
typedef struct {
|
||||
pthread_mutex_t lock;
|
||||
bool waitingForLock;
|
||||
@@ -511,3 +514,80 @@ static size_t get_optimal_object_size(size_t objsize, unsigned int minsize)
|
||||
return optsize;
|
||||
}
|
||||
}
|
||||
|
||||
void memory_check(int which)
|
||||
{
|
||||
switch(which)
|
||||
{
|
||||
case QUERIES:
|
||||
if(counters->queries >= counters->queries_MAX-1)
|
||||
{
|
||||
// Have to reallocate shared memory
|
||||
queries = enlarge_shmem_struct(QUERIES);
|
||||
if(queries == NULL)
|
||||
{
|
||||
logg("FATAL: Memory allocation failed! Exiting");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case FORWARDED:
|
||||
if(counters->forwarded >= counters->forwarded_MAX-1)
|
||||
{
|
||||
// Have to reallocate shared memory
|
||||
forwarded = enlarge_shmem_struct(FORWARDED);
|
||||
if(forwarded == NULL)
|
||||
{
|
||||
logg("FATAL: Memory allocation failed! Exiting");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CLIENTS:
|
||||
if(counters->clients >= counters->clients_MAX-1)
|
||||
{
|
||||
// Have to reallocate shared memory
|
||||
clients = enlarge_shmem_struct(CLIENTS);
|
||||
if(clients == NULL)
|
||||
{
|
||||
logg("FATAL: Memory allocation failed! Exiting");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case DOMAINS:
|
||||
if(counters->domains >= counters->domains_MAX-1)
|
||||
{
|
||||
// Have to reallocate shared memory
|
||||
domains = enlarge_shmem_struct(DOMAINS);
|
||||
if(domains == NULL)
|
||||
{
|
||||
logg("FATAL: Memory allocation failed! Exiting");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* That cannot happen */
|
||||
logg("Fatal error in memory_check(%i)", which);
|
||||
exit(EXIT_FAILURE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
queriesDataStruct* _getQuery(int queryID, int line, const char * function, const char * file)
|
||||
{
|
||||
if(queryID < 0 || queryID > counters->queries_MAX)
|
||||
{
|
||||
logg("FATAL: Trying to access query ID %i, but maximum is %i", queryID, counters->queries_MAX);
|
||||
logg(" found in %s() (%s:%i)", function, file, line);
|
||||
return NULL;
|
||||
}
|
||||
if(queries[queryID].magic != MAGICBYTE)
|
||||
{
|
||||
logg("FATAL: Trying to access query ID %i, but magic byte is %x", queryID, queries[queryID].magic);
|
||||
logg(" found in %s() (%s:%i)", function, file, line);
|
||||
return NULL;
|
||||
}
|
||||
return &queries[queryID];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user