:yay:
This commit is contained in:
@ -260,7 +260,9 @@ class CascadePeerServe(socketserver.StreamRequestHandler):
|
|||||||
resp.extend(struct.pack('!Q', block.length))
|
resp.extend(struct.pack('!Q', block.length))
|
||||||
resp.extend(data)
|
resp.extend(data)
|
||||||
|
|
||||||
|
print("sending")
|
||||||
self.request.sendall(resp)
|
self.request.sendall(resp)
|
||||||
|
print("sent")
|
||||||
|
|
||||||
def reporterror(self, code: int, msg: str) -> None:
|
def reporterror(self, code: int, msg: str) -> None:
|
||||||
msgdata = bytes(msg, 'utf-8')
|
msgdata = bytes(msg, 'utf-8')
|
||||||
|
@ -48,7 +48,7 @@ class TrackerServer(socketserver.StreamRequestHandler):
|
|||||||
if datalen != CMD_LENGTH:
|
if datalen != CMD_LENGTH:
|
||||||
self.respond_error(f'Data for command=1 must be of length {CMD_LENGTH}, got {datalen}')
|
self.respond_error(f'Data for command=1 must be of length {CMD_LENGTH}, got {datalen}')
|
||||||
return
|
return
|
||||||
|
|
||||||
data = self.request.recv(CMD_LENGTH)
|
data = self.request.recv(CMD_LENGTH)
|
||||||
if len(data) != CMD_LENGTH:
|
if len(data) != CMD_LENGTH:
|
||||||
self.respond_error(f'Data from socket had length {len(data)}, expected {CMD_LENGTH}')
|
self.respond_error(f'Data from socket had length {len(data)}, expected {CMD_LENGTH}')
|
||||||
@ -78,7 +78,7 @@ class TrackerServer(socketserver.StreamRequestHandler):
|
|||||||
# Avoid peers registering as good peers without approval
|
# Avoid peers registering as good peers without approval
|
||||||
if is_good_client(data[32:36], self.goodips):
|
if is_good_client(data[32:36], self.goodips):
|
||||||
if str(ipaddress.IPv4Address(data[32:36])) == self.client_address[0]:
|
if str(ipaddress.IPv4Address(data[32:36])) == self.client_address[0]:
|
||||||
print("Registering a good client")
|
print(f"Registering a good client at {ipaddress.IPv4Address(data[32:36])}:{int.from_bytes(data[36:38],'big')}")
|
||||||
else:
|
else:
|
||||||
self.respond_error(f'The IP reported to the tracker ({".".join([str(x) for x in data[32:36]])}) is a reserved IP')
|
self.respond_error(f'The IP reported to the tracker ({".".join([str(x) for x in data[32:36]])}) is a reserved IP')
|
||||||
return
|
return
|
||||||
@ -88,6 +88,7 @@ class TrackerServer(socketserver.StreamRequestHandler):
|
|||||||
with self.lock:
|
with self.lock:
|
||||||
self.active_clients[hashhex][ipportkey] = int(time.time())
|
self.active_clients[hashhex][ipportkey] = int(time.time())
|
||||||
|
|
||||||
|
print(f"Reporting clients to {ipaddress.IPv4Address(data[32:36])}:{int.from_bytes(data[36:38],'big')}")
|
||||||
self.report_clients(hash.hex(), ipportkey)
|
self.report_clients(hash.hex(), ipportkey)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
BIN
A3/src/cascade
BIN
A3/src/cascade
Binary file not shown.
@ -139,7 +139,7 @@ void download_only_peer(char *cascade_file)
|
|||||||
{
|
{
|
||||||
if (peers[i].good)
|
if (peers[i].good)
|
||||||
{
|
{
|
||||||
peer = peers[i];
|
peer = (peers[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,6 +147,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);
|
||||||
}
|
}
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
free_resources();
|
free_resources();
|
||||||
}
|
}
|
||||||
@ -253,7 +254,7 @@ csc_file_t* csc_parse_file(const char* sourcefile, const char* destination)
|
|||||||
casc_file_data->blockcount = 1 + floor(
|
casc_file_data->blockcount = 1 + floor(
|
||||||
(casc_file_data->targetsize - 1.0)/casc_file_data->blocksize
|
(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;
|
casc_file_data->trailblocksize = casc_file_data->targetsize - ((casc_file_data->blockcount - 1) * casc_file_data->blocksize);
|
||||||
|
|
||||||
csc_block_t* block_list = malloc(
|
csc_block_t* block_list = malloc(
|
||||||
sizeof(csc_block_t) * casc_file_data->blockcount
|
sizeof(csc_block_t) * casc_file_data->blockcount
|
||||||
@ -360,20 +361,75 @@ void get_block(csc_block_t* block, csc_peer_t peer, unsigned char* hash, char* o
|
|||||||
{
|
{
|
||||||
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);
|
||||||
|
|
||||||
|
int buffer_size;
|
||||||
|
if (block->length + PEER_RESPONSE_HEADER_SIZE > MAX_LINE) {
|
||||||
|
buffer_size = block->length + PEER_RESPONSE_HEADER_SIZE;
|
||||||
|
} else {
|
||||||
|
buffer_size = MAX_LINE;
|
||||||
|
}
|
||||||
|
printf("%i\n", buffer_size);
|
||||||
rio_t rio;
|
rio_t rio;
|
||||||
char rio_buf[MAX_LINE];
|
char rio_buf[buffer_size];
|
||||||
int peer_socket;
|
int peer_socket;
|
||||||
|
peer_socket = Open_clientfd(peer.ip, peer.port);
|
||||||
|
Rio_readinitb(&rio, peer_socket);
|
||||||
|
|
||||||
/*
|
struct ClientRequest request;
|
||||||
TODO Request a block from a peer
|
memcpy(request.protocol, "CASCADE1", 8);
|
||||||
|
for (int i = 0;i<16;i++) {
|
||||||
|
request.reserved[i] = 0;
|
||||||
|
}
|
||||||
|
request.block_num = be64toh(block->index);
|
||||||
|
strncpy(request.hash, hash, 32);
|
||||||
|
|
||||||
HINT: Remember that integers sent over a network in TCP are done so in network byte order (big-endian) and
|
memcpy(rio_buf, &request, PEER_REQUEST_HEADER_SIZE);
|
||||||
will need to be converted to a more useful format.
|
Rio_writen(peer_socket, rio_buf, PEER_REQUEST_HEADER_SIZE);
|
||||||
|
|
||||||
HINT: Remember to check that the data you have recieved is the data you expect. You can check this as you
|
Rio_readnb(&rio, rio_buf, buffer_size);
|
||||||
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'
|
char reply_header[PEER_RESPONSE_HEADER_SIZE];
|
||||||
*/
|
memcpy(reply_header, rio_buf, PEER_RESPONSE_HEADER_SIZE);
|
||||||
|
|
||||||
|
uint64_t msglen = be64toh(*((unsigned long long*)&reply_header[1]));
|
||||||
|
|
||||||
|
if (msglen == 0)
|
||||||
|
{
|
||||||
|
Close(peer_socket);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reply_header[0] != 0)
|
||||||
|
{
|
||||||
|
char* error_buf = malloc(msglen + 1);
|
||||||
|
if (error_buf == NULL)
|
||||||
|
{
|
||||||
|
printf("Tracker error %d and out-of-memory reading error\n", reply_header[0]);
|
||||||
|
Close(peer_socket);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char block_data[msglen];
|
||||||
|
memcpy(block_data,&rio_buf[PEER_RESPONSE_HEADER_SIZE],msglen);
|
||||||
|
|
||||||
|
uint8_t shabuffer[SHA256_HASH_SIZE];
|
||||||
|
|
||||||
|
SHA256_CTX shactx;
|
||||||
|
sha256_init(&shactx);
|
||||||
|
sha256_update(&shactx, block_data, msglen);
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
FILE* fp = fopen(output_file, "rb+");
|
FILE* fp = fopen(output_file, "rb+");
|
||||||
if (fp == 0)
|
if (fp == 0)
|
||||||
@ -383,15 +439,10 @@ void get_block(csc_block_t* block, csc_peer_t peer, unsigned char* hash, char* o
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
fseek(fp, block->offset, SEEK_SET);
|
||||||
TODO Write the block into the data file
|
fputs(block_data,fp);
|
||||||
|
|
||||||
HINT: You can write a block to a specific index using the fseek(...) function. Check the documentation
|
printf("Got block %d. Wrote from %d to %d\n", block->index, block->offset, block->offset+msglen-1);
|
||||||
online for details on how this work and what it does
|
|
||||||
*/
|
|
||||||
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);
|
Close(peer_socket);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
}
|
}
|
||||||
@ -420,12 +471,12 @@ int get_peers_list(csc_peer_t** peers, uint8_t hash[32])
|
|||||||
struct RequestBody request_body;
|
struct RequestBody request_body;
|
||||||
strncpy(request_body.hash, hash, 32);
|
strncpy(request_body.hash, hash, 32);
|
||||||
inet_aton(my_ip, &request_body.ip);
|
inet_aton(my_ip, &request_body.ip);
|
||||||
request_body.port = atol(my_port);
|
request_body.port = be16toh(atol(my_port));
|
||||||
memcpy(&rio_buf[HEADER_SIZE], &request_body, BODY_SIZE);
|
memcpy(&rio_buf[HEADER_SIZE], &request_body, BODY_SIZE);
|
||||||
|
|
||||||
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, MAX_LINE);
|
||||||
|
|
||||||
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);
|
||||||
@ -461,7 +512,7 @@ int get_peers_list(csc_peer_t** peers, uint8_t hash[32])
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
int peercount = msglen/12;
|
int peercount = msglen/12;
|
||||||
peers = malloc(peercount * sizeof(csc_peer_t));
|
*peers = malloc(peercount * sizeof(csc_peer_t));
|
||||||
|
|
||||||
for (int i = 0;i<peercount;i++) {
|
for (int i = 0;i<peercount;i++) {
|
||||||
csc_peer_t peer;
|
csc_peer_t peer;
|
||||||
@ -469,8 +520,9 @@ int get_peers_list(csc_peer_t** peers, uint8_t hash[32])
|
|||||||
struct in_addr ip = {};
|
struct in_addr ip = {};
|
||||||
sprintf(peer.ip, "%u.%u.%u.%u", peer_data[0], peer_data[1], peer_data[2], peer_data[3]);
|
sprintf(peer.ip, "%u.%u.%u.%u", peer_data[0], peer_data[1], peer_data[2], peer_data[3]);
|
||||||
sprintf(peer.port, "%u", be16toh(*((uint16_t*)&peer_data[4])));
|
sprintf(peer.port, "%u", be16toh(*((uint16_t*)&peer_data[4])));
|
||||||
}
|
|
||||||
|
|
||||||
|
(*peers)[i] = peer;
|
||||||
|
}
|
||||||
Close(tracker_socket);
|
Close(tracker_socket);
|
||||||
return peercount;
|
return peercount;
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@ struct RequestBody
|
|||||||
struct ClientRequest
|
struct ClientRequest
|
||||||
{
|
{
|
||||||
char protocol[8];
|
char protocol[8];
|
||||||
char reserved[12];
|
char reserved[16];
|
||||||
uint64_t block_num;
|
uint64_t block_num;
|
||||||
uint8_t hash[32];
|
uint8_t hash[32];
|
||||||
};
|
};
|
||||||
|
@ -859,7 +859,7 @@ ssize_t rio_readnb(rio_t *rp, void *usrbuf, size_t n)
|
|||||||
|
|
||||||
while (nleft > 0) {
|
while (nleft > 0) {
|
||||||
if ((nread = rio_read(rp, bufp, nleft)) < 0)
|
if ((nread = rio_read(rp, bufp, nleft)) < 0)
|
||||||
return -1; /* errno set by read() */
|
return -1; /* errno set by read() */
|
||||||
else if (nread == 0)
|
else if (nread == 0)
|
||||||
break; /* EOF */
|
break; /* EOF */
|
||||||
nleft -= nread;
|
nleft -= nread;
|
||||||
|
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user