Exemple #1
0
 /**
  *  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;
 }
Exemple #2
0
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);
}
Exemple #3
0
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;
}