Skip to content

Commit 4dbbde7

Browse files
committed
feat: added ServiceDomain and FDQN to Hostname string utility functions
1 parent f4f6c12 commit 4dbbde7

File tree

3 files changed

+76
-17
lines changed

3 files changed

+76
-17
lines changed

src/MDNS.ts

+24-16
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import type {
88
MulticastSocketInfo,
99
SocketHostRow,
1010
RemoteInfo,
11+
FDQN,
1112
} from './types';
1213
import type {
1314
CachableResourceRecord,
@@ -57,10 +58,10 @@ class MDNS {
5758

5859
protected localRecordCache: ResourceRecordCache;
5960
protected localRecordCacheDirty = true;
60-
protected _localServices: Map<Hostname, Service> = new Map();
61+
protected _localServices: Map<FDQN, Service> = new Map();
6162

6263
protected networkRecordCache: ResourceRecordCache;
63-
protected _networkServices: Map<Hostname, Service> = new Map();
64+
protected _networkServices: Map<FDQN, Service> = new Map();
6465
protected sockets: Array<dgram.Socket> = [];
6566
protected socketMap: WeakMap<dgram.Socket, SocketInfo> = new WeakMap();
6667
protected socketHostTable: Table<SocketHostRow> = new Table(
@@ -140,7 +141,7 @@ class MDNS {
140141
* The Key is a FDQN.
141142
*/
142143
@ready(new errors.ErrorMDNSNotRunning())
143-
public get localServices(): ReadonlyMap<Hostname, Service> {
144+
public get localServices(): ReadonlyMap<FDQN, Service> {
144145
return this._localServices;
145146
}
146147

@@ -149,7 +150,7 @@ class MDNS {
149150
* The Key is a FDQN.
150151
*/
151152
@ready(new errors.ErrorMDNSNotRunning())
152-
public get networkServices(): ReadonlyMap<Hostname, Service> {
153+
public get networkServices(): ReadonlyMap<FDQN, Service> {
153154
return this._networkServices;
154155
}
155156

@@ -1003,22 +1004,22 @@ class MDNS {
10031004

10041005
protected extractRelatedFdqns(
10051006
resourceRecords: ResourceRecord | Array<ResourceRecord>,
1006-
): Array<Hostname> {
1007+
): Array<FDQN> {
10071008
if (!Array.isArray(resourceRecords)) {
10081009
return this.extractRelatedFdqns([resourceRecords]);
10091010
}
1010-
const relatedFdqns: Array<Hostname> = [];
1011+
const relatedFdqns: Array<FDQN> = [];
10111012
for (const resourceRecord of resourceRecords) {
10121013
if (
10131014
resourceRecord.type === RType.SRV ||
10141015
resourceRecord.type === RType.TXT
10151016
) {
1016-
relatedFdqns.push(resourceRecord.name as Hostname);
1017+
relatedFdqns.push(resourceRecord.name as FDQN);
10171018
} else if (
10181019
resourceRecord.type === RType.PTR &&
10191020
resourceRecord.name !== '_services._dns-sd._udp.local'
10201021
) {
1021-
relatedFdqns.push(resourceRecord.data as Hostname);
1022+
relatedFdqns.push(resourceRecord.data as FDQN);
10221023
} else if (
10231024
resourceRecord.type === RType.A ||
10241025
resourceRecord.type === RType.AAAA
@@ -1029,7 +1030,7 @@ class MDNS {
10291030
);
10301031
for (const relatedResourceRecord of relatedResourceRecords) {
10311032
if (relatedResourceRecord.type === RType.SRV) {
1032-
relatedFdqns.push(relatedResourceRecord.name as Hostname);
1033+
relatedFdqns.push(relatedResourceRecord.name as FDQN);
10331034
}
10341035
}
10351036
}
@@ -1160,9 +1161,7 @@ class MDNS {
11601161
hostname: this._hostname,
11611162
hosts: [],
11621163
};
1163-
const serviceDomain =
1164-
`_${service.type}._${service.protocol}.local` as Hostname;
1165-
const fdqn = `${service.name}.${serviceDomain}` as Hostname;
1164+
const fdqn = utils.toFdqn(service);
11661165

11671166
this._localServices.set(fdqn, service);
11681167
this.localRecordCacheDirty = true;
@@ -1200,8 +1199,11 @@ class MDNS {
12001199
type: string;
12011200
protocol: 'udp' | 'tcp';
12021201
}) {
1203-
const serviceDomain = `_${type}._${protocol}.local` as Hostname;
1204-
const fdqn = `${name}.${serviceDomain}` as Hostname;
1202+
const fdqn = utils.toFdqn({
1203+
name,
1204+
type,
1205+
protocol,
1206+
});
12051207

12061208
const foundService = this._localServices.get(fdqn);
12071209
if (foundService == null) return;
@@ -1248,7 +1250,10 @@ class MDNS {
12481250
minDelay?: number;
12491251
maxDelay?: number;
12501252
}) {
1251-
const serviceDomain = `_${type}._${protocol}.local` as Hostname;
1253+
const serviceDomain = utils.toServiceDomain({
1254+
type,
1255+
protocol,
1256+
});
12521257
const questionRecord: QuestionRecord = {
12531258
name: serviceDomain,
12541259
type: QType.PTR,
@@ -1329,7 +1334,10 @@ class MDNS {
13291334
type: string;
13301335
protocol: 'udp' | 'tcp';
13311336
}) {
1332-
const serviceDomain = `_${type}._${protocol}.local`;
1337+
const serviceDomain = utils.toServiceDomain({
1338+
type,
1339+
protocol,
1340+
});
13331341
this.queries.get(serviceDomain)?.cancel();
13341342
}
13351343
}

src/types.ts

+8-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,13 @@ type Host = Opaque<'Host', string>;
3232
/**
3333
* Hostnames are resolved to IP addresses
3434
*/
35-
type Hostname = Opaque<'Hostname', string>;
35+
type Hostname = Opaque<'Hostname', string> | FDQN;
36+
37+
/**
38+
* FDQNs are in the format `{service.name}._${service.type}._${service.protocol}.local`.
39+
* FDQNs are also Hostnames.
40+
*/
41+
type FDQN = Opaque<'FDQN', string>;
3642

3743
/**
3844
* Ports are numbers from 0 to 65535
@@ -122,6 +128,7 @@ export type {
122128
PromiseDeconstructed,
123129
Host,
124130
Hostname,
131+
FDQN,
125132
Port,
126133
Address,
127134
Service,

src/utils.ts

+44
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import type {
22
Callback,
3+
FDQN,
34
Host,
45
Hostname,
56
NetworkInterfaces,
@@ -239,6 +240,47 @@ function getRandomPacketId(): number {
239240
return Math.floor(Math.random() * 65535);
240241
}
241242

243+
function toServiceDomain({
244+
type,
245+
protocol,
246+
}: {
247+
type: string;
248+
protocol: 'udp' | 'tcp';
249+
}): Hostname {
250+
return `_${type}._${protocol}.local` as Hostname;
251+
}
252+
253+
function toFdqn({
254+
name,
255+
type,
256+
protocol,
257+
serviceDomain,
258+
}: {
259+
name: string;
260+
} & (
261+
| {
262+
type: string;
263+
protocol: 'udp' | 'tcp';
264+
serviceDomain?: undefined;
265+
}
266+
| {
267+
type?: undefined;
268+
protocol?: undefined;
269+
serviceDomain: Hostname;
270+
}
271+
)): FDQN {
272+
let serviceDomain_: Hostname | undefined;
273+
if (serviceDomain == null) {
274+
serviceDomain_ = toServiceDomain({
275+
type,
276+
protocol,
277+
});
278+
} else {
279+
serviceDomain_ = serviceDomain;
280+
}
281+
return `${name}.${serviceDomain_}` as FDQN;
282+
}
283+
242284
export {
243285
isPort,
244286
isIPv4,
@@ -254,4 +296,6 @@ export {
254296
toServiceResourceRecords,
255297
bindSocket,
256298
getRandomPacketId,
299+
toServiceDomain,
300+
toFdqn,
257301
};

0 commit comments

Comments
 (0)