📄 pepeertransportprotocol.java
字号:
other_peer_uninterested_version = 1;
other_peer_request_version = 1;
other_peer_bt_lt_ext_version = 1;
other_peer_az_request_hint_version = 1;
other_peer_az_bad_piece_version = 1;
ut_pex_enabled = false;
ml_dht_enabled = false;
closing_mon = new AEMonitor("PEPeerTransportProtocol:closing");
general_mon = new AEMonitor("PEPeerTransportProtocol:data");
handshake_reserved_bytes = null;
has_received_initial_pex = false;
peer_listeners_mon = new AEMonitor("PEPeerTransportProtocol:PL");
is_optimistic_unchoke = false;
peer_exchange_item = null;
peer_exchange_supported = false;
manager = _manager;
diskManager = manager.getDiskManager();
piecePicker = manager.getPiecePicker();
nbPieces = diskManager.getNbPieces();
lastNeededUndonePieceChange = 0x8000000000000000L;
peer_source = _peer_source;
ip = _ip;
port = _tcp_port;
tcp_listen_port = _tcp_port;
udp_listen_port = _udp_port;
crypto_level = _crypto_level;
data = _initial_user_data;
if (data != null)
{
Boolean pc = (Boolean)data.get(Peer.PR_PRIORITY_CONNECTION);
if (pc != null && pc.booleanValue())
setPriorityConnection(true);
}
udp_non_data_port = UDPNetworkManager.getSingleton().getUDPNonDataListeningPortNumber();
peer_item_identity = PeerItemFactory.createPeerItem(ip, tcp_listen_port, PeerItem.convertSourceID(_peer_source), (byte)0, _udp_port, crypto_level, 0);
incoming = false;
peer_stats = manager.createPeerStats(this);
if (port < 0 || port > 65535)
{
closeConnectionInternally((new StringBuilder()).append("given remote port is invalid: ").append(port).toString());
return;
}
boolean use_crypto = _require_crypto_handshake || NetworkManager.getCryptoRequired(manager.getAdapter().getCryptoLevel());
if (isLANLocal())
use_crypto = false;
InetSocketAddress endpoint_address;
ProtocolEndpoint pe;
if (_use_tcp)
{
endpoint_address = new InetSocketAddress(ip, tcp_listen_port);
pe = new ProtocolEndpointTCP(endpoint_address);
} else
{
endpoint_address = new InetSocketAddress(ip, udp_listen_port);
pe = new ProtocolEndpointUDP(endpoint_address);
}
ConnectionEndpoint connection_endpoint = new ConnectionEndpoint(endpoint_address);
connection_endpoint.addProtocol(pe);
connection = NetworkManager.getSingleton().createConnection(connection_endpoint, new BTMessageEncoder(), new BTMessageDecoder(), use_crypto, !_require_crypto_handshake, manager.getSecrets(_crypto_level));
plugin_connection = new ConnectionImpl(connection, incoming);
changePeerState(10);
ByteBuffer initial_outbound_data = null;
if (use_crypto)
{
BTHandshake handshake = new BTHandshake(manager.getHash(), manager.getPeerId(), manager.isExtendedMessagingEnabled(), other_peer_handshake_version);
if (Logger.isEnabled())
Logger.log(new LogEvent(this, LOGID, (new StringBuilder()).append("Sending encrypted handshake with reserved bytes: ").append(ByteFormatter.nicePrint(handshake.getReserved(), false)).toString()));
DirectByteBuffer ddbs[] = handshake.getRawData();
int handshake_len = 0;
for (int i = 0; i < ddbs.length; i++)
handshake_len += ddbs[i].remaining((byte)9);
initial_outbound_data = ByteBuffer.allocate(handshake_len);
for (int i = 0; i < ddbs.length; i++)
{
DirectByteBuffer ddb = ddbs[i];
initial_outbound_data.put(ddb.getBuffer((byte)9));
ddb.returnToPool();
}
initial_outbound_data.flip();
handshake_sent = true;
}
int priority;
if (manager.isSeeding())
priority = 4;
else
if (manager.isRTA())
{
if (PeerClassifier.isAzureusIP(ip))
priority = 0;
else
priority = 1;
} else
if (PeerClassifier.isAzureusIP(ip))
priority = 1;
else
priority = 3;
if (peer_source == "Plugin" && priority > 2)
priority = 2;
connection.connect(initial_outbound_data, priority, new com.aelitis.azureus.core.networkmanager.NetworkConnection.ConnectionListener() {
private boolean connect_ok;
final PEPeerTransportProtocol this$0;
public final void connectStarted()
{
connection_state = 1;
}
public final void connectSuccess(ByteBuffer remaining_initial_data)
{
connect_ok = true;
if (closing)
return;
generateSessionId();
if (Logger.isEnabled())
Logger.log(new LogEvent(PEPeerTransportProtocol.this, PEPeerTransportProtocol.LOGID, "Out: Established outgoing connection"));
initializeConnection();
if (remaining_initial_data != null && remaining_initial_data.remaining() > 0)
connection.getOutgoingMessageQueue().addMessage(new BTRawMessage(new DirectByteBuffer(remaining_initial_data)), false);
sendBTHandshake();
}
public final void connectFailure(Throwable failure_msg)
{
closeConnectionInternally((new StringBuilder()).append("failed to establish outgoing connection: ").append(failure_msg.getMessage()).toString(), true, true);
}
public final void exceptionThrown(Throwable error)
{
if (error.getMessage() == null)
Debug.out("error.getMessage() == null", error);
closeConnectionInternally((new StringBuilder()).append("connection exception: ").append(error.getMessage()).toString(), !connect_ok, true);
}
public String getDescription()
{
return getString();
}
{
this$0 = PEPeerTransportProtocol.this;
super();
}
});
if (Logger.isEnabled())
Logger.log(new LogEvent(this, LOGID, "Out: Creating outgoing connection"));
}
protected void initializeConnection()
{
if (closing)
{
return;
} else
{
recent_outgoing_requests = new LinkedHashMap(16, 0.75F, true) {
final PEPeerTransportProtocol this$0;
public final boolean removeEldestEntry(java.util.Map.Entry eldest)
{
return size() > 16;
}
{
this$0 = PEPeerTransportProtocol.this;
super(x0, x1, x2);
}
};
recent_outgoing_requests_mon = new AEMonitor("PEPeerTransportProtocol:ROR");
message_limiter = new PeerMessageLimiter();
outgoing_have_message_aggregator = new OutgoingBTHaveMessageAggregator(connection.getOutgoingMessageQueue(), other_peer_bt_have_version, other_peer_az_have_version);
connection_established_time = SystemTime.getCurrentTime();
connection_state = 2;
changePeerState(20);
registerForMessageHandling();
return;
}
}
public String getPeerSource()
{
return peer_source;
}
protected void closeConnectionInternally(String reason, boolean connect_failed, boolean network_failure)
{
performClose(reason, connect_failed, false, network_failure);
}
protected void closeConnectionInternally(String reason)
{
performClose(reason, false, false, false);
}
public void closeConnection(String reason)
{
performClose(reason, false, true, false);
}
private void performClose(String reason, boolean connect_failed, boolean externally_closed, boolean network_failure)
{
closing_mon.enter();
if (closing)
{
closing_mon.exit();
return;
}
closing = true;
interested_in_other_peer = false;
lastNeededUndonePieceChange = 0x7fffffffffffffffL;
if (isSnubbed())
manager.decNbPeersSnubbed();
if (identityAdded)
{
if (peer_id != null)
PeerIdentityManager.removeIdentity(manager.getPeerIdentityDataID(), peer_id, getPort());
else
Debug.out("PeerIdentity added but peer_id == null !!!");
identityAdded = false;
}
changePeerState(40);
closing_mon.exit();
break MISSING_BLOCK_LABEL_130;
Exception exception;
exception;
closing_mon.exit();
throw exception;
cancelRequests();
if (outgoing_have_message_aggregator != null)
outgoing_have_message_aggregator.destroy();
if (peer_exchange_item != null)
peer_exchange_item.destroy();
if (outgoing_piece_message_handler != null)
outgoing_piece_message_handler.destroy();
if (connection != null)
connection.close();
if (ip_resolver_request != null)
ip_resolver_request.cancel();
removeAvailability();
changePeerState(50);
if (Logger.isEnabled())
Logger.log(new LogEvent(this, LOGID, (new StringBuilder()).append("Peer connection closed: ").append(reason).toString()));
if (!externally_closed)
manager.peerConnectionClosed(this, connect_failed, network_failure);
setPriorityConnection(false);
outgoing_have_message_aggregator = null;
peer_exchange_item = null;
outgoing_piece_message_handler = null;
plugin_connection = null;
if (peer_stats.getTotalDataBytesReceived() > 0L || peer_stats.getTotalDataBytesSent() > 0L || SystemTime.getCurrentTime() - connection_established_time > 30000L)
recentlyDisconnected.put(mySessionID, this);
return;
}
public PEPeerTransport reconnect(boolean tryUDP)
{
boolean use_tcp = isTCP() && (!tryUDP || getUDPListenPort() <= 0);
if (use_tcp && getTCPListenPort() > 0 || !use_tcp && getUDPListenPort() > 0)
{
boolean use_crypto = getPeerItemIdentity().getHandshakeType() == 1;
PEPeerTransport new_conn = PEPeerTransportFactory.createTransport(manager, getPeerSource(), getIp(), getTCPListenPort(), getUDPListenPort(), use_tcp, use_crypto, crypto_level, null);
Logger.log(new LogEvent(new Object[] {
this, new_conn
}, LOGID, "attempting to reconnect, creating new connection"));
if (new_conn instanceof PEPeerTransportProtocol)
{
PEPeerTransportProtocol pt = (PEPeerTransportProtocol)new_conn;
pt.checkForReconnect(mySessionID);
}
manager.addPeer(new_conn);
return new_conn;
} else
{
return null;
}
}
public boolean isSafeForReconnect()
{
return allowReconnect;
}
private void checkForReconnect(HashWrapper oldID)
{
PEPeerTransportProtocol oldTransport = recentlyDisconnected.remove(oldID);
if (oldTransport != null)
{
Logger.log(new LogEvent(this, LOGID, 0, (new StringBuilder()).append("reassociating stats from ").append(oldTransport).append(" with this connection").toString()));
peerSessionID = oldTransport.peerSessionID;
peer_stats = oldTransport.peer_stats;
peer_stats.setPeer(this);
unchokedTimeTotal += oldTransport.unchokedTimeTotal;
unchokedTime += oldTransport.unchokedTime;
setSnubbed(oldTransport.isSnubbed());
snubbed = oldTransport.snubbed;
last_good_data_time = oldTransport.last_good_data_time;
}
}
private void generateSessionId()
{
SHA1Hasher sha1 = new SHA1Hasher();
sha1.update(sessionSecret);
sha1.update(manager.getHash());
sha1.update(getIp().getBytes());
mySessionID = sha1.getHash();
checkForReconnect(mySessionID);
}
private void addAvailability()
{
if (!availabilityAdded && !closing && peerHavePieces != null && current_peer_state == 30)
{
List peer_listeners_ref = peer_listeners_cow;
if (peer_listeners_ref != null)
{
for (int i = 0; i < peer_listeners_ref.size(); i++)
{
PEPeerListener peerListener = (PEPeerListener)peer_listeners_ref.get(i);
peerListener.addAvailability(this, peerHavePieces);
}
availabilityAdded = true;
}
}
}
private void removeAvailability()
{
if (availabilityAdded && peerHavePieces != null)
{
List peer_listeners_ref = peer_listeners_cow;
if (peer_listeners_ref != null)
{
for (int i = 0; i < peer_listeners_ref.size(); i++)
{
PEPeerListener peerListener = (PEPeerListener)peer_listeners_ref.get(i);
peerListener.removeAvailability(this, peerHavePieces);
}
}
availabilityAdded = false;
}
peerHavePieces = null;
}
protected void sendBTHandshake()
{
if (!handshake_sent)
{
BTHandshake handshake = new BTHandshake(manager.getHash(), manager.getPeerId(), manager.isExtendedMessagingEnabled(), other_peer_handshake_version);
if (Logger.isEnabled())
Logger.log(new LogEvent(this, LOGID, (new StringBuilder()).append("Sending handshake with reserved bytes: ").append(ByteFormatter.nicePrint(handshake.getReserved(), false)).toString()));
if (Constants.isCVSVersion())
{
byte reserved[] = handshake.getReserved();
boolean supports_azmp = (reserved[0] & 0x80) == 128;
boolean supports_ltep = (reserved[5] & 0x10) == 16;
if (supports_ltep && !supports_azmp)
Logger.log(new LogAlert(this, false, 3, (new StringBuilder()).append("AZMP support has failed in Azureus, please report this in the <a href=\"http://forum.vuze.com/forum.jspa?forumID=4\">CVS bug report forum</a>.\nDebug data: ").append(ByteFormatter.nicePrint(reserved)).toString()));
}
connection.getOutgoingMessageQueue().addMessage(handshake, false);
}
}
private void sendLTHandshake()
{
String client_name = "Azureus 4.2.0.0";
int localTcpPort = TCPNetworkManager.getSingleton().getTCPListeningPortNumber();
String tcpPortOverride = COConfigurationManager.getStringParameter("TCP.Listen.Port.Override");
try
{
localTcpPort = Integer.parseInt(tcpPortOverride);
}
catch (NumberFormatException e) { }
boolean require_crypto = NetworkManager.getCryptoRequired(manager.getAdapter().getCryptoLevel());
Map data_dict = new HashMap();
data_dict.put("m", lt_ext_map);
data_dict.put("v", client_name);
data_dict.put("p", new Integer(localTcpPort));
data_dict.put("e", new Long(require_crypto ? 1L : 0L));
data_dict.put("upload_only", new Long(!manager.isSeeding() || ENABLE_LAZY_BITFIELD ? 0L : 1L));
LTHandshake lt_handshake = new LTHandshake(data_dict, other_peer_bt_lt_ext_version);
connection.getOutgoingMessageQueue().addMessage(lt_handshake, false);
}
private void sendAZHandshake()
{
Message avail_msgs[] = MessageManager.getSingleton().getRegisteredMessages();
String avail_ids[] = new String[avail_msgs.length];
byte avail_vers[] = new byte[avail_msgs.length];
for (int i = 0; i < avail_msgs.length; i++)
{
avail_ids[i] = avail_msgs[i].getID();
avail_vers[i] = avail_msgs[i].getVersion();
}
int local_tcp_port = TCPNetworkManager.getSingleton().getTCPListeningPortNumber();
int local_udp_port = UDPNetworkManager.getSingleton().getUDPListeningPortNumber();
int local_udp2_port = UDPNetworkManager.getSingleton().getUDPNonDataListeningPortNumber();
String tcpPortOverride = COConfigurationManager.getStringParameter("TCP.Listen.Port.Override");
try
{
local_tcp_port = Integer.parseInt(tcpPortOverride);
}
catch (NumberFormatException e) { }
boolean require_crypto = NetworkManager.getCryptoRequired(manager.getAdapter().getCryptoLevel());
if (peerSessionID != null)
Logger.log(new LogEvent(this, LOGID, 0, "notifying peer of reconnect attempt"));
AZHandshake az_handshake = new AZHandshake(AZPeerIdentityManager.getAZPeerIdentity(), mySessionID, peerSessionID, "Azureus", "4.2.0.0", local_tcp_port, local_udp_port, local_udp2_port, avail_ids, avail_vers, require_crypto ? 1 : 0, other_peer_handshake_version, manager.isSeeding() && !ENABLE_LAZY_BITFIELD);
connection.getOutgoingMessageQueue().addMessage(az_handshake, false);
}
public int getPeerState()
{
return current_peer_state;
}
public boolean isDownloadPossible()
{
if (!closing && !choked_by_other_peer)
{
if (lastNeededUndonePieceChange < piecePicker.getNeededUndonePieceChange())
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -