📄 pepeercontrolimpl.java
字号:
}
return;
}
// piece can be null when running a recheck on completion
final PEPieceImpl pePiece =pePieces[pieceNumber];
// the piece has been written correctly
if (outcome ==1)
{
if (pePiece !=null)
{
if (needsMD5CheckOnCompletion(pieceNumber))
MD5CheckPiece(pePiece, true);
List list =pePiece.getPieceWrites();
if (list.size() >0)
{
// For each Block
for (int i =0; i <pePiece.getNbBlocks(); i++ )
{
// System.out.println("Processing block " + i);
// Find out the correct hash
List listPerBlock =pePiece.getPieceWrites(i);
byte[] correctHash =null;
// PEPeer correctSender = null;
Iterator iterPerBlock =listPerBlock.iterator();
while (iterPerBlock.hasNext())
{
PEPieceWriteImpl write =(PEPieceWriteImpl) iterPerBlock.next();
if (write.isCorrect())
{
correctHash =write.getHash();
// correctSender = write.getSender();
}
}
// System.out.println("Correct Hash " + correctHash);
// If it's found
if (correctHash !=null)
{
iterPerBlock =listPerBlock.iterator();
while (iterPerBlock.hasNext())
{
PEPieceWriteImpl write =(PEPieceWriteImpl) iterPerBlock.next();
if (!Arrays.equals(write.getHash(), correctHash))
{
// Bad peer found here
badPeerDetected(write.getSender());
}
}
}
}
}
removePiece(pePiece, pieceNumber);
}
// send all clients a have message
sendHave(pieceNumber); //XXX: if Done isn't set yet, might refuse to send this piece
} else if (outcome ==0)
{
// the piece is corrupt
if (pePiece !=null)
{
MD5CheckPiece(pePiece, false);
String[] writers =pePiece.getWriters();
List uniqueWriters =new ArrayList();
int[] writesPerWriter =new int[writers.length];
for (int i =0; i <writers.length; i++ )
{
String writer =writers[i];
if (writer !=null)
{
int writerId =uniqueWriters.indexOf(writer);
if (writerId ==-1)
{
uniqueWriters.add(writer);
writerId =uniqueWriters.size() -1;
}
writesPerWriter[writerId]++ ;
}
}
int nbWriters =uniqueWriters.size();
if (nbWriters ==1)
{
// Very simple case, only 1 peer contributed for that piece,
// so, let's mark it as a bad peer
badPeerDetected((String)uniqueWriters.get(0));
// and let's reset the whole piece
pePiece.reset();
} else if (nbWriters >1)
{
int maxWrites =0;
String bestWriter =null;
for (int i =0; i <uniqueWriters.size(); i++ )
{
final int writes =writesPerWriter[i];
if (writes >maxWrites)
{
final String writer =(String) uniqueWriters.get(i);
final PEPeerTransport pt =getTransportFromAddress(writer);
if (pt !=null &&pt.getReservedPieceNumber() ==-1 &&!ip_filter.isInRange(writer, adapter.getDisplayName()))
{
bestWriter =writer;
maxWrites =writes;
}
}
}
if (bestWriter !=null)
{
pePiece.setReservedBy(bestWriter);
getTransportFromAddress(bestWriter).setReservedPieceNumber(pePiece.getPieceNumber());
pePiece.setRequestable();
for (int i =0; i <pePiece.getNbBlocks(); i++ )
{
// If the block was contributed by someone else
if (writers[i] ==null ||!writers[i].equals(bestWriter))
{
pePiece.reDownloadBlock(i);
}
}
} else
{
// In all cases, reset the piece
pePiece.reset();
}
} else
{
// In all cases, reset the piece
pePiece.reset();
}
// if we are in end-game mode, we need to re-add all the piece chunks
// to the list of chunks needing to be downloaded
piecePicker.addEndGameChunks(pePiece);
_stats.hashFailed(pePiece.getLength());
}
} else
{
// cancelled, download stopped
}
} finally
{
if (check_type ==CHECK_REASON_SCAN)
rescan_piece_time =SystemTime.getCurrentTime();
if (!seeding_mode)
checkFinished(false);
}
}
private void badPeerDetected(String ip)
{
final PEPeerTransport peer =getTransportFromAddress(ip);
// Debug.out("Bad Peer Detected: " + peerIP + " [" + peer.getClient() + "]");
final IpFilterManager filter_manager =IpFilterManagerFactory.getSingleton();
// Ban fist to avoid a fast reco of the bad peer
final int nbWarnings =filter_manager.getBadIps().addWarningForIp(ip);
// no need to reset the bad chunk count as the peer is going to be disconnected and
// if it comes back it'll start afresh
if (nbWarnings >WARNINGS_LIMIT)
{
if (COConfigurationManager.getBooleanParameter("Ip Filter Enable Banning"))
{
// if a block-ban occurred, check other connections
if (ip_filter.ban(ip, adapter.getDisplayName()))
{
checkForBannedConnections();
}
if (peer !=null)
{
int ps =peer.getPeerState();
// might have been through here very recently and already started closing
// the peer (due to multiple bad blocks being found from same peer when checking piece)
if (!(ps ==PEPeer.CLOSING ||ps ==PEPeer.DISCONNECTED))
{
// Close connection
closeAndRemovePeer(peer, "has sent too many bad pieces, " +WARNINGS_LIMIT +" max.", true);
}
// Trace the ban
if (Logger.isEnabled())
Logger.log(new LogEvent(peer, LOGID, LogEvent.LT_ERROR, ip +" : has been banned and won't be able "
+"to connect until you restart azureus"));
}
}
}
}
public PEPiece[] getPieces()
{
return pePieces;
}
public PEPiece getPiece(int pieceNumber)
{
return pePieces[pieceNumber];
}
public PEPeerStats
createPeerStats()
{
return( new PEPeerStatsImpl() );
}
public DiskManagerReadRequest
createDiskManagerRequest(
int pieceNumber,
int offset,
int length )
{
return( disk_mgr.createReadRequest( pieceNumber, offset, length ));
}
public void
addListener(
PEPeerManagerListener l )
{
try{
this_mon.enter();
//copy on write
ArrayList peer_manager_listeners = new ArrayList( peer_manager_listeners_cow.size() + 1 );
peer_manager_listeners.addAll( peer_manager_listeners_cow );
peer_manager_listeners.add( l );
peer_manager_listeners_cow = peer_manager_listeners;
}finally{
this_mon.exit();
}
}
public void
removeListener(
PEPeerManagerListener l )
{
try{
this_mon.enter();
//copy on write
ArrayList peer_manager_listeners = new ArrayList( peer_manager_listeners_cow );
peer_manager_listeners.remove( l );
peer_manager_listeners_cow = peer_manager_listeners;
}finally{
this_mon.exit();
}
}
public void
parameterChanged(
String parameterName)
{
disconnect_seeds_when_seeding = COConfigurationManager.getBooleanParameter("Disconnect Seed", true);
if ( parameterName.equals("Ip Filter Enabled")){
checkForBannedConnections();
}
}
protected void
checkForBannedConnections()
{
if ( ip_filter.isEnabled()){ //if ipfiltering is enabled, remove any existing filtered connections
ArrayList to_close = null;
ArrayList peer_transports = peer_transports_cow;
for (int i=0; i < peer_transports.size(); i++) {
PEPeerTransport conn = (PEPeerTransport)peer_transports.get( i );
if ( ip_filter.isInRange( conn.getIp(), adapter.getDisplayName() )) {
if( to_close == null ) to_close = new ArrayList();
to_close.add( conn );
}
}
if( to_close != null ) {
for( int i=0; i < to_close.size(); i++ ) {
closeAndRemovePeer( (PEPeerTransport)to_close.get(i), "IPFilter banned IP address", true );
}
}
}
}
public boolean isSuperSeedMode() {
return superSeedMode;
}
public boolean isInEndGameMode() {
return piecePicker.isInEndGameMode();
}
public void
setSuperSeedMode(
boolean _superSeedMode)
{
if (_superSeedMode && superSeedPieces == null ){
initialiseSuperSeedMode();
}
superSeedMode = _superSeedMode;
}
private void
initialiseSuperSeedMode()
{
superSeedPieces = new SuperSeedPiece[_nbPieces];
for(int i = 0 ; i < _nbPieces ; i++) {
superSeedPieces[i] = new SuperSeedPiece(this,i);
}
}
private void updatePeersInSuperSeedMode() {
if(!superSeedMode) {
return;
}
//Refresh the update time in case this is needed
for(int i = 0 ; i < superSeedPieces.length ; i++) {
superSeedPieces[i].updateTime();
}
//Use the same number of announces than unchoke
int nbUnchoke = adapter.getMaxUploads();
if(superSeedModeNumberOfAnnounces >= 2 * nbUnchoke)
return;
//Find an available Peer
PEPeer selectedPeer = null;
List sortedPeers = null;
ArrayList peer_transports = peer_transports_cow;
sortedPeers = new ArrayList(peer_transports.size());
Iterator iter =peer_transports.iterator();
while(iter.hasNext()) {
sortedPeers.add(new SuperSeedPeer((PEPeer)iter.next()));
}
Collections.sort(sortedPeers);
iter = sortedPeers.iterator();
while(iter.hasNext()) {
PEPeer peer = ((SuperSeedPeer)iter.next()).peer;
if((peer.getUniqueAnnounce() == -1) && (peer.getPeerState() == PEPeer.TRANSFERING)) {
selectedPeer = peer;
break;
}
}
if(selectedPeer == null ||selectedPeer.getPeerState() >=PEPeer.CLOSING)
return;
if(selectedPeer.getUploadHint() == 0) {
//Set to infinite
selectedPeer.setUploadHint(Constants.INFINITY_AS_INT);
}
//Find a piece
boolean found = false;
SuperSeedPiece piece = null;
while(!found) {
piece = superSeedPieces[superSeedModeCurrentPiece];
if(piece.getLevel() > 0) {
piece = null;
superSeedModeCurrentPiece++;
if(superSeedModeCurrentPiece >= _nbPieces) {
superSeedModeCurrentPiece = 0;
//quit superseed mode
superSeedMode = false;
closeAndRemoveAllPeers( "quiting SuperSeed mode", true );
return;
}
} else {
found = true;
}
}
if(piece == null) {
return;
}
//If this peer already has this piece, return (shouldn't happen)
if(selectedPeer.isPieceAvailable(piece.getPieceNumber())) {
return;
}
selectedPeer.setUniqueAnnounce(piece.getPieceNumber());
superSeedModeNumberOfAnnounces++;
piece.pieceRevealedToPeer();
((PEPeerTransport)selectedPeer).sendHave(piece.getPieceNumber());
}
public void updateSuperSeedPiece(PEPeer peer,int pieceNumber) {
if (!superSeedMode)
return;
superSeedPieces[pieceNumber].peerHasPiece(null);
if(peer.getUniqueAnnounce() == pieceNumber)
{
peer.setUniqueAnnounce(-1);
superSeedModeNumberOfAnnounces--;
}
}
public boolean
isAZMessagingEnabled()
{
return( adapter.isAZMessagingEnabled());
}
public boolean
isPeerExchangeEnabled()
{
return( adapter.isPeerExchangeEnabled());
}
public LimitedRateGroup getUploadLimitedRateGroup() { return upload_limited_rate_group; }
public LimitedRateGroup getDownloadLimitedRateGroup() { return download_limited_rate_group; }
/** To retreive arbitrary objects against this object. */
public Object
getData(
String key)
{
try{
this_mon.enter();
if (user_data == null) return null;
return user_data.get(key);
}finally{
this_mon.exit();
}
}
/** To store arbitrary objects against
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -