Skip to content

Commit

Permalink
first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
bwp91 committed Sep 1, 2024
1 parent 335f614 commit 3062503
Show file tree
Hide file tree
Showing 17 changed files with 4,049 additions and 3,173 deletions.
35 changes: 0 additions & 35 deletions .eslintrc

This file was deleted.

2 changes: 1 addition & 1 deletion .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
github: Supereg
custom: "https://paypal.me/Supereg"
custom: 'https://paypal.me/Supereg'
6 changes: 3 additions & 3 deletions .github/labeler.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# Add 'beta' label to any PR where the base branch name starts with `beta` or has a `beta` section in the name
beta:
- base-branch: ['^beta', 'beta', 'beta*']
- base-branch: [^beta, beta, 'beta*']

# Add 'beta' label to any PR where the base branch name starts with `beta` or has a `beta` section in the name
alpha:
- base-branch: ['^alpha', 'alpha', 'alpha*']
- base-branch: [^alpha, alpha, 'alpha*']

# Add 'latest' label to any PR where the base branch name starts with `latest` or has a `latest` section in the name
latest:
- base-branch: ['^latest', 'latest', 'latest*']
- base-branch: [^latest, latest, 'latest*']
18 changes: 9 additions & 9 deletions .github/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,18 @@ changelog:
categories:
- title: Breaking Changes 🛠
labels:
- 'breaking change'
- breaking change
- title: Featured Changes ✨
labels:
- 'feature'
- 'enhancement'
- feature
- enhancement
- title: Bug Fixes 🐛
labels:
- 'fix'
- 'bugfix'
- 'bug'
- fix
- bugfix
- bug
- title: Other Changes
labels:
- "chore"
- "housekeeping"
- "*"
- chore
- housekeeping
- '*'
6 changes: 3 additions & 3 deletions .github/workflows/alpha-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ jobs:
if: ${{ github.repository == 'homebridge/ciao' }}
uses: homebridge/.github/.github/workflows/npm-publish.yml@latest
with:
tag: 'alpha'
tag: alpha
dynamically_adjust_version: true
npm_version_command: 'pre'
pre_id: 'alpha'
npm_version_command: pre
pre_id: alpha
secrets:
npm_auth_token: ${{ secrets.npm_token }}
6 changes: 3 additions & 3 deletions .github/workflows/beta-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ jobs:

uses: homebridge/.github/.github/workflows/npm-publish.yml@latest
with:
tag: 'beta'
tag: beta
dynamically_adjust_version: true
npm_version_command: 'pre'
pre_id: 'beta'
npm_version_command: pre
pre_id: beta
secrets:
npm_auth_token: ${{ secrets.npm_token }}
6 changes: 3 additions & 3 deletions .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
name: "CodeQL"
name: CodeQL

on:
push:
branches: [ latest, beta* ]
branches: [latest, beta*]
pull_request:
branches: [ latest, beta* ]
branches: [latest, beta*]
schedule:
- cron: '34 14 * * 5'

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/pr-labeler.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ jobs:
stale:
uses: homebridge/.github/.github/workflows/pr-labeler.yml@latest
secrets:
token: ${{ secrets.GITHUB_TOKEN }}
token: ${{ secrets.GITHUB_TOKEN }}
2 changes: 1 addition & 1 deletion .github/workflows/release-drafter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@ jobs:
stale:
uses: homebridge/.github/.github/workflows/release-drafter.yml@latest
secrets:
token: ${{ secrets.GITHUB_TOKEN }}
token: ${{ secrets.GITHUB_TOKEN }}
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
lib/
dist/

