diff --git a/A3/src/Makefile b/A3/src/Makefile index da85a6e..aa191c5 100644 --- a/A3/src/Makefile +++ b/A3/src/Makefile @@ -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 diff --git a/A3/src/cascade b/A3/src/cascade index 9038e7d..b7d75e8 100755 Binary files a/A3/src/cascade and b/A3/src/cascade differ diff --git a/A3/src/cascade.c b/A3/src/cascade.c index c37482e..6fc12f2 100644 --- a/A3/src/cascade.c +++ b/A3/src/cascade.c @@ -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; icompleted) { + 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; ix,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