Heck yeah 😄

This commit is contained in:
Nikolaj
2021-11-12 12:58:32 +01:00
parent c367c20cdf
commit bec557f51c
5 changed files with 132 additions and 100 deletions

View File

@ -1,5 +1,5 @@
#GCC=gcc -O3 -g -Wall -Wextra -pedantic -std=gnu11
GCC=gcc -O3
GCC=gcc -O3 -g -Wall -Wextra -pedantic -std=gnu11
#GCC=gcc -O3
LD_FLAGS= -lpthread
all: cascade

Binary file not shown.

View File

@ -40,7 +40,7 @@ void free_resources()
* a normal size for the hash would be given by the global variable
* 'SHA256_HASH_SIZE', that has been defined in sha256.h
*/
unsigned char* get_file_sha(const char* sourcefile, uint8_t hash[32], int size)
void get_file_sha(const char* sourcefile, uint8_t hash[32], int size)
{
int casc_file_size;
@ -48,7 +48,7 @@ unsigned char* get_file_sha(const char* sourcefile, uint8_t hash[32], int size)
if (fp == 0)
{
printf("Failed to open source: %s\n", sourcefile);
return NULL;
return;
}
fseek(fp, 0L, SEEK_END);
@ -62,19 +62,86 @@ unsigned char* get_file_sha(const char* sourcefile, uint8_t hash[32], int size)
get_data_sha(buffer, hash, casc_file_size, size);
}
csc_file_t* check_blocks(const char* destination, csc_file_t* casc_file_data) {
casc_file_data->completed = 1;
FILE* fp = fopen(destination, "a+w");
if (fp == NULL)
{
printf("Failed to open destination file %s\n", destination);
csc_free_file(casc_file_data);
return NULL;
}
void* buffer = malloc(casc_file_data->blocksize);
if (buffer == NULL)
{
printf("No block buffer asigned: %ld\n", casc_file_data->blocksize);
csc_free_file(casc_file_data);
fclose(fp);
return NULL;
}
SHA256_CTX shactx;
for(unsigned long long i = 0; i < casc_file_data->blockcount; i++)
{
uint8_t* shabuffer = malloc(sizeof(uint8_t) * SHA256_HASH_SIZE);
unsigned long long size = casc_file_data->blocks[i].length;
if (fread(buffer, size, 1, fp) != 1)
{
break;
}
sha256_init(&shactx);
sha256_update(&shactx, buffer, size);
sha256_final(&shactx, shabuffer);
if (memcmp((&(&casc_file_data->blocks[i])->hash)->x, shabuffer, 32) == 0) {
(&casc_file_data->blocks[i])->completed = 1;
} else {
(&casc_file_data->blocks[i])->completed = 0;
casc_file_data->completed = 0;
}
}
if (casc_file_data->completed) {
rewind(fp);
buffer = malloc(casc_file_data->targetsize);
uint8_t* shabuffer = malloc(sizeof(uint8_t) * SHA256_HASH_SIZE);
fread(buffer, casc_file_data->targetsize, 1, fp);
sha256_init(&shactx);
sha256_update(&shactx, buffer, casc_file_data->targetsize);
sha256_final(&shactx, shabuffer);
if (!(memcmp((&casc_file_data->targethash)->x, shabuffer, 32) == 0)) {
casc_file_data->completed = 0;
for (unsigned long long i = 0;i < casc_file_data->blockcount;i++) {
(&casc_file_data->blocks[i])->completed = 0;
}
}
}
fclose(fp);
return casc_file_data;
}
/*
* Gets a sha256 hash of specified data, sourcedata. The hash itself is
* placed into the given variable 'hash'. Any size can be created, but a
* a normal size for the hash would be given by the global variable
* 'SHA256_HASH_SIZE', that has been defined in sha256.h
*/
void get_data_sha(const char* sourcedata, char* hash, uint32_t data_size, int hash_size)
void get_data_sha(const char* sourcedata, unsigned char* hash, uint32_t data_size, int hash_size)
{
SHA256_CTX shactx;
unsigned char shabuffer[hash_size];
uint8_t* shabuffer = malloc(sizeof(uint8_t) * hash_size);
sha256_init(&shactx);
sha256_update(&shactx, sourcedata, data_size);
sha256_final(&shactx, &shabuffer);
sha256_final(&shactx, shabuffer);
for (int i=0; i<hash_size; i++)
{
@ -117,40 +184,43 @@ void download_only_peer(char *cascade_file)
uint8_t hash_buf[32];
get_file_sha(cascade_file, hash_buf, 32);
int peercount = 0;
while (peercount == 0)
{
peercount = get_peers_list(&peers, hash_buf);
if (peercount == 0)
while (!casc_file->completed) {
int peercount = 0;
while (peercount == 0)
{
printf("No peers were found. Will try again in %d seconds\n", PEER_REQUEST_DELAY);
fflush(stdout);
sleep(PEER_REQUEST_DELAY);
peercount = get_peers_list(&peers, hash_buf);
if (peercount == 0)
{
printf("No peers were found. Will try again in %d seconds\n", PEER_REQUEST_DELAY);
fflush(stdout);
sleep(PEER_REQUEST_DELAY);
}
else
{
printf("Found %d peer(s)\n", peercount);
}
}
else
csc_peer_t peer = (peers[0]);
// Get a good peer if one is available
for (int i=0; i<peercount; i++)
{
printf("Found %d peer(s)\n", peercount);
if (peers[i].good)
{
peer = (peers[i]);
}
}
for (int i=0; i<uncomp_count; i++)
{
get_block(queue[i], peer, hash_buf, output_file);
}
printf("\n");
casc_file = check_blocks(output_file,casc_file);
}
csc_peer_t peer = (peers[0]);
// Get a good peer if one is available
for (int i=0; i<peercount; i++)
{
if (peers[i].good)
{
peer = (peers[i]);
}
}
for (int i=0; i<uncomp_count; i++)
{
get_block(queue[i], peer, hash_buf, output_file);
}
// TODO test if everything is all right
printf("\n");
printf("File fully downloaded\n");
free_resources();
}
@ -159,7 +229,7 @@ void download_only_peer(char *cascade_file)
*/
int count_occurences(char string[], char c)
{
int i=0;
size_t i=0;
int count=0;
for(i=0; i<strlen(string); i++)
{
@ -205,7 +275,6 @@ uint8_t* hex_to_bytes(const char* string) {
}
data[(index/2)] += value << (((index + 1) % 2) * 4);
index++;
}
@ -251,12 +320,15 @@ csc_file_t* csc_parse_file(const char* sourcefile, const char* destination)
x[i] = (uint8_t)(*((unsigned long long*)&header[32+i]));
}
csc_hashdata_t* hash = {x};
csc_hashdata_t* hash = malloc(sizeof(csc_hashdata_t));
memcpy(hash->x,x,SHA256_HASH_SIZE);
casc_file_data->targethash = *hash;
casc_file_data->blockcount = 1 + floor(
(casc_file_data->targetsize - 1.0)/casc_file_data->blocksize
);
casc_file_data->trailblocksize = casc_file_data->targetsize - ((casc_file_data->blockcount - 1) * casc_file_data->blocksize);
casc_file_data->completed = 0;
csc_block_t* block_list = malloc(
sizeof(csc_block_t) * casc_file_data->blockcount
@ -282,52 +354,14 @@ csc_file_t* csc_parse_file(const char* sourcefile, const char* destination)
fclose(fp);
return NULL;
}
csc_hashdata_t* hash = {block_x};
csc_hashdata_t* hash = malloc(sizeof(csc_hashdata_t));
memcpy(hash->x,block_x,SHA256_HASH_SIZE);
block->hash = *hash;
}
fclose(fp);
fp = fopen(destination, "a+w");
if (fp == NULL)
{
printf("Failed to open destination file %s\n", destination);
csc_free_file(casc_file_data);
return NULL;
}
void* buffer = malloc(casc_file_data->blocksize);
if (buffer == NULL)
{
printf("No block buffer asigned: %d\n", casc_file_data->blocksize);
csc_free_file(casc_file_data);
fclose(fp);
return NULL;
}
SHA256_CTX shactx;
for(unsigned long long i = 0; i < casc_file_data->blockcount; i++)
{
uint8_t shabuffer[SHA256_HASH_SIZE];
unsigned long long size = casc_file_data->blocks[i].length;
if (fread(buffer, size, 1, fp) != 1)
{
break;
}
sha256_init(&shactx);
sha256_update(&shactx, buffer, size);
sha256_final(&shactx, &shabuffer);
if (memcmp((&(&casc_file_data->blocks[i])->hash)->x, shabuffer, 32) == 0) {
(&casc_file_data->blocks[i])->completed = 1;
} else {
(&casc_file_data->blocks[i])->completed = 0;
}
}
fclose(fp);
return casc_file_data;
return check_blocks(destination, casc_file_data);
}
/*
@ -340,12 +374,12 @@ void csc_free_file(csc_file_t* file)
free(file);
}
size_t readbytes(int sock, void* buffer, size_t count)
size_t readbytes(int sock, uint8_t* buffer, size_t count)
{
size_t remaining = count;
while(remaining > 0)
{
size_t read = recv(sock, buffer, remaining, NULL);
size_t read = recv(sock, buffer, remaining, 0);
if (read == 0)
return 0;
buffer += read;
@ -361,7 +395,7 @@ size_t readbytes(int sock, void* buffer, size_t count)
*/
void get_block(csc_block_t* block, csc_peer_t peer, unsigned char* hash, char* output_file)
{
printf("Attempting to get block %d from %s:%s for %s\n", block->index, peer.ip, peer.port, output_file);
printf("Attempting to get block %ld from %s:%s for %s\n", block->index, peer.ip, peer.port, output_file);
int buffer_size;
if (block->length + PEER_RESPONSE_HEADER_SIZE > MAX_LINE) {
@ -396,7 +430,7 @@ void get_block(csc_block_t* block, csc_peer_t peer, unsigned char* hash, char* o
if (msglen == 0)
{
Close(peer_socket);
return 0;
return;
}
if (reply_header[0] != 0)
@ -406,27 +440,27 @@ void get_block(csc_block_t* block, csc_peer_t peer, unsigned char* hash, char* o
{
printf("Tracker error %d and out-of-memory reading error\n", reply_header[0]);
Close(peer_socket);
return NULL;
return;
}
memset(error_buf, 0, msglen + 1);
memcpy(error_buf, &rio_buf[PEER_RESPONSE_HEADER_SIZE], msglen);
printf("Peer gave error: %d - %s\n", reply_header[0], error_buf);
free(error_buf);
Close(peer_socket);
return NULL;
return;
}
uint8_t shabuffer[SHA256_HASH_SIZE];
uint8_t* shabuffer = malloc(sizeof(uint8_t) * SHA256_HASH_SIZE);
SHA256_CTX shactx;
sha256_init(&shactx);
sha256_update(&shactx, &rio_buf[PEER_RESPONSE_HEADER_SIZE], msglen);
sha256_final(&shactx, &shabuffer);
sha256_final(&shactx, shabuffer);
if (memcmp(shabuffer, (&block->hash)->x, SHA256_HASH_SIZE) != 0) {
printf("Not the same hash\n");
Close(peer_socket);
return NULL;
return;
}
FILE* fp = fopen(output_file, "rb+");
@ -438,9 +472,9 @@ void get_block(csc_block_t* block, csc_peer_t peer, unsigned char* hash, char* o
}
fseek(fp, block->offset, SEEK_SET);
fputs(&rio_buf[0,PEER_RESPONSE_HEADER_SIZE],fp);
fwrite(&rio_buf[PEER_RESPONSE_HEADER_SIZE],msglen,1,fp);
printf("Got block %d. Wrote from %d to %d\n", block->index, block->offset, block->offset+msglen-1);
printf("Got block %ld. Wrote from %ld to %ld\n", block->index, block->offset, block->offset+msglen-1);
Close(peer_socket);
fclose(fp);
}
@ -461,7 +495,7 @@ int get_peers_list(csc_peer_t** peers, uint8_t hash[32])
Rio_readinitb(&rio, tracker_socket);
struct RequestHeader request_header;
strncpy(request_header.protocol, "CASC", 4);
memcpy(request_header.protocol, "CASC", 4);
request_header.version = htonl(1);
request_header.command = htonl(1);
request_header.length = htonl(BODY_SIZE);
@ -495,21 +529,21 @@ int get_peers_list(csc_peer_t** peers, uint8_t hash[32])
{
printf("Tracker error %d and out-of-memory reading error\n", reply_header[0]);
Close(tracker_socket);
return NULL;
return 0;
}
memset(error_buf, 0, msglen + 1);
memcpy(error_buf, &rio_buf[REPLY_HEADER_SIZE], msglen); // Fixed by Rune
printf("Tracker gave error: %d - %s\n", reply_header[0], error_buf);
free(error_buf);
Close(tracker_socket);
return NULL;
return 0;
}
if (msglen % 12 != 0)
{
printf("LIST response from tracker was length %llu but should be evenly divisible by 12\n", msglen);
printf("LIST response from tracker was length %u but should be evenly divisible by 12\n", msglen);
Close(tracker_socket);
return NULL;
return 0;
}
int peercount = msglen/12;
*peers = malloc(peercount * sizeof(csc_peer_t));
@ -517,7 +551,6 @@ int get_peers_list(csc_peer_t** peers, uint8_t hash[32])
for (int i = 0;i<peercount;i++) {
csc_peer_t peer;
uint8_t* peer_data = &rio_buf[REPLY_HEADER_SIZE + 12*i];
struct in_addr ip = {};
sprintf(peer.ip, "%u.%u.%u.%u", peer_data[0], peer_data[1], peer_data[2], peer_data[3]);
sprintf(peer.port, "%u", be16toh(*((uint16_t*)&peer_data[4])));

View File

@ -67,6 +67,7 @@ typedef struct csc_file {
uint64_t trailblocksize; // Size of last block. Will differ from standard block size if data does not evenly divide amoungst blocks
uint64_t blockcount; // Number of blocks data is divided into
csc_block_t* blocks; // Pointer to array of all blocks
uint8_t completed;
} csc_file_t;
typedef struct csc_peer {
@ -76,9 +77,6 @@ typedef struct csc_peer {
uint8_t good; // Flag for if this is 'Good' peer. e.g. Always provides valid responses according to protocol
} csc_peer_t;
typedef struct csc_server {
} csc_server_t;
/*
* Parses a hex-string and returns the bytes corresponding to the value
*/
@ -114,4 +112,6 @@ int csc_download_block(csc_ipport_t client, csc_hashdata_t cascadehash, uint64_t
int get_peers_list(csc_peer_t** peers, uint8_t hash[32]);
void get_block(csc_block_t* block, csc_peer_t peer, unsigned char* hash, char* output_file);
void get_data_sha(const char* sourcedata, unsigned char* hash, uint32_t data_size, int hash_size);
#endif

View File

@ -124454,4 +124454,3 @@ End of this Etext of The Complete Works of William Shakespeare
Yネ3<EFBFBD>