Changeset 3054a24
- Timestamp:
- Dec 15, 2018 4:54:01 PM (2 years ago)
- Branches:
- master
- Children:
- 9437e2c
- Parents:
- 5d06de8
- Location:
- apps/routerconsole/java/src/net/i2p/router
- Files:
-
- 1 added
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
apps/routerconsole/java/src/net/i2p/router/web/helpers/SybilRenderer.java
r5d06de8 r3054a24 31 31 import net.i2p.router.peermanager.DBHistory; 32 32 import net.i2p.router.peermanager.PeerProfile; 33 import net.i2p.router.sybil.Pair; 33 34 import net.i2p.router.sybil.Points; 34 35 import net.i2p.router.tunnel.pool.TunnelPool; … … 248 249 249 250 // IP analysis 250 renderIPGroupsFamily(out, buf, ris, points); 251 renderIPGroupsUs(out, buf, ris, points); 252 renderIPGroups32(out, buf, ris, points); 253 renderIPGroups24(out, buf, ris, points); 254 renderIPGroups16(out, buf, ris, points); 251 Map<String, List<RouterInfo>> fmap = calculateIPGroupsFamily(ris, points); 252 renderIPGroupsFamily(out, buf, fmap); 253 List<RouterInfo> ri32 = new ArrayList<RouterInfo>(4); 254 List<RouterInfo> ri24 = new ArrayList<RouterInfo>(4); 255 List<RouterInfo> ri16 = new ArrayList<RouterInfo>(4); 256 calculateIPGroupsUs(ris, points, ri32, ri24, ri16); 257 renderIPGroupsUs(out, buf, ri32, ri24, ri16); 258 Map<Integer, List<RouterInfo>> map = calculateIPGroups32(ris, points); 259 renderIPGroups32(out, buf, map); 260 map = calculateIPGroups24(ris, points); 261 renderIPGroups24(out, buf, map); 262 map = calculateIPGroups16(ris, points); 263 //renderIPGroups16(out, buf, map); 255 264 256 265 // Pairwise distance analysis 257 renderPairDistance(out, buf, ris, points); 266 List<Pair> pairs = new ArrayList<Pair>(PAIRMAX); 267 double avg = calculatePairDistance(ris, points, pairs); 268 renderPairDistance(out, buf, pairs, avg); 258 269 259 270 // Distance to our router analysis 260 271 buf.append("<h3 id=\"ritoday\" class=\"sybils\">Closest Floodfills to Our Routing Key (Where we Store our RI)</h3>"); 261 272 buf.append("<p class=\"sybil_info\"><a href=\"/netdb?caps=f&sybil\">See all</a></p>"); 262 renderRouterInfoHTML(out, buf, ourRKey, "our rkey", avgMinDist, ris, points); 273 calculateRouterInfo(ourRKey, "our rkey", ris, points); 274 renderRouterInfoHTML(out, buf, ourRKey, avgMinDist, ris); 263 275 RouterKeyGenerator rkgen = _context.routerKeyGenerator(); 264 276 Hash nkey = rkgen.getNextRoutingKey(us); 265 277 buf.append("<h3 id=\"ritmrw\" class=\"sybils\">Closest Floodfills to Tomorrow's Routing Key (Where we will Store our RI)</h3>"); 266 278 buf.append("<p class=\"sybil_info\"><a href=\"/netdb?caps=f&sybil\">See all</a></p>"); 267 renderRouterInfoHTML(out, buf, nkey, "our rkey (tomorrow)", avgMinDist, ris, points); 279 calculateRouterInfo(nkey, "our rkey (tomorrow)", ris, points); 280 renderRouterInfoHTML(out, buf, nkey, avgMinDist, ris); 268 281 269 282 buf.append("<h3 id=\"dht\" class=\"sybils\">Closest Floodfills to Our Router Hash (DHT Neighbors if we are Floodfill)</h3>"); 270 renderRouterInfoHTML(out, buf, us, "our router", avgMinDist, ris, points); 283 calculateRouterInfo(us, "our router", ris, points); 284 renderRouterInfoHTML(out, buf, us, avgMinDist, ris); 271 285 272 286 // Distance to our published destinations analysis … … 289 303 buf.append("<h3 class=\"sybils\">Closest floodfills to the Routing Key for " + name + " (where we store our LS)</h3>"); 290 304 buf.append("<p class=\"sybil_info\"><a href=\"/netdb?caps=f&sybil=" + ls.getHash().toBase64() + "\">See all</a></p>"); 291 renderRouterInfoHTML(out, buf, rkey, name, avgMinDist, ris, points); 305 calculateRouterInfo(rkey, name, ris, points); 306 renderRouterInfoHTML(out, buf, rkey, avgMinDist, ris); 292 307 nkey = rkgen.getNextRoutingKey(ls.getHash()); 293 308 buf.append("<h3 class=\"sybils\">Closest floodfills to Tomorrow's Routing Key for " + name + " (where we will store our LS)</h3>"); 294 309 buf.append("<p class=\"sybil_info\"><a href=\"/netdb?caps=f&sybil=" + ls.getHash().toBase64() + "\">See all</a></p>"); 295 renderRouterInfoHTML(out, buf, nkey, name + " (tomorrow)", avgMinDist, ris, points); 310 calculateRouterInfo(nkey, name + " (tomorrow)", ris, points); 311 renderRouterInfoHTML(out, buf, nkey, avgMinDist, ris); 296 312 } 297 313 … … 345 361 346 362 // IP analysis 347 renderIPGroupsFamily(null, null, ris, points); 348 renderIPGroupsUs(null, null, ris, points); 349 renderIPGroups32(null, null, ris, points); 350 renderIPGroups24(null, null, ris, points); 351 renderIPGroups16(null, null, ris, points); 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); 352 371 353 372 // Pairwise distance analysis 354 renderPairDistance(null, null, ris, points); 373 List<Pair> pairs = new ArrayList<Pair>(PAIRMAX); 374 calculatePairDistance(ris, points, pairs); 355 375 356 376 // Distance to our router analysis 357 377 // closest to our routing key today 358 378 Hash ourRKey = _context.router().getRouterInfo().getRoutingKey(); 359 renderRouterInfoHTML(null, null, ourRKey, "our rkey", avgMinDist, ris, points);379 calculateRouterInfo(ourRKey, "our rkey", ris, points); 360 380 // closest to our routing key tomorrow 361 381 RouterKeyGenerator rkgen = _context.routerKeyGenerator(); 362 382 Hash nkey = rkgen.getNextRoutingKey(us); 363 renderRouterInfoHTML(null, null, nkey, "our rkey (tomorrow)", avgMinDist, ris, points);383 calculateRouterInfo(nkey, "our rkey (tomorrow)", ris, points); 364 384 // closest to us 365 renderRouterInfoHTML(null, null, us, "our router", avgMinDist, ris, points);385 calculateRouterInfo(us, "our router", ris, points); 366 386 367 387 // Distance to our published destinations analysis … … 381 401 String name = (in != null) ? DataHelper.escapeHTML(in.getSettings().getDestinationNickname()) : client.toBase64().substring(0,4); 382 402 // closest to routing key today 383 renderRouterInfoHTML(null, null, rkey, name, avgMinDist, ris, points);403 calculateRouterInfo(rkey, name, ris, points); 384 404 // closest to routing key tomorrow 385 405 nkey = rkgen.getNextRoutingKey(ls.getHash()); 386 renderRouterInfoHTML(null, null, nkey, name + " (tomorrow)", avgMinDist, ris, points);406 calculateRouterInfo(nkey, name + " (tomorrow)", ris, points); 387 407 } 388 408 … … 393 413 } 394 414 395 private static class Pair implements Comparable<Pair> { 396 public final RouterInfo r1, r2; 397 public final BigInteger dist; 398 public Pair(RouterInfo ri1, RouterInfo ri2, BigInteger distance) { 399 r1 = ri1; r2 = ri2; dist = distance; 400 } 401 public int compareTo(Pair p) { 402 return this.dist.compareTo(p.dist); 403 } 404 } 405 406 /** 407 * @param out null for background analysis 408 * @param buf null for background analysis 409 */ 410 private void renderPairDistance(Writer out, StringBuilder buf, List<RouterInfo> ris, Map<Hash, Points> points) throws IOException { 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) { 411 422 int sz = ris.size(); 412 List<Pair> pairs = new ArrayList<Pair>(PAIRMAX);413 423 double total = 0; 414 424 for (int i = 0; i < sz; i++) { … … 431 441 432 442 double avg = total / (sz * sz / 2d); 433 if (buf != null) {434 buf.append("<h3 class=\"sybils\">Average Floodfill Distance is ").append(fmt.format(avg)).append("</h3>" +435 "<h3 id=\"pairs\" class=\"sybils\">Closest Floodfill Pairs by Hash</h3>");436 }437 443 for (Pair p : pairs) { 438 444 double distance = biLog2(p.dist); … … 440 446 if (point < 0) 441 447 break; // sorted; 442 if (buf != null && point >= 2) {443 // limit display444 buf.append("<p class=\"hashdist\"><b>Hash Distance: ").append(fmt.format(distance)).append(": </b>" +445 "</p>");446 renderRouterInfo(buf, p.r1, null, false, false);447 renderRouterInfo(buf, p.r2, null, false, false);448 }449 448 point *= PAIR_DISTANCE_FACTOR; 450 449 String b2 = p.r2.getHash().toBase64(); … … 455 454 ") to other floodfill <a href=\"netdb?r=" + b1 + "\">" + b1 + "</a>"); 456 455 } 457 if (buf != null) { 458 out.write(buf.toString()); 459 out.flush(); 460 buf.setLength(0); 461 } 456 return avg; 457 } 458 459 /** 460 * @param pairs sorted 461 */ 462 private void renderPairDistance(Writer out, StringBuilder buf, List<Pair> pairs, double avg) throws IOException { 463 buf.append("<h3 class=\"sybils\">Average Floodfill Distance is ").append(fmt.format(avg)).append("</h3>" + 464 "<h3 id=\"pairs\" class=\"sybils\">Closest Floodfill Pairs by Hash</h3>"); 465 466 for (Pair p : pairs) { 467 double distance = biLog2(p.dist); 468 double point = MIN_CLOSE - distance; 469 // limit display 470 if (point < 2) 471 break; // sorted; 472 buf.append("<p class=\"hashdist\"><b>Hash Distance: ").append(fmt.format(distance)).append("</b>" + 473 "</p>"); 474 renderRouterInfo(buf, p.r1, null, false, false); 475 renderRouterInfo(buf, p.r2, null, false, false); 476 } 477 478 out.write(buf.toString()); 479 out.flush(); 480 buf.setLength(0); 462 481 } 463 482 … … 483 502 484 503 private static class FooComparator implements Comparator<Integer>, Serializable { 485 private final ObjectCounter<Integer> _o;486 public FooComparator( ObjectCounter<Integer> o) { _o = o;}504 private final Map<Integer, List<RouterInfo>> _o; 505 public FooComparator(Map<Integer, List<RouterInfo>> o) { _o = o;} 487 506 public int compare(Integer l, Integer r) { 488 507 // reverse by count 489 int rv = _o. count(r) - _o.count(l);508 int rv = _o.get(r).size() - _o.get(l).size(); 490 509 if (rv != 0) 491 510 return rv; … … 496 515 497 516 private static class FoofComparator implements Comparator<String>, Serializable { 498 private final ObjectCounter<String> _o;517 private final Map<String, List<RouterInfo>> _o; 499 518 private final Collator _comp = Collator.getInstance(); 500 public FoofComparator( ObjectCounter<String> o) { _o = o;}519 public FoofComparator(Map<String, List<RouterInfo>> o) { _o = o;} 501 520 public int compare(String l, String r) { 502 521 // reverse by count 503 int rv = _o. count(r) - _o.count(l);522 int rv = _o.get(r).size() - _o.get(l).size(); 504 523 if (rv != 0) 505 524 return rv; … … 510 529 511 530 /** 512 * @param out null for background analysis 513 * @param buf null for background analysis 514 */ 515 private void renderIPGroupsUs(Writer out, StringBuilder buf, List<RouterInfo> ris, Map<Hash, Points> points) throws IOException { 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) { 516 538 RouterInfo us = _context.router().getRouterInfo(); 517 539 byte[] ourIP = getIP(us); 518 540 if (ourIP == null) 519 541 return; 520 if (buf != null)521 buf.append("<h3 id=\"ourIP\" class=\"sybils\">Floodfills close to Our IP</h3>");522 boolean found = false;523 542 for (RouterInfo info : ris) { 524 543 byte[] ip = getIP(info); … … 526 545 continue; 527 546 if (ip[0] == ourIP[0] && ip[1] == ourIP[1]) { 528 if (buf != null)529 buf.append("<p id=\"sybil_info\"><b>");530 547 if (ip[2] == ourIP[2]) { 531 548 if (ip[3] == ourIP[3]) { 532 if (buf != null)533 buf.append("Same IP as us");534 549 addPoints(points, info.getHash(), POINTS_US32, "Same IP as us"); 535 550 } else { 536 if (buf != null)537 buf.append("Same /24 as us");538 551 addPoints(points, info.getHash(), POINTS_US24, "Same /24 as us"); 539 552 } 540 553 } else { 541 if (buf != null)542 buf.append("Same /16 as us");543 554 addPoints(points, info.getHash(), POINTS_US16, "Same /16 as us"); 544 555 } 545 if (buf != null) { 546 buf.append(":</b></p>"); 547 renderRouterInfo(buf, info, null, false, false); 548 } 549 found = true; 550 } 551 } 552 if (buf != null) { 553 if (!found) 554 buf.append("<p class=\"notfound\">None</p>"); 555 out.write(buf.toString()); 556 out.flush(); 557 buf.setLength(0); 558 } 559 } 560 561 /** 562 * @param out null for background analysis 563 * @param buf null for background analysis 564 */ 565 private void renderIPGroups32(Writer out, StringBuilder buf, List<RouterInfo> ris, Map<Hash, Points> points) throws IOException { 566 if (buf != null) 567 buf.append("<h3 id=\"sameIP\" class=\"sybils\">Floodfills with the Same IP</h3>"); 556 } 557 } 558 } 559 560 /** 561 * 562 */ 563 private void renderIPGroupsUs(Writer out, StringBuilder buf, List<RouterInfo> ri32, 564 List<RouterInfo> ri24, List<RouterInfo> ri16) throws IOException { 565 buf.append("<h3 id=\"ourIP\" class=\"sybils\">Floodfills close to Our IP</h3>"); 566 boolean found = false; 567 for (RouterInfo info : ri32) { 568 buf.append("<p id=\"sybil_info\"><b>"); 569 buf.append("Same IP as us"); 570 buf.append(":</b></p>"); 571 renderRouterInfo(buf, info, null, false, false); 572 found = true; 573 } 574 for (RouterInfo info : ri24) { 575 buf.append("<p id=\"sybil_info\"><b>"); 576 buf.append("Same /24 as us"); 577 buf.append(":</b></p>"); 578 renderRouterInfo(buf, info, null, false, false); 579 found = true; 580 } 581 for (RouterInfo info : ri16) { 582 buf.append("<p id=\"sybil_info\"><b>"); 583 buf.append("Same /16 as us"); 584 buf.append(":</b></p>"); 585 renderRouterInfo(buf, info, null, false, false); 586 found = true; 587 } 588 if (!found) 589 buf.append("<p class=\"notfound\">None</p>"); 590 out.write(buf.toString()); 591 out.flush(); 592 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) { 568 599 ObjectCounter<Integer> oc = new ObjectCounter<Integer>(); 569 600 for (RouterInfo info : ris) { … … 574 605 oc.increment(x); 575 606 } 576 List<Integer> foo = new ArrayList<Integer>();607 Map<Integer, List<RouterInfo>> rv = new HashMap<Integer, List<RouterInfo>>(); 577 608 for (Integer ii : oc.objects()) { 578 609 int count = oc.count(ii); 579 610 if (count >= 2) 580 foo.add(ii); 581 } 582 Collections.sort(foo, new FooComparator(oc)); 583 boolean found = false; 584 for (Integer ii : foo) { 611 rv.put(ii, new ArrayList<RouterInfo>(4)); 612 } 613 for (Map.Entry<Integer, List<RouterInfo>> e : rv.entrySet()) { 614 Integer ii = e.getKey(); 585 615 int count = oc.count(ii); 586 616 int i = ii.intValue(); … … 589 619 int i2 = (i >> 8) & 0xff; 590 620 int i3 = i & 0xff; 591 String sip = i0 + "." + i1 + '.' + i2 + '.' + i3;592 if (buf != null) {593 buf.append("<p class=\"sybil_info\"><b>").append(count).append(" floodfills with IP <a href=\"/netdb?ip=")594 .append(sip).append("&sybil\">").append(sip)595 .append("</a>:</b></p>");596 }597 621 for (RouterInfo info : ris) { 598 622 byte[] ip = getIP(info); … … 607 631 if ((ip[3] & 0xff) != i3) 608 632 continue; 609 found = true; 610 if (buf != null) 611 renderRouterInfo(buf, info, null, false, false); 633 e.getValue().add(info); 612 634 double point = POINTS32 * (count - 1); 613 635 addPoints(points, info.getHash(), point, "Same IP with " + (count - 1) + " other" + (( count > 2) ? "s" : "")); 614 636 } 615 637 } 616 if (buf != null) { 617 if (!found) 618 buf.append("<p class=\"notfound\">None</p>"); 619 out.write(buf.toString()); 620 out.flush(); 621 buf.setLength(0); 622 } 623 } 624 625 /** 626 * @param out null for background analysis 627 * @param buf null for background analysis 628 */ 629 private void renderIPGroups24(Writer out, StringBuilder buf, List<RouterInfo> ris, Map<Hash, Points> points) throws IOException { 630 if (buf != null) 631 buf.append("<h3 id=\"same24\" class=\"sybils\">Floodfills in the Same /24 (2 minimum)</h3>"); 638 return rv; 639 } 640 641 /** 642 * 643 */ 644 private void renderIPGroups32(Writer out, StringBuilder buf, Map<Integer, List<RouterInfo>> map) throws IOException { 645 buf.append("<h3 id=\"sameIP\" class=\"sybils\">Floodfills with the Same IP</h3>"); 646 List<Integer> foo = new ArrayList<Integer>(map.keySet()); 647 Collections.sort(foo, new FooComparator(map)); 648 boolean found = false; 649 for (Integer ii : foo) { 650 List<RouterInfo> ris = map.get(ii); 651 int count = ris.size(); 652 int i = ii.intValue(); 653 int i0 = (i >> 24) & 0xff; 654 int i1 = (i >> 16) & 0xff; 655 int i2 = (i >> 8) & 0xff; 656 int i3 = i & 0xff; 657 String sip = i0 + "." + i1 + '.' + i2 + '.' + i3; 658 buf.append("<p class=\"sybil_info\"><b>").append(count).append(" floodfills with IP <a href=\"/netdb?ip=") 659 .append(sip).append("&sybil\">").append(sip) 660 .append("</a>:</b></p>"); 661 for (RouterInfo info : ris) { 662 found = true; 663 renderRouterInfo(buf, info, null, false, false); 664 } 665 } 666 if (!found) 667 buf.append("<p class=\"notfound\">None</p>"); 668 out.write(buf.toString()); 669 out.flush(); 670 buf.setLength(0); 671 } 672 673 /** 674 * @since 0.9.38 split out from renderIPGroups24() 675 */ 676 private Map<Integer, List<RouterInfo>> calculateIPGroups24(List<RouterInfo> ris, Map<Hash, Points> points) { 632 677 ObjectCounter<Integer> oc = new ObjectCounter<Integer>(); 633 678 for (RouterInfo info : ris) { … … 638 683 oc.increment(x); 639 684 } 640 List<Integer> foo = new ArrayList<Integer>();685 Map<Integer, List<RouterInfo>> rv = new HashMap<Integer, List<RouterInfo>>(); 641 686 for (Integer ii : oc.objects()) { 642 687 int count = oc.count(ii); 643 688 if (count >= 2) 644 foo.add(ii); 645 } 646 Collections.sort(foo, new FooComparator(oc)); 647 boolean found = false; 648 for (Integer ii : foo) { 689 rv.put(ii, new ArrayList<RouterInfo>(4)); 690 } 691 for (Map.Entry<Integer, List<RouterInfo>> e : rv.entrySet()) { 692 Integer ii = e.getKey(); 649 693 int count = oc.count(ii); 650 694 int i = ii.intValue(); … … 652 696 int i1 = (i >> 8) & 0xff; 653 697 int i2 = i & 0xff; 654 String sip = i0 + "." + i1 + '.' + i2 + ".0/24";655 if (buf != null) {656 buf.append("<p class=\"sybil_info\"><b>").append(count).append(" floodfills with IP <a href=\"/netdb?ip=")657 .append(sip).append("&sybil\">").append(sip)658 .append("</a>:</b></p>");659 }660 698 for (RouterInfo info : ris) { 661 699 byte[] ip = getIP(info); … … 668 706 if ((ip[2] & 0xff) != i2) 669 707 continue; 670 found = true; 671 if (buf != null) 672 renderRouterInfo(buf, info, null, false, false); 708 e.getValue().add(info); 673 709 double point = POINTS24 * (count - 1); 674 710 addPoints(points, info.getHash(), point, "Same /24 IP with " + (count - 1) + " other" + (( count > 2) ? "s" : "")); 675 711 } 676 712 } 677 if (buf != null) { 678 if (!found) 679 buf.append("<p class=\"notfound\">None</p>"); 680 out.write(buf.toString()); 681 out.flush(); 682 buf.setLength(0); 683 } 684 } 685 686 /** 687 * @param out null for background analysis 688 * @param buf null for background analysis 689 */ 690 private void renderIPGroups16(Writer out, StringBuilder buf, List<RouterInfo> ris, Map<Hash, Points> points) throws IOException { 691 if (buf != null) 692 buf.append("<h3 id=\"same16\" class=\"sybils\">Floodfills in the Same /16 (4 minimum)</h3>"); 713 return rv; 714 } 715 716 /** 717 * 718 */ 719 private void renderIPGroups24(Writer out, StringBuilder buf, Map<Integer, List<RouterInfo>> map) throws IOException { 720 buf.append("<h3 id=\"same24\" class=\"sybils\">Floodfills in the Same /24 (2 minimum)</h3>"); 721 List<Integer> foo = new ArrayList<Integer>(map.keySet()); 722 Collections.sort(foo, new FooComparator(map)); 723 boolean found = false; 724 for (Integer ii : foo) { 725 List<RouterInfo> ris = map.get(ii); 726 int count = ris.size(); 727 int i = ii.intValue(); 728 int i0 = i >> 16; 729 int i1 = (i >> 8) & 0xff; 730 int i2 = i & 0xff; 731 String sip = i0 + "." + i1 + '.' + i2 + ".0/24"; 732 buf.append("<p class=\"sybil_info\"><b>").append(count).append(" floodfills with IP <a href=\"/netdb?ip=") 733 .append(sip).append("&sybil\">").append(sip) 734 .append("</a>:</b></p>"); 735 for (RouterInfo info : ris) { 736 found = true; 737 renderRouterInfo(buf, info, null, false, false); 738 } 739 } 740 if (!found) 741 buf.append("<p class=\"notfound\">None</p>"); 742 out.write(buf.toString()); 743 out.flush(); 744 buf.setLength(0); 745 } 746 747 /** 748 * @since 0.9.38 split out from renderIPGroups16() 749 */ 750 private Map<Integer, List<RouterInfo>> calculateIPGroups16(List<RouterInfo> ris, Map<Hash, Points> points) { 693 751 ObjectCounter<Integer> oc = new ObjectCounter<Integer>(); 694 752 for (RouterInfo info : ris) { … … 699 757 oc.increment(x); 700 758 } 701 List<Integer> foo = new ArrayList<Integer>();759 Map<Integer, List<RouterInfo>> rv = new HashMap<Integer, List<RouterInfo>>(); 702 760 for (Integer ii : oc.objects()) { 703 761 int count = oc.count(ii); 704 762 if (count >= 4) 705 foo.add(ii); 706 } 707 Collections.sort(foo, new FooComparator(oc)); 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 /** 788 * 789 */ 790 private void renderIPGroups16(Writer out, StringBuilder buf, Map<Integer, List<RouterInfo>> map) throws IOException { 791 buf.append("<h3 id=\"same16\" class=\"sybils\">Floodfills in the Same /16 (4 minimum)</h3>"); 792 List<Integer> foo = new ArrayList<Integer>(map.keySet()); 793 Collections.sort(foo, new FooComparator(map)); 708 794 boolean found = false; 709 795 for (Integer ii : foo) { 710 int count = oc.count(ii); 796 List<RouterInfo> ris = map.get(ii); 797 int count = ris.size(); 711 798 int i = ii.intValue(); 712 799 int i0 = i >> 8; … … 719 806 } 720 807 for (RouterInfo info : ris) { 721 byte[] ip = getIP(info);722 if (ip == null)723 continue;724 if ((ip[0] & 0xff) != i0)725 continue;726 if ((ip[1] & 0xff) != i1)727 continue;728 808 found = true; 729 // limit display 730 //renderRouterInfo(buf, info, null, false, false); 731 double point = POINTS16 * (count - 1); 732 addPoints(points, info.getHash(), point, "Same /16 IP with " + (count - 1) + " other" + (( count > 2) ? "s" : "")); 733 } 734 } 735 if (buf != null) { 736 if (!found) 737 buf.append("<p class=\"notfound\">None</p>"); 738 out.write(buf.toString()); 739 out.flush(); 740 buf.setLength(0); 741 } 742 } 743 744 /** 745 * @param out null for background analysis 746 * @param buf null for background analysis 747 */ 748 private void renderIPGroupsFamily(Writer out, StringBuilder buf, List<RouterInfo> ris, Map<Hash, Points> points) throws IOException { 749 if (buf != null) 750 buf.append("<h3 id=\"samefamily\" class=\"sybils\">Floodfills in the same Family</h3><div class=\"sybil_container\">"); 809 renderRouterInfo(buf, info, null, false, false); 810 } 811 } 812 if (!found) 813 buf.append("<p class=\"notfound\">None</p>"); 814 out.write(buf.toString()); 815 out.flush(); 816 buf.setLength(0); 817 } 818 819 /** 820 * @since 0.9.38 split out from renderIPGroupsFamily() 821 */ 822 private Map<String, List<RouterInfo>> calculateIPGroupsFamily(List<RouterInfo> ris, Map<Hash, Points> points) { 751 823 ObjectCounter<String> oc = new ObjectCounter<String>(); 752 824 for (RouterInfo info : ris) { … … 757 829 } 758 830 List<String> foo = new ArrayList<String>(oc.objects()); 759 Collections.sort(foo, new FoofComparator(oc));831 Map<String, List<RouterInfo>> rv = new HashMap<String, List<RouterInfo>>(foo.size()); 760 832 FamilyKeyCrypto fkc = _context.router().getFamilyKeyCrypto(); 761 833 String ourFamily = fkc != null ? fkc.getOurFamilyName() : null; 762 boolean found = false;763 834 for (String s : foo) { 764 835 int count = oc.count(s); 836 List<RouterInfo> list = new ArrayList<RouterInfo>(count); 837 rv.put(s, list); 765 838 String ss = DataHelper.escapeHTML(s); 766 if (buf != null && count > 1) {767 buf.append("<p class=\"family\"><b>").append(count).append(" floodfills in family: <a href=\"/netdb?fam=")768 .append(ss).append("&sybil\">").append(ss).append("</a></b></p>");769 }770 839 for (RouterInfo info : ris) { 771 840 String fam = info.getOption("family"); … … 774 843 if (!fam.equals(s)) 775 844 continue; 776 found = true; 777 // limit display 778 //renderRouterInfo(buf, info, null, false, false); 845 list.add(info); 779 846 double point = POINTS_FAMILY; 780 847 if (fkc != null && s.equals(ourFamily)) { … … 790 857 } 791 858 } 792 if (buf != null) { 793 if (!found) 794 buf.append("<p class=\"notfound\">None</p>"); 795 buf.append("</div>"); 796 out.write(buf.toString()); 797 out.flush(); 798 buf.setLength(0); 799 } 859 return rv; 860 } 861 862 /** 863 * 864 */ 865 private void renderIPGroupsFamily(Writer out, StringBuilder buf, Map<String, List<RouterInfo>> map) throws IOException { 866 buf.append("<h3 id=\"samefamily\" class=\"sybils\">Floodfills in the same Family</h3><div class=\"sybil_container\">"); 867 List<String> foo = new ArrayList<String>(map.keySet()); 868 Collections.sort(foo, new FoofComparator(map)); 869 FamilyKeyCrypto fkc = _context.router().getFamilyKeyCrypto(); 870 String ourFamily = fkc != null ? fkc.getOurFamilyName() : null; 871 boolean found = false; 872 for (String s : foo) { 873 List<RouterInfo> list = map.get(s); 874 int count = list.size(); 875 String ss = DataHelper.escapeHTML(s); 876 if (count > 1) { 877 buf.append("<p class=\"family\"><b>").append(count).append(" floodfills in family: <a href=\"/netdb?fam=") 878 .append(ss).append("&sybil\">").append(ss).append("</a></b></p>"); 879 found = true; 880 } 881 //for (RouterInfo info : ris) { 882 // limit display 883 //renderRouterInfo(buf, info, null, false, false); 884 //} 885 } 886 if (!found) 887 buf.append("<p class=\"notfound\">None</p>"); 888 buf.append("</div>"); 889 out.write(buf.toString()); 890 out.flush(); 891 buf.setLength(0); 800 892 } 801 893 … … 879 971 880 972 /** 881 * @param out null for background analysis882 * @param buf null for background analysis883 973 * @param usName HTML escaped 884 */ 885 private void renderRouterInfoHTML(Writer out, StringBuilder buf, Hash us, String usName, double avgMinDist, 886 List<RouterInfo> ris, Map<Hash, Points> points) throws IOException { 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) { 887 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 } 991 } 992 993 /** 994 * Render routers closer than MIN_CLOSE up to MAX routers 995 * @param ris sorted, closest first 996 * @param usName HTML escaped 997 */ 998 private void renderRouterInfoHTML(Writer out, StringBuilder buf, Hash us, double avgMinDist, 999 List<RouterInfo> ris) throws IOException { 888 1000 double min = 256; 889 1001 double max = 0; … … 895 1007 for (int i = 0; i < count; i++) { 896 1008 RouterInfo ri = ris.get(i); 897 double dist; 898 if (buf != null) { 899 dist = renderRouterInfo(buf, ri, us, false, false); 900 } else { 901 BigInteger bidist = HashDistance.getDistance(us, ri.getHash()); 902 dist = biLog2(bidist); 903 } 904 if (buf != null && dist < avgMinDist) { 1009 double dist = renderRouterInfo(buf, ri, us, false, false); 1010 if (dist < MIN_CLOSE) 1011 break; 1012 if (dist < avgMinDist) { 905 1013 if (i == 0) { 906 1014 //buf.append("<p><b>Not to worry, but above router is closer than average minimum distance " + fmt.format(avgMinDist) + "</b></p>"); … … 923 1031 else if (i == medIdx + 1 && isEven) 924 1032 median = (median + dist) / 2; 925 double point = MIN_CLOSE - dist; 926 if (point > 0) { 927 point *= OUR_KEY_FACTOR; 928 addPoints(points, ri.getHash(), point, "Very close (" + fmt.format(dist) + ") to our key " + usName + ": " + us.toBase64()); 929 } 930 if (i >= MAX - 1) 931 break; 932 } 933 if (buf != null) { 934 double avg = tot / count; 935 buf.append("<p id=\"sybil_totals\"><b>Totals for " + count + " floodfills: </b><span class=\"netdb_name\">MIN:</span > " + fmt.format(min) + " <span class=\"netdb_name\">AVG:</span> " + 936 fmt.format(avg) + " <span class=\"netdb_name\">MEDIAN:</span> " + fmt.format(median) + " <span class=\"netdb_name\">MAX:</span> " + fmt.format(max) + "</p>\n"); 937 out.write(buf.toString()); 938 out.flush(); 939 buf.setLength(0); 940 } 1033 } 1034 double avg = tot / count; 1035 buf.append("<p id=\"sybil_totals\"><b>Totals for " + count + 1036 " floodfills: </b><span class=\"netdb_name\">MIN:</span > " + fmt.format(min) + 1037 " <span class=\"netdb_name\">AVG:</span> " + fmt.format(avg) + 1038 " <span class=\"netdb_name\">MEDIAN:</span> " + fmt.format(median) + 1039 " <span class=\"netdb_name\">MAX:</span> " + fmt.format(max) + 1040 "</p>\n"); 1041 out.write(buf.toString()); 1042 out.flush(); 1043 buf.setLength(0); 941 1044 } 942 1045
Note: See TracChangeset
for help on using the changeset viewer.