API: Fix some client-side APIs to honor defaults in Properties;

add javadocs to specify where we do and don't (ticket #1491)
This commit is contained in:
zzz
2015-03-31 13:18:11 +00:00
parent 22c4149358
commit fadc624f7c
14 changed files with 116 additions and 39 deletions

View File

@ -540,6 +540,8 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging {
* This DOES update a running TunnelTask, but NOT the session. * This DOES update a running TunnelTask, but NOT the session.
* A more efficient runClientOptions(). * A more efficient runClientOptions().
* *
* Defaults in opts properties are not recommended, they may or may not be honored.
*
* @param opts non-null * @param opts non-null
* @since 0.9.1 * @since 0.9.1
*/ */

View File

@ -113,6 +113,8 @@ public class TunnelController implements Logging {
* the prefix should be used (and, in turn, that prefix should be stripped off * the prefix should be used (and, in turn, that prefix should be stripped off
* before being interpreted by this controller) * before being interpreted by this controller)
* *
* Defaults in config properties are not recommended, they may or may not be honored.
*
* @param config original key=value mapping non-null * @param config original key=value mapping non-null
* @param prefix beginning of key values that are relevant to this tunnel * @param prefix beginning of key values that are relevant to this tunnel
*/ */
@ -121,6 +123,7 @@ public class TunnelController implements Logging {
} }
/** /**
* Defaults in config properties are not recommended, they may or may not be honored.
* *
* @param config original key=value mapping non-null * @param config original key=value mapping non-null
* @param prefix beginning of key values that are relevant to this tunnel * @param prefix beginning of key values that are relevant to this tunnel
@ -506,6 +509,7 @@ public class TunnelController implements Logging {
/** /**
* These are the ones stored with a prefix of "option." * These are the ones stored with a prefix of "option."
* Defaults in config properties are not honored.
* *
* @return keys with the "option." prefix stripped, non-null * @return keys with the "option." prefix stripped, non-null
* @since 0.9.1 Much better than getClientOptions() * @since 0.9.1 Much better than getClientOptions()

View File

@ -73,6 +73,9 @@ public interface I2PSocketManager {
/** /**
* Create a modified copy of the current options, to be used in a setDefaultOptions() call. * Create a modified copy of the current options, to be used in a setDefaultOptions() call.
*
* As of 0.9.19, defaults in opts are honored.
*
* @param opts The new options, may be null * @param opts The new options, may be null
*/ */
public I2PSocketOptions buildOptions(Properties opts); public I2PSocketOptions buildOptions(Properties opts);

View File

@ -49,6 +49,7 @@ public class I2PSocketManagerFactory {
* I2CP router on the local machine on the default port (7654). * I2CP router on the local machine on the default port (7654).
* *
* Blocks for a long time while the router builds tunnels. * Blocks for a long time while the router builds tunnels.
* The nonblocking createDisconnectedManager() is preferred.
* *
* @return the newly created socket manager, or null if there were errors * @return the newly created socket manager, or null if there were errors
*/ */
@ -61,6 +62,7 @@ public class I2PSocketManagerFactory {
* I2CP router on the local machine on the default port (7654). * I2CP router on the local machine on the default port (7654).
* *
* Blocks for a long time while the router builds tunnels. * Blocks for a long time while the router builds tunnels.
* The nonblocking createDisconnectedManager() is preferred.
* *
* @param opts Streaming and I2CP options, may be null * @param opts Streaming and I2CP options, may be null
* @return the newly created socket manager, or null if there were errors * @return the newly created socket manager, or null if there were errors
@ -74,6 +76,7 @@ public class I2PSocketManagerFactory {
* I2CP router on the specified host and port. * I2CP router on the specified host and port.
* *
* Blocks for a long time while the router builds tunnels. * Blocks for a long time while the router builds tunnels.
* The nonblocking createDisconnectedManager() is preferred.
* *
* @param host I2CP host null to use default, ignored if in router context * @param host I2CP host null to use default, ignored if in router context
* @param port I2CP port <= 0 to use default, ignored if in router context * @param port I2CP port <= 0 to use default, ignored if in router context
@ -88,6 +91,7 @@ public class I2PSocketManagerFactory {
* I2CP router on the given machine reachable through the given port. * I2CP router on the given machine reachable through the given port.
* *
* Blocks for a long time while the router builds tunnels. * Blocks for a long time while the router builds tunnels.
* The nonblocking createDisconnectedManager() is preferred.
* *
* @param i2cpHost I2CP host null to use default, ignored if in router context * @param i2cpHost I2CP host null to use default, ignored if in router context
* @param i2cpPort I2CP port <= 0 to use default, ignored if in router context * @param i2cpPort I2CP port <= 0 to use default, ignored if in router context
@ -115,6 +119,7 @@ public class I2PSocketManagerFactory {
* stream and connected to the default I2CP host and port. * stream and connected to the default I2CP host and port.
* *
* Blocks for a long time while the router builds tunnels. * Blocks for a long time while the router builds tunnels.
* The nonblocking createDisconnectedManager() is preferred.
* *
* @param myPrivateKeyStream private key stream, format is specified in {@link net.i2p.data.PrivateKeyFile PrivateKeyFile} * @param myPrivateKeyStream private key stream, format is specified in {@link net.i2p.data.PrivateKeyFile PrivateKeyFile}
* or null for a transient destination. Caller must close. * or null for a transient destination. Caller must close.
@ -129,6 +134,7 @@ public class I2PSocketManagerFactory {
* stream and connected to the default I2CP host and port. * stream and connected to the default I2CP host and port.
* *
* Blocks for a long time while the router builds tunnels. * Blocks for a long time while the router builds tunnels.
* The nonblocking createDisconnectedManager() is preferred.
* *
* @param myPrivateKeyStream private key stream, format is specified in {@link net.i2p.data.PrivateKeyFile PrivateKeyFile} * @param myPrivateKeyStream private key stream, format is specified in {@link net.i2p.data.PrivateKeyFile PrivateKeyFile}
* or null for a transient destination. Caller must close. * or null for a transient destination. Caller must close.
@ -145,6 +151,7 @@ public class I2PSocketManagerFactory {
* port. * port.
* *
* Blocks for a long time while the router builds tunnels. * Blocks for a long time while the router builds tunnels.
* The nonblocking createDisconnectedManager() is preferred.
* *
* @param myPrivateKeyStream private key stream, format is specified in {@link net.i2p.data.PrivateKeyFile PrivateKeyFile} * @param myPrivateKeyStream private key stream, format is specified in {@link net.i2p.data.PrivateKeyFile PrivateKeyFile}
* or null for a transient destination. Caller must close. * or null for a transient destination. Caller must close.
@ -220,11 +227,11 @@ public class I2PSocketManagerFactory {
Properties syscopy = (Properties) System.getProperties().clone(); Properties syscopy = (Properties) System.getProperties().clone();
for (Map.Entry<Object, Object> e : syscopy.entrySet()) { for (Map.Entry<Object, Object> e : syscopy.entrySet()) {
String name = (String) e.getKey(); String name = (String) e.getKey();
if (!opts.containsKey(name)) if (opts.getProperty(name) != null)
opts.setProperty(name, (String) e.getValue()); opts.setProperty(name, (String) e.getValue());
} }
// as of 0.8.1 (I2CP default is BestEffort) // as of 0.8.1 (I2CP default is BestEffort)
if (!opts.containsKey(I2PClient.PROP_RELIABILITY)) if (opts.getProperty(I2PClient.PROP_RELIABILITY) == null)
opts.setProperty(I2PClient.PROP_RELIABILITY, I2PClient.PROP_RELIABILITY_NONE); opts.setProperty(I2PClient.PROP_RELIABILITY, I2PClient.PROP_RELIABILITY_NONE);
if (i2cpHost != null) if (i2cpHost != null)

View File

@ -264,6 +264,9 @@ class ConnectionOptions extends I2PSocketOptionsImpl {
/** /**
* Sets max buffer size, connect timeout, read timeout, and write timeout * Sets max buffer size, connect timeout, read timeout, and write timeout
* from properties. Does not set local port or remote port. * from properties. Does not set local port or remote port.
*
* As of 0.9.19, defaults in opts are honored.
*
* @param opts may be null * @param opts may be null
*/ */
public ConnectionOptions(Properties opts) { public ConnectionOptions(Properties opts) {
@ -388,66 +391,68 @@ class ConnectionOptions extends I2PSocketOptionsImpl {
/** /**
* Note: NOT part of the interface * Note: NOT part of the interface
*
* As of 0.9.19, defaults in opts are honored.
*/ */
@Override @Override
public void setProperties(Properties opts) { public void setProperties(Properties opts) {
super.setProperties(opts); super.setProperties(opts);
if (opts == null) return; if (opts == null) return;
if (opts.containsKey(PROP_MAX_WINDOW_SIZE)) if (opts.getProperty(PROP_MAX_WINDOW_SIZE) != null)
setMaxWindowSize(getInt(opts, PROP_MAX_WINDOW_SIZE, Connection.MAX_WINDOW_SIZE)); setMaxWindowSize(getInt(opts, PROP_MAX_WINDOW_SIZE, Connection.MAX_WINDOW_SIZE));
if (opts.containsKey(PROP_CONNECT_DELAY)) if (opts.getProperty(PROP_CONNECT_DELAY) != null)
setConnectDelay(getInt(opts, PROP_CONNECT_DELAY, -1)); setConnectDelay(getInt(opts, PROP_CONNECT_DELAY, -1));
if (opts.containsKey(PROP_PROFILE)) if (opts.getProperty(PROP_PROFILE) != null)
setProfile(getInt(opts, PROP_PROFILE, PROFILE_BULK)); setProfile(getInt(opts, PROP_PROFILE, PROFILE_BULK));
if (opts.containsKey(PROP_MAX_MESSAGE_SIZE)) if (opts.getProperty(PROP_MAX_MESSAGE_SIZE) != null)
setMaxMessageSize(getInt(opts, PROP_MAX_MESSAGE_SIZE, Packet.MAX_PAYLOAD_SIZE)); setMaxMessageSize(getInt(opts, PROP_MAX_MESSAGE_SIZE, Packet.MAX_PAYLOAD_SIZE));
if (opts.containsKey(PROP_INITIAL_RECEIVE_WINDOW)) if (opts.getProperty(PROP_INITIAL_RECEIVE_WINDOW) != null)
setReceiveWindow(getInt(opts, PROP_INITIAL_RECEIVE_WINDOW, 1)); setReceiveWindow(getInt(opts, PROP_INITIAL_RECEIVE_WINDOW, 1));
if (opts.containsKey(PROP_INITIAL_RESEND_DELAY)) if (opts.getProperty(PROP_INITIAL_RESEND_DELAY) != null)
setResendDelay(getInt(opts, PROP_INITIAL_RESEND_DELAY, 1000)); setResendDelay(getInt(opts, PROP_INITIAL_RESEND_DELAY, 1000));
if (opts.containsKey(PROP_INITIAL_ACK_DELAY)) if (opts.getProperty(PROP_INITIAL_ACK_DELAY) != null)
setSendAckDelay(getInt(opts, PROP_INITIAL_ACK_DELAY, DEFAULT_INITIAL_ACK_DELAY)); setSendAckDelay(getInt(opts, PROP_INITIAL_ACK_DELAY, DEFAULT_INITIAL_ACK_DELAY));
if (opts.containsKey(PROP_INITIAL_WINDOW_SIZE)) if (opts.getProperty(PROP_INITIAL_WINDOW_SIZE) != null)
setWindowSize(getInt(opts, PROP_INITIAL_WINDOW_SIZE, INITIAL_WINDOW_SIZE)); setWindowSize(getInt(opts, PROP_INITIAL_WINDOW_SIZE, INITIAL_WINDOW_SIZE));
if (opts.containsKey(PROP_MAX_RESENDS)) if (opts.getProperty(PROP_MAX_RESENDS) != null)
setMaxResends(getInt(opts, PROP_MAX_RESENDS, DEFAULT_MAX_SENDS)); setMaxResends(getInt(opts, PROP_MAX_RESENDS, DEFAULT_MAX_SENDS));
// handled in super() // handled in super()
//if (opts.containsKey(PROP_WRITE_TIMEOUT)) //if (opts.getProperty(PROP_WRITE_TIMEOUT))
// setWriteTimeout(getInt(opts, PROP_WRITE_TIMEOUT, -1)); // setWriteTimeout(getInt(opts, PROP_WRITE_TIMEOUT, -1));
if (opts.containsKey(PROP_INACTIVITY_TIMEOUT)) if (opts.getProperty(PROP_INACTIVITY_TIMEOUT) != null)
setInactivityTimeout(getInt(opts, PROP_INACTIVITY_TIMEOUT, DEFAULT_INACTIVITY_TIMEOUT)); setInactivityTimeout(getInt(opts, PROP_INACTIVITY_TIMEOUT, DEFAULT_INACTIVITY_TIMEOUT));
if (opts.containsKey(PROP_INACTIVITY_ACTION)) if (opts.getProperty(PROP_INACTIVITY_ACTION) != null)
setInactivityAction(getInt(opts, PROP_INACTIVITY_ACTION, DEFAULT_INACTIVITY_ACTION)); setInactivityAction(getInt(opts, PROP_INACTIVITY_ACTION, DEFAULT_INACTIVITY_ACTION));
setInboundBufferSize(getMaxMessageSize() * (Connection.MAX_WINDOW_SIZE + 2)); setInboundBufferSize(getMaxMessageSize() * (Connection.MAX_WINDOW_SIZE + 2));
if (opts.contains(PROP_CONGESTION_AVOIDANCE_GROWTH_RATE_FACTOR)) if (opts.getProperty(PROP_CONGESTION_AVOIDANCE_GROWTH_RATE_FACTOR) != null)
setCongestionAvoidanceGrowthRateFactor(getInt(opts, PROP_CONGESTION_AVOIDANCE_GROWTH_RATE_FACTOR, setCongestionAvoidanceGrowthRateFactor(getInt(opts, PROP_CONGESTION_AVOIDANCE_GROWTH_RATE_FACTOR,
DEFAULT_CONGESTION_AVOIDANCE_GROWTH_RATE_FACTOR)); DEFAULT_CONGESTION_AVOIDANCE_GROWTH_RATE_FACTOR));
if (opts.contains(PROP_SLOW_START_GROWTH_RATE_FACTOR)) if (opts.getProperty(PROP_SLOW_START_GROWTH_RATE_FACTOR) != null)
setSlowStartGrowthRateFactor(getInt(opts, PROP_SLOW_START_GROWTH_RATE_FACTOR, setSlowStartGrowthRateFactor(getInt(opts, PROP_SLOW_START_GROWTH_RATE_FACTOR,
DEFAULT_SLOW_START_GROWTH_RATE_FACTOR)); DEFAULT_SLOW_START_GROWTH_RATE_FACTOR));
if (opts.containsKey(PROP_CONNECT_TIMEOUT)) if (opts.getProperty(PROP_CONNECT_TIMEOUT) != null)
// overrides default in super() // overrides default in super()
setConnectTimeout(getInt(opts, PROP_CONNECT_TIMEOUT, Connection.DEFAULT_CONNECT_TIMEOUT)); setConnectTimeout(getInt(opts, PROP_CONNECT_TIMEOUT, Connection.DEFAULT_CONNECT_TIMEOUT));
if (opts.containsKey(PROP_ANSWER_PINGS)) if (opts.getProperty(PROP_ANSWER_PINGS) != null)
setAnswerPings(getBool(opts, PROP_ANSWER_PINGS, DEFAULT_ANSWER_PINGS)); setAnswerPings(getBool(opts, PROP_ANSWER_PINGS, DEFAULT_ANSWER_PINGS));
if (opts.containsKey(PROP_ENFORCE_PROTO)) if (opts.getProperty(PROP_ENFORCE_PROTO) != null)
setEnforceProtocol(getBool(opts, PROP_ENFORCE_PROTO, DEFAULT_ENFORCE_PROTO)); setEnforceProtocol(getBool(opts, PROP_ENFORCE_PROTO, DEFAULT_ENFORCE_PROTO));
if (opts.containsKey(PROP_DISABLE_REJ_LOG)) if (opts.getProperty(PROP_DISABLE_REJ_LOG) != null)
setDisableRejectLogging(getBool(opts, PROP_DISABLE_REJ_LOG, false)); setDisableRejectLogging(getBool(opts, PROP_DISABLE_REJ_LOG, false));
initLists(opts); initLists(opts);
if (opts.containsKey(PROP_MAX_CONNS_MIN)) if (opts.getProperty(PROP_MAX_CONNS_MIN) != null)
_maxConnsPerMinute = getInt(opts, PROP_MAX_CONNS_MIN, 0); _maxConnsPerMinute = getInt(opts, PROP_MAX_CONNS_MIN, 0);
if (opts.containsKey(PROP_MAX_CONNS_HOUR)) if (opts.getProperty(PROP_MAX_CONNS_HOUR) != null)
_maxConnsPerHour = getInt(opts, PROP_MAX_CONNS_HOUR, 0); _maxConnsPerHour = getInt(opts, PROP_MAX_CONNS_HOUR, 0);
if (opts.containsKey(PROP_MAX_CONNS_DAY)) if (opts.getProperty(PROP_MAX_CONNS_DAY) != null)
_maxConnsPerDay = getInt(opts, PROP_MAX_CONNS_DAY, 0); _maxConnsPerDay = getInt(opts, PROP_MAX_CONNS_DAY, 0);
if (opts.containsKey(PROP_MAX_TOTAL_CONNS_MIN)) if (opts.getProperty(PROP_MAX_TOTAL_CONNS_MIN) != null)
_maxTotalConnsPerMinute = getInt(opts, PROP_MAX_TOTAL_CONNS_MIN, 0); _maxTotalConnsPerMinute = getInt(opts, PROP_MAX_TOTAL_CONNS_MIN, 0);
if (opts.containsKey(PROP_MAX_TOTAL_CONNS_HOUR)) if (opts.getProperty(PROP_MAX_TOTAL_CONNS_HOUR) != null)
_maxTotalConnsPerHour = getInt(opts, PROP_MAX_TOTAL_CONNS_HOUR, 0); _maxTotalConnsPerHour = getInt(opts, PROP_MAX_TOTAL_CONNS_HOUR, 0);
if (opts.containsKey(PROP_MAX_TOTAL_CONNS_DAY)) if (opts.getProperty(PROP_MAX_TOTAL_CONNS_DAY) != null)
_maxTotalConnsPerDay = getInt(opts, PROP_MAX_TOTAL_CONNS_DAY, 0); _maxTotalConnsPerDay = getInt(opts, PROP_MAX_TOTAL_CONNS_DAY, 0);
if (opts.containsKey(PROP_MAX_STREAMS)) if (opts.getProperty(PROP_MAX_STREAMS) != null)
_maxConns = getInt(opts, PROP_MAX_STREAMS, 0); _maxConns = getInt(opts, PROP_MAX_STREAMS, 0);
_rto = getInt(opts, PROP_INITIAL_RTO, INITIAL_RTO); _rto = getInt(opts, PROP_INITIAL_RTO, INITIAL_RTO);

View File

@ -102,6 +102,9 @@ public class I2PSocketManagerFull implements I2PSocketManager {
/** /**
* Create a modified copy of the current options, to be used in a setDefaultOptions() call. * Create a modified copy of the current options, to be used in a setDefaultOptions() call.
*
* As of 0.9.19, defaults in opts are honored.
*
* @param opts The new options, may be null * @param opts The new options, may be null
*/ */
public I2PSocketOptions buildOptions(Properties opts) { public I2PSocketOptions buildOptions(Properties opts) {
@ -216,6 +219,7 @@ public class I2PSocketManagerFull implements I2PSocketManager {
* Parameters in the I2PSocketOptions interface may be changed directly * Parameters in the I2PSocketOptions interface may be changed directly
* with the setters; no need to use this method for those. * 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. * 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 * @param options as created from a call to buildOptions(properties), non-null
*/ */
public void setDefaultOptions(I2PSocketOptions options) { public void setDefaultOptions(I2PSocketOptions options) {

View File

@ -47,6 +47,9 @@ class I2PSocketOptionsImpl implements I2PSocketOptions {
/** /**
* Sets max buffer size, connect timeout, read timeout, and write timeout * Sets max buffer size, connect timeout, read timeout, and write timeout
* from properties. Does not set local port or remote port. * from properties. Does not set local port or remote port.
*
* As of 0.9.19, defaults in opts are honored.
*
* @param opts may be null * @param opts may be null
*/ */
public I2PSocketOptionsImpl(Properties opts) { public I2PSocketOptionsImpl(Properties opts) {
@ -56,17 +59,20 @@ class I2PSocketOptionsImpl implements I2PSocketOptions {
/** /**
* Sets max buffer size, connect timeout, read timeout, and write timeout * Sets max buffer size, connect timeout, read timeout, and write timeout
* from properties. Does not set local port or remote port. * from properties. Does not set local port or remote port.
*
* As of 0.9.19, defaults in opts are honored.
*
* @param opts may be null * @param opts may be null
*/ */
public void setProperties(Properties opts) { public void setProperties(Properties opts) {
if (opts == null) return; if (opts == null) return;
if (opts.containsKey(PROP_BUFFER_SIZE)) if (opts.getProperty(PROP_BUFFER_SIZE) != null)
_maxBufferSize = getInt(opts, PROP_BUFFER_SIZE, DEFAULT_BUFFER_SIZE); _maxBufferSize = getInt(opts, PROP_BUFFER_SIZE, DEFAULT_BUFFER_SIZE);
if (opts.containsKey(PROP_CONNECT_TIMEOUT)) if (opts.getProperty(PROP_CONNECT_TIMEOUT) != null)
_connectTimeout = getInt(opts, PROP_CONNECT_TIMEOUT, DEFAULT_CONNECT_TIMEOUT); _connectTimeout = getInt(opts, PROP_CONNECT_TIMEOUT, DEFAULT_CONNECT_TIMEOUT);
if (opts.containsKey(PROP_READ_TIMEOUT)) if (opts.getProperty(PROP_READ_TIMEOUT) != null)
_readTimeout = getInt(opts, PROP_READ_TIMEOUT, -1); _readTimeout = getInt(opts, PROP_READ_TIMEOUT, -1);
if (opts.containsKey(PROP_WRITE_TIMEOUT)) if (opts.getProperty(PROP_WRITE_TIMEOUT) != null)
_writeTimeout = getInt(opts, PROP_WRITE_TIMEOUT, DEFAULT_WRITE_TIMEOUT); _writeTimeout = getInt(opts, PROP_WRITE_TIMEOUT, DEFAULT_WRITE_TIMEOUT);
} }
@ -95,6 +101,9 @@ class I2PSocketOptionsImpl implements I2PSocketOptions {
} }
} }
/**
* Not part of the API, not for external use.
*/
public static double getDouble(Properties opts, String name, double defaultVal) { public static double getDouble(Properties opts, String name, double defaultVal) {
if (opts == null) return defaultVal; if (opts == null) return defaultVal;
String val = opts.getProperty(name); String val = opts.getProperty(name);

View File

@ -72,6 +72,8 @@ public interface I2PClient {
* the router how to handle the new session, and to configure the end to end * the router how to handle the new session, and to configure the end to end
* encryption. * encryption.
* *
* As of 0.9.19, defaults in options are honored.
*
* @param destKeyStream location from which to read the Destination, PrivateKey, and SigningPrivateKey from, * @param destKeyStream location from which to read the Destination, PrivateKey, and SigningPrivateKey from,
* format is specified in {@link net.i2p.data.PrivateKeyFile PrivateKeyFile} * format is specified in {@link net.i2p.data.PrivateKeyFile PrivateKeyFile}
* @param options set of options to configure the router with, if null will use System properties * @param options set of options to configure the router with, if null will use System properties

View File

@ -235,6 +235,8 @@ abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2CPMessa
* Create a new session, reading the Destination, PrivateKey, and SigningPrivateKey * Create a new session, reading the Destination, PrivateKey, and SigningPrivateKey
* from the destKeyStream, and using the specified options to connect to the router * from the destKeyStream, and using the specified options to connect to the router
* *
* As of 0.9.19, defaults in options are honored.
*
* @param destKeyStream stream containing the private key data, * @param destKeyStream stream containing the private key data,
* format is specified in {@link net.i2p.data.PrivateKeyFile PrivateKeyFile} * format is specified in {@link net.i2p.data.PrivateKeyFile PrivateKeyFile}
* @param options set of options to configure the router with, if null will use System properties * @param options set of options to configure the router with, if null will use System properties
@ -314,11 +316,14 @@ abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2CPMessa
} }
} }
/** save some memory, don't pass along the pointless properties */ /**
* Save some memory, don't pass along the pointless properties.
* As of 0.9.19, defaults from options will be promoted to real values in rv.
* @return a new Properties without defaults
*/
private Properties filter(Properties options) { private Properties filter(Properties options) {
Properties rv = new Properties(); Properties rv = new Properties();
for (Object oKey : options.keySet()) { // TODO-Java6: s/keySet()/stringPropertyNames()/ for (String key : options.stringPropertyNames()) {
String key = (String) oKey;
if (key.startsWith("java.") || if (key.startsWith("java.") ||
key.startsWith("user.") || key.startsWith("user.") ||
key.startsWith("os.") || key.startsWith("os.") ||
@ -787,7 +792,9 @@ abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2CPMessa
I2CPMessageProducer getProducer() { return _producer; } I2CPMessageProducer getProducer() { return _producer; }
/** /**
* Retrieve the configuration options * Retrieve the configuration options, filtered.
* All defaults passed in via constructor have been promoted to the primary map.
*
* @return non-null, if insantiated with null options, this will be the System properties. * @return non-null, if insantiated with null options, this will be the System properties.
*/ */
Properties getOptions() { return _options; } Properties getOptions() { return _options; }

View File

@ -172,11 +172,13 @@ public class DataHelper {
* Property keys and values must not contain '=' or ';', this is not checked and they are not escaped * Property keys and values must not contain '=' or ';', this is not checked and they are not escaped
* Keys and values must be 255 bytes or less, * Keys and values must be 255 bytes or less,
* Formatted length must not exceed 65535 bytes * Formatted length must not exceed 65535 bytes
* @throws DataFormatException if either is too long. *
* Properties from the defaults table of props (if any) are not written out by this method.
* *
* @param rawStream stream to write to * @param rawStream stream to write to
* @param props properties to write out * @param props properties to write out
* @throws DataFormatException if there is not enough valid data to write out * @throws DataFormatException if there is not enough valid data to write out,
* or a length limit is exceeded
* @throws IOException if there is an IO error writing out the data * @throws IOException if there is an IO error writing out the data
*/ */
public static void writeProperties(OutputStream rawStream, Properties props) public static void writeProperties(OutputStream rawStream, Properties props)
@ -190,7 +192,8 @@ public class DataHelper {
* Property keys and values must not contain '=' or ';', this is not checked and they are not escaped * Property keys and values must not contain '=' or ';', this is not checked and they are not escaped
* Keys and values must be 255 bytes or less, * Keys and values must be 255 bytes or less,
* Formatted length must not exceed 65535 bytes * Formatted length must not exceed 65535 bytes
* @throws DataFormatException if either is too long. *
* Properties from the defaults table of props (if any) are not written out by this method.
* *
* jrandom disabled UTF-8 in mid-2004, for performance reasons, * jrandom disabled UTF-8 in mid-2004, for performance reasons,
* i.e. slow foo.getBytes("UTF-8") * i.e. slow foo.getBytes("UTF-8")
@ -199,6 +202,7 @@ public class DataHelper {
* Use utf8 = false for RouterAddress (fast, non UTF-8) * Use utf8 = false for RouterAddress (fast, non UTF-8)
* Use utf8 = true for SessionConfig (slow, UTF-8) * Use utf8 = true for SessionConfig (slow, UTF-8)
* @param props source may be null * @param props source may be null
* @throws DataFormatException if a length limit is exceeded
*/ */
public static void writeProperties(OutputStream rawStream, Properties props, boolean utf8) public static void writeProperties(OutputStream rawStream, Properties props, boolean utf8)
throws DataFormatException, IOException { throws DataFormatException, IOException {
@ -213,6 +217,8 @@ public class DataHelper {
* Keys and values must be 255 bytes or less, * Keys and values must be 255 bytes or less,
* Formatted length must not exceed 65535 bytes * Formatted length must not exceed 65535 bytes
* *
* Properties from the defaults table of props (if any) are not written out by this method.
*
* jrandom disabled UTF-8 in mid-2004, for performance reasons, * jrandom disabled UTF-8 in mid-2004, for performance reasons,
* i.e. slow foo.getBytes("UTF-8") * i.e. slow foo.getBytes("UTF-8")
* Re-enable it so we can pass UTF-8 tunnel names through the I2CP SessionConfig. * Re-enable it so we can pass UTF-8 tunnel names through the I2CP SessionConfig.
@ -269,6 +275,8 @@ public class DataHelper {
* Strings will be UTF-8 encoded in the byte array. * Strings will be UTF-8 encoded in the byte array.
* Warning - confusing method name, Properties is the source. * Warning - confusing method name, Properties is the source.
* *
* Properties from the defaults table of props (if any) are not written out by this method.
*
* @deprecated unused * @deprecated unused
* *
* @param target returned array as specified in data structure spec * @param target returned array as specified in data structure spec
@ -364,6 +372,8 @@ public class DataHelper {
* Formatted length must not exceed 65535 bytes * Formatted length must not exceed 65535 bytes
* Warning - confusing method name, Properties is the source. * Warning - confusing method name, Properties is the source.
* *
* Properties from the defaults table of props (if any) are not written out by this method.
*
* @throws DataFormatException if key, value, or total is too long * @throws DataFormatException if key, value, or total is too long
*/ */
public static byte[] toProperties(Properties opts) throws DataFormatException { public static byte[] toProperties(Properties opts) throws DataFormatException {
@ -477,6 +487,8 @@ public class DataHelper {
* Note that this does not escape the \r or \n that are unescaped in loadProps() above. * Note that this does not escape the \r or \n that are unescaped in loadProps() above.
* As of 0.8.1, file will be mode 600. * As of 0.8.1, file will be mode 600.
* *
* Properties from the defaults table of props (if any) are not written out by this method.
*
* Leading or trailing whitespace in values is not checked but * Leading or trailing whitespace in values is not checked but
* will be trimmed by loadProps() * will be trimmed by loadProps()
* *

View File

@ -45,6 +45,10 @@ public class GetDateMessage extends I2CPMessageImpl {
} }
/** /**
* Defaults in GetDateMessage options are, in general, NOT honored.
* Defaults are not serialized out-of-JVM, and the router does not recognize defaults in-JVM.
* Client side must promote defaults to the primary map.
*
* @param version the client's version String to be sent to the router; may be null; * @param version the client's version String to be sent to the router; may be null;
* must be non-null if options is non-null and non-empty. * must be non-null if options is non-null and non-empty.
* @param options Client options to be sent to the router; primarily for authentication; may be null; * @param options Client options to be sent to the router; primarily for authentication; may be null;

View File

@ -91,6 +91,10 @@ public class SessionConfig extends DataStructureImpl {
* Configure the session with the given options; * Configure the session with the given options;
* keys and values 255 bytes (not chars) max each * keys and values 255 bytes (not chars) max each
* *
* Defaults in SessionConfig options are, in general, NOT honored.
* Defaults are not serialized out-of-JVM, and the router does not recognize defaults in-JVM.
* Client side must promote defaults to the primary map.
*
* @param options Properties for this session * @param options Properties for this session
*/ */
public void setOptions(Properties options) { public void setOptions(Properties options) {

View File

@ -237,9 +237,12 @@ public class TunnelPoolSettings {
public Properties getUnknownOptions() { return _unknownOptions; } public Properties getUnknownOptions() { return _unknownOptions; }
/** /**
* Defaults in props are NOT honored.
* In-JVM client side must promote defaults to the primary map.
*
* @param prefix non-null * @param prefix non-null
*/ */
public void readFromProperties(String prefix, Map<Object, Object> props) { public void readFromProperties(String prefix, Properties props) {
for (Map.Entry<Object, Object> e : props.entrySet()) { for (Map.Entry<Object, Object> e : props.entrySet()) {
String name = (String) e.getKey(); String name = (String) e.getKey();
String value = (String) e.getValue(); String value = (String) e.getValue();

View File

@ -161,6 +161,11 @@ class ClientMessageEventListener implements I2CPMessageReader.I2CPMessageEventLi
_runner.disconnected(); _runner.disconnected();
} }
/**
* Defaults in GetDateMessage options are NOT honored.
* Defaults are not serialized out-of-JVM, and the router does not recognize defaults in-JVM.
* Client side must promote defaults to the primary map.
*/
private void handleGetDate(GetDateMessage message) { private void handleGetDate(GetDateMessage message) {
// sent by clients >= 0.8.7 // sent by clients >= 0.8.7
String clientVersion = message.getVersion(); String clientVersion = message.getVersion();
@ -192,6 +197,9 @@ class ClientMessageEventListener implements I2CPMessageReader.I2CPMessageEventLi
* sending the DisconnectMessage... but right now the client will send _us_ a * sending the DisconnectMessage... but right now the client will send _us_ a
* DisconnectMessage in return, and not wait around for our DisconnectMessage. * DisconnectMessage in return, and not wait around for our DisconnectMessage.
* So keep it simple. * So keep it simple.
*
* Defaults in SessionConfig options are, in general, NOT honored.
* In-JVM client side must promote defaults to the primary map.
*/ */
private void handleCreateSession(CreateSessionMessage message) { private void handleCreateSession(CreateSessionMessage message) {
SessionConfig in = message.getSessionConfig(); SessionConfig in = message.getSessionConfig();
@ -459,6 +467,9 @@ class ClientMessageEventListener implements I2CPMessageReader.I2CPMessageEventLi
* *
* Note that this does NOT update the few options handled in * Note that this does NOT update the few options handled in
* ClientConnectionRunner.sessionEstablished(). Those can't be changed later. * ClientConnectionRunner.sessionEstablished(). Those can't be changed later.
*
* Defaults in SessionConfig options are, in general, NOT honored.
* In-JVM client side must promote defaults to the primary map.
*/ */
private void handleReconfigureSession(ReconfigureSessionMessage message) { private void handleReconfigureSession(ReconfigureSessionMessage message) {
SessionConfig cfg = _runner.getConfig(); SessionConfig cfg = _runner.getConfig();