forked from I2P_Developers/i2p.i2p
* i2ptunnel:
- Refactor TCG to use ClientApp interface - Remove 'reload config' button - Synchronization fixes - Don't instantiate early, to allow router to hold a reference. TCG.getInstance() may now return null when in RouterContext. - Jsps display message when TCG not initialized
This commit is contained in:
@@ -12,6 +12,8 @@ import java.util.Properties;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import net.i2p.I2PAppContext;
|
import net.i2p.I2PAppContext;
|
||||||
|
import net.i2p.app.*;
|
||||||
|
import static net.i2p.app.ClientAppState.*;
|
||||||
import net.i2p.client.I2PSession;
|
import net.i2p.client.I2PSession;
|
||||||
import net.i2p.client.I2PSessionException;
|
import net.i2p.client.I2PSessionException;
|
||||||
import net.i2p.data.DataHelper;
|
import net.i2p.data.DataHelper;
|
||||||
@@ -23,16 +25,21 @@ import net.i2p.util.OrderedProperties;
|
|||||||
* Coordinate a set of tunnels within the JVM, loading and storing their config
|
* Coordinate a set of tunnels within the JVM, loading and storing their config
|
||||||
* to disk, and building new ones as requested.
|
* to disk, and building new ones as requested.
|
||||||
*
|
*
|
||||||
* Warning - this is a singleton. Todo: fix
|
* This is the entry point from clients.config.
|
||||||
*/
|
*/
|
||||||
public class TunnelControllerGroup {
|
public class TunnelControllerGroup implements ClientApp {
|
||||||
private Log _log;
|
private final Log _log;
|
||||||
private static TunnelControllerGroup _instance;
|
private volatile ClientAppState _state;
|
||||||
|
private final I2PAppContext _context;
|
||||||
|
private final ClientAppManager _mgr;
|
||||||
|
private static volatile TunnelControllerGroup _instance;
|
||||||
static final String DEFAULT_CONFIG_FILE = "i2ptunnel.config";
|
static final String DEFAULT_CONFIG_FILE = "i2ptunnel.config";
|
||||||
|
|
||||||
private final List<TunnelController> _controllers;
|
private final List<TunnelController> _controllers;
|
||||||
private String _configFile = DEFAULT_CONFIG_FILE;
|
private final String _configFile;
|
||||||
|
|
||||||
|
private static final String REGISTERED_NAME = "i2ptunnel";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Map of I2PSession to a Set of TunnelController objects
|
* Map of I2PSession to a Set of TunnelController objects
|
||||||
* using the session (to prevent closing the session until
|
* using the session (to prevent closing the session until
|
||||||
@@ -41,48 +48,143 @@ public class TunnelControllerGroup {
|
|||||||
*/
|
*/
|
||||||
private final Map<I2PSession, Set<TunnelController>> _sessions;
|
private final Map<I2PSession, Set<TunnelController>> _sessions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* In I2PAppContext will instantiate if necessary and always return non-null.
|
||||||
|
* As of 0.9.4, when in RouterContext, will return null
|
||||||
|
* if the TCG has not yet been started by the router.
|
||||||
|
*
|
||||||
|
* @throws IllegalArgumentException if unable to load from i2ptunnel.config
|
||||||
|
*/
|
||||||
public static TunnelControllerGroup getInstance() {
|
public static TunnelControllerGroup getInstance() {
|
||||||
synchronized (TunnelControllerGroup.class) {
|
synchronized (TunnelControllerGroup.class) {
|
||||||
if (_instance == null)
|
if (_instance == null) {
|
||||||
_instance = new TunnelControllerGroup(DEFAULT_CONFIG_FILE);
|
I2PAppContext ctx = I2PAppContext.getGlobalContext();
|
||||||
|
if (!ctx.isRouterContext()) {
|
||||||
|
_instance = new TunnelControllerGroup(ctx, null, null);
|
||||||
|
_instance.startup();
|
||||||
|
} // else wait for the router to start it
|
||||||
|
}
|
||||||
return _instance;
|
return _instance;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private TunnelControllerGroup(String configFile) {
|
/**
|
||||||
_log = I2PAppContext.getGlobalContext().logManager().getLog(TunnelControllerGroup.class);
|
* Instantiation only. Caller must call startup().
|
||||||
_controllers = Collections.synchronizedList(new ArrayList());
|
* Config file problems will not throw exception until startup().
|
||||||
_configFile = configFile;
|
*
|
||||||
|
* @param mgr may be null
|
||||||
|
* @param args one arg, the config file, if not absolute will be relative to the context's config dir,
|
||||||
|
* if empty or null, the default is i2ptunnel.config
|
||||||
|
* @since 0.9.4
|
||||||
|
*/
|
||||||
|
public TunnelControllerGroup(I2PAppContext context, ClientAppManager mgr, String[] args) {
|
||||||
|
_state = UNINITIALIZED;
|
||||||
|
_context = context;
|
||||||
|
_mgr = mgr;
|
||||||
|
_log = _context.logManager().getLog(TunnelControllerGroup.class);
|
||||||
|
_controllers = new ArrayList();
|
||||||
|
if (args == null || args.length <= 0)
|
||||||
|
_configFile = DEFAULT_CONFIG_FILE;
|
||||||
|
else if (args.length == 1)
|
||||||
|
_configFile = args[0];
|
||||||
|
else
|
||||||
|
throw new IllegalArgumentException("Usage: TunnelControllerGroup [filename]");
|
||||||
_sessions = new HashMap(4);
|
_sessions = new HashMap(4);
|
||||||
loadControllers(_configFile);
|
synchronized (TunnelControllerGroup.class) {
|
||||||
I2PAppContext.getGlobalContext().addShutdownTask(new Shutdown());
|
if (_instance == null)
|
||||||
|
_instance = this;
|
||||||
|
}
|
||||||
|
if (_instance != this) {
|
||||||
|
_log.logAlways(Log.WARN, "New TunnelControllerGroup, now you have two");
|
||||||
|
if (_log.shouldLog(Log.WARN))
|
||||||
|
_log.warn("I did it", new Exception());
|
||||||
|
}
|
||||||
|
_state = INITIALIZED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param args one arg, the config file, if not absolute will be relative to the context's config dir,
|
||||||
|
* if no args, the default is i2ptunnel.config
|
||||||
|
* @throws IllegalArgumentException if unable to load from config from file
|
||||||
|
*/
|
||||||
public static void main(String args[]) {
|
public static void main(String args[]) {
|
||||||
synchronized (TunnelControllerGroup.class) {
|
synchronized (TunnelControllerGroup.class) {
|
||||||
if (_instance != null) return; // already loaded through the web
|
if (_instance != null) return; // already loaded through the web
|
||||||
|
_instance = new TunnelControllerGroup(I2PAppContext.getGlobalContext(), null, args);
|
||||||
if ( (args == null) || (args.length <= 0) ) {
|
_instance.startup();
|
||||||
_instance = new TunnelControllerGroup(DEFAULT_CONFIG_FILE);
|
|
||||||
} else if (args.length == 1) {
|
|
||||||
_instance = new TunnelControllerGroup(args[0]);
|
|
||||||
} else {
|
|
||||||
System.err.println("Usage: TunnelControllerGroup [filename]");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ClientApp interface
|
||||||
|
* @throws IllegalArgumentException if unable to load config from file
|
||||||
|
* @since 0.9.4
|
||||||
|
*/
|
||||||
|
public void startup() {
|
||||||
|
loadControllers(_configFile);
|
||||||
|
if (_mgr != null)
|
||||||
|
_mgr.register(this);
|
||||||
|
_context.addShutdownTask(new Shutdown());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ClientApp interface
|
||||||
|
* @since 0.9.4
|
||||||
|
*/
|
||||||
|
public ClientAppState getState() {
|
||||||
|
return _state;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ClientApp interface
|
||||||
|
* @since 0.9.4
|
||||||
|
*/
|
||||||
|
public String getName() {
|
||||||
|
return REGISTERED_NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ClientApp interface
|
||||||
|
* @since 0.9.4
|
||||||
|
*/
|
||||||
|
public String getDisplayName() {
|
||||||
|
return REGISTERED_NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 0.9.4
|
||||||
|
*/
|
||||||
|
private void changeState(ClientAppState state) {
|
||||||
|
changeState(state, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 0.9.4
|
||||||
|
*/
|
||||||
|
private synchronized void changeState(ClientAppState state, Exception e) {
|
||||||
|
_state = state;
|
||||||
|
if (_mgr != null)
|
||||||
|
_mgr.notify(this, state, null, e);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Warning - destroys the singleton!
|
* Warning - destroys the singleton!
|
||||||
* @since 0.8.8
|
* @since 0.8.8
|
||||||
*/
|
*/
|
||||||
private static class Shutdown implements Runnable {
|
private class Shutdown implements Runnable {
|
||||||
public void run() {
|
public void run() {
|
||||||
shutdown();
|
shutdown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ClientApp interface
|
||||||
|
* @since 0.9.4
|
||||||
|
*/
|
||||||
|
public void shutdown(String[] args) {
|
||||||
|
shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Warning - destroys the singleton!
|
* Warning - destroys the singleton!
|
||||||
* Caller must root a new context before calling instance() or main() again.
|
* Caller must root a new context before calling instance() or main() again.
|
||||||
@@ -91,28 +193,31 @@ public class TunnelControllerGroup {
|
|||||||
*
|
*
|
||||||
* @since 0.8.8
|
* @since 0.8.8
|
||||||
*/
|
*/
|
||||||
public static void shutdown() {
|
public void shutdown() {
|
||||||
|
changeState(STOPPING);
|
||||||
|
if (_mgr != null)
|
||||||
|
_mgr.unregister(this);
|
||||||
|
unloadControllers();
|
||||||
synchronized (TunnelControllerGroup.class) {
|
synchronized (TunnelControllerGroup.class) {
|
||||||
if (_instance == null) return;
|
if (_instance == this)
|
||||||
_instance.unloadControllers();
|
_instance = null;
|
||||||
_instance._log = null;
|
|
||||||
_instance = null;
|
|
||||||
}
|
}
|
||||||
|
/// fixme static
|
||||||
I2PTunnelClientBase.killClientExecutor();
|
I2PTunnelClientBase.killClientExecutor();
|
||||||
|
changeState(STOPPED);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load up all of the tunnels configured in the given file (but do not start
|
* Load up all of the tunnels configured in the given file (but do not start
|
||||||
* them)
|
* them)
|
||||||
*
|
*
|
||||||
|
* DEPRECATED for use outside this class. Use startup() or getInstance().
|
||||||
|
*
|
||||||
|
* @throws IllegalArgumentException if unable to load from file
|
||||||
*/
|
*/
|
||||||
public void loadControllers(String configFile) {
|
public synchronized void loadControllers(String configFile) {
|
||||||
|
changeState(STARTING);
|
||||||
Properties cfg = loadConfig(configFile);
|
Properties cfg = loadConfig(configFile);
|
||||||
if (cfg == null) {
|
|
||||||
if (_log.shouldLog(Log.WARN))
|
|
||||||
_log.warn("Unable to load the config from " + configFile);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while (true) {
|
while (true) {
|
||||||
String type = cfg.getProperty("tunnel." + i + ".type");
|
String type = cfg.getProperty("tunnel." + i + ".type");
|
||||||
@@ -127,20 +232,28 @@ public class TunnelControllerGroup {
|
|||||||
|
|
||||||
if (_log.shouldLog(Log.INFO))
|
if (_log.shouldLog(Log.INFO))
|
||||||
_log.info(i + " controllers loaded from " + configFile);
|
_log.info(i + " controllers loaded from " + configFile);
|
||||||
|
changeState(RUNNING);
|
||||||
}
|
}
|
||||||
|
|
||||||
private class StartControllers implements Runnable {
|
private class StartControllers implements Runnable {
|
||||||
public void run() {
|
public void run() {
|
||||||
for (int i = 0; i < _controllers.size(); i++) {
|
synchronized(TunnelControllerGroup.this) {
|
||||||
TunnelController controller = _controllers.get(i);
|
for (int i = 0; i < _controllers.size(); i++) {
|
||||||
if (controller.getStartOnLoad())
|
TunnelController controller = _controllers.get(i);
|
||||||
controller.startTunnel();
|
if (controller.getStartOnLoad())
|
||||||
|
controller.startTunnel();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
public void reloadControllers() {
|
* Stop all tunnels, reload config, and restart those configured to do so.
|
||||||
|
* WARNING - Does NOT simply reload the configuration!!! This is probably not what you want.
|
||||||
|
*
|
||||||
|
* @throws IllegalArgumentException if unable to reload config file
|
||||||
|
*/
|
||||||
|
public synchronized void reloadControllers() {
|
||||||
unloadControllers();
|
unloadControllers();
|
||||||
loadControllers(_configFile);
|
loadControllers(_configFile);
|
||||||
}
|
}
|
||||||
@@ -150,7 +263,7 @@ public class TunnelControllerGroup {
|
|||||||
* file or do other silly things)
|
* file or do other silly things)
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public void unloadControllers() {
|
public synchronized void unloadControllers() {
|
||||||
stopAllControllers();
|
stopAllControllers();
|
||||||
_controllers.clear();
|
_controllers.clear();
|
||||||
if (_log.shouldLog(Log.INFO))
|
if (_log.shouldLog(Log.INFO))
|
||||||
@@ -162,14 +275,14 @@ public class TunnelControllerGroup {
|
|||||||
* a config file or start it or anything)
|
* a config file or start it or anything)
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public void addController(TunnelController controller) { _controllers.add(controller); }
|
public synchronized void addController(TunnelController controller) { _controllers.add(controller); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stop and remove the given tunnel
|
* Stop and remove the given tunnel
|
||||||
*
|
*
|
||||||
* @return list of messages from the controller as it is stopped
|
* @return list of messages from the controller as it is stopped
|
||||||
*/
|
*/
|
||||||
public List<String> removeController(TunnelController controller) {
|
public synchronized List<String> removeController(TunnelController controller) {
|
||||||
if (controller == null) return new ArrayList();
|
if (controller == null) return new ArrayList();
|
||||||
controller.stopTunnel();
|
controller.stopTunnel();
|
||||||
List<String> msgs = controller.clearMessages();
|
List<String> msgs = controller.clearMessages();
|
||||||
@@ -183,7 +296,7 @@ public class TunnelControllerGroup {
|
|||||||
*
|
*
|
||||||
* @return list of messages the tunnels generate when stopped
|
* @return list of messages the tunnels generate when stopped
|
||||||
*/
|
*/
|
||||||
public List<String> stopAllControllers() {
|
public synchronized List<String> stopAllControllers() {
|
||||||
List<String> msgs = new ArrayList();
|
List<String> msgs = new ArrayList();
|
||||||
for (int i = 0; i < _controllers.size(); i++) {
|
for (int i = 0; i < _controllers.size(); i++) {
|
||||||
TunnelController controller = _controllers.get(i);
|
TunnelController controller = _controllers.get(i);
|
||||||
@@ -200,7 +313,7 @@ public class TunnelControllerGroup {
|
|||||||
*
|
*
|
||||||
* @return list of messages the tunnels generate when started
|
* @return list of messages the tunnels generate when started
|
||||||
*/
|
*/
|
||||||
public List<String> startAllControllers() {
|
public synchronized List<String> startAllControllers() {
|
||||||
List<String> msgs = new ArrayList();
|
List<String> msgs = new ArrayList();
|
||||||
for (int i = 0; i < _controllers.size(); i++) {
|
for (int i = 0; i < _controllers.size(); i++) {
|
||||||
TunnelController controller = _controllers.get(i);
|
TunnelController controller = _controllers.get(i);
|
||||||
@@ -218,7 +331,7 @@ public class TunnelControllerGroup {
|
|||||||
*
|
*
|
||||||
* @return list of messages the tunnels generate when restarted
|
* @return list of messages the tunnels generate when restarted
|
||||||
*/
|
*/
|
||||||
public List<String> restartAllControllers() {
|
public synchronized List<String> restartAllControllers() {
|
||||||
List<String> msgs = new ArrayList();
|
List<String> msgs = new ArrayList();
|
||||||
for (int i = 0; i < _controllers.size(); i++) {
|
for (int i = 0; i < _controllers.size(); i++) {
|
||||||
TunnelController controller = _controllers.get(i);
|
TunnelController controller = _controllers.get(i);
|
||||||
@@ -235,7 +348,7 @@ public class TunnelControllerGroup {
|
|||||||
*
|
*
|
||||||
* @return list of messages the tunnels have generated
|
* @return list of messages the tunnels have generated
|
||||||
*/
|
*/
|
||||||
public List<String> clearAllMessages() {
|
public synchronized List<String> clearAllMessages() {
|
||||||
List<String> msgs = new ArrayList();
|
List<String> msgs = new ArrayList();
|
||||||
for (int i = 0; i < _controllers.size(); i++) {
|
for (int i = 0; i < _controllers.size(); i++) {
|
||||||
TunnelController controller = _controllers.get(i);
|
TunnelController controller = _controllers.get(i);
|
||||||
@@ -257,8 +370,7 @@ public class TunnelControllerGroup {
|
|||||||
* Save the configuration of all known tunnels to the given file
|
* Save the configuration of all known tunnels to the given file
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public void saveConfig(String configFile) throws IOException {
|
public synchronized void saveConfig(String configFile) throws IOException {
|
||||||
_configFile = configFile;
|
|
||||||
File cfgFile = new File(configFile);
|
File cfgFile = new File(configFile);
|
||||||
if (!cfgFile.isAbsolute())
|
if (!cfgFile.isAbsolute())
|
||||||
cfgFile = new File(I2PAppContext.getGlobalContext().getConfigDir(), configFile);
|
cfgFile = new File(I2PAppContext.getGlobalContext().getConfigDir(), configFile);
|
||||||
@@ -279,16 +391,17 @@ public class TunnelControllerGroup {
|
|||||||
/**
|
/**
|
||||||
* Load up the config data from the file
|
* Load up the config data from the file
|
||||||
*
|
*
|
||||||
* @return properties loaded or null if there was an error
|
* @return properties loaded
|
||||||
|
* @throws IllegalArgumentException if unable to load from file
|
||||||
*/
|
*/
|
||||||
private Properties loadConfig(String configFile) {
|
private synchronized Properties loadConfig(String configFile) {
|
||||||
File cfgFile = new File(configFile);
|
File cfgFile = new File(configFile);
|
||||||
if (!cfgFile.isAbsolute())
|
if (!cfgFile.isAbsolute())
|
||||||
cfgFile = new File(I2PAppContext.getGlobalContext().getConfigDir(), configFile);
|
cfgFile = new File(I2PAppContext.getGlobalContext().getConfigDir(), configFile);
|
||||||
if (!cfgFile.exists()) {
|
if (!cfgFile.exists()) {
|
||||||
if (_log.shouldLog(Log.ERROR))
|
if (_log.shouldLog(Log.ERROR))
|
||||||
_log.error("Unable to load the controllers from " + cfgFile.getAbsolutePath());
|
_log.error("Unable to load the controllers from " + cfgFile.getAbsolutePath());
|
||||||
return null;
|
throw new IllegalArgumentException("Unable to load the controllers from " + cfgFile.getAbsolutePath());
|
||||||
}
|
}
|
||||||
|
|
||||||
Properties props = new Properties();
|
Properties props = new Properties();
|
||||||
@@ -298,7 +411,7 @@ public class TunnelControllerGroup {
|
|||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
if (_log.shouldLog(Log.ERROR))
|
if (_log.shouldLog(Log.ERROR))
|
||||||
_log.error("Error reading the controllers from " + cfgFile.getAbsolutePath(), ioe);
|
_log.error("Error reading the controllers from " + cfgFile.getAbsolutePath(), ioe);
|
||||||
return null;
|
throw new IllegalArgumentException("Error reading the controllers from " + cfgFile.getAbsolutePath(), ioe);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -307,7 +420,9 @@ public class TunnelControllerGroup {
|
|||||||
*
|
*
|
||||||
* @return list of TunnelController objects
|
* @return list of TunnelController objects
|
||||||
*/
|
*/
|
||||||
public List<TunnelController> getControllers() { return _controllers; }
|
public synchronized List<TunnelController> getControllers() {
|
||||||
|
return new ArrayList(_controllers);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -29,8 +29,8 @@ import net.i2p.util.Addresses;
|
|||||||
/**
|
/**
|
||||||
* Ugly little accessor for the edit page
|
* Ugly little accessor for the edit page
|
||||||
*
|
*
|
||||||
* Warning - This class is not part of the i2ptunnel API, and at some point
|
* Warning - This class is not part of the i2ptunnel API,
|
||||||
* it will be moved from the jar to the war.
|
* it has been moved from the jar to the war.
|
||||||
* Usage by classes outside of i2ptunnel.war is deprecated.
|
* Usage by classes outside of i2ptunnel.war is deprecated.
|
||||||
*/
|
*/
|
||||||
public class EditBean extends IndexBean {
|
public class EditBean extends IndexBean {
|
||||||
@@ -38,6 +38,8 @@ public class EditBean extends IndexBean {
|
|||||||
|
|
||||||
public static boolean staticIsClient(int tunnel) {
|
public static boolean staticIsClient(int tunnel) {
|
||||||
TunnelControllerGroup group = TunnelControllerGroup.getInstance();
|
TunnelControllerGroup group = TunnelControllerGroup.getInstance();
|
||||||
|
if (group == null)
|
||||||
|
return false;
|
||||||
List controllers = group.getControllers();
|
List controllers = group.getControllers();
|
||||||
if (controllers.size() > tunnel) {
|
if (controllers.size() > tunnel) {
|
||||||
TunnelController cur = (TunnelController)controllers.get(tunnel);
|
TunnelController cur = (TunnelController)controllers.get(tunnel);
|
||||||
@@ -55,6 +57,7 @@ public class EditBean extends IndexBean {
|
|||||||
else
|
else
|
||||||
return "127.0.0.1";
|
return "127.0.0.1";
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getTargetPort(int tunnel) {
|
public String getTargetPort(int tunnel) {
|
||||||
TunnelController tun = getController(tunnel);
|
TunnelController tun = getController(tunnel);
|
||||||
if (tun != null && tun.getTargetPort() != null)
|
if (tun != null && tun.getTargetPort() != null)
|
||||||
@@ -62,6 +65,7 @@ public class EditBean extends IndexBean {
|
|||||||
else
|
else
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getSpoofedHost(int tunnel) {
|
public String getSpoofedHost(int tunnel) {
|
||||||
TunnelController tun = getController(tunnel);
|
TunnelController tun = getController(tunnel);
|
||||||
if (tun != null && tun.getSpoofedHost() != null)
|
if (tun != null && tun.getSpoofedHost() != null)
|
||||||
@@ -69,12 +73,13 @@ public class EditBean extends IndexBean {
|
|||||||
else
|
else
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getPrivateKeyFile(int tunnel) {
|
public String getPrivateKeyFile(int tunnel) {
|
||||||
TunnelController tun = getController(tunnel);
|
TunnelController tun = getController(tunnel);
|
||||||
if (tun != null && tun.getPrivKeyFile() != null)
|
if (tun != null && tun.getPrivKeyFile() != null)
|
||||||
return tun.getPrivKeyFile();
|
return tun.getPrivKeyFile();
|
||||||
if (tunnel < 0)
|
if (tunnel < 0)
|
||||||
tunnel = _group.getControllers().size();
|
tunnel = _group == null ? 1 : _group.getControllers().size() + 1;
|
||||||
return "i2ptunnel" + tunnel + "-privKeys.dat";
|
return "i2ptunnel" + tunnel + "-privKeys.dat";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -42,14 +42,15 @@ import net.i2p.util.PasswordManager;
|
|||||||
/**
|
/**
|
||||||
* Simple accessor for exposing tunnel info, but also an ugly form handler
|
* Simple accessor for exposing tunnel info, but also an ugly form handler
|
||||||
*
|
*
|
||||||
* Warning - This class is not part of the i2ptunnel API, and at some point
|
* Warning - This class is not part of the i2ptunnel API,
|
||||||
* it will be moved from the jar to the war.
|
* it has been moved from the jar to the war.
|
||||||
* Usage by classes outside of i2ptunnel.war is deprecated.
|
* Usage by classes outside of i2ptunnel.war is deprecated.
|
||||||
*/
|
*/
|
||||||
public class IndexBean {
|
public class IndexBean {
|
||||||
protected final I2PAppContext _context;
|
protected final I2PAppContext _context;
|
||||||
protected final Log _log;
|
protected final Log _log;
|
||||||
protected final TunnelControllerGroup _group;
|
protected final TunnelControllerGroup _group;
|
||||||
|
private final String _fatalError;
|
||||||
private String _action;
|
private String _action;
|
||||||
private int _tunnel;
|
private int _tunnel;
|
||||||
//private long _prevNonce;
|
//private long _prevNonce;
|
||||||
@@ -110,7 +111,18 @@ public class IndexBean {
|
|||||||
public IndexBean() {
|
public IndexBean() {
|
||||||
_context = I2PAppContext.getGlobalContext();
|
_context = I2PAppContext.getGlobalContext();
|
||||||
_log = _context.logManager().getLog(IndexBean.class);
|
_log = _context.logManager().getLog(IndexBean.class);
|
||||||
_group = TunnelControllerGroup.getInstance();
|
TunnelControllerGroup tcg;
|
||||||
|
String error;
|
||||||
|
try {
|
||||||
|
tcg = TunnelControllerGroup.getInstance();
|
||||||
|
error = tcg == null ? _("Tunnels are not initialized yet, please reload in two minutes.")
|
||||||
|
: null;
|
||||||
|
} catch (IllegalArgumentException iae) {
|
||||||
|
tcg = null;
|
||||||
|
error = iae.toString();
|
||||||
|
}
|
||||||
|
_group = tcg;
|
||||||
|
_fatalError = error;
|
||||||
_tunnel = -1;
|
_tunnel = -1;
|
||||||
_curNonce = "-1";
|
_curNonce = "-1";
|
||||||
addNonce();
|
addNonce();
|
||||||
@@ -118,6 +130,13 @@ public class IndexBean {
|
|||||||
_otherOptions = new ConcurrentHashMap(4);
|
_otherOptions = new ConcurrentHashMap(4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 0.9.4
|
||||||
|
*/
|
||||||
|
public boolean isInitialized() {
|
||||||
|
return _group != null;
|
||||||
|
}
|
||||||
|
|
||||||
public static String getNextNonce() {
|
public static String getNextNonce() {
|
||||||
synchronized (_nonces) {
|
synchronized (_nonces) {
|
||||||
return _nonces.get(0);
|
return _nonces.get(0);
|
||||||
@@ -164,6 +183,8 @@ public class IndexBean {
|
|||||||
private String processAction() {
|
private String processAction() {
|
||||||
if ( (_action == null) || (_action.trim().length() <= 0) || ("Cancel".equals(_action)))
|
if ( (_action == null) || (_action.trim().length() <= 0) || ("Cancel".equals(_action)))
|
||||||
return "";
|
return "";
|
||||||
|
if (_group == null)
|
||||||
|
return "Error - tunnels are not initialized yet";
|
||||||
// If passwords are turned on, all is assumed good
|
// If passwords are turned on, all is assumed good
|
||||||
if (!_context.getBooleanProperty(PROP_PW_ENABLE) &&
|
if (!_context.getBooleanProperty(PROP_PW_ENABLE) &&
|
||||||
!haveNonce(_curNonce))
|
!haveNonce(_curNonce))
|
||||||
@@ -197,27 +218,27 @@ public class IndexBean {
|
|||||||
else
|
else
|
||||||
return "Action " + _action + " unknown";
|
return "Action " + _action + " unknown";
|
||||||
}
|
}
|
||||||
|
|
||||||
private String stopAll() {
|
private String stopAll() {
|
||||||
if (_group == null) return "";
|
|
||||||
List<String> msgs = _group.stopAllControllers();
|
List<String> msgs = _group.stopAllControllers();
|
||||||
return getMessages(msgs);
|
return getMessages(msgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String startAll() {
|
private String startAll() {
|
||||||
if (_group == null) return "";
|
|
||||||
List<String> msgs = _group.startAllControllers();
|
List<String> msgs = _group.startAllControllers();
|
||||||
return getMessages(msgs);
|
return getMessages(msgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String restartAll() {
|
private String restartAll() {
|
||||||
if (_group == null) return "";
|
|
||||||
List<String> msgs = _group.restartAllControllers();
|
List<String> msgs = _group.restartAllControllers();
|
||||||
return getMessages(msgs);
|
return getMessages(msgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String reloadConfig() {
|
private String reloadConfig() {
|
||||||
if (_group == null) return "";
|
|
||||||
|
|
||||||
_group.reloadControllers();
|
_group.reloadControllers();
|
||||||
return _("Configuration reloaded for all tunnels");
|
return _("Configuration reloaded for all tunnels");
|
||||||
}
|
}
|
||||||
|
|
||||||
private String start() {
|
private String start() {
|
||||||
if (_tunnel < 0) return "Invalid tunnel";
|
if (_tunnel < 0) return "Invalid tunnel";
|
||||||
|
|
||||||
@@ -372,7 +393,7 @@ public class IndexBean {
|
|||||||
*/
|
*/
|
||||||
public String getMessages() {
|
public String getMessages() {
|
||||||
if (_group == null)
|
if (_group == null)
|
||||||
return "";
|
return _fatalError;
|
||||||
|
|
||||||
StringBuilder buf = new StringBuilder(512);
|
StringBuilder buf = new StringBuilder(512);
|
||||||
if (_action != null) {
|
if (_action != null) {
|
||||||
|
@@ -31,7 +31,11 @@
|
|||||||
<body id="tunnelEditPage">
|
<body id="tunnelEditPage">
|
||||||
<div id="pageHeader">
|
<div id="pageHeader">
|
||||||
</div>
|
</div>
|
||||||
|
<%
|
||||||
|
|
||||||
|
if (editBean.isInitialized()) {
|
||||||
|
|
||||||
|
%>
|
||||||
<form method="post" action="list">
|
<form method="post" action="list">
|
||||||
|
|
||||||
<div id="tunnelEditPanel" class="panel">
|
<div id="tunnelEditPanel" class="panel">
|
||||||
@@ -508,5 +512,12 @@
|
|||||||
</form>
|
</form>
|
||||||
<div id="pageFooter">
|
<div id="pageFooter">
|
||||||
</div>
|
</div>
|
||||||
|
<%
|
||||||
|
|
||||||
|
} else {
|
||||||
|
%>Tunnels are not initialized yet, please reload in two minutes.<%
|
||||||
|
} // isInitialized()
|
||||||
|
|
||||||
|
%>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@@ -31,7 +31,11 @@
|
|||||||
<body id="tunnelEditPage">
|
<body id="tunnelEditPage">
|
||||||
<div id="pageHeader">
|
<div id="pageHeader">
|
||||||
</div>
|
</div>
|
||||||
|
<%
|
||||||
|
|
||||||
|
if (editBean.isInitialized()) {
|
||||||
|
|
||||||
|
%>
|
||||||
<form method="post" action="list">
|
<form method="post" action="list">
|
||||||
|
|
||||||
<div id="tunnelEditPanel" class="panel">
|
<div id="tunnelEditPanel" class="panel">
|
||||||
@@ -518,5 +522,12 @@
|
|||||||
</form>
|
</form>
|
||||||
<div id="pageFooter">
|
<div id="pageFooter">
|
||||||
</div>
|
</div>
|
||||||
|
<%
|
||||||
|
|
||||||
|
} else {
|
||||||
|
%>Tunnels are not initialized yet, please reload in two minutes.<%
|
||||||
|
} // isInitialized()
|
||||||
|
|
||||||
|
%>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@@ -55,12 +55,23 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<%
|
||||||
|
|
||||||
|
if (indexBean.isInitialized()) {
|
||||||
|
|
||||||
|
%>
|
||||||
<div id="globalOperationsPanel" class="panel">
|
<div id="globalOperationsPanel" class="panel">
|
||||||
<div class="header"></div>
|
<div class="header"></div>
|
||||||
<div class="footer">
|
<div class="footer">
|
||||||
<div class="toolbox">
|
<div class="toolbox">
|
||||||
<a class="control" href="wizard"><%=intl._("Tunnel Wizard")%></a> <a class="control" href="list?nonce=<%=indexBean.getNextNonce()%>&action=Stop%20all"><%=intl._("Stop All")%></a> <a class="control" href="list?nonce=<%=indexBean.getNextNonce()%>&action=Start%20all"><%=intl._("Start All")%></a> <a class="control" href="list?nonce=<%=indexBean.getNextNonce()%>&action=Restart%20all"><%=intl._("Restart All")%></a> <a class="control" href="list?nonce=<%=indexBean.getNextNonce()%>&action=Reload%20configuration"><%=intl._("Reload Config")%></a>
|
<a class="control" href="wizard"><%=intl._("Tunnel Wizard")%></a>
|
||||||
|
<a class="control" href="list?nonce=<%=indexBean.getNextNonce()%>&action=Stop%20all"><%=intl._("Stop All")%></a>
|
||||||
|
<a class="control" href="list?nonce=<%=indexBean.getNextNonce()%>&action=Start%20all"><%=intl._("Start All")%></a>
|
||||||
|
<a class="control" href="list?nonce=<%=indexBean.getNextNonce()%>&action=Restart%20all"><%=intl._("Restart All")%></a>
|
||||||
|
<%--
|
||||||
|
//this is really bad because it stops and restarts all tunnels, which is probably not what you want
|
||||||
|
<a class="control" href="list?nonce=<%=indexBean.getNextNonce()%>&action=Reload%20configuration"><%=intl._("Reload Config")%></a>
|
||||||
|
--%>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -327,6 +338,11 @@
|
|||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<%
|
||||||
|
|
||||||
|
} // isInitialized()
|
||||||
|
|
||||||
|
%>
|
||||||
<div id="pageFooter">
|
<div id="pageFooter">
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
Reference in New Issue
Block a user