예제 #1
0
 public void signalBlockComplete(int blockNumber) throws IOException {
   signalBlockCompleteCounter++;
   if (signalBlockCompleteCounter > SEND_BLOCKMASK_UPDATE_INTERVAL_IN_BLOCKS) {
     signalBlockCompleteCounter = 0;
     BlockFile bf = storage.getBlockFile(fd.getRootHash());
     if (bf == null) {
       return;
     }
     List<Friend> list = manager.getFriendsInterestedIn(root);
     if (list != null) {
       for (Friend f : list) {
         FriendConnection fc = f.getFriendConnection();
         if (fc != null) {
           if (T.t) {
             T.info(
                 "Friend "
                     + f
                     + " is interested in file "
                     + root
                     + ". Sending updated block mask to him.");
           }
           fc.send(new BlockMaskResult(root, bf.getBlockMask()));
         }
       }
     }
   }
 }
예제 #2
0
 private void forcesslhandshake() throws IOException {
   for (Friend f : manager.friends()) {
     if (f.getFriendConnection() != null) {
       printer.println("Starting SSL handshake for " + f);
       ((SSLCryptoLayer) core.getCryptoManager().getCryptoLayer())
           .resendHandshake(f.getFriendConnection());
     }
   }
 }
예제 #3
0
 private void connect(String nickname) throws IOException {
   printer.println("Connecting to " + nickname + "...");
   Friend f = manager.getFriend(nickname);
   manager
       .getNetMan()
       .connect(
           f.getLastKnownHost(),
           f.getLastKnownPort(),
           new FriendConnection(manager.getNetMan(), Connection.Direction.OUT, f.getGuid()));
 }
예제 #4
0
 private void list() {
   printer.println("Friends: ");
   for (Friend f : manager.friends()) {
     printer.println(
         "  "
             + f.getNickname()
             + " "
             + (f.getFriendConnection() == null
                 ? "disconnected"
                 : f.getFriendConnection().getSocketAddress()));
   }
 }
예제 #5
0
 public void route(int dstGuid, RPC rpc) throws IOException {
   Friend f = netMan.getFriendManager().getFriend(dstGuid);
   if (f != null && f.getFriendConnection() != null) {
     if (T.t) {
       T.info("Rerouting package to friend");
     }
     f.getFriendConnection().send(rpc);
   } else {
     // note that one of our friends COULD actually be a closer Route to the destination. But this
     // way we send
     // the rpc the same way back as be got it. No biggie probably.
     rpc.init(this);
     Packet p = createRPCPacket(rpc);
     send(new Route(netMan.getFriendManager().getMyGUID(), dstGuid, p));
   }
 }
예제 #6
0
  public int selectBestBlockForDownload(Friend remoteFriend) throws IOException {
    if (T.t) {
      T.debug("Selecting best block for download. Remote: " + remoteFriend);
    }
    BlockMask bm = blockMasks.get(remoteFriend.getGuid());
    if (bm == null) {
      if (T.t) {
        T.info("Ehh. Don't know anything about this friends block mask. Can't download.");
      }
      return -1;
    }

    BitSet interestingBlocks = getInterestingBlocks(bm);

    // remove bocks in progress from interesting blocks:
    BlockFile bf = storage.getBlockFile(root);
    BitSet blocksInProgress = bf == null ? new BitSet() : bf.getBlocksInProgress();
    blocksInProgress.flip(0, fd.getNumberOfBlocks());
    blocksInProgress.and(interestingBlocks);

    if (blocksInProgress.cardinality() > 0) {
      // there are blocks of interest that are NOT in progress. Take one of these
      interestingBlocks = blocksInProgress;
    } // else there are only blocks in progress. Use any of them

    int highestBlockNumber = 0;
    if (bf != null) {
      highestBlockNumber = bf.getHighestCompleteBlock();
    }
    highestBlockNumber += manager.getCore().getSettings().getInternal().getMaxfileexpandinblocks();
    // we prefer to load blocks below highestBlockNumber
    if (interestingBlocks.nextSetBit(0) < highestBlockNumber) {
      // we're good - there are interesting blocks below the highest block number.

      // remove all blocks above highest block number:
      if (highestBlockNumber + 1 < fd.getNumberOfBlocks()) {
        interestingBlocks.clear(highestBlockNumber + 1, fd.getNumberOfBlocks());
      }
    }

    // select a random block of the ones we're interested in - change this to rarest first in the
    // future
    int c = interestingBlocks.cardinality();
    int n = (int) (Math.random() * c);
    for (int i = interestingBlocks.nextSetBit(0), j = 0;
        i >= 0;
        i = interestingBlocks.nextSetBit(i + 1), j++) {
      if (j == n) {
        return i;
      }
    }

    if (T.t) {
      T.trace("Can't find any block to download from " + remoteFriend);
    }
    return -1;
  }
