Commit c77b37a319fc698a43cdde6568d83d251a31753b
Factor out recursive CNAME lookups
Prevent infinite recursion using a stack argumentcel committed on 11/26/2016, 5:42:33 PM
Parent: c384b4a399e23b0210261e731e0ca78d6c84983f
Files changed
lib/query.js | changed |
lib/query.js | ||
---|---|---|
@@ -173,8 +173,60 @@ | ||
173 | 173 … | }); |
174 | 174 … | }; |
175 | 175 … | |
176 | 176 … | 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) { | |
177 | 229 … | // look up records that match a question, including wildcard records |
178 | 230 … | // and zone authority records |
179 | 231 … | var authorityDomains = expandName(question.name); |
180 | 232 … | var wildcardDomains = expandName(question.name, '*'); |
@@ -230,30 +282,7 @@ | ||
230 | 282 … | } |
231 | 283 … | }); |
232 | 284 … | result.expires = Date.now() + ttl * 60e3; |
233 | 285 … | 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 | - } | |
257 | 286 … | cb(null, result); |
258 | 287 … | })); |
259 | 288 … | }; |
Built with git-ssb-web