diff --git a/src/FTL.h b/src/FTL.h index 002627fb..a9359c10 100644 --- a/src/FTL.h +++ b/src/FTL.h @@ -52,8 +52,8 @@ #define SOCKETBUFFERLEN 1024 // How often do we garbage collect (to ensure we only have data fitting to the MAXLOGAGE defined above)? [seconds] -// Default: 3600 (once per hour) -#define GCinterval 3600 +// Default: 600 (10 minute intervals) +#define GCinterval 600 // Delay applied to the garbage collecting [seconds] // Default: -60 (one minute before a full hour) @@ -69,15 +69,18 @@ #define MAXLOGAGE 24 // Interval for overTime data [seconds] -// Default: 600 (10 minute intervals) -#define OVERTIME_INTERVAL 600 +// Default: same as GCinterval +#define OVERTIME_INTERVAL GCinterval // How many overTime slots do we need? -// (24+1) hours * number of intervals per hour -// We need to be able to hold 25 hours as we need some reserve -// due to that GC is only running once an hours so the shown data -// can be 24 hours + 59 minutes -#define OVERTIME_SLOTS ((MAXLOGAGE+1)*3600/OVERTIME_INTERVAL) +// This is the maximum log age divided by the overtime interval +// plus one extra timeslot for the very first timeslot. +// Example (default settings): 24*3600/600 + 1 = 144 + 1 slots +// Which corresponds to something like +// Mon 08:05:00 - Tue 08:05:00 +// Without the extra last timestamp, the first timeslot +// would incorrectly be located at Mon 08:15:00 +#define OVERTIME_SLOTS ((MAXLOGAGE*3600)/OVERTIME_INTERVAL + 1) // Interval for re-resolving ALL known host names [seconds] // Default: 3600 (once every hour) diff --git a/src/api/api.c b/src/api/api.c index 3b1ae78b..a63ec31e 100644 --- a/src/api/api.c +++ b/src/api/api.c @@ -152,39 +152,9 @@ void getStats(const int *sock) void getOverTime(const int *sock) { - int from = 0, until = OVERTIME_SLOTS; - bool found = false; - time_t mintime = overTime[0].timestamp; - - // Start with the first non-empty overTime slot - for(int slot = 0; slot < OVERTIME_SLOTS; slot++) - { - if((overTime[slot].total > 0 || overTime[slot].blocked > 0) && - overTime[slot].timestamp >= mintime) - { - from = slot; - found = true; - break; - } - } - - // End with last non-empty overTime slot - for(int slot = 0; slot < OVERTIME_SLOTS; slot++) - { - if(overTime[slot].timestamp >= time(NULL)) - { - until = slot; - break; - } - } - - // Check if there is any data to be sent - if(!found) - return; - if(istelnet[*sock]) { - for(int slot = from; slot < until; slot++) + for(int slot = 0; slot < OVERTIME_SLOTS; slot++) { ssend(*sock,"%lli %i %i\n", (long long)overTime[slot].timestamp, @@ -198,15 +168,15 @@ void getOverTime(const int *sock) // and map16 can hold up to (2^16)-1 = 65535 pairs // Send domains over time - pack_map16_start(*sock, (uint16_t) (until - from)); - for(int slot = from; slot < until; slot++) { + pack_map16_start(*sock, (uint16_t) OVERTIME_SLOTS); + for(int slot = 0; slot < OVERTIME_SLOTS; slot++) { pack_int32(*sock, (int32_t)overTime[slot].timestamp); pack_int32(*sock, overTime[slot].total); } // Send ads over time - pack_map16_start(*sock, (uint16_t) (until - from)); - for(int slot = from; slot < until; slot++) { + pack_map16_start(*sock, (uint16_t) OVERTIME_SLOTS); + for(int slot = 0; slot < OVERTIME_SLOTS; slot++) { pack_int32(*sock, (int32_t)overTime[slot].timestamp); pack_int32(*sock, overTime[slot].blocked); } @@ -1255,36 +1225,11 @@ void getDBstats(const int *sock) void getClientsOverTime(const int *sock) { - int sendit = -1, until = OVERTIME_SLOTS; - // Exit before processing any data if requested via config setting get_privacy_level(NULL); if(config.privacylevel >= PRIVACY_HIDE_DOMAINS_CLIENTS) return; - // Find minimum ID to send - for(int slot = 0; slot < OVERTIME_SLOTS; slot++) - { - if((overTime[slot].total > 0 || overTime[slot].blocked > 0) && - overTime[slot].timestamp >= overTime[0].timestamp) - { - sendit = slot; - break; - } - } - if(sendit < 0) - return; - - // Find minimum ID to send - for(int slot = 0; slot < OVERTIME_SLOTS; slot++) - { - if(overTime[slot].timestamp >= time(NULL)) - { - until = slot; - break; - } - } - // 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 @@ -1314,7 +1259,7 @@ void getClientsOverTime(const int *sock) } // Main return loop - for(int slot = sendit; slot < until; slot++) + for(int slot = 0; slot < OVERTIME_SLOTS; slot++) { if(istelnet[*sock]) ssend(*sock, "%lli", (long long)overTime[slot].timestamp); diff --git a/src/dnsmasq_interface.c b/src/dnsmasq_interface.c index 8d82ec42..0730c40b 100644 --- a/src/dnsmasq_interface.c +++ b/src/dnsmasq_interface.c @@ -3348,8 +3348,8 @@ int check_struct_sizes(void) int result = 0; result += check_one_struct("ConfigStruct", sizeof(ConfigStruct), 112, 104); result += check_one_struct("queriesData", sizeof(queriesData), 56, 44); - result += check_one_struct("upstreamsData", sizeof(upstreamsData), 640, 624); - result += check_one_struct("clientsData", sizeof(clientsData), 696, 668); + result += check_one_struct("upstreamsData", sizeof(upstreamsData), 616, 604); + result += check_one_struct("clientsData", sizeof(clientsData), 672, 648); result += check_one_struct("domainsData", sizeof(domainsData), 24, 20); result += check_one_struct("DNSCacheData", sizeof(DNSCacheData), 16, 16); result += check_one_struct("ednsData", sizeof(ednsData), 72, 72); diff --git a/src/gc.c b/src/gc.c index 2dd4d2d0..b2eff794 100644 --- a/src/gc.c +++ b/src/gc.c @@ -159,7 +159,6 @@ void *GC_thread(void *val) // Align the start time of this GC run to the GCinterval. This will also align with the // oldest overTime interval after GC is done. mintime -= mintime % GCinterval; - mintime += GCinterval; if(config.debug & DEBUG_GC) { diff --git a/src/overTime.c b/src/overTime.c index 786f0bd8..292070bd 100644 --- a/src/overTime.c +++ b/src/overTime.c @@ -29,7 +29,9 @@ static void initSlot(const unsigned int index, const time_t timestamp) // Possible debug printing if(config.debug & DEBUG_OVERTIME) { - logg("initSlot(%u, %llu): Zeroing overTime slot", index, (long long)timestamp); + char timestr[20]; + strftime(timestr, 20, "%Y-%m-%d %H:%M:%S", localtime(×tamp)); + logg("initSlot(%u, %llu): Zeroing overTime slot at %s", index, (long long)timestamp, timestr); } // Initialize overTime entry @@ -70,20 +72,29 @@ void initOverTime(void) // Get current timestamp time_t now = time(NULL); - // Get the centered timestamp of the current timestamp - const time_t last_slot_ts = now - now % OVERTIME_INTERVAL + (OVERTIME_INTERVAL / 2); - const time_t first_slot_ts = last_slot_ts - (OVERTIME_SLOTS-1) * OVERTIME_INTERVAL; + // Get the centered timestamp of the end of the next garbage collection interval + // This is necessary to construct all slots until the point where we are moving + // the entire overTime structure into the future (i.e., generate "new" slots) + // Get beginning of Advance to Center this interval at + // previous GC interval next GC int. 5 minutes less than full + // vvvvvvvvvvvvvvvvvvvvvv vvvvvvvvvvvv vvvvvvvvvvvvvvvvvvvvvvvvv + const time_t newest = now - now % GCinterval + GCinterval - (OVERTIME_INTERVAL / 2); + // Oldest timestamp is (OVERTIME_SLOTS-1) times the OVERTIME_INTERVAL in the past + const time_t oldest = newest - (OVERTIME_SLOTS-1) * OVERTIME_INTERVAL; if(config.debug & DEBUG_OVERTIME) - logg("initOverTime(): Initializing %i slots from %llu to %llu", - OVERTIME_SLOTS, - (long long)first_slot_ts, - (long long)last_slot_ts); + { + char first[20], last[20]; + strftime(first, 20, "%Y-%m-%d %H:%M:%S", localtime(&oldest)); + strftime(last, 20, "%Y-%m-%d %H:%M:%S", localtime(&newest)); + logg("initOverTime(): Initializing %i slots from %s (%llu) to %s (%llu)", + OVERTIME_SLOTS, first, (long long)oldest, last, (long long)newest); + } // Iterate over overTime for(int i = 0; i < OVERTIME_SLOTS; i++) { - time_t this_slot_ts = first_slot_ts + OVERTIME_INTERVAL * i; + time_t this_slot_ts = oldest + OVERTIME_INTERVAL * i; // Initialize overTime slot initSlot(i, this_slot_ts); }