diff --git a/core/java/src/net/i2p/client/I2PSessionImpl.java b/core/java/src/net/i2p/client/I2PSessionImpl.java index b7d9741fedacf836b356ee7fcb7b821b963910a1..e43be08f8e9fc9b7f054a8eb094e8c55dda6997d 100644 --- a/core/java/src/net/i2p/client/I2PSessionImpl.java +++ b/core/java/src/net/i2p/client/I2PSessionImpl.java @@ -58,22 +58,22 @@ import net.i2p.util.VersionComparator; abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2CPMessageEventListener { protected final Log _log; /** who we are */ - private Destination _myDestination; + private final Destination _myDestination; /** private key for decryption */ - private PrivateKey _privateKey; + private final PrivateKey _privateKey; /** private key for signing */ - private SigningPrivateKey _signingPrivateKey; + private final SigningPrivateKey _signingPrivateKey; /** configuration options */ - private Properties _options; + private final Properties _options; /** this session's Id */ private SessionId _sessionId; /** currently granted lease set, or null */ private volatile LeaseSet _leaseSet; /** hostname of router - will be null if in RouterContext */ - protected String _hostname; + protected final String _hostname; /** port num to router - will be 0 if in RouterContext */ - protected int _portNum; + protected final int _portNum; /** socket for comm */ protected Socket _socket; /** reader that always searches for messages */ @@ -169,15 +169,36 @@ abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2CPMessa private static final int BUF_SIZE = 32*1024; - /** for extension */ + /** + * for extension by SimpleSession (no dest) + */ protected I2PSessionImpl(I2PAppContext context, Properties options) { + this(context, options, false); + } + + /** + * Basic setup of finals + * @since 0.9.7 + */ + private I2PSessionImpl(I2PAppContext context, Properties options, boolean hasDest) { _context = context; _log = context.logManager().getLog(getClass()); _closed = true; if (options == null) options = (Properties) System.getProperties().clone(); - loadConfig(options); + _options = loadConfig(options); + _hostname = getHost(); + _portNum = getPort(); _fastReceive = Boolean.parseBoolean(_options.getProperty(I2PClient.PROP_FAST_RECEIVE)); + if (hasDest) { + _myDestination = new Destination(); + _privateKey = new PrivateKey(); + _signingPrivateKey = new SigningPrivateKey(); + } else { + _myDestination = null; + _privateKey = null; + _signingPrivateKey = null; + } } /** @@ -190,7 +211,7 @@ abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2CPMessa * @throws I2PSessionException if there is a problem loading the private keys or */ public I2PSessionImpl(I2PAppContext context, InputStream destKeyStream, Properties options) throws I2PSessionException { - this(context, options); + this(context, options, true); _handlerMap = new I2PClientMessageHandlerMap(context); _producer = new I2CPMessageProducer(context); _availabilityNotifier = new AvailabilityNotifier(); @@ -208,40 +229,56 @@ abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2CPMessa * Parse the config for anything we know about. * Also fill in the authorization properties if missing. */ - private void loadConfig(Properties options) { - _options = new Properties(); - _options.putAll(filter(options)); - if (_context.isRouterContext()) { - // just for logging - _hostname = "[internal connection]"; - } else { - _hostname = _options.getProperty(I2PClient.PROP_TCP_HOST, "127.0.0.1"); - String portNum = _options.getProperty(I2PClient.PROP_TCP_PORT, LISTEN_PORT + ""); - try { - _portNum = Integer.parseInt(portNum); - } catch (NumberFormatException nfe) { - if (_log.shouldLog(Log.WARN)) - _log.warn(getPrefix() + "Invalid port number specified, defaulting to " - + LISTEN_PORT, nfe); - _portNum = LISTEN_PORT; - } - } + private final Properties loadConfig(Properties opts) { + Properties options = new Properties(); + options.putAll(filter(opts)); // auto-add auth if required, not set in the options, and we are not in the same JVM if ((!_context.isRouterContext()) && _context.getBooleanProperty("i2cp.auth") && - ((!options.containsKey("i2cp.username")) || (!options.containsKey("i2cp.password")))) { + ((!opts.containsKey("i2cp.username")) || (!opts.containsKey("i2cp.password")))) { String configUser = _context.getProperty("i2cp.username"); String configPW = _context.getProperty("i2cp.password"); if (configUser != null && configPW != null) { - _options.setProperty("i2cp.username", configUser); - _options.setProperty("i2cp.password", configPW); + options.setProperty("i2cp.username", configUser); + options.setProperty("i2cp.password", configPW); } } - if (_options.getProperty(I2PClient.PROP_FAST_RECEIVE) == null) - _options.setProperty(I2PClient.PROP_FAST_RECEIVE, "true"); - if (_options.getProperty(I2PClient.PROP_RELIABILITY) == null) - _options.setProperty(I2PClient.PROP_RELIABILITY, "none"); + if (options.getProperty(I2PClient.PROP_FAST_RECEIVE) == null) + options.setProperty(I2PClient.PROP_FAST_RECEIVE, "true"); + if (options.getProperty(I2PClient.PROP_RELIABILITY) == null) + options.setProperty(I2PClient.PROP_RELIABILITY, "none"); + return options; + } + + /** + * Get I2CP host from the config + * @since 0.9.7 was in loadConfig() + */ + private String getHost() { + if (_context.isRouterContext()) + // just for logging + return "[internal connection]"; + return _options.getProperty(I2PClient.PROP_TCP_HOST, "127.0.0.1"); + } + + /** + * Get I2CP port from the config + * @since 0.9.7 was in loadConfig() + */ + private int getPort() { + if (_context.isRouterContext()) + // just for logging + return 0; + String portNum = _options.getProperty(I2PClient.PROP_TCP_PORT, LISTEN_PORT + ""); + try { + return Integer.parseInt(portNum); + } catch (NumberFormatException nfe) { + if (_log.shouldLog(Log.WARN)) + _log.warn(getPrefix() + "Invalid port number specified, defaulting to " + + LISTEN_PORT, nfe); + return LISTEN_PORT; + } } /** save some memory, don't pass along the pointless properties */ @@ -332,9 +369,6 @@ abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2CPMessa * @throws IOException if there is a problem reading the file */ private void readDestination(InputStream destKeyStream) throws DataFormatException, IOException { - _myDestination = new Destination(); - _privateKey = new PrivateKey(); - _signingPrivateKey = new SigningPrivateKey(); _myDestination.readBytes(destKeyStream); _privateKey.readBytes(destKeyStream); _signingPrivateKey.readBytes(destKeyStream); diff --git a/core/java/src/net/i2p/client/SessionIdleTimer.java b/core/java/src/net/i2p/client/SessionIdleTimer.java index d7b94911c29c8439bb7f5e7d4426cb5272644453..cf5c8c02915c217aff90191c4b3621a08f24399e 100644 --- a/core/java/src/net/i2p/client/SessionIdleTimer.java +++ b/core/java/src/net/i2p/client/SessionIdleTimer.java @@ -22,60 +22,67 @@ class SessionIdleTimer implements SimpleTimer.TimedEvent { public static final long MINIMUM_TIME = 5*60*1000; private static final long DEFAULT_REDUCE_TIME = 20*60*1000; private static final long DEFAULT_CLOSE_TIME = 30*60*1000; - private final static Log _log = new Log(SessionIdleTimer.class); + private final Log _log; private final I2PAppContext _context; private final I2PSessionImpl _session; - private boolean _reduceEnabled; - private int _reduceQuantity; - private long _reduceTime; - private boolean _shutdownEnabled; - private long _shutdownTime; - private long _minimumTime; + private final boolean _reduceEnabled; + private final int _reduceQuantity; + private final long _reduceTime; + private final boolean _shutdownEnabled; + private final long _shutdownTime; + private final long _minimumTime; private long _lastActive; /** * reduce, shutdown, or both must be true */ public SessionIdleTimer(I2PAppContext context, I2PSessionImpl session, boolean reduce, boolean shutdown) { - _context = context; - _session = session; - _reduceEnabled = reduce; - _shutdownEnabled = shutdown; if (! (reduce || shutdown)) throw new IllegalArgumentException("At least one must be enabled"); + _context = context; + _log = context.logManager().getLog(SessionIdleTimer.class); + _session = session; Properties props = session.getOptions(); - _minimumTime = Long.MAX_VALUE; - _lastActive = 0; + long minimumTime = Long.MAX_VALUE; + long reduceTime = 0; + long shutdownTime = 0; + int reduceQuantity = 0; if (reduce) { - _reduceQuantity = 1; + reduceQuantity = 1; String p = props.getProperty("i2cp.reduceQuantity"); if (p != null) { try { - _reduceQuantity = Math.max(Integer.parseInt(p), 1); + reduceQuantity = Math.max(Integer.parseInt(p), 1); // also check vs. configured quantities? } catch (NumberFormatException nfe) {} } - _reduceTime = DEFAULT_REDUCE_TIME; + reduceTime = DEFAULT_REDUCE_TIME; p = props.getProperty("i2cp.reduceIdleTime"); if (p != null) { try { - _reduceTime = Math.max(Long.parseLong(p), MINIMUM_TIME); + reduceTime = Math.max(Long.parseLong(p), MINIMUM_TIME); } catch (NumberFormatException nfe) {} } - _minimumTime = _reduceTime; + minimumTime = reduceTime; } if (shutdown) { - _shutdownTime = DEFAULT_CLOSE_TIME; + shutdownTime = DEFAULT_CLOSE_TIME; String p = props.getProperty("i2cp.closeIdleTime"); if (p != null) { try { - _shutdownTime = Math.max(Long.parseLong(p), MINIMUM_TIME); + shutdownTime = Math.max(Long.parseLong(p), MINIMUM_TIME); } catch (NumberFormatException nfe) {} } - _minimumTime = Math.min(_minimumTime, _shutdownTime); - if (reduce && _shutdownTime <= _reduceTime) + minimumTime = Math.min(minimumTime, shutdownTime); + if (reduce && shutdownTime <= reduceTime) reduce = false; } + _reduceEnabled = reduce; + _reduceQuantity = reduceQuantity; + _reduceTime = reduceTime; + _shutdownEnabled = shutdown; + _shutdownTime = shutdownTime; + _minimumTime = minimumTime; } public void timeReached() {