use of net.i2p.data.router.RouterAddress in project i2p.i2p by i2p.
the class ConnectChecker method getOutboundMask.
/**
* Our outbound mask.
* For most cases, we use our comm system status.
*
* @return bitmask for initiating connections
* @since 0.9.34
*/
public int getOutboundMask(RouterInfo us) {
// from us
int cf = 0;
Status status = ctx.commSystem().getStatus();
switch(status) {
case OK:
// use what we published, as the OK state doesn't tell us about IPv6
// Addresses.isConnectedIPv6() is too slow
Collection<RouterAddress> a = us.getAddresses();
if (a.isEmpty()) {
// TODO ipv6
if (!isNTCPDisabled())
cf |= NTCP_V4;
if (!isSSUDisabled())
cf |= SSU_V4;
} else {
cf = getConnectMask(a);
}
break;
case IPV4_OK_IPV6_FIREWALLED:
case IPV4_UNKNOWN_IPV6_OK:
case IPV4_FIREWALLED_IPV6_OK:
case IPV4_SNAT_IPV6_OK:
case IPV4_UNKNOWN_IPV6_FIREWALLED:
if (!isNTCPDisabled())
cf |= NTCP_V4 | NTCP_V6;
if (!isSSUDisabled())
cf |= SSU_V4 | SSU_V6;
break;
case IPV4_DISABLED_IPV6_OK:
case IPV4_DISABLED_IPV6_UNKNOWN:
case IPV4_DISABLED_IPV6_FIREWALLED:
if (!isNTCPDisabled())
cf |= NTCP_V6;
if (!isSSUDisabled())
cf |= SSU_V6;
break;
case DIFFERENT:
case IPV4_SNAT_IPV6_UNKNOWN:
case IPV4_FIREWALLED_IPV6_UNKNOWN:
case REJECT_UNSOLICITED:
case IPV4_OK_IPV6_UNKNOWN:
case DISCONNECTED:
case HOSED:
case UNKNOWN:
default:
if (!isNTCPDisabled())
cf |= NTCP_V4;
if (!isSSUDisabled())
cf |= SSU_V4;
break;
}
return cf;
}
use of net.i2p.data.router.RouterAddress in project i2p.i2p by i2p.
the class TransportImpl method replaceAddress.
/**
* Replace any existing addresses for the current transport
* with the same IP length (4 or 16) with the given one.
* TODO: Allow multiple addresses of the same length.
* Calls listener.transportAddressChanged()
* To remove all IPv4 or IPv6 addresses, use removeAddress(boolean).
*
* @param address null to remove all
*/
protected void replaceAddress(RouterAddress address) {
if (_log.shouldLog(Log.WARN))
_log.warn("Replacing address with " + address, new Exception());
if (address == null) {
_currentAddresses.clear();
} else {
boolean isIPv6 = TransportUtil.isIPv6(address);
for (RouterAddress ra : _currentAddresses) {
if (isIPv6 == TransportUtil.isIPv6(ra))
// COWAL
_currentAddresses.remove(ra);
}
_currentAddresses.add(address);
}
if (_log.shouldLog(Log.WARN))
_log.warn(getStyle() + " now has " + _currentAddresses.size() + " addresses");
if (_listener != null)
_listener.transportAddressChanged();
}
use of net.i2p.data.router.RouterAddress in project i2p.i2p by i2p.
the class PeerTestManager method receiveFromAliceAsBob.
/**
* The PeerTest message came from the peer referenced in the message (or there wasn't
* any info in the message), plus we are not acting as Charlie (so we've got to be Bob).
*
* testInfo IP/port ignored
* @param state null if new
*/
private void receiveFromAliceAsBob(RemoteHostId from, UDPPacketReader.PeerTestReader testInfo, long nonce, PeerTestState state) {
// we are Bob, so pick a (potentially) Charlie and send Charlie Alice's info
PeerState charlie;
RouterInfo charlieInfo = null;
int sz = from.getIP().length;
boolean isIPv6 = sz == 16;
if (state == null) {
// pick a new charlie
// if (from.getIP().length != 4) {
// if (_log.shouldLog(Log.WARN))
// _log.warn("PeerTest over IPv6 from Alice as Bob? " + from);
// return;
// }
charlie = _transport.pickTestPeer(CHARLIE, isIPv6, from);
} else {
charlie = _transport.getPeerState(new RemoteHostId(state.getCharlieIP().getAddress(), state.getCharliePort()));
}
if (charlie == null) {
if (_log.shouldLog(Log.WARN))
_log.warn("Unable to pick a charlie (no peer), IPv6? " + isIPv6);
return;
}
charlieInfo = _context.netDb().lookupRouterInfoLocally(charlie.getRemotePeer());
if (charlieInfo == null) {
if (_log.shouldLog(Log.WARN))
_log.warn("Unable to pick a charlie (no RI), IPv6? " + isIPv6);
return;
}
// TODO should only do most of this if isNew
InetAddress aliceIP = null;
SessionKey aliceIntroKey = null;
try {
aliceIP = InetAddress.getByAddress(from.getIP());
aliceIntroKey = new SessionKey(new byte[SessionKey.KEYSIZE_BYTES]);
testInfo.readIntroKey(aliceIntroKey.getData(), 0);
RouterAddress raddr = _transport.getTargetAddress(charlieInfo);
if (raddr == null) {
if (_log.shouldLog(Log.WARN))
_log.warn("Unable to pick a charlie (no addr), IPv6? " + isIPv6);
return;
}
UDPAddress addr = new UDPAddress(raddr);
byte[] ikey = addr.getIntroKey();
if (ikey == null) {
if (_log.shouldLog(Log.WARN))
_log.warn("Unable to pick a charlie (no ikey), IPv6? " + isIPv6);
return;
}
SessionKey charlieIntroKey = new SessionKey(ikey);
// UDPPacket packet = _packetBuilder.buildPeerTestToAlice(aliceIP, from.getPort(), aliceIntroKey, charlieIntroKey, nonce);
// _transport.send(packet);
long now = _context.clock().now();
boolean isNew = false;
if (state == null) {
isNew = true;
state = new PeerTestState(BOB, isIPv6, nonce, now);
} else {
if (state.getReceiveAliceTime() > now - (RESEND_TIMEOUT / 2)) {
if (_log.shouldLog(Log.WARN))
_log.warn("Too soon, not retransmitting: " + state);
return;
}
}
state.setAliceIP(aliceIP);
state.setAlicePort(from.getPort());
state.setAliceIntroKey(aliceIntroKey);
state.setCharlieIP(charlie.getRemoteIPAddress());
state.setCharliePort(charlie.getRemotePort());
state.setCharlieIntroKey(charlieIntroKey);
state.setLastSendTime(now);
state.setReceiveAliceTime(now);
if (state.incrementPacketsRelayed() > MAX_RELAYED_PER_TEST_BOB) {
if (_log.shouldLog(Log.WARN))
_log.warn("Too many, not retransmitting: " + state);
return;
}
if (isNew) {
_activeTests.put(Long.valueOf(nonce), state);
_context.simpleTimer2().addEvent(new RemoveTest(nonce), MAX_CHARLIE_LIFETIME);
}
UDPPacket packet = _packetBuilder.buildPeerTestToCharlie(aliceIP, from.getPort(), aliceIntroKey, nonce, charlie.getRemoteIPAddress(), charlie.getRemotePort(), charlie.getCurrentCipherKey(), charlie.getCurrentMACKey());
if (_log.shouldLog(Log.DEBUG))
_log.debug("Receive from Alice: " + state);
_transport.send(packet);
} catch (UnknownHostException uhe) {
if (_log.shouldLog(Log.WARN))
_log.warn("Unable to build the aliceIP from " + from, uhe);
_context.statManager().addRateData("udp.testBadIP", 1);
}
}
use of net.i2p.data.router.RouterAddress in project i2p.i2p by i2p.
the class UDPTransport method getTargetAddress.
/**
* Get first available address we can use.
* @return address or null
* @since 0.9.6
*/
RouterAddress getTargetAddress(RouterInfo target) {
List<RouterAddress> addrs = getTargetAddresses(target);
for (int i = 0; i < addrs.size(); i++) {
RouterAddress addr = addrs.get(i);
if (addr.getOption("ihost0") == null) {
byte[] ip = addr.getIP();
int port = addr.getPort();
if (ip == null || !TransportUtil.isValidPort(port) || (!isValid(ip)) || (Arrays.equals(ip, getExternalIP()) && !allowLocal())) {
continue;
}
} else {
// introducers
if (getIPv6Config() == IPV6_ONLY)
continue;
}
return addr;
}
return null;
}
use of net.i2p.data.router.RouterAddress in project i2p.i2p by i2p.
the class UDPTransport method pickTestPeer.
/**
* Pick a Bob (if we are Alice) or a Charlie (if we are Bob).
*
* For Bob (as called from PeerTestEvent below), returns an established IPv4/v6 peer.
* While the protocol allows Alice to select an unestablished Bob, we don't support that.
*
* For Charlie (as called from PeerTestManager), returns an established IPv4 or IPv6 peer.
* (doesn't matter how Bob and Charlie communicate)
*
* Any returned peer must advertise an IPv4 address to prove it is IPv4-capable.
* Ditto for v6.
*
* @param peerRole The role of the peer we are looking for, BOB or CHARLIE only (NOT our role)
* @param isIPv6 true to get a v6-capable peer back
* @param dontInclude may be null
* @return IPv4 peer or null
*/
PeerState pickTestPeer(PeerTestState.Role peerRole, boolean isIPv6, RemoteHostId dontInclude) {
if (peerRole == ALICE)
throw new IllegalArgumentException();
List<PeerState> peers = new ArrayList<PeerState>(_peersByIdent.values());
for (Iterator<PeerState> iter = new RandomIterator<PeerState>(peers); iter.hasNext(); ) {
PeerState peer = iter.next();
if ((dontInclude != null) && (dontInclude.equals(peer.getRemoteHostId())))
continue;
// enforce IPv4/v6 connection if we are ALICE looking for a BOB
byte[] ip = peer.getRemoteIP();
if (peerRole == BOB) {
if (isIPv6) {
if (ip.length != 16)
continue;
} else {
if (ip.length != 4)
continue;
}
}
// enforce IPv4/v6 advertised for all
RouterInfo peerInfo = _context.netDb().lookupRouterInfoLocally(peer.getRemotePeer());
if (peerInfo == null)
continue;
if (isIPv6) {
String v = peerInfo.getVersion();
if (VersionComparator.comp(v, MIN_V6_PEER_TEST_VERSION) < 0)
continue;
}
ip = null;
List<RouterAddress> addrs = getTargetAddresses(peerInfo);
for (RouterAddress addr : addrs) {
byte[] rip = addr.getIP();
if (rip != null) {
if (isIPv6) {
if (rip.length != 16)
continue;
} else {
if (rip.length != 4)
continue;
}
// as of 0.9.27, we trust the 'B' cap for IPv6
String caps = addr.getOption(UDPAddress.PROP_CAPACITY);
if (caps != null && caps.contains(CAP_TESTING)) {
ip = rip;
break;
}
}
}
if (ip == null)
continue;
if (isTooClose(ip))
continue;
return peer;
}
return null;
}
Aggregations