fix(gateway): advertise bonjour hostname
This commit is contained in:
@@ -49,6 +49,15 @@ If browsing shows instances but resolving fails, you’re usually hitting a LAN
|
||||
- **Bonjour doesn’t cross networks**: London/Vienna style setups require Tailnet (MagicDNS/IP) or SSH.
|
||||
- **Multicast blocked**: some Wi‑Fi networks (enterprise/hotels) disable mDNS; expect “no results”.
|
||||
- **Sleep / interface churn**: macOS may temporarily drop mDNS results when switching networks; retry.
|
||||
- **Browse works but resolve fails (iOS “NoSuchRecord”)**: make sure the advertiser publishes a valid SRV target hostname.
|
||||
- Implementation detail: `@homebridge/ciao` defaults `hostname` to the *service instance name* when `hostname` is omitted. If your instance name contains spaces/parentheses, some resolvers can fail to resolve the implied A/AAAA record.
|
||||
- Fix: set an explicit DNS-safe `hostname` (single label; no `.local`) in `src/infra/bonjour.ts`.
|
||||
|
||||
## Escaped instance names (`\\032`)
|
||||
Bonjour/DNS-SD often escapes bytes in service instance names as decimal `\\DDD` sequences (e.g. spaces become `\\032`).
|
||||
|
||||
- This is normal at the protocol level.
|
||||
- UIs should decode for display (iOS uses `BonjourEscapes.decode` in `apps/shared/ClawdisKit`).
|
||||
|
||||
## Disabling / configuration
|
||||
|
||||
|
||||
@@ -20,6 +20,8 @@ const { startGatewayBonjourAdvertiser } = await import("./bonjour.js");
|
||||
describe("gateway bonjour advertiser", () => {
|
||||
type ServiceCall = {
|
||||
name?: unknown;
|
||||
hostname?: unknown;
|
||||
domain?: unknown;
|
||||
txt?: unknown;
|
||||
};
|
||||
|
||||
@@ -66,6 +68,8 @@ describe("gateway bonjour advertiser", () => {
|
||||
>;
|
||||
expect(masterCall?.[0]?.type).toBe("clawdis-master");
|
||||
expect(masterCall?.[0]?.port).toBe(2222);
|
||||
expect(masterCall?.[0]?.domain).toBe("local");
|
||||
expect(masterCall?.[0]?.hostname).toBe("test-host");
|
||||
expect((masterCall?.[0]?.txt as Record<string, string>)?.lanHost).toBe(
|
||||
"test-host.local",
|
||||
);
|
||||
@@ -75,6 +79,8 @@ describe("gateway bonjour advertiser", () => {
|
||||
|
||||
expect(bridgeCall?.[0]?.type).toBe("clawdis-bridge");
|
||||
expect(bridgeCall?.[0]?.port).toBe(18790);
|
||||
expect(bridgeCall?.[0]?.domain).toBe("local");
|
||||
expect(bridgeCall?.[0]?.hostname).toBe("test-host");
|
||||
expect((bridgeCall?.[0]?.txt as Record<string, string>)?.bridgePort).toBe(
|
||||
"18790",
|
||||
);
|
||||
@@ -109,6 +115,8 @@ describe("gateway bonjour advertiser", () => {
|
||||
|
||||
const [masterCall] = createService.mock.calls as Array<[ServiceCall]>;
|
||||
expect(masterCall?.[0]?.name).toBe("Mac (Clawdis)");
|
||||
expect(masterCall?.[0]?.domain).toBe("local");
|
||||
expect(masterCall?.[0]?.hostname).toBe("Mac");
|
||||
expect((masterCall?.[0]?.txt as Record<string, string>)?.lanHost).toBe(
|
||||
"Mac.local",
|
||||
);
|
||||
|
||||
@@ -74,6 +74,8 @@ export async function startGatewayBonjourAdvertiser(
|
||||
type: "clawdis-master",
|
||||
protocol: Protocol.TCP,
|
||||
port: opts.sshPort ?? 22,
|
||||
domain: "local",
|
||||
hostname,
|
||||
txt: {
|
||||
...txtBase,
|
||||
sshPort: String(opts.sshPort ?? 22),
|
||||
@@ -88,6 +90,8 @@ export async function startGatewayBonjourAdvertiser(
|
||||
type: "clawdis-bridge",
|
||||
protocol: Protocol.TCP,
|
||||
port: opts.bridgePort,
|
||||
domain: "local",
|
||||
hostname,
|
||||
txt: {
|
||||
...txtBase,
|
||||
transport: "bridge",
|
||||
|
||||
Reference in New Issue
Block a user