# Created by .ignore support plugin (hsz.mobi)
### JetBrains template
Expand Down
96 changes: 48 additions & 48 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@
advertising on multicast dns ([RFC 6762](https://tools.ietf.org/html/rfc6762))
implemented in plain Typescript/JavaScript.

It is used in [HAP-NodeJS](https://github.com/homebridge/HAP-NodeJS) and is the successor of the
[bonjour-hap](https://github.com/homebridge/bonjour) (and [bonjour](https://github.com/watson/bonjour)) library,
It is used in [HAP-NodeJS](https://github.com/homebridge/HAP-NodeJS) and is the successor of the
[bonjour-hap](https://github.com/homebridge/bonjour) (and [bonjour](https://github.com/watson/bonjour)) library,
aiming to be more robust, more maintainable and RFC compliant (read [Notice](https://github.com/homebridge/bonjour#notice)).

`ciao` features a multicast dns responder to publish service on the local network.
It will eventually gain browsing functionality in the future to also discover services on the local network
(There is currently no schedule when discover functionality will arrive.
(There is currently no schedule when discover functionality will arrive.
A possible querier implementation is limited as explained in [RFC 6762 15.1.](https://tools.ietf.org/html/rfc6762#section-15.1)
as it can't receive unicast responses).

Expand All @@ -43,62 +43,61 @@ npm install --save @homebridge/ciao
## Example

```ts
const ciao = require("@homebridge/ciao");
const ciao = require('@homebridge/ciao')

const responder = ciao.getResponder();
const responder = ciao.getResponder()

// create a service defining a web server running on port 3000
const service = responder.createService({
name: 'My Web Server',
type: 'http',
port: 3000, // optional, can also be set via updatePort() before advertising
txt: { // optional
key: "value",
}
name: 'My Web Server',
type: 'http',
port: 3000, // optional, can also be set via updatePort() before advertising
txt: { // optional
key: 'value',
}
})


service.advertise().then(() => {
// stuff you do when the service is published
console.log("Service is published :)");
});
console.log('Service is published :)')
})

// ....

service.updateTxt({ // replaces current txt
newKey: "newValue",
});
newKey: 'newValue',
})

// ....

service.end().then(() => {
// service is now UNANNOUNCED and can be published again
});
})

// ....

// frees the service objects (and calls end() if still announced).
// The service object cannot be used again afterwards.
service.destroy();
service.destroy()
```

## Documentation
## Documentation

The full documentation can be found [here](https://developers.homebridge.io/ciao/modules.html).

### API overview

This section links to the most important aspects of the documentation as used in the example above.

First of all the [getResponder](https://developers.homebridge.io/ciao/functions/getResponder.html) function
First of all the [getResponder](https://developers.homebridge.io/ciao/functions/getResponder.html) function
should be used to get a reference to a [Responder](https://developers.homebridge.io/ciao/classes/Responder.html) object.
The function takes some optional [options](https://developers.homebridge.io/ciao/interfaces/MDNSServerOptions.html)
to configure the underlying mdns server.

The [createService](https://developers.homebridge.io/ciao/classes/Responder.html#createService) method of the `Responder`
object can now be used to create a new [CiaoService](https://developers.homebridge.io/ciao/classes/CiaoService.html)
object can now be used to create a new [CiaoService](https://developers.homebridge.io/ciao/classes/CiaoService.html)
supplying the desired [configuration](https://developers.homebridge.io/ciao/interfaces/ServiceOptions.html)
as the first parameter. You might have a look at the
as the first parameter. You might have a look at the
_[restrictedAddresses](https://developers.homebridge.io/ciao/interfaces/ServiceOptions.html#restrictedAddresses)_
(and _[disabledIpv6](https://developers.homebridge.io/ciao/interfaces/ServiceOptions.html#disabledIpv6)_) configuration
if you don't want to advertise on all available addresses/network interfaces.
Expand All @@ -110,11 +109,11 @@ event, in oder to persist any changes happening to the service name resulting of
The method [updateTxt](https://developers.homebridge.io/ciao/classes/CiaoService.html#updateTxt) can be used
to update the contest of the txt exposed by the service.

Any application SHOULD hook up a listener on events like SIGTERM or SIGINT and call the
Any application SHOULD hook up a listener on events like SIGTERM or SIGINT and call the
[shutdown](https://developers.homebridge.io/ciao/classes/Responder.html#shutdown) method of the responder object.
This will ensure, that goodbye packets are sent out on all connected network interfaces and all hosts
on the network get instantly notified of the shutdown.
Otherwise, stale data will remain in the caches of surrounding mdns browsers.
Otherwise, stale data will remain in the caches of surrounding mdns browsers.

### MTU

Expand All @@ -123,10 +122,10 @@ IP Fragmentation and ensure that all sent packets are smaller than the Maximum T
the network interface. The MTU defaults to 1500 Bytes on pretty much all network cards for Ethernet and Wi-Fi.
`ciao` can't reliable detect modifications made to this default MTU size.
Thus , we rely on a hardcoded value, which is `1440` for the **UDP Payload Size** (Remember: the MTU defines the amount
of bytes Ethernet or Wi-Fi can transport on the local link. There is additional overhead caused by the IP Header
and the UDP Header. So the amount of bytes we are able to fit into a single UDP packet is smaller).
of bytes Ethernet or Wi-Fi can transport on the local link. There is additional overhead caused by the IP Header
and the UDP Header. So the amount of bytes we are able to fit into a single UDP packet is smaller).
If you know, that the MTU differs on your machine, you can set the true **UDP Payload Size** in bytes
using the `CIAO_UPS` environment variable.
using the `CIAO_UPS` environment variable.

### Notice on native mDNS responders

Expand All @@ -135,29 +134,30 @@ _"It is possible to have more than one Multicast DNS responder and/or
querier implementation coexist on the same machine, but there are some known issues."_

The RFC lists three possible issues:
* [15.1.](https://tools.ietf.org/html/rfc6762#section-15.1) **Receiving Unicast Responses:**
As multiple sockets (from multiple responders) are bound to the port 5353, only one can receive unicast responses.
Unicast responses is a way to reduce traffic on the multicast address, as answers to a particular question can be
sent directly to the querier. As ciao does not hold the primary socket on port 5353, it can't receive unicast responses
and thus must sent any queries without setting the QU (unicast response) flag. Any responses to our questions are
sent on multicast and thus increase the load on the network.
This currently isn't really a problem, as the only time we send queries is in the probing step before we
advertise a new service (Future query functionality is much more affected).
* [15.2.](https://tools.ietf.org/html/rfc6762#section-15.2) **Multipacket Known-Answer lists:**
When the known-answer list of a query is too large to fit into a single dns packet, a querier can split those
records into multiple packets (and setting the truncation flag).
A responder will then reassemble those packets, which are identified by their originating ip address.
Thus, known-answer lists could be messed up when two queriers are sending at the same time.
Again ciao currently only sends queries when probing, so the probability of this happening is pretty low.
* [15.3.](https://tools.ietf.org/html/rfc6762#section-15.3) **Efficiency:**
The last point is pretty simple. Two independently running responders use twice the memory and twice the computing power.
It doesn't improve the situation that this is running using an interpreted language.
So yes, it's probably not very efficient.

As the RFC also states in [15.4](https://tools.ietf.org/html/rfc6762#section-15.4), it is recommended to use

- [15.1.](https://tools.ietf.org/html/rfc6762#section-15.1) **Receiving Unicast Responses:**
As multiple sockets (from multiple responders) are bound to the port 5353, only one can receive unicast responses.
Unicast responses is a way to reduce traffic on the multicast address, as answers to a particular question can be
sent directly to the querier. As ciao does not hold the primary socket on port 5353, it can't receive unicast responses
and thus must sent any queries without setting the QU (unicast response) flag. Any responses to our questions are
sent on multicast and thus increase the load on the network.
This currently isn't really a problem, as the only time we send queries is in the probing step before we
advertise a new service (Future query functionality is much more affected).
- [15.2.](https://tools.ietf.org/html/rfc6762#section-15.2) **Multipacket Known-Answer lists:**
When the known-answer list of a query is too large to fit into a single dns packet, a querier can split those
records into multiple packets (and setting the truncation flag).
A responder will then reassemble those packets, which are identified by their originating ip address.
Thus, known-answer lists could be messed up when two queriers are sending at the same time.
Again ciao currently only sends queries when probing, so the probability of this happening is pretty low.
- [15.3.](https://tools.ietf.org/html/rfc6762#section-15.3) **Efficiency:**
The last point is pretty simple. Two independently running responders use twice the memory and twice the computing power.
It doesn't improve the situation that this is running using an interpreted language.
So yes, it's probably not very efficient.

As the RFC also states in [15.4](https://tools.ietf.org/html/rfc6762#section-15.4), it is recommended to use
a single mDNS implementation where possible. It is recommended to use the [mdns](https://www.npmjs.com/package/mdns)
library where possible, as the library is pretty much a binding for existing mDNS implementations running on your
system (like `mDNSResponder` on macOS or `avahi` on most linux based systems).
system (like `mDNSResponder` on macOS or `avahi` on most linux based systems).
The one downside with the `mdns` library is that running it on Windows is not really straight forward.
Generally we experienced with `homebridge` that many users run into problems when trying to install `mdns`.
Thus `bonjour-hap` and then `ciao` was created to provide a much easier to set up system.
48 changes: 48 additions & 0 deletions eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import antfu from '@antfu/eslint-config'

export default antfu(
{
ignores: ['dist', 'docs'],
jsx: false,
typescript: true,
formatters: {
markdown: true,
},
rules: {
'curly': ['error', 'multi-line'],
'import/extensions': ['error', 'ignorePackages'],
'import/order': 0,
'jsdoc/check-alignment': 'error',
'jsdoc/check-line-alignment': 'error',
'no-undef': 'error',
'perfectionist/sort-exports': 'error',
'perfectionist/sort-imports': [
'error',
{
groups: [
'builtin-type',
'external-type',
'internal-type',
['parent-type', 'sibling-type', 'index-type'],
'builtin',
'external',
'internal',
['parent', 'sibling', 'index'],
'object',
'unknown',
],
order: 'asc',
type: 'natural',
},
],
'perfectionist/sort-named-exports': 'error',
'perfectionist/sort-named-imports': 'error',
'sort-imports': 0,
'style/brace-style': ['error', '1tbs', { allowSingleLine: true }],
'style/quote-props': ['error', 'consistent-as-needed'],
'test/no-only-tests': 'error',
'unicorn/no-useless-spread': 'error',
'unused-imports/no-unused-vars': ['error', { caughtErrors: 'none' }],
},
},
)
13 changes: 0 additions & 13 deletions jest.config.ts

This file was deleted.

Loading

0 comments on commit 3062503

Please sign in to comment.