📄 udpconnectionmanager.java
字号:
/*
* Created on 22 Jun 2006
* Created by Paul Gardner
* Copyright (C) 2006 Aelitis, All Rights Reserved.
*
* 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, or (at your option) any later version.
* 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.
* 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.
*
* AELITIS, SAS au capital de 46,603.30 euros
* 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
*
*/
package com.aelitis.azureus.core.networkmanager.impl.udp;
import java.util.*;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import org.gudy.azureus2.core3.config.COConfigurationManager;
import org.gudy.azureus2.core3.config.ParameterListener;
import org.gudy.azureus2.core3.logging.LogEvent;
import org.gudy.azureus2.core3.logging.LogIDs;
import org.gudy.azureus2.core3.logging.Logger;
import org.gudy.azureus2.core3.util.AEThread;
import org.gudy.azureus2.core3.util.Debug;
import org.gudy.azureus2.core3.util.SystemTime;
import com.aelitis.azureus.core.networkmanager.ConnectionEndpoint;
import com.aelitis.azureus.core.networkmanager.impl.IncomingConnectionManager;
import com.aelitis.azureus.core.networkmanager.impl.ProtocolDecoder;
import com.aelitis.azureus.core.networkmanager.impl.TransportCryptoManager;
import com.aelitis.azureus.core.networkmanager.impl.TransportHelperFilter;
import com.aelitis.azureus.core.util.bloom.BloomFilter;
import com.aelitis.azureus.core.util.bloom.BloomFilterFactory;
public class
UDPConnectionManager
implements NetworkGlueListener
{
private static final LogIDs LOGID = LogIDs.NET;
private static final boolean LOOPBACK = false;
private static final boolean FORCE_LOG = false;
private static boolean LOG = false;
static{
COConfigurationManager.addAndFireParameterListener(
"Logging Enable UDP Transport",
new ParameterListener()
{
public void
parameterChanged(
String name )
{
LOG = FORCE_LOG || COConfigurationManager.getBooleanParameter( name );
}
});
}
public static final int TIMER_TICK_MILLIS = 25;
public static final int THREAD_LINGER_ON_IDLE_PERIOD = 30*1000;
public static final int DEAD_KEY_RETENTION_PERIOD = 30*1000;
public static final int STATS_TIME = 60*1000;
public static final int STATS_TICKS = STATS_TIME / TIMER_TICK_MILLIS;
private final Map connection_sets = new HashMap();
private final Map recently_dead_keys = new HashMap();
private int next_connection_id;
private IncomingConnectionManager incoming_manager = IncomingConnectionManager.getSingleton();
private NetworkGlue network_glue;
private UDPSelector selector;
private ProtocolTimer protocol_timer;
private long idle_start;
private static final int BLOOM_RECREATE = 30*1000;
private static final int BLOOM_INCREASE = 1000;
private BloomFilter incoming_bloom = BloomFilterFactory.createAddRemove4Bit(BLOOM_INCREASE);
private long incoming_bloom_create_time = SystemTime.getCurrentTime();
private long last_incoming;
private int rate_limit_discard_packets;
private int rate_limit_discard_bytes;
private int setup_discard_packets;
private int setup_discard_bytes;
protected
UDPConnectionManager()
{
if ( LOOPBACK ){
network_glue = new NetworkGlueLoopBack( this );
}else{
network_glue = new NetworkGlueUDP( this );
}
}
protected UDPSelector
checkThreadCreation()
{
// called while holding the "connections" monitor
if ( selector == null ){
if (Logger.isEnabled()){
Logger.log(new LogEvent(LOGID, "UDPConnectionManager: activating" ));
}
selector = new UDPSelector(this );
protocol_timer = new ProtocolTimer();
}
return( selector );
}
protected void
checkThreadDeath(
boolean connections_running )
{
// called while holding the "connections" monitor
if ( connections_running ){
idle_start = 0;
}else{
long now = SystemTime.getCurrentTime();
if ( idle_start == 0 ){
idle_start = now;
}else if ( idle_start > now ){
idle_start = now;
}else if ( now - idle_start > THREAD_LINGER_ON_IDLE_PERIOD ){
if (Logger.isEnabled()){
Logger.log(new LogEvent(LOGID, "UDPConnectionManager: deactivating" ));
}
selector.destroy();
selector = null;
protocol_timer.destroy();
protocol_timer = null;
}
}
}
protected void
poll()
{
synchronized( connection_sets ){
Iterator it = connection_sets.values().iterator();
while( it.hasNext()){
((UDPConnectionSet)it.next()).poll();
}
}
}
public void
remove(
UDPConnectionSet set,
UDPConnection connection )
{
synchronized( connection_sets ){
if ( set.remove( connection )){
String key = set.getKey();
if ( set.hasFailed()){
if ( connection_sets.remove( key ) != null ){
set.removed();
recently_dead_keys.put( key, new Long( SystemTime.getCurrentTime()));
if (Logger.isEnabled()){
Logger.log(new LogEvent(LOGID, "Connection set " + key + " failed"));
}
}
}
}
}
}
public void
failed(
UDPConnectionSet set )
{
synchronized( connection_sets ){
String key = set.getKey();
if ( connection_sets.remove( key ) != null ){
set.removed();
recently_dead_keys.put( key, new Long( SystemTime.getCurrentTime()));
if (Logger.isEnabled()){
Logger.log(new LogEvent(LOGID, "Connection set " + key + " failed"));
}
}
}
}
protected UDPConnection
registerOutgoing(
UDPTransportHelper helper )
throws IOException
{
int local_port = UDPNetworkManager.getSingleton().getUDPListeningPortNumber();
InetSocketAddress address = helper.getAddress();
String key = local_port + ":" + address.getAddress().getHostAddress() + ":" + address.getPort();
synchronized( connection_sets ){
UDPSelector current_selector = checkThreadCreation();
UDPConnectionSet connection_set = (UDPConnectionSet)connection_sets.get( key );
if ( connection_set == null ){
timeoutDeadKeys();
connection_set = new UDPConnectionSet( this, key, current_selector, local_port, address );
if (Logger.isEnabled()){
Logger.log(new LogEvent(LOGID, "Created new set - " + connection_set.getName() + ", outgoing"));
}
connection_sets.put( key, connection_set );
}
UDPConnection connection = new UDPConnection( connection_set, allocationConnectionID(), helper );
connection_set.add( connection );
return( connection );
}
}
public void
receive(
int local_port,
InetSocketAddress remote_address,
byte[] data,
int data_length )
{
String key = local_port + ":" + remote_address.getAddress().getHostAddress() + ":" + remote_address.getPort();
UDPConnectionSet connection_set;
synchronized( connection_sets ){
UDPSelector current_selector = checkThreadCreation();
connection_set = (UDPConnectionSet)connection_sets.get( key );
if ( connection_set == null ){
timeoutDeadKeys();
// check that this at least looks like an initial crypto packet
if ( data_length >= UDPNetworkManager.MIN_INCOMING_INITIAL_PACKET_SIZE &&
data_length <= UDPNetworkManager.MAX_INCOMING_INITIAL_PACKET_SIZE ){
if ( !rateLimitIncoming( remote_address )){
rate_limit_discard_packets++;
rate_limit_discard_bytes += data_length;
return;
}
connection_set = new UDPConnectionSet( this, key, current_selector, local_port, remote_address );
if (Logger.isEnabled()){
Logger.log(new LogEvent(LOGID, "Created new set - " + connection_set.getName() + ", incoming"));
}
connection_sets.put( key, connection_set );
}else{
if ( recently_dead_keys.get( key ) == null ){
// we can get quite a lot of these if things get out of sync
// Debug.out( "Incoming UDP packet mismatch for connection establishment: " + key );
}
setup_discard_packets++;
setup_discard_bytes += data_length;
return;
}
}
}
try{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -