mirror of
https://github.com/pi-hole/FTL.git
synced 2024-10-26 16:52:18 +02:00
Add new CONNECTION_ERROR message to the Pi-hole diagnosis system
Signed-off-by: DL6ER <dl6er@dl6er.de>
This commit is contained in:
@@ -60,6 +60,8 @@ static const char *get_message_type_str(const enum message_type type)
|
||||
return "DISK_EXTENDED";
|
||||
case CERTIFICATE_DOMAIN_MISMATCH_MESSAGE:
|
||||
return "CERTIFICATE_DOMAIN_MISMATCH";
|
||||
case CONNECTION_ERROR_MESSAGE:
|
||||
return "CONNECTION_ERROR";
|
||||
case MAX_MESSAGE:
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
@@ -92,6 +94,8 @@ static enum message_type get_message_type_from_string(const char *typestr)
|
||||
return DISK_MESSAGE_EXTENDED;
|
||||
else if (strcmp(typestr, "CERTIFICATE_DOMAIN_MISMATCH") == 0)
|
||||
return CERTIFICATE_DOMAIN_MISMATCH_MESSAGE;
|
||||
else if (strcmp(typestr, "CONNECTION_ERROR") == 0)
|
||||
return CONNECTION_ERROR_MESSAGE;
|
||||
else
|
||||
return MAX_MESSAGE;
|
||||
}
|
||||
@@ -183,6 +187,14 @@ static unsigned char message_blob_types[MAX_MESSAGE][5] =
|
||||
SQLITE_NULL, // not used
|
||||
SQLITE_NULL, // not used
|
||||
SQLITE_NULL // not used
|
||||
},
|
||||
{
|
||||
// CONNECTION_ERROR_MESSAGE: The message column contains the server address
|
||||
SQLITE_TEXT, // reason
|
||||
SQLITE_TEXT, // error message
|
||||
SQLITE_NULL, // not used
|
||||
SQLITE_NULL, // not used
|
||||
SQLITE_NULL // not used
|
||||
}
|
||||
};
|
||||
// Create message table in the database
|
||||
@@ -710,6 +722,40 @@ static void format_certificate_domain_mismatch(char *plain, const int sizeof_pla
|
||||
free(escaped_domain);
|
||||
}
|
||||
|
||||
static void format_connection_error(char *plain, const int sizeof_plain, char *html, const int sizeof_html,
|
||||
const char *server, const char *reason, const char *error)
|
||||
{
|
||||
if(snprintf(plain, sizeof_plain, "Connection error (%s): %s (%s)", server, reason, error) > sizeof_plain)
|
||||
log_warn("format_connection_error(): Buffer too small to hold plain message, warning truncated");
|
||||
|
||||
// Return early if HTML text is not required
|
||||
if(sizeof_html < 1 || html == NULL)
|
||||
return;
|
||||
|
||||
char *escaped_reason = escape_html(reason);
|
||||
char *escaped_error = escape_html(error);
|
||||
char *escaped_server = escape_html(server);
|
||||
|
||||
// Return early if memory allocation failed
|
||||
if(escaped_reason == NULL || escaped_error == NULL || escaped_server == NULL)
|
||||
{
|
||||
if(escaped_reason != NULL)
|
||||
free(escaped_reason);
|
||||
if(escaped_error != NULL)
|
||||
free(escaped_error);
|
||||
if(escaped_server != NULL)
|
||||
free(escaped_server);
|
||||
return;
|
||||
}
|
||||
|
||||
if(snprintf(html, sizeof_html, "Connection error (<strong>%s</strong>): %s (<strong>%s</strong>)", server, reason, error) > sizeof_html)
|
||||
log_warn("format_connection_error(): Buffer too small to hold HTML message, warning truncated");
|
||||
|
||||
free(escaped_reason);
|
||||
free(escaped_error);
|
||||
free(escaped_server);
|
||||
}
|
||||
|
||||
int count_messages(const bool filter_dnsmasq_warnings)
|
||||
{
|
||||
int count = 0;
|
||||
@@ -798,7 +844,7 @@ bool format_messages(cJSON *array)
|
||||
|
||||
// Generate messages
|
||||
char plain[1024] = { 0 }, html[2048] = { 0 };
|
||||
const int mtype = get_message_type_from_string(mtypestr);
|
||||
const enum message_type mtype = get_message_type_from_string(mtypestr);
|
||||
switch(mtype)
|
||||
{
|
||||
case REGEX_MESSAGE:
|
||||
@@ -944,6 +990,23 @@ bool format_messages(cJSON *array)
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case CONNECTION_ERROR_MESSAGE:
|
||||
{
|
||||
const char *server = (const char*)sqlite3_column_text(stmt, 3);
|
||||
const char *reason = (const char*)sqlite3_column_text(stmt, 4);
|
||||
const char *error = (const char*)sqlite3_column_text(stmt, 5);
|
||||
|
||||
format_connection_error(plain, sizeof(plain), html, sizeof(html),
|
||||
server, reason, error);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case MAX_MESSAGE: // Fall through
|
||||
default:
|
||||
log_warn("format_messages() - Unknown message type: %s", mtypestr);
|
||||
break;
|
||||
}
|
||||
|
||||
// Add the plain message
|
||||
@@ -1183,3 +1246,19 @@ void log_certificate_domain_mismatch(const char *certfile, const char *domain)
|
||||
if(rowid == -1)
|
||||
log_err("log_certificate_domain_mismatch(): Failed to add message to database");
|
||||
}
|
||||
|
||||
void log_connection_error(const char *server, const char *reason, const char *error)
|
||||
{
|
||||
// Create message
|
||||
char buf[2048];
|
||||
format_connection_error(buf, sizeof(buf), NULL, 0, server, reason, error);
|
||||
|
||||
// Log to FTL.log
|
||||
log_warn("%s", buf);
|
||||
|
||||
// Log to database
|
||||
const int rowid = add_message(CONNECTION_ERROR_MESSAGE, server, 2, reason, error);
|
||||
|
||||
if(rowid == -1)
|
||||
log_err("logg_connection_error(): Failed to add message to database");
|
||||
}
|
||||
|
||||
@@ -29,5 +29,6 @@ void logg_warn_dnsmasq_message(char *message);
|
||||
void log_resource_shortage(const double load, const int nprocs, const int shmem, const int disk, const char *path, const char *msg);
|
||||
void logg_inaccessible_adlist(const int dbindex, const char *address);
|
||||
void log_certificate_domain_mismatch(const char *certfile, const char *domain);
|
||||
void log_connection_error(const char *server, const char *reason, const char *error);
|
||||
|
||||
#endif //MESSAGETABLE_H
|
||||
|
||||
+31
-12
@@ -3514,20 +3514,39 @@ void FTL_connection_error(const char *reason, const union mysockaddr *addr)
|
||||
// Make a private copy of the error
|
||||
const char *error = strerror(errno);
|
||||
|
||||
if(config.debug.queries.v.b)
|
||||
{
|
||||
const int id = daemon->log_display_id;
|
||||
// Format the address into a string (if available)
|
||||
in_port_t port = 0;
|
||||
char ip[ADDRSTRLEN + 1] = { 0 };
|
||||
if(addr != NULL)
|
||||
mysockaddr_extract_ip_port(addr, ip, &port);
|
||||
|
||||
// Format the address into a string (if available)
|
||||
in_port_t port = 0;
|
||||
char ip[ADDRSTRLEN] = { 0 };
|
||||
if(addr != NULL)
|
||||
mysockaddr_extract_ip_port(addr, ip, &port);
|
||||
|
||||
// Log to FTL.log
|
||||
log_debug(DEBUG_QUERIES, "Connection error: %s (%s) for %s#%u (ID %d)", reason, error, ip, port, id);
|
||||
}
|
||||
// Log to FTL.log
|
||||
const int id = daemon->log_display_id;
|
||||
log_debug(DEBUG_QUERIES, "Connection error (%s#%u, ID %d): %s (%s)", ip, port, id, reason, error);
|
||||
|
||||
// Log to pihole.log
|
||||
my_syslog(LOG_ERR, "%s: %s", reason, error);
|
||||
|
||||
// Add to Pi-hole diagnostics but do not add messages more often than
|
||||
// once every five seconds to avoid hammering the database with errors
|
||||
// on continuously failing connections
|
||||
static time_t last = 0;
|
||||
if(time(NULL) - last > 5)
|
||||
{
|
||||
last = time(NULL);
|
||||
char *server = NULL;
|
||||
if(ip[0] != '\0')
|
||||
{
|
||||
const size_t len = strlen(ip) + 6;
|
||||
server = calloc(len, sizeof(char));
|
||||
if(server != NULL)
|
||||
{
|
||||
snprintf(server, len, "%s#%u", ip, port);
|
||||
server[len - 1] = '\0';
|
||||
}
|
||||
}
|
||||
log_connection_error(server, reason, error);
|
||||
if(server != NULL)
|
||||
free(server);
|
||||
}
|
||||
}
|
||||
@@ -273,6 +273,7 @@ enum message_type {
|
||||
INACCESSIBLE_ADLIST_MESSAGE,
|
||||
DISK_MESSAGE_EXTENDED,
|
||||
CERTIFICATE_DOMAIN_MISMATCH_MESSAGE,
|
||||
CONNECTION_ERROR_MESSAGE,
|
||||
MAX_MESSAGE,
|
||||
} __attribute__ ((packed));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user