Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new GRAVITY_RESTORED_MESSAGE message type #2122

Open
wants to merge 2 commits into
base: development
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions src/database/gravity-db.c
Original file line number Diff line number Diff line change
Expand Up @@ -2720,6 +2720,49 @@ void check_inaccessible_adlists(void)
sqlite3_finalize(query_stmt);
}

/**
* @brief Check if gravity was restored from a local backup.
*
* This function checks the "gravity_restored" property in the "info" table of the gravity database.
* If the property value is "false", it means gravity was not restored and the function returns.
* Any other value indicates that gravity was restored, and a log entry is created.
*
* @note If the gravity database is not available or an SQL error occurs during query preparation,
* an error message is logged and the function returns.
*/
void check_restored_gravity(void)
{
// Do not proceed when database is not available
if(!gravityDB_opened && !gravityDB_open())
{
log_err("check_restored_gravity(): Gravity database not available");
return;
}

const char *querystr = "SELECT value FROM info WHERE property = 'gravity_restored'";
sqlite3_stmt *query_stmt = NULL;
int rc = sqlite3_prepare_v2(gravity_db, querystr, -1, &query_stmt, NULL);
if(rc != SQLITE_OK){
log_err("check_restored_gravity(): %s - SQL error prepare: %s", querystr, sqlite3_errstr(rc));
gravityDB_close();
return;
}

// Perform query
if((rc = sqlite3_step(query_stmt)) == SQLITE_ROW)
{
const char *restored = (const char*)sqlite3_column_text(query_stmt, 0);
if(strcmp(restored, "false") != 0)
{
// log to the message table
log_gravity_restored(restored);
}
}

// Finalize statement
sqlite3_finalize(query_stmt);
}

static sqlite3_int64 last_updated = -1;
bool gravity_updated(void)
{
Expand Down
1 change: 1 addition & 0 deletions src/database/gravity-db.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ char* get_client_names_from_ids(const char *group_ids) __attribute__ ((malloc));
void gravityDB_finalizeTable(void);
int gravityDB_count(const enum gravity_tables list);
void check_inaccessible_adlists(void);
void check_restored_gravity(void);
bool gravity_updated(void);

cJSON *gen_abp_patterns(const char *domain, const bool antigravity);
Expand Down
67 changes: 67 additions & 0 deletions src/database/message-table.c
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@ static const char *get_message_type_str(const enum message_type type)
return "NTP";
case VERIFY_MESSAGE:
return "VERIFY";
case GRAVITY_RESTORED_MESSAGE:
return "GRAVITY_RESTORED";
case MAX_MESSAGE:
default:
return "UNKNOWN";
Expand Down Expand Up @@ -141,6 +143,8 @@ static enum message_type get_message_type_from_string(const char *typestr)
return NTP_MESSAGE;
else if (strcmp(typestr, "VERIFY") == 0)
return VERIFY_MESSAGE;
else if (strcmp(typestr, "GRAVITY_RESTORED") == 0)
return GRAVITY_RESTORED_MESSAGE;
else
return MAX_MESSAGE;
}
Expand Down Expand Up @@ -256,6 +260,14 @@ static unsigned char message_blob_types[MAX_MESSAGE][5] =
SQLITE_TEXT, // FTL commit hash
SQLITE_TEXT, // FTL architecture
SQLITE_NULL // not used
},
{
// GRAVITY_RESTORED_MESSAGE: The message column contains the status
SQLITE_NULL, // not used
SQLITE_NULL, // not used
SQLITE_NULL, // not used
SQLITE_NULL, // not used
SQLITE_NULL // not used
}
};
// Create message table in the database
Expand Down Expand Up @@ -975,6 +987,37 @@ static void format_verify_message(char *plain, const int sizeof_plain, char *htm
free(escaped_arch);
}

static void format_gravity_restored_message(char *plain, const int sizeof_plain, char *html, const int sizeof_html,
const char *status)
{
const bool failed = strcmp(status, "failed") == 0;

if(snprintf(plain, sizeof_plain, "Gravity database restore %s", failed ? "failed" : "successful") > sizeof_plain)
log_warn("format_gravity_restored_message(): Buffer too small to hold plain message, warning truncated");

// Return early if HTML text is not required
if(sizeof_html < 1 || html == NULL)
return;

if(failed)
{
if(snprintf(html, sizeof_html, "Gravity database damaged, restore attempt <strong>failed</strong><br><br>Please check your filesystem for corruption, and your disk space for availability.") > sizeof_html)
DL6ER marked this conversation as resolved.
Show resolved Hide resolved
log_warn("format_gravity_restored_message(): Buffer too small to hold HTML message, warning truncated");
}
else
{
char *escaped_status = escape_html(status);

// Return early if memory allocation failed
if(escaped_status == NULL)
return;

if(snprintf(html, sizeof_html, "Gravity database damaged, restore attempt <strong>successful</strong><br>The gravity database was restored using the backup file <code>%s</code><br><br>Please check your filesystem for corruption, and your disk space for availability.", escaped_status) > sizeof_html)
DL6ER marked this conversation as resolved.
Show resolved Hide resolved

free(escaped_status);
}
}

int count_messages(const bool filter_dnsmasq_warnings)
{
int count = 0;
Expand Down Expand Up @@ -1248,6 +1291,16 @@ bool format_messages(cJSON *array)
break;
}

case GRAVITY_RESTORED_MESSAGE:
{
const char *status = (const char*)sqlite3_column_text(stmt, 3);

format_gravity_restored_message(plain, sizeof(plain), html, sizeof(html),
status);

break;
}

case MAX_MESSAGE: // Fall through
default:
log_warn("format_messages() - Unknown message type: %s", mtypestr);
Expand Down Expand Up @@ -1533,3 +1586,17 @@ void log_verify_message(const char *expected, const char *actual)
add_message(VERIFY_MESSAGE, buf, expected, actual, GIT_HASH, FTL_ARCH);

}

void log_gravity_restored(const char *status)
{
// Create message
char buf[2048];
format_gravity_restored_message(buf, sizeof(buf), NULL, 0, status);

// Log to FTL.log
log_warn("%s", buf);

// Log to database
add_message_no_args(GRAVITY_RESTORED_MESSAGE, status);

}
1 change: 1 addition & 0 deletions src/database/message-table.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,6 @@ void log_certificate_domain_mismatch(const char *certfile, const char *domain);
void log_connection_error(const char *server, const char *reason, const char *error);
void log_ntp_message(const bool error, const bool server, const char *message);
void log_verify_message(const char *expected, const char *actual);
void log_gravity_restored(const char *status);

#endif //MESSAGETABLE_H
3 changes: 3 additions & 0 deletions src/datastructure.c
Original file line number Diff line number Diff line change
Expand Up @@ -679,6 +679,9 @@ void FTL_reload_all_domainlists(void)
// Check for inaccessible adlist URLs
check_inaccessible_adlists();

// Check for restored gravity database
check_restored_gravity();

// Reset FTL's internal DNS cache storing whether a specific domain
// has already been validated for a specific user
FTL_reset_per_client_domain_data();
Expand Down
1 change: 1 addition & 0 deletions src/enums.h
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,7 @@ enum message_type {
CONNECTION_ERROR_MESSAGE,
NTP_MESSAGE,
VERIFY_MESSAGE,
GRAVITY_RESTORED_MESSAGE,
MAX_MESSAGE,
} __attribute__ ((packed));

Expand Down
Loading