mirror of
https://github.com/pi-hole/FTL.git
synced 2024-10-26 16:52:18 +02:00
Merge pull request #134 from pi-hole/new/clientsovertime
[WIP] Add clients over time data structure
This commit is contained in:
@@ -169,6 +169,8 @@ typedef struct {
|
||||
int forwardnum;
|
||||
int *forwarddata;
|
||||
int *querytypedata;
|
||||
int clientnum;
|
||||
int *clientdata;
|
||||
} overTimeDataStruct;
|
||||
|
||||
typedef struct {
|
||||
@@ -179,6 +181,7 @@ typedef struct {
|
||||
int forwardedips;
|
||||
int forwardednames;
|
||||
int forwarddata;
|
||||
int clientdata;
|
||||
int querytypedata;
|
||||
} memoryStruct;
|
||||
|
||||
|
||||
@@ -272,6 +272,8 @@ void process_pihole_log(int file)
|
||||
overTime[timeidx].forwardnum = 0;
|
||||
overTime[timeidx].forwarddata = NULL;
|
||||
overTime[timeidx].querytypedata = calloc(2, sizeof(int));
|
||||
overTime[timeidx].clientnum = 0;
|
||||
overTime[timeidx].clientdata = NULL;
|
||||
memory.querytypedata += 2*sizeof(int);
|
||||
counters.overTime++;
|
||||
|
||||
@@ -600,6 +602,27 @@ void process_pihole_log(int file)
|
||||
break;
|
||||
}
|
||||
|
||||
// Determine if there is enough space for saving the current
|
||||
// clientID in the overTime data structure, allocate space otherwise
|
||||
validate_access("overTime", timeidx, true, __LINE__, __FUNCTION__, __FILE__);
|
||||
if(overTime[timeidx].clientnum <= clientID)
|
||||
{
|
||||
// Reallocate more space for clientdata
|
||||
overTime[timeidx].clientdata = realloc(overTime[timeidx].clientdata, (clientID+1)*sizeof(*overTime[timeidx].clientdata));
|
||||
// Initialize new data fields with zeroes
|
||||
for(i = overTime[timeidx].clientnum; i <= clientID; i++)
|
||||
{
|
||||
overTime[timeidx].clientdata[i] = 0;
|
||||
memory.clientdata++;
|
||||
}
|
||||
// Update counter
|
||||
overTime[timeidx].clientnum = clientID + 1;
|
||||
}
|
||||
|
||||
// Update overTime data structure with the new client
|
||||
validate_access_oTcl(timeidx, clientID, __LINE__, __FUNCTION__, __FILE__);
|
||||
overTime[timeidx].clientdata[clientID]++;
|
||||
|
||||
// Free allocated memory
|
||||
free(client);
|
||||
free(domain);
|
||||
@@ -655,11 +678,13 @@ void process_pihole_log(int file)
|
||||
overTime[timeidx].forwardnum = 0;
|
||||
overTime[timeidx].forwarddata = NULL;
|
||||
overTime[timeidx].querytypedata = calloc(2, sizeof(int));
|
||||
overTime[timeidx].clientnum = 0;
|
||||
overTime[timeidx].clientdata = NULL;
|
||||
memory.querytypedata += 2*sizeof(int);
|
||||
counters.overTime++;
|
||||
}
|
||||
// Determine if there is enough space for saving the current
|
||||
// forwardID in the overTime data structure -allocate space otherwise
|
||||
// forwardID in the overTime data structure, allocate space otherwise
|
||||
validate_access("overTime", timeidx, true, __LINE__, __FUNCTION__, __FILE__);
|
||||
if(overTime[timeidx].forwardnum <= forwardID)
|
||||
{
|
||||
@@ -1041,7 +1066,18 @@ void validate_access_oTfd(int timeidx, int pos, int line, const char * function,
|
||||
if(pos >= limit || pos < 0)
|
||||
{
|
||||
logg("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
|
||||
logg("FATAL ERROR: Trying to access overTime.forwardata[%i], but maximum is %i", pos, limit);
|
||||
logg("FATAL ERROR: Trying to access overTime.forwarddata[%i], but maximum is %i", pos, limit);
|
||||
logg(" found in %s() (line %i) in %s", function, line, file);
|
||||
}
|
||||
}
|
||||
|
||||
void validate_access_oTcl(int timeidx, int pos, int line, const char * function, const char * file)
|
||||
{
|
||||
int limit = overTime[timeidx].clientnum;
|
||||
if(pos >= limit || pos < 0)
|
||||
{
|
||||
logg("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
|
||||
logg("FATAL ERROR: Trying to access overTime.clientdata[%i], but maximum is %i", pos, limit);
|
||||
logg(" found in %s() (line %i) in %s", function, line, file);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,6 +30,8 @@ void getClientID(int *sock);
|
||||
void getQueryTypesOverTime(int *sock);
|
||||
void getVersion(int *sock);
|
||||
void getDBstats(int *sock);
|
||||
void getClientsOverTime(int *sock);
|
||||
void getClientNames(int *sock);
|
||||
|
||||
void process_request(char *client_message, int *sock)
|
||||
{
|
||||
@@ -113,6 +115,16 @@ void process_request(char *client_message, int *sock)
|
||||
processed = true;
|
||||
getDBstats(sock);
|
||||
}
|
||||
else if(command(client_message, ">ClientsoverTime"))
|
||||
{
|
||||
processed = true;
|
||||
getClientsOverTime(sock);
|
||||
}
|
||||
else if(command(client_message, ">client-names"))
|
||||
{
|
||||
processed = true;
|
||||
getClientNames(sock);
|
||||
}
|
||||
|
||||
// Test only at the end if we want to quit or kill
|
||||
// so things can be processed before
|
||||
@@ -439,7 +451,7 @@ void getTopClients(char *client_message, int *sock)
|
||||
// Sort temporary array
|
||||
qsort(temparray, counters.clients, sizeof(int[2]), cmpasc);
|
||||
|
||||
// Get domains 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");
|
||||
if(excludeclients != NULL)
|
||||
{
|
||||
@@ -1026,3 +1038,116 @@ void getDBstats(int *sock)
|
||||
if(debugclients)
|
||||
logg("Sent DB info to client, ID: %i", *sock);
|
||||
}
|
||||
|
||||
void getClientsOverTime(int *sock)
|
||||
{
|
||||
char server_message[SOCKETBUFFERLEN];
|
||||
int i, sendit = -1;
|
||||
|
||||
for(i = 0; i < counters.overTime; i++)
|
||||
{
|
||||
validate_access("overTime", i, true, __LINE__, __FUNCTION__, __FILE__);
|
||||
if((overTime[i].total > 0 || overTime[i].blocked > 0))
|
||||
{
|
||||
sendit = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(sendit < 0)
|
||||
return;
|
||||
|
||||
// Get clients which the user doesn't want to see
|
||||
char * excludeclients = read_setupVarsconf("API_EXCLUDE_CLIENTS");
|
||||
// Array of clients to be skipped in the output
|
||||
// if skipclient[i] == true then this client should be hidden from
|
||||
// returned data. We initialize it with false
|
||||
bool skipclient[counters.clients];
|
||||
memset(skipclient, false, counters.clients*sizeof(bool));
|
||||
|
||||
if(excludeclients != NULL)
|
||||
{
|
||||
getSetupVarsArray(excludeclients);
|
||||
|
||||
for(i=0; i < counters.clients; i++)
|
||||
{
|
||||
validate_access("clients", i, true, __LINE__, __FUNCTION__, __FILE__);
|
||||
// Check if this client should be skipped
|
||||
if(insetupVarsArray(clients[i].ip) || insetupVarsArray(clients[i].name))
|
||||
{
|
||||
skipclient[i] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Main return loop
|
||||
for(i = sendit; i < counters.overTime; i++)
|
||||
{
|
||||
validate_access("overTime", i, true, __LINE__, __FUNCTION__, __FILE__);
|
||||
sprintf(server_message, "%i", overTime[i].timestamp);
|
||||
|
||||
// Loop over forward destinations to generate output to be sent to the client
|
||||
int j;
|
||||
for(j = 0; j < counters.clients; j++)
|
||||
{
|
||||
int thisclient = 0;
|
||||
|
||||
if(skipclient[j])
|
||||
continue;
|
||||
|
||||
if(j < overTime[i].clientnum)
|
||||
{
|
||||
// This client entry does already exist at this timestamp
|
||||
// -> use counter of requests sent to this destination
|
||||
thisclient = overTime[i].clientdata[j];
|
||||
}
|
||||
|
||||
sprintf(server_message + strlen(server_message), " %i", thisclient);
|
||||
}
|
||||
|
||||
sprintf(server_message + strlen(server_message), "\n");
|
||||
swrite(server_message, *sock);
|
||||
}
|
||||
|
||||
if(excludeclients != NULL)
|
||||
clearSetupVarsArray();
|
||||
}
|
||||
|
||||
void getClientNames(int *sock)
|
||||
{
|
||||
char server_message[SOCKETBUFFERLEN];
|
||||
int i;
|
||||
|
||||
// Get clients which the user doesn't want to see
|
||||
char * excludeclients = read_setupVarsconf("API_EXCLUDE_CLIENTS");
|
||||
// Array of clients to be skipped in the output
|
||||
// if skipclient[i] == true then this client should be hidden from
|
||||
// returned data. We initialize it with false
|
||||
bool skipclient[counters.clients];
|
||||
memset(skipclient, false, counters.clients*sizeof(bool));
|
||||
|
||||
if(excludeclients != NULL)
|
||||
{
|
||||
getSetupVarsArray(excludeclients);
|
||||
|
||||
for(i=0; i < counters.clients; i++)
|
||||
{
|
||||
validate_access("clients", i, true, __LINE__, __FUNCTION__, __FILE__);
|
||||
// Check if this client should be skipped
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Loop over clients to generate output to be sent to the client
|
||||
for(i = 0; i < counters.clients; i++)
|
||||
{
|
||||
validate_access("clients", i, true, __LINE__, __FUNCTION__, __FILE__);
|
||||
if(insetupVarsArray(clients[i].ip) || insetupVarsArray(clients[i].name))
|
||||
continue;
|
||||
|
||||
sprintf(server_message,"%i %i %s %s\n", i, clients[i].count, clients[i].ip, clients[i].name);
|
||||
swrite(server_message, *sock);
|
||||
}
|
||||
|
||||
if(excludeclients != NULL)
|
||||
clearSetupVarsArray();
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ void process_pihole_log(int file);
|
||||
void *pihole_log_thread(void *val);
|
||||
void validate_access(const char * name, int pos, bool testmagic, int line, const char * function, const char * file);
|
||||
void validate_access_oTfd(int timeidx, int pos, int line, const char * function, const char * file);
|
||||
void validate_access_oTcl(int timeidx, int pos, int line, const char * function, const char * file);
|
||||
void reresolveHostnames(void);
|
||||
|
||||
void pihole_log_flushed(bool message);
|
||||
|
||||
Reference in New Issue
Block a user