161 lines
4.0 KiB
C
161 lines
4.0 KiB
C
|
|
// Created by haraldwolff on 07.08.22.
|
|
//
|
|
|
|
#include <blksync.h>
|
|
#include <hash.h>
|
|
#include <time.h>
|
|
|
|
/*
|
|
|
|
int sync_merkle(bsync_engine_t *engine, merkle_t* merkle, merkle_t *remote, int d, int n);
|
|
|
|
int bs_send_merkle(bsync_engine_t *engine){
|
|
int s;
|
|
int blocks = (engine->filesize + engine->blocksize - 1) / engine->blocksize;
|
|
uint64_t hash;
|
|
merkle_t *merkle, *remote_merkle;
|
|
|
|
if (merkle_create(&remote_merkle, 2, blocks)<0)
|
|
return -ENOMEM;
|
|
|
|
s = bs_merkle_build(engine, &merkle);
|
|
if (s < 0){
|
|
fprintf(stderr, "failed to build merkle tree.\n");
|
|
}
|
|
|
|
fprintf(stdout, "synchronize merkle trees...\n");
|
|
fflush(stdout);
|
|
|
|
if (bs_recv(engine->remote, &hash, sizeof(uint64_t)) < 0)
|
|
return -EIO;
|
|
|
|
merkle_set(remote_merkle, 0, 0, hash);
|
|
fprintf(stdout, "remote top: 0x%016lx\n", hash);
|
|
fflush(stdout);
|
|
|
|
if (engine->tool_flags & BS_DEBUG){
|
|
merkle_dump( merkle );
|
|
}
|
|
|
|
if (sync_merkle(engine, merkle, remote_merkle, 0, 0)<0)
|
|
{
|
|
fprintf(stderr, "could not sync merkle trees.\n");
|
|
return -1;
|
|
}
|
|
|
|
s = -1;
|
|
if (
|
|
(bs_send(engine->remote, &s, sizeof(int)) < 0) ||
|
|
(bs_send(engine->remote, &s, sizeof(int)) < 0)
|
|
){
|
|
fprintf(stderr, "failed to send end-of-sync mark\n");
|
|
return -EIO;
|
|
}
|
|
|
|
if (engine->tool_flags & BS_DEBUG){
|
|
merkle_dump( remote_merkle );
|
|
}
|
|
|
|
uint64_t *myrow, *yourrow;
|
|
char *block = malloc(engine->blocksize);
|
|
if (!block) {
|
|
fprintf(stderr, "out of memory allocating block buffer\n");
|
|
return -ENOMEM;
|
|
}
|
|
|
|
merkle_get_row(merkle, merkle->parameters.depth, &myrow, NULL);
|
|
merkle_get_row(remote_merkle, remote_merkle->parameters.depth, &yourrow, NULL);
|
|
|
|
int count_changed = 0;
|
|
int count_sent = 0;
|
|
|
|
for (int nblock = 0; nblock < blocks; nblock++) {
|
|
if (yourrow[nblock] && (yourrow[nblock] != myrow[nblock]))
|
|
count_changed++;
|
|
}
|
|
|
|
for (int nblock = 0; nblock < blocks; nblock++){
|
|
if (yourrow[nblock] && (yourrow[nblock] != myrow[nblock])){
|
|
long offset = ((long)engine->blocksize) * nblock;
|
|
int size = (nblock == (blocks - 1)) ? engine->filesize - offset : engine->blocksize;
|
|
if (read_block(engine, offset, block, size)<0)
|
|
return -EIO;
|
|
|
|
if (engine->tool_flags & BS_VERBOSE) {
|
|
fprintf(stdout, "\tsending block 0x%016lx (%d bytes)\n", offset, size);
|
|
fflush(stdout);
|
|
}
|
|
|
|
if (
|
|
(bs_send(engine->remote, &offset, sizeof(offset)) < 0) ||
|
|
(bs_send(engine->remote, block, size) < 0)
|
|
){
|
|
fprintf(stderr, "could not send block at 0x%016lx\n", offset);
|
|
return -EIO;
|
|
}
|
|
count_sent++;
|
|
|
|
time_t now = time(NULL);
|
|
if (engine->t_last_update != now){
|
|
bs_time_t bst;
|
|
engine->t_last_update = now;
|
|
bs_time_set( &bst, (now - engine->t_start) * (count_changed-count_sent) / count_sent);
|
|
fprintf(stdout, "\r%d / %d [ %d%% ] => %02d:%02d:%02d", count_sent, count_changed, 100 * count_sent / count_changed, bst.hours, bst.minutes, bst.seconds);
|
|
fflush(stdout);
|
|
}
|
|
}
|
|
}
|
|
|
|
free(block);
|
|
|
|
hash = -1;
|
|
bs_send(engine->remote, &hash, sizeof(hash));
|
|
|
|
merkle_free(merkle);
|
|
merkle_free(remote_merkle);
|
|
return 0;
|
|
}
|
|
|
|
int sync_merkle(bsync_engine_t *engine, merkle_t* merkle, merkle_t *remote, int d, int n)
|
|
{
|
|
uint64_t mine, yours;
|
|
uint64_t *nextrow;
|
|
|
|
merkle_get(merkle, d, n, &mine);
|
|
merkle_get(remote, d, n, &yours);
|
|
|
|
if (engine->tool_flags & BS_DEBUG) {
|
|
fprintf(stdout, "%d / %d : 0x%016lx 0x%016lx\n", d, n, mine, yours);
|
|
fflush(stdout);
|
|
}
|
|
|
|
if (mine != yours){
|
|
if (
|
|
(bs_send(engine->remote, &d, sizeof(int)) < 0) ||
|
|
(bs_send(engine->remote, &n, sizeof(int)) < 0)
|
|
){
|
|
fprintf(stderr, "failed to request tree hashes for d=%d n=%d\n", d, n);
|
|
return -EIO;
|
|
}
|
|
|
|
merkle_get_row(remote, d+1, &nextrow, NULL);
|
|
if (bs_recv(engine->remote, &nextrow[n * (remote->parameters.n)], remote->parameters.n * sizeof(uint64_t)) < 0)
|
|
{
|
|
fprintf(stderr, "failed to receive tree hashes for d=%d n=%d\n", d, n);
|
|
return -EIO;
|
|
}
|
|
|
|
if (d < (remote->parameters.depth-1)) {
|
|
for (int i = 0; i < remote->parameters.n; i++) {
|
|
int s = sync_merkle(engine, merkle, remote, d+1, (n*merkle->parameters.n) + i);
|
|
if (s < 0)
|
|
return s;
|
|
}
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
*/
|