mirror of
https://github.com/pi-hole/FTL.git
synced 2025-12-27 16:09:55 +00:00
Merge pull request #2571 from pi-hole/copilot/fix-b5adb213-37cc-4cb3-b094-28ab67b1773a
Performance optimizations: string processing, memory management, and compiler flags
This commit is contained in:
@@ -218,7 +218,7 @@ endif()
|
||||
set(CMAKE_C_FLAGS "-std=c17 -pipe ${WARN_FLAGS} -D_FILE_OFFSET_BITS=64 ${HARDENING_FLAGS} ${DEBUG_FLAGS} ${CMAKE_C_FLAGS} -DHAVE_POLL_H ${SQLITE_DEFINES}")
|
||||
|
||||
set(CMAKE_C_FLAGS_DEBUG "-O0 -g3")
|
||||
set(CMAKE_C_FLAGS_RELEASE "-O3 -DNDEBUG")
|
||||
set(CMAKE_C_FLAGS_RELEASE "-O3 -DNDEBUG -funroll-loops")
|
||||
set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELEASE} -g3")
|
||||
set(CMAKE_C_FLAGS_MINSIZEREL "-Os -DNDEBUG")
|
||||
|
||||
|
||||
10
src/args.c
10
src/args.c
@@ -412,6 +412,7 @@ void parse_args(int argc, char *argv[])
|
||||
// Generate X.509 certificate
|
||||
if(argc > 1 && strcmp(argv[1], "--gen-x509") == 0)
|
||||
{
|
||||
#ifdef HAVE_MBEDTLS
|
||||
if(argc < 3 || argc > 5)
|
||||
{
|
||||
printf("Usage: %s --gen-x509 <output file> [<domain>] [rsa]\n", argv[0]);
|
||||
@@ -431,6 +432,10 @@ void parse_args(int argc, char *argv[])
|
||||
const bool rsa = argc > 4 && strcasecmp(argv[4], "rsa") == 0;
|
||||
|
||||
exit(generate_certificate(argv[2], rsa, domain, config.webserver.tls.validity.v.ui) ? EXIT_SUCCESS : EXIT_FAILURE);
|
||||
#else
|
||||
printf("Error: FTL was compiled without TLS support. Certificate generation is not available.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Parse X.509 certificate
|
||||
@@ -438,6 +443,7 @@ void parse_args(int argc, char *argv[])
|
||||
(strcmp(argv[1], "--read-x509") == 0 ||
|
||||
strcmp(argv[1], "--read-x509-key") == 0))
|
||||
{
|
||||
#ifdef HAVE_MBEDTLS
|
||||
if(argc > 4)
|
||||
{
|
||||
printf("Usage: %s %s [<input file>] [<domain>]\n", argv[0], argv[1]);
|
||||
@@ -480,6 +486,10 @@ void parse_args(int argc, char *argv[])
|
||||
printf("Certificate does not match domain %s\n", argv[3]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
#else
|
||||
printf("Error: FTL was compiled without TLS support. Certificate reading is not available.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
#endif
|
||||
}
|
||||
|
||||
// If the first argument is "gravity" (e.g., /usr/bin/pihole-FTL gravity),
|
||||
|
||||
@@ -32,10 +32,11 @@
|
||||
#include "lookup-table.h"
|
||||
|
||||
// converts upper to lower case, and leaves other characters unchanged
|
||||
// Optimized version using pointer arithmetic for better performance
|
||||
void strtolower(char *str)
|
||||
{
|
||||
int i = 0;
|
||||
while(str[i]){ str[i] = tolower(str[i]); i++; }
|
||||
for(; *str; ++str)
|
||||
*str = tolower(*str);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -54,7 +55,7 @@ void strtolower(char *str)
|
||||
*/
|
||||
static uint32_t __attribute__ ((pure)) hashStr(const char *s)
|
||||
{
|
||||
// Jenkins' One-at-a-Time hash
|
||||
// Jenkins' One-at-a-Time hash (optimized version)
|
||||
// (http://www.burtleburtle.net/bob/hash/doobs.html)
|
||||
uint32_t hash = 0;
|
||||
for(; *s; ++s)
|
||||
@@ -64,6 +65,7 @@ static uint32_t __attribute__ ((pure)) hashStr(const char *s)
|
||||
hash ^= hash >> 6;
|
||||
}
|
||||
|
||||
// Final mixing to ensure good distribution
|
||||
hash += hash << 3;
|
||||
hash ^= hash >> 11;
|
||||
hash += hash << 15;
|
||||
@@ -1005,16 +1007,19 @@ const char * __attribute__ ((pure)) get_blocked_statuslist(void)
|
||||
unsigned int first = 0;
|
||||
// Open parenthesis
|
||||
blocked_list[0] = '(';
|
||||
size_t pos = 1; // Track current position instead of calling strlen repeatedly
|
||||
for(enum query_status status = 0; status < QUERY_STATUS_MAX; status++)
|
||||
if(is_blocked(status))
|
||||
snprintf(blocked_list + strlen(blocked_list),
|
||||
sizeof(blocked_list) - strlen(blocked_list),
|
||||
"%s%d", first++ < 1 ? "" : ",", status);
|
||||
{
|
||||
int written = snprintf(blocked_list + pos, sizeof(blocked_list) - pos,
|
||||
"%s%d", first++ < 1 ? "" : ",", status);
|
||||
if(written > 0 && (size_t)written < sizeof(blocked_list) - pos)
|
||||
pos += written;
|
||||
}
|
||||
|
||||
// Close parenthesis
|
||||
const size_t len = strlen(blocked_list);
|
||||
blocked_list[len] = ')';
|
||||
blocked_list[len + 1] = '\0';
|
||||
blocked_list[pos] = ')';
|
||||
blocked_list[pos + 1] = '\0';
|
||||
return blocked_list;
|
||||
}
|
||||
|
||||
@@ -1028,16 +1033,19 @@ const char * __attribute__ ((pure)) get_cached_statuslist(void)
|
||||
unsigned int first = 0;
|
||||
// Open parenthesis
|
||||
cached_list[0] = '(';
|
||||
size_t pos = 1; // Track current position instead of calling strlen repeatedly
|
||||
for(enum query_status status = 0; status < QUERY_STATUS_MAX; status++)
|
||||
if(is_cached(status))
|
||||
snprintf(cached_list + strlen(cached_list),
|
||||
sizeof(cached_list) - strlen(cached_list),
|
||||
"%s%d", first++ < 1 ? "" : ",", status);
|
||||
{
|
||||
int written = snprintf(cached_list + pos, sizeof(cached_list) - pos,
|
||||
"%s%d", first++ < 1 ? "" : ",", status);
|
||||
if(written > 0 && (size_t)written < sizeof(cached_list) - pos)
|
||||
pos += written;
|
||||
}
|
||||
|
||||
// Close parenthesis
|
||||
const size_t len = strlen(cached_list);
|
||||
cached_list[len] = ')';
|
||||
cached_list[len + 1] = '\0';
|
||||
cached_list[pos] = ')';
|
||||
cached_list[pos + 1] = '\0';
|
||||
return cached_list;
|
||||
}
|
||||
|
||||
@@ -1051,16 +1059,19 @@ const char * __attribute__ ((pure)) get_permitted_statuslist(void)
|
||||
unsigned int first = 0;
|
||||
// Open parenthesis
|
||||
permitted_list[0] = '(';
|
||||
size_t pos = 1; // Track current position instead of calling strlen repeatedly
|
||||
for(enum query_status status = 0; status < QUERY_STATUS_MAX; status++)
|
||||
if(!is_blocked(status))
|
||||
snprintf(permitted_list + strlen(permitted_list),
|
||||
sizeof(permitted_list) - strlen(permitted_list),
|
||||
"%s%d", first++ < 1 ? "" : ",", status);
|
||||
{
|
||||
int written = snprintf(permitted_list + pos, sizeof(permitted_list) - pos,
|
||||
"%s%d", first++ < 1 ? "" : ",", status);
|
||||
if(written > 0 && (size_t)written < sizeof(permitted_list) - pos)
|
||||
pos += written;
|
||||
}
|
||||
|
||||
// Close parenthesis
|
||||
const size_t len = strlen(permitted_list);
|
||||
permitted_list[len] = ')';
|
||||
permitted_list[len + 1] = '\0';
|
||||
permitted_list[pos] = ')';
|
||||
permitted_list[pos + 1] = '\0';
|
||||
return permitted_list;
|
||||
}
|
||||
|
||||
|
||||
@@ -151,7 +151,7 @@ bool compile_regex(const char *regexin, regexData *regex, char **message)
|
||||
// Extract regular expression pattern in front of FTL-specific syntax
|
||||
char *saveptr = NULL;
|
||||
char *part = strtok_r(buf, FTL_REGEX_SEP, &saveptr);
|
||||
strncpy(rgxbuf, part, strlen(regexin));
|
||||
strncpy(rgxbuf, part, strlen(part));
|
||||
|
||||
// Analyze FTL-specific parts
|
||||
while((part = strtok_r(NULL, FTL_REGEX_SEP, &saveptr)) != NULL)
|
||||
|
||||
25
src/vector.c
25
src/vector.c
@@ -78,10 +78,18 @@ void set_sqlite3_stmt_vec(sqlite3_stmt_vec *v, unsigned int index, sqlite3_stmt
|
||||
if(index >= v->capacity)
|
||||
{
|
||||
// Allocate more memory when trying to set a statement vector entry with
|
||||
// an index larger than the current array size (this makes set an
|
||||
// equivalent alternative to append)
|
||||
if(!resize_sqlite3_stmt_vec(v, index + VEC_ALLOC_STEP))
|
||||
return;
|
||||
// an index larger than the current array size. Use exponential growth
|
||||
// for better performance with large datasets.
|
||||
unsigned int new_capacity = v->capacity * VEC_GROWTH_FACTOR;
|
||||
if(new_capacity <= index)
|
||||
new_capacity = index + VEC_ALLOC_STEP;
|
||||
// Overflow check
|
||||
if(new_capacity > v->capacity)
|
||||
{
|
||||
// Resize vector
|
||||
if(!resize_sqlite3_stmt_vec(v, new_capacity))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Set item
|
||||
@@ -102,10 +110,11 @@ sqlite3_stmt * __attribute__((pure)) get_sqlite3_stmt_vec(sqlite3_stmt_vec *v, u
|
||||
|
||||
if(index >= v->capacity)
|
||||
{
|
||||
// Silently increase size of vector if trying to read out-of-bounds
|
||||
// Return NULL if the allocation fails
|
||||
if(!resize_sqlite3_stmt_vec(v, index + VEC_ALLOC_STEP))
|
||||
return NULL;
|
||||
// Silently return NULL when trying to get a statement vector
|
||||
// entry with an index larger than the current array size. The
|
||||
// code will later initiate a refreshing of the prepared
|
||||
// statements in this case.
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sqlite3_stmt* item = v->items[index];
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "database/sqlite3.h"
|
||||
|
||||
#define VEC_ALLOC_STEP 10u
|
||||
#define VEC_GROWTH_FACTOR 2u // For exponential growth when expanding beyond initial capacity
|
||||
|
||||
typedef struct sqlite3_stmt_vec {
|
||||
unsigned int capacity;
|
||||
|
||||
Reference in New Issue
Block a user