diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/FloodfillPeerSelector.java b/router/java/src/net/i2p/router/networkdb/kademlia/FloodfillPeerSelector.java index 23a34c32f9..49ff573e4e 100644 --- a/router/java/src/net/i2p/router/networkdb/kademlia/FloodfillPeerSelector.java +++ b/router/java/src/net/i2p/router/networkdb/kademlia/FloodfillPeerSelector.java @@ -294,7 +294,7 @@ class FloodfillPeerSelector extends PeerSelector { * @since 0.9.5 modified from ProfileOrganizer */ private Set maskedIPSet(Hash peer, RouterInfo pinfo, int mask) { - Set rv = new HashSet(2); + Set rv = new HashSet(4); byte[] commIP = _context.commSystem().getIP(peer); if (commIP != null) rv.add(maskedIP(commIP, mask)); @@ -313,12 +313,22 @@ class FloodfillPeerSelector extends PeerSelector { /** * generate an arbitrary unique value for this ip/mask (mask = 1-4) + * If IPv6, force mask = 8. * @since 0.9.5 copied from ProfileOrganizer */ private static Integer maskedIP(byte[] ip, int mask) { - int rv = 0; - for (int i = 0; i < mask; i++) - rv = (rv << 8) | (ip[i] & 0xff); + int rv = ip[0]; + if (ip.length == 16) { + for (int i = 1; i < 8; i++) { + rv <<= i * 4; + rv ^= ip[i]; + } + } else { + for (int i = 1; i < mask; i++) { + rv <<= 8; + rv ^= ip[i]; + } + } return Integer.valueOf(rv); } diff --git a/router/java/src/net/i2p/router/peermanager/ProfileOrganizer.java b/router/java/src/net/i2p/router/peermanager/ProfileOrganizer.java index 55b57bae93..4ded9f81c1 100644 --- a/router/java/src/net/i2p/router/peermanager/ProfileOrganizer.java +++ b/router/java/src/net/i2p/router/peermanager/ProfileOrganizer.java @@ -1264,7 +1264,7 @@ public class ProfileOrganizer { * @return an opaque set of masked IPs for this peer */ private Set maskedIPSet(Hash peer, int mask) { - Set rv = new HashSet(2); + Set rv = new HashSet(4); byte[] commIP = _context.commSystem().getIP(peer); if (commIP != null) rv.add(maskedIP(commIP, mask)); @@ -1282,11 +1282,23 @@ public class ProfileOrganizer { return rv; } - /** generate an arbitrary unique value for this ip/mask (mask = 1-4) */ + /** + * generate an arbitrary unique value for this ip/mask (mask = 1-4) + * If IPv6, force mask = 8. + */ private static Integer maskedIP(byte[] ip, int mask) { - int rv = 0; - for (int i = 0; i < mask; i++) - rv = (rv << 8) | (ip[i] & 0xff); + int rv = ip[0]; + if (ip.length == 16) { + for (int i = 1; i < 8; i++) { + rv <<= i * 4; + rv ^= ip[i]; + } + } else { + for (int i = 1; i < mask; i++) { + rv <<= 8; + rv ^= ip[i]; + } + } return Integer.valueOf(rv); } diff --git a/router/java/src/net/i2p/router/transport/ntcp/NTCPConnection.java b/router/java/src/net/i2p/router/transport/ntcp/NTCPConnection.java index cc2e6ac29f..e18933cc99 100644 --- a/router/java/src/net/i2p/router/transport/ntcp/NTCPConnection.java +++ b/router/java/src/net/i2p/router/transport/ntcp/NTCPConnection.java @@ -1,6 +1,7 @@ package net.i2p.router.transport.ntcp; import java.io.IOException; +import java.net.Inet6Address; import java.nio.ByteBuffer; import java.nio.channels.SelectionKey; import java.nio.channels.SocketChannel; @@ -87,7 +88,7 @@ class NTCPConnection { private final NTCPTransport _transport; private final boolean _isInbound; private volatile boolean _closed; - private RouterAddress _remAddr; + private final RouterAddress _remAddr; private RouterIdentity _remotePeer; private long _clockSkew; // in seconds /** @@ -161,6 +162,7 @@ class NTCPConnection { _log = ctx.logManager().getLog(getClass()); _created = System.currentTimeMillis(); _transport = transport; + _remAddr = null; _chan = chan; _readBufs = new ConcurrentLinkedQueue(); _writeBufs = new ConcurrentLinkedQueue(); @@ -212,15 +214,42 @@ class NTCPConnection { _prevReadBlock = new byte[BLOCK_SIZE]; _transport.establishing(this); } - + + /** + * Valid for inbound; valid for outbound shortly after creation + */ public SocketChannel getChannel() { return _chan; } + + /** + * Valid for inbound; valid for outbound shortly after creation + */ public SelectionKey getKey() { return _conKey; } public void setChannel(SocketChannel chan) { _chan = chan; } public void setKey(SelectionKey key) { _conKey = key; } public boolean isInbound() { return _isInbound; } public boolean isEstablished() { return _established; } + + /** + * @since IPv6 + */ + public boolean isIPv6() { + return _chan != null && + _chan.socket().getInetAddress() instanceof Inet6Address; + } + + /** + * Only valid during establishment; null later + */ public EstablishState getEstablishState() { return _establishState; } + + /** + * Only valid for outbound; null for inbound + */ public RouterAddress getRemoteAddress() { return _remAddr; } + + /** + * Valid for outbound; valid for inbound after handshake + */ public RouterIdentity getRemotePeer() { return _remotePeer; } public void setRemotePeer(RouterIdentity ident) { _remotePeer = ident; } diff --git a/router/java/src/net/i2p/router/transport/ntcp/NTCPTransport.java b/router/java/src/net/i2p/router/transport/ntcp/NTCPTransport.java index ed1de62b08..3be51b3df5 100644 --- a/router/java/src/net/i2p/router/transport/ntcp/NTCPTransport.java +++ b/router/java/src/net/i2p/router/transport/ntcp/NTCPTransport.java @@ -1052,7 +1052,7 @@ public class NTCPTransport extends TransportImpl { @Override public void renderStatusHTML(java.io.Writer out, String urlBase, int sortFlags) throws IOException { - TreeSet peers = new TreeSet(getComparator(sortFlags)); + TreeSet peers = new TreeSet(getComparator(sortFlags)); peers.addAll(_conByIdent.values()); long offsetTotal = 0; @@ -1070,6 +1070,7 @@ public class NTCPTransport extends TransportImpl { "\n" + "" + "" + + "" + "" + "" + "" + @@ -1082,8 +1083,7 @@ public class NTCPTransport extends TransportImpl { " \n"); out.write(buf.toString()); buf.setLength(0); - for (Iterator iter = peers.iterator(); iter.hasNext(); ) { - NTCPConnection con = (NTCPConnection)iter.next(); + for (NTCPConnection con : peers) { buf.append("\n"); - buf.append(""); long idleIn = Math.max(now-peer.getLastReceiveTime(), 0); long idleOut = Math.max(now-peer.getLastSendTime(), 0); @@ -2660,23 +2667,24 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority numPeers++; } + if (numPeers > 0) { // buf.append("\n"); - buf.append("" + + buf.append("" + "" + "\n" + "\n" + "\n" + ""); } + } // numPeers > 0 buf.append("
").append(_("Peer")).append("").append(_("Dir")).append("").append(_("IPv6")).append("").append(_("Idle")).append("").append(_("In/Out")).append("").append(_("Up")).append("
"); buf.append(_context.commSystem().renderPeerHTML(con.getRemotePeer().calculateHash())); //byte[] ip = getIP(con.getRemotePeer().calculateHash()); @@ -1094,6 +1094,11 @@ public class NTCPTransport extends TransportImpl { buf.append("\"Inbound\""); else buf.append("\"Outbound\""); + buf.append(""); + if (con.isIPv6()) + buf.append("✓"); + else + buf.append(" "); buf.append(""); buf.append(DataHelper.formatDuration2(con.getTimeSinceReceive())); buf.append(THINSP).append(DataHelper.formatDuration2(con.getTimeSinceSend())); @@ -1142,7 +1147,8 @@ public class NTCPTransport extends TransportImpl { if (!peers.isEmpty()) { // buf.append("

").append(peers.size()).append(' ').append(_("peers")).append("  "); + buf.append("
").append(_("SUMMARY")) + .append(""); buf.append("").append(formatRate(bpsRecv/1024)).append(THINSP).append(formatRate(bpsSend/1024)).append(""); buf.append("").append(DataHelper.formatDuration2(totalUptime/peers.size())); buf.append("").append(DataHelper.formatDuration2(offsetTotal*1000/peers.size())); diff --git a/router/java/src/net/i2p/router/transport/udp/PeerState.java b/router/java/src/net/i2p/router/transport/udp/PeerState.java index 04b9448159..a60af4d324 100644 --- a/router/java/src/net/i2p/router/transport/udp/PeerState.java +++ b/router/java/src/net/i2p/router/transport/udp/PeerState.java @@ -694,6 +694,12 @@ class PeerState { public int getConcurrentSendWindow() { return _concurrentMessagesAllowed; } public int getConsecutiveSendRejections() { return _consecutiveRejections; } public boolean isInbound() { return _isInbound; } + + /** @since IPv6 */ + public boolean isIPv6() { + return _remoteIP.length == 16; + } + public long getIntroducerTime() { return _lastIntroducerTime; } public void setIntroducerTime() { _lastIntroducerTime = _context.clock().now(); } diff --git a/router/java/src/net/i2p/router/transport/udp/UDPTransport.java b/router/java/src/net/i2p/router/transport/udp/UDPTransport.java index abc6117144..90a22d763b 100644 --- a/router/java/src/net/i2p/router/transport/udp/UDPTransport.java +++ b/router/java/src/net/i2p/router/transport/udp/UDPTransport.java @@ -2449,6 +2449,7 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority appendSortLinks(buf, urlBase, sortFlags, _("Sort by peer hash"), FLAG_ALPHA); buf.append("").append(_("Dir")) + .append("").append(_("IPv6")) .append("").append(_("Idle")).append("
"); appendSortLinks(buf, urlBase, sortFlags, _("Sort by idle inbound"), FLAG_IDLE_IN); buf.append(" / "); @@ -2491,8 +2492,7 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority out.write(buf.toString()); buf.setLength(0); long now = _context.clock().now(); - for (Iterator iter = peers.iterator(); iter.hasNext(); ) { - PeerState peer = (PeerState)iter.next(); + for (PeerState peer : peers) { if (now-peer.getLastReceiveTime() > 60*60*1000) continue; // don't include old peers @@ -2536,6 +2536,13 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority //if (ip != null) // buf.append(' ').append(_context.blocklist().toStr(ip)); buf.append(""); + + buf.append("
"); + if (peer.isIPv6()) + buf.append("✓"); + else + buf.append(" "); + buf.append("

").append(_("SUMMARY")).append("
").append(_("SUMMARY")).append(""); buf.append(formatKBps(bpsIn)).append(THINSP).append(formatKBps(bpsOut)); - long x = numPeers > 0 ? uptimeMsTotal/numPeers : 0; + long x = uptimeMsTotal/numPeers; buf.append("").append(DataHelper.formatDuration2(x)); - x = numPeers > 0 ? offsetTotal/numPeers : 0; + x = offsetTotal/numPeers; buf.append("").append(DataHelper.formatDuration2(x)).append(""); - buf.append(numPeers > 0 ? cwinTotal/(numPeers*1024) + "K" : "0K"); + buf.append(cwinTotal/(numPeers*1024) + "K"); buf.append(" "); - buf.append(numPeers > 0 ? DataHelper.formatDuration2(rttTotal/numPeers) : '0'); + buf.append(DataHelper.formatDuration2(rttTotal/numPeers)); //buf.append(" "); buf.append(""); - buf.append(numPeers > 0 ? DataHelper.formatDuration2(rtoTotal/numPeers) : '0'); + buf.append(DataHelper.formatDuration2(rtoTotal/numPeers)); buf.append("").append(_mtu).append(""); buf.append(sendTotal).append("").append(recvTotal).append("").append(resentTotal); @@ -2696,6 +2704,7 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority buf.append(" pBRH direct: ").append(dir).append(" indirect: ").append(indir); buf.append("
\n"); /*****