/* * File : TRTrackerServerUDP.java * Created : 19-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 org.gudy.azureus2.core3.util.*; import org.gudy.azureus2.core3.config.*; import org.gudy.azureus2.core3.logging.*; import org.gudy.azureus2.core3.tracker.server.*; import org.gudy.azureus2.core3.tracker.server.impl.*; import com.aelitis.azureus.core.networkmanager.admin.NetworkAdmin; import com.aelitis.net.udp.uc.PRUDPPacket; public class TRTrackerServerUDP extends TRTrackerServerImpl { private static final LogIDs LOGID = LogIDs.TRACKER; private static final int THREAD_POOL_SIZE = 10; private ThreadPool thread_pool; private int port; private InetAddress current_bind_ip; private DatagramSocket dg_socket; private volatile boolean closed; public TRTrackerServerUDP( String _name, int _port, boolean _start_up_ready ) { super( _name, _start_up_ready ); port = _port; thread_pool = new ThreadPool( "TrackerServer:UDP:"+port, THREAD_POOL_SIZE ); try{ InetAddress bind_ip = NetworkAdmin.getSingleton().getSingleHomedServiceBindAddress(); InetSocketAddress address; DatagramSocket socket; if ( bind_ip == null ){ address = new InetSocketAddress(InetAddress.getByName("127.0.0.1"),port); socket = new DatagramSocket( port ); }else{ current_bind_ip = bind_ip; address = new InetSocketAddress( bind_ip, port); socket = new DatagramSocket(address); } socket.setReuseAddress(true); dg_socket = socket; final InetSocketAddress f_address = address; Thread recv_thread = new AEThread("TRTrackerServerUDP:recv.loop") { public void runSupport() { recvLoop( dg_socket, f_address ); } }; recv_thread.setDaemon( true ); recv_thread.start(); Logger.log(new LogEvent(LOGID, "TRTrackerServerUDP: recv established on port " + port)); }catch( Throwable e ){ Logger.log(new LogEvent(LOGID, "TRTrackerServerUDP: " + "DatagramSocket bind failed on port " + port, e)); } } public InetAddress getBindIP() { return( current_bind_ip ); } protected void recvLoop( DatagramSocket socket, InetSocketAddress address ) { long successful_accepts = 0; long failed_accepts = 0; while( !closed ){ try{ byte[] buf = new byte[PRUDPPacket.MAX_PACKET_SIZE]; DatagramPacket packet = new DatagramPacket( buf, buf.length, address ); socket.receive( packet ); successful_accepts++; failed_accepts = 0; String ip = packet.getAddress().getHostAddress(); if ( !ip_filter.isInRange( ip, "Tracker", null )){ thread_pool.run( new TRTrackerServerProcessorUDP( this, socket, packet )); } }catch( Throwable e ){ if ( !closed ){ failed_accepts++; Logger.log(new LogEvent(LOGID, "TRTrackerServer: receive failed on port " + port, e)); if (( failed_accepts > 100 && successful_accepts == 0 ) || failed_accepts > 1000 ){ // looks like its not going to work... // some kind of socket problem Logger.logTextResource(new LogAlert(LogAlert.UNREPEATABLE, LogAlert.AT_ERROR, "Network.alert.acceptfail"), new String[] { "" + port, "UDP" }); break; } } } } } public int getPort() { return( port ); } public String getHost() { return( COConfigurationManager.getStringParameter( "Tracker IP", "" )); } public boolean isSSL() { return( false ); } public void addRequestListener( TRTrackerServerRequestListener l ) { } public void removeRequestListener( TRTrackerServerRequestListener l ) { } protected void closeSupport() { closed = true; try{ dg_socket.close(); }catch( Throwable e ){ } destroySupport(); } }