/* @brief Converts a given binary number to an int. * @param binaryNumber: Number to convert. * @param len: Length of the buffer. */ int binary2int(uint8_t *buf, int len){ char temp[2*len]; bzero(temp, 2*len); binary2hex(buf, len, temp); int ret = (int)strtol(temp, NULL, 16); return ret; }
void printHash(uint8_t *hash) { char buf[50]; bzero(buf, 50); binary2hex(hash, 20, buf); printf("%s\n", buf); }
void printChunk(chunkList *list) { int i; for(i = 0; i < list->numChunk; i++) { char buf[50]; bzero(buf, 50); chunkLine *line = &(list->list[i]); binary2hex(line->hash, 20, buf); fprintf(stderr,"%d: %s\n", line->seq, buf); } }
void print_packet(struct packet* packet){ unsigned short magic_number = ntohs(*(unsigned short*)(packet->header)); unsigned char version_number = *(unsigned char*)(packet->header+2); unsigned char packet_type = *(unsigned char*)(packet->header+3); unsigned short header_length = ntohs(*(unsigned short*)(packet->header+4)); unsigned short in_packet_length = ntohs(*(unsigned short*)(packet->header+6)); unsigned int seq_number = ntohl(*(unsigned int*)(packet->header+8)); unsigned int ack_number = ntohl(*(unsigned int*)(packet->header+12)); printf("Printing packet....................................................................\n"); printf("magic_number: %hu, version_number: %hhu, packet_type: %hhu\n", magic_number, version_number, packet_type); printf("header_length: %hu, packet_length: %hu\n", header_length, in_packet_length); printf("seq_number: %u, ack_number: %u\n", seq_number, ack_number); unsigned short i = 0; char ascii_buf[CHUNK_HASH_SIZE]; if(packet_type!=DATA){ for(i=4;i<in_packet_length-header_length;i=i+20){ binary2hex((uint8_t *)(&(packet->payload[i])), SHA1_HASH_SIZE, ascii_buf); printf("hash: %s\n", ascii_buf); } } printf("End printing packet....................................................................\n\n"); }
void print_packet(uint8_t* packet, int i) { packet_info myPack = {0}; byte_buf *tempRequest = create_bytebuf(PACKET_LENGTH); mmemclear(tempRequest); memcpy(tempRequest->buf, packet, PACKET_LENGTH); mmemmove(myPack.magicNumber, tempRequest, 2); mmemmove(myPack.versionNumber, tempRequest, 1); mmemmove(myPack.packetType, tempRequest, 1); mmemmove(myPack.headerLength, tempRequest, 2); mmemmove(myPack.totalPacketLength, tempRequest, 2); mmemmove(myPack.sequenceNumber, tempRequest, 4); mmemmove(myPack.ackNumber, tempRequest, 4); int type = binary2int(myPack.packetType, 1); int hlen = binary2int(myPack.headerLength, 2); int plen = binary2int(myPack.totalPacketLength, 2); if(type == 0 || type == 1){ mmemmove(myPack.numberHashes, tempRequest, 1); mmemmove(myPack.padding, tempRequest, 3); } mmemmove(myPack.body, tempRequest, plen - hlen); int numh = binary2int(myPack.numberHashes, 1); char typestr[10]; switch (type) { case 0: sprintf(typestr, "WHOHAS"); break; case 1: sprintf(typestr, "IHAVE"); break; case 2: sprintf(typestr, "GET"); break; case 3: sprintf(typestr, "DATA"); break; case 4: sprintf(typestr, "ACK"); break; case 5: sprintf(typestr, "DENIED"); break; default: sprintf(typestr, "DEFAULT"); break; } printf("\n###############################\n"); if(i == SEND) printf("Sending packet with contents:\n"); if(i == RECV) printf("Receiving packet with contents:\n"); printf("Magic Number: %d\n", binary2int(myPack.magicNumber, 2)); printf("Version Number: %d\n", binary2int(myPack.versionNumber, 1)); printf("Packet Type : %s\n", typestr); printf("Header Len : %d\n", hlen); printf("Packet Len : %d\n", plen); printf("Seq No : %d\n", binary2int(myPack.sequenceNumber , 4)); printf("Ack No : %d\n", binary2int(myPack.ackNumber , 4)); printf("Hash No : %d\n", numh); char hash[45] = {0}; for(int i = 0; i < numh; i++) { binary2hex(myPack.body + 20 * i, 20, hash); printf("Hash %d: %s \n", i, hash); bzero(hash, 45); } if(type == 2) // GET { binary2hex(myPack.body, 20, hash); printf("Hash %d: %s \n", i, hash); bzero(hash, 45); } printf("###############################\n\n"); delete_bytebuf(tempRequest); }
void flushDownload(int sock) { int i = 0; int idx; uint8_t *hash; Packet *pkt; connDown *pool = downloadPool; for(i = 0; i < peerInfo.numPeer; i++) { int peerID = peerInfo.peerList[i].peerID; Packet *ack = peek(pool[peerID].ackSendQueue); while(ack != NULL) { peerList_t *p = &(peerInfo.peerList[i]); fprintf(stderr,"Sending ACK %d\n", getPacketAck(ack)); int retVal = spiffy_sendto(sock, ack->payload, getPacketSize(ack), 0, (struct sockaddr *) & (p->addr), sizeof(p->addr)); fprintf(stderr,"Sent ACK %d\n", getPacketAck(ack)); if(retVal == -1) { // spiffy_sendto() does not work!! fprintf(stderr,"spiffy_sendto() returned -1.\n"); enqueue(pool[peerID].ackSendQueue, dequeue(pool[peerID].ackSendQueue)); } else { dequeue(pool[peerID].ackSendQueue); freePacket(ack); ack = dequeue(pool[peerID].ackSendQueue); } } switch(pool[peerID].state) { case 0: // Ready pkt = dequeue(pool[peerID].getQueue); while(pkt != NULL) { hash = getPacketHash(pkt, 0); printHash(hash); idx = searchHash(hash, &getChunk, 0); if(idx == -1) { // Someone else is sending or has sent this chunk freePacket(pkt); pkt = dequeue(pool[peerID].getQueue); } else if(numConnDown < maxConn){ getChunk.list[idx].fetchState = 2; if(downloadPool[peerID].connected == 1) fprintf(stderr,"NOT SUPPOSED TO BE CONNECTEED! \n\n\n\n\n\n"); downloadPool[peerID].connected = 1; numConnDown++; break; } else { // Cannot allow more download connections fprintf(stderr,"->No more download connection allowed!\n"); pool[peerID].state = 2; break; } } if(pool[peerID].state == 2) break; if(pkt != NULL) { fprintf(stderr,"Sending a GET\n"); peerList_t *p = &(peerInfo.peerList[i]); hash = pkt->payload + 16; char buf[50]; bzero(buf, 50); binary2hex(hash, 20, buf); fprintf(stderr,"GET hash:%s\n", buf); pool[peerID].curChunkID = searchHash(hash, &getChunk, -1); int retVal = spiffy_sendto(sock, pkt->payload, getPacketSize(pkt), 0, (struct sockaddr *) & (p->addr), sizeof(p->addr)); if(retVal == -1) { // Spiffy is broken! fprintf(stderr,"spiffy_snetto() returned -1.\n"); newPacketWHOHAS(nonCongestQueue); freePacket(pkt); cleanUpConnDown(&(pool[peerID])); numConnDown--; return; } setPacketTime(pkt); enqueue(pool[peerID].timeoutQueue, pkt); pool[peerID].state = 1; } break; case 1: { // Downloading pkt = peek(pool[peerID].timeoutQueue); struct timeval curTime; gettimeofday(&curTime, NULL); long dt = diffTimeval(&curTime, &(pkt->timestamp)); if(dt > GET_TIMEOUT_SEC) { pool[peerID].timeoutCount++; fprintf(stderr,"GET request timed out %d times!\n", pool[peerID].timeoutCount); setPacketTime(pkt); if(pool[peerID].timeoutCount == 3) { getChunk.list[pool[peerID].curChunkID].fetchState = 0; pool[peerID].state = 0; newPacketWHOHAS(nonCongestQueue); freePacket(pkt); cleanUpConnDown(&(pool[peerID])); numConnDown--; } } break; } case 2: { break; } default: break; } } }
int mediafirefs_flush(const char *path, struct fuse_file_info *file_info) { printf("FUNCTION: flush. path: %s\n", path); FILE *fh; char *file_name; char *dir_name; const char *folder_key; char *upload_key; char *temp1; char *temp2; int retval; struct mediafirefs_context_private *ctx; struct mediafirefs_openfile *openfile; struct mfconn_upload_check_result check_result; unsigned char bhash[SHA256_DIGEST_LENGTH]; char *hash; uint64_t size; openfile = (struct mediafirefs_openfile *)(uintptr_t) file_info->fh; if (openfile->is_flushed) { return 0; } ctx = fuse_get_context()->private_data; // zero out check result to prevent spurious results later memset(&check_result,0,sizeof(check_result)); pthread_mutex_lock(&(ctx->mutex)); if (openfile->is_readonly) { /* nothing to do here */ pthread_mutex_unlock(&(ctx->mutex)); return 0; } // if the file only exists locally, an initial upload has to be done if (openfile->is_local) { // pass a copy because dirname and basename may modify their argument temp1 = strdup(openfile->path); file_name = basename(temp1); temp2 = strdup(openfile->path); dir_name = dirname(temp2); fh = fdopen(openfile->fd, "r"); rewind(fh); folder_key = folder_tree_path_get_key(ctx->tree, ctx->conn, dir_name); size = -1; retval = calc_sha256(fh, bhash, &size); rewind(fh); if (retval != 0) { fprintf(stderr, "failed to calculate hash\n"); free(temp1); free(temp2); pthread_mutex_unlock(&(ctx->mutex)); return -EACCES; } hash = binary2hex(bhash, SHA256_DIGEST_LENGTH); retval = mfconn_api_upload_check(ctx->conn, file_name, hash, size, folder_key, &check_result); if (retval != 0) { free(temp1); free(temp2); free(hash); fprintf(stderr, "mfconn_api_upload_check failed\n"); fprintf(stderr, "file_name: %s\n",file_name); fprintf(stderr, "hash: %s\n",hash); fprintf(stderr, "size: %jd\n",size); fprintf(stderr, "folder_key: %s\n",folder_key); pthread_mutex_unlock(&(ctx->mutex)); return -EACCES; } if (check_result.hash_exists) { // hash exists, so use upload/instant retval = mfconn_api_upload_instant(ctx->conn, file_name, hash, size, folder_key); free(temp1); free(temp2); free(hash); if (retval != 0) { fprintf(stderr, "mfconn_api_upload_instant failed\n"); pthread_mutex_unlock(&(ctx->mutex)); return -EACCES; } } else { // hash does not exist, so do full upload upload_key = NULL; retval = mfconn_api_upload_simple(ctx->conn, folder_key, fh, file_name, true, &upload_key); free(temp1); free(temp2); free(hash); if (retval != 0 || upload_key == NULL) { fprintf(stderr, "mfconn_api_upload_simple failed\n"); fprintf(stderr, "file_name: %s\n",file_name); fprintf(stderr, "hash: %s\n",hash); fprintf(stderr, "size: %jd\n",size); fprintf(stderr, "folder_key: %s\n",folder_key); pthread_mutex_unlock(&(ctx->mutex)); return -EACCES; } // poll for completion retval = mfconn_upload_poll_for_completion(ctx->conn, upload_key); free(upload_key); if (retval != 0) { fprintf(stderr, "mfconn_upload_poll_for_completion failed\n"); pthread_mutex_unlock(&(ctx->mutex)); return -1; } else { account_add_state_flags(ctx->account, ACCOUNT_FLAG_DIRTY_SIZE); } } folder_tree_update(ctx->tree, ctx->conn, true); openfile->is_flushed = true; pthread_mutex_unlock(&(ctx->mutex)); return 0; } // the file was not opened readonly and also existed on the remote // thus, we have to check whether any changes were made and if yes, upload // a patch retval = folder_tree_upload_patch(ctx->tree, ctx->conn, openfile->path); if (retval != 0) { fprintf(stderr, "folder_tree_upload_patch failed\n"); pthread_mutex_unlock(&(ctx->mutex)); return -EACCES; } else { account_add_state_flags(ctx->account, ACCOUNT_FLAG_DIRTY_SIZE); } folder_tree_update(ctx->tree, ctx->conn, true); openfile->is_flushed = true; pthread_mutex_unlock(&(ctx->mutex)); return 0; }