Example #1
0
/** Selects the appropriate piece to download and requests it to the remote_peer */
void Peer::requestNewPieceTo(Connection* remote_peer)
{
  int piece = selectPieceToDownload(remote_peer);
  if (piece != -1) {
    current_pieces |= (1U << (unsigned int)piece);
    sendRequestTo(remote_peer, piece);
  }
}
Example #2
0
/*!
  Send and encode a request to a specific receptor.
  
  \sa vpNetwork::sendRequest()
  \sa vpNetwork::sendAndEncodeRequest()
  \sa vpNetwork::sendAndEncodeRequestTo()
  \sa vpNetwork::send()
  \sa vpNetwork::sendTo()
  
  \param req : Request to send.
  \param dest : Index of the receptor receiving the request.
  
  \return The number of bytes that have been sent, -1 if an error occured.
*/
int vpNetwork::sendAndEncodeRequestTo(vpRequest &req, const unsigned int &dest)
{
  req.encode();
  return sendRequestTo(req,dest);
}
Example #3
0
void Peer::handleMessage()
{
  const char* type_names[10] = {"HANDSHAKE", "CHOKE",    "UNCHOKE", "INTERESTED", "NOTINTERESTED",
                                "HAVE",      "BITFIELD", "REQUEST", "PIECE",      "CANCEL"};

  XBT_DEBUG("Received a %s message from %s", type_names[message->type], message->return_mailbox->get_cname());

  auto known_peer         = connected_peers.find(message->peer_id);
  Connection* remote_peer = (known_peer == connected_peers.end()) ? nullptr : known_peer->second;
  xbt_assert(remote_peer != nullptr || message->type == MESSAGE_HANDSHAKE,
             "The impossible did happened: A not-in-our-list peer sent us a message.");

  switch (message->type) {
    case MESSAGE_HANDSHAKE:
      // Check if the peer is in our connection list.
      if (remote_peer == nullptr) {
        XBT_DEBUG("This peer %d was unknown, answer to its handshake", message->peer_id);
        connected_peers[message->peer_id] = new Connection(message->peer_id);
        sendMessage(message->return_mailbox, MESSAGE_HANDSHAKE, MESSAGE_HANDSHAKE_SIZE);
      }
      // Send our bitfield to the peer
      sendBitfield(message->return_mailbox);
      break;
    case MESSAGE_BITFIELD:
      // Update the pieces list
      updatePiecesCountFromBitfield(message->bitfield);
      // Store the bitfield
      remote_peer->bitfield = message->bitfield;
      xbt_assert(not remote_peer->am_interested, "Should not be interested at first");
      if (isInterestedBy(remote_peer)) {
        remote_peer->am_interested = true;
        sendMessage(message->return_mailbox, MESSAGE_INTERESTED, MESSAGE_INTERESTED_SIZE);
      }
      break;
    case MESSAGE_INTERESTED:
      // Update the interested state of the peer.
      remote_peer->interested = true;
      updateActivePeersSet(remote_peer);
      break;
    case MESSAGE_NOTINTERESTED:
      remote_peer->interested = false;
      updateActivePeersSet(remote_peer);
      break;
    case MESSAGE_UNCHOKE:
      xbt_assert(remote_peer->choked_download);
      remote_peer->choked_download = false;
      // Send requests to the peer, since it has unchoked us
      if (remote_peer->am_interested)
        requestNewPieceTo(remote_peer);
      break;
    case MESSAGE_CHOKE:
      xbt_assert(not remote_peer->choked_download);
      remote_peer->choked_download = true;
      if (remote_peer->current_piece != -1)
        removeCurrentPiece(remote_peer, remote_peer->current_piece);
      break;
    case MESSAGE_HAVE:
      XBT_DEBUG("\t for piece %d", message->piece);
      xbt_assert((message->piece >= 0 && static_cast<unsigned int>(message->piece) < FILE_PIECES),
                 "Wrong HAVE message received");
      remote_peer->bitfield = remote_peer->bitfield | (1U << static_cast<unsigned int>(message->piece));
      pieces_count[message->piece]++;
      // If the piece is in our pieces, we tell the peer that we are interested.
      if (not remote_peer->am_interested && hasNotPiece(message->piece)) {
        remote_peer->am_interested = true;
        sendMessage(message->return_mailbox, MESSAGE_INTERESTED, MESSAGE_INTERESTED_SIZE);
        if (not remote_peer->choked_download)
          requestNewPieceTo(remote_peer);
      }
      break;
    case MESSAGE_REQUEST:
      xbt_assert(remote_peer->interested);
      xbt_assert((message->piece >= 0 && static_cast<unsigned int>(message->piece) < FILE_PIECES),
                 "Wrong HAVE message received");
      if (not remote_peer->choked_upload) {
        XBT_DEBUG("\t for piece %d (%d,%d)", message->piece, message->block_index,
                  message->block_index + message->block_length);
        if (not hasNotPiece(message->piece)) {
          sendPiece(message->return_mailbox, message->piece, message->block_index, message->block_length);
        }
      } else {
        XBT_DEBUG("\t for piece %d but he is choked.", message->peer_id);
      }
      break;
    case MESSAGE_PIECE:
      XBT_DEBUG(" \t for piece %d (%d,%d)", message->piece, message->block_index,
                message->block_index + message->block_length);
      xbt_assert(not remote_peer->choked_download);
      xbt_assert(remote_peer->am_interested || ENABLE_END_GAME_MODE,
                 "Can't received a piece if I'm not interested without end-game mode!"
                 "piece (%d) bitfield (%u) remote bitfield (%u)",
                 message->piece, bitfield_, remote_peer->bitfield);
      xbt_assert(not remote_peer->choked_download, "Can't received a piece if I'm choked !");
      xbt_assert((message->piece >= 0 && static_cast<unsigned int>(message->piece) < FILE_PIECES),
                 "Wrong piece received");
      // TODO: Execute a computation.
      if (hasNotPiece(static_cast<unsigned int>(message->piece))) {
        updateBitfieldBlocks(message->piece, message->block_index, message->block_length);
        if (hasCompletedPiece(static_cast<unsigned int>(message->piece))) {
          // Removing the piece from our piece list
          removeCurrentPiece(remote_peer, message->piece);
          // Setting the fact that we have the piece
          bitfield_ = bitfield_ | (1U << static_cast<unsigned int>(message->piece));
          XBT_DEBUG("My status is now %s", getStatus().c_str());
          // Sending the information to all the peers we are connected to
          sendHaveToAllPeers(message->piece);
          // sending UNINTERESTED to peers that do not have what we want.
          updateInterestedAfterReceive();
        } else {                                      // piece not completed
          sendRequestTo(remote_peer, message->piece); // ask for the next block
        }
      } else {
        XBT_DEBUG("However, we already have it");
        xbt_assert(ENABLE_END_GAME_MODE, "Should not happen because we don't use end game mode !");
        requestNewPieceTo(remote_peer);
      }
      break;
    case MESSAGE_CANCEL:
      break;
    default:
      THROW_IMPOSSIBLE;
  }
  // Update the peer speed.
  if (remote_peer) {
    remote_peer->addSpeedValue(1.0 / (simgrid::s4u::Engine::get_clock() - begin_receive_time));
  }
  begin_receive_time = simgrid::s4u::Engine::get_clock();
}
Example #4
0
/*!
  Send a request to the first receptor in the list.
  
  \sa vpNetwork::sendRequestTo()
  \sa vpNetwork::sendAndEncodeRequest()
  \sa vpNetwork::sendAndEncodeRequestTo()
  \sa vpNetwork::send()
  \sa vpNetwork::sendTo()
  
  \param req : Request to send.
  
  \return The number of bytes that have been sent, -1 if an error occured.
*/
int vpNetwork::sendRequest(vpRequest &req)
{
  return sendRequestTo(req,0);
}