SSU: Remove restrictions on IPv6 introducers (prop. 158)

WIP, not fully tested
Don't try to rebuild IPv4 address when IPv4 disabled
Don't bid on a peer if marked unreachable
Fail outbound immediately if no valid introducers
Reduce IPv6 too-close length check from 8 bytes to 4
Log tweaks
This commit is contained in:
zzz
2021-04-03 15:24:03 -04:00
parent 1b1b0f545f
commit 1307e5b2e0
3 changed files with 38 additions and 27 deletions

View File

@@ -943,16 +943,16 @@ class EstablishmentManager {
_context.statManager().addRateData("udp.sendIntroRelayRequest", 1);
List<UDPPacket> requests = _builder.buildRelayRequest(_transport, this, state, _transport.getIntroKey());
if (requests.isEmpty()) {
// FIXME need a failed OB state
if (_log.shouldLog(Log.WARN))
_log.warn("No valid introducers! " + state);
// set failed state, remove nonce, and return
processExpired(state);
return;
}
for (UDPPacket req : requests) {
_transport.send(req);
}
if (_log.shouldLog(Log.DEBUG))
_log.debug("Send intro for " + state + " with our intro key as " + _transport.getIntroKey());
_log.debug("Send relay request for " + state + " with our intro key as " + _transport.getIntroKey());
state.introSent();
}
@@ -1043,13 +1043,13 @@ class EstablishmentManager {
/**
* Are IP and port valid? This is only for checking the relay response.
* Reject all IPv6, for now, even if we are configured for it.
* Allow IPv6 as of 0.9.50.
* Refuse anybody in the same /16
* @since 0.9.3, pkg private since 0.9.45 for PacketBuider
*/
boolean isValid(byte[] ip, int port) {
return TransportUtil.isValidPort(port) &&
ip != null && ip.length == 4 &&
ip != null &&
_transport.isValid(ip) &&
(!_transport.isTooClose(ip)) &&
(!_context.blocklist().isBlocklisted(ip));
@@ -1377,7 +1377,7 @@ class EstablishmentManager {
boolean removed = _liveIntroductions.remove(Long.valueOf(nonce), outboundState);
if (removed) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Send intro for " + outboundState + " timed out");
_log.debug("Relay request for " + outboundState + " timed out");
_context.statManager().addRateData("udp.sendIntroRelayTimeout", 1);
}
}

View File

@@ -1224,7 +1224,7 @@ class PacketBuilder {
(Arrays.equals(iaddr.getAddress(), _transport.getExternalIP()) && !_transport.allowLocal())) {
if (_log.shouldLog(Log.WARN))
_log.warn("Cannot build a relay request for " + state.getRemoteIdentity().calculateHash()
+ ", as the introducer address is invalid: " + Addresses.toString(iaddr.getAddress(), iport));
+ ", introducer address is invalid or blocklisted: " + Addresses.toString(iaddr.getAddress(), iport));
// TODO implement some sort of introducer banlist
continue;
}
@@ -1262,7 +1262,7 @@ class PacketBuilder {
rv.add(pkt);
else if (_log.shouldWarn())
_log.warn("Cannot build a relay request for " + state.getRemoteIdentity().calculateHash()
+ ", as we don't have an IPv4 address to send to: " + Addresses.toString(iaddr.getAddress(), iport));
+ ", as we don't have an address to send to: " + Addresses.toString(iaddr.getAddress(), iport));
}
return rv;
}
@@ -1278,18 +1278,28 @@ class PacketBuilder {
byte data[] = pkt.getData();
int off = HEADER_SIZE;
// Must specify these if request is going over IPv6
// Must specify these if request is going over IPv6 for v4 or vice versa
byte ourIP[];
int ourPort;
if (introHost instanceof Inet6Address) {
RouterAddress ra = _transport.getCurrentExternalAddress(false);
if (ra == null)
RouterAddress ra = _transport.getCurrentExternalAddress(true);
if (ra == null) {
ra = _transport.getCurrentExternalAddress(false);
if (ra == null)
return null;
}
byte[] ip = ra.getIP();
if (ip == null)
return null;
ourIP = ra.getIP();
if (ourIP == null)
return null;
ourPort = _transport.getRequestedPort();
if (ip.length != 16) {
ourIP = ip;
ourPort = _transport.getRequestedPort();
} else {
ourIP = null;
ourPort = 0;
}
} else {
// TODO IPv4 introducer, IPv6 introduction
ourIP = null;
ourPort = 0;
}

View File

@@ -825,7 +825,7 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
if (DataHelper.eq(ip, 0, myip, 0, 2))
return true;
} else if (ip.length == 16) {
if (DataHelper.eq(ip, 0, myip, 0, 8))
if (DataHelper.eq(ip, 0, myip, 0, 4))
return true;
}
}
@@ -1822,7 +1822,6 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
* @return 1 for ipv4, 2 for ipv6, 0 for neither
*/
private int locked_needsRebuild() {
if (_needsRebuild) return 1; // assume ipv4
if (_context.router().isHidden()) return 0;
TransportUtil.IPv6Config config = getIPv6Config();
// IPv4
@@ -1849,6 +1848,8 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
* @since 0.9.50 split out from above
*/
private boolean locked_needsRebuild(RouterAddress addr, boolean ipv6) {
if (_needsRebuild)
return true;
if (introducersRequired(ipv6)) {
UDPAddress ua = new UDPAddress(addr);
long now = _context.clock().now();
@@ -2043,6 +2044,9 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
return null;
}
if (isUnreachable(to))
return null;
// Validate his SSU address
RouterAddress addr = getTargetAddress(toAddress);
if (addr == null) {
@@ -2150,11 +2154,8 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
}
} else {
// introducers
if (getIPv6Config() == IPV6_ONLY)
continue;
// TODO support IPv6 introductions
String caps = addr.getOption(UDPAddress.PROP_CAPACITY);
if (caps != null && caps.contains(CAP_IPV6) /* && !_haveIPv6Address */ )
if (caps != null && caps.contains(CAP_IPV6) && !_haveIPv6Address)
continue;
}
return addr;
@@ -2340,13 +2341,14 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
}
/**
* Rebuild to get updated cost and introducers. IPv4 only.
* Rebuild to get updated cost and introducers. IPv4 only, unless configured as IPv6 only.
* Do not tell the router (he is the one calling this)
* @since 0.7.12
*/
@Override
public List<RouterAddress> updateAddress() {
rebuildExternalAddress(false, false);
boolean ipv6 = getIPv6Config() == IPV6_ONLY;
rebuildExternalAddress(false, ipv6);
return getCurrentAddresses();
}
@@ -2672,8 +2674,7 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
addr = null;
}
if (!isIPv6)
_needsRebuild = false;
_needsRebuild = false;
return addr;
} else {
if (_log.shouldLog(Log.WARN))
@@ -3311,8 +3312,8 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
} else if ((!haveCap || !peer.isInbound()) &&
peer.getMayDisconnect() &&
peer.getMessagesReceived() <= 2 && peer.getMessagesSent() <= 2) {
if (_log.shouldInfo())
_log.info("Possible early disconnect for: " + peer);
//if (_log.shouldInfo())
// _log.info("Possible early disconnect for: " + peer);
inactivityCutoff = mayDisconCutoff;
} else {
inactivityCutoff = shortInactivityCutoff;