Updated with new hints from David
This commit is contained in:
@ -24,6 +24,9 @@ struct csc_file *casc_file;
|
|||||||
csc_block_t** queue;
|
csc_block_t** queue;
|
||||||
csc_peer_t* peers;
|
csc_peer_t* peers;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Frees global resources that are malloc'ed during peer downloads.
|
||||||
|
*/
|
||||||
void free_resources()
|
void free_resources()
|
||||||
{
|
{
|
||||||
free(queue);
|
free(queue);
|
||||||
@ -31,6 +34,12 @@ void free_resources()
|
|||||||
csc_free_file(casc_file);
|
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)
|
unsigned char* get_file_sha(const char* sourcefile, uint8_t hash[32], int size)
|
||||||
{
|
{
|
||||||
int casc_file_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);
|
fread(buffer, casc_file_size, 1, fp);
|
||||||
fclose(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;
|
SHA256_CTX shactx;
|
||||||
uint8_t shabuffer[size];
|
unsigned char shabuffer[hash_size];
|
||||||
sha256_init(&shactx);
|
sha256_init(&shactx);
|
||||||
sha256_update(&shactx, buffer, casc_file_size);
|
sha256_update(&shactx, sourcedata, data_size);
|
||||||
sha256_final(&shactx, &shabuffer);
|
sha256_final(&shactx, &shabuffer);
|
||||||
|
|
||||||
for (int i=0; i<size; i++)
|
for (int i=0; i<hash_size; i++)
|
||||||
{
|
{
|
||||||
hash[i] = shabuffer[i];
|
hash[i] = shabuffer[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Perform all client based interactions in the P2P network for a given cascade file.
|
||||||
|
* E.g. parse a cascade file and get all the relevent data from somewhere else on the
|
||||||
|
* network.
|
||||||
|
*/
|
||||||
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);
|
||||||
@ -79,11 +104,12 @@ void download_only_peer(char *cascade_file)
|
|||||||
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;
|
int uncomp_count = 0;
|
||||||
|
queue = malloc(casc_file->blockcount * sizeof(csc_block_t*));
|
||||||
for (unsigned long long i = 0;i<casc_file->blockcount;i++) {
|
for (unsigned long long i = 0;i<casc_file->blockcount;i++) {
|
||||||
if ((&casc_file->blocks[i])->completed == 0) {
|
if ((&casc_file->blocks[i])->completed == 0) {
|
||||||
uncomp[uncomp_count] = &casc_file->blocks[i];
|
queue[uncomp_count]0 = &casc_file->blocks[i];
|
||||||
uncomp_count++;
|
uncomp_count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -131,6 +157,9 @@ void download_only_peer(char *cascade_file)
|
|||||||
free_resources();
|
free_resources();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Count how many times a character occurs in a string
|
||||||
|
*/
|
||||||
int count_occurences(char string[], char c)
|
int count_occurences(char string[], char c)
|
||||||
{
|
{
|
||||||
int i=0;
|
int i=0;
|
||||||
@ -146,6 +175,9 @@ int count_occurences(char string[], char c)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Adapted from: https://stackoverflow.com/a/35452093/
|
// 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) {
|
uint8_t* hex_to_bytes(const char* string) {
|
||||||
|
|
||||||
if(string == NULL)
|
if(string == NULL)
|
||||||
@ -326,6 +358,10 @@ size_t readbytes(int sock, void* buffer, size_t count)
|
|||||||
return 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)
|
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);
|
||||||
@ -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
|
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+");
|
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
|
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;
|
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);
|
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])
|
int get_peers_list(csc_peer_t** peers, uint8_t hash[32])
|
||||||
{
|
{
|
||||||
rio_t rio;
|
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
|
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;
|
struct RequestHeader request_header;
|
||||||
@ -439,19 +491,9 @@ int get_peers_list(csc_peer_t** peers, uint8_t hash[32])
|
|||||||
return peercount;
|
return peercount;
|
||||||
}
|
}
|
||||||
|
|
||||||
// int main() {
|
/*
|
||||||
// csc_file_t* f = csc_parse_file("./tests/shakespeare.10kib.txt.cascade","shakespeare.txt");
|
* The entry point for the code. Parses command line arguments and starts up the appropriate peer code.
|
||||||
// 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)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
if (argc != MAIN_ARGNUM + 1)
|
if (argc != MAIN_ARGNUM + 1)
|
||||||
|
Reference in New Issue
Block a user