forked from I2P_Developers/i2p.i2p
NTCP: Add option to disable NTCP1 (ticket #2328)
Don't bid for outbound-only NTCP2 addresses Fix NTCP2 cost when transitioning to inbound
This commit is contained in:
21
history.txt
21
history.txt
@ -1,3 +1,24 @@
|
||||
2019-02-07 zzz
|
||||
* NTCP:
|
||||
- Add option to disable NTCP1 (ticket #2328)
|
||||
- Don't bid for outbound-only NTCP2 addresses
|
||||
- Fix NTCP2 cost when transitioning to inbound
|
||||
|
||||
2019-02-06 zzz
|
||||
* Build: Add targets for alternate debian distros (ticket #2410)
|
||||
* Crypto: Shortcut GroupElement representation conversion
|
||||
* I2CP: Prevent use of repliable datagrams with offline keys
|
||||
|
||||
2019-02-05 zzz
|
||||
* Transport:
|
||||
- Clean up unreachable() methods (ticket #2382)
|
||||
- Speed up NTCP allowConnection() (ticket #2381)
|
||||
- OutNetMessage cleanup (ticket #2386)
|
||||
- SSU PacketHandler cleanup (ticket #2383)
|
||||
|
||||
2019-02-04 zzz
|
||||
* I2CP: Change format and message type of CreateLeaseSet2 message
|
||||
|
||||
2019-02-03 zzz
|
||||
* I2CP:
|
||||
- Remove revocation private key from CreateLeaseset2 message
|
||||
|
@ -18,7 +18,7 @@ public class RouterVersion {
|
||||
/** deprecated */
|
||||
public final static String ID = "Monotone";
|
||||
public final static String VERSION = CoreVersion.VERSION;
|
||||
public final static long BUILD = 6;
|
||||
public final static long BUILD = 7;
|
||||
|
||||
/** for example "-test" */
|
||||
public final static String EXTRA = "";
|
||||
|
@ -70,6 +70,8 @@ public class TransportManager implements TransportEventListener {
|
||||
private final UPnPManager _upnpManager;
|
||||
private final DHSessionKeyBuilder.PrecalcRunner _dhThread;
|
||||
private final X25519KeyFactory _xdhThread;
|
||||
private final boolean _enableUDP;
|
||||
private final boolean _enableNTCP1;
|
||||
|
||||
/** default true */
|
||||
public final static String PROP_ENABLE_UDP = "i2np.udp.enable";
|
||||
@ -78,6 +80,9 @@ public class TransportManager implements TransportEventListener {
|
||||
/** default true */
|
||||
public final static String PROP_ENABLE_UPNP = "i2np.upnp.enable";
|
||||
|
||||
/** default true */
|
||||
private static final String PROP_NTCP1_ENABLE = "i2np.ntcp1.enable";
|
||||
private static final boolean DEFAULT_NTCP1_ENABLE = true;
|
||||
private static final String PROP_NTCP2_ENABLE = "i2np.ntcp2.enable";
|
||||
private static final boolean DEFAULT_NTCP2_ENABLE = true;
|
||||
|
||||
@ -102,9 +107,12 @@ public class TransportManager implements TransportEventListener {
|
||||
_upnpManager = new UPnPManager(context, this);
|
||||
else
|
||||
_upnpManager = null;
|
||||
_dhThread = new DHSessionKeyBuilder.PrecalcRunner(context);
|
||||
_enableUDP = _context.getBooleanPropertyDefaultTrue(PROP_ENABLE_UDP);
|
||||
_enableNTCP1 = isNTCPEnabled(context) &&
|
||||
context.getProperty(PROP_NTCP1_ENABLE, DEFAULT_NTCP1_ENABLE);
|
||||
boolean enableNTCP2 = isNTCPEnabled(context) &&
|
||||
context.getProperty(PROP_NTCP2_ENABLE, DEFAULT_NTCP2_ENABLE);
|
||||
_dhThread = (_enableUDP || enableNTCP2) ? new DHSessionKeyBuilder.PrecalcRunner(context) : null;
|
||||
_xdhThread = enableNTCP2 ? new X25519KeyFactory(context) : null;
|
||||
}
|
||||
|
||||
@ -149,6 +157,7 @@ public class TransportManager implements TransportEventListener {
|
||||
/**
|
||||
* Hook for pluggable transport creation.
|
||||
*
|
||||
* @return null if both NTCP1 and SSU are disabled
|
||||
* @since 0.9.16
|
||||
*/
|
||||
DHSessionKeyBuilder.Factory getDHFactory() {
|
||||
@ -172,15 +181,15 @@ public class TransportManager implements TransportEventListener {
|
||||
}
|
||||
|
||||
private void configTransports() {
|
||||
boolean enableUDP = _context.getBooleanPropertyDefaultTrue(PROP_ENABLE_UDP);
|
||||
Transport udp = null;
|
||||
if (enableUDP) {
|
||||
if (_enableUDP) {
|
||||
udp = new UDPTransport(_context, _dhThread);
|
||||
addTransport(udp);
|
||||
initializeAddress(udp);
|
||||
}
|
||||
if (isNTCPEnabled(_context)) {
|
||||
Transport ntcp = new NTCPTransport(_context, _dhThread, _xdhThread);
|
||||
DHSessionKeyBuilder.PrecalcRunner dh = _enableNTCP1 ? _dhThread : null;
|
||||
Transport ntcp = new NTCPTransport(_context, dh, _xdhThread);
|
||||
addTransport(ntcp);
|
||||
initializeAddress(ntcp);
|
||||
if (udp != null) {
|
||||
@ -315,7 +324,7 @@ public class TransportManager implements TransportEventListener {
|
||||
}
|
||||
|
||||
synchronized void startListening() {
|
||||
if (_dhThread.getState() == Thread.State.NEW)
|
||||
if (_dhThread != null && _dhThread.getState() == Thread.State.NEW)
|
||||
_dhThread.start();
|
||||
if (_xdhThread != null && _xdhThread.getState() == Thread.State.NEW)
|
||||
_xdhThread.start();
|
||||
@ -377,7 +386,8 @@ public class TransportManager implements TransportEventListener {
|
||||
*/
|
||||
synchronized void shutdown() {
|
||||
stopListening();
|
||||
_dhThread.shutdown();
|
||||
if (_dhThread != null)
|
||||
_dhThread.shutdown();
|
||||
if (_xdhThread != null)
|
||||
_xdhThread.shutdown();
|
||||
Addresses.clearCaches();
|
||||
|
@ -191,12 +191,17 @@ abstract class EstablishBase implements EstablishState {
|
||||
_log = ctx.logManager().getLog(getClass());
|
||||
_transport = transport;
|
||||
_con = con;
|
||||
// null if NTCP1 disabled
|
||||
_dh = _transport.getDHBuilder();
|
||||
_hX_xor_bobIdentHash = SimpleByteCache.acquire(HXY_SIZE);
|
||||
if (_con.isInbound()) {
|
||||
_X = SimpleByteCache.acquire(XY_SIZE);
|
||||
_Y = _dh.getMyPublicValueBytes();
|
||||
_Y = (_dh != null) ?_dh.getMyPublicValueBytes() : null;
|
||||
} else {
|
||||
// OutboundNTCP2State does not extend this,
|
||||
// can't get here with NTCP1 disabled
|
||||
if (_dh == null)
|
||||
throw new IllegalStateException();
|
||||
_X = _dh.getMyPublicValueBytes();
|
||||
_Y = SimpleByteCache.acquire(XY_SIZE);
|
||||
}
|
||||
@ -304,7 +309,7 @@ abstract class EstablishBase implements EstablishState {
|
||||
SimpleByteCache.release(_prevEncrypted);
|
||||
SimpleByteCache.release(_curDecrypted);
|
||||
SimpleByteCache.release(_hX_xor_bobIdentHash);
|
||||
if (_dh.getPeerPublicValue() == null)
|
||||
if (_dh != null && _dh.getPeerPublicValue() == null)
|
||||
_transport.returnUnused(_dh);
|
||||
}
|
||||
|
||||
|
@ -123,6 +123,8 @@ class InboundEstablishState extends EstablishBase implements NTCP2Payload.Payloa
|
||||
public int getVersion() {
|
||||
if (!_transport.isNTCP2Enabled())
|
||||
return 1;
|
||||
if (!_transport.isNTCP1Enabled())
|
||||
return 2;
|
||||
synchronized (_stateLock) {
|
||||
if (_state == State.IB_INIT)
|
||||
return 0;
|
||||
@ -160,7 +162,8 @@ class InboundEstablishState extends EstablishBase implements NTCP2Payload.Payloa
|
||||
_log.warn("Short buffer got " + remaining + " total now " + _received + " on " + this);
|
||||
return;
|
||||
}
|
||||
if (remaining + _received < NTCP1_MSG1_SIZE) {
|
||||
if (remaining + _received < NTCP1_MSG1_SIZE ||
|
||||
!_transport.isNTCP1Enabled()) {
|
||||
// Less than 288 total received, assume NTCP2
|
||||
// TODO can't change our mind later if we get more than 287
|
||||
_con.setVersion(2);
|
||||
@ -743,6 +746,7 @@ class InboundEstablishState extends EstablishBase implements NTCP2Payload.Payloa
|
||||
fail("Clock Skew: " + _peerSkew, null, true);
|
||||
return;
|
||||
}
|
||||
// TODO if NTCP1 disabled, we should allow longer padding
|
||||
if (_padlen1 > PADDING1_MAX) {
|
||||
fail("bad msg 1 padlen: " + _padlen1);
|
||||
return;
|
||||
|
@ -137,6 +137,7 @@ public class NTCPTransport extends TransportImpl {
|
||||
private static final int NTCP2_IV_LEN = OutboundNTCP2State.IV_SIZE;
|
||||
private static final int NTCP2_KEY_LEN = OutboundNTCP2State.KEY_SIZE;
|
||||
private static final long MIN_DOWNTIME_TO_REKEY = 30*24*60*60*1000L;
|
||||
private final boolean _enableNTCP1;
|
||||
private final boolean _enableNTCP2;
|
||||
private final byte[] _ntcp2StaticPubkey;
|
||||
private final byte[] _ntcp2StaticPrivkey;
|
||||
@ -145,6 +146,7 @@ public class NTCPTransport extends TransportImpl {
|
||||
private final String _b64Ntcp2StaticIV;
|
||||
|
||||
/**
|
||||
* @param dh null to disable NTCP1
|
||||
* @param xdh null to disable NTCP2
|
||||
*/
|
||||
public NTCPTransport(RouterContext ctx, DHSessionKeyBuilder.Factory dh, X25519KeyFactory xdh) {
|
||||
@ -238,7 +240,10 @@ public class NTCPTransport extends TransportImpl {
|
||||
_nearCapacityCostBid = new SharedBid(105);
|
||||
_transientFail = new SharedBid(TransportBid.TRANSIENT_FAIL);
|
||||
|
||||
_enableNTCP1 = dh != null;
|
||||
_enableNTCP2 = xdh != null;
|
||||
if (!_enableNTCP1 && !_enableNTCP2)
|
||||
throw new IllegalArgumentException();
|
||||
if (_enableNTCP2) {
|
||||
boolean shouldSave = false;
|
||||
byte[] priv = null;
|
||||
@ -577,6 +582,10 @@ public class NTCPTransport extends TransportImpl {
|
||||
List<RouterAddress> addrs = getTargetAddresses(target);
|
||||
for (int i = 0; i < addrs.size(); i++) {
|
||||
RouterAddress addr = addrs.get(i);
|
||||
// use this to skip outbound-only NTCP2,
|
||||
// and NTCP1 if disabled
|
||||
if (getNTCPVersion(addr) == 0)
|
||||
continue;
|
||||
byte[] ip = addr.getIP();
|
||||
if (!TransportUtil.isValidPort(addr.getPort()) || ip == null) {
|
||||
//_context.statManager().addRateData("ntcp.connectFailedInvalidPort", 1);
|
||||
@ -840,7 +849,7 @@ public class NTCPTransport extends TransportImpl {
|
||||
props.setProperty(RouterAddress.PROP_PORT, Integer.toString(port));
|
||||
addNTCP2Options(props);
|
||||
int cost = getDefaultCost(ia instanceof Inet6Address);
|
||||
myAddress = new RouterAddress(STYLE, props, cost);
|
||||
myAddress = new RouterAddress(getPublishStyle(), props, cost);
|
||||
replaceAddress(myAddress);
|
||||
}
|
||||
} else if (_enableNTCP2) {
|
||||
@ -969,7 +978,7 @@ public class NTCPTransport extends TransportImpl {
|
||||
props.setProperty(RouterAddress.PROP_PORT, Integer.toString(port));
|
||||
addNTCP2Options(props);
|
||||
int cost = getDefaultCost(false);
|
||||
myAddress = new RouterAddress(STYLE, props, cost);
|
||||
myAddress = new RouterAddress(getPublishStyle(), props, cost);
|
||||
}
|
||||
if (!_endpoints.isEmpty()) {
|
||||
// If we are already bound to the new address, OR
|
||||
@ -1052,6 +1061,9 @@ public class NTCPTransport extends TransportImpl {
|
||||
*/
|
||||
net.i2p.router.transport.ntcp.Writer getWriter() { return _writer; }
|
||||
|
||||
/**
|
||||
* @return always "NTCP" even if NTCP1 is disabled
|
||||
*/
|
||||
public String getStyle() { return STYLE; }
|
||||
|
||||
/**
|
||||
@ -1064,16 +1076,25 @@ public class NTCPTransport extends TransportImpl {
|
||||
return _enableNTCP2 ? STYLE2 : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return "NTCP" if NTCP1 is enabled, else "NTCP2"
|
||||
* @since 0.9.39
|
||||
*/
|
||||
private String getPublishStyle() {
|
||||
return _enableNTCP1 ? STYLE : STYLE2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook for NTCPConnection
|
||||
*/
|
||||
EventPumper getPumper() { return _pumper; }
|
||||
|
||||
/**
|
||||
* @return null if not configured for NTCP1
|
||||
* @since 0.9
|
||||
*/
|
||||
DHSessionKeyBuilder getDHBuilder() {
|
||||
return _dhFactory.getBuilder();
|
||||
return _dhFactory != null ? _dhFactory.getBuilder() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1092,7 +1113,8 @@ public class NTCPTransport extends TransportImpl {
|
||||
* @since 0.9.16
|
||||
*/
|
||||
void returnUnused(DHSessionKeyBuilder builder) {
|
||||
_dhFactory.returnUnused(builder);
|
||||
if (_dhFactory != null)
|
||||
_dhFactory.returnUnused(builder);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1185,7 +1207,7 @@ public class NTCPTransport extends TransportImpl {
|
||||
props.setProperty(RouterAddress.PROP_PORT, Integer.toString(p));
|
||||
addNTCP2Options(props);
|
||||
int cost = getDefaultCost(false);
|
||||
RouterAddress addr = new RouterAddress(STYLE, props, cost);
|
||||
RouterAddress addr = new RouterAddress(getPublishStyle(), props, cost);
|
||||
return addr;
|
||||
}
|
||||
|
||||
@ -1205,6 +1227,13 @@ public class NTCPTransport extends TransportImpl {
|
||||
props.setProperty("v", NTCP2_VERSION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Is NTCP1 enabled?
|
||||
*
|
||||
* @since 0.9.39
|
||||
*/
|
||||
boolean isNTCP1Enabled() { return _enableNTCP1; }
|
||||
|
||||
/**
|
||||
* Is NTCP2 enabled?
|
||||
*
|
||||
@ -1267,9 +1296,11 @@ public class NTCPTransport extends TransportImpl {
|
||||
addr.getOption("i") == null ||
|
||||
addr.getOption("s") == null ||
|
||||
(!v.equals(NTCP2_VERSION) && !v.startsWith(NTCP2_VERSION_ALT))) {
|
||||
return (rv == 1) ? 1 : 0;
|
||||
// his address is NTCP1 or is outbound NTCP2 only
|
||||
return (rv == 1 && _enableNTCP1) ? 1 : 0;
|
||||
}
|
||||
// todo validate s/i b64, or just catch it later?
|
||||
// his address is NTCP2
|
||||
// do not validate the s/i b64, we will just catch it later
|
||||
return NTCP2_INT_VERSION;
|
||||
}
|
||||
|
||||
@ -1461,7 +1492,7 @@ public class NTCPTransport extends TransportImpl {
|
||||
cost = oldAddr.getCost();
|
||||
newProps.putAll(oldAddr.getOptionsMap());
|
||||
}
|
||||
RouterAddress newAddr = new RouterAddress(STYLE, newProps, cost);
|
||||
RouterAddress newAddr = new RouterAddress(getPublishStyle(), newProps, cost);
|
||||
|
||||
boolean changed = false;
|
||||
|
||||
@ -1532,6 +1563,8 @@ public class NTCPTransport extends TransportImpl {
|
||||
return;
|
||||
if (ohost == null || ! ohost.equalsIgnoreCase(nhost)) {
|
||||
newProps.setProperty(RouterAddress.PROP_HOST, nhost);
|
||||
if (cost == NTCP2_OUTBOUND_COST)
|
||||
newAddr.setCost(DEFAULT_COST);
|
||||
changed = true;
|
||||
}
|
||||
} else if (enabled.equals("false") &&
|
||||
@ -1543,6 +1576,8 @@ public class NTCPTransport extends TransportImpl {
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("old host: " + ohost + " config: " + name + " new: " + name);
|
||||
newProps.setProperty(RouterAddress.PROP_HOST, name);
|
||||
if (cost == NTCP2_OUTBOUND_COST)
|
||||
newAddr.setCost(DEFAULT_COST);
|
||||
changed = true;
|
||||
} else if (ohost == null || ohost.length() <= 0) {
|
||||
return;
|
||||
|
Reference in New Issue
Block a user