📄 trtrackerclientclassicimpl.java
字号:
tracker_status_str = MessageText.getString("PeerManager.status.checking") + "..."; //$NON-NLS-1$ //$NON-NLS-2$
TRTrackerResponse response = null;
if ( stopped ){
if ( tracker_state == TS_INITIALISED ){
// never started
tracker_state = TS_STOPPED;
}else if ( tracker_state != TS_STOPPED ){
response = stopSupport();
if ( response.getStatus() == TRTrackerResponse.ST_ONLINE ){
tracker_state = TS_STOPPED;
}else{
// just have one go at sending a stop event as we don't want to sit here
// forever trying to send stop to a stuffed tracker
tracker_state = TS_STOPPED;
}
}
}else if ( tracker_state == TS_INITIALISED ){
// always go through the "start" phase, even if we're already complete
// as some trackers insist on the initial "start"
response = startSupport();
if ( response.getStatus() == TRTrackerResponse.ST_ONLINE ){
tracker_state = TS_DOWNLOADING;
}
}else if ( completed ){
if ( !complete_reported ){
response = completeSupport();
if ( response.getStatus() == TRTrackerResponse.ST_ONLINE ){
complete_reported = true;
tracker_state = TS_COMPLETED;
}
}else{
tracker_state = TS_COMPLETED;
response = updateSupport();
}
}else{
response = updateSupport();
}
if ( response != null ){
int rs = response.getStatus();
if ( rs == TRTrackerResponse.ST_OFFLINE ){
tracker_status_str = MessageText.getString("PeerManager.status.offline");
String reason = response.getFailureReason();
if ( reason != null ){
tracker_status_str += " (" + reason + ")";
}
}else if ( rs == TRTrackerResponse.ST_REPORTED_ERROR ){
tracker_status_str = MessageText.getString("PeerManager.status.error");
String reason = response.getFailureReason();
if ( reason != null ){
tracker_status_str += " (" + reason + ")";
}
// move state back to initialised to next time around a "started"
// event it resent. Required for trackers like 123torrents.com that
// will fail peers that don't start with a "started" event after a
// tracker restart
tracker_state = TS_INITIALISED;
}else{
tracker_status_str = MessageText.getString("PeerManager.status.ok"); //set the status //$NON-NLS-1$
}
last_response = response;
listeners.dispatch( LDT_TRACKER_RESPONSE, response );
return( response.getTimeToWait());
}else{
tracker_status_str = "";
return( getErrorRetryInterval() );
}
}catch( Throwable e ){
Debug.printStackTrace( e );
return( getErrorRetryInterval() );
}finally{
try{
this_mon.enter();
if ( clear_progress ){
update_in_progress = false;
}
}finally{
this_mon.exit();
}
}
}
protected TRTrackerResponse
startSupport()
{
LGLogger.log(componentID, evtLifeCycle, LGLogger.SENT, "Tracker Client is sending a start Request");
// System.out.println( "started");
return(update("started"));
}
protected TRTrackerResponse
completeSupport()
{
LGLogger.log(componentID, evtLifeCycle, LGLogger.SENT, "Tracker Client is sending a completed Request");
// System.out.println( "complete");
return(update("completed"));
}
protected TRTrackerResponse
stopSupport()
{
LGLogger.log(componentID, evtLifeCycle, LGLogger.SENT, "Tracker Client is sending a stopped Request");
// System.out.println( "stop");
return( update("stopped"));
}
protected TRTrackerResponse
updateSupport()
{
LGLogger.log(componentID, evtLifeCycle, LGLogger.SENT, "Tracker Client is sending an update Request");
// System.out.println( "update");
return update("");
}
private TRTrackerResponse
update(String evt)
{
TRTrackerResponseImpl last_failure_resp = null;
outer:
for (int i = 0 ; i < trackerUrlLists.size() ; i++) {
List urls = (List) trackerUrlLists.get(i);
for (int j = 0 ; j < urls.size() ; j++) {
URL url = (URL)urls.get(j);
lastUsedUrl = url;
URL request_url = null;
try{
request_url = constructUrl(evt,url);
TRTrackerResponseImpl resp = decodeTrackerResponse( updateOld(request_url));
if ( resp.getStatus() == TRTrackerResponse.ST_ONLINE ){
urls.remove(j);
urls.add(0,url);
trackerUrlLists.remove(i);
trackerUrlLists.add(0,urls);
informURLChange( url, false );
//and return the result
return( resp );
}else{
last_failure_resp = resp;
}
}catch( MalformedURLException e ){
Debug.printStackTrace( e );
last_failure_resp =
new TRTrackerResponseImpl(
TRTrackerResponse.ST_OFFLINE,
getErrorRetryInterval(),
"malformed URL '" + (request_url==null?"<null>":request_url.toString()) + "'" );
}catch( Exception e ){
//e.printStackTrace();
last_failure_resp =
new TRTrackerResponseImpl(
TRTrackerResponse.ST_OFFLINE,
getErrorRetryInterval(),
e.getMessage());
}
if ( destroyed ){
break outer;
}
}
}
// things no good here
if ( last_failure_resp == null ){
last_failure_resp =
new TRTrackerResponseImpl(
TRTrackerResponse.ST_OFFLINE,
getErrorRetryInterval(),
"Reason Unknown" );
}
TRTrackerResponsePeer[] cached_peers = getPeersFromCache();
if ( cached_peers.length > 0 ){
// System.out.println( "cached peers used:" + cached_peers.length );
last_failure_resp.setPeers( cached_peers );
}
return( last_failure_resp );
}
private byte[]
updateOld(
URL reqUrl )
throws Exception
{
// set context in case authentication dialog is required
TorrentUtils.setTLSTorrentHash( torrent_hash );
// loop to possibly retry update on SSL certificate install
for (int i=0;i<2;i++){
String failure_reason = null;
try{
String protocol = reqUrl.getProtocol();
LGLogger.log(componentID, evtFullTrace, LGLogger.INFORMATION, "Tracker Client is Requesting : " + reqUrl);
ByteArrayOutputStream message = new ByteArrayOutputStream();
if ( protocol.equalsIgnoreCase("udp")){
failure_reason = announceUDP( reqUrl, message );
}else{
failure_reason = announceHTTP( reqUrl, message );
}
// if we've got some kind of response then return it
if ( message.size() > 0 ){
return( message.toByteArray());
}else{
if ( failure_reason == null ){
failure_reason = "No data received from tracker";
}
}
}catch( SSLHandshakeException e ){
// e.printStackTrace();
if ( i == 0 && e.getMessage().indexOf("No trusted certificate found") != -1 ){
if ( SESecurityManager.installServerCertificates( reqUrl )){
// certificate has been installed
continue; // retry with new certificate
}else{
failure_reason = exceptionToString( e );
}
}
}catch (Exception e){
// e.printStackTrace();
failure_reason = exceptionToString( e );
}
if ( failure_reason.indexOf("401" ) != -1 ){
failure_reason = "Tracker authentication failed";
}
LGLogger.log(componentID, evtErrors, LGLogger.ERROR, "Exception while processing the Tracker Request : " + failure_reason);
throw( new Exception( failure_reason));
}
// should never get here as second iteration of loop will always cause an exit
throw( new Exception( "Internal Error: should never get here" ));
}
protected String
announceHTTP(
URL reqUrl,
ByteArrayOutputStream message )
throws IOException
{
TRTrackerUtilsImpl.checkForBlacklistedURLs( reqUrl );
reqUrl = TRTrackerUtilsImpl.adjustURLForHosting( reqUrl );
reqUrl = AEProxyFactory.getAddressMapper().internalise( reqUrl );
String failure_reason = null;
HttpURLConnection con;
if ( reqUrl.getProtocol().equalsIgnoreCase("https")){
// see ConfigurationChecker for SSL client defaults
HttpsURLConnection ssl_con = (HttpsURLConnection)reqUrl.openConnection();
// allow for certs that contain IP addresses rather than dns names
ssl_con.setHostnameVerifier(
new HostnameVerifier()
{
public boolean
verify(
String host,
SSLSession session )
{
return( true );
}
});
con = ssl_con;
}else{
con = (HttpURLConnection) reqUrl.openConnection();
}
con.setRequestProperty("User-Agent", Constants.AZUREUS_NAME + " " + Constants.AZUREUS_VERSION);
con.setRequestProperty("Connection", "close" );
// some trackers support gzip encoding of replies
con.addRequestProperty("Accept-Encoding","gzip");
try{
con.connect();
InputStream is = null;
try{
is = con.getInputStream();
String encoding = con.getHeaderField( "content-encoding");
boolean gzip = encoding != null && encoding.equalsIgnoreCase("gzip");
// System.out.println( "encoding = " + encoding );
if ( gzip ){
is = new GZIPInputStream( is );
}
// there are some trackers out there that don't set content length correctly
// so we can't reliably use it :(
int content_length = -1; //con.getContentLength();
// System.out.println(length);
byte[] data = new byte[1024];
int num_read = 0;
// some trackers don't return content-length
while ( content_length <= 0 || num_read < content_length ){
try{
int len = is.read(data);
if ( len > 0 ){
message.write(data, 0, len);
num_read += len;
}else if ( len == 0 ){
Thread.sleep(20);
}else{
break;
}
}catch (Exception e){
LGLogger.log(componentID, evtErrors, LGLogger.ERROR, "Exception while Requesting Tracker : " + e);
LGLogger.log(componentID, evtFullTrace, LGLogger.ERROR, "Message Received was : " + message);
failure_reason = exceptionToString( e );
break;
}
}
LGLogger.log(componentID, evtFullTrace, LGLogger.RECEIVED, "Tracker Client ["+lastUsedUrl+"] has received : " + message);
}catch (Exception e){
// e.printStackTrace();
failure_reason = exceptionToString( e );
}finally{
if (is != null) {
try {
is.close();
}catch (Exception e) {
}
is = null;
}
}
}finally{
con.disconnect();
}
return( failure_reason );
}
protected String
announceUDP(
URL reqUrl,
ByteArrayOutputStream message )
throws IOException
{
reqUrl = TRTrackerUtilsImpl.adjustURLForHosting( reqUrl );
String failure_reason = null;
PasswordAuthentication auth = null;
try{
if ( reqUrl.getQuery().toLowerCase().indexOf("auth") != -1 ){
auth = SESecurityManager.getPasswordAuthentication( UDP_REALM, reqUrl );
}
PRUDPPacketHandler handler = PRUDPPacketHandlerFactory.getHandler( peer_server.getPort());
InetSocketAddress destination = new InetSocketAddress(reqUrl.getHost(),reqUrl.getPort()==-1?80:reqUrl.getPort());
for (int retry_loop=0;retry_loop<PRUDPPacket.DEFAULT_RETRY_COUNT;retry_loop++){
try{
PRUDPPacket connect_request = new PRUDPPacketRequestConnect();
PRUDPPacket reply = handler.sendAndReceive( auth, connect_request, destination );
if ( reply.getAction() == PRUDPPacket.ACT_REPLY_CONNECT ){
PRUDPPacketReplyConnect connect_reply = (PRUDPPacketReplyConnect)reply;
long my_connection = connect_reply.getConnectionId();
PRUDPPacketRequest request;
if ( PRUDPPacket.VERSION == 1 ){
PRUDPPacketRequestAnnounce announce_request = new PRUDPPacketRequestAnnounce( my_connection );
request = announce_request;
// bit of a hack this...
String url_str = reqUrl.toString();
int p_pos = url_str.indexOf("?");
url_str = url_str.substring(p_pos+1);
String event_str = getURLParam( url_str, "event" );
int event = PRUDPPacketRequestAnnounce.EV_UPDATE;
if ( event_str != null ){
if ( event_str.equals( "started" )){
event = PRUDPPacketRequestAnnounce.EV_STARTED;
}else if ( event_str.equals( "stopped" )){
event = PRUDPPacketRequestAnnounce.EV_STOPPED;
}else if ( event_str.equals( "completed" )){
event = PRUDPPacketRequestAnnounce.EV_COMPLETED;
}
}
String ip_str = getURLParam( url_str, "ip" );
int ip = 0;
if ( ip_str != null ){
ip = PRHelpers.addressToInt( ip_str);
}
announce_request.setDetails(
torrent_hash,
tracker_peer_id,
getLongURLParam( url_str, "downloaded" ),
event,
ip,
(int)getLongURLParam( url_str, "numwant" ),
getLongURLParam( url_str, "left" ),
(short)getLongURLParam( url_str, "port" ),
getLongURLParam( url_str, "uploaded" ));
}else{
PRUDPPacketRequestAnnounce2 announce_request = new PRUDPPacketRequestAnnounce2( my_connection );
request = announce_request;
// bit of a hack this...
String url_str = reqUrl.toString();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -