Index: frontend/node_modules/multicast-dns/.travis.yml
===================================================================
--- frontend/node_modules/multicast-dns/.travis.yml	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/multicast-dns/.travis.yml	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,6 @@
+language: node_js
+node_js:
+  - "6"
+  - "8"
+  - "9"
+  - "node"
Index: frontend/node_modules/multicast-dns/LICENSE
===================================================================
--- frontend/node_modules/multicast-dns/LICENSE	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/multicast-dns/LICENSE	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2015 Mathias Buus
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
Index: frontend/node_modules/multicast-dns/README.md
===================================================================
--- frontend/node_modules/multicast-dns/README.md	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/multicast-dns/README.md	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,210 @@
+# multicast-dns
+
+Low level multicast-dns implementation in pure javascript
+
+```
+npm install multicast-dns
+```
+
+[![build status](http://img.shields.io/travis/mafintosh/multicast-dns.svg?style=flat)](http://travis-ci.org/mafintosh/multicast-dns)
+
+## Usage
+
+``` js
+var mdns = require('multicast-dns')()
+
+mdns.on('response', function(response) {
+  console.log('got a response packet:', response)
+})
+
+mdns.on('query', function(query) {
+  console.log('got a query packet:', query)
+})
+
+// lets query for an A record for 'brunhilde.local'
+mdns.query({
+  questions:[{
+    name: 'brunhilde.local',
+    type: 'A'
+  }]
+})
+```
+
+Running the above (change `brunhilde.local` to `your-own-hostname.local`) will print an echo of the query packet first
+
+``` js
+got a query packet: { type: 'query',
+  questions: [ { name: 'brunhilde.local', type: 'A', class: 1 } ],
+  answers: [],
+  authorities: [],
+  additionals: [] }
+```
+
+And then a response packet
+
+``` js
+got a response packet: { type: 'response',
+  questions: [],
+  answers:
+   [ { name: 'brunhilde.local',
+       type: 'A',
+       class: 'IN',
+       ttl: 120,
+       flush: true,
+       data: '192.168.1.5' } ],
+  authorities: [],
+  additionals:
+   [ { name: 'brunhilde.local',
+       type: 'A',
+       class: 'IN',
+       ttl: 120,
+       flush: true,
+       data: '192.168.1.5' },
+     { name: 'brunhilde.local',
+       type: 'AAAA',
+       class: 'IN',
+       ttl: 120,
+       flush: true,
+       data: 'fe80::5ef9:38ff:fe8c:ceaa' } ] }
+```
+
+
+# CLI
+
+```
+npm install -g multicast-dns
+```
+
+```
+multicast-dns brunhilde.local
+> 192.168.1.1
+```
+
+# API
+
+A packet has the following format
+
+``` js
+{
+  questions: [{
+    name: 'brunhilde.local',
+    type: 'A'
+  }],
+  answers: [{
+    name: 'brunhilde.local',
+    type: 'A',
+    ttl: seconds,
+    data: (record type specific data)
+  }],
+  additionals: [
+    (same format as answers)
+  ],
+  authorities: [
+    (same format as answers)
+  ]
+}
+```
+
+Currently data from `SRV`, `A`, `PTR`, `TXT`, `AAAA` and `HINFO` records is passed
+
+#### `mdns = multicastdns([options])`
+
+Creates a new `mdns` instance. Options can contain the following
+
+``` js
+{
+  multicast: true // use udp multicasting
+  interface: '192.168.0.2' // explicitly specify a network interface. defaults to all
+  port: 5353, // set the udp port
+  ip: '224.0.0.251', // set the udp ip
+  ttl: 255, // set the multicast ttl
+  loopback: true, // receive your own packets
+  reuseAddr: true // set the reuseAddr option when creating the socket (requires node >=0.11.13)
+}
+```
+
+#### `mdns.on('query', (packet, rinfo))`
+
+Emitted when a query packet is received.
+
+``` js
+mdns.on('query', function(query) {
+  if (query.questions[0] && query.questions[0].name === 'brunhilde.local') {
+    mdns.respond(someResponse) // see below
+  }
+})
+```
+
+#### `mdns.on('response', (packet, rinfo))`
+
+Emitted when a response packet is received.
+
+The response might not be a response to a query you send as this
+is the result of someone multicasting a response.
+
+#### `mdns.query(packet, [cb])`
+
+Send a dns query. The callback will be called when the packet was sent.
+
+The following shorthands are equivalent
+
+``` js
+mdns.query('brunhilde.local', 'A')
+mdns.query([{name:'brunhilde.local', type:'A'}])
+mdns.query({
+  questions: [{name:'brunhilde.local', type:'A'}]
+})
+```
+
+#### `mdns.respond(packet, [cb])`
+
+Send a dns response. The callback will be called when the packet was sent.
+
+``` js
+// reply with a SRV and a A record as an answer
+mdns.respond({
+  answers: [{
+    name: 'my-service',
+    type: 'SRV',
+    data: {
+      port: 9999,
+      weight: 0,
+      priority: 10,
+      target: 'my-service.example.com'
+    }
+  }, {
+    name: 'brunhilde.local',
+    type: 'A',
+    ttl: 300,
+    data: '192.168.1.5'
+  }]
+})
+```
+
+The following shorthands are equivalent
+
+``` js
+mdns.respond([{name:'brunhilde.local', type:'A', data:'192.158.1.5'}])
+mdns.respond({
+  answers: [{name:'brunhilde.local', type:'A', data:'192.158.1.5'}]
+})
+```
+
+#### `mdns.destroy()`
+
+Destroy the mdns instance. Closes the udp socket.
+
+# Development
+
+To start hacking on this module you can use this example to get started
+
+```
+git clone git://github.com/mafintosh/multicast-dns.git
+npm install
+node example.js
+node cli.js $(hostname).local
+```
+
+## License
+
+MIT
Index: frontend/node_modules/multicast-dns/appveyor.yml
===================================================================
--- frontend/node_modules/multicast-dns/appveyor.yml	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/multicast-dns/appveyor.yml	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,30 @@
+environment:
+  matrix:
+    - nodejs_version: 10
+    - nodejs_version: 9
+    - nodejs_version: 8
+    - nodejs_version: 6
+
+platform:
+  - x64
+
+test_script:
+  - node --version
+  - yarn --version
+  - npm test
+
+install:
+  - ps: Install-Product node $env:nodejs_version x64
+  - set CI=true
+  - npm install
+
+matrix:
+  fast_finish: true
+
+build: off
+
+version: '{build}'
+
+shallow_clone: true
+
+clone_depth: 1
Index: frontend/node_modules/multicast-dns/cli.js
===================================================================
--- frontend/node_modules/multicast-dns/cli.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/multicast-dns/cli.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,64 @@
+#!/usr/bin/env node
+
+var mdns = require('./')()
+var path = require('path')
+var os = require('os')
+
+var announcing = process.argv.indexOf('--announce') > -1
+
+if (process.argv.length < 3) {
+  console.error('Usage: %s <hostname>', path.basename(process.argv[1]))
+  process.exit(1)
+}
+var hostname = process.argv[2]
+
+if (announcing) {
+  var ip = getIp()
+  mdns.on('query', function (query, rinfo) {
+    query.questions.forEach(function (q) {
+      if (q.name === hostname) {
+        console.log('Responding %s -> %s', q.name, ip)
+        mdns.respond({
+          answers: [{
+            type: 'A',
+            name: q.name,
+            data: ip
+          }]
+        }, {port: rinfo.port})
+      }
+    })
+  })
+} else {
+  mdns.on('response', function (response) {
+    response.answers.forEach(function (answer) {
+      if (answer.name === hostname) {
+        console.log(answer.data)
+        process.exit()
+      }
+    })
+  })
+
+  mdns.query(hostname, 'A')
+
+  // Give responses 3 seconds to respond
+  setTimeout(function () {
+    console.error('Hostname not found')
+    process.exit(1)
+  }, 3000)
+}
+
+function getIp () {
+  var networks = os.networkInterfaces()
+  var found = '127.0.0.1'
+
+  Object.keys(networks).forEach(function (k) {
+    var n = networks[k]
+    n.forEach(function (addr) {
+      if (addr.family === 'IPv4' && !addr.internal) {
+        found = addr.address
+      }
+    })
+  })
+
+  return found
+}
Index: frontend/node_modules/multicast-dns/example.js
===================================================================
--- frontend/node_modules/multicast-dns/example.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/multicast-dns/example.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,36 @@
+var mdns = require('./')()
+
+mdns.on('warning', function (err) {
+  console.log(err.stack)
+})
+
+mdns.on('response', function (response) {
+  console.log('got a response packet:', response)
+})
+
+mdns.on('query', function (query) {
+  console.log('got a query packet:', query)
+
+  // iterate over all questions to check if we should respond
+  query.questions.forEach(function (q) {
+    if (q.type === 'A' && q.name === 'example.local') {
+      // send an A-record response for example.local
+      mdns.respond({
+        answers: [{
+          name: 'example.local',
+          type: 'A',
+          ttl: 300,
+          data: '192.168.1.5'
+        }]
+      })
+    }
+  })
+})
+
+// lets query for an A-record for example.local
+mdns.query({
+  questions: [{
+    name: 'example.local',
+    type: 'A'
+  }]
+})
Index: frontend/node_modules/multicast-dns/index.js
===================================================================
--- frontend/node_modules/multicast-dns/index.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/multicast-dns/index.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,205 @@
+var packet = require('dns-packet')
+var dgram = require('dgram')
+var thunky = require('thunky')
+var events = require('events')
+var os = require('os')
+
+var noop = function () {}
+
+module.exports = function (opts) {
+  if (!opts) opts = {}
+
+  var that = new events.EventEmitter()
+  var port = typeof opts.port === 'number' ? opts.port : 5353
+  var type = opts.type || 'udp4'
+  var ip = opts.ip || opts.host || (type === 'udp4' ? '224.0.0.251' : null)
+  var me = {address: ip, port: port}
+  var memberships = {}
+  var destroyed = false
+  var interval = null
+
+  if (type === 'udp6' && (!ip || !opts.interface)) {
+    throw new Error('For IPv6 multicast you must specify `ip` and `interface`')
+  }
+
+  var socket = opts.socket || dgram.createSocket({
+    type: type,
+    reuseAddr: opts.reuseAddr !== false,
+    toString: function () {
+      return type
+    }
+  })
+
+  socket.on('error', function (err) {
+    if (err.code === 'EACCES' || err.code === 'EADDRINUSE') that.emit('error', err)
+    else that.emit('warning', err)
+  })
+
+  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('listening', function () {
+    if (!port) port = me.port = socket.address().port
+    if (opts.multicast !== false) {
+      that.update()
+      interval = setInterval(that.update, 5000)
+      socket.setMulticastTTL(opts.ttl || 255)
+      socket.setMulticastLoopback(opts.loopback !== false)
+    }
+  })
+
+  var bind = thunky(function (cb) {
+    if (!port || opts.bind === false) return cb(null)
+    socket.once('error', cb)
+    socket.bind(port, opts.bind || opts.interface, function () {
+      socket.removeListener('error', cb)
+      cb(null)
+    })
+  })
+
+  bind(function (err) {
+    if (err) return that.emit('error', err)
+    that.emit('ready')
+  })
+
+  that.send = function (value, rinfo, cb) {
+    if (typeof rinfo === 'function') return that.send(value, null, rinfo)
+    if (!cb) cb = noop
+    if (!rinfo) rinfo = me
+    else if (!rinfo.host && !rinfo.address) rinfo.address = me.address
+
+    bind(onbind)
+
+    function onbind (err) {
+      if (destroyed) return cb()
+      if (err) return cb(err)
+      var message = packet.encode(value)
+      socket.send(message, 0, message.length, rinfo.port, rinfo.address || rinfo.host, cb)
+    }
+  }
+
+  that.response =
+  that.respond = function (res, rinfo, cb) {
+    if (Array.isArray(res)) res = {answers: res}
+
+    res.type = 'response'
+    res.flags = (res.flags || 0) | packet.AUTHORITATIVE_ANSWER
+    that.send(res, rinfo, cb)
+  }
+
+  that.query = function (q, type, rinfo, cb) {
+    if (typeof type === 'function') return that.query(q, null, null, type)
+    if (typeof type === 'object' && type && type.port) return that.query(q, null, type, rinfo)
+    if (typeof rinfo === 'function') return that.query(q, type, null, rinfo)
+    if (!cb) cb = noop
+
+    if (typeof q === 'string') q = [{name: q, type: type || 'ANY'}]
+    if (Array.isArray(q)) q = {type: 'query', questions: q}
+
+    q.type = 'query'
+    that.send(q, rinfo, cb)
+  }
+
+  that.destroy = function (cb) {
+    if (!cb) cb = noop
+    if (destroyed) return process.nextTick(cb)
+    destroyed = true
+    clearInterval(interval)
+
+    // Need to drop memberships by hand and ignore errors.
+    // socket.close() does not cope with errors.
+    for (var iface in memberships) {
+      try {
+        socket.dropMembership(ip, iface)
+      } catch (e) {
+        // eat it
+      }
+    }
+    memberships = {}
+    socket.close(cb)
+  }
+
+  that.update = function () {
+    var ifaces = opts.interface ? [].concat(opts.interface) : allInterfaces()
+    var updated = false
+
+    for (var i = 0; i < ifaces.length; i++) {
+      var addr = ifaces[i]
+      if (memberships[addr]) continue
+
+      try {
+        socket.addMembership(ip, addr)
+        memberships[addr] = true
+        updated = true
+      } catch (err) {
+        that.emit('warning', err)
+      }
+    }
+
+    if (updated) {
+      if (socket.setMulticastInterface) {
+        try {
+          socket.setMulticastInterface(opts.interface || defaultInterface())
+        } catch (err) {
+          that.emit('warning', err)
+        }
+      }
+      that.emit('networkInterface')
+    }
+  }
+
+  return that
+}
+
+function defaultInterface () {
+  var networks = os.networkInterfaces()
+  var names = Object.keys(networks)
+
+  for (var i = 0; i < names.length; i++) {
+    var net = networks[names[i]]
+    for (var j = 0; j < net.length; j++) {
+      var iface = net[j]
+      if (isIPv4(iface.family) && !iface.internal) {
+        if (os.platform() === 'darwin' && names[i] === 'en0') return iface.address
+        return '0.0.0.0'
+      }
+    }
+  }
+
+  return '127.0.0.1'
+}
+
+function allInterfaces () {
+  var networks = os.networkInterfaces()
+  var names = Object.keys(networks)
+  var res = []
+
+  for (var i = 0; i < names.length; i++) {
+    var net = networks[names[i]]
+    for (var j = 0; j < net.length; j++) {
+      var iface = net[j]
+      if (isIPv4(iface.family)) {
+        res.push(iface.address)
+        // could only addMembership once per interface (https://nodejs.org/api/dgram.html#dgram_socket_addmembership_multicastaddress_multicastinterface)
+        break
+      }
+    }
+  }
+
+  return res
+}
+
+function isIPv4 (family) { // for backwards compat
+  return family === 4 || family === 'IPv4'
+}
Index: frontend/node_modules/multicast-dns/package.json
===================================================================
--- frontend/node_modules/multicast-dns/package.json	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/multicast-dns/package.json	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,43 @@
+{
+  "name": "multicast-dns",
+  "version": "7.2.5",
+  "description": "Low level multicast-dns implementation in pure javascript",
+  "main": "index.js",
+  "scripts": {
+    "test": "standard && tape test.js"
+  },
+  "bin": "cli.js",
+  "dependencies": {
+    "dns-packet": "^5.2.2",
+    "thunky": "^1.0.2"
+  },
+  "devDependencies": {
+    "standard": "^11.0.1",
+    "tape": "^4.8.0"
+  },
+  "repository": {
+    "type": "git",
+    "url": "https://github.com/mafintosh/multicast-dns.git"
+  },
+  "author": "Mathias Buus (@mafintosh)",
+  "license": "MIT",
+  "bugs": {
+    "url": "https://github.com/mafintosh/multicast-dns/issues"
+  },
+  "homepage": "https://github.com/mafintosh/multicast-dns",
+  "keywords": [
+    "multicast",
+    "dns",
+    "mdns",
+    "multicastdns",
+    "dns-sd",
+    "service",
+    "discovery",
+    "bonjour",
+    "avahi"
+  ],
+  "coordinates": [
+    55.6465878,
+    12.5492251
+  ]
+}
Index: frontend/node_modules/multicast-dns/test.js
===================================================================
--- frontend/node_modules/multicast-dns/test.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/multicast-dns/test.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,260 @@
+var mdns = require('./')
+var tape = require('tape')
+var dgram = require('dgram')
+
+var port = function (cb) {
+  var s = dgram.createSocket('udp4')
+  s.bind(0, function () {
+    var port = s.address().port
+    s.on('close', function () {
+      cb(port)
+    })
+    s.close()
+  })
+}
+
+var configs = [
+  {ip: '127.0.0.1', multicast: false}
+  // {'interface': '127.0.0.1', multicast: true}
+]
+
+var tests = configs.map(function (config) {
+  return function (name, fn) {
+    tape(name, function (t) {
+      port(function (p) {
+        config.port = p
+        var dns = mdns(config)
+        dns.on('warning', function (e) {
+          t.error(e)
+        })
+        fn(dns, t)
+      })
+    })
+  }
+})
+
+tests.forEach(function (test) {
+  test('works', function (dns, t) {
+    t.plan(3)
+
+    dns.once('query', function (packet) {
+      t.same(packet.type, 'query')
+      dns.destroy(function () {
+        t.ok(true, 'destroys')
+      })
+    })
+
+    dns.query('hello-world', function () {
+      t.ok(true, 'flushed')
+    })
+  })
+
+  test('ANY query', function (dns, t) {
+    dns.once('query', function (packet) {
+      t.same(packet.questions.length, 1, 'one question')
+      t.same(packet.questions[0], {name: 'hello-world', type: 'ANY', class: 'IN'})
+      dns.destroy(function () {
+        t.end()
+      })
+    })
+
+    dns.query('hello-world', 'ANY')
+  })
+
+  test('A record', function (dns, t) {
+    dns.once('query', function (packet) {
+      t.same(packet.questions.length, 1, 'one question')
+      t.same(packet.questions[0], {name: 'hello-world', type: 'A', class: 'IN'})
+      dns.respond([{type: 'A', name: 'hello-world', ttl: 120, data: '127.0.0.1'}])
+    })
+
+    dns.once('response', function (packet) {
+      t.same(packet.answers.length, 1, 'one answer')
+      t.same(packet.answers[0], {type: 'A', name: 'hello-world', ttl: 120, data: '127.0.0.1', class: 'IN', flush: false})
+      dns.destroy(function () {
+        t.end()
+      })
+    })
+
+    dns.query('hello-world', 'A')
+  })
+
+  test('A record (two questions)', function (dns, t) {
+    dns.once('query', function (packet) {
+      t.same(packet.questions.length, 2, 'two questions')
+      t.same(packet.questions[0], {name: 'hello-world', type: 'A', class: 'IN'})
+      t.same(packet.questions[1], {name: 'hej.verden', type: 'A', class: 'IN'})
+      dns.respond([{type: 'A', name: 'hello-world', ttl: 120, data: '127.0.0.1'}, {
+        type: 'A',
+        name: 'hej.verden',
+        ttl: 120,
+        data: '127.0.0.2'
+      }])
+    })
+
+    dns.once('response', function (packet) {
+      t.same(packet.answers.length, 2, 'one answers')
+      t.same(packet.answers[0], {type: 'A', name: 'hello-world', ttl: 120, data: '127.0.0.1', class: 'IN', flush: false})
+      t.same(packet.answers[1], {type: 'A', name: 'hej.verden', ttl: 120, data: '127.0.0.2', class: 'IN', flush: false})
+      dns.destroy(function () {
+        t.end()
+      })
+    })
+
+    dns.query([{name: 'hello-world', type: 'A'}, {name: 'hej.verden', type: 'A'}])
+  })
+
+  test('AAAA record', function (dns, t) {
+    dns.once('query', function (packet) {
+      t.same(packet.questions.length, 1, 'one question')
+      t.same(packet.questions[0], {name: 'hello-world', type: 'AAAA', class: 'IN'})
+      dns.respond([{type: 'AAAA', name: 'hello-world', ttl: 120, data: 'fe80::5ef9:38ff:fe8c:ceaa'}])
+    })
+
+    dns.once('response', function (packet) {
+      t.same(packet.answers.length, 1, 'one answer')
+      t.same(packet.answers[0], {
+        type: 'AAAA',
+        name: 'hello-world',
+        ttl: 120,
+        data: 'fe80::5ef9:38ff:fe8c:ceaa',
+        class: 'IN',
+        flush: false
+      })
+      dns.destroy(function () {
+        t.end()
+      })
+    })
+
+    dns.query('hello-world', 'AAAA')
+  })
+
+  test('SRV record', function (dns, t) {
+    dns.once('query', function (packet) {
+      t.same(packet.questions.length, 1, 'one question')
+      t.same(packet.questions[0], {name: 'hello-world', type: 'SRV', class: 'IN'})
+      dns.respond([{
+        type: 'SRV',
+        name: 'hello-world',
+        ttl: 120,
+        data: {port: 11111, target: 'hello.world.com', priority: 10, weight: 12}
+      }])
+    })
+
+    dns.once('response', function (packet) {
+      t.same(packet.answers.length, 1, 'one answer')
+      t.same(packet.answers[0], {
+        type: 'SRV',
+        name: 'hello-world',
+        ttl: 120,
+        data: {port: 11111, target: 'hello.world.com', priority: 10, weight: 12},
+        class: 'IN',
+        flush: false
+      })
+      dns.destroy(function () {
+        t.end()
+      })
+    })
+
+    dns.query('hello-world', 'SRV')
+  })
+
+  test('TXT record', function (dns, t) {
+    var data = [Buffer.from('black box')]
+
+    dns.once('query', function (packet) {
+      t.same(packet.questions.length, 1, 'one question')
+      t.same(packet.questions[0], {name: 'hello-world', type: 'TXT', class: 'IN'})
+      dns.respond([{type: 'TXT', name: 'hello-world', ttl: 120, data: data}])
+    })
+
+    dns.once('response', function (packet) {
+      t.same(packet.answers.length, 1, 'one answer')
+      t.same(packet.answers[0], {type: 'TXT', name: 'hello-world', ttl: 120, data: data, class: 'IN', flush: false})
+      dns.destroy(function () {
+        t.end()
+      })
+    })
+
+    dns.query('hello-world', 'TXT')
+  })
+
+  test('TXT array record', function (dns, t) {
+    var data = ['black', 'box']
+
+    dns.once('query', function (packet) {
+      t.same(packet.questions.length, 1, 'one question')
+      t.same(packet.questions[0], {name: 'hello-world', type: 'TXT', class: 'IN'})
+      dns.respond([{type: 'TXT', name: 'hello-world', ttl: 120, data: data}])
+    })
+
+    dns.once('response', function (packet) {
+      t.same(packet.answers.length, 1, 'one answer')
+      t.same(packet.answers[0], {type: 'TXT', name: 'hello-world', ttl: 120, data: data, class: 'IN', flush: false})
+      dns.destroy(function () {
+        t.end()
+      })
+    })
+
+    dns.query('hello-world', 'TXT')
+  })
+
+  test('QU question bit', function (dns, t) {
+    dns.once('query', function (packet) {
+      t.same(packet.questions, [
+        {type: 'A', name: 'foo', class: 'IN'},
+        {type: 'A', name: 'bar', class: 'IN'}
+      ])
+      dns.destroy(function () {
+        t.end()
+      })
+    })
+
+    dns.query([
+      {type: 'A', name: 'foo', class: 'IN'},
+      {type: 'A', name: 'bar', class: 'IN'}
+    ])
+  })
+
+  test('cache flush bit', function (dns, t) {
+    dns.once('query', function (packet) {
+      dns.respond({
+        answers: [
+          {type: 'A', name: 'foo', ttl: 120, data: '127.0.0.1', class: 'IN', flush: true},
+          {type: 'A', name: 'foo', ttl: 120, data: '127.0.0.2', class: 'IN', flush: false}
+        ],
+        additionals: [
+          {type: 'A', name: 'foo', ttl: 120, data: '127.0.0.3', class: 'IN', flush: true}
+        ]
+      })
+    })
+
+    dns.once('response', function (packet) {
+      t.same(packet.answers, [
+        {type: 'A', name: 'foo', ttl: 120, data: '127.0.0.1', class: 'IN', flush: true},
+        {type: 'A', name: 'foo', ttl: 120, data: '127.0.0.2', class: 'IN', flush: false}
+      ])
+      t.same(packet.additionals[0], {type: 'A', name: 'foo', ttl: 120, data: '127.0.0.3', class: 'IN', flush: true})
+      dns.destroy(function () {
+        t.end()
+      })
+    })
+
+    dns.query('foo', 'A')
+  })
+
+  test('Authoritive Answer bit', function (dns, t) {
+    dns.once('query', function (packet) {
+      dns.respond([])
+    })
+
+    dns.once('response', function (packet) {
+      t.ok(packet.flag_aa, 'should be set')
+      dns.destroy(function () {
+        t.end()
+      })
+    })
+
+    dns.query('foo', 'A')
+  })
+})
