Changeset 8226e92


Ignore:
Timestamp:
Dec 16, 2015 2:37:40 PM (4 years ago)
Author:
zzz <zzz@…>
Branches:
master
Children:
c59496f3
Parents:
af26f73
Message:

Profiles: Don't use same family in a tunnel
Reduce IPv6 mask from 8 to 6

File:
1 edited

Legend:

Unmodified
Added
Removed
  • router/java/src/net/i2p/router/peermanager/ProfileOrganizer.java

    raf26f73 r8226e92  
    1818import java.util.concurrent.locks.ReentrantReadWriteLock;
    1919
    20 import net.i2p.crypto.SHA256Generator;
     20import net.i2p.data.DataHelper;
    2121import net.i2p.data.Hash;
    2222import net.i2p.data.router.RouterAddress;
     
    12351235
    12361236    /**
     1237      *
     1238      * As of 0.9.24, checks for a netdb family match as well, unless mask == 0.
     1239      *
    12371240     * @param mask 0-4 Number of bytes to match to determine if peers in the same IP range should
    12381241     *             not be in the same tunnel. 0 = disable check; 1 = /8; 2 = /16; 3 = /24; 4 = exact IP match
     
    12401243    private void locked_selectPeers(Map<Hash, PeerProfile> peers, int howMany, Set<Hash> toExclude, Set<Hash> matches, int mask) {
    12411244        List<Hash> all = new ArrayList<Hash>(peers.keySet());
    1242         Set<Integer> IPSet = new HashSet<Integer>(8);
     1245        Set<String> IPSet = new HashSet<String>(8);
    12431246        // use RandomIterator to avoid shuffling the whole thing
    12441247        for (Iterator<Hash> iter = new RandomIterator<Hash>(all); (matches.size() < howMany) && iter.hasNext(); ) {
     
    12661269     * Does the peer's IP address NOT match the IP address of any peer already in the set,
    12671270     * on any transport, within a given mask?
     1271     *
     1272     * As of 0.9.24, checks for a netdb family match as well.
     1273     *
    12681274     * @param mask is 1-4 (number of bytes to match)
    12691275     * @param IPMatches all IPs so far, modified by this routine
    12701276     */
    1271     private boolean notRestricted(Hash peer, Set<Integer> IPSet, int mask) {
    1272         Set<Integer> peerIPs = maskedIPSet(peer, mask);
     1277    private boolean notRestricted(Hash peer, Set<String> IPSet, int mask) {
     1278        Set<String> peerIPs = maskedIPSet(peer, mask);
    12731279        if (containsAny(IPSet, peerIPs))
    12741280            return false;
     
    12811287      * Includes the comm system's record of the IP, and all netDb addresses.
    12821288      *
     1289      * As of 0.9.24, returned set will include netdb family as well.
     1290      *
    12831291      * @return an opaque set of masked IPs for this peer
    12841292      */
    1285     private Set<Integer> maskedIPSet(Hash peer, int mask) {
    1286         Set<Integer> rv = new HashSet<Integer>(4);
     1293    private Set<String> maskedIPSet(Hash peer, int mask) {
     1294        Set<String> rv = new HashSet<String>(4);
    12871295        byte[] commIP = _context.commSystem().getIP(peer);
    12881296        if (commIP != null)
     
    12971305            rv.add(maskedIP(pib, mask));
    12981306        }
     1307        String family = pinfo.getOption("family");
     1308        if (family != null) {
     1309            // TODO should KNDF put a family-verified indicator in the RI,
     1310            // after checking the sig, or does it matter?
     1311            // What's the threat here of not avoid ding a router
     1312            // falsely claiming to be in the family?
     1313            // Prefix with something so an IP can't be spoofed
     1314            rv.add('x' + family);
     1315        }
    12991316        return rv;
    13001317    }
     
    13021319    /**
    13031320     * generate an arbitrary unique value for this ip/mask (mask = 1-4)
    1304      * If IPv6, force mask = 8.
    1305      */
    1306     private static Integer maskedIP(byte[] ip, int mask) {
    1307         int rv = ip[0];
     1321     * If IPv6, force mask = 6.
     1322     */
     1323    private static String maskedIP(byte[] ip, int mask) {
     1324        final StringBuilder buf = new StringBuilder(1 + (mask*2));
     1325        final char delim;
    13081326        if (ip.length == 16) {
    1309             for (int i = 1; i < 8; i++) {
    1310                 rv <<= i * 4;
    1311                 rv ^= ip[i];
    1312             }
     1327            mask = 6;
     1328            delim = ':';
    13131329        } else {
    1314             for (int i = 1; i < mask; i++) {
    1315                 rv <<= 8;
    1316                 rv ^= ip[i];
    1317             }
    1318         }
    1319         return Integer.valueOf(rv);
     1330            delim = '.';
     1331        }
     1332        buf.append(delim);
     1333        buf.append(Long.toHexString(DataHelper.fromLong(ip, 0, mask)));
     1334        return buf.toString();
    13201335    }
    13211336
    13221337    /** does a contain any of the elements in b? */
    13231338    private static <T> boolean  containsAny(Set<T> a, Set<T> b) {
     1339        if (a.isEmpty() || b.isEmpty())
     1340            return false;
    13241341        for (T o : b) {
    13251342            if (a.contains(o))
Note: See TracChangeset for help on using the changeset viewer.