Skip to content

Commit

Permalink
Add wildcard search support for the find function
Browse files Browse the repository at this point in the history
  • Loading branch information
watson committed Jan 23, 2016
1 parent aea960b commit 230f9fe
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 13 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,11 @@ Listen for services advertised on the network. An optional callback can
be provided as the 2nd argument and will be added as an event listener
for the `up` event.

Options are:
Options (all optional):

- `type` (string)
- `subtypes` (array of strings, optional)
- `protocol` (string, optional) - defaults to `tcp`
- `subtypes` (array of strings)
- `protocol` (string) - defaults to `tcp`

#### `var browser = bonjour.findOne(options[, callback])`

Expand Down
54 changes: 44 additions & 10 deletions lib/browser.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ var dnsEqual = require('dns-equal')
var txt = require('mdns-txt')()

var TLD = '.local'
var WILDCARD = '_services._dns-sd._udp' + TLD

module.exports = Browser

Expand All @@ -18,24 +19,36 @@ util.inherits(Browser, EventEmitter)
* The browser listens for services by querying for PTR records of a given
* type, protocol and domain, e.g. _http._tcp.local.
*
* If no type is given, a wild card search is performed.
*
* An internal list of online services is kept which starts out empty. When
* ever a new service is discovered, it's added to the list and an "up" event
* is emitted with that service. When it's discovered that the service is no
* longer available, it is removed from the list and a "down" event is emitted
* with that service.
*/
function Browser (mdns, opts, onup) {
if (!opts.type) throw new Error('Required type not given')
if (typeof opts === 'function') return new Browser(mdns, null, opts)

EventEmitter.call(this)

if (onup) this.on('up', onup)

this._name = serviceName.stringify(opts.type, opts.protocol || 'tcp') + TLD
this._mdns = mdns
this._onresponse = null
this._serviceMap = {}

if (!opts || !opts.type) {
this._name = WILDCARD
this._wildcard = true
} else {
this._name = serviceName.stringify(opts.type, opts.protocol || 'tcp') + TLD
if (opts.name) this._name = opts.name + '.' + this._name
this._wildcard = false
}

this.services = []

if (onup) this.on('up', onup)

this.start()
}

Expand All @@ -44,15 +57,31 @@ Browser.prototype.start = function () {

var self = this

// List of names for the browser to listen for. In a normal search this will
// be the primary name stored on the browser. In case of a wildcard search
// the names will be determined at runtime as responses come in.
var nameMap = {}
if (!this._wildcard) nameMap[this._name] = true

this._onresponse = function (packet) {
goodbyes(self._name, packet).forEach(self._removeService.bind(self))
if (self._wildcard) {
packet.answers.forEach(function (answer) {
if (answer.type !== 'PTR' || answer.name !== self._name || answer.name in nameMap) return
nameMap[answer.data] = true
self._mdns.query(answer.data, 'PTR')
})
}

Object.keys(nameMap).forEach(function (name) {
goodbyes(name, packet).forEach(self._removeService.bind(self))

var matches = buildServicesFor(self._name, packet)
if (matches.length === 0) return
var matches = buildServicesFor(name, packet)
if (matches.length === 0) return

matches.forEach(function (service) {
if (self._serviceMap[service.fqdn]) return
self._addService(service)
matches.forEach(function (service) {
if (self._serviceMap[service.fqdn]) return
self._addService(service)
})
})
}

Expand Down Expand Up @@ -134,6 +163,8 @@ function buildServicesFor (name, packet) {
}
})

if (!service.name) return

records
.filter(function (rr) {
return (rr.type === 'A' || rr.type === 'AAAA') && dnsEqual(rr.name, service.host)
Expand All @@ -144,4 +175,7 @@ function buildServicesFor (name, packet) {

return service
})
.filter(function (rr) {
return !!rr
})
}

0 comments on commit 230f9fe

Please sign in to comment.