📄 dhtplugin.java
字号:
/*
* Created on 24-Jan-2005
* Created by Paul Gardner
* Copyright (C) 2004, 2005, 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.plugins.dht;
import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.gudy.azureus2.core3.util.AEMonitor;
import org.gudy.azureus2.core3.util.AESemaphore;
import org.gudy.azureus2.core3.util.AEThread;
import org.gudy.azureus2.core3.util.Constants;
import org.gudy.azureus2.core3.util.Debug;
import org.gudy.azureus2.plugins.*;
import org.gudy.azureus2.plugins.logging.LoggerChannel;
import org.gudy.azureus2.plugins.logging.LoggerChannelListener;
import org.gudy.azureus2.plugins.ui.UIManager;
import org.gudy.azureus2.plugins.ui.components.UITextField;
import org.gudy.azureus2.plugins.ui.config.*;
import org.gudy.azureus2.plugins.ui.model.*;
import org.gudy.azureus2.plugins.utils.UTTimerEvent;
import org.gudy.azureus2.plugins.utils.UTTimerEventPerformer;
import com.aelitis.azureus.core.AzureusCoreFactory;
import com.aelitis.azureus.core.dht.DHT;
import com.aelitis.azureus.core.dht.DHTLogger;
import com.aelitis.azureus.core.dht.control.DHTControlActivity;
import com.aelitis.azureus.core.dht.transport.DHTTransportContact;
import com.aelitis.azureus.core.dht.transport.DHTTransportFullStats;
import com.aelitis.azureus.core.dht.transport.DHTTransportListener;
import com.aelitis.azureus.core.dht.transport.udp.DHTTransportUDP;
import com.aelitis.azureus.core.dht.transport.udp.impl.DHTTransportUDPImpl;
import com.aelitis.azureus.core.networkmanager.impl.udp.UDPNetworkManager;
import com.aelitis.azureus.core.versioncheck.VersionCheckClient;
import com.aelitis.azureus.plugins.dht.impl.DHTPluginImpl;
import com.aelitis.azureus.plugins.upnp.UPnPMapping;
import com.aelitis.azureus.plugins.upnp.UPnPPlugin;
/**
* @author parg
*
*/
public class
DHTPlugin
implements Plugin
{
// data will be the DHT instance created
public static final int EVENT_DHT_AVAILABLE = PluginEvent.PEV_FIRST_USER_EVENT;
public static final int STATUS_DISABLED = 1;
public static final int STATUS_INITALISING = 2;
public static final int STATUS_RUNNING = 3;
public static final int STATUS_FAILED = 4;
public static final byte FLAG_SINGLE_VALUE = DHT.FLAG_SINGLE_VALUE;
public static final byte FLAG_DOWNLOADING = DHT.FLAG_DOWNLOADING;
public static final byte FLAG_SEEDING = DHT.FLAG_SEEDING;
public static final byte FLAG_MULTI_VALUE = DHT.FLAG_MULTI_VALUE;
public static final byte FLAG_STATS = DHT.FLAG_STATS;
public static final byte DT_NONE = DHT.DT_NONE;
public static final byte DT_FREQUENCY = DHT.DT_FREQUENCY;
public static final byte DT_SIZE = DHT.DT_SIZE;
public static final int MAX_VALUE_SIZE = DHT.MAX_VALUE_SIZE;
private static final String PLUGIN_VERSION = "1.0";
private static final String PLUGIN_NAME = "Distributed DB";
private static final String PLUGIN_CONFIGSECTION_ID = "plugins.dht";
private static final boolean TRACE_NON_MAIN = false;
private static final boolean MAIN_DHT_ENABLE = true;
private static final boolean CVS_DHT_ENABLE = true;
static{
if ( TRACE_NON_MAIN ){
System.out.println( "**** DHTPlugin - tracing non-main network actions ****" );
}
}
private PluginInterface plugin_interface;
private int status = STATUS_INITALISING;
private DHTPluginImpl[] dhts;
private ActionParameter reseed;
private boolean enabled;
private int dht_data_port;
private boolean got_extended_use;
private boolean extended_use;
private AESemaphore init_sem = new AESemaphore("DHTPlugin:init" );
private AEMonitor port_change_mon = new AEMonitor( "DHTPlugin:portChanger" );
private boolean port_changing;
private int port_change_outstanding;
private BooleanParameter ipfilter_logging;
private UPnPMapping upnp_mapping;
private LoggerChannel log;
private DHTLogger dht_log;
private List listeners = new ArrayList();
public void
initialize(
PluginInterface _plugin_interface )
{
plugin_interface = _plugin_interface;
plugin_interface.getPluginProperties().setProperty( "plugin.version", PLUGIN_VERSION );
plugin_interface.getPluginProperties().setProperty( "plugin.name", PLUGIN_NAME );
dht_data_port = UDPNetworkManager.getSingleton().getUDPNonDataListeningPortNumber();
log = plugin_interface.getLogger().getTimeStampedChannel(PLUGIN_NAME);
UIManager ui_manager = plugin_interface.getUIManager();
final BasicPluginViewModel model =
ui_manager.createBasicPluginViewModel( PLUGIN_NAME);
model.setConfigSectionID(PLUGIN_CONFIGSECTION_ID);
BasicPluginConfigModel config = ui_manager.createBasicPluginConfigModel(ConfigSection.SECTION_PLUGINS, PLUGIN_CONFIGSECTION_ID);
config.addLabelParameter2( "dht.info" );
final BooleanParameter enabled_param = config.addBooleanParameter2( "dht.enabled", "dht.enabled", true );
plugin_interface.getPluginconfig().addListener(
new PluginConfigListener()
{
public void
configSaved()
{
int new_dht_data_port = UDPNetworkManager.getSingleton().getUDPNonDataListeningPortNumber();
if ( new_dht_data_port != dht_data_port ){
changePort( new_dht_data_port );
}
}
});
LabelParameter reseed_label = config.addLabelParameter2( "dht.reseed.label" );
final StringParameter reseed_ip = config.addStringParameter2( "dht.reseed.ip", "dht.reseed.ip", "" );
final IntParameter reseed_port = config.addIntParameter2( "dht.reseed.port", "dht.reseed.port", 0 );
reseed = config.addActionParameter2( "dht.reseed.info", "dht.reseed");
reseed.setEnabled( false );
config.createGroup( "dht.reseed.group",
new Parameter[]{ reseed_label, reseed_ip, reseed_port, reseed });
ipfilter_logging = config.addBooleanParameter2( "dht.ipfilter.log", "dht.ipfilter.log", true );
final BooleanParameter advanced = config.addBooleanParameter2( "dht.advanced", "dht.advanced", false );
LabelParameter advanced_label = config.addLabelParameter2( "dht.advanced.label" );
final StringParameter override_ip = config.addStringParameter2( "dht.override.ip", "dht.override.ip", "" );
config.createGroup( "dht.advanced.group",
new Parameter[]{ advanced_label, override_ip });
advanced.addEnabledOnSelection( advanced_label );
advanced.addEnabledOnSelection( override_ip );
final StringParameter command = config.addStringParameter2( "dht.execute.command", "dht.execute.command", "print" );
ActionParameter execute = config.addActionParameter2( "dht.execute.info", "dht.execute");
final BooleanParameter logging = config.addBooleanParameter2( "dht.logging", "dht.logging", false );
config.createGroup( "dht.diagnostics.group",
new Parameter[]{ command, execute, logging });
logging.addListener(
new ParameterListener()
{
public void
parameterChanged(
Parameter param )
{
if ( dhts != null ){
for (int i=0;i<dhts.length;i++){
dhts[i].setLogging( logging.getValue());
}
}
}
});
final DHTPluginOperationListener log_polistener =
new DHTPluginOperationListener()
{
public void
diversified()
{
}
public void
valueRead(
DHTPluginContact originator,
DHTPluginValue value )
{
log.log( "valueRead: " + new String(value.getValue()) + " from " + originator.getName());
if ( ( value.getFlags() & DHTPlugin.FLAG_STATS ) != 0 ){
DHTPluginKeyStats stats = decodeStats( value );
log.log( " stats: size=" + stats.getSize());
}
}
public void
valueWritten(
DHTPluginContact target,
DHTPluginValue value )
{
log.log( "valueWritten:" + new String( value.getValue()) + " to " + target.getName());
}
public void
complete(
boolean timeout_occurred )
{
log.log( "complete: timeout = " + timeout_occurred );
}
};
execute.addListener(
new ParameterListener()
{
public void
parameterChanged(
Parameter param )
{
Thread t =
new AEThread( "DHT:commandrunner" )
{
public void
runSupport()
{
if ( dhts == null ){
return;
}
for (int i=0;i<dhts.length;i++){
DHT dht = dhts[i].getDHT();
DHTTransportUDP transport = (DHTTransportUDP)dht.getTransport();
String c = command.getValue().trim();
String lc = c.toLowerCase();
if ( lc.equals("print")){
dht.print();
dhts[i].logStats();
}else if ( lc.equals( "testca" )){
((DHTTransportUDPImpl)transport).testExternalAddressChange();
}else if ( lc.equals( "testnd" )){
((DHTTransportUDPImpl)transport).testNetworkAlive( false );
}else if ( lc.equals( "testna" )){
((DHTTransportUDPImpl)transport).testNetworkAlive( true );
}else{
int pos = c.indexOf( ' ' );
if ( pos != -1 ){
String lhs = lc.substring(0,pos);
String rhs = c.substring(pos+1);
if ( lhs.equals( "set" )){
pos = rhs.indexOf( '=' );
if ( pos != -1 ){
DHTPlugin.this.put(
rhs.substring(0,pos).getBytes(),
"DHT Plugin: set",
rhs.substring(pos+1).getBytes(),
(byte)0,
log_polistener );
}
}else if ( lhs.equals( "get" )){
DHTPlugin.this.get(
rhs.getBytes(), "DHT Plugin: get", (byte)0, 1, 10000, true, false, log_polistener );
}else if ( lhs.equals( "query" )){
DHTPlugin.this.get(
rhs.getBytes(), "DHT Plugin: get", DHTPlugin.FLAG_STATS, 1, 10000, true, false, log_polistener );
}else if ( lhs.equals( "punch" )){
Map originator_data = new HashMap();
originator_data.put( "hello", "mum" );
dht.getNATPuncher().punch( "Test", transport.getLocalContact(), null, originator_data );
}else if ( lhs.equals( "stats" )){
try{
pos = rhs.indexOf( ":" );
DHTTransportContact contact;
if ( pos == -1 ){
contact = transport.getLocalContact();
}else{
String host = rhs.substring(0,pos);
int port = Integer.parseInt( rhs.substring(pos+1));
contact =
transport.importContact(
new InetSocketAddress( host, port ),
transport.getProtocolVersion());
}
DHTTransportFullStats stats = contact.getStats();
log.log( "Stats:" + (stats==null?"<null>":stats.getString()));
DHTControlActivity[] activities = dht.getControl().getActivities();
for (int j=0;j<activities.length;j++){
log.log( " act:" + activities[j].getString());
}
}catch( Throwable e ){
Debug.printStackTrace(e);
}
}
}
}
}
}
};
t.setDaemon(true);
t.start();
}
});
reseed.addListener(
new ParameterListener()
{
public void
parameterChanged(
Parameter param )
{
reseed.setEnabled( false );
Thread t =
new AEThread( "DHT:reseeder" )
{
public void
runSupport()
{
try{
String ip = reseed_ip.getValue().trim();
if ( dhts == null ){
return;
}
int port = reseed_port.getValue();
for (int i=0;i<dhts.length;i++){
DHTPluginImpl dht = dhts[i];
if ( ip.length() == 0 || port == 0 ){
dht.checkForReSeed( true );
}else{
if ( dht.importSeed( ip, port ) != null ){
dht.integrateDHT( false, null );
}
}
}
}finally{
reseed.setEnabled( true );
}
}
};
t.setDaemon( true );
t.start();
}
});
model.getActivity().setVisible( false );
model.getProgress().setVisible( false );
log.addListener(
new LoggerChannelListener()
{
public void
messageLogged(
int type,
String message )
{
model.getLogArea().appendText( message+"\n");
}
public void
messageLogged(
String str,
Throwable error )
{
model.getLogArea().appendText( error.toString()+"\n");
}
});
dht_log =
new DHTLogger()
{
public void
log(
String str )
{
log.log( str );
}
public void
log(
Throwable e )
{
log.log( e );
}
public void
log(
int log_type,
String str )
{
if ( isEnabled( log_type )){
log.log( str );
}
}
public boolean
isEnabled(
int log_type )
{
if ( log_type == DHTLogger.LT_IP_FILTER ){
return( ipfilter_logging.getValue());
}
return( true );
}
public PluginInterface
getPluginInterface()
{
return( log.getLogger().getPluginInterface());
}
};
if (!enabled_param.getValue()){
model.getStatus().setText( "Disabled" );
status = STATUS_DISABLED;
init_sem.releaseForever();
return;
}
PluginInterface pi_upnp = plugin_interface.getPluginManager().getPluginInterfaceByClass( UPnPPlugin.class );
if ( pi_upnp == null ){
log.log( "UPnP plugin not found, can't map port" );
}else{
upnp_mapping = ((UPnPPlugin)pi_upnp.getPlugin()).addMapping(
plugin_interface.getPluginName(),
false,
dht_data_port,
true );
}
setPluginInfo();
plugin_interface.addListener(
new PluginListener()
{
public void
initializationComplete()
{
String ip = null;
if ( advanced.getValue()){
ip = override_ip.getValue().trim();
if ( ip.length() == 0 ){
ip = null;
}
}
initComplete( model.getStatus(), logging.getValue(), ip );
}
public void
closedownInitiated()
{
if ( dhts != null ){
for (int i=0;i<dhts.length;i++){
dhts[i].closedownInitiated();
}
}
}
public void
closedownComplete()
{
}
});
final int sample_frequency = 60*1000;
final int sample_stats_ticks = 15; // every 15 mins
plugin_interface.getUtilities().createTimer("DHTStats", true ).addPeriodicEvent(
sample_frequency,
new UTTimerEventPerformer()
{
public void
perform(
UTTimerEvent event )
{
if ( dhts != null ){
for (int i=0;i<dhts.length;i++){
dhts[i].updateStats( sample_stats_ticks );
}
}
setPluginInfo();
}
});
}
protected void
changePort(
int _new_port )
{
// don't check for new_port being dht_data_port here as we want to continue to pick up
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -