git ssb

15+

ansuz / dnssb



Commit d3027fee807fce808aec9f7948f0719338d790e2

Merge branch 'show-cmd'

ansuz committed on 11/25/2016, 10:37:44 PM
Parent: c24fdc18c3deb086c2ba4086840b4abf85b6376c
Parent: a916aab11e0c6b05c831a6cb93d1754faf91e9d1

Files changed

index.jschanged
lib/dump.jschanged
lib/index.jschanged
lib/query.jschanged
lib/server.jschanged
lib/format.jsadded
package.jsonchanged
index.jsView
@@ -12,8 +12,9 @@
1212 var updateHelp = "\tdnssb update name [ttl] [class] type value";
1313 var branchHelp = "\tdnssb branch name type (class)";
1414 var serverHelp = "\tdnssb server port host";
1515 var dumpHelp = "\tdnssb dump";
16 +var showHelp = "\tdnssb show [domain]";
1617
1718 var CLI_Help = function () {
1819 [
1920 "try one of:",
@@ -21,8 +22,9 @@
2122 publishHelp,
2223 updateHelp,
2324 branchHelp,
2425 dumpHelp,
26 + showHelp,
2527 ].forEach(function (m) {
2628 console.log(m);
2729 });
2830 };
@@ -34,18 +36,42 @@
3436 CLI_Help();
3537 break;
3638 case 'dump':
3739 (function () {
38- var count = 0;
39- Lib.dump.records(function (record) { // each
40- console.log(JSON.stringify(record, null, 2));
41- count++;
42- }, function (sbot) { // done
43- console.log("Found a total of %s valid ssb-dns records", count);
44- sbot.close();
40 + var Client = require("ssb-client");
41 +
42 + Client(function (err, sbot) {
43 + if (err) throw err;
44 +
45 + var count = 0;
46 + Lib.dump.records(sbot, function (record) { // each
47 + console.log(JSON.stringify(record, null, 2));
48 + count++;
49 + }, function (err) { // done
50 + if (err) throw err;
51 + console.log("Found a total of %s valid ssb-dns records", count);
52 + sbot.close();
53 + });
4554 });
4655 }());
4756 break;
57 + case 'show':
58 + (function () {
59 + var name = argv[1] || '';
60 + var Client = require("ssb-client");
61 +
62 + Client(function (err, sbot) {
63 + if (err) throw err;
64 +
65 + Lib.dump.formattedRecords(sbot, {name: name}, function (line) {
66 + console.log(line);
67 + }, function (err) { // done
68 + if (err) throw err;
69 + sbot.close();
70 + });
71 + });
72 + }());
73 + break;
4874 case 'server':
4975 (function () {
5076 var port = argv[1] || 53053;
5177 var host = argv[2] || '127.0.0.1';
lib/dump.jsView
@@ -1,22 +1,52 @@
11 var Pull = require("pull-stream");
2 +var Paramap = require("pull-paramap");
3 +var AsyncMemo = require("asyncmemo");
4 +var getAvatar = require("ssb-avatar");
25 var Query = require("./query");
6 +var Format = require("./format");
37 var Dump = module.exports = {};
48
5-Dump.records = function (each, done) {
6- var Client = require("ssb-client");
9 +Dump.records = function (sbot, each, done) {
10 + Pull(Query.all(sbot),
11 + Query.drainSet(each, done));
12 +};
713
8- Client(function (err, sbot) {
9- if (err) { return void done(err); }
14 +function sortRecords(records) {
15 + records.forEach(function (r) {
16 + r.labels = typeof r.name === 'string'
17 + ? r.name.split(/\./).reverse() : [];
18 + });
19 + records.sort(function (a, b) {
20 + var len = Math.max(a.labels.length, b.labels.length);
21 + for (var i = 0; i < len; i++) {
22 + var labA = a.labels[i] || '';
23 + var labB = b.labels[i] || '';
24 + if (labA > labB) return 1;
25 + if (labA < labB) return -1;
26 + }
27 + return 0;
28 + })
29 +}
1030
11- Pull(Query.all(sbot),
12- Query.drainSet(each, function (err) {
13- if (err) throw err;
14- done(sbot);
31 +Dump.formattedRecords = function (sbot, opts, each, done) {
32 + sbot.whoami(function (err, feed) {
33 + if (err) throw err;
34 + var getAbout = AsyncMemo(getAvatar, sbot, feed.id);
35 +
36 + Pull(Query.inDomain(sbot, opts.name),
37 + Query.collectSet(function (err, records) {
38 + if (err) throw err;
39 + records.forEach(Format.formatNames(opts.name));
40 + sortRecords(records);
41 + Pull(Pull.values(records),
42 + Paramap(function (record, cb) {
43 + getAbout(record.author, function (err, about) {
44 + record.authorName = '@' + about.name;
45 + cb(err, record);
46 + });
47 + }, 8),
48 + Pull.map(Format.recordsToLines(Format.getMaxLengths(records))),
49 + Pull.drain(each, done))
1550 }));
1651 });
1752 };
18-
19-Dump.recordToLine = function (record) {
20- // TODO: output in zone-file-like format
21- return JSON.stringify(record);
22-};
lib/index.jsView
@@ -9,8 +9,10 @@
99 Lib.query = require("./query");
1010
1111 Lib.parse = require("./parse");
1212
13 +Lib.format = require("./format");
14 +
1315 // run as a scuttlebot plugin
1416 var plugin = Lib;
1517 var pkg = require("../package");
1618 plugin.name = "dns";
lib/query.jsView
@@ -41,8 +41,47 @@
4141 Pull.map(msgToRecord),
4242 Pull.filter());
4343 };
4444
45 +function recordsInDomain(sbot, name) {
46 + var path = name.split(/\./g).reverse()
47 +
48 + /* enable this when records without path propery are to be deprecated:
49 + // use ssb-query if it is supported
50 + if (sbot.query) return sbot.query.read({
51 + query: [{$filter: {value: {content: {
52 + type: 'ssb-dns',
53 + path: {$prefix: path}
54 + }}}}]
55 + });
56 + */
57 +
58 + // fallback to logt
59 + return Pull(sbot.messagesByType({
60 + type: 'ssb-dns',
61 + }),
62 + Pull.filter(function (msg) {
63 + var c = msg.value.content;
64 + var p = c.path;
65 + if (!p) {
66 + var name = c.record && c.record.name;
67 + if (typeof name !== 'string') return false;
68 + p = name.split(/\./).reverse()
69 + }
70 + for (var i = 0; i < path.length; i++) {
71 + if (path[i] !== p[i]) return false;
72 + }
73 + return true;
74 + }));
75 +}
76 +
77 +Query.inDomain = function (sbot, name) {
78 + if (!name) return Query.all(sbot);
79 + return Pull(recordsInDomain(sbot, name),
80 + Pull.map(msgToRecord),
81 + Pull.filter());
82 +};
83 +
4584 function expandName(name, wildcard) {
4685 var names = {};
4786 for (var labels = name.split(/\./); labels.length; labels.shift()) {
4887 if (wildcard) labels[0] = wildcard;
@@ -107,8 +146,17 @@
107146 onEnd(null);
108147 });
109148 };
110149
150 +Query.collectSet = function (cb) {
151 + var records = [];
152 + return Query.drainSet(function (record) {
153 + records.push(record);
154 + }, function (err) {
155 + return cb(err, records);
156 + });
157 +};
158 +
111159 Query.query = function (sbot, question, cb) {
112160 // look up records that match a question, including wildcard records
113161 // and zone authority records
114162 var authorityDomains = expandName(question.name);
lib/server.jsView
@@ -1,8 +1,9 @@
11 var Pull = require("pull-stream");
22 var Ansuz = require("ansuz");
33 var Query = require("./query");
44 var Dump = require("./dump");
5 +var Format = require("./format");
56 var Net = require("net");
67 var Pad = require("pad-ipv6");
78
89 var Server = module.exports = {};
@@ -47,10 +48,10 @@
4748 res.responseCode = 3; // NXDOMAIN
4849 }
4950 }
5051 if (opt && opt.verbose) {
51- var recs = records.map(Dump.recordToLine).join(", ")
52- var auths = authorities.map(Dump.recordToLine).join(", ")
52 + var recs = records.map(Format.recordToLine).join(", ")
53 + var auths = authorities.map(Format.recordToLine).join(", ")
5354 console.log("%s: %s%s", q.name, recs,
5455 auths ? '. auths: ' : '', auths);
5556 }
5657 res.answer = result.answers;
lib/format.jsView
@@ -1,0 +1,81 @@
1 +var Format = module.exports = {};
2 +var Pull = require("pull-stream");
3 +
4 +function pad(str, len) {
5 + if (Math.abs(len) < String(str).length) return str;
6 + if (len < 0) return (' ' + str).substr(len);
7 + if (len > 0) return (str + ' ').substr(0, len);
8 +}
9 +
10 +Format.formatNames = function (name) {
11 + if (!name) {
12 + // make record name absolute
13 + return function (record) {
14 + record.name = record.name.replace(/\.?$/, '.');
15 + };
16 + }
17 + // make records' names be relative to some domain
18 + if (/[^a-z0-9\-.]/.test(name)) {
19 + throw new TypeError('name has bad characters');
20 + }
21 + var nameRegexp = new RegExp('(?:^|\\.)' + name.replace(/\./g, '\\.') + '$');
22 + return function (record) {
23 + record.name = record.name.replace(nameRegexp, '') || '@';
24 + };
25 +};
26 +
27 +Format.getMaxLengths = function (records) {
28 + var maxLengths = {};
29 + records.forEach(function (record) {
30 + for (var k in record) {
31 + var len = String(record[k]).length
32 + if (len > ~~maxLengths[k]) maxLengths[k] = len;
33 + }
34 + });
35 + return maxLengths;
36 +};
37 +
38 +Format.recordsToLines = function (maxLengths) {
39 + return function (record) {
40 + return [
41 + record.id,
42 + pad(record.authorName, 12),
43 + pad(record.name, -maxLengths.name),
44 + pad(record.ttl, -maxLengths.ttl),
45 + pad(record.class, maxLengths.class),
46 + pad(record.type, maxLengths.type),
47 + dataToString(record, record.data)
48 + ].join(' ');
49 + };
50 +};
51 +
52 +function dataToString(record, data) {
53 + switch (record.class + " " + record.type) {
54 + case "IN A":
55 + case "IN AAAA":
56 + case "IN NS":
57 + case "IN PTR":
58 + case "IN CNAME":
59 + return data;
60 + case "IN MX":
61 + return [].concat(data).join(" ");
62 + case "IN SOA":
63 + return [data.mname, data.rname, data.serial,
64 + data.refresh, data.retry, data.expire, data.ttl].join(" ");
65 + case "IN TXT":
66 + case "IN SPF":
67 + return [].concat(data).join("");
68 + case "IN SRV":
69 + return [data.priority, data.weight, data.port,
70 + data.target].join(" ");
71 + case "IN DS":
72 + return [data.key_tag, data.algorithm, data.digest_type,
73 + data.digest].join(" ");
74 + case "IN SSHFP":
75 + return [data.algorithm, data.fp_type, data.fingerprint].join(" ");
76 + case "NONE A":
77 + return "";
78 + default:
79 + return JSON.stringify(record.data);
80 + }
81 +}
package.jsonView
@@ -10,12 +10,16 @@
1010 "scripts": {
1111 "test": "echo \"Error: no test specified\" && exit 1"
1212 },
1313 "dependencies": {
14 + "asyncmemo": "^0.1.0",
1415 "ansuz": "0.0.14",
1516 "modern-dnsd": "^0.9.9",
1617 "kvset": "1.0.0",
1718 "pad-ipv6": "^1.0.2",
19 + "pull-paramap": "^1.1.6",
20 + "pull-stream": "^3.4.5",
21 + "ssb-avatar": "^0.2.0",
1822 "ssb-client": "^4.0.2",
1923 "ssb-ref": "^2.6.2"
2024 },
2125 "keywords": [

Built with git-ssb-web