pathfinderTree.js 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. #!/usr/bin/env node
  2. /* vim: set expandtab ts=4 sw=4: */
  3. /*
  4. * You may redistribute this program and/or modify it under the terms of
  5. * the GNU General Public License as published by the Free Software Foundation,
  6. * either version 3 of the License, or (at your option) any later version.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU General Public License
  14. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. */
  16. var Cjdns = require('../cjdnsadmin/cjdnsadmin');
  17. var nThen = require('../cjdnsadmin/nthen');
  18. var getAddresses = function (cjdns, callback) {
  19. var addresses = [];
  20. var again = function (i) {
  21. cjdns.NodeStore_dumpTable(i, function (err, table) {
  22. if (err) { throw err; }
  23. var j;
  24. for (j = 0; j < table.routingTable.length; j++) {
  25. var r = table.routingTable[j];
  26. if (addresses.indexOf(r.ip) === -1) { addresses.push(r.ip); }
  27. }
  28. if (j) {
  29. again(i+1);
  30. } else {
  31. callback(addresses);
  32. }
  33. });
  34. };
  35. again(0);
  36. };
  37. var buildTreeCycle = function (current, nodes) {
  38. current.peers = [];
  39. for (var i = nodes.length - 1; i >= 0; i--) {
  40. if (nodes[i].bestParent && nodes[i].bestParent.ip == current.ip) {
  41. current.peers.push(nodes[i]);
  42. nodes.splice(i, 1);
  43. }
  44. }
  45. for (var i = 0; i < current.peers.length; i++) {
  46. buildTreeCycle(current.peers[i], nodes);
  47. }
  48. return current;
  49. };
  50. var buildTree = function (origNodes) {
  51. var nodes = [];
  52. nodes.push.apply(nodes, origNodes);
  53. for (var i = 0; i < nodes.length; i++) {
  54. if (nodes[i].bestParent && nodes[i].ip === nodes[i].bestParent.ip) {
  55. var current = nodes[i];
  56. nodes.splice(i, 1);
  57. var out = buildTreeCycle(current, nodes);
  58. //if (nodes.length > 0) { throw new Error(); }
  59. return out;
  60. }
  61. }
  62. throw new Error();
  63. };
  64. var printTree = function (tree, spaces) {
  65. console.log(spaces + tree.ip + ' ' + tree.bestParent.parentChildLabel + ' ' + tree.routeLabel + ' ' + tree.reach);
  66. for (var i = 0; i < tree.peers.length; i++) {
  67. printTree(tree.peers[i], spaces + ' ');
  68. }
  69. };
  70. Cjdns.connectWithAdminInfo(function (cjdns) {
  71. var addrs;
  72. var nodes = [];
  73. nThen(function (waitFor) {
  74. getAddresses(cjdns, waitFor(function (addrs) { addresses = addrs; }));
  75. }).nThen(function (waitFor) {
  76. var nt = nThen;
  77. addresses.forEach(function (addr) {
  78. nt = nt(function (waitFor) {
  79. cjdns.NodeStore_nodeForAddr(addr, waitFor(function (err, ret) {
  80. if (err) { throw err; }
  81. if (ret.error !== 'none') { throw new Error(ret.error); }
  82. ret.result.ip = addr;
  83. nodes.push(ret.result);
  84. }));
  85. }).nThen;
  86. });
  87. nt(waitFor());
  88. }).nThen(function (waitFor) {
  89. //console.log(JSON.stringify(nodes, null, ' '));
  90. var tree = buildTree(nodes);
  91. printTree(tree, '');
  92. cjdns.disconnect();
  93. });
  94. });