Пример #1
0
  void bitfieldMessage(byte[] bitmap) {
    synchronized (this) {
      if (_log.shouldLog(Log.DEBUG)) _log.debug(peer + " rcv bitfield");
      if (bitfield != null) {
        // XXX - Be liberal in what you accept?
        if (_log.shouldLog(Log.WARN)) _log.warn("Got unexpected bitfield message from " + peer);
        return;
      }

      // XXX - Check for weird bitfield and disconnect?
      // FIXME will have to regenerate the bitfield after we know exactly
      // how many pieces there are, as we don't know how many spare bits there are.
      if (metainfo == null) bitfield = new BitField(bitmap, bitmap.length * 8);
      else bitfield = new BitField(bitmap, metainfo.getPieces());
    }
    if (metainfo == null) return;
    boolean interest = listener.gotBitField(peer, bitfield);
    setInteresting(interest);
    if (bitfield.complete() && !interest) {
      // They are seeding and we are seeding,
      // why did they contact us? (robert)
      // Dump them quick before we send our whole bitmap
      if (_log.shouldLog(Log.WARN)) _log.warn("Disconnecting seed that connects to seeds: " + peer);
      peer.disconnect(true);
    }
  }
Пример #2
0
 /**
  * Switch from magnet mode to normal mode. If we already have the metainfo, this does nothing.
  *
  * @param meta non-null
  * @since 0.8.4
  */
 public void setMetaInfo(MetaInfo meta) {
   if (metainfo != null) return;
   BitField oldBF = bitfield;
   if (oldBF != null) {
     if (oldBF.size() != meta.getPieces())
       // fix bitfield, it was too big by 1-7 bits
       bitfield = new BitField(oldBF.getFieldBytes(), meta.getPieces());
     // else no extra
   } else {
     // it will be initialized later
     // bitfield = new BitField(meta.getPieces());
   }
   metainfo = meta;
   if (bitfield != null && bitfield.count() > 0) setInteresting(true);
 }
Пример #3
0
  void haveMessage(int piece) {
    if (_log.shouldLog(Log.DEBUG)) _log.debug(peer + " rcv have(" + piece + ")");
    // FIXME we will lose these until we get the metainfo
    if (metainfo == null) return;
    // Sanity check
    if (piece < 0 || piece >= metainfo.getPieces()) {
      // XXX disconnect?
      if (_log.shouldLog(Log.WARN))
        _log.warn("Got strange 'have: " + piece + "' message from " + peer);
      return;
    }

    synchronized (this) {
      // Can happen if the other side never send a bitfield message.
      if (bitfield == null) bitfield = new BitField(metainfo.getPieces());

      bitfield.set(piece);
    }

    if (listener.gotHave(peer, piece)) setInteresting(true);
  }
Пример #4
0
 /**
  * Sets whether or not we are interested in pieces from this peer. Defaults to false. When
  * interest is true and this peer unchokes us then we start downloading from it. Has no effect
  * when not connected.
  *
  * @deprecated unused
  */
 public void setInteresting(boolean interest) {
   PeerState s = state;
   if (s != null) s.setInteresting(interest);
 }
Пример #5
0
  /**
   * Adds a new request to the outstanding requests list. Then send interested if we weren't. Then
   * send new requests if not choked. If nothing to request, send not interested if we were.
   *
   * <p>This is called from several places:
   *
   * <pre>
   *   By getOustandingRequest() when the first part of a chunk comes in
   *   By havePiece() when somebody got a new piece completed
   *   By chokeMessage() when we receive an unchoke
   *   By setInteresting() when we are now interested
   *   By PeerCoordinator.updatePiecePriorities()
   * </pre>
   */
  synchronized void addRequest() {
    // no bitfield yet? nothing to request then.
    if (bitfield == null) return;
    if (metainfo == null) return;
    boolean more_pieces = true;
    while (more_pieces) {
      more_pieces = outstandingRequests.size() < MAX_PIPELINE;
      // We want something and we don't have outstanding requests?
      if (more_pieces && lastRequest == null) {
        // we have nothing in the queue right now
        if (!interesting) {
          // If we need something, set interesting but delay pulling
          // a request from the PeerCoordinator until unchoked.
          if (listener.needPiece(this.peer, bitfield)) {
            setInteresting(true);
            if (_log.shouldLog(Log.DEBUG))
              _log.debug(
                  peer
                      + " addRequest() we need something, setting interesting, delaying requestNextPiece()");
          } else {
            if (_log.shouldLog(Log.DEBUG)) _log.debug(peer + " addRequest() needs nothing");
          }
          return;
        }
        if (choked) {
          // If choked, delay pulling
          // a request from the PeerCoordinator until unchoked.
          if (_log.shouldLog(Log.DEBUG))
            _log.debug(peer + " addRequest() we are choked, delaying requestNextPiece()");
          return;
        }
        // huh? rv unused
        more_pieces = requestNextPiece();
      } else if (more_pieces) // We want something
      {
        int pieceLength;
        boolean isLastChunk;
        pieceLength = metainfo.getPieceLength(lastRequest.getPiece());
        isLastChunk = lastRequest.off + lastRequest.len == pieceLength;

        // Last part of a piece?
        if (isLastChunk) more_pieces = requestNextPiece();
        else {
          PartialPiece nextPiece = lastRequest.getPartialPiece();
          int nextBegin = lastRequest.off + PARTSIZE;
          int maxLength = pieceLength - nextBegin;
          int nextLength = maxLength > PARTSIZE ? PARTSIZE : maxLength;
          Request req = new Request(nextPiece, nextBegin, nextLength);
          outstandingRequests.add(req);
          if (!choked) out.sendRequest(req);
          lastRequest = req;
        }
      }
    }

    // failsafe
    // However this is bad as it thrashes the peer when we change our mind
    // Ticket 691 cause here?
    if (interesting && lastRequest == null && outstandingRequests.isEmpty()) setInteresting(false);

    if (_log.shouldLog(Log.DEBUG)) _log.debug(peer + " requests " + outstandingRequests);
  }