/* * Created on 09-Dec-2004 * Created by Paul Gardner * Copyright (C) 2004 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, SARL au capital de 30,000 euros * 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France. * */ package com.aelitis.azureus.plugins.networks.i2p; import java.io.*; import java.net.URL; import java.net.URLClassLoader; import java.text.SimpleDateFormat; import java.util.*; 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.config.*; import org.gudy.azureus2.plugins.ui.model.BasicPluginConfigModel; import org.gudy.azureus2.plugins.ui.model.BasicPluginViewModel; import org.gudy.azureus2.plugins.utils.LocaleUtilities; import com.aelitis.azureus.core.proxy.socks.AESocksProxyFactory; import com.aelitis.azureus.plugins.upnp.UPnPMapping; import com.aelitis.azureus.plugins.upnp.UPnPPlugin; /** * @author parg * */ public class I2PPlugin implements Plugin { private static final int PROXY_CON_TIMEOUT = 120*1000; private static final int PROXY_READ_TIMEOUT = 120*1000; protected PluginInterface plugin_interface; public static final String[] I2P_JARS = { "i2p.jar", "streaming.jar", "mstreaming.jar", "jbigi.jar" }; public static final String CONFIG_ENABLE = "enable"; public static final boolean CONFIG_ENABLE_DEFAULT = true; public static final String CONFIG_PROXY_PORT = "proxy_port"; public static final int CONFIG_PROXY_PORT_DEFAULT = 0; //public static final String CONFIG_PROXY_I2P_ONLY = "proxy_i2p_only"; //public static final boolean CONFIG_PROXY_I2P_ONLY_DEFAULT = false; public static final String CONFIG_I2P_LOCATION = "i2p_location"; public static String CONFIG_I2P_LOCATION_DEFAULT = "/home/mic/i2p"; public static final String CONFIG_UPNP_ENABLE = "upnp_enable"; public static final boolean CONFIG_UPNP_ENABLE_DEFAULT = false; public static final String CONFIG_UPNP_LEAVE_MAPPING = "upnp_persistent_mapping"; public static final boolean CONFIG_UPNP_LEAVE_MAPPING_DEFAULT = true; public static final String CONFIG_UPNP_PORT = "upnp_port"; public static final int CONFIG_UPNP_PORT_DEFAULT = 8887; public static final String CONFIG_I2P_ROUTER_HOST = "i2p_router_host"; public static final String CONFIG_I2P_ROUTER_HOST_DEFAULT = "localhost"; public static final String CONFIG_I2P_ROUTER_PORT = "i2p_router_port"; public static final int CONFIG_I2P_ROUTER_PORT_DEFAULT = 7654; public static final String CONFIG_I2P_ROUTER_OPTIONS = "i2p_router_options"; public static final String CONFIG_I2P_ROUTER_OPTIONS_DEFAULT = ""; public static final String CONFIG_TRACE = "trace"; public static final boolean CONFIG_TRACE_DEFAULT = false; protected LoggerChannel log; protected LoggerChannelListener log_temp; protected List logs = new ArrayList(); protected BooleanParameter enable; protected IntParameter proxy_port; //protected BooleanParameter proxy_i2p_only; protected BooleanParameter upnp_enable; protected IntParameter upnp_port; protected BooleanParameter upnp_persist; protected StringParameter i2p_router_host; protected IntParameter i2p_router_port; protected StringParameter i2p_router_options; protected BooleanParameter trace; public void load( PluginInterface _plugin_interface ) { plugin_interface = _plugin_interface; log = plugin_interface.getLogger().getChannel( "I2P Network Plugin"); if ( plugin_interface.getUtilities().isWindows()){ String win_def = "C:\\Program Files\\i2p"; if ( new File(win_def).exists()){ CONFIG_I2P_LOCATION_DEFAULT = win_def; } } log_temp = new LoggerChannelListener() { public void messageLogged( int type, String content ) { logs.add( content ); } public void messageLogged( String str, Throwable error ) { if ( str.length() > 0 ){ logs.add( str ); } http://rt.com/news/right-nationalists-storm-ukraine-701/ logs.add( Debug.getNestedExceptionMessage( error )); } }; log.addListener( log_temp ); UIManager ui_manager = plugin_interface.getUIManager(); BasicPluginConfigModel config_model = ui_manager.createBasicPluginConfigModel( "plugins", "i2pnet.name"); enable = config_model.addBooleanParameter2( CONFIG_ENABLE, "i2pnet.enable", CONFIG_ENABLE_DEFAULT ); LabelParameter lab1 = config_model.addLabelParameter2( "i2pnet.proxy_port.info" ); proxy_port = config_model.addIntParameter2( CONFIG_PROXY_PORT, "i2pnet.proxy_port", CONFIG_PROXY_PORT_DEFAULT ); /* * this doesn't work as Java will revert to not using the proxy if it fails. GRRRRRRRRRRR * proxy_i2p_only = config_model.addBooleanParameter2( CONFIG_PROXY_I2P_ONLY, "i2pnet.proxy_i2p_only", CONFIG_PROXY_I2P_ONLY_DEFAULT ); LabelParameter lab2 = config_model.addLabelParameter2( "i2pnet.proxy_i2p_only.info" ); config_model.createGroup( "i2pnet.i2p_only_group", new Parameter[]{ proxy_i2p_only, lab2 }); */ DirectoryParameter location = config_model.addDirectoryParameter2( CONFIG_I2P_LOCATION, "i2pnet.i2p_location", CONFIG_I2P_LOCATION_DEFAULT ); upnp_enable = config_model.addBooleanParameter2( CONFIG_UPNP_ENABLE, "i2pnet.upnp_enable", CONFIG_UPNP_ENABLE_DEFAULT ); upnp_persist = config_model.addBooleanParameter2( CONFIG_UPNP_LEAVE_MAPPING, "i2pnet.upnp_persist", CONFIG_UPNP_LEAVE_MAPPING_DEFAULT ); upnp_port = config_model.addIntParameter2( CONFIG_UPNP_PORT, "i2pnet.upnp_port", CONFIG_UPNP_PORT_DEFAULT ); config_model.createGroup( "i2pnet.upnp_group", new Parameter[]{ upnp_enable, upnp_persist, upnp_port }); // I2P Router stuff LabelParameter i2p_lab = config_model.addLabelParameter2( "i2pnet.i2p_options.info" ); i2p_router_host = config_model.addStringParameter2( CONFIG_I2P_ROUTER_HOST, "i2pnet.i2p_router_host", CONFIG_I2P_ROUTER_HOST_DEFAULT ); i2p_router_port = config_model.addIntParameter2( CONFIG_I2P_ROUTER_PORT, "i2pnet.i2p_router_port", CONFIG_I2P_ROUTER_PORT_DEFAULT ); i2p_router_options = config_model.addStringParameter2( CONFIG_I2P_ROUTER_OPTIONS, "i2pnet.i2p_router_options", CONFIG_I2P_ROUTER_OPTIONS_DEFAULT ); config_model.createGroup( "i2pnet.i2p_router_group", new Parameter[]{ i2p_lab, i2p_router_host, i2p_router_port, i2p_router_options }); trace = config_model.addBooleanParameter2( CONFIG_TRACE, "i2pnet.trace_enable", CONFIG_TRACE_DEFAULT ); enable.addEnabledOnSelection( proxy_port ); // enable.addEnabledOnSelection( proxy_i2p_only ); enable.addEnabledOnSelection( lab1 ); // enable.addEnabledOnSelection( lab2 ); enable.addEnabledOnSelection( location ); enable.addEnabledOnSelection( upnp_enable ); ParameterListener pl = new ParameterListener() { public void parameterChanged( Parameter param ) { upnp_port.setEnabled( enable.getValue() && upnp_enable.getValue()); upnp_persist.setEnabled( enable.getValue() && upnp_enable.getValue()); } }; enable.addListener( pl ); upnp_enable.addListener( pl ); pl.parameterChanged(null); enable.addEnabledOnSelection( i2p_lab ); enable.addEnabledOnSelection( i2p_router_host ); enable.addEnabledOnSelection( i2p_router_port ); enable.addEnabledOnSelection( i2p_router_options ); enable.addEnabledOnSelection( trace ); if ( enable.getValue()){ boolean bad = false; boolean alert = false; try{ String loc = location.getValue(); if ( loc.length() == 0 || !new File(loc).exists()){ bad = true; alert = true; throw( new Exception( "I2P install location not defined, plugin initialisation failed." )); } File lib = new File( loc, "lib" ); URL[] jars = new URL[I2P_JARS.length]; for (int i=0;i<jars.length;i++){ File jar = new File(lib,I2P_JARS[i] ); if ( !jar.exists()){ bad = true; throw( new Exception( "I2P jar file '" + jar + "' not found" )); } jars[i] = jar.toURL(); } ClassLoader class_loader = getClass().getClassLoader(); if ( class_loader instanceof URLClassLoader ){ URL[] old = ((URLClassLoader)class_loader).getURLs(); URL[] new_urls = new URL[old.length+jars.length]; System.arraycopy( old, 0, new_urls, 0, old.length ); System.arraycopy( jars, 0, new_urls, old.length, jars.length ); class_loader = new URLClassLoader( new_urls, class_loader ); }else{ class_loader = new URLClassLoader(jars,class_loader); } int port = proxy_port.getValue(); if ( port == 0 ){ bad = true; throw( new Exception( "I2P poxy port not defined, can't initialise" )); } final I2PPluginConnectionManager con_man = new I2PPluginConnectionManager( class_loader, log ); AESocksProxyFactory.create( port, PROXY_CON_TIMEOUT, PROXY_READ_TIMEOUT, con_man ); log.log( "Established network proxy on port " + port ); plugin_interface.addListener( new PluginListener() { public void initializationComplete() { con_man.initialise( i2p_router_host, i2p_router_port, i2p_router_options, trace ); // proxy_i2p_only ); } public void closedownInitiated() { con_man.closedown(); } public void closedownComplete() { } }); }catch( Throwable e ){ if ( bad ){ if ( alert ){ log.logAlert( LoggerChannel.LT_ERROR, e.getMessage()); }else{ log.log( e.getMessage()); } }else{ log.log(e); } } } } public void initialize( PluginInterface _plugin_interface ) { LocaleUtilities loc_utils = plugin_interface.getUtilities().getLocaleUtilities(); UIManager ui_manager = plugin_interface.getUIManager(); final BasicPluginViewModel view_model = ui_manager.createBasicPluginViewModel( loc_utils.getLocalisedMessageText( "i2pnet.name" )); view_model.getActivity().setVisible( false ); view_model.getProgress().setVisible( false ); log.removeListener( log_temp ); log.addListener( new LoggerChannelListener() { public void messageLogged( int type, String content ) { view_model.getLogArea().appendText( getTimeStamp() + content + "\n" ); } public void messageLogged( String str, Throwable error ) { if ( str.length() > 0 ){ view_model.getLogArea().appendText( getTimeStamp() + str + "\n" ); } view_model.getLogArea().appendText( getTimeStamp() + Debug.getNestedExceptionMessage(error) + "\n" ); } protected String getTimeStamp() { return( "[" + new SimpleDateFormat( "HH:mm:ss" ).format(new Date()) + "] " ); } }); for (int i=0;i<logs.size();i++){ log.log((String)logs.get(i)); } logs.clear(); view_model.getStatus().setText( enable.getValue()?"Enabled":"Disabled"); enable.addListener( new ParameterListener() { public void parameterChanged( Parameter p ) { view_model.getStatus().setText( enable.getValue()?"Enabled":"Disabled"); } }); if ( enable.getValue()){ if ( plugin_interface.getPluginconfig().getBooleanParameter( PluginConfig.CORE_PARAM_BOOLEAN_SOCKS_PROXY_NO_INWARD_CONNECTION )){ log.logAlert( LoggerChannel.LT_ERROR, "I2P Plugin requires that the 'inform tracker of limitation' setting for 'Connection' is deselected - please amend it" ); } plugin_interface.addListener( new PluginListener() { public void initializationComplete() { PluginInterface pi_upnp = plugin_interface.getPluginManager().getPluginInterfaceByClass( UPnPPlugin.class ); if ( pi_upnp == null ){ log.log( "No UPnP plugin available, not attempting port mapping"); }else{ if ( upnp_enable.getValue()){ UPnPMapping mapping = ((UPnPPlugin)pi_upnp.getPlugin()).addMapping( plugin_interface.getPluginName(), true, upnp_port.getValue(), true ); if ( upnp_persist.getValue()){ mapping.setPersistent( UPnPMapping.PT_PERSISTENT ); } }else{ log.log( "UPnP disabled for the plugin, not attempting port mapping"); } } } public void closedownInitiated() { } public void closedownComplete() { } }); } } }