Merge feat/p3-checksum-choice: --checksum-choice/--cc and --checksum-seed

This commit is contained in:
2026-09-07 19:53:28 +02:00
20 changed files with 813 additions and 50 deletions
+64 -2
View File
@@ -809,11 +809,11 @@ static void test_config_is_remote_dest() {
are negotiated to the receiver so it knows to reply STATUS_APPEND on a
shorter destination. */
static void test_config_append_wire_roundtrip() {
if (is_running_under_valgrind())
return;
struct {
bool append, append_verify;
} cases[] = {{true, false}, {false, true}, {true, true}, {false, false}};
if (is_running_under_valgrind())
return;
for (size_t i = 0; i < sizeof(cases) / sizeof(cases[0]); i++) {
int p[2];
EXPECT_EQ_INT(socketpair(AF_UNIX, SOCK_STREAM, 0, p), 0);
@@ -848,6 +848,66 @@ static void test_config_append_wire_roundtrip() {
}
}
/* --checksum-choice/--cc and --checksum-seed cross the wire intact so the
receiver hashes the on-disk old file with the same algorithm and seed. */
static void test_config_checksum_options_wire_roundtrip() {
struct {
int algo;
unsigned long long seed;
} cases[] = {
{CHECKSUM_ALGO_XXH64, 0},
{CHECKSUM_ALGO_XXH64, 42},
{CHECKSUM_ALGO_MD5, 7},
{CHECKSUM_ALGO_MD5, 0},
};
if (is_running_under_valgrind())
return;
for (size_t i = 0; i < sizeof(cases) / sizeof(cases[0]); i++) {
int p[2];
EXPECT_EQ_INT(socketpair(AF_UNIX, SOCK_STREAM, 0, p), 0);
pid_t pid = fork();
if (pid == 0) {
close(p[1]);
io_set_fds(p[0], p[0]);
Config* recv = config_receive(p[0]);
bool ok = recv != NULL && recv->checksum_algo == cases[i].algo &&
recv->checksum_seed == cases[i].seed;
config_delete(recv);
close(p[0]);
_exit(ok ? 0 : 1);
} else {
close(p[0]);
io_set_fds(p[1], p[1]);
Config* send_cfg = config_create();
EXPECT_NOT_NULL(send_cfg);
send_cfg->send_directory = str_dup("/src");
send_cfg->receive_root_directory = str_dup("/dst");
send_cfg->checksum_algo = cases[i].algo;
send_cfg->checksum_seed = cases[i].seed;
bool sent = config_send(p[1], send_cfg);
int status;
waitpid(pid, &status, 0);
close(p[1]);
config_delete(send_cfg);
EXPECT_TRUE(sent);
EXPECT_TRUE(WIFEXITED(status) && WEXITSTATUS(status) == 0);
}
}
}
/* An out-of-range algorithm id on the wire must be rejected on receive, never
accepted as-is (prevents mixing unsupported digests on a path). */
static void test_config_receive_rejects_invalid_checksum_algo() {
if (is_running_under_valgrind())
return;
Config* c = config_create();
EXPECT_NOT_NULL(c);
c->send_directory = str_dup("/src");
c->receive_root_directory = str_dup("/dst");
c->checksum_algo = 99;
EXPECT_FALSE(roundtrip_config_ok(c));
config_delete(c);
}
void test_config() {
test_config_lifecycle();
test_config_ssh_dest();
@@ -870,6 +930,8 @@ void test_config() {
test_config_basis_roundtrip();
test_config_basis_wire_rejects_escaping();
test_config_basis_normalization();
test_config_checksum_options_wire_roundtrip();
test_config_receive_rejects_invalid_checksum_algo();
}
test_config_delete_timing_early_helper();
test_config_is_remote_dest();