* I2PTunnel:

- More client options cleanups
   - Options changes now propagate to running
     socket managers and sessions, and through to the router
 * SocketManager:
   - Simplify factory, use 4-arg constructor,
     make fields final, deprecate 0-arg constructor
   - Improve how options are updated
   - Javadocs
This commit is contained in:
zzz
2012-06-14 19:44:47 +00:00
parent 64221fb3fb
commit e522ffad4e
10 changed files with 255 additions and 115 deletions

View File

@@ -193,7 +193,7 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging {
} }
} }
/** @return non-null */ /** @return A copy, non-null */
List<I2PSession> getSessions() { List<I2PSession> getSessions() {
return new ArrayList(_sessions); return new ArrayList(_sessions);
} }
@@ -208,6 +208,10 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging {
_sessions.remove(session); _sessions.remove(session);
} }
/**
* Generic options used for clients and servers
* @return not a copy
*/
public Properties getClientOptions() { return _clientOptions; } public Properties getClientOptions() { return _clientOptions; }
private void addtask(I2PTunnelTask tsk) { private void addtask(I2PTunnelTask tsk) {
@@ -327,11 +331,13 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging {
/** /**
* Configure the extra I2CP options to use in any subsequent I2CP sessions. * Configure the extra I2CP options to use in any subsequent I2CP sessions.
* Generic options used for clients and servers
* Usage: "clientoptions[ key=value]*" . * Usage: "clientoptions[ key=value]*" .
* *
* Sets the event "clientoptions_onResult" = "ok" after completion. * Sets the event "clientoptions_onResult" = "ok" after completion.
* *
* Deprecated use setClientOptions() * Deprecated To be made private, use setClientOptions().
* This does NOT update a running TunnelTask.
* *
* @param args each args[i] is a key=value pair to add to the options * @param args each args[i] is a key=value pair to add to the options
* @param l logger to receive events and output * @param l logger to receive events and output
@@ -351,17 +357,22 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging {
} }
/** /**
* A more efficient runClientOptions() * Generic options used for clients and servers.
* This DOES update a running TunnelTask, but NOT the session.
* A more efficient runClientOptions().
* *
* @param opts non-null * @param opts non-null
* @since 0.9.1 * @since 0.9.1
*/ */
public void setClientOptions(Properties opts) { public void setClientOptions(Properties opts) {
_clientOptions.clear(); for (Iterator iter = _clientOptions.keySet().iterator(); iter.hasNext();) {
for (Map.Entry e : opts.entrySet()) { Object key = iter.next();
String key = (String) e.getKey(); if (!opts.containsKey(key))
String val = (String) e.getValue(); iter.remove();
_clientOptions.setProperty(key, val); }
_clientOptions.putAll(opts);
for (I2PTunnelTask task : tasks) {
task.optionsUpdated(this);
} }
notifyEvent("clientoptions_onResult", "ok"); notifyEvent("clientoptions_onResult", "ok");
} }

View File

@@ -495,6 +495,22 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna
return opts; return opts;
} }
/**
* Update the I2PSocketManager.
*
* @since 0.9.1
*/
@Override
public void optionsUpdated(I2PTunnel tunnel) {
if (getTunnel() != tunnel)
return;
I2PSocketManager sm = _ownDest ? sockMgr : socketManager;
if (sm == null)
return;
Properties props = tunnel.getClientOptions();
sm.setDefaultOptions(sockMgr.buildOptions(props));
}
/** /**
* Create a new I2PSocket towards to the specified destination, * Create a new I2PSocket towards to the specified destination,
* adding it to the list of connections actually managed by this * adding it to the list of connections actually managed by this

View File

@@ -295,6 +295,19 @@ public class I2PTunnelServer extends I2PTunnelTask implements Runnable {
} }
} }
/**
* Update the I2PSocketManager.
*
* @since 0.9.1
*/
@Override
public void optionsUpdated(I2PTunnel tunnel) {
if (getTunnel() != tunnel || sockMgr == null)
return;
Properties props = tunnel.getClientOptions();
sockMgr.setDefaultOptions(sockMgr.buildOptions(props));
}
protected int getHandlerCount() { protected int getHandlerCount() {
int rv = DEFAULT_HANDLER_COUNT; int rv = DEFAULT_HANDLER_COUNT;
String cnt = getTunnel().getClientOptions().getProperty(PROP_HANDLER_COUNT); String cnt = getTunnel().getClientOptions().getProperty(PROP_HANDLER_COUNT);

View File

@@ -58,6 +58,15 @@ public abstract class I2PTunnelTask extends EventDispatcherImpl {
public abstract boolean close(boolean forced); public abstract boolean close(boolean forced);
/**
* Notify the task that I2PTunnel's options have been updated.
* Extending classes should override and call I2PTunnel.getClientOptions(),
* then update the I2PSocketManager.
*
* @since 0.9.1
*/
public void optionsUpdated(I2PTunnel tunnel) {}
/** /**
* For tasks that don't call I2PTunnel.addSession() directly * For tasks that don't call I2PTunnel.addSession() directly
* @since 0.8.13 * @since 0.8.13

View File

@@ -328,6 +328,7 @@ public class TunnelController implements Logging {
_log.info("Releasing session " + s); _log.info("Releasing session " + s);
TunnelControllerGroup.getInstance().release(this, s); TunnelControllerGroup.getInstance().release(this, s);
} }
// _sessions.clear() ????
} else { } else {
if (_log.shouldLog(Log.WARN)) if (_log.shouldLog(Log.WARN))
_log.warn("No sessions to release? for " + getName()); _log.warn("No sessions to release? for " + getName());
@@ -386,7 +387,13 @@ public class TunnelController implements Logging {
} }
} }
private void setSessionOptions() { /**
* These are the ones stored with a prefix of "option."
*
* @return keys with the "option." prefix stripped
* @since 0.9.1 Much better than getClientOptions()
*/
public Properties getClientOptionProps() {
Properties opts = new Properties(); Properties opts = new Properties();
for (Map.Entry e : _config.entrySet()) { for (Map.Entry e : _config.entrySet()) {
String key = (String) e.getKey(); String key = (String) e.getKey();
@@ -396,7 +403,11 @@ public class TunnelController implements Logging {
opts.setProperty(key, val); opts.setProperty(key, val);
} }
} }
_tunnel.setClientOptions(opts); return opts;
}
private void setSessionOptions() {
_tunnel.setClientOptions(getClientOptionProps());
} }
private void setI2CPOptions() { private void setI2CPOptions() {
@@ -430,25 +441,37 @@ public class TunnelController implements Logging {
startTunnel(); startTunnel();
} }
/**
* As of 0.9.1, updates the options on an existing session
*/
public void setConfig(Properties config, String prefix) { public void setConfig(Properties config, String prefix) {
Properties props = new Properties(); Properties props = new Properties();
for (Iterator iter = config.keySet().iterator(); iter.hasNext(); ) { for (Map.Entry e : config.entrySet()) {
String key = (String)iter.next(); String key = (String) e.getKey();
String val = config.getProperty(key);
if (key.startsWith(prefix)) { if (key.startsWith(prefix)) {
key = key.substring(prefix.length()); key = key.substring(prefix.length());
String val = (String) e.getValue();
props.setProperty(key, val); props.setProperty(key, val);
if (_log.shouldLog(Log.DEBUG))
_log.debug("Set prop [" + key + "] to [" + val + "]");
} }
} }
_config = props; _config = props;
// tell i2ptunnel, who will tell the TunnelTask, who will tell the SocketManager
setSessionOptions();
if (_running && _sessions != null) {
for (I2PSession s : _sessions) {
// tell the router via the session
if (!s.isClosed()) {
s.updateOptions(_tunnel.getClientOptions());
}
}
}
} }
public Properties getConfig(String prefix) { public Properties getConfig(String prefix) {
Properties rv = new Properties(); Properties rv = new Properties();
for (Iterator iter = _config.keySet().iterator(); iter.hasNext(); ) { for (Map.Entry e : _config.entrySet()) {
String key = (String)iter.next(); String key = (String) e.getKey();
String val = _config.getProperty(key); String val = (String) e.getValue();
rv.setProperty(prefix + key, val); rv.setProperty(prefix + key, val);
} }
return rv; return rv;
@@ -459,19 +482,27 @@ public class TunnelController implements Logging {
public String getDescription() { return _config.getProperty("description"); } public String getDescription() { return _config.getProperty("description"); }
public String getI2CPHost() { return _config.getProperty("i2cpHost"); } public String getI2CPHost() { return _config.getProperty("i2cpHost"); }
public String getI2CPPort() { return _config.getProperty("i2cpPort"); } public String getI2CPPort() { return _config.getProperty("i2cpPort"); }
/**
* These are the ones with a prefix of "option."
*
* @return one big string of "key=val key=val ..."
* @deprecated why would you want this? Use getClientOptionProps() instead
*/
public String getClientOptions() { public String getClientOptions() {
StringBuilder opts = new StringBuilder(64); StringBuilder opts = new StringBuilder(64);
for (Iterator iter = _config.keySet().iterator(); iter.hasNext(); ) { for (Map.Entry e : _config.entrySet()) {
String key = (String)iter.next(); String key = (String) e.getKey();
String val = _config.getProperty(key);
if (key.startsWith("option.")) { if (key.startsWith("option.")) {
key = key.substring("option.".length()); key = key.substring("option.".length());
String val = (String) e.getValue();
if (opts.length() > 0) opts.append(' '); if (opts.length() > 0) opts.append(' ');
opts.append(key).append('=').append(val); opts.append(key).append('=').append(val);
} }
} }
return opts.toString(); return opts.toString();
} }
public String getListenOnInterface() { return _config.getProperty("interface"); } public String getListenOnInterface() { return _config.getProperty("interface"); }
public String getTargetHost() { return _config.getProperty("targetHost"); } public String getTargetHost() { return _config.getProperty("targetHost"); }
public String getTargetPort() { return _config.getProperty("targetPort"); } public String getTargetPort() { return _config.getProperty("targetPort"); }
@@ -485,6 +516,7 @@ public class TunnelController implements Logging {
/** default true */ /** default true */
public boolean getStartOnLoad() { return Boolean.valueOf(_config.getProperty("startOnLoad", "true")).booleanValue(); } public boolean getStartOnLoad() { return Boolean.valueOf(_config.getProperty("startOnLoad", "true")).booleanValue(); }
public boolean getPersistentClientKey() { return Boolean.valueOf(_config.getProperty("option.persistentClientKey")).booleanValue(); } public boolean getPersistentClientKey() { return Boolean.valueOf(_config.getProperty("option.persistentClientKey")).booleanValue(); }
public String getMyDestination() { public String getMyDestination() {
if (_tunnel != null) { if (_tunnel != null) {
List<I2PSession> sessions = _tunnel.getSessions(); List<I2PSession> sessions = _tunnel.getSessions();

View File

@@ -376,18 +376,6 @@ public class EditBean extends IndexBean {
*/ */
private static Properties getOptions(TunnelController controller) { private static Properties getOptions(TunnelController controller) {
if (controller == null) return null; if (controller == null) return null;
String opts = controller.getClientOptions(); return controller.getClientOptionProps();
StringTokenizer tok = new StringTokenizer(opts);
Properties props = new Properties();
while (tok.hasMoreTokens()) {
String pair = tok.nextToken();
int eq = pair.indexOf('=');
if ( (eq <= 0) || (eq >= pair.length()) )
continue;
String key = pair.substring(0, eq);
String val = pair.substring(eq+1);
props.setProperty(key, val);
}
return props;
} }
} }

View File

@@ -38,11 +38,32 @@ public interface I2PSocketManager {
*/ */
public void setAcceptTimeout(long ms); public void setAcceptTimeout(long ms);
public long getAcceptTimeout(); public long getAcceptTimeout();
/**
* Update the options on a running socket manager.
* Parameters in the I2PSocketOptions interface may be changed directly
* with the setters; no need to use this method for those.
* This does NOT update the underlying I2CP or tunnel options; use getSession().updateOptions() for that.
* @param options as created from a call to buildOptions(properties), non-null
*/
public void setDefaultOptions(I2PSocketOptions options); public void setDefaultOptions(I2PSocketOptions options);
/**
* Current options, not a copy, setters may be used to make changes.
*/
public I2PSocketOptions getDefaultOptions(); public I2PSocketOptions getDefaultOptions();
public I2PServerSocket getServerSocket(); public I2PServerSocket getServerSocket();
/**
* Create a copy of the current options, to be used in a setDefaultOptions() call.
*/
public I2PSocketOptions buildOptions(); public I2PSocketOptions buildOptions();
/**
* Create a modified copy of the current options, to be used in a setDefaultOptions() call.
* @param opts The new options, may be null
*/
public I2PSocketOptions buildOptions(Properties opts); public I2PSocketOptions buildOptions(Properties opts);
/** /**
@@ -102,6 +123,10 @@ public interface I2PSocketManager {
public String getName(); public String getName();
public void setName(String name); public void setName(String name);
/**
* Deprecated - Factory will initialize.
* @throws UnsupportedOperationException always
*/
public void init(I2PAppContext context, I2PSession session, Properties opts, String name); public void init(I2PAppContext context, I2PSession session, Properties opts, String name);
public void addDisconnectListener(DisconnectListener lsnr); public void addDisconnectListener(DisconnectListener lsnr);

View File

@@ -4,6 +4,7 @@ import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.util.Iterator; import java.util.Iterator;
import java.util.Properties; import java.util.Properties;
@@ -161,39 +162,18 @@ public class I2PSocketManagerFactory {
} }
private static I2PSocketManager createManager(I2PSession session, Properties opts, String name) { private static I2PSocketManager createManager(I2PSession session, Properties opts, String name) {
//if (false) { I2PAppContext context = I2PAppContext.getGlobalContext();
//I2PSocketManagerImpl mgr = new I2PSocketManagerImpl(); String classname = opts.getProperty(PROP_MANAGER, DEFAULT_MANAGER);
//mgr.setSession(session); try {
//mgr.setDefaultOptions(new I2PSocketOptions()); Class cls = Class.forName(classname);
//return mgr; Constructor<I2PSocketManager> con = (Constructor<I2PSocketManager>)
//} else { cls.getConstructor(new Class[] {I2PAppContext.class, I2PSession.class, Properties.class, String.class});
String classname = opts.getProperty(PROP_MANAGER, DEFAULT_MANAGER); I2PSocketManager mgr = con.newInstance(new Object[] {context, session, opts, name});
if (classname != null) { return mgr;
try { } catch (Throwable t) {
Class cls = Class.forName(classname); _log.log(Log.CRIT, "Error loading " + classname, t);
Object obj = cls.newInstance(); throw new IllegalStateException(t);
if (obj instanceof I2PSocketManager) { }
I2PSocketManager mgr = (I2PSocketManager)obj;
I2PAppContext context = I2PAppContext.getGlobalContext();
mgr.init(context, session, opts, name);
return mgr;
} else {
throw new IllegalStateException("Invalid manager class [" + classname + "]");
}
} catch (ClassNotFoundException cnfe) {
_log.error("Error loading " + classname, cnfe);
throw new IllegalStateException("Invalid manager class [" + classname + "] - not found");
} catch (InstantiationException ie) {
_log.error("Error loading " + classname, ie);
throw new IllegalStateException("Invalid manager class [" + classname + "] - unable to instantiate");
} catch (IllegalAccessException iae) {
_log.error("Error loading " + classname, iae);
throw new IllegalStateException("Invalid manager class [" + classname + "] - illegal access");
}
} else {
throw new IllegalStateException("No manager class specified");
}
//}
} }

View File

@@ -237,7 +237,33 @@ class ConnectionOptions extends I2PSocketOptionsImpl {
*/ */
public ConnectionOptions(ConnectionOptions opts) { public ConnectionOptions(ConnectionOptions opts) {
super(opts); super(opts);
if (opts != null) { if (opts != null)
update(opts);
}
/**
* Update everything by copying over from opts
* @param opts non-null
* @since 0.9.1
*/
public void updateAll(ConnectionOptions opts) {
// user is unlikely to change these 6 between buildOptions() and setDefaultOptions(),
// since they may be updated directly, but just in case...
setConnectTimeout(opts.getConnectTimeout());
setReadTimeout(opts.getReadTimeout());
setWriteTimeout(opts.getWriteTimeout());
setMaxBufferSize(opts.getMaxBufferSize());
setLocalPort(opts.getLocalPort());
setPort(opts.getPort());
update(opts);
}
/**
* Update everything (except super) by copying over from opts
* @param opts non-null
* @since 0.9.1
*/
private void update(ConnectionOptions opts) {
setMaxWindowSize(opts.getMaxWindowSize()); setMaxWindowSize(opts.getMaxWindowSize());
setConnectDelay(opts.getConnectDelay()); setConnectDelay(opts.getConnectDelay());
setProfile(opts.getProfile()); setProfile(opts.getProfile());
@@ -265,7 +291,6 @@ class ConnectionOptions extends I2PSocketOptionsImpl {
_maxTotalConnsPerMinute = opts.getMaxTotalConnsPerMinute(); _maxTotalConnsPerMinute = opts.getMaxTotalConnsPerMinute();
_maxTotalConnsPerHour = opts.getMaxTotalConnsPerHour(); _maxTotalConnsPerHour = opts.getMaxTotalConnsPerHour();
_maxTotalConnsPerDay = opts.getMaxTotalConnsPerDay(); _maxTotalConnsPerDay = opts.getMaxTotalConnsPerDay();
}
} }
@Override @Override
@@ -301,6 +326,9 @@ class ConnectionOptions extends I2PSocketOptionsImpl {
_maxTotalConnsPerDay = getInt(opts, PROP_MAX_TOTAL_CONNS_DAY, 0); _maxTotalConnsPerDay = getInt(opts, PROP_MAX_TOTAL_CONNS_DAY, 0);
} }
/**
* Note: NOT part of the interface
*/
@Override @Override
public void setProperties(Properties opts) { public void setProperties(Properties opts) {
super.setProperties(opts); super.setProperties(opts);
@@ -611,30 +639,35 @@ class ConnectionOptions extends I2PSocketOptionsImpl {
private void initLists(Properties opts) { private void initLists(Properties opts) {
_accessListEnabled = getBool(opts, PROP_ENABLE_ACCESS_LIST, false); _accessListEnabled = getBool(opts, PROP_ENABLE_ACCESS_LIST, false);
_blackListEnabled = getBool(opts, PROP_ENABLE_BLACKLIST, false); _blackListEnabled = getBool(opts, PROP_ENABLE_BLACKLIST, false);
// Don't think these would ever be accessed simultaneously,
// but avoid concurrent modification just in case
Set<Hash> accessList, blackList;
if (_accessListEnabled) if (_accessListEnabled)
_accessList = new HashSet(); accessList = new HashSet();
else else
_accessList = Collections.EMPTY_SET; accessList = Collections.EMPTY_SET;
if (_blackListEnabled) if (_blackListEnabled)
_blackList = new HashSet(); blackList = new HashSet();
else else
_blackList = Collections.EMPTY_SET; blackList = Collections.EMPTY_SET;
if (!(_accessListEnabled || _blackListEnabled)) if (_accessListEnabled || _blackListEnabled) {
return; String hashes = opts.getProperty(PROP_ACCESS_LIST);
String hashes = opts.getProperty(PROP_ACCESS_LIST); if (hashes == null)
if (hashes == null) return;
return; StringTokenizer tok = new StringTokenizer(hashes, ", ");
StringTokenizer tok = new StringTokenizer(hashes, ", "); while (tok.hasMoreTokens()) {
while (tok.hasMoreTokens()) { String hashstr = tok.nextToken();
String hashstr = tok.nextToken(); Hash h = ConvertToHash.getHash(hashstr);
Hash h = ConvertToHash.getHash(hashstr); if (h == null)
if (h == null) error("bad list hash: " + hashstr);
error("bad list hash: " + hashstr); else if (_blackListEnabled)
else if (_blackListEnabled) blackList.add(h);
_blackList.add(h); else
else accessList.add(h);
_accessList.add(h); }
} }
_accessList = accessList;
_blackList = blackList;
if (_accessListEnabled && _accessList.isEmpty()) if (_accessListEnabled && _accessList.isEmpty())
error("Connection access list enabled but no valid entries; no peers can connect"); error("Connection access list enabled but no valid entries; no peers can connect");
else if (_blackListEnabled && _blackList.isEmpty()) else if (_blackListEnabled && _blackList.isEmpty())
@@ -647,9 +680,10 @@ class ConnectionOptions extends I2PSocketOptionsImpl {
log.error(s); log.error(s);
} }
@Override /** doesn't include everything */
@Override
public String toString() { public String toString() {
StringBuilder buf = new StringBuilder(128); StringBuilder buf = new StringBuilder(256);
buf.append("conDelay=").append(_connectDelay); buf.append("conDelay=").append(_connectDelay);
buf.append(" maxSize=").append(_maxMessageSize); buf.append(" maxSize=").append(_maxMessageSize);
buf.append(" rtt=").append(_rtt); buf.append(" rtt=").append(_rtt);
@@ -663,6 +697,14 @@ class ConnectionOptions extends I2PSocketOptionsImpl {
buf.append(" inactivityTimeout=").append(_inactivityTimeout); buf.append(" inactivityTimeout=").append(_inactivityTimeout);
buf.append(" inboundBuffer=").append(_inboundBufferSize); buf.append(" inboundBuffer=").append(_inboundBufferSize);
buf.append(" maxWindowSize=").append(_maxWindowSize); buf.append(" maxWindowSize=").append(_maxWindowSize);
buf.append(" blacklistSize=").append(_blackList.size());
buf.append(" whitelistSize=").append(_accessList.size());
buf.append(" maxConns=").append(_maxConnsPerMinute).append('/')
.append(_maxConnsPerHour).append('/')
.append(_maxConnsPerDay);
buf.append(" maxTotalConns=").append(_maxTotalConnsPerMinute).append('/')
.append(_maxTotalConnsPerHour).append('/')
.append(_maxTotalConnsPerDay);
return buf.toString(); return buf.toString();
} }

View File

@@ -28,17 +28,17 @@ import net.i2p.util.Log;
* Direct instantiation by others is deprecated. * Direct instantiation by others is deprecated.
*/ */
public class I2PSocketManagerFull implements I2PSocketManager { public class I2PSocketManagerFull implements I2PSocketManager {
private I2PAppContext _context; private final I2PAppContext _context;
private Log _log; private final Log _log;
private I2PSession _session; private final I2PSession _session;
private I2PServerSocketFull _serverSocket; private final I2PServerSocketFull _serverSocket;
private StandardServerSocket _realServerSocket; private StandardServerSocket _realServerSocket;
private ConnectionOptions _defaultOptions; private final ConnectionOptions _defaultOptions;
private long _acceptTimeout; private long _acceptTimeout;
private String _name; private String _name;
private int _maxStreams; private int _maxStreams;
private static int __managerId = 0; private static int __managerId = 0;
private ConnectionManager _connectionManager; private final ConnectionManager _connectionManager;
/** /**
* How long to wait for the client app to accept() before sending back CLOSE? * How long to wait for the client app to accept() before sending back CLOSE?
@@ -46,10 +46,28 @@ public class I2PSocketManagerFull implements I2PSocketManager {
*/ */
private static final long ACCEPT_TIMEOUT_DEFAULT = 5*1000; private static final long ACCEPT_TIMEOUT_DEFAULT = 5*1000;
/**
* @deprecated use 4-arg constructor
* @throws UnsupportedOperationException always
*/
public I2PSocketManagerFull() { public I2PSocketManagerFull() {
throw new UnsupportedOperationException();
}
/** how many streams will we allow at once? */
public static final String PROP_MAX_STREAMS = "i2p.streaming.maxConcurrentStreams";
/**
* @deprecated use 4-arg constructor
* @throws UnsupportedOperationException always
*/
public void init(I2PAppContext context, I2PSession session, Properties opts, String name) {
throw new UnsupportedOperationException();
} }
/** /**
* This is what I2PSocketManagerFactory.createManager() returns.
* Direct instantiation by others is deprecated.
* *
* @param context * @param context
* @param session * @param session
@@ -57,22 +75,6 @@ public class I2PSocketManagerFull implements I2PSocketManager {
* @param name * @param name
*/ */
public I2PSocketManagerFull(I2PAppContext context, I2PSession session, Properties opts, String name) { public I2PSocketManagerFull(I2PAppContext context, I2PSession session, Properties opts, String name) {
this();
init(context, session, opts, name);
}
/** how many streams will we allow at once? */
public static final String PROP_MAX_STREAMS = "i2p.streaming.maxConcurrentStreams";
/**
*
*
* @param context
* @param session
* @param opts
* @param name
*/
public void init(I2PAppContext context, I2PSession session, Properties opts, String name) {
_context = context; _context = context;
_session = session; _session = session;
_log = _context.logManager().getLog(I2PSocketManagerFull.class); _log = _context.logManager().getLog(I2PSocketManagerFull.class);
@@ -98,7 +100,15 @@ public class I2PSocketManagerFull implements I2PSocketManager {
} }
} }
/**
* Create a copy of the current options, to be used in a setDefaultOptions() call.
*/
public I2PSocketOptions buildOptions() { return buildOptions(null); } public I2PSocketOptions buildOptions() { return buildOptions(null); }
/**
* Create a modified copy of the current options, to be used in a setDefaultOptions() call.
* @param opts The new options, may be null
*/
public I2PSocketOptions buildOptions(Properties opts) { public I2PSocketOptions buildOptions(Properties opts) {
ConnectionOptions curOpts = new ConnectionOptions(_defaultOptions); ConnectionOptions curOpts = new ConnectionOptions(_defaultOptions);
curOpts.setProperties(opts); curOpts.setProperties(opts);
@@ -159,10 +169,24 @@ public class I2PSocketManagerFull implements I2PSocketManager {
public void setAcceptTimeout(long ms) { _acceptTimeout = ms; } public void setAcceptTimeout(long ms) { _acceptTimeout = ms; }
public long getAcceptTimeout() { return _acceptTimeout; } public long getAcceptTimeout() { return _acceptTimeout; }
/**
* Update the options on a running socket manager.
* Parameters in the I2PSocketOptions interface may be changed directly
* with the setters; no need to use this method for those.
* This does NOT update the underlying I2CP or tunnel options; use getSession().updateOptions() for that.
* @param options as created from a call to buildOptions(properties), non-null
*/
public void setDefaultOptions(I2PSocketOptions options) { public void setDefaultOptions(I2PSocketOptions options) {
_defaultOptions = new ConnectionOptions((ConnectionOptions) options); if (!(options instanceof ConnectionOptions))
throw new IllegalArgumentException();
if (_log.shouldLog(Log.WARN))
_log.warn("Changing options from:\n " + _defaultOptions + "\nto:\n " + options);
_defaultOptions.updateAll((ConnectionOptions) options);
} }
/**
* Current options, not a copy, setters may be used to make changes.
*/
public I2PSocketOptions getDefaultOptions() { public I2PSocketOptions getDefaultOptions() {
return _defaultOptions; return _defaultOptions;
} }