Skip to content
This repository has been archived by the owner on Feb 12, 2024. It is now read-only.

Commit

Permalink
feat: support _dnslink subdomain specified dnslinks (#1843)
Browse files Browse the repository at this point in the history
  • Loading branch information
chancehudson authored and Alan Shaw committed Jan 24, 2019
1 parent 2df45d7 commit a17253e
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 11 deletions.
52 changes: 41 additions & 11 deletions src/core/runtime/dns-nodejs.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,51 @@
'use strict'

const dns = require('dns')
const _ = require('lodash')
const errcode = require('err-code')

module.exports = (domain, opts, callback) => {
dns.resolveTxt(domain, (err, records) => {
if (err) {
return callback(err, null)
}
resolveDnslink(domain)
.catch(err => {
// If the code is not ENOTFOUND or ERR_DNSLINK_NOT_FOUND then throw the error
if (err.code !== 'ENOTFOUND' && err.code !== 'ERR_DNSLINK_NOT_FOUND') throw err

// TODO: implement recursive option

for (const record of records) {
if (record[0].startsWith('dnslink=')) {
return callback(null, record[0].substr(8, record[0].length - 1))
if (domain.startsWith('_dnslink.')) {
// The supplied domain contains a _dnslink component
// Check the non-_dnslink domain
const rootDomain = domain.replace('_dnslink.', '')
return resolveDnslink(rootDomain)
}
}
// Check the _dnslink subdomain
const _dnslinkDomain = `_dnslink.${domain}`
// If this throws then we propagate the error
return resolveDnslink(_dnslinkDomain)
})
.then(dnslinkRecord => {
callback(null, dnslinkRecord.replace('dnslink=', ''))
})
.catch(callback)
}

callback(new Error('domain does not have a txt dnslink entry'))
function resolveDnslink (domain) {
const DNSLINK_REGEX = /^dnslink=.+$/
return new Promise((resolve, reject) => {
dns.resolveTxt(domain, (err, records) => {
if (err) return reject(err)
resolve(records)
})
})
.then(records => {
return _.chain(records).flatten().filter(record => {
return DNSLINK_REGEX.test(record)
}).value()
})
.then(dnslinkRecords => {
// we now have dns text entries as an array of strings
// only records passing the DNSLINK_REGEX text are included
if (dnslinkRecords.length === 0) {
throw errcode(`No dnslink records found for domain: ${domain}`, 'ERR_DNSLINK_NOT_FOUND')
}
return dnslinkRecords[0]
})
}
8 changes: 8 additions & 0 deletions test/cli/dns.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,12 @@ describe('dns', () => runOnAndOff((thing) => {
expect(res.substr(0, 6)).to.eql('/ipns/')
})
})

it('resolve _dnslink.ipfs.io dns', function () {
this.timeout(60 * 1000)

return ipfs('dns _dnslink.ipfs.io').then((res) => {
expect(res.substr(0, 6)).to.eql('/ipns/')
})
})
}))

0 comments on commit a17253e

Please sign in to comment.