sparse-tools/src/bs_comm_handshake.c

109 lines
3.1 KiB
C

//
// Created by haraldwolff on 08.08.22.
//
#include <stdlib.h>
#include <sys/socket.h>
#include <blksync.h>
#include <bs_comm.h>
#include <bs_engine.h>
int bs_comm_handshake(bs_engine_t *engine) {
if (!engine->file.handle)
{
int s = bs_engine_open_file(engine);
if (s)
fatal("could not open file %s\n", engine->file.filename);
}
bs_hello_t hello, remote;
memset(&hello, 0, sizeof(hello));
hello.magic = bs_magic;
hello.bs_flags = engine->bs_flags;
hello.filesize = engine->file.size;
hello.blocksize = engine->parameters.blocksize;
if (send(engine->comm.remote, &hello, sizeof(hello), 0) < 0)
return -1;
if (recv(engine->comm.remote, &remote, sizeof(remote), 0) < 0)
return -1;
bs_flags_t mine, yours;
mine = hello.bs_flags & (BS_RECEIVER | BS_SENDER);
yours = remote.bs_flags & (BS_RECEIVER | BS_SENDER);
if (yours == (BS_RECEIVER | BS_SENDER))
{
fprintf(stderr, "remote wants to be receiver and sender.\n");
exit(EXIT_FAILURE);
}
if (!mine && !yours)
{
mine = engine->tool_flags & BS_LISTENER ? BS_RECEIVER : BS_SENDER;
} else if (!mine)
{
mine = (~yours) & (BS_SENDER | BS_RECEIVER);
}
if (mine == yours) {
fprintf(stderr, "remote wants to be same like me, can't work.\n");
exit(EXIT_FAILURE);
}
engine->bs_flags |= mine;
if ((engine->bs_flags & BS_COMPRESSION_MASK) & ~(BS_COMPRESSION_BZ2))
{
fprintf(stderr, "unknown compression bs_flags\n");
exit(EXIT_FAILURE);
}
if ((engine->bs_flags & BS_PROTO_MASK) & ~(BS_LINEAR | BS_MERKLE))
{
fprintf(stderr, "unknown protocol bs_flags\n");
exit(EXIT_FAILURE);
}
if (!engine->parameters.blocksize)
engine->parameters.blocksize = remote.blocksize ? remote.blocksize : defaultBlocksize;
else if (remote.blocksize && (engine->parameters.blocksize != remote.blocksize))
{
fprintf(stderr, "incompatible block sizes\n");
exit(EXIT_FAILURE);
} else if (engine->parameters.blocksize > MAX_MSG_PAYLOAD_LENGTH){
fatal("requested blocksize too large. (%d > %d)", remote.blocksize, MAX_MSG_PAYLOAD_LENGTH);
}
if ((engine->bs_flags & BS_COMPRESSION_MASK) && (remote.bs_flags & BS_COMPRESSION_MASK) && ((engine->bs_flags & BS_COMPRESSION_MASK) != (remote.bs_flags & BS_COMPRESSION_MASK))){
fprintf(stderr, "incomatible compression modes\n");
exit(EXIT_FAILURE);
} else if (!(engine->bs_flags & BS_COMPRESSION_MASK)){
engine->bs_flags |= remote.bs_flags & BS_COMPRESSION_MASK;
}
if ((engine->bs_flags & BS_PROTO_MASK) && (remote.bs_flags & BS_PROTO_MASK) && ((engine->bs_flags & BS_PROTO_MASK) != (remote.bs_flags & BS_PROTO_MASK))){
fprintf(stderr, "incomatible protocol modes\n");
exit(EXIT_FAILURE);
} else if (!(engine->bs_flags & BS_PROTO_MASK)){
engine->bs_flags |= remote.bs_flags & BS_PROTO_MASK;
}
if (!(engine->bs_flags & BS_PROTO_MASK))
engine->bs_flags |= BS_LINEAR;
if ((engine->bs_flags & BS_RECEIVER) && (engine->file.size != remote.filesize)){
fprintf(stdout, "truncate needed to %ld bytes (0x%lx)\n", remote.filesize, remote.filesize);
fflush(stdout);
if (bs_engine_truncate_file(engine, remote.filesize))
fatal("could not truncate file %s ( %s )", engine->file.filename, strerror(errno));
}
return 0;
}