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 LD_FLAGS= -lpthread
all: cascade all: cascade

BIN
A3/src/cascade Executable file

Binary file not shown.

View File

@ -4,6 +4,7 @@
#include <sys/socket.h> #include <sys/socket.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <string.h> #include <string.h>
#include <math.h>
#ifdef __APPLE__ #ifdef __APPLE__
#include "./endian.h" #include "./endian.h"
@ -22,7 +23,7 @@ char my_port[PORT_LEN];
struct csc_file *casc_file; struct csc_file *casc_file;
csc_block_t** queue; csc_block_t** queue;
csc_peer_t* peers; csc_peer_t* peers;
void free_resources() void free_resources()
{ {
free(queue); free(queue);
@ -30,7 +31,7 @@ void free_resources()
csc_free_file(casc_file); 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; 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); printf("Failed to open source: %s\n", sourcefile);
return NULL; return NULL;
} }
fseek(fp, 0L, SEEK_END); fseek(fp, 0L, SEEK_END);
casc_file_size = ftell(fp); casc_file_size = ftell(fp);
fseek(fp, 0L, SEEK_SET); fseek(fp, 0L, SEEK_SET);
char buffer[casc_file_size]; char buffer[casc_file_size];
fread(buffer, casc_file_size, 1, fp); fread(buffer, casc_file_size, 1, fp);
fclose(fp); fclose(fp);
SHA256_CTX shactx; SHA256_CTX shactx;
unsigned char shabuffer[size]; uint8_t shabuffer[size];
sha256_init(&shactx); sha256_init(&shactx);
sha256_update(&shactx, buffer, casc_file_size); sha256_update(&shactx, buffer, casc_file_size);
sha256_final(&shactx, &shabuffer); sha256_final(&shactx, &shabuffer);
for (int i=0; i<size; i++) for (int i=0; i<size; i++)
{ {
hash[i] = shabuffer[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) void download_only_peer(char *cascade_file)
{ {
printf("Managing download only for: %s\n", cascade_file); printf("Managing download only for: %s\n", cascade_file);
if (access(cascade_file, F_OK ) != 0 ) if (access(cascade_file, F_OK ) != 0 )
{ {
fprintf(stderr, ">> File %s does not exist\n", cascade_file); fprintf(stderr, ">> File %s does not exist\n", cascade_file);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
char output_file[strlen(cascade_file)]; char output_file[strlen(cascade_file)];
memcpy(output_file, cascade_file, strlen(cascade_file)); memcpy(output_file, cascade_file, strlen(cascade_file));
char* r = strstr(cascade_file, "cascade"); char* r = strstr(cascade_file, "cascade");
int cutoff = r - cascade_file ; int cutoff = r - cascade_file ;
output_file[cutoff-1] = '\0'; output_file[cutoff-1] = '\0';
printf("Downloading to: %s\n", output_file); printf("Downloading to: %s\n", output_file);
casc_file = csc_parse_file(cascade_file, output_file); casc_file = csc_parse_file(cascade_file, output_file);
csc_block_t** uncomp = malloc(sizeof(csc_block_t*) * casc_file->blockcount);
/* int uncomp_count = 0;
TODO Create a list of missing blocks 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++;
TODO Compute the hash of the cascade file }
HINT: Do not implement hashing from scratch. Use the provided 'get_file_sha' function }
*/
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; int peercount = 0;
while (peercount == 0) while (peercount == 0)
@ -103,7 +112,7 @@ void download_only_peer(char *cascade_file)
printf("Found %d peer(s)\n", peercount); printf("Found %d peer(s)\n", peercount);
} }
} }
csc_peer_t peer = (peers[0]); csc_peer_t peer = (peers[0]);
// Get a good peer if one is available // Get a good peer if one is available
for (int i=0; i<peercount; i++) 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); get_block(queue[i], peer, hash_buf, output_file);
} }
free_resources(); free_resources();
} }
@ -126,7 +135,7 @@ int count_occurences(char string[], char c)
{ {
int i=0; int i=0;
int count=0; int count=0;
for(i=0; i<strlen(string); i++) for(i=0; i<strlen(string); i++)
{ {
if(string[i] == c) if(string[i] == c)
{ {
@ -139,7 +148,7 @@ int count_occurences(char string[], char c)
// Adapted from: https://stackoverflow.com/a/35452093/ // Adapted from: https://stackoverflow.com/a/35452093/
uint8_t* hex_to_bytes(const char* string) { uint8_t* hex_to_bytes(const char* string) {
if(string == NULL) if(string == NULL)
return NULL; return NULL;
size_t slength = strlen(string); size_t slength = strlen(string);
@ -157,7 +166,7 @@ uint8_t* hex_to_bytes(const char* string) {
int value = 0; int value = 0;
if(c >= '0' && c <= '9') if(c >= '0' && c <= '9')
value = (c - '0'); value = (c - '0');
else if (c >= 'A' && c <= 'F') else if (c >= 'A' && c <= 'F')
value = (10 + (c - 'A')); value = (10 + (c - 'A'));
else if (c >= 'a' && c <= 'f') else if (c >= 'a' && c <= 'f')
value = (10 + (c - 'a')); 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->targetsize = be64toh(*((unsigned long long*)&header[16]));
casc_file_data->blocksize = be64toh(*((unsigned long long*)&header[24])); 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); fclose(fp);
fp = fopen(destination, "a+w"); 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); csc_free_file(casc_file_data);
return NULL; return NULL;
} }
void* buffer = malloc(casc_file_data->blocksize); void* buffer = malloc(casc_file_data->blocksize);
if (buffer == NULL) if (buffer == NULL)
{ {
@ -236,12 +275,12 @@ csc_file_t* csc_parse_file(const char* sourcefile, const char* destination)
fclose(fp); fclose(fp);
return NULL; return NULL;
} }
SHA256_CTX shactx; SHA256_CTX shactx;
for(unsigned long long i = 0; i < casc_file_data->blockcount; i++) for(unsigned long long i = 0; i < casc_file_data->blockcount; i++)
{ {
char shabuffer[SHA256_HASH_SIZE]; uint8_t shabuffer[SHA256_HASH_SIZE];
unsigned long long size = casc_file_data->blocks[i].length; unsigned long long size = casc_file_data->blocks[i].length;
if (fread(buffer, size, 1, fp) != 1) if (fread(buffer, size, 1, fp) != 1)
{ {
break; break;
@ -250,16 +289,12 @@ csc_file_t* csc_parse_file(const char* sourcefile, const char* destination)
sha256_init(&shactx); sha256_init(&shactx);
sha256_update(&shactx, buffer, size); sha256_update(&shactx, buffer, size);
sha256_final(&shactx, &shabuffer); sha256_final(&shactx, &shabuffer);
/* if (memcmp((&(&casc_file_data->blocks[i])->hash)->x, shabuffer, 32) == 0) {
TODO Compare the hashes taken from the Cascade file with those of the local data (&casc_file_data->blocks[i])->completed = 1;
file and keep a record of any missing blocks } else {
(&casc_file_data->blocks[i])->completed = 0;
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
*/
} }
fclose(fp); 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) 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 %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]; char rio_buf[MAX_LINE];
int peer_socket; int peer_socket;
/* /*
TODO Request a block from a peer TODO Request a block from a peer
*/ */
FILE* fp = fopen(output_file, "rb+"); FILE* fp = fopen(output_file, "rb+");
if (fp == 0) 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 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); printf("Got block %d. Wrote from %d to %d\n", block->index, block->offset, block->offset+write_count-1);
Close(peer_socket); Close(peer_socket);
fclose(fp); 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; rio_t rio;
char rio_buf[MAX_LINE]; uint8_t rio_buf[MAX_LINE];
for (int i = 0; i < MAX_LINE ; i++) {
rio_buf[i] = 0;
}
int tracker_socket; int tracker_socket;
/* /*
TODO Setup a connection to the tracker 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); request_header.length = htonl(BODY_SIZE);
memcpy(rio_buf, &request_header, HEADER_SIZE); memcpy(rio_buf, &request_header, HEADER_SIZE);
/* struct RequestBody request_body;
TODO Complete the peer list request and strncpy(request_body.hash, hash, 32);
HINT The header has been provided above as a guide 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_writen(tracker_socket, rio_buf, MESSAGE_SIZE);
Rio_readnb(&rio, rio_buf, MAXLINE); Rio_readnb(&rio, rio_buf, MAXLINE);
char reply_header[REPLY_HEADER_SIZE]; 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]); uint32_t msglen = ntohl(*(uint32_t*)&reply_header[1]);
if (msglen == 0) if (msglen == 0)
{ {
Close(tracker_socket); Close(tracker_socket);
return 0; return 0;
} }
if (reply_header[0] != 0) if (reply_header[0] != 0)
{ {
char* error_buf = malloc(msglen + 1); char* error_buf = malloc(msglen + 1);
if (error_buf == NULL) if (error_buf == NULL)
@ -379,41 +426,55 @@ int get_peers_list(csc_peer_t** peers, unsigned char* hash)
Close(tracker_socket); Close(tracker_socket);
return NULL; return NULL;
} }
/* /*
TODO Parse the body of the response to get a list of peers 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 is an array of 'csc_peer's, as defined in cascade.h
*/ */
int peercount;
Close(tracker_socket); Close(tracker_socket);
return peercount; 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]); fprintf(stderr, "Usage: %s <cascade file(s)> <tracker server ip> <tracker server port> <peer ip> <peer port>.\n", argv[0]);
exit(EXIT_FAILURE); 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]); fprintf(stderr, ">> Invalid tracker IP: %s\n", argv[2]);
exit(EXIT_FAILURE); 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]); fprintf(stderr, ">> Invalid tracker port: %s\n", argv[3]);
exit(EXIT_FAILURE); 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]); fprintf(stderr, ">> Invalid peer IP: %s\n", argv[4]);
exit(EXIT_FAILURE); 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]); fprintf(stderr, ">> Invalid peer port: %s\n", argv[5]);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
@ -423,7 +484,7 @@ int main(int argc, char **argv)
snprintf(tracker_port, PORT_LEN, argv[3]); snprintf(tracker_port, PORT_LEN, argv[3]);
snprintf(my_ip, IP_LEN, argv[4]); snprintf(my_ip, IP_LEN, argv[4]);
snprintf(my_port, PORT_LEN, argv[5]); snprintf(my_port, PORT_LEN, argv[5]);
char cas_str[strlen(argv[1])]; char cas_str[strlen(argv[1])];
snprintf(cas_str, strlen(argv[1])+1, argv[1]); snprintf(cas_str, strlen(argv[1])+1, argv[1]);
char delim[] = ":"; char delim[] = ":";
@ -443,7 +504,7 @@ int main(int argc, char **argv)
} }
else else
{ {
printf("Abort on %s\n", ptr); printf("Abort on %s\n", ptr);
fprintf(stderr, ">> Invalid cascade file: %s\n", ptr); fprintf(stderr, ">> Invalid cascade file: %s\n", ptr);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }

View File

@ -24,7 +24,7 @@ struct RequestHeader
struct RequestBody struct RequestBody
{ {
char hash[32]; uint8_t hash[32];
struct in_addr ip; struct in_addr ip;
unsigned short port; unsigned short port;
}; };
@ -34,7 +34,7 @@ struct ClientRequest
char protocol[8]; char protocol[8];
char reserved[12]; char reserved[12];
uint64_t block_num; uint64_t block_num;
char hash[32]; uint8_t hash[32];
}; };
struct ClientResponseHeader 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 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); void get_block(csc_block_t* block, csc_peer_t peer, unsigned char* hash, char* output_file);
#endif #endif

124456
A3/src/shakespeare.txt Normal file

File diff suppressed because it is too large Load Diff

View File