git ssb

15+

ansuz / dnssb



Commit c77b37a319fc698a43cdde6568d83d251a31753b

Factor out recursive CNAME lookups

Prevent infinite recursion using a stack argument
cel committed on 11/26/2016, 5:42:33 PM
Parent: c384b4a399e23b0210261e731e0ca78d6c84983f

Files changed

lib/query.jschanged
lib/query.jsView
@@ -173,8 +173,60 @@
173173 });
174174 };
175175
176176 Query.query = function (sbot, question, cb) {
177 + Query.queryRecursive(sbot, question, [], cb)
178 +}
179 +
180 +// recursive query
181 +Query.queryRecursive = function (sbot, question, stack, cb) {
182 + var result = {
183 + answers: [],
184 + authorities: [],
185 + additionals: [],
186 + expires: Date.now() + 60*60e3,
187 + };
188 +
189 + // avoid infinite recursion
190 + if (stack.some(function (q) {
191 + return isRecordEqual(q, question);
192 + })) {
193 + return cb(null, result)
194 + }
195 +
196 + var waiting = 1;
197 + Query.querySingle(sbot, question, next);
198 +
199 + function next(err, res) {
200 + if (err) return waiting = 0, cb(err);
201 +
202 + merge(result.additionals, res.additionals);
203 + merge(result.answers, res.answers);
204 + merge(result.authorities, res.authorities);
205 + if (res.expires < result.expires) result.expires = res.expires;
206 +
207 + // recurse on CNAMEs
208 + if (question.type !== 'CNAME') {
209 + var stack2 = stack.concat(question)
210 + res.answers.filter(function (answer) {
211 + return answer.type === 'CNAME';
212 + }).map(function (record) {
213 + return {
214 + class: question.class,
215 + type: question.type,
216 + name: record.data.replace(/\.$/, '')
217 + }
218 + }).forEach(function (q) {
219 + waiting++
220 + Query.queryRecursive(sbot, q, stack2, next)
221 + });
222 + }
223 +
224 + if (!--waiting) cb(null, result);
225 + }
226 +}
227 +
228 +Query.querySingle = function (sbot, question, cb) {
177229 // look up records that match a question, including wildcard records
178230 // and zone authority records
179231 var authorityDomains = expandName(question.name);
180232 var wildcardDomains = expandName(question.name, '*');
@@ -230,30 +282,7 @@
230282 }
231283 });
232284 result.expires = Date.now() + ttl * 60e3;
233285 result.additionals = [];
234- // resolve cnames with another query
235- if (question.type !== 'CNAME') {
236- var cnames = result.answers.filter(function (answer) {
237- return answer.type === 'CNAME';
238- });
239- var waiting = cnames.length;
240- if (waiting > 0) {
241- return cnames.forEach(function (record) {
242- Query.query(sbot, {
243- class: question.class,
244- type: question.type,
245- name: record.data.replace(/\.$/, '')
246- }, next);
247- })
248- function next(err, res) {
249- if (err) return waiting = 0, cb(err)
250- merge(result.additionals, res.additionals);
251- merge(result.answers, res.answers);
252- merge(result.authorities, res.authorities);
253- if (!--waiting) cb(err, result);
254- }
255- }
256- }
257286 cb(null, result);
258287 }));
259288 };

Built with git-ssb-web