예제 #7
0
  @Override
  public void execute(Packet in) throws IOException {
    Friend f = con.getRemoteFriend();
    if (f == null) {
      // this can happen when a friend is removed using the UI. Just blow this connection away.
      con.close();
      return;
    }
    boolean guidMismatch = false;
    int remoteGUID = in.readInt();
    if (remoteGUID != f.getGuid()) {
      if (T.t) {
        T.warn("GUID mismatch!!! Closing connection.");
      }
      //            f.setGuid(remoteGUID);
      guidMismatch = true;
    }

    int port = in.readInt();
    f.updateLastKnownHostInfo(
        manager.getNetMan().getSocketFor(con).getInetAddress().getHostAddress(), port);
    f.setShareSize(in.readLong());
    int buildNumber = in.readInt();
    f.setAllianceBuildNumber(buildNumber);

    if (CoreSubsystem.ALLOW_TO_SEND_UPGRADE_TO_FRIENDS) {
      if (buildNumber < Version.BUILD_NUMBER && buildNumber > 1120) {
        // remote has old version
        Hash h = core.getFileManager().getAutomaticUpgrade().getMyJarHash();
        if (h != null) {
          send(new NewVersionAvailable(h));
        }
      }
    }

    // now that we have a good connection to friend: verify that we only have ONE connection
    if (con.getRemoteFriend().hasMultipleFriendConnections()) {
      if (T.t) {
        T.trace(
            "Has multple connections to a friend. Figuring out wich one of us should close the connection");
      }
      if ((con.getDirection() == Connection.Direction.IN
              && con.getRemoteUserGUID() > manager.getMyGUID())
          || (con.getDirection() == Connection.Direction.OUT
              && manager.getMyGUID() > con.getRemoteUserGUID())) {
        // serveral connections. Its up to us to close one
        if (T.t) {
          T.info("Already connected to " + con.getRemoteFriend() + ". Closing connection");
        }
        send(new GracefulClose(GracefulClose.DUPLICATE_CONNECTION));
        // con.close();
        // close connection when we in turn receive a graceful close
      }
    }
    if (guidMismatch) {
      send(new GracefulClose(GracefulClose.GUID_MISMATCH));
    } else {
      // this is the place for an event: "FriendSuccessfullyConnected".
      core.getNetworkManager().signalFriendConnected(con.getRemoteFriend());

      core.getUICallback().nodeOrSubnodesUpdated(con.getRemoteFriend());
    }
  }
예제 #8
0
  @Override
  public void execute(Packet in) throws IOException {
    Friend f = con.getRemoteFriend();

    boolean guidMismatch = false;
    int remoteGUID = in.readInt();
    if (remoteGUID != f.getGuid()) {
      if (T.t) {
        T.warn("GUID mismatch!!! Closing connection.");
      }
      //            f.setGuid(remoteGUID);
      guidMismatch = true;
    }

    int port = in.readInt();
    f.updateLastKnownHostInfo(
        manager.getNetMan().getSocketFor(con).getInetAddress().getHostAddress(), port);
    f.setShareSize(in.readLong());
    int buildNumber = in.readInt();
    f.setAllianceBuildNumber(buildNumber);
    f.setTotalBytesReceived(in.readLong());
    f.setTotalBytesSent(in.readLong());
    f.setHighestIncomingCPS(in.readInt());
    f.setHighestOutgoingCPS(in.readInt());
    f.setNumberOfFilesShared(in.readInt());
    f.setNumberOfInvitedFriends(in.readInt());
    try {
      String dnsName = in.readUTF();
      if (!dnsName.trim().isEmpty()) {
        f.updateLastKnownHostInfo(dnsName, port);
      }
    } catch (BufferUnderflowException ex) {
    }

    if (CoreSubsystem.ALLOW_TO_SEND_UPGRADE_TO_FRIENDS) {
      if (buildNumber < Version.BUILD_NUMBER && buildNumber > 1120) {
        // remote has old version
        Hash h = core.getFileManager().getAutomaticUpgrade().getMyJarHash();
        if (h != null) {
          send(new NewVersionAvailable(h));
        }
      }
    }

    // now that we have a good connection to friend: verify that we only have ONE connection
    if (con.getRemoteFriend().hasMultipleFriendConnections()) {
      if (T.t) {
        T.trace(
            "Has multple connections to a friend. Figuring out wich one of us should close the connection");
      }
      if ((con.getDirection() == Connection.Direction.IN
              && con.getRemoteUserGUID() > manager.getMyGUID())
          || (con.getDirection() == Connection.Direction.OUT
              && manager.getMyGUID() > con.getRemoteUserGUID())) {
        // serveral connections. Its up to us to close one
        if (T.t) {
          T.info("Already connected to " + con.getRemoteFriend() + ". Closing connection");
        }
        send(new GracefulClose(GracefulClose.DUPLICATE_CONNECTION));
        // con.close();
        // close connection when we in turn receive a graceful close
      }
    }
    if (guidMismatch) {
      send(new GracefulClose(GracefulClose.GUID_MISMATCH));
    } else {
      // this is the place for an event: "FriendSuccessfullyConnected".
      core.getNetworkManager().signalFriendConnected(con.getRemoteFriend());
      core.getUICallback().nodeOrSubnodesUpdated(con.getRemoteFriend());
      core.updateLastSeenOnlineFor(con.getRemoteFriend());
      System.setProperty("alliance.network.friendsonline", "" + manager.getNFriendsConnected());
    }
  }
예제 #9
0
 private void remotedir(int sharebaseIndex, String user, String path) throws IOException {
   Friend f = manager.getFriend(user);
   printer.println("Found friend: " + f + " for " + user);
   f.getFriendConnection().send(new GetDirectoryListing(sharebaseIndex, path));
 }
예제 #10
0
 private void remotesharebases(String s) throws IOException {
   Friend f = manager.getFriend(s);
   f.getFriendConnection().send(new GetShareBaseList());
 }
예제 #11
0
 private void showbuilds() {
   for (Friend f : core.getFriendManager().friends()) {
     printer.println(
         f.getAllianceBuildNumber() + ": " + core.getFriendManager().nickname(f.getGuid()));
   }
 }