diff --git a/A3/src/cascade.c b/A3/src/cascade.c index 1a5c958..a8914f3 100644 --- a/A3/src/cascade.c +++ b/A3/src/cascade.c @@ -24,6 +24,9 @@ struct csc_file *casc_file; csc_block_t** queue; csc_peer_t* peers; +/* + * Frees global resources that are malloc'ed during peer downloads. + */ void free_resources() { free(queue); @@ -31,6 +34,12 @@ void free_resources() csc_free_file(casc_file); } +/* + * Gets a sha256 hash of a specified file, sourcefile. 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 + */ unsigned char* get_file_sha(const char* sourcefile, uint8_t hash[32], int size) { int casc_file_size; @@ -50,18 +59,34 @@ unsigned char* get_file_sha(const char* sourcefile, uint8_t hash[32], int size) fread(buffer, casc_file_size, 1, fp); fclose(fp); + get_data_sha(buffer, hash, casc_file_size, size); +} + +/* + * 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) +{ SHA256_CTX shactx; - uint8_t shabuffer[size]; + unsigned char shabuffer[hash_size]; sha256_init(&shactx); - sha256_update(&shactx, buffer, casc_file_size); + sha256_update(&shactx, sourcedata, data_size); sha256_final(&shactx, &shabuffer); - for (int i=0; iblockcount); + int uncomp_count = 0; + queue = malloc(casc_file->blockcount * sizeof(csc_block_t*)); for (unsigned long long i = 0;iblockcount;i++) { if ((&casc_file->blocks[i])->completed == 0) { - uncomp[uncomp_count] = &casc_file->blocks[i]; + queue[uncomp_count]0 = &casc_file->blocks[i]; uncomp_count++; } } @@ -131,6 +157,9 @@ void download_only_peer(char *cascade_file) free_resources(); } +/* + * Count how many times a character occurs in a string + */ int count_occurences(char string[], char c) { int i=0; @@ -146,6 +175,9 @@ int count_occurences(char string[], char c) } // Adapted from: https://stackoverflow.com/a/35452093/ +/* + * Convert a string of hexidecimal into a string of bytes + */ uint8_t* hex_to_bytes(const char* string) { if(string == NULL) @@ -326,6 +358,10 @@ size_t readbytes(int sock, void* buffer, size_t count) return count; } +/* + * Get a specified block from a peer on the network. The block is retrieved and then inserted directly into + * the appropriate data file at the appropriate location. + */ 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); @@ -336,6 +372,13 @@ void get_block(csc_block_t* block, csc_peer_t peer, unsigned char* hash, char* o /* TODO Request a block from a peer + + HINT: Remember that integers sent over a network in TCP are done so in network byte order (big-endian) and + will need to be converted to a more useful format. + + HINT: Remember to check that the data you have recieved is the data you expect. You can check this as you + should already have a hash of block in block->hash, and you can get the hash of the data you just read by + using the function 'get_data_sha' */ FILE* fp = fopen(output_file, "rb+"); @@ -348,6 +391,9 @@ void get_block(csc_block_t* block, csc_peer_t peer, unsigned char* hash, char* o /* TODO Write the block into the data file + + HINT: You can write a block to a specific index using the fseek(...) function. Check the documentation + online for details on how this work and what it does */ int write_count; @@ -356,6 +402,10 @@ void get_block(csc_block_t* block, csc_peer_t peer, unsigned char* hash, char* o fclose(fp); } +/* + * Get a list of peers on the network from a tracker. Note that this query is doing double duty according to + * the protocol, and by asking for a list of peers we are also enrolling on the network ourselves. + */ int get_peers_list(csc_peer_t** peers, uint8_t hash[32]) { rio_t rio; @@ -368,6 +418,8 @@ int get_peers_list(csc_peer_t** peers, uint8_t hash[32]) /* TODO Setup a connection to the tracker + + HINT: Remember that as well as making a connection, you'll also need to initialise a buffer for messages */ struct RequestHeader request_header; @@ -439,19 +491,9 @@ int get_peers_list(csc_peer_t** peers, uint8_t hash[32]) return peercount; } -// 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"); -// } - +/* + * The entry point for the code. Parses command line arguments and starts up the appropriate peer code. + */ int main(int argc, char **argv) { if (argc != MAIN_ARGNUM + 1)