/** * Unlike accessing the peer database, this only returns currently * connected peers and includes data not yet saved in the peer db. */ fc::vector<db::peer::record> node::active_peers()const { if( !my->_thread.is_current() ) { return my->_thread.async( [this](){ return active_peers(); } ).wait(); } fc::vector<db::peer::record> recs(my->_dist_to_con.size()); auto itr = my->_dist_to_con.begin(); auto end = my->_dist_to_con.end(); int i = 0; while( itr != end ) { recs[i] = itr->second->get_db_record(); ++i; ++itr; } return recs; }
void* draw_state() { printf("\033[2J\033[1;1H"); int pieces = file_length/piece_length+1; printf("%d byte file, %d byte pieces, %d pieces, %d active, %d choked\n", file_length,piece_length,file_length/piece_length+1,active_peers(),choked_peers()); for(int i=0;i<pieces;i++) { if(i%80 == 0) printf("\n"); switch(piece_status[i]) { case PIECE_EMPTY: printf("."); break; case PIECE_PENDING: printf("x"); break; case PIECE_FINISHED: printf("X"); break; default: printf("?"); } } fflush(stdout); }
void listen_from_peers() { struct peer_state* peer = peers; unsigned int msglen = 0; while(missing_blocks() > 0) { fd_set fdrset_clone; fd_set fdwset_clone; FD_COPY(&fdrset,&fdrset_clone); FD_COPY(&fdwset,&fdwset_clone); int rdy = select(FD_SETSIZE,&fdrset_clone,&fdwset_clone,0, 0); if(rdy <= 0) { continue; } peer = peers; if(active_peers() == 0){ break; } while(peer){ if(FD_ISSET(peer->socket,&fdwset_clone)){ if(peer->connected == 0){ //to send the handshake if it is not connected send_handshake(peer); } else if(peer->send_count > 0) { //to send the have/interested/piece messages to peers send_buffed_msg(peer); } } if(FD_ISSET(peer->socket,&fdrset_clone)) { int newbytes = recv(peer->socket,peer->incoming+peer->count,BUFSIZE-peer->count,0); if(newbytes <= 0){ peer->trying_to_connect = 0; if(newbytes == 0){ piece_status[peer->requested_piece] = PIECE_EMPTY; } disconnet_peer(peer); reconnect_peer(peer); peer = peer->next; continue; } peer->count += newbytes; if(!peer->handshaked){ peer->count -= peer->incoming[0]+49; if(peer->count) { memmove(peer->incoming,peer->incoming + peer->incoming[0]+49,peer->count); } peer->handshaked = 1; } if(memcmp(peer->incoming+peer->incoming[0]+8+20,"-UICCS450-",strlen("-UICCS450-"))==0) { fprintf(stderr,"Caught a CS450 peer, exiting.\n"); disconnet_peer(peer); continue; } while(peer->count >= (ntohl(((int*)peer->incoming)[0])) + 4){ msglen = ntohl(((int*)peer->incoming)[0]); switch(peer->incoming[4]) { // CHOKE case 0: { if(debug) fprintf(stderr,"Choke\n"); peer->choked = 1; piece_status[peer->requested_piece]=PIECE_EMPTY; peer->requested_piece = -1; break; } // UNCHOKE case 1: { if(debug) fprintf(stderr,"Unchoke\n"); peer->choked = 0; peer->requested_piece = next_piece(-1,peer); request_block(peer,peer->requested_piece,0); break; } //Interested case 2: { //dev_notifier(); send_choke_unchoke_msg(peer,0); //ischoked = 0 peer->not_interested = 0; break; } //Not interested case 3: { //dev_notifier(); peer->not_interested = 1; break; } // HAVE -- update the bitfield for this peer case 4: { int piece = ntohl(*((int*)&peer->incoming[5])); int bitfield_byte = piece/8; int bitfield_bit = piece%8; if(debug) fprintf(stderr,"Have %d\n",piece); peer->bitfield[bitfield_byte] |= 1 << (7 - bitfield_bit); piece_occurence_value[piece]++; send_interested(peer); break; } // BITFIELD -- set the bitfield for this peer case 5: //peer->choked = 0; //commenting it according to prof's note in class if(debug) printf("Bitfield of length %d\n",msglen-1); int fieldlen = msglen - 1; if(fieldlen != (file_length/piece_length/8+1)) { disconnet_peer(peer); if(active_peers() == 0){ break; } peer = peer->next; continue; } memcpy(peer->bitfield,peer->incoming+5,fieldlen); read_bit_maps(peer->bitfield,fieldlen); send_interested(peer); break; //Request piece case 6: { if(peer->i_choked_it == 1) break; decode_request_send_piece_to_peer(peer); } break; // PIECE case 7: { //make the tit for tatter peer->send_recv_balancer++; if(peer->i_choked_it && peer->send_recv_balancer == 0){ peer->i_choked_it = 0; send_choke_unchoke_msg(peer,0); //unchoke peer } int piece = ntohl(*((int*)&peer->incoming[5])); int offset = ntohl(*((int*)&peer->incoming[9])); int datalen = msglen - 9; fprintf(stderr,"Writing piece %d, offset %d, ending at %d\n",piece,offset,piece*piece_length+offset+datalen); write_block(peer->incoming+13,piece,offset,datalen,1); draw_state(); offset+=datalen; if(offset==piece_length || (piece*piece_length+offset == file_length) ) { broadcast_have_msg(piece); draw_state(); if(debug) fprintf(stderr,"Reached end of piece %d at offset %d\n",piece,offset); peer->requested_piece=next_piece(piece,peer); offset = 0; } request_block(peer,peer->requested_piece,offset); break; } } drop_message(peer); } } peer = peer->next; } } return; }