forked from I2P_Developers/i2p.i2p
* Transports:
- Prefer IPv6 by default - Fix IPv6-only option - Don't try NTCP IPv6 addresses unless we have one - Fix non-%16 SSU padding in data and session confirmed packets; enable by default - Log tweaks
This commit is contained in:
10
history.txt
10
history.txt
@@ -1,3 +1,13 @@
|
||||
2012-07-25 zzz
|
||||
* Transports:
|
||||
- Prefer IPv6 by default
|
||||
- Fix IPv6-only option
|
||||
- Don't try NTCP IPv6 addresses unless we have one
|
||||
- Fix non-%16 SSU padding; enable by default
|
||||
* Tunnels:
|
||||
- Make expl. default 3 hops (ticket #966)
|
||||
- Allow expl. fallback up to -2 hops
|
||||
|
||||
2012-07-24 zzz
|
||||
* GeoIP: Fix lookups, broken in IPv6 branch
|
||||
* UPnP:
|
||||
|
||||
@@ -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 = 10;
|
||||
public final static long BUILD = 11;
|
||||
|
||||
/** for example "-test" */
|
||||
public final static String EXTRA = "";
|
||||
|
||||
@@ -243,8 +243,8 @@ public abstract class TransportImpl implements Transport {
|
||||
if (!sendSuccessful)
|
||||
msg.transportFailed(getStyle());
|
||||
|
||||
if (msToSend > 1000) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
if (msToSend > 1500) {
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.warn(getStyle() + " afterSend slow: " + (sendSuccessful ? "success " : "FAIL ")
|
||||
+ msg.getMessageSize() + " byte "
|
||||
+ msg.getMessageType() + ' ' + msg.getMessageId() + " to "
|
||||
@@ -577,14 +577,24 @@ public abstract class TransportImpl implements Transport {
|
||||
*/
|
||||
protected List<RouterAddress> getTargetAddresses(RouterInfo target) {
|
||||
List<RouterAddress> rv = target.getTargetAddresses(getStyle());
|
||||
if (rv.isEmpty())
|
||||
return rv;
|
||||
// Shuffle so everybody doesn't use the first one
|
||||
if (rv.size() > 1) {
|
||||
if (rv.size() > 1)
|
||||
Collections.shuffle(rv, _context.random());
|
||||
TransportUtil.IPv6Config config = getIPv6Config();
|
||||
int adj;
|
||||
switch (config) {
|
||||
TransportUtil.IPv6Config config = getIPv6Config();
|
||||
int adj;
|
||||
switch (config) {
|
||||
case IPV6_DISABLED:
|
||||
adj = 10; break;
|
||||
adj = 10;
|
||||
/**** IPv6 addresses will be rejected in isPubliclyRoutable()
|
||||
for (Iterator<RouterAddress> iter = rv.iterator(); iter.hasNext(); ) {
|
||||
byte[] ip = iter.next().getIP();
|
||||
if (ip != null && ip.length == 16)
|
||||
iter.remove();
|
||||
}
|
||||
****/
|
||||
break;
|
||||
case IPV6_NOT_PREFERRED:
|
||||
adj = 1; break;
|
||||
default:
|
||||
@@ -593,10 +603,17 @@ public abstract class TransportImpl implements Transport {
|
||||
case IPV6_PREFERRED:
|
||||
adj = -1; break;
|
||||
case IPV6_ONLY:
|
||||
adj = -10; break;
|
||||
}
|
||||
Collections.sort(rv, new AddrComparator(adj));
|
||||
adj = -10;
|
||||
// IPv4 addresses not rejected in isPubliclyRoutable()
|
||||
for (Iterator<RouterAddress> iter = rv.iterator(); iter.hasNext(); ) {
|
||||
byte[] ip = iter.next().getIP();
|
||||
if (ip != null && ip.length == 4)
|
||||
iter.remove();
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (rv.size() > 1)
|
||||
Collections.sort(rv, new AddrComparator(adj));
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ public abstract class TransportUtil {
|
||||
}
|
||||
|
||||
private static final Map<String, IPv6Config> BY_NAME = new HashMap<String, IPv6Config>();
|
||||
public static final IPv6Config DEFAULT_IPV6_CONFIG = IPv6Config.IPV6_DISABLED;
|
||||
public static final IPv6Config DEFAULT_IPV6_CONFIG = IPv6Config.IPV6_PREFERRED;
|
||||
|
||||
static {
|
||||
for (IPv6Config cfg : IPv6Config.values()) {
|
||||
@@ -60,6 +60,7 @@ public abstract class TransportUtil {
|
||||
}
|
||||
// alias
|
||||
BY_NAME.put("true", IPv6Config.IPV6_ENABLED);
|
||||
BY_NAME.put("disable", IPv6Config.IPV6_DISABLED);
|
||||
}
|
||||
|
||||
public static IPv6Config getIPv6Config(RouterContext ctx, String transportStyle) {
|
||||
|
||||
@@ -25,6 +25,7 @@ import net.i2p.data.RouterIdentity;
|
||||
import net.i2p.router.CommSystemFacade;
|
||||
import net.i2p.router.RouterContext;
|
||||
import net.i2p.router.transport.FIFOBandwidthLimiter;
|
||||
import net.i2p.util.Addresses;
|
||||
import net.i2p.util.ConcurrentHashSet;
|
||||
import net.i2p.util.I2PThread;
|
||||
import net.i2p.util.Log;
|
||||
@@ -781,8 +782,8 @@ class EventPumper implements Runnable {
|
||||
SelectionKey key = con.getChannel().register(_selector, SelectionKey.OP_CONNECT);
|
||||
key.attach(con);
|
||||
con.setKey(key);
|
||||
RouterAddress naddr = con.getRemoteAddress();
|
||||
try {
|
||||
RouterAddress naddr = con.getRemoteAddress();
|
||||
if (naddr.getPort() <= 0)
|
||||
throw new IOException("Invalid NTCP address: " + naddr);
|
||||
InetSocketAddress saddr = new InetSocketAddress(naddr.getHost(), naddr.getPort());
|
||||
@@ -794,7 +795,8 @@ class EventPumper implements Runnable {
|
||||
processConnect(key);
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
if (_log.shouldLog(Log.WARN)) _log.warn("error connecting", ioe);
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("error connecting to " + Addresses.toString(naddr.getIP(), naddr.getPort()), ioe);
|
||||
_context.statManager().addRateData("ntcp.connectFailedIOE", 1);
|
||||
_transport.markUnreachable(con.getRemotePeer().calculateHash());
|
||||
//if (ntcpOnly(con)) {
|
||||
|
||||
@@ -72,6 +72,12 @@ public class NTCPTransport extends TransportImpl {
|
||||
*/
|
||||
private final Set<NTCPConnection> _establishing;
|
||||
|
||||
/**
|
||||
* Do we have a public IPv6 address?
|
||||
* TODO periodically update via CSFI.NetMonitor?
|
||||
*/
|
||||
private boolean _haveIPv6Address;
|
||||
|
||||
public final static String PROP_I2NP_NTCP_HOSTNAME = "i2np.ntcp.hostname";
|
||||
public final static String PROP_I2NP_NTCP_PORT = "i2np.ntcp.port";
|
||||
public final static String PROP_I2NP_NTCP_AUTO_PORT = "i2np.ntcp.autoport";
|
||||
@@ -364,7 +370,7 @@ public class NTCPTransport extends TransportImpl {
|
||||
// _log.debug("no bid when trying to send to " + peer + " as they don't have a valid ntcp address");
|
||||
continue;
|
||||
}
|
||||
if (!isPubliclyRoutable(ip)) {
|
||||
if (!isValid(ip)) {
|
||||
if (! _context.getBooleanProperty("i2np.ntcp.allowLocal")) {
|
||||
//_context.statManager().addRateData("ntcp.bidRejectedLocalAddress", 1);
|
||||
//if (_log.shouldLog(Log.DEBUG))
|
||||
@@ -376,6 +382,21 @@ public class NTCPTransport extends TransportImpl {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* An IPv6 address is only valid if we are configured to support IPv6
|
||||
* AND we have a public IPv6 address.
|
||||
*
|
||||
* @param addr may be null, returns false
|
||||
* @since 0.9.8
|
||||
*/
|
||||
private boolean isValid(byte addr[]) {
|
||||
if (addr == null) return false;
|
||||
if (isPubliclyRoutable(addr) &&
|
||||
(addr.length != 16 || _haveIPv6Address))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean allowConnection() {
|
||||
return countActivePeers() < getMaxConnections();
|
||||
@@ -809,7 +830,12 @@ public class NTCPTransport extends TransportImpl {
|
||||
public void externalAddressReceived(AddressSource source, byte[] ip, int port) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Received address: " + Addresses.toString(ip, port) + " from: " + source);
|
||||
if (ip != null && !isPubliclyRoutable(ip)) {
|
||||
if ((source == SOURCE_INTERFACE || source == SOURCE_SSU)
|
||||
&& ip != null && ip.length == 16) {
|
||||
// must be set before isValid() call
|
||||
_haveIPv6Address = true;
|
||||
}
|
||||
if (ip != null && !isValid(ip)) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Invalid address: " + Addresses.toString(ip, port) + " from: " + source);
|
||||
return;
|
||||
|
||||
@@ -161,6 +161,7 @@ class PacketBuilder {
|
||||
private static final int MAX_RESEND_ACKS_SMALL = 4;
|
||||
|
||||
private static final String PROP_PADDING = "i2np.udp.padding";
|
||||
private static final boolean DEFAULT_ENABLE_PADDING = true;
|
||||
|
||||
/**
|
||||
* @param transport may be null for unit testing only
|
||||
@@ -408,7 +409,7 @@ class PacketBuilder {
|
||||
|
||||
// pad up so we're on the encryption boundary
|
||||
off = pad1(data, off);
|
||||
off = pad2(data, off, currentMTU);
|
||||
off = pad2(data, off, currentMTU - (ipHeaderSize + UDP_HEADER_SIZE));
|
||||
pkt.setLength(off);
|
||||
|
||||
authenticate(packet, peer.getCurrentCipherKey(), peer.getCurrentMACKey());
|
||||
@@ -782,6 +783,9 @@ class PacketBuilder {
|
||||
_context.random().nextBytes(data, off, paddingRequired);
|
||||
off += paddingRequired;
|
||||
}
|
||||
// We cannot have non-mod16 (pad2) padding here, since the signature
|
||||
// is at the end. As of 0.9.7 we won't decrypt past the end of the packet
|
||||
// so trailing non-mod-16 data is ignored. That truncates the sig.
|
||||
|
||||
// BUG: NPE here if null signature
|
||||
System.arraycopy(state.getSentSignature().getData(), 0, data, off, Signature.SIGNATURE_BYTES);
|
||||
@@ -792,8 +796,9 @@ class PacketBuilder {
|
||||
// nothing more to add beyond the identity fragment
|
||||
// pad up so we're on the encryption boundary
|
||||
off = pad1(data, off);
|
||||
// allowed but untested
|
||||
//off = pad2(data, off);
|
||||
}
|
||||
off = pad2(data, off);
|
||||
pkt.setLength(off);
|
||||
authenticate(packet, state.getCipherKey(), state.getMACKey());
|
||||
setTo(packet, to, state.getSentPort());
|
||||
@@ -1351,7 +1356,7 @@ class PacketBuilder {
|
||||
* @since 0.9.7
|
||||
*/
|
||||
private int pad2(byte[] data, int off) {
|
||||
if (!_context.getBooleanProperty(PROP_PADDING))
|
||||
if (!_context.getProperty(PROP_PADDING, DEFAULT_ENABLE_PADDING))
|
||||
return off;
|
||||
int padSize = _context.random().nextInt(MAX_PAD2);
|
||||
if (padSize == 0)
|
||||
@@ -1370,7 +1375,7 @@ class PacketBuilder {
|
||||
* @since 0.9.7
|
||||
*/
|
||||
private int pad2(byte[] data, int off, int maxLen) {
|
||||
if (!_context.getBooleanProperty(PROP_PADDING))
|
||||
if (!_context.getProperty(PROP_PADDING, DEFAULT_ENABLE_PADDING))
|
||||
return off;
|
||||
if (off >= maxLen)
|
||||
return off;
|
||||
|
||||
Reference in New Issue
Block a user