lib/query.jsView |
---|
154 | 154 … | } |
155 | 155 … | return []; |
156 | 156 … | }; |
157 | 157 … | |
| 158 … | +Wildcards.prototype.getTopRecords = function () { |
| 159 … | + |
| 160 … | + if (this.lengths.length) { |
| 161 … | + var len = Math.min.apply(Math, this.lengths); |
| 162 … | + return this.recordsByLength[len] || []; |
| 163 … | + } |
| 164 … | + return []; |
| 165 … | +}; |
| 166 … | + |
158 | 167 … | function ZoneSerials() { |
159 | 168 … | this.serials = {}; |
160 | 169 … | } |
161 | 170 … | |
199 | 208 … | |
200 | 209 … | var nonRecurseTypes = { |
201 | 210 … | CNAME: true, |
202 | 211 … | AXFR: true, |
| 212 … | + IXFR: true, |
203 | 213 … | }; |
204 | 214 … | |
205 | 215 … | Query.query = function (sbot, question, cb) { |
206 | 216 … | if (nonRecurseTypes[question.type]) { |
259 | 269 … | |
260 | 270 … | |
261 | 271 … | var authorityDomains = expandName(question.name); |
262 | 272 … | var wildcardDomains = expandName(question.name, '*'); |
263 | | - var isTransfer = question.type === 'AXFR' |
| 273 … | + var isIncrementalTransfer = question.type === 'IXFR' |
| 274 … | + var isTransfer = isIncrementalTransfer || question.type === 'AXFR' |
| 275 … | + |
264 | 276 … | var authorities = new Wildcards(); |
265 | 277 … | var answers = isTransfer ? new Records() : new Wildcards(); |
266 | 278 … | var zoneSerials = new ZoneSerials(); |
267 | 279 … | var result = { |
270 | 282 … | Pull(Query.all(sbot), |
271 | 283 … | Pull.filter(function (record) { |
272 | 284 … | var recordDomains = expandName(record.name); |
273 | 285 … | zoneSerials.addRecord(recordDomains); |
274 | | - var nameMatches = isTransfer |
275 | | - ? question.name in recordDomains |
276 | | - : record.name in wildcardDomains; |
| 286 … | + if (isIncrementalTransfer |
| 287 … | + && zoneSerials.getSerial(question.name) < question.serial) { |
| 288 … | + return false |
| 289 … | + } |
| 290 … | + var nameMatches = isTransfer ? question.name in recordDomains : |
| 291 … | + record.type === 'SOA' ? record.name in authorityDomains : |
| 292 … | + record.name in wildcardDomains; |
277 | 293 … | if (nameMatches) { |
278 | 294 … | result.domainExists = true; |
279 | 295 … | } |
280 | | - if (record.type === 'SOA') { |
281 | | - return record.name in authorityDomains; |
282 | | - } |
283 | 296 … | return nameMatches |
284 | 297 … | && (isTransfer |
285 | 298 … | || question.type === record.type |
286 | 299 … | || question.type === '*' |
310 | 323 … | result.answers = answers.getRecords(); |
311 | 324 … | result.answers.forEach(function (record) { |
312 | 325 … | if (record.ttl < ttl) ttl = record.ttl; |
313 | 326 … | }); |
314 | | - result.authorities = authorities.getRecords(); |
| 327 … | + result.authorities = isTransfer |
| 328 … | + ? authorities.getTopRecords() |
| 329 … | + : authorities.getRecords(); |
315 | 330 … | result.authorities.forEach(function (auth) { |
316 | 331 … | if (!auth.data.serial) { |
317 | 332 … | |
318 | 333 … | auth.data.serial = zoneSerials.getSerial(auth.name); |
330 | 345 … | |
331 | 346 … | result.questions.push(question); |
332 | 347 … | |
333 | 348 … | var soa = result.authorities.splice(0)[0]; |
334 | | - result.answers = [soa].concat(result.answers.filter(function (r) { |
335 | | - return r !== soa; |
336 | | - }), [soa]); |
| 349 … | + if (soa) { |
| 350 … | + result.answers = [soa].concat( |
| 351 … | + result.answers.filter(function (r) { return r !== soa; }), |
| 352 … | + [soa] |
| 353 … | + ); |
| 354 … | + } |
337 | 355 … | } |
338 | 356 … | cb(null, result); |
339 | 357 … | })); |
340 | 358 … | }; |