Changeset 19b1b3c for apps


Ignore:
Timestamp:
Oct 9, 2018 2:55:13 PM (21 months ago)
Author:
zzz <zzz@…>
Branches:
master
Children:
8332385
Parents:
bdd7c35a
Message:

Sybil: Prep for background analysis
sort threat points
consolidate strings

File:
1 edited

Legend:

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

    rbdd7c35a r19b1b3c  
    109109         private double points;
    110110         private final List<String> reasons;
    111          /** @param us ROUTING KEY */
     111
    112112         public Points(double points, String reason) {
    113113             this.points = points;
     
    122122    private static class PointsComparator implements Comparator<Hash>, Serializable {
    123123         private final Map<Hash, Points> _points;
    124          /** @param us ROUTING KEY */
     124
    125125         public PointsComparator(Map<Hash, Points> points) {
    126126             _points = points;
     
    132132    }
    133133
     134    /**
     135     *  Reverse points, then forward by text
     136     *  @since 0.9.38
     137     */
     138    private static class ReasonComparator implements Comparator<String>, Serializable {
     139         public int compare(String l, String r) {
     140             int lc = l.indexOf(':');
     141             int rc = r.indexOf(':');
     142             if (lc <= 0 || rc <= 0)
     143                 return 0;
     144             double ld, rd;
     145             try {
     146                 // skip "<b>"
     147                 ld = Double.parseDouble(l.substring(3, lc));
     148                 rd = Double.parseDouble(r.substring(3, rc));
     149             } catch (NumberFormatException nfe) {
     150                 return 0;
     151             }
     152             int rv = Double.compare(rd, ld);
     153             if (rv != 0)
     154                 return rv;
     155             return l.compareTo(r);
     156        }
     157    }
     158
    134159    private void addPoints(Map<Hash, Points> points, Hash h, double d, String reason) {
     160        String rsn = "<b>" + fmt.format(d) + ":</b> " + reason;
    135161        Points dd = points.get(h);
    136162        if (dd != null) {
    137163            dd.points += d;
    138             dd.reasons.add("<b>" + fmt.format(d) + ":</b> " + reason);
     164            dd.reasons.add(rsn);
    139165        } else {
    140             points.put(h, new Points(d, "<b>" + fmt.format(d) + ":</b> " + reason));
     166            points.put(h, new Points(d, rsn));
    141167        }
    142168    }
     
    195221        }
    196222        double avgMinDist = tot / count;
    197         buf.append("<div id=\"sybils_summary\">\n");
    198         buf.append("<b>Average closest floodfill distance:</b> ").append(fmt.format(avgMinDist)).append("<br>\n");
    199         buf.append("<b>Routing Data:</b> \"").append(DataHelper.getUTF8(_context.routerKeyGenerator().getModData()))
    200            .append("\" <b>Last Changed:</b> ").append(new Date(_context.routerKeyGenerator().getLastChanged())).append("<br>\n");
    201         buf.append("<b>Next Routing Data:</b> \"").append(DataHelper.getUTF8(_context.routerKeyGenerator().getNextModData()))
    202            .append("\" <b>Rotates in:</b> ").append(DataHelper.formatDuration(_context.routerKeyGenerator().getTimeTillMidnight())).append("\n");
    203         buf.append("</div>\n");
     223        buf.append("<div id=\"sybils_summary\">\n" +
     224                   "<b>Average closest floodfill distance:</b> ").append(fmt.format(avgMinDist)).append("<br>\n" +
     225                   "<b>Routing Data:</b> \"").append(DataHelper.getUTF8(_context.routerKeyGenerator().getModData()))
     226           .append("\" <b>Last Changed:</b> ").append(new Date(_context.routerKeyGenerator().getLastChanged())).append("<br>\n" +
     227                   "<b>Next Routing Data:</b> \"").append(DataHelper.getUTF8(_context.routerKeyGenerator().getNextModData()))
     228           .append("\" <b>Rotates in:</b> ").append(DataHelper.formatDuration(_context.routerKeyGenerator().getTimeTillMidnight())).append("\n" +
     229                   "</div>\n");
    204230
    205231        Map<Hash, Points> points = new HashMap<Hash, Points>(64);
     
    271297                    break;  // sorted
    272298                buf.append("<p class=\"threatpoints\"><b>Threat Points: " + fmt.format(p) + "</b></p><ul>");
     299                if (pp.reasons.size() > 1)
     300                    Collections.sort(pp.reasons, new ReasonComparator());
    273301                for (String s : pp.reasons) {
    274302                    buf.append("<li>").append(s).append("</li>");
     
    295323    }
    296324
     325    /**
     326     *  @param out null for background analysis
     327     *  @param buf null for background analysis
     328     */
    297329    private void renderPairDistance(Writer out, StringBuilder buf, List<RouterInfo> ris, Map<Hash, Points> points) throws IOException {
    298330        int sz = ris.size();
     
    318350
    319351        double avg = total / (sz * sz / 2d);
    320         buf.append("<h3 class=\"sybils\">Average Floodfill Distance is ").append(fmt.format(avg)).append("</h3>");
    321 
    322         buf.append("<h3 id=\"pairs\" class=\"sybils\">Closest Floodfill Pairs by Hash</h3>");
     352        if (buf != null) {
     353            buf.append("<h3 class=\"sybils\">Average Floodfill Distance is ").append(fmt.format(avg)).append("</h3>" +
     354                       "<h3 id=\"pairs\" class=\"sybils\">Closest Floodfill Pairs by Hash</h3>");
     355        }
    323356        for (Pair p : pairs) {
    324357            double distance = biLog2(p.dist);
     
    326359            if (point < 0)
    327360                break;  // sorted;
    328             if (point >= 2) {
     361            if (buf != null && point >= 2) {
    329362                // limit display
    330                 buf.append("<p class=\"hashdist\"><b>Hash Distance: ").append(fmt.format(distance)).append(": </b>");
    331                 buf.append("</p>");
     363                buf.append("<p class=\"hashdist\"><b>Hash Distance: ").append(fmt.format(distance)).append(": </b>" +
     364                           "</p>");
    332365                renderRouterInfo(buf, p.r1, null, false, false);
    333366                renderRouterInfo(buf, p.r2, null, false, false);
     
    341374                          ") to other floodfill <a href=\"netdb?r=" + b1 + "\">" + b1 + "</a>");
    342375        }
    343         out.write(buf.toString());
    344         out.flush();
    345         buf.setLength(0);
     376        if (buf != null) {
     377            out.write(buf.toString());
     378            out.flush();
     379            buf.setLength(0);
     380        }
    346381    }
    347382
     
    393428    }
    394429
     430    /**
     431     *  @param out null for background analysis
     432     *  @param buf null for background analysis
     433     */
    395434    private void renderIPGroupsUs(Writer out, StringBuilder buf, List<RouterInfo> ris, Map<Hash, Points> points) throws IOException {
    396435        RouterInfo us = _context.router().getRouterInfo();
     
    398437        if (ourIP == null)
    399438            return;
    400         buf.append("<h3 id=\"ourIP\" class=\"sybils\">Floodfills close to Our IP</h3>");
     439        if (buf != null)
     440            buf.append("<h3 id=\"ourIP\" class=\"sybils\">Floodfills close to Our IP</h3>");
    401441        boolean found = false;
    402442        for (RouterInfo info : ris) {
     
    405445                continue;
    406446            if (ip[0] == ourIP[0] && ip[1] == ourIP[1]) {
    407                 buf.append("<p id=\"sybil_info\"><b>");
     447                if (buf != null)
     448                    buf.append("<p id=\"sybil_info\"><b>");
    408449                if (ip[2] == ourIP[2]) {
    409450                    if (ip[3] == ourIP[3]) {
    410                         buf.append("Same IP as us");
     451                        if (buf != null)
     452                            buf.append("Same IP as us");
    411453                        addPoints(points, info.getHash(), POINTS_US32, "Same IP as us");
    412454                    } else {
    413                         buf.append("Same /24 as us");
     455                        if (buf != null)
     456                            buf.append("Same /24 as us");
    414457                        addPoints(points, info.getHash(), POINTS_US24, "Same /24 as us");
    415458                    }
    416459                } else {
    417                     buf.append("Same /16 as us");
     460                    if (buf != null)
     461                        buf.append("Same /16 as us");
    418462                    addPoints(points, info.getHash(), POINTS_US16, "Same /16 as us");
    419463                }
    420                 buf.append(":</b></p>");
    421                 renderRouterInfo(buf, info, null, false, false);
     464                if (buf != null) {
     465                    buf.append(":</b></p>");
     466                    renderRouterInfo(buf, info, null, false, false);
     467                }
    422468                found = true;
    423469            }
    424470        }
    425         if (!found)
    426             buf.append("<p class=\"notfound\">None</p>");
    427         out.write(buf.toString());
    428         out.flush();
    429         buf.setLength(0);
    430     }
    431 
     471        if (buf != null) {
     472            if (!found)
     473                buf.append("<p class=\"notfound\">None</p>");
     474            out.write(buf.toString());
     475            out.flush();
     476            buf.setLength(0);
     477        }
     478    }
     479
     480    /**
     481     *  @param out null for background analysis
     482     *  @param buf null for background analysis
     483     */
    432484    private void renderIPGroups32(Writer out, StringBuilder buf, List<RouterInfo> ris, Map<Hash, Points> points) throws IOException {
    433         buf.append("<h3 id=\"sameIP\" class=\"sybils\">Floodfills with the Same IP</h3>");
     485        if (buf != null)
     486            buf.append("<h3 id=\"sameIP\" class=\"sybils\">Floodfills with the Same IP</h3>");
    434487        ObjectCounter<Integer> oc = new ObjectCounter<Integer>();
    435488        for (RouterInfo info : ris) {
     
    456509            int i3 = i & 0xff;
    457510            String sip = i0 + "." + i1 + '.' + i2 + '.' + i3;
    458             buf.append("<p class=\"sybil_info\"><b>").append(count).append(" floodfills with IP <a href=\"/netdb?ip=")
    459                .append(sip).append("&amp;sybil\">").append(sip)
    460                .append("</a>:</b></p>");
     511            if (buf != null) {
     512                buf.append("<p class=\"sybil_info\"><b>").append(count).append(" floodfills with IP <a href=\"/netdb?ip=")
     513                   .append(sip).append("&amp;sybil\">").append(sip)
     514                   .append("</a>:</b></p>");
     515            }
    461516            for (RouterInfo info : ris) {
    462517                byte[] ip = getIP(info);
     
    472527                    continue;
    473528                found = true;
    474                 renderRouterInfo(buf, info, null, false, false);
     529                if (buf != null)
     530                    renderRouterInfo(buf, info, null, false, false);
    475531                double point = POINTS32 * (count - 1);
    476532                addPoints(points, info.getHash(), point, "Same IP with " + (count - 1) + " other" + (( count > 2) ? "s" : ""));
    477533            }
    478534        }
    479         if (!found)
    480             buf.append("<p class=\"notfound\">None</p>");
    481         out.write(buf.toString());
    482         out.flush();
    483         buf.setLength(0);
    484     }
    485 
     535        if (buf != null) {
     536            if (!found)
     537                buf.append("<p class=\"notfound\">None</p>");
     538            out.write(buf.toString());
     539            out.flush();
     540            buf.setLength(0);
     541        }
     542    }
     543
     544    /**
     545     *  @param out null for background analysis
     546     *  @param buf null for background analysis
     547     */
    486548    private void renderIPGroups24(Writer out, StringBuilder buf, List<RouterInfo> ris, Map<Hash, Points> points) throws IOException {
    487         buf.append("<h3 id=\"same24\" class=\"sybils\">Floodfills in the Same /24 (2 minimum)</h3>");
     549        if (buf != null)
     550            buf.append("<h3 id=\"same24\" class=\"sybils\">Floodfills in the Same /24 (2 minimum)</h3>");
    488551        ObjectCounter<Integer> oc = new ObjectCounter<Integer>();
    489552        for (RouterInfo info : ris) {
     
    509572            int i2 = i & 0xff;
    510573            String sip = i0 + "." + i1 + '.' + i2 + ".0/24";
    511             buf.append("<p class=\"sybil_info\"><b>").append(count).append(" floodfills with IP <a href=\"/netdb?ip=")
    512                .append(sip).append("&amp;sybil\">").append(sip)
    513                .append("</a>:</b></p>");
     574            if (buf != null) {
     575                buf.append("<p class=\"sybil_info\"><b>").append(count).append(" floodfills with IP <a href=\"/netdb?ip=")
     576                   .append(sip).append("&amp;sybil\">").append(sip)
     577                   .append("</a>:</b></p>");
     578            }
    514579            for (RouterInfo info : ris) {
    515580                byte[] ip = getIP(info);
     
    523588                    continue;
    524589                found = true;
    525                 renderRouterInfo(buf, info, null, false, false);
     590                if (buf != null)
     591                    renderRouterInfo(buf, info, null, false, false);
    526592                double point = POINTS24 * (count - 1);
    527593                addPoints(points, info.getHash(), point, "Same /24 IP with " + (count - 1) + " other" + (( count > 2) ? "s" : ""));
    528594            }
    529595        }
    530         if (!found)
    531             buf.append("<p class=\"notfound\">None</p>");
    532         out.write(buf.toString());
    533         out.flush();
    534         buf.setLength(0);
    535     }
    536 
     596        if (buf != null) {
     597            if (!found)
     598                buf.append("<p class=\"notfound\">None</p>");
     599            out.write(buf.toString());
     600            out.flush();
     601            buf.setLength(0);
     602        }
     603    }
     604
     605    /**
     606     *  @param out null for background analysis
     607     *  @param buf null for background analysis
     608     */
    537609    private void renderIPGroups16(Writer out, StringBuilder buf, List<RouterInfo> ris, Map<Hash, Points> points) throws IOException {
    538         buf.append("<h3 id=\"same16\" class=\"sybils\">Floodfills in the Same /16 (4 minimum)</h3>");
     610        if (buf != null)
     611            buf.append("<h3 id=\"same16\" class=\"sybils\">Floodfills in the Same /16 (4 minimum)</h3>");
    539612        ObjectCounter<Integer> oc = new ObjectCounter<Integer>();
    540613        for (RouterInfo info : ris) {
     
    559632            int i1 = i & 0xff;
    560633            String sip = i0 + "." + i1 + ".0.0/16";
    561             buf.append("<p class=\"sybil_info\"><b>").append(count).append(" floodfills with IP <a href=\"/netdb?ip=")
    562                .append(sip).append("&amp;sybil\">").append(sip)
    563                .append("</a></b></p>");
     634            if (buf != null) {
     635                buf.append("<p class=\"sybil_info\"><b>").append(count).append(" floodfills with IP <a href=\"/netdb?ip=")
     636                   .append(sip).append("&amp;sybil\">").append(sip)
     637                   .append("</a></b></p>");
     638            }
    564639            for (RouterInfo info : ris) {
    565640                byte[] ip = getIP(info);
     
    577652            }
    578653        }
    579         if (!found)
    580             buf.append("<p class=\"notfound\">None</p>");
    581         out.write(buf.toString());
    582         out.flush();
    583         buf.setLength(0);
    584     }
    585 
     654        if (buf != null) {
     655            if (!found)
     656                buf.append("<p class=\"notfound\">None</p>");
     657            out.write(buf.toString());
     658            out.flush();
     659            buf.setLength(0);
     660        }
     661    }
     662
     663    /**
     664     *  @param out null for background analysis
     665     *  @param buf null for background analysis
     666     */
    586667    private void renderIPGroupsFamily(Writer out, StringBuilder buf, List<RouterInfo> ris, Map<Hash, Points> points) throws IOException {
    587         buf.append("<h3 id=\"samefamily\" class=\"sybils\">Floodfills in the same Family</h3><div class=\"sybil_container\">");
     668        if (buf != null)
     669            buf.append("<h3 id=\"samefamily\" class=\"sybils\">Floodfills in the same Family</h3><div class=\"sybil_container\">");
    588670        ObjectCounter<String> oc = new ObjectCounter<String>();
    589671        for (RouterInfo info : ris) {
     
    601683            int count = oc.count(s);
    602684            String ss = DataHelper.escapeHTML(s);
    603             if (count > 1) {
     685            if (buf != null && count > 1) {
    604686                buf.append("<p class=\"family\"><b>").append(count).append(" floodfills in family: &nbsp;<a href=\"/netdb?fam=")
    605687                   .append(ss).append("&amp;sybil\">").append(ss).append("</a></b></p>");
     
    627709            }
    628710        }
    629         if (!found)
    630             buf.append("<p class=\"notfound\">None</p>");
    631         buf.append("</div>");
    632         out.write(buf.toString());
    633         out.flush();
    634         buf.setLength(0);
     711        if (buf != null) {
     712            if (!found)
     713                buf.append("<p class=\"notfound\">None</p>");
     714            buf.append("</div>");
     715            out.write(buf.toString());
     716            out.flush();
     717            buf.setLength(0);
     718        }
    635719    }
    636720
     
    713797    }
    714798
     799    /**
     800     *  @param out null for background analysis
     801     *  @param buf null for background analysis
     802     */
    715803    private void renderRouterInfoHTML(Writer out, StringBuilder buf, Hash us, double avgMinDist,
    716804                                      List<RouterInfo> ris, Map<Hash, Points> points) throws IOException {
     
    725813        for (int i = 0; i < count; i++) {
    726814            RouterInfo ri = ris.get(i);
    727             double dist = renderRouterInfo(buf, ri, us, false, false);
    728             if (dist < avgMinDist) {
     815            double dist;
     816            if (buf != null) {
     817                dist = renderRouterInfo(buf, ri, us, false, false);
     818            } else {
     819                BigInteger bidist = HashDistance.getDistance(us, ri.getHash());
     820                dist = biLog2(bidist);
     821            }
     822            if (buf != null && dist < avgMinDist) {
    729823                if (i == 0) {
    730824                    //buf.append("<p><b>Not to worry, but above router is closer than average minimum distance " + fmt.format(avgMinDist) + "</b></p>");
     
    755849                break;
    756850        }
    757         double avg = tot / count;
    758         buf.append("<p id=\"sybil_totals\"><b>Totals for " + count + " floodfills: &nbsp;</b><span class=\"netdb_name\">MIN:</span > " + fmt.format(min) + "&nbsp; <span class=\"netdb_name\">AVG:</span> " +
    759             fmt.format(avg) + "&nbsp; <span class=\"netdb_name\">MEDIAN:</span> " + fmt.format(median) + "&nbsp; <span class=\"netdb_name\">MAX:</span> " + fmt.format(max) + "</p>\n");
    760         out.write(buf.toString());
    761         out.flush();
    762         buf.setLength(0);
     851        if (buf != null) {
     852            double avg = tot / count;
     853            buf.append("<p id=\"sybil_totals\"><b>Totals for " + count + " floodfills: &nbsp;</b><span class=\"netdb_name\">MIN:</span > " + fmt.format(min) + "&nbsp; <span class=\"netdb_name\">AVG:</span> " +
     854                fmt.format(avg) + "&nbsp; <span class=\"netdb_name\">MEDIAN:</span> " + fmt.format(median) + "&nbsp; <span class=\"netdb_name\">MAX:</span> " + fmt.format(max) + "</p>\n");
     855            out.write(buf.toString());
     856            out.flush();
     857            buf.setLength(0);
     858        }
    763859    }
    764860
     
    803899            buf.append("</th><th>");
    804900            if(country != null) {
    805                 buf.append("<a href=\"/netdb?c=").append(country).append("\">");
    806                 buf.append("<img height=\"11\" width=\"16\" alt=\"").append(country.toUpperCase(Locale.US)).append('\"');
    807                 buf.append(" title=\"").append(getTranslatedCountry(country)).append('\"');
    808                 buf.append(" src=\"/flags.jsp?c=").append(country).append("\"> ").append("</a>");
     901                buf.append("<a href=\"/netdb?c=").append(country).append("\">" +
     902                           "<img height=\"11\" width=\"16\" alt=\"").append(country.toUpperCase(Locale.US)).append('\"' +
     903                           " title=\"").append(getTranslatedCountry(country)).append('\"' +
     904                           " src=\"/flags.jsp?c=").append(country).append("\"> ").append("</a>");
    809905            }
    810906            if (!full) {
     
    821917            }
    822918        }
    823         buf.append("<p><b>Version:</b> ").append(DataHelper.stripHTML(info.getVersion())).append("</p>\n");
    824         buf.append("<p><b>Caps:</b> ").append(DataHelper.stripHTML(info.getCapabilities())).append("</p>\n");
     919        buf.append("<p><b>Version:</b> ").append(DataHelper.stripHTML(info.getVersion())).append("</p>\n" +
     920                   "<p><b>Caps:</b> ").append(DataHelper.stripHTML(info.getCapabilities())).append("</p>\n");
    825921        String kr = info.getOption("netdb.knownRouters");
    826922;
     
    9081004        buf.append("<p><b>").append(_t("Signing Key")).append(":</b> ")
    9091005           .append(info.getIdentity().getSigningPublicKey().getType().toString()).append("</p>\n");
    910         buf.append("<p class=\"sybil_filler\">&nbsp;</p>");
    911         buf.append("</div></td></tr><tr><td class=\"sybil_addresses\" colspan=\"3\"><table><tr><td><b>" + _t("Addresses") + ":</b></td><td>");
     1006        buf.append("<p class=\"sybil_filler\">&nbsp;</p>" +
     1007                   "</div></td></tr><tr><td class=\"sybil_addresses\" colspan=\"3\"><table><tr><td><b>" + _t("Addresses") + ":</b></td><td>");
    9121008        Collection<RouterAddress> addrs = info.getAddresses();
    9131009        if (addrs.size() > 1) {
     
    9321028            }
    9331029        }
    934         buf.append("</table></td></tr>\n");
    935         buf.append("</table>\n");
     1030        buf.append("</table></td></tr>\n" +
     1031                   "</table>\n");
    9361032        return distance;
    9371033    }
Note: See TracChangeset for help on using the changeset viewer.