Changeset 9437e2c


Ignore:
Timestamp:
Dec 15, 2018 5:49:52 PM (20 months ago)
Author:
zzz <zzz@…>
Branches:
master
Children:
fa0d63f
Parents:
3054a24
Message:

Sybil: Refactoring to separate analysis and display, part 3

Location:
apps/routerconsole/java/src/net/i2p/router
Files:
2 added
2 edited

Legend:

Unmodified
Added
Removed
  • apps/routerconsole/java/src/net/i2p/router/web/helpers/NetDbRenderer.java

    r3054a24 r9437e2c  
    3939import net.i2p.router.util.HashDistance;   // debug
    4040import net.i2p.router.networkdb.kademlia.FloodfillNetworkDatabaseFacade;
     41import static net.i2p.router.sybil.Util.biLog2;
    4142import net.i2p.router.web.Messages;
    4243import net.i2p.router.web.WebAppStarter;
     
    580581
    581582    /**
    582      * For debugging
    583      * http://forums.sun.com/thread.jspa?threadID=597652
    584      * @since 0.7.14
    585      */
    586     public static double biLog2(BigInteger a) {
    587         int b = a.bitLength() - 1;
    588         double c = 0;
    589         double d = 0.5;
    590         for (int i = b; i >= 0; --i) {
    591              if (a.testBit(i))
    592                  c += d;
    593              d /= 2;
    594         }
    595         return b + c;
    596     }
    597 
    598     /**
    599583     *  @param mode 0: charts only; 1: full routerinfos; 2: abbreviated routerinfos
    600584     */
  • apps/routerconsole/java/src/net/i2p/router/web/helpers/SybilRenderer.java

    r3054a24 r9437e2c  
    3131import net.i2p.router.peermanager.DBHistory;
    3232import net.i2p.router.peermanager.PeerProfile;
     33import net.i2p.router.sybil.Analysis;
    3334import net.i2p.router.sybil.Pair;
    3435import net.i2p.router.sybil.Points;
     36import static net.i2p.router.sybil.Util.biLog2;
    3537import net.i2p.router.tunnel.pool.TunnelPool;
    3638import net.i2p.router.util.HashDistance;
     
    5860    private final DecimalFormat fmt = new DecimalFormat("#0.00");
    5961
    60     private static final int PAIRMAX = 20;
    61     private static final int MAX = 10;
    62     // multiplied by size - 1, will also get POINTS24 added
    63     private static final double POINTS32 = 5.0;
    64     // multiplied by size - 1, will also get POINTS16 added
    65     private static final double POINTS24 = 5.0;
    66     // multiplied by size - 1
    67     private static final double POINTS16 = 0.25;
    68     private static final double POINTS_US32 = 25.0;
    69     private static final double POINTS_US24 = 25.0;
    70     private static final double POINTS_US16 = 10.0;
    71     private static final double POINTS_FAMILY = -10.0;
    72     private static final double POINTS_BAD_OUR_FAMILY = 100.0;
    73     private static final double POINTS_OUR_FAMILY = -100.0;
    74     private static final double MIN_CLOSE = 242.0;
    75     private static final double PAIR_DISTANCE_FACTOR = 2.0;
    76     private static final double OUR_KEY_FACTOR = 4.0;
     62    private static final int PAIRMAX = Analysis.PAIRMAX;
     63    private static final int MAX = Analysis.MAX;
     64    private static final double MIN_CLOSE = Analysis.MIN_CLOSE;
    7765    private static final double MIN_DISPLAY_POINTS = 12.01;
    78     private static final double VERSION_FACTOR = 1.0;
    79     private static final double POINTS_BAD_VERSION = 50.0;
    80     private static final double POINTS_UNREACHABLE = 4.0;
    81     private static final double POINTS_NEW = 4.0;
    82     private static final double POINTS_BANLIST = 25.0;
    8366
    8467    public SybilRenderer(RouterContext ctx) {
     
    9275        renderRouterInfoHTML(out, (String)null);
    9376        return "";
    94     }
    95 
    96     private static class RouterInfoRoutingKeyComparator implements Comparator<RouterInfo>, Serializable {
    97          private final Hash _us;
    98          /** @param us ROUTING KEY */
    99          public RouterInfoRoutingKeyComparator(Hash us) {
    100              _us = us;
    101          }
    102          public int compare(RouterInfo l, RouterInfo r) {
    103              return HashDistance.getDistance(_us, l.getHash()).compareTo(HashDistance.getDistance(_us, r.getHash()));
    104         }
    10577    }
    10678
     
    142114
    143115    /**
    144      *  Merge points1 into points2.
    145      *  points1 is unmodified.
    146      */
    147 /****
    148     private void mergePoints(Map<Hash, Points> points1, Map<Hash, Points> points2) {
    149         for (Map.Entry<Hash, Points> e : points1.entrySet()) {
    150              Hash h = e.getKey();
    151              Points p1 = e.getValue();
    152              Points p2 = points2.get(h);
    153              if (p2 != null) {
    154                  p2.points += p1.points;
    155                  p2.reasons.addAll(p1.reasons);
    156              } else {
    157                  points2.put(h, p1);
    158              }
    159         }
    160     }
    161 ****/
    162 
    163     /** */
    164     private void addPoints(Map<Hash, Points> points, Hash h, double d, String reason) {
    165         Points dd = points.get(h);
    166         if (dd != null) {
    167             dd.addPoints(d, reason);
    168         } else {
    169             points.put(h, new Points(d, reason));
    170         }
    171     }
    172 
    173     /**
    174      *  All the floodfills, not including us
    175      *  @since 0.9.38 split out from renderRouterInfoHTML
    176      */
    177     private List<RouterInfo> getFloodfills(Hash us) {
    178         Set<Hash> ffs = _context.peerManager().getPeersByCapability('f');
    179         List<RouterInfo> ris = new ArrayList<RouterInfo>(ffs.size());
    180         for (Hash ff : ffs) {
    181              if (ff.equals(us))
    182                  continue;
    183              RouterInfo ri = _context.netDb().lookupRouterInfoLocally(ff);
    184              if (ri != null)
    185                  ris.add(ri);
    186         }
    187         return ris;
    188     }
    189 
    190     private double getAvgMinDist(List<RouterInfo> ris) {
    191         double tot = 0;
    192         int count = 200;
    193         byte[] b = new byte[32];
    194         for (int i = 0; i < count; i++) {
    195             _context.random().nextBytes(b);
    196             Hash h = new Hash(b);
    197             double d = closestDistance(h, ris);
    198             tot += d;
    199         }
    200         double avgMinDist = tot / count;
    201         return avgMinDist;
    202     }
    203 
    204     /**
    205116     *  The whole thing
    206117     *
     
    210121        Hash us = _context.routerHash();
    211122        Hash ourRKey = _context.router().getRouterInfo().getRoutingKey();
    212         List<RouterInfo> ris = getFloodfills(us);
     123        Analysis analysis = new Analysis(_context);
     124        List<RouterInfo> ris = analysis.getFloodfills(us);
    213125        if (ris.isEmpty()) {
    214126            out.write("<h3 class=\"sybils\">No known floodfills</h3>");
     
    237149        buf.append("<h3 id=\"known\" class=\"sybils\">Known Floodfills: ").append(ris.size()).append("</h3>");
    238150
    239         double avgMinDist = getAvgMinDist(ris);
     151        double avgMinDist = analysis.getAvgMinDist(ris);
    240152        buf.append("<div id=\"sybils_summary\">\n" +
    241153                   "<b>Average closest floodfill distance:</b> ").append(fmt.format(avgMinDist)).append("<br>\n" +
     
    249161
    250162        // IP analysis
    251         Map<String, List<RouterInfo>> fmap = calculateIPGroupsFamily(ris, points);
     163        Map<String, List<RouterInfo>> fmap = analysis.calculateIPGroupsFamily(ris, points);
    252164        renderIPGroupsFamily(out, buf, fmap);
    253165        List<RouterInfo> ri32 = new ArrayList<RouterInfo>(4);
    254166        List<RouterInfo> ri24 = new ArrayList<RouterInfo>(4);
    255167        List<RouterInfo> ri16 = new ArrayList<RouterInfo>(4);
    256         calculateIPGroupsUs(ris, points, ri32, ri24, ri16);
     168        analysis.calculateIPGroupsUs(ris, points, ri32, ri24, ri16);
    257169        renderIPGroupsUs(out, buf, ri32, ri24, ri16);
    258         Map<Integer, List<RouterInfo>> map = calculateIPGroups32(ris, points);
     170        Map<Integer, List<RouterInfo>> map = analysis.calculateIPGroups32(ris, points);
    259171        renderIPGroups32(out, buf, map);
    260         map = calculateIPGroups24(ris, points);
     172        map = analysis.calculateIPGroups24(ris, points);
    261173        renderIPGroups24(out, buf, map);
    262         map = calculateIPGroups16(ris, points);
     174        map = analysis.calculateIPGroups16(ris, points);
    263175        //renderIPGroups16(out, buf, map);
    264176
    265177        // Pairwise distance analysis
    266178        List<Pair> pairs = new ArrayList<Pair>(PAIRMAX);
    267         double avg = calculatePairDistance(ris, points, pairs);
     179        double avg = analysis.calculatePairDistance(ris, points, pairs);
    268180        renderPairDistance(out, buf, pairs, avg);
    269181
     
    271183        buf.append("<h3 id=\"ritoday\" class=\"sybils\">Closest Floodfills to Our Routing Key (Where we Store our RI)</h3>");
    272184        buf.append("<p class=\"sybil_info\"><a href=\"/netdb?caps=f&amp;sybil\">See all</a></p>");
    273         calculateRouterInfo(ourRKey, "our rkey", ris, points);
     185        analysis.calculateRouterInfo(ourRKey, "our rkey", ris, points);
    274186        renderRouterInfoHTML(out, buf, ourRKey, avgMinDist, ris);
    275187        RouterKeyGenerator rkgen = _context.routerKeyGenerator();
     
    277189        buf.append("<h3 id=\"ritmrw\" class=\"sybils\">Closest Floodfills to Tomorrow's Routing Key (Where we will Store our RI)</h3>");
    278190        buf.append("<p class=\"sybil_info\"><a href=\"/netdb?caps=f&amp;sybil\">See all</a></p>");
    279         calculateRouterInfo(nkey, "our rkey (tomorrow)", ris, points);
     191        analysis.calculateRouterInfo(nkey, "our rkey (tomorrow)", ris, points);
    280192        renderRouterInfoHTML(out, buf, nkey, avgMinDist, ris);
    281193
    282194        buf.append("<h3 id=\"dht\" class=\"sybils\">Closest Floodfills to Our Router Hash (DHT Neighbors if we are Floodfill)</h3>");
    283         calculateRouterInfo(us, "our router", ris, points);
     195        analysis.calculateRouterInfo(us, "our router", ris, points);
    284196        renderRouterInfoHTML(out, buf, us, avgMinDist, ris);
    285197
     
    303215            buf.append("<h3 class=\"sybils\">Closest floodfills to the Routing Key for " + name + " (where we store our LS)</h3>");
    304216            buf.append("<p class=\"sybil_info\"><a href=\"/netdb?caps=f&amp;sybil=" + ls.getHash().toBase64() + "\">See all</a></p>");
    305             calculateRouterInfo(rkey, name, ris, points);
     217            analysis.calculateRouterInfo(rkey, name, ris, points);
    306218            renderRouterInfoHTML(out, buf, rkey, avgMinDist, ris);
    307219            nkey = rkgen.getNextRoutingKey(ls.getHash());
    308220            buf.append("<h3 class=\"sybils\">Closest floodfills to Tomorrow's Routing Key for " + name + " (where we will store our LS)</h3>");
    309221            buf.append("<p class=\"sybil_info\"><a href=\"/netdb?caps=f&amp;sybil=" + ls.getHash().toBase64() + "\">See all</a></p>");
    310             calculateRouterInfo(nkey, name + " (tomorrow)", ris, points);
     222            analysis.calculateRouterInfo(nkey, name + " (tomorrow)", ris, points);
    311223            renderRouterInfoHTML(out, buf, nkey, avgMinDist, ris);
    312224        }
    313225
    314226        // Profile analysis
    315         addProfilePoints(ris, points);
    316         addVersionPoints(ris, points);
     227        analysis.addProfilePoints(ris, points);
     228        analysis.addVersionPoints(ris, points);
    317229
    318230        if (!points.isEmpty()) {
     
    349261
    350262    /**
    351      *  Analyze threats. No output.
    352      *  Return separate maps for each cause instead?
    353      *  @since 0.9.38
    354      */
    355     public Map<Hash, Points> backgroundAnalysis() throws IOException {
    356         Hash us = _context.routerHash();
    357         List<RouterInfo> ris = getFloodfills(us);
    358 
    359         double avgMinDist = getAvgMinDist(ris);
    360         Map<Hash, Points> points = new HashMap<Hash, Points>(64);
    361 
    362         // IP analysis
    363         calculateIPGroupsFamily(ris, points);
    364         List<RouterInfo> ri32 = new ArrayList<RouterInfo>(4);
    365         List<RouterInfo> ri24 = new ArrayList<RouterInfo>(4);
    366         List<RouterInfo> ri16 = new ArrayList<RouterInfo>(4);
    367         calculateIPGroupsUs(ris, points, ri32, ri24, ri16);
    368         calculateIPGroups32(ris, points);
    369         calculateIPGroups24(ris, points);
    370         calculateIPGroups16(ris, points);
    371 
    372         // Pairwise distance analysis
    373         List<Pair> pairs = new ArrayList<Pair>(PAIRMAX);
    374         calculatePairDistance(ris, points, pairs);
    375 
    376         // Distance to our router analysis
    377         // closest to our routing key today
    378         Hash ourRKey = _context.router().getRouterInfo().getRoutingKey();
    379         calculateRouterInfo(ourRKey, "our rkey", ris, points);
    380         // closest to our routing key tomorrow
    381         RouterKeyGenerator rkgen = _context.routerKeyGenerator();
    382         Hash nkey = rkgen.getNextRoutingKey(us);
    383         calculateRouterInfo(nkey, "our rkey (tomorrow)", ris, points);
    384         // closest to us
    385         calculateRouterInfo(us, "our router", ris, points);
    386 
    387         // Distance to our published destinations analysis
    388         Map<Hash, TunnelPool> clientInboundPools = _context.tunnelManager().getInboundClientPools();
    389         List<Hash> destinations = new ArrayList<Hash>(clientInboundPools.keySet());
    390         for (Hash client : destinations) {
    391             boolean isLocal = _context.clientManager().isLocal(client);
    392             if (!isLocal)
    393                 continue;
    394             if (! _context.clientManager().shouldPublishLeaseSet(client))
    395                 continue;
    396             LeaseSet ls = _context.netDb().lookupLeaseSetLocally(client);
    397             if (ls == null)
    398                 continue;
    399             Hash rkey = ls.getRoutingKey();
    400             TunnelPool in = clientInboundPools.get(client);
    401             String name = (in != null) ? DataHelper.escapeHTML(in.getSettings().getDestinationNickname()) : client.toBase64().substring(0,4);
    402             // closest to routing key today
    403             calculateRouterInfo(rkey, name, ris, points);
    404             // closest to routing key tomorrow
    405             nkey = rkgen.getNextRoutingKey(ls.getHash());
    406             calculateRouterInfo(nkey, name + " (tomorrow)", ris, points);
    407         }
    408 
    409         // Profile analysis
    410         addProfilePoints(ris, points);
    411         addVersionPoints(ris, points);
    412         return points;
    413     }
    414 
    415     /**
    416      *  @param pairs out parameter, sorted
    417      *  @param return average distance
    418      *  @since 0.9.38 split out from renderPairDistance()
    419      */
    420     private double calculatePairDistance(List<RouterInfo> ris, Map<Hash, Points> points,
    421                                          List<Pair> pairs) {
    422         int sz = ris.size();
    423         double total = 0;
    424         for (int i = 0; i < sz; i++) {
    425             RouterInfo info1 = ris.get(i);
    426             for (int j = i + 1; j < sz; j++) {
    427                 RouterInfo info2 = ris.get(j);
    428                 BigInteger dist = HashDistance.getDistance(info1.getHash(), info2.getHash());
    429                 if (pairs.isEmpty()) {
    430                     pairs.add(new Pair(info1, info2, dist));
    431                 } else if (pairs.size() < PAIRMAX) {
    432                     pairs.add(new Pair(info1, info2, dist));
    433                     Collections.sort(pairs);
    434                 } else if (dist.compareTo(pairs.get(PAIRMAX - 1).dist) < 0) {
    435                     pairs.set(PAIRMAX - 1, new Pair(info1, info2, dist));
    436                     Collections.sort(pairs);
    437                 }
    438                 total += biLog2(dist);
    439             }
    440         }
    441 
    442         double avg = total / (sz * sz / 2d);
    443         for (Pair p : pairs) {
    444             double distance = biLog2(p.dist);
    445             double point = MIN_CLOSE - distance;
    446             if (point < 0)
    447                 break;  // sorted;
    448             point *= PAIR_DISTANCE_FACTOR;
    449             String b2 = p.r2.getHash().toBase64();
    450             addPoints(points, p.r1.getHash(), point, "Very close (" + fmt.format(distance) +
    451                           ") to other floodfill <a href=\"netdb?r=" + b2 + "\">" + b2 + "</a>");
    452             String b1 = p.r1.getHash().toBase64();
    453             addPoints(points, p.r2.getHash(), point, "Very close (" + fmt.format(distance) +
    454                           ") to other floodfill <a href=\"netdb?r=" + b1 + "\">" + b1 + "</a>");
    455         }
    456         return avg;
    457     }
    458 
    459     /**
    460263     *  @param pairs sorted
    461264     */
     
    479282        out.flush();
    480283        buf.setLength(0);
    481     }
    482 
    483     private double closestDistance(Hash h, List<RouterInfo> ris) {
    484         BigInteger min = (new BigInteger("2")).pow(256);
    485         for (RouterInfo info : ris) {
    486             BigInteger dist = HashDistance.getDistance(h, info.getHash());
    487             if (dist.compareTo(min) < 0)
    488                 min = dist;
    489         }
    490         return biLog2(min);
    491     }
    492 
    493     /** v4 only */
    494     private static byte[] getIP(RouterInfo ri) {
    495         for (RouterAddress ra : ri.getAddresses()) {
    496             byte[] rv = ra.getIP();
    497             if (rv != null && rv.length == 4)
    498                 return rv;
    499         }
    500         return null;
    501284    }
    502285
     
    529312
    530313    /**
    531      *  @param ri32 out parameter
    532      *  @param ri24 out parameter
    533      *  @param ri16 out parameter
    534      *  @since 0.9.38 split out from renderIPGroupsUs()
    535      */
    536     private void calculateIPGroupsUs(List<RouterInfo> ris, Map<Hash, Points> points,
    537                                      List<RouterInfo> ri32, List<RouterInfo> ri24, List<RouterInfo> ri16) {
    538         RouterInfo us = _context.router().getRouterInfo();
    539         byte[] ourIP = getIP(us);
    540         if (ourIP == null)
    541             return;
    542         for (RouterInfo info : ris) {
    543             byte[] ip = getIP(info);
    544             if (ip == null)
    545                 continue;
    546             if (ip[0] == ourIP[0] && ip[1] == ourIP[1]) {
    547                 if (ip[2] == ourIP[2]) {
    548                     if (ip[3] == ourIP[3]) {
    549                         addPoints(points, info.getHash(), POINTS_US32, "Same IP as us");
    550                     } else {
    551                         addPoints(points, info.getHash(), POINTS_US24, "Same /24 as us");
    552                     }
    553                 } else {
    554                     addPoints(points, info.getHash(), POINTS_US16, "Same /16 as us");
    555                 }
    556             }
    557         }
    558     }
    559 
    560     /**
    561314     *
    562315     */
     
    591344        out.flush();
    592345        buf.setLength(0);
    593     }
    594 
    595     /**
    596      *  @since 0.9.38 split out from renderIPGroups32()
    597      */
    598     private Map<Integer, List<RouterInfo>> calculateIPGroups32(List<RouterInfo> ris, Map<Hash, Points> points) {
    599         ObjectCounter<Integer> oc = new ObjectCounter<Integer>();
    600         for (RouterInfo info : ris) {
    601             byte[] ip = getIP(info);
    602             if (ip == null)
    603                 continue;
    604             Integer x = Integer.valueOf((int) DataHelper.fromLong(ip, 0, 4));
    605             oc.increment(x);
    606         }
    607         Map<Integer, List<RouterInfo>> rv = new HashMap<Integer, List<RouterInfo>>();
    608         for (Integer ii : oc.objects()) {
    609             int count = oc.count(ii);
    610             if (count >= 2)
    611                 rv.put(ii, new ArrayList<RouterInfo>(4));
    612         }
    613         for (Map.Entry<Integer, List<RouterInfo>> e : rv.entrySet()) {
    614             Integer ii = e.getKey();
    615             int count = oc.count(ii);
    616             int i = ii.intValue();
    617             int i0 = (i >> 24) & 0xff;
    618             int i1 = (i >> 16) & 0xff;
    619             int i2 = (i >> 8) & 0xff;
    620             int i3 = i & 0xff;
    621             for (RouterInfo info : ris) {
    622                 byte[] ip = getIP(info);
    623                 if (ip == null)
    624                     continue;
    625                 if ((ip[0] & 0xff) != i0)
    626                     continue;
    627                 if ((ip[1] & 0xff) != i1)
    628                     continue;
    629                 if ((ip[2] & 0xff) != i2)
    630                     continue;
    631                 if ((ip[3] & 0xff) != i3)
    632                     continue;
    633                 e.getValue().add(info);
    634                 double point = POINTS32 * (count - 1);
    635                 addPoints(points, info.getHash(), point, "Same IP with " + (count - 1) + " other" + (( count > 2) ? "s" : ""));
    636             }
    637         }
    638         return rv;
    639346    }
    640347
     
    672379
    673380    /**
    674      *  @since 0.9.38 split out from renderIPGroups24()
    675      */
    676     private Map<Integer, List<RouterInfo>> calculateIPGroups24(List<RouterInfo> ris, Map<Hash, Points> points) {
    677         ObjectCounter<Integer> oc = new ObjectCounter<Integer>();
    678         for (RouterInfo info : ris) {
    679             byte[] ip = getIP(info);
    680             if (ip == null)
    681                 continue;
    682             Integer x = Integer.valueOf((int) DataHelper.fromLong(ip, 0, 3));
    683             oc.increment(x);
    684         }
    685         Map<Integer, List<RouterInfo>> rv = new HashMap<Integer, List<RouterInfo>>();
    686         for (Integer ii : oc.objects()) {
    687             int count = oc.count(ii);
    688             if (count >= 2)
    689                 rv.put(ii, new ArrayList<RouterInfo>(4));
    690         }
    691         for (Map.Entry<Integer, List<RouterInfo>> e : rv.entrySet()) {
    692             Integer ii = e.getKey();
    693             int count = oc.count(ii);
    694             int i = ii.intValue();
    695             int i0 = i >> 16;
    696             int i1 = (i >> 8) & 0xff;
    697             int i2 = i & 0xff;
    698             for (RouterInfo info : ris) {
    699                 byte[] ip = getIP(info);
    700                 if (ip == null)
    701                     continue;
    702                 if ((ip[0] & 0xff) != i0)
    703                     continue;
    704                 if ((ip[1] & 0xff) != i1)
    705                     continue;
    706                 if ((ip[2] & 0xff) != i2)
    707                     continue;
    708                 e.getValue().add(info);
    709                 double point = POINTS24 * (count - 1);
    710                 addPoints(points, info.getHash(), point, "Same /24 IP with " + (count - 1) + " other" + (( count > 2) ? "s" : ""));
    711             }
    712         }
    713         return rv;
    714     }
    715 
    716     /**
    717381     *
    718382     */
     
    746410
    747411    /**
    748      *  @since 0.9.38 split out from renderIPGroups16()
    749      */
    750     private Map<Integer, List<RouterInfo>> calculateIPGroups16(List<RouterInfo> ris, Map<Hash, Points> points) {
    751         ObjectCounter<Integer> oc = new ObjectCounter<Integer>();
    752         for (RouterInfo info : ris) {
    753             byte[] ip = getIP(info);
    754             if (ip == null)
    755                 continue;
    756             Integer x = Integer.valueOf((int) DataHelper.fromLong(ip, 0, 2));
    757             oc.increment(x);
    758         }
    759         Map<Integer, List<RouterInfo>> rv = new HashMap<Integer, List<RouterInfo>>();
    760         for (Integer ii : oc.objects()) {
    761             int count = oc.count(ii);
    762             if (count >= 4)
    763                 rv.put(ii, new ArrayList<RouterInfo>(8));
    764         }
    765         for (Map.Entry<Integer, List<RouterInfo>> e : rv.entrySet()) {
    766             Integer ii = e.getKey();
    767             int count = oc.count(ii);
    768             int i = ii.intValue();
    769             int i0 = i >> 8;
    770             int i1 = i & 0xff;
    771             for (RouterInfo info : ris) {
    772                 byte[] ip = getIP(info);
    773                 if (ip == null)
    774                     continue;
    775                 if ((ip[0] & 0xff) != i0)
    776                     continue;
    777                 if ((ip[1] & 0xff) != i1)
    778                     continue;
    779                 e.getValue().add(info);
    780                 double point = POINTS16 * (count - 1);
    781                 addPoints(points, info.getHash(), point, "Same /16 IP with " + (count - 1) + " other" + (( count > 2) ? "s" : ""));
    782             }
    783         }
    784         return rv;
    785     }
    786 
    787     /**
    788412     *
    789413     */
     
    818442
    819443    /**
    820      *  @since 0.9.38 split out from renderIPGroupsFamily()
    821      */
    822     private Map<String, List<RouterInfo>> calculateIPGroupsFamily(List<RouterInfo> ris, Map<Hash, Points> points) {
    823         ObjectCounter<String> oc = new ObjectCounter<String>();
    824         for (RouterInfo info : ris) {
    825             String fam = info.getOption("family");
    826             if (fam == null)
    827                 continue;
    828             oc.increment(fam);
    829         }
    830         List<String> foo = new ArrayList<String>(oc.objects());
    831         Map<String, List<RouterInfo>> rv = new HashMap<String, List<RouterInfo>>(foo.size());
    832         FamilyKeyCrypto fkc = _context.router().getFamilyKeyCrypto();
    833         String ourFamily = fkc != null ? fkc.getOurFamilyName() : null;
    834         for (String s : foo) {
    835             int count = oc.count(s);
    836             List<RouterInfo> list = new ArrayList<RouterInfo>(count);
    837             rv.put(s, list);
    838             String ss = DataHelper.escapeHTML(s);
    839             for (RouterInfo info : ris) {
    840                 String fam = info.getOption("family");
    841                 if (fam == null)
    842                     continue;
    843                 if (!fam.equals(s))
    844                     continue;
    845                 list.add(info);
    846                 double point = POINTS_FAMILY;
    847                 if (fkc != null && s.equals(ourFamily)) {
    848                     if (fkc.verifyOurFamily(info))
    849                         addPoints(points, info.getHash(), POINTS_OUR_FAMILY, "Our family \"" + ss + "\" with " + (count - 1) + " other" + (( count > 2) ? "s" : ""));
    850                     else
    851                         addPoints(points, info.getHash(), POINTS_BAD_OUR_FAMILY, "Spoofed our family \"" + ss + "\" with " + (count - 1) + " other" + (( count > 2) ? "s" : ""));
    852                 } else if (count > 1) {
    853                     addPoints(points, info.getHash(), point, "In family \"" + ss + "\" with " + (count - 1) + " other" + (( count > 2) ? "s" : ""));
    854                 } else {
    855                     addPoints(points, info.getHash(), point, "In family \"" + ss + '"');
    856                 }
    857             }
    858         }
    859         return rv;
    860     }
    861 
    862     /**
    863444     *
    864445     */
     
    890471        out.flush();
    891472        buf.setLength(0);
    892     }
    893 
    894     private static final long DAY = 24*60*60*1000L;
    895 
    896     private void addProfilePoints(List<RouterInfo> ris, Map<Hash, Points> points) {
    897         long now = _context.clock().now();
    898         RateAverages ra = RateAverages.getTemp();
    899         for (RouterInfo info : ris) {
    900             Hash h = info.getHash();
    901             if (_context.banlist().isBanlisted(h))
    902                 addPoints(points, h, POINTS_BANLIST, "Banlisted");
    903             PeerProfile prof = _context.profileOrganizer().getProfileNonblocking(h);
    904             if (prof != null) {
    905                 long heard = prof.getFirstHeardAbout();
    906                 if (heard > 0) {
    907                     long age = Math.max(now - heard, 1);
    908                     if (age < 2 * DAY) {
    909                         // (POINTS_NEW / 48) for every hour under 48, max POINTS_NEW
    910                         double point = Math.min(POINTS_NEW, (2 * DAY - age) / (2 * DAY / POINTS_NEW));
    911                         addPoints(points, h, point,
    912                                   "First heard about: " + _t("{0} ago", DataHelper.formatDuration2(age)));
    913                     }
    914                 }
    915                 DBHistory dbh = prof.getDBHistory();
    916                 if (dbh != null) {
    917                     RateStat rs = dbh.getFailedLookupRate();
    918                     if (rs != null) {
    919                         Rate r = rs.getRate(24*60*60*1000);
    920                         if (r != null) {
    921                             r.computeAverages(ra, false);
    922                             if (ra.getTotalEventCount() > 0) {
    923                                 double avg = 100 * ra.getAverage();
    924                                 if (avg > 40)
    925                                     addPoints(points, h, (avg - 40) / 6.0, "Lookup fail rate " + ((int) avg) + '%');
    926                             }
    927                         }
    928                     }
    929                 }
    930             }
    931         }
    932     }
    933 
    934     private void addVersionPoints(List<RouterInfo> ris, Map<Hash, Points> points) {
    935         RouterInfo us = _context.router().getRouterInfo();
    936         if (us == null) return;
    937         String ourVer = us.getVersion();
    938         if (!ourVer.startsWith("0.9.")) return;
    939         ourVer = ourVer.substring(4);
    940         int dot = ourVer.indexOf('.');
    941         if (dot > 0)
    942             ourVer = ourVer.substring(0, dot);
    943         int minor;
    944         try {
    945             minor = Integer.parseInt(ourVer);
    946         } catch (NumberFormatException nfe) { return; }
    947         for (RouterInfo info : ris) {
    948             Hash h = info.getHash();
    949             String caps = info.getCapabilities();
    950             if (!caps.contains("R"))
    951                 addPoints(points, h, POINTS_UNREACHABLE, "Unreachable: " + DataHelper.escapeHTML(caps));
    952             String hisFullVer = info.getVersion();
    953             if (!hisFullVer.startsWith("0.9.")) {
    954                 addPoints(points, h, POINTS_BAD_VERSION, "Strange version " + DataHelper.escapeHTML(hisFullVer));
    955                 continue;
    956             }
    957             String hisVer = hisFullVer.substring(4);
    958             dot = hisVer.indexOf('.');
    959             if (dot > 0)
    960                 hisVer = hisVer.substring(0, dot);
    961             int hisMinor;
    962             try {
    963                 hisMinor = Integer.parseInt(hisVer);
    964             } catch (NumberFormatException nfe) { continue; }
    965             int howOld = minor - hisMinor;
    966             if (howOld < 3)
    967                 continue;
    968             addPoints(points, h, howOld * VERSION_FACTOR, howOld + " versions behind: " + DataHelper.escapeHTML(hisFullVer));
    969         }
    970     }
    971 
    972     /**
    973      *  @param usName HTML escaped
    974      *  @param ris will be re-sorted in place
    975      *  @since 0.9.38 split out from renderRouterInfoHTML()
    976      */
    977     private void calculateRouterInfo(Hash us, String usName,
    978                                      List<RouterInfo> ris, Map<Hash, Points> points) {
    979         Collections.sort(ris, new RouterInfoRoutingKeyComparator(us));
    980         int count = Math.min(MAX, ris.size());
    981         for (int i = 0; i < count; i++) {
    982             RouterInfo ri = ris.get(i);
    983             BigInteger bidist = HashDistance.getDistance(us, ri.getHash());
    984             double dist = biLog2(bidist);
    985             double point = MIN_CLOSE - dist;
    986             if (point <= 0)
    987                 break;
    988             point *= OUR_KEY_FACTOR;
    989             addPoints(points, ri.getHash(), point, "Very close (" + fmt.format(dist) + ") to our key " + usName + ": " + us.toBase64());
    990         }
    991473    }
    992474
     
    1042524        out.flush();
    1043525        buf.setLength(0);
    1044     }
    1045 
    1046     /**
    1047      * For debugging
    1048      * http://forums.sun.com/thread.jspa?threadID=597652
    1049      * @since 0.7.14
    1050      */
    1051     private static double biLog2(BigInteger a) {
    1052         return NetDbRenderer.biLog2(a);
    1053526    }
    1054527
Note: See TracChangeset for help on using the changeset viewer.