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 -g -Wall -Wextra -pedantic -std=gnu11
GCC=gcc -O3 #GCC=gcc -O3
LD_FLAGS= -lpthread LD_FLAGS= -lpthread
all: cascade 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 * a normal size for the hash would be given by the global variable
* 'SHA256_HASH_SIZE', that has been defined in sha256.h * '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; 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) if (fp == 0)
{ {
printf("Failed to open source: %s\n", sourcefile); printf("Failed to open source: %s\n", sourcefile);
return NULL; return;
} }
fseek(fp, 0L, SEEK_END); 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); 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 * 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 * 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 * a normal size for the hash would be given by the global variable
* 'SHA256_HASH_SIZE', that has been defined in sha256.h * '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; SHA256_CTX shactx;
unsigned char shabuffer[hash_size]; uint8_t* shabuffer = malloc(sizeof(uint8_t) * hash_size);
sha256_init(&shactx); sha256_init(&shactx);
sha256_update(&shactx, sourcedata, data_size); sha256_update(&shactx, sourcedata, data_size);
sha256_final(&shactx, &shabuffer); sha256_final(&shactx, shabuffer);
for (int i=0; i<hash_size; i++) for (int i=0; i<hash_size; i++)
{ {
@ -117,40 +184,43 @@ void download_only_peer(char *cascade_file)
uint8_t hash_buf[32]; uint8_t hash_buf[32];
get_file_sha(cascade_file, hash_buf, 32); get_file_sha(cascade_file, hash_buf, 32);
int peercount = 0; while (!casc_file->completed) {
while (peercount == 0) int peercount = 0;
{ while (peercount == 0)
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); peercount = get_peers_list(&peers, hash_buf);
fflush(stdout); if (peercount == 0)
sleep(PEER_REQUEST_DELAY); {
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]); printf("File fully downloaded\n");
// 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");
free_resources(); free_resources();
} }
@ -159,7 +229,7 @@ void download_only_peer(char *cascade_file)
*/ */
int count_occurences(char string[], char c) int count_occurences(char string[], char c)
{ {
int i=0; size_t i=0;
int count=0; int count=0;
for(i=0; i<strlen(string); i++) 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); data[(index/2)] += value << (((index + 1) % 2) * 4);
index++; 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])); 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->targethash = *hash;
casc_file_data->blockcount = 1 + floor( casc_file_data->blockcount = 1 + floor(
(casc_file_data->targetsize - 1.0)/casc_file_data->blocksize (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->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( csc_block_t* block_list = malloc(
sizeof(csc_block_t) * casc_file_data->blockcount 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); fclose(fp);
return NULL; 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; block->hash = *hash;
} }
fclose(fp); fclose(fp);
fp = fopen(destination, "a+w"); return check_blocks(destination, casc_file_data);
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;
} }
/* /*
@ -340,12 +374,12 @@ void csc_free_file(csc_file_t* file)
free(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; size_t remaining = count;
while(remaining > 0) while(remaining > 0)
{ {
size_t read = recv(sock, buffer, remaining, NULL); size_t read = recv(sock, buffer, remaining, 0);
if (read == 0) if (read == 0)
return 0; return 0;
buffer += read; 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) 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; int buffer_size;
if (block->length + PEER_RESPONSE_HEADER_SIZE > MAX_LINE) { 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) if (msglen == 0)
{ {
Close(peer_socket); Close(peer_socket);
return 0; return;
} }
if (reply_header[0] != 0) 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]); printf("Tracker error %d and out-of-memory reading error\n", reply_header[0]);
Close(peer_socket); Close(peer_socket);
return NULL; return;
} }
memset(error_buf, 0, msglen + 1); memset(error_buf, 0, msglen + 1);
memcpy(error_buf, &rio_buf[PEER_RESPONSE_HEADER_SIZE], msglen); memcpy(error_buf, &rio_buf[PEER_RESPONSE_HEADER_SIZE], msglen);
printf("Peer gave error: %d - %s\n", reply_header[0], error_buf); printf("Peer gave error: %d - %s\n", reply_header[0], error_buf);
free(error_buf); free(error_buf);
Close(peer_socket); 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_CTX shactx;
sha256_init(&shactx); sha256_init(&shactx);
sha256_update(&shactx, &rio_buf[PEER_RESPONSE_HEADER_SIZE], msglen); 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) { if (memcmp(shabuffer, (&block->hash)->x, SHA256_HASH_SIZE) != 0) {
printf("Not the same hash\n"); printf("Not the same hash\n");
Close(peer_socket); Close(peer_socket);
return NULL; return;
} }
FILE* fp = fopen(output_file, "rb+"); 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); 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); Close(peer_socket);
fclose(fp); fclose(fp);
} }
@ -461,7 +495,7 @@ int get_peers_list(csc_peer_t** peers, uint8_t hash[32])
Rio_readinitb(&rio, tracker_socket); Rio_readinitb(&rio, tracker_socket);
struct RequestHeader request_header; struct RequestHeader request_header;
strncpy(request_header.protocol, "CASC", 4); memcpy(request_header.protocol, "CASC", 4);
request_header.version = htonl(1); request_header.version = htonl(1);
request_header.command = htonl(1); request_header.command = htonl(1);
request_header.length = htonl(BODY_SIZE); 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]); printf("Tracker error %d and out-of-memory reading error\n", reply_header[0]);
Close(tracker_socket); Close(tracker_socket);
return NULL; return 0;
} }
memset(error_buf, 0, msglen + 1); memset(error_buf, 0, msglen + 1);
memcpy(error_buf, &rio_buf[REPLY_HEADER_SIZE], msglen); // Fixed by Rune memcpy(error_buf, &rio_buf[REPLY_HEADER_SIZE], msglen); // Fixed by Rune
printf("Tracker gave error: %d - %s\n", reply_header[0], error_buf); printf("Tracker gave error: %d - %s\n", reply_header[0], error_buf);
free(error_buf); free(error_buf);
Close(tracker_socket); Close(tracker_socket);
return NULL; return 0;
} }
if (msglen % 12 != 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); Close(tracker_socket);
return NULL; return 0;
} }
int peercount = msglen/12; int peercount = msglen/12;
*peers = malloc(peercount * sizeof(csc_peer_t)); *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++) { for (int i = 0;i<peercount;i++) {
csc_peer_t peer; csc_peer_t peer;
uint8_t* peer_data = &rio_buf[REPLY_HEADER_SIZE + 12*i]; 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.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]))); 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 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 uint64_t blockcount; // Number of blocks data is divided into
csc_block_t* blocks; // Pointer to array of all blocks csc_block_t* blocks; // Pointer to array of all blocks
uint8_t completed;
} csc_file_t; } csc_file_t;
typedef struct csc_peer { 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 uint8_t good; // Flag for if this is 'Good' peer. e.g. Always provides valid responses according to protocol
} csc_peer_t; } csc_peer_t;
typedef struct csc_server {
} csc_server_t;
/* /*
* Parses a hex-string and returns the bytes corresponding to the value * 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]); 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_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 #endif

View File

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