Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
type: question.type,
class: 'IN',
name: question.name,
data: question.type === 'A' ? '127.0.0.1' : '::1',
ttl: 600
}]
}
} else {
// Update the request packet to do a different host
log('Proxying requested DNS name to: ', conf.proxyDnsTo)
const origName = question.name
requestPacket.questions.forEach(q => q.name = conf.proxyDnsTo)
// Send it off
const proxiedResponse = await deferToDnsFallback(request, dnsPacket.encode(requestPacket).buffer)
// Change any response names back
responsePacket = dnsPacket.decode(Buffer.from(new Uint8Array(await proxiedResponse.arrayBuffer())))
responsePacket.questions.forEach(q => {
if (q.name === conf.proxyDnsTo) q.name = origName
})
responsePacket.answers.forEach(a => {
if (a.name === conf.proxyDnsTo) a.name = origName
})
}
// Send the response back
const responseBody = dnsPacket.encode(responsePacket).buffer
if (conf.log) logDnsPacket('Response DNS (custom): ', dnsPacket.decode(Buffer.from(new Uint8Array(responseBody))))
return new Response(dnsPacket.encode(responsePacket).buffer, {
status: 200,
headers: { 'Content-Type': 'application/dns-message' }
})
}
const newRequest = new Request(conf.dnsHttpUrlFallback, {
method: request.method,
headers: { 'Content-Type': 'application/dns-message' },
body: requestBody,
})
const response = await fetch(newRequest)
const responseContentType = response.headers.get('content-type')
if (responseContentType !== 'application/dns-message') {
const respText = await response.clone().text()
throw new Error('Got other content type, resp text: ' + respText)
}
// Log the DNS packet before returning
if (conf.log) try {
const responseBody = await response.clone().arrayBuffer()
logDnsPacket('Response DNS (deferred): ', dnsPacket.decode(Buffer.from(new Uint8Array(responseBody))))
} catch (e) { }
return response
}
function dnsErrorServFail (id, query) {
const { questions, flags } = dnsPacket.decode(query)
// http://www.faqs.org/rfcs/rfc2929.html
// 1 1 1 1 1 1
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
// |QR| Opcode |AA|TC|RD|RA| Z|AD|CD| RCODE |
return dnsPacket.encode({
id,
type: 'response',
flags:
(0b0111100000000000 & flags) | // opcode copied from query
(0b0000000100000000 & flags) | // rd copied from query
(0b0000000010000000) | // ra always true
(0b0000000000000010), // rcode always ServFail
questions
async function handleDnsQuery(request: Request) {
// We need to take out the body and parse the DNS packet
const requestBody = await request.arrayBuffer()
const requestPacket = dnsPacket.decode(Buffer.from(new Uint8Array(requestBody)))
logDnsPacket('Request DNS: ', requestPacket)
// We only handle single questions for A and AAAA of the new TLD
const question = (requestPacket.questions && requestPacket.questions.length === 1) ? requestPacket.questions[0] : null
if (question === null ||
(question.type !== 'A' && question.type !== 'AAAA') ||
!question.name.endsWith('.' + conf.newTld)) return deferToDnsFallback(request, requestBody)
log('Responding to query for new TLD')
// If we ask for our TLD on localhost, we'll just send back the fixed local
// IPs. However, if our host is something else, we defer to the fallback and
// just change the answer names so we get SOAs, NSs, As, CNAMEs, etc.
let responsePacket: dnsPacket.Packet
if (conf.proxyDnsTo === 'localhost') {
log('Sending back localhost IPs')
responsePacket = {
socket.on('message', function (message, rinfo) {
try {
message = packet.decode(message)
} catch (err) {
that.emit('warning', err)
return
}
that.emit('packet', message, rinfo)
if (message.type === 'query') that.emit('query', message, rinfo)
if (message.type === 'response') that.emit('response', message, rinfo)
})
socket.on('message', function (message, rinfo) {
try {
message = packet.decode(message)
} catch (err) {
that.emit('warning', err)
return
}
that.emit('packet', message, rinfo)
if (message.type === 'query') that.emit('query', message, rinfo)
if (message.type === 'response') that.emit('response', message, rinfo)
})
stream.on('end', () => {
performance.mark('dns-after')
performance.measure('dns', 'dns-before', 'dns-after')
clearTimeout(timeout)
let packet
try {
packet = dnsPacket.decode(Buffer.concat(chunks))
} catch (error) {
reject(error)
return
}
if (packet.rcode === 'NOERROR' && packet.type === 'response') {
resolve()
} else {
reject(new Error(`Bad DNS message: ${packet.rcode}`))
}
})
})
socket.on('message', async (message, rinfo) => {
logger.info('query received')
const packet = dnsPacket.decode(message)
if (
program.sink &&
packet
.questions
.map(q => blocked[q.name] !== undefined)
.every(h => h)) {
const reply = lie(packet.id)
socket.send(reply, 0, reply.length, rinfo.port, rinfo.address)
return
}
const reply = await fetch(client, pathname, message)
logger.info('reply sent')
socket.send(reply, 0, reply.length, rinfo.port, rinfo.address)
})