version 1.14, 2019/03/23 16:04:28 |
version 1.15, 2019/05/08 20:00:25 |
|
|
hash_slow(buf + offs, (size_t)osz, md, sess); |
hash_slow(buf + offs, (size_t)osz, md, sess); |
have_md = 1; |
have_md = 1; |
if (memcmp(md, blks->blks[hint].chksum_long, blks->csum) == 0) { |
if (memcmp(md, blks->blks[hint].chksum_long, blks->csum) == 0) { |
LOG4(sess, "%s: found matching hinted match: " |
LOG4("%s: found matching hinted match: " |
"position %jd, block %zu (position %jd, size %zu)", |
"position %jd, block %zu (position %jd, size %zu)", |
path, |
path, |
(intmax_t)offs, blks->blks[hint].idx, |
(intmax_t)offs, blks->blks[hint].idx, |
|
|
if ((size_t)osz != blks->blks[i].len) |
if ((size_t)osz != blks->blks[i].len) |
continue; |
continue; |
|
|
LOG4(sess, "%s: found matching fast match: " |
LOG4("%s: found matching fast match: " |
"position %jd, block %zu (position %jd, size %zu)", |
"position %jd, block %zu (position %jd, size %zu)", |
path, |
path, |
(intmax_t)offs, blks->blks[i].idx, |
(intmax_t)offs, blks->blks[i].idx, |
|
|
if (memcmp(md, blks->blks[i].chksum_long, blks->csum)) |
if (memcmp(md, blks->blks[i].chksum_long, blks->csum)) |
continue; |
continue; |
|
|
LOG4(sess, "%s: sender verifies slow match", path); |
LOG4("%s: sender verifies slow match", path); |
return &blks->blks[i]; |
return &blks->blks[i]; |
} |
} |
|
|
|
|
sz = st->offs - last; |
sz = st->offs - last; |
st->dirty += sz; |
st->dirty += sz; |
st->total += sz; |
st->total += sz; |
LOG4(sess, |
LOG4("%s: flushing %jd B before %zu B block %zu", |
"%s: flushing %jd B before %zu B block %zu", |
|
path, (intmax_t)sz, |
path, (intmax_t)sz, |
blk->len, blk->idx); |
blk->len, blk->idx); |
tok = -(blk->idx + 1); |
tok = -(blk->idx + 1); |
|
|
/* Emit remaining data and send terminator token. */ |
/* Emit remaining data and send terminator token. */ |
|
|
sz = st->mapsz - last; |
sz = st->mapsz - last; |
LOG4(sess, "%s: flushing remaining %jd B", |
LOG4("%s: flushing remaining %jd B", |
path, (intmax_t)sz); |
path, (intmax_t)sz); |
|
|
st->total += sz; |
st->total += sz; |
|
|
st->curst = st->mapsz ? BLKSTAT_DATA : BLKSTAT_TOK; |
st->curst = st->mapsz ? BLKSTAT_DATA : BLKSTAT_TOK; |
st->dirty = st->total = st->mapsz; |
st->dirty = st->total = st->mapsz; |
|
|
LOG4(sess, "%s: flushing whole file %zu B", |
LOG4("%s: flushing whole file %zu B", |
path, st->mapsz); |
path, st->mapsz); |
} |
} |
} |
} |
|
|
off_t offs = 0; |
off_t offs = 0; |
|
|
if ((s = calloc(1, sizeof(struct blkset))) == NULL) { |
if ((s = calloc(1, sizeof(struct blkset))) == NULL) { |
ERR(sess, "calloc"); |
ERR("calloc"); |
return NULL; |
return NULL; |
} |
} |
|
|
|
|
*/ |
*/ |
|
|
if (!io_read_size(sess, fd, &s->blksz)) { |
if (!io_read_size(sess, fd, &s->blksz)) { |
ERRX1(sess, "io_read_size"); |
ERRX1("io_read_size"); |
goto out; |
goto out; |
} else if (!io_read_size(sess, fd, &s->len)) { |
} else if (!io_read_size(sess, fd, &s->len)) { |
ERRX1(sess, "io_read_size"); |
ERRX1("io_read_size"); |
goto out; |
goto out; |
} else if (!io_read_size(sess, fd, &s->csum)) { |
} else if (!io_read_size(sess, fd, &s->csum)) { |
ERRX1(sess, "io_read_int"); |
ERRX1("io_read_int"); |
goto out; |
goto out; |
} else if (!io_read_size(sess, fd, &s->rem)) { |
} else if (!io_read_size(sess, fd, &s->rem)) { |
ERRX1(sess, "io_read_int"); |
ERRX1("io_read_int"); |
goto out; |
goto out; |
} else if (s->rem && s->rem >= s->len) { |
} else if (s->rem && s->rem >= s->len) { |
ERRX(sess, "block remainder is " |
ERRX("block remainder is " |
"greater than block size"); |
"greater than block size"); |
goto out; |
goto out; |
} |
} |
|
|
LOG3(sess, "%s: read block prologue: %zu blocks of " |
LOG3("%s: read block prologue: %zu blocks of " |
"%zu B, %zu B remainder, %zu B checksum", path, |
"%zu B, %zu B remainder, %zu B checksum", path, |
s->blksz, s->len, s->rem, s->csum); |
s->blksz, s->len, s->rem, s->csum); |
|
|
if (s->blksz) { |
if (s->blksz) { |
s->blks = calloc(s->blksz, sizeof(struct blk)); |
s->blks = calloc(s->blksz, sizeof(struct blk)); |
if (s->blks == NULL) { |
if (s->blks == NULL) { |
ERR(sess, "calloc"); |
ERR("calloc"); |
goto out; |
goto out; |
} |
} |
} |
} |
|
|
for (j = 0; j < s->blksz; j++) { |
for (j = 0; j < s->blksz; j++) { |
b = &s->blks[j]; |
b = &s->blks[j]; |
if (!io_read_int(sess, fd, &i)) { |
if (!io_read_int(sess, fd, &i)) { |
ERRX1(sess, "io_read_int"); |
ERRX1("io_read_int"); |
goto out; |
goto out; |
} |
} |
b->chksum_short = i; |
b->chksum_short = i; |
|
|
assert(s->csum <= sizeof(b->chksum_long)); |
assert(s->csum <= sizeof(b->chksum_long)); |
if (!io_read_buf(sess, |
if (!io_read_buf(sess, |
fd, b->chksum_long, s->csum)) { |
fd, b->chksum_long, s->csum)) { |
ERRX1(sess, "io_read_buf"); |
ERRX1("io_read_buf"); |
goto out; |
goto out; |
} |
} |
|
|
|
|
s->rem : s->len; |
s->rem : s->len; |
offs += b->len; |
offs += b->len; |
|
|
LOG4(sess, "%s: read block %zu, length %zu B", |
LOG4("%s: read block %zu, length %zu B", |
path, b->idx, b->len); |
path, b->idx, b->len); |
} |
} |
|
|
s->size = offs; |
s->size = offs; |
LOG3(sess, "%s: read blocks: %zu blocks, %jd B total blocked data", |
LOG3("%s: read blocks: %zu blocks, %jd B total blocked data", |
path, s->blksz, (intmax_t)s->size); |
path, s->blksz, (intmax_t)s->size); |
return s; |
return s; |
out: |
out: |
|
|
assert(sz <= sizeof(buf)); |
assert(sz <= sizeof(buf)); |
|
|
if (!io_read_buf(sess, fd, buf, sz)) { |
if (!io_read_buf(sess, fd, buf, sz)) { |
ERRX1(sess, "io_read_buf"); |
ERRX1("io_read_buf"); |
return 0; |
return 0; |
} |
} |
|
|
if (!io_unbuffer_size(sess, buf, &pos, sz, &p->blksz)) |
if (!io_unbuffer_size(sess, buf, &pos, sz, &p->blksz)) |
ERRX1(sess, "io_unbuffer_size"); |
ERRX1("io_unbuffer_size"); |
else if (!io_unbuffer_size(sess, buf, &pos, sz, &p->len)) |
else if (!io_unbuffer_size(sess, buf, &pos, sz, &p->len)) |
ERRX1(sess, "io_unbuffer_size"); |
ERRX1("io_unbuffer_size"); |
else if (!io_unbuffer_size(sess, buf, &pos, sz, &p->csum)) |
else if (!io_unbuffer_size(sess, buf, &pos, sz, &p->csum)) |
ERRX1(sess, "io_unbuffer_size"); |
ERRX1("io_unbuffer_size"); |
else if (!io_unbuffer_size(sess, buf, &pos, sz, &p->rem)) |
else if (!io_unbuffer_size(sess, buf, &pos, sz, &p->rem)) |
ERRX1(sess, "io_unbuffer_size"); |
ERRX1("io_unbuffer_size"); |
else if (p->len && p->rem >= p->len) |
else if (p->len && p->rem >= p->len) |
ERRX1(sess, "non-zero length is less than remainder"); |
ERRX1("non-zero length is less than remainder"); |
else if (p->csum == 0 || p->csum > 16) |
else if (p->csum == 0 || p->csum > 16) |
ERRX1(sess, "inappropriate checksum length"); |
ERRX1("inappropriate checksum length"); |
else |
else |
return 1; |
return 1; |
|
|
|
|
p->csum); /* long checksum */ |
p->csum); /* long checksum */ |
|
|
if ((buf = malloc(sz)) == NULL) { |
if ((buf = malloc(sz)) == NULL) { |
ERR(sess, "malloc"); |
ERR("malloc"); |
return 0; |
return 0; |
} |
} |
|
|
|
|
assert(pos == sz); |
assert(pos == sz); |
|
|
if (!io_write_buf(sess, fd, buf, sz)) { |
if (!io_write_buf(sess, fd, buf, sz)) { |
ERRX1(sess, "io_write_buf"); |
ERRX1("io_write_buf"); |
goto out; |
goto out; |
} |
} |
|
|
LOG3(sess, "%s: sent block prologue: %zu blocks of %zu B, " |
LOG3("%s: sent block prologue: %zu blocks of %zu B, " |
"%zu B remainder, %zu B checksum", |
"%zu B remainder, %zu B checksum", |
path, p->blksz, p->len, p->rem, p->csum); |
path, p->blksz, p->len, p->rem, p->csum); |
rc = 1; |
rc = 1; |