some stuff

This commit is contained in:
Nikolaj
2021-11-04 16:00:22 +01:00
parent 9856de01e4
commit 3237f413db
6 changed files with 124604 additions and 86 deletions

View File

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

BIN
A3/src/cascade Executable file

Binary file not shown.

View File

@ -4,6 +4,7 @@
#include <sys/socket.h>
#include <arpa/inet.h>
#include <string.h>
#include <math.h>
#ifdef __APPLE__
#include "./endian.h"
@ -22,7 +23,7 @@ char my_port[PORT_LEN];
struct csc_file *casc_file;
csc_block_t** queue;
csc_peer_t* peers;
void free_resources()
{
free(queue);
@ -30,7 +31,7 @@ void free_resources()
csc_free_file(casc_file);
}
unsigned char* get_file_sha(const char* sourcefile, csc_file_t* res, char* hash, int size)
unsigned char* get_file_sha(const char* sourcefile, uint8_t hash[32], int size)
{
int casc_file_size;
@ -40,21 +41,21 @@ unsigned char* get_file_sha(const char* sourcefile, csc_file_t* res, char* hash,
printf("Failed to open source: %s\n", sourcefile);
return NULL;
}
fseek(fp, 0L, SEEK_END);
casc_file_size = ftell(fp);
fseek(fp, 0L, SEEK_SET);
char buffer[casc_file_size];
fread(buffer, casc_file_size, 1, fp);
fread(buffer, casc_file_size, 1, fp);
fclose(fp);
SHA256_CTX shactx;
unsigned char shabuffer[size];
uint8_t shabuffer[size];
sha256_init(&shactx);
sha256_update(&shactx, buffer, casc_file_size);
sha256_final(&shactx, &shabuffer);
for (int i=0; i<size; i++)
{
hash[i] = shabuffer[i];
@ -63,30 +64,38 @@ unsigned char* get_file_sha(const char* sourcefile, csc_file_t* res, char* hash,
void download_only_peer(char *cascade_file)
{
printf("Managing download only for: %s\n", cascade_file);
if (access(cascade_file, F_OK ) != 0 )
printf("Managing download only for: %s\n", cascade_file);
if (access(cascade_file, F_OK ) != 0 )
{
fprintf(stderr, ">> File %s does not exist\n", cascade_file);
exit(EXIT_FAILURE);
}
char output_file[strlen(cascade_file)];
char output_file[strlen(cascade_file)];
memcpy(output_file, cascade_file, strlen(cascade_file));
char* r = strstr(cascade_file, "cascade");
int cutoff = r - cascade_file ;
output_file[cutoff-1] = '\0';
printf("Downloading to: %s\n", output_file);
casc_file = csc_parse_file(cascade_file, output_file);
/*
TODO Create a list of missing blocks
*/
/*
TODO Compute the hash of the cascade file
HINT: Do not implement hashing from scratch. Use the provided 'get_file_sha' function
*/
csc_block_t** uncomp = malloc(sizeof(csc_block_t*) * casc_file->blockcount);
int uncomp_count = 0;
for (unsigned long long i = 0;i<casc_file->blockcount;i++) {
if ((&casc_file->blocks[i])->completed == 0) {
uncomp[uncomp_count] = &casc_file->blocks[i];
uncomp_count++;
}
}
queue = malloc(sizeof(csc_block_t*) * uncomp_count);
for (int i = 0;i<uncomp_count;i++) {
queue[i] = uncomp[i];
}
free(uncomp);
uint8_t hash_buf[32];
get_file_sha(cascade_file, hash_buf, 32);
int peercount = 0;
while (peercount == 0)
@ -103,7 +112,7 @@ void download_only_peer(char *cascade_file)
printf("Found %d peer(s)\n", peercount);
}
}
csc_peer_t peer = (peers[0]);
// Get a good peer if one is available
for (int i=0; i<peercount; i++)
@ -118,7 +127,7 @@ void download_only_peer(char *cascade_file)
{
get_block(queue[i], peer, hash_buf, output_file);
}
free_resources();
}
@ -126,7 +135,7 @@ int count_occurences(char string[], char c)
{
int i=0;
int count=0;
for(i=0; i<strlen(string); i++)
for(i=0; i<strlen(string); i++)
{
if(string[i] == c)
{
@ -139,7 +148,7 @@ int count_occurences(char string[], char c)
// Adapted from: https://stackoverflow.com/a/35452093/
uint8_t* hex_to_bytes(const char* string) {
if(string == NULL)
if(string == NULL)
return NULL;
size_t slength = strlen(string);
@ -157,7 +166,7 @@ uint8_t* hex_to_bytes(const char* string) {
int value = 0;
if(c >= '0' && c <= '9')
value = (c - '0');
else if (c >= 'A' && c <= 'F')
else if (c >= 'A' && c <= 'F')
value = (10 + (c - 'A'));
else if (c >= 'a' && c <= 'f')
value = (10 + (c - 'a'));
@ -208,16 +217,46 @@ csc_file_t* csc_parse_file(const char* sourcefile, const char* destination)
casc_file_data->targetsize = be64toh(*((unsigned long long*)&header[16]));
casc_file_data->blocksize = be64toh(*((unsigned long long*)&header[24]));
uint8_t x[32];
for (int i = 0; i < 32; i++) {
x[i] = (uint8_t)(*((unsigned long long*)&header[32+i]));
}
csc_hashdata_t* hash = {x};
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->blockcount * casc_file_data->blocksize) - casc_file_data->targetsize;
csc_block_t* block_list = malloc(
sizeof(csc_block_t) * casc_file_data->blockcount
);
casc_file_data->blocks = block_list;
for (unsigned long long b = 0;b < casc_file_data->blockcount; b++) {
csc_block_t* block = &(block_list[b]);
block->index = b;
block->offset = b * casc_file_data->blocksize;
if (b == casc_file_data->blockcount - 1 ) {
block->length = casc_file_data->trailblocksize;
} else {
block->length = casc_file_data->blocksize;
}
block->completed = 0;
uint8_t block_x[32];
if (fread(block_x, 1, 32, fp) != 32) {
printf("Cascade file not readable\n");
fclose(fp);
return NULL;
}
csc_hashdata_t* hash = {block_x};
block->hash = *hash;
}
/*
TODO Parse the cascade file and store the data in an appropriate data structure
HINT Use the definition of the 'csc_file' struct in cascade.h, as well as the
assignment handout for guidance on what each attribute is and where it is stored
in the files header/body.
*/
fclose(fp);
fp = fopen(destination, "a+w");
@ -227,7 +266,7 @@ csc_file_t* csc_parse_file(const char* sourcefile, const char* destination)
csc_free_file(casc_file_data);
return NULL;
}
void* buffer = malloc(casc_file_data->blocksize);
if (buffer == NULL)
{
@ -236,12 +275,12 @@ csc_file_t* csc_parse_file(const char* sourcefile, const char* destination)
fclose(fp);
return NULL;
}
SHA256_CTX shactx;
for(unsigned long long i = 0; i < casc_file_data->blockcount; i++)
{
char shabuffer[SHA256_HASH_SIZE];
unsigned long long size = casc_file_data->blocks[i].length;
uint8_t shabuffer[SHA256_HASH_SIZE];
unsigned long long size = casc_file_data->blocks[i].length;
if (fread(buffer, size, 1, fp) != 1)
{
break;
@ -250,16 +289,12 @@ csc_file_t* csc_parse_file(const char* sourcefile, const char* destination)
sha256_init(&shactx);
sha256_update(&shactx, buffer, size);
sha256_final(&shactx, &shabuffer);
/*
TODO Compare the hashes taken from the Cascade file with those of the local data
file and keep a record of any missing blocks
HINT The code above takes a hash of each block of data in the local file in turn
and stores it in the 'shabuffer' variable. You can compare then compare 'shabuffer'
directly to the hashes of each block you have hopefully already assigned as part
of the 'casc_file_data' struct
*/
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);
@ -294,15 +329,15 @@ 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);
rio_t rio;
rio_t rio;
char rio_buf[MAX_LINE];
int peer_socket;
/*
TODO Request a block from a peer
*/
FILE* fp = fopen(output_file, "rb+");
if (fp == 0)
{
@ -314,18 +349,23 @@ void get_block(csc_block_t* block, csc_peer_t peer, unsigned char* hash, char* o
/*
TODO Write the block into the data file
*/
int write_count;
printf("Got block %d. Wrote from %d to %d\n", block->index, block->offset, block->offset+write_count-1);
Close(peer_socket);
fclose(fp);
}
int get_peers_list(csc_peer_t** peers, unsigned char* hash)
int get_peers_list(csc_peer_t** peers, uint8_t hash[32])
{
rio_t rio;
char rio_buf[MAX_LINE];
rio_t rio;
uint8_t rio_buf[MAX_LINE];
for (int i = 0; i < MAX_LINE ; i++) {
rio_buf[i] = 0;
}
int tracker_socket;
/*
TODO Setup a connection to the tracker
*/
@ -337,26 +377,33 @@ int get_peers_list(csc_peer_t** peers, unsigned char* hash)
request_header.length = htonl(BODY_SIZE);
memcpy(rio_buf, &request_header, HEADER_SIZE);
/*
TODO Complete the peer list request and
HINT The header has been provided above as a guide
*/
struct RequestBody request_body;
strncpy(request_body.hash, hash, 32);
inet_pton(AF_INET, my_ip, &request_body.ip);
request_body.port = atol(my_port);
memcpy(&rio_buf[HEADER_SIZE], &request_body, BODY_SIZE);
for (int i = 0;i<128;i++) {
printf("%02x ",rio_buf[i]);
}
printf("\n");
return 0; // TODO REMOVE
Rio_writen(tracker_socket, rio_buf, MESSAGE_SIZE);
Rio_readnb(&rio, rio_buf, MAXLINE);
char reply_header[REPLY_HEADER_SIZE];
memcpy(reply_header, rio_buf, REPLY_HEADER_SIZE);
memcpy(reply_header, rio_buf, REPLY_HEADER_SIZE);
uint32_t msglen = ntohl(*(uint32_t*)&reply_header[1]);
if (msglen == 0)
{
Close(tracker_socket);
return 0;
return 0;
}
if (reply_header[0] != 0)
if (reply_header[0] != 0)
{
char* error_buf = malloc(msglen + 1);
if (error_buf == NULL)
@ -379,41 +426,55 @@ int get_peers_list(csc_peer_t** peers, unsigned char* hash)
Close(tracker_socket);
return NULL;
}
/*
TODO Parse the body of the response to get a list of peers
HINT Some of the later provided code expects the peers to be stored in the ''peers' variable, which
HINT Some of the later provided code expects the peers to be stored in the ''peers' variable, which
is an array of 'csc_peer's, as defined in cascade.h
*/
int peercount;
Close(tracker_socket);
return peercount;
}
int main(int argc, char **argv)
// int main() {
// csc_file_t* f = csc_parse_file("./tests/shakespeare.10kib.txt.cascade","shakespeare.txt");
// printf("File size: %i\nBlock Size: %i\nBlock Count: %i\nFile hash: ", f->targetsize, f->blocksize, f->blockcount);
// for (int i = 0;i<32;i++) {
// printf("%02x ",(&f->targethash)->x[i]);
// }
// printf("\nFirst block hash: ");
// for (int i = 0;i<32;i++) {
// printf("%02x ",(&(&f->blocks[0])->hash)->x[i]);
// }
// printf("\n");
// }
int main(int argc, char **argv)
{
if (argc != MAIN_ARGNUM + 1)
if (argc != MAIN_ARGNUM + 1)
{
fprintf(stderr, "Usage: %s <cascade file(s)> <tracker server ip> <tracker server port> <peer ip> <peer port>.\n", argv[0]);
exit(EXIT_FAILURE);
}
else if (!is_valid_ip(argv[2]))
}
else if (!is_valid_ip(argv[2]))
{
fprintf(stderr, ">> Invalid tracker IP: %s\n", argv[2]);
exit(EXIT_FAILURE);
}
else if (!is_valid_port(argv[3]))
}
else if (!is_valid_port(argv[3]))
{
fprintf(stderr, ">> Invalid tracker port: %s\n", argv[3]);
exit(EXIT_FAILURE);
}
else if (!is_valid_ip(argv[4]))
}
else if (!is_valid_ip(argv[4]))
{
fprintf(stderr, ">> Invalid peer IP: %s\n", argv[4]);
exit(EXIT_FAILURE);
}
else if (!is_valid_port(argv[5]))
}
else if (!is_valid_port(argv[5]))
{
fprintf(stderr, ">> Invalid peer port: %s\n", argv[5]);
exit(EXIT_FAILURE);
@ -423,7 +484,7 @@ int main(int argc, char **argv)
snprintf(tracker_port, PORT_LEN, argv[3]);
snprintf(my_ip, IP_LEN, argv[4]);
snprintf(my_port, PORT_LEN, argv[5]);
char cas_str[strlen(argv[1])];
snprintf(cas_str, strlen(argv[1])+1, argv[1]);
char delim[] = ":";
@ -443,7 +504,7 @@ int main(int argc, char **argv)
}
else
{
printf("Abort on %s\n", ptr);
printf("Abort on %s\n", ptr);
fprintf(stderr, ">> Invalid cascade file: %s\n", ptr);
exit(EXIT_FAILURE);
}

View File

@ -24,7 +24,7 @@ struct RequestHeader
struct RequestBody
{
char hash[32];
uint8_t hash[32];
struct in_addr ip;
unsigned short port;
};
@ -34,7 +34,7 @@ struct ClientRequest
char protocol[8];
char reserved[12];
uint64_t block_num;
char hash[32];
uint8_t hash[32];
};
struct ClientResponseHeader
@ -111,7 +111,7 @@ int csc_get_peers(csc_ipport_t tracker, csc_hashdata_t cascadehash, csc_ipport_t
*/
int csc_download_block(csc_ipport_t client, csc_hashdata_t cascadehash, uint64_t blockno, uint64_t blocklength, void* buffer);
int get_peers_list(csc_peer_t** peers, unsigned char* hash);
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);
#endif

124456
A3/src/shakespeare.txt Normal file

File diff suppressed because it is too large Load Diff

View File