⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 trtrackerserverprocessorudp.java

📁 这是一个基于java编写的torrent的P2P源码
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*
 * File    : TRTrackerServerProcessorUDP.java
 * Created : 20-Jan-2004
 * By      : parg
 * 
 * Azureus - a Java Bittorrent client
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details ( see the LICENSE file ).
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

package org.gudy.azureus2.core3.tracker.server.impl.udp;

/**
 * @author parg
 *
 */

import java.net.*;
import java.io.*;
import java.security.SecureRandom;
import java.util.*;

import org.gudy.azureus2.core3.util.*;
import org.gudy.azureus2.core3.logging.*;
import org.gudy.azureus2.core3.tracker.server.*;
import org.gudy.azureus2.core3.tracker.server.impl.*;

import org.gudy.azureus2.core3.tracker.protocol.*;
import org.gudy.azureus2.core3.tracker.protocol.udp.*;

import com.aelitis.net.udp.uc.PRUDPPacket;
import com.aelitis.net.udp.uc.PRUDPPacketRequest;

public class 
TRTrackerServerProcessorUDP
	extends		TRTrackerServerProcessor
{
	private static final LogIDs LOGID = LogIDs.TRACKER;
		// client may connect + then retry announce up to 4 times -> * 6
	
	public static final long CONNECTION_ID_LIFETIME	= PRUDPPacket.DEFAULT_UDP_TIMEOUT*6;
	
	private TRTrackerServerUDP		server;
	private DatagramSocket			socket;
	private DatagramPacket			request_dg;
	
	private static Map				connection_id_map 	= new LinkedHashMap();
	private static SecureRandom		random				= new SecureRandom();
	private static AEMonitor		random_mon 			= new AEMonitor( "TRTrackerServerUDP:rand" );

	static{
	  	PRUDPTrackerCodecs.registerCodecs();
	}
	
	protected
	TRTrackerServerProcessorUDP(
		TRTrackerServerUDP		_server,
		DatagramSocket			_socket,
		DatagramPacket			_packet )
	{
		server			= _server;
		socket			= _socket;
		request_dg		= _packet;
	}
	
	public void
	runSupport()
	{				
		byte[]	input_buffer = new byte[request_dg.getLength()];
		
		System.arraycopy( request_dg.getData(), 0, input_buffer, 0, input_buffer.length );
		
		int	packet_data_length = input_buffer.length;
		
		String	auth_user			= null;
		byte[] 	auth_user_bytes		= null;
		byte[]	auth_hash			= null;
		
		
		if ( server.isTrackerPasswordEnabled()){
		
				// auth detail should be attached to the packet. Auth details are 16
				// bytes
			
			if ( input_buffer.length < 17 ){
				
				Logger.log(new LogEvent(LOGID, LogEvent.LT_WARNING,
						"TRTrackerServerProcessorUDP: "
								+ "packet received but authorisation missing")); 

				return;
			}
			
			packet_data_length -= 16;
			
			auth_user_bytes = new byte[8];
			
			auth_hash = new byte[8];
			
			System.arraycopy( input_buffer, packet_data_length, auth_user_bytes, 0, 8 );
			
			int	user_len = 0;
			
			while( user_len < 8 && auth_user_bytes[user_len] != 0 ){
				
				user_len++;
			}
			
			auth_user = new String( auth_user_bytes, 0, user_len );
			
			System.arraycopy( input_buffer, packet_data_length+8, auth_hash, 0, 8 );
		}
				
		DataInputStream is = new DataInputStream(new ByteArrayInputStream(input_buffer, 0, packet_data_length ));
		
		try{
			String	client_ip_address = request_dg.getAddress().getHostAddress();
			
			PRUDPPacketRequest	request = PRUDPPacketRequest.deserialiseRequest( null, is );
			
			Logger.log(new LogEvent(LOGID,
					"TRTrackerServerProcessorUDP: packet received: "
							+ request.getString())); 
				
			PRUDPPacket					reply 	= null;
			TRTrackerServerTorrentImpl	torrent	= null;
			
			if ( auth_user_bytes != null ){
				
				// user name is irrelevant as we only have one at the moment
	
				//<parg_home> so <new_packet> = <old_packet> + <user_padded_to_8_bytes> + <hash>
				//<parg_home> where <hash> = first 8 bytes of sha1(<old_packet> + <user_padded_to_8> + sha1(pass))
				//<XTF> Yes
				
								
				byte[] sha1_pw = null;
				
				if ( server.hasExternalAuthorisation()){
					
					try{
						URL	resource = new URL( "udp://" + server.getHost() + ":" + server.getPort() + "/" );
					
						sha1_pw = server.performExternalAuthorisation( resource, auth_user );
						
					}catch( MalformedURLException e ){
						
						Debug.printStackTrace( e );
						
					}
					
					if ( sha1_pw == null ){
				
						Logger.log(new LogEvent(LOGID, LogEvent.LT_ERROR,
								"TRTrackerServerProcessorUDP: auth fails for user '"
										+ auth_user + "'")); 

						reply = new PRUDPPacketReplyError( request.getTransactionId(), "Access Denied" );
					}
				}else{
					
					sha1_pw = server.getPassword();
				}
				
					// if we haven't already failed then check the PW
				
				if ( reply == null ){
					
					SHA1Hasher	hasher = new SHA1Hasher();
					
					hasher.update( input_buffer, 0, packet_data_length);
					hasher.update( auth_user_bytes );
					hasher.update( sha1_pw );
					
					byte[]	digest = hasher.getDigest();
					
					for (int i=0;i<auth_hash.length;i++){
						
						if ( auth_hash[i] != digest[i] ){
					
							Logger.log(new LogEvent(LOGID, LogEvent.LT_ERROR,
									"TRTrackerServerProcessorUDP: auth fails for user '"
											+ auth_user + "'")); 
	
							reply = new PRUDPPacketReplyError( request.getTransactionId(), "Access Denied" );
							
							break;
						}
					}
				}
			}
			
			if( reply == null ){
				
				try{
					int	type = request.getAction();
					
					if ( type == PRUDPPacketTracker.ACT_REQUEST_CONNECT ){
						
						reply = handleConnect( client_ip_address, request );
						
					}else if (type == PRUDPPacketTracker.ACT_REQUEST_ANNOUNCE ){
						
						Object[] x = handleAnnounceAndScrape( client_ip_address, request, TRTrackerServerRequest.RT_ANNOUNCE );
						
						reply 	= (PRUDPPacket)x[0];
						torrent	= (TRTrackerServerTorrentImpl)x[1];
				
					}else if ( type == PRUDPPacketTracker.ACT_REQUEST_SCRAPE ){
						
						Object[] x = handleAnnounceAndScrape( client_ip_address, request, TRTrackerServerRequest.RT_SCRAPE );
						
						reply 	= (PRUDPPacket)x[0];
						torrent	= (TRTrackerServerTorrentImpl)x[1];
	
					}else{
						
						reply = new PRUDPPacketReplyError( request.getTransactionId(), "unsupported action");
					}
				}catch( Throwable e ){
					
					// e.printStackTrace();
					
					String	error = e.getMessage();
					
					if ( error == null ){
						
						error = e.toString();
					}
					
					reply = new PRUDPPacketReplyError( request.getTransactionId(), error );
				}
			}
			
			if ( reply != null ){
				
				InetAddress address = request_dg.getAddress();
				
				ByteArrayOutputStream	baos = new ByteArrayOutputStream();
				
				DataOutputStream os = new DataOutputStream( baos );
										
				reply.serialise(os);
				
				byte[]	output_buffer = baos.toByteArray();
				
				DatagramPacket reply_packet = new DatagramPacket(output_buffer, output_buffer.length,address,request_dg.getPort());
							
				socket.send( reply_packet );
				
				if ( torrent != null ){
					
					server.updateStats( torrent, input_buffer.length, output_buffer.length );
				}
			}
			
		}catch( Throwable e ){
			
			Logger.log(new LogEvent(LOGID,
					"TRTrackerServerProcessorUDP: processing fails", e)); 
		}finally{
			
			try{
				is.close();
				
			}catch( Throwable e ){
				
			}
		}
	}
	
	public void
	interruptTask()
	{
	}
	
	protected long
	allocateConnectionId(
		String	client_address )
	{
		try{
			random_mon.enter();
	
			long	id = random.nextLong();
			
			Long	new_key = new Long(id);
			
			connectionData	new_data = new connectionData( client_address );
			
				// check for timeouts
			
			Iterator	it = connection_id_map.keySet().iterator();
			
			while(it.hasNext()){
				
				Long	key = (Long)it.next();
				
				connectionData	data = (connectionData)connection_id_map.get(key);
			
				if ( new_data.getTime() - data.getTime() > CONNECTION_ID_LIFETIME ){
					
					// System.out.println( "TRTrackerServerProcessorUDP: conection id timeout" );
					
					it.remove();
					
				}else{
						// insertion order into map is time based - LinkedHashMap returns keys in same order
					
					break;
				}
			}	
						
			connection_id_map.put( new_key, new_data );
			
			// System.out.println( "TRTrackerServerProcessorUDP: allocated:" + id + ", conection id map size = " + connection_id_map.size());
			
			return( id );
		}finally{
			
			random_mon.exit();
		}
	}
	
	protected boolean
	checkConnectionId(
		String	client_address,
		long	id )
	{
		try{
			random_mon.enter();
			
			Long	key = new Long(id);
			
			connectionData data = (connectionData)connection_id_map.get( key );
			
			if ( data == null ){
				
				// System.out.println( "TRTrackerServerProcessorUDP: rejected:" + id + ", data not found" );
				
				return( false );
				
			}else{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -