@lakutata/netif 0.0.0-stage → 3.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. package/LICENSE +23 -0
  2. package/README.md +299 -2
  3. package/README.zh-CN.md +229 -0
  4. package/binding.gyp +43 -0
  5. package/dist/cjs/exceptions/NetIfException.d.ts +17 -0
  6. package/dist/cjs/exceptions/NetIfException.js +24 -0
  7. package/dist/cjs/exceptions/NetIfNotEnforcedException.d.ts +12 -0
  8. package/dist/cjs/exceptions/NetIfNotEnforcedException.js +19 -0
  9. package/dist/cjs/exceptions/NetIfNotFoundException.d.ts +12 -0
  10. package/dist/cjs/exceptions/NetIfNotFoundException.js +19 -0
  11. package/dist/cjs/exceptions/NetIfNotSupportedException.d.ts +12 -0
  12. package/dist/cjs/exceptions/NetIfNotSupportedException.js +19 -0
  13. package/dist/cjs/exceptions/NetIfTimeoutException.d.ts +11 -0
  14. package/dist/cjs/exceptions/NetIfTimeoutException.js +18 -0
  15. package/dist/cjs/exports/Netif.d.ts +11 -0
  16. package/dist/cjs/exports/Netif.js +26 -0
  17. package/dist/cjs/lib/Addon.d.ts +5 -0
  18. package/dist/cjs/lib/Addon.js +9 -0
  19. package/dist/cjs/lib/Attachment.d.ts +152 -0
  20. package/dist/cjs/lib/Attachment.js +415 -0
  21. package/dist/cjs/lib/Enforcement.d.ts +22 -0
  22. package/dist/cjs/lib/Enforcement.js +45 -0
  23. package/dist/cjs/lib/Functions.d.ts +66 -0
  24. package/dist/cjs/lib/Functions.js +97 -0
  25. package/dist/cjs/lib/InterfaceListener.d.ts +92 -0
  26. package/dist/cjs/lib/InterfaceListener.js +99 -0
  27. package/dist/cjs/lib/InterfaceUDPSocket.d.ts +119 -0
  28. package/dist/cjs/lib/InterfaceUDPSocket.js +245 -0
  29. package/dist/cjs/lib/Internal.d.ts +10 -0
  30. package/dist/cjs/lib/Internal.js +9 -0
  31. package/dist/cjs/lib/Native.d.ts +54 -0
  32. package/dist/cjs/lib/Native.js +83 -0
  33. package/dist/cjs/lib/NetworkInterface.d.ts +313 -0
  34. package/dist/cjs/lib/NetworkInterface.js +391 -0
  35. package/dist/cjs/lib/Registry.d.ts +26 -0
  36. package/dist/cjs/lib/Registry.js +103 -0
  37. package/dist/cjs/lib/Snapshot.d.ts +17 -0
  38. package/dist/cjs/lib/Snapshot.js +84 -0
  39. package/dist/cjs/lib/Types.d.ts +63 -0
  40. package/dist/cjs/lib/Types.js +2 -0
  41. package/dist/cjs/package.json +1 -0
  42. package/dist/esm/exceptions/NetIfException.js +20 -0
  43. package/dist/esm/exceptions/NetIfNotEnforcedException.js +15 -0
  44. package/dist/esm/exceptions/NetIfNotFoundException.js +15 -0
  45. package/dist/esm/exceptions/NetIfNotSupportedException.js +15 -0
  46. package/dist/esm/exceptions/NetIfTimeoutException.js +14 -0
  47. package/dist/esm/exports/Netif.js +9 -0
  48. package/dist/esm/lib/Addon.js +10 -0
  49. package/dist/esm/lib/Attachment.js +410 -0
  50. package/dist/esm/lib/Enforcement.js +41 -0
  51. package/dist/esm/lib/Functions.js +92 -0
  52. package/dist/esm/lib/InterfaceListener.js +95 -0
  53. package/dist/esm/lib/InterfaceUDPSocket.js +241 -0
  54. package/dist/esm/lib/Internal.js +6 -0
  55. package/dist/esm/lib/Native.js +75 -0
  56. package/dist/esm/lib/NetworkInterface.js +386 -0
  57. package/dist/esm/lib/Registry.js +100 -0
  58. package/dist/esm/lib/Snapshot.js +79 -0
  59. package/dist/esm/lib/Types.js +1 -0
  60. package/dist/types/exceptions/NetIfException.d.ts +17 -0
  61. package/dist/types/exceptions/NetIfNotEnforcedException.d.ts +12 -0
  62. package/dist/types/exceptions/NetIfNotFoundException.d.ts +12 -0
  63. package/dist/types/exceptions/NetIfNotSupportedException.d.ts +12 -0
  64. package/dist/types/exceptions/NetIfTimeoutException.d.ts +11 -0
  65. package/dist/types/exports/Netif.d.ts +11 -0
  66. package/dist/types/lib/Addon.d.ts +5 -0
  67. package/dist/types/lib/Attachment.d.ts +152 -0
  68. package/dist/types/lib/Enforcement.d.ts +22 -0
  69. package/dist/types/lib/Functions.d.ts +66 -0
  70. package/dist/types/lib/InterfaceListener.d.ts +92 -0
  71. package/dist/types/lib/InterfaceUDPSocket.d.ts +119 -0
  72. package/dist/types/lib/Internal.d.ts +10 -0
  73. package/dist/types/lib/Native.d.ts +54 -0
  74. package/dist/types/lib/NetworkInterface.d.ts +313 -0
  75. package/dist/types/lib/Registry.d.ts +26 -0
  76. package/dist/types/lib/Snapshot.d.ts +17 -0
  77. package/dist/types/lib/Types.d.ts +63 -0
  78. package/native/Interfaces.cpp +34 -0
  79. package/native/Interfaces.h +47 -0
  80. package/native/Sockets.h +36 -0
  81. package/native/Watcher.h +27 -0
  82. package/native/addon.cpp +195 -0
  83. package/native/darwin/Interfaces.cpp +150 -0
  84. package/native/darwin/Sockets.cpp +44 -0
  85. package/native/darwin/Watcher.cpp +113 -0
  86. package/native/linux/Interfaces.cpp +133 -0
  87. package/native/linux/RouteNetlink.h +38 -0
  88. package/native/linux/Sockets.cpp +89 -0
  89. package/native/linux/Watcher.cpp +70 -0
  90. package/native/windows/Interfaces.cpp +78 -0
  91. package/native/windows/Sockets.cpp +56 -0
  92. package/native/windows/Watcher.cpp +53 -0
  93. package/package.json +81 -4
@@ -0,0 +1,152 @@
1
+ import { EventEmitter } from 'node:events';
2
+ import { type Family } from './Enforcement.js';
3
+ import { type NetworkInterface } from './NetworkInterface.js';
4
+ import { type InterfaceAddress } from './Types.js';
5
+ /**
6
+ * An address a listener or a UDP socket of an interface can be reached at.
7
+ */
8
+ export interface ListeningAddress {
9
+ /**
10
+ * The address (an IPv6 address without its scope).
11
+ */
12
+ address: string;
13
+ /**
14
+ * `'IPv4'` or `'IPv6'`.
15
+ */
16
+ family: 'IPv4' | 'IPv6';
17
+ /**
18
+ * The port.
19
+ */
20
+ port: number;
21
+ /**
22
+ * IPv6 only: the scope of the address (the index of the interface for a link-local one), 0 for a global one.
23
+ */
24
+ scopeid?: number;
25
+ }
26
+ /**
27
+ * The options common to the listeners and the UDP sockets of an interface
28
+ */
29
+ export interface AttachmentOptions {
30
+ port: number;
31
+ family?: 'IPv4' | 'IPv6' | 'both';
32
+ strict?: boolean;
33
+ }
34
+ /**
35
+ * What a socket of an attachment is made on: a socket bound to the interface (Linux, its descriptor), or an address of
36
+ * the interface (the host with its scope, and the port)
37
+ */
38
+ export type Target = {
39
+ fd: number;
40
+ } | {
41
+ host: string;
42
+ port: number;
43
+ };
44
+ /**
45
+ * A socket of an attachment: bound to the interface, or to one of its addresses
46
+ */
47
+ export interface Endpoint<Handle> {
48
+ key: string;
49
+ family: Family;
50
+ handle: Handle;
51
+ address?: InterfaceAddress;
52
+ }
53
+ /**
54
+ * The code of the error of the system an error carries
55
+ */
56
+ export declare function codeOf(error: unknown): unknown;
57
+ /**
58
+ * The sockets of an interface kept matching it (the base of the listeners and the UDP sockets): on Linux sockets bound
59
+ * to the interface, one by family, made again when the interface is plugged back (a new index); elsewhere (and on Linux
60
+ * without the permission to bind) a socket by address of the interface, made and closed as its addresses change. The
61
+ * guarantee that the system refuses what comes through another interface (`enforced`), followed; with `strict` the
62
+ * sockets are closed while it is lost. The changes of the interface are followed one at a time.
63
+ */
64
+ export declare abstract class Attachment<Events extends Record<keyof Events, unknown[]>, Handle> extends EventEmitter<Events> {
65
+ #private;
66
+ /**
67
+ * The interface.
68
+ */
69
+ readonly networkInterface: NetworkInterface;
70
+ protected readonly families: Family[];
71
+ protected readonly strict: boolean;
72
+ /**
73
+ * Internal: the options checked.
74
+ * @param networkInterface The interface.
75
+ * @param options The port, the families and `strict`.
76
+ * @param ownsInterface Whether the interface is closed with it.
77
+ */
78
+ protected constructor(networkInterface: NetworkInterface, options: AttachmentOptions, ownsInterface: boolean);
79
+ /**
80
+ * Whether a TCP (true) or a UDP socket is bound to the interface
81
+ */
82
+ protected abstract readonly stream: boolean;
83
+ /**
84
+ * Makes a socket of a family on the target: its handle once it listens (or is bound)
85
+ */
86
+ protected abstract openHandle(target: Target, family: Family): Promise<Handle>;
87
+ /**
88
+ * The port of a socket made
89
+ */
90
+ protected abstract portOf(handle: Handle): number | undefined;
91
+ /**
92
+ * Closes a socket
93
+ */
94
+ protected abstract closeHandle(handle: Handle): void;
95
+ /**
96
+ * Whether the system refuses, through another interface, what is sent to the addresses of the interface: always on
97
+ * Linux (the sockets are bound to the interface), on Windows while every other interface receives with the strong
98
+ * host model and does not forward, on macOS when it is set to (`net.inet.ip.check_interface` 2, forwarding off).
99
+ */
100
+ get enforced(): boolean;
101
+ /**
102
+ * Why what comes through another interface is not refused, `undefined` while it is.
103
+ */
104
+ get reason(): string | undefined;
105
+ /**
106
+ * The port, `undefined` until a port 0 was given one by the system.
107
+ */
108
+ get port(): number | undefined;
109
+ /**
110
+ * Whether the interface is listened on now (it exists, and has an address where its addresses are listened on).
111
+ */
112
+ get listening(): boolean;
113
+ /**
114
+ * The addresses it can be reached at now. On Linux the sockets bound to the interface also get what is sent to
115
+ * another address of the machine through the interface.
116
+ */
117
+ get addresses(): ListeningAddress[];
118
+ /**
119
+ * Whether it was closed.
120
+ */
121
+ get closed(): boolean;
122
+ /**
123
+ * Whether the sockets are bound to the interface (Linux), not to its addresses
124
+ */
125
+ protected get boundToInterface(): boolean;
126
+ /**
127
+ * The sockets now
128
+ */
129
+ protected endpoints(): Endpoint<Handle>[];
130
+ /**
131
+ * A socket made, before it is counted (its settings applied: the broadcasts, the multicast groups)
132
+ */
133
+ protected prepare(_endpoint: Endpoint<Handle>): void;
134
+ /**
135
+ * A socket closed, no longer counted
136
+ */
137
+ protected released(_endpoint: Endpoint<Handle>): void;
138
+ /**
139
+ * Internal: the first binding, which the method that made it waits for.
140
+ * @returns It.
141
+ */
142
+ start(): Promise<this>;
143
+ /**
144
+ * Stops: the sockets closed (the listener does not wait for the connections established, which are left to the
145
+ * server).
146
+ */
147
+ close(): Promise<void>;
148
+ /**
149
+ * An error of a binding again, or of a socket: the error event, the binding retried a little later
150
+ */
151
+ protected failed(error: unknown): void;
152
+ }
@@ -0,0 +1,22 @@
1
+ /**
2
+ * A family of addresses
3
+ */
4
+ export type Family = 'IPv4' | 'IPv6';
5
+ /**
6
+ * Whether the system refuses the connections and the datagrams reaching the addresses of an interface through another
7
+ * interface, and why not
8
+ */
9
+ export interface Enforcement {
10
+ enforced: boolean;
11
+ reason?: string;
12
+ }
13
+ /**
14
+ * Why a socket of Linux could not be bound to the interface
15
+ */
16
+ export declare const LINUX_PERMISSION: string;
17
+ /**
18
+ * Whether the system refuses, through the other interfaces, the packets for the addresses of the interface of the index
19
+ * when they are listened on by address: the strong host model of Windows (every other interface receiving with it and
20
+ * not forwarding) and of macOS (net.inet.ip.check_interface set to 2, forwarding off); never on Linux
21
+ */
22
+ export declare function addressEnforcement(index: number, families: Family[]): Enforcement;
@@ -0,0 +1,66 @@
1
+ import { type Server } from 'node:net';
2
+ import { InterfaceListener, type ListenOptions } from './InterfaceListener.js';
3
+ import { type InterfaceSelector } from './NetworkInterface.js';
4
+ import { type NetworkInterfaceInfo } from './Types.js';
5
+ /**
6
+ * The network interfaces of the machine, the ones without an address too, with their state: their name, index,
7
+ * hardware address, whether they are enabled and connected, their usable addresses. More than `os.networkInterfaces()`,
8
+ * which lists only the interfaces with an address and no state.
9
+ * @returns The interfaces, in the order of the system.
10
+ * @example
11
+ * ```typescript
12
+ * import {listInterfaces, type NetworkInterfaceInfo} from '@lakutata/netif'
13
+ *
14
+ * for (const entry of listInterfaces()) {
15
+ * console.log(entry.name, entry.running ? 'connected' : 'not connected', entry.addresses.map(address => address.cidr))
16
+ * }
17
+ * const connected: NetworkInterfaceInfo[] = listInterfaces().filter(entry => entry.running && !entry.loopback)
18
+ * ```
19
+ */
20
+ export declare function listInterfaces(): NetworkInterfaceInfo[];
21
+ /**
22
+ * Listens on an interface for a server: `new NetworkInterface(selector).listen(server, options)` in one call, the
23
+ * interface followed until the listener is closed.
24
+ * @param selector The interface: its name, `{mac}` or `{index}`.
25
+ * @param server A `net.Server` or a server built on one (`http`, `https`, `http2`, `tls`), which must not listen itself.
26
+ * @param options The port, the families, `strict` and the backlog.
27
+ * @returns The listener.
28
+ * @throws NetIfNotEnforcedException With `strict`, where the system cannot refuse the connections coming through another
29
+ * interface.
30
+ * @throws NetIfNotFoundException An index or a hardware address that cannot be found.
31
+ * @throws NetIfException The system refused the first listening, its code as `errno`.
32
+ * @example
33
+ * ```typescript
34
+ * import {createServer} from 'node:http'
35
+ * import {type InterfaceListener, listenOn} from '@lakutata/netif'
36
+ *
37
+ * const listener: InterfaceListener = await listenOn('eth1', createServer((request, response) => response.end('ok')), {port: 8080})
38
+ * console.log(listener.addresses)
39
+ * ```
40
+ */
41
+ export declare function listenOn(selector: InterfaceSelector, server: Server, options: ListenOptions): Promise<InterfaceListener>;
42
+ /**
43
+ * Listens on several interfaces for a server: `listenOn()` for each of them, one listener by interface, the interfaces
44
+ * followed until their listeners are closed. When one of them cannot be listened on, the ones listened on already are
45
+ * closed and the error is thrown. Several interfaces need a port: 0 lets the system choose one for the first
46
+ * interface, which may not exist yet. With it, the package implements `IInterfaceListening` of `@lakutata/core`: the
47
+ * entrypoints of lakutata listen on interfaces through it.
48
+ * @param selectors An interface (its name, `{mac}` or `{index}`), or several.
49
+ * @param server A `net.Server` or a server built on one (`http`, `https`, `http2`, `tls`), which must not listen itself.
50
+ * @param options The port, the families, `strict` and the backlog, the same for every interface.
51
+ * @returns The listeners, in the order of the interfaces.
52
+ * @throws TypeError No interface, or a port 0 with several of them.
53
+ * @throws NetIfNotEnforcedException With `strict`, where the system cannot refuse the connections coming through another
54
+ * interface.
55
+ * @throws NetIfException The system refused a first listening, its code as `errno`.
56
+ * @example
57
+ * ```typescript
58
+ * import {createServer} from 'node:http'
59
+ * import {type InterfaceListener, listenOnAll} from '@lakutata/netif'
60
+ *
61
+ * const server = createServer((request, response) => response.end('ok'))
62
+ * const listeners: InterfaceListener[] = await listenOnAll(['eth1', {mac: '52:54:00:12:34:56'}], server, {port: 8080})
63
+ * for (const listener of listeners) listener.on('error', error => console.error(error))
64
+ * ```
65
+ */
66
+ export declare function listenOnAll(selectors: InterfaceSelector | InterfaceSelector[], server: Server, options: ListenOptions): Promise<InterfaceListener[]>;
@@ -0,0 +1,92 @@
1
+ import { type Server } from 'node:net';
2
+ import type { IInterfaceListener } from '@lakutata/core';
3
+ import { Attachment, type Target } from './Attachment.js';
4
+ import { type Family } from './Enforcement.js';
5
+ import { type NetworkInterface } from './NetworkInterface.js';
6
+ /**
7
+ * The options of `listen()`.
8
+ */
9
+ export interface ListenOptions {
10
+ /**
11
+ * The port. 0: one the system chooses, kept when the interface is listened on again.
12
+ */
13
+ port: number;
14
+ /**
15
+ * The families listened on: `'IPv4'`, `'IPv6'` or `'both'` (by default). With `'both'`, a system without IPv6 is
16
+ * listened on in IPv4.
17
+ */
18
+ family?: 'IPv4' | 'IPv6' | 'both';
19
+ /**
20
+ * `true`: the listening is refused (a `NetIfNotEnforcedException`) where the system cannot refuse the connections
21
+ * reaching the addresses of the interface through another interface, and it stops while that guarantee is lost.
22
+ * `false` by default: the best the system allows, told by `enforced`.
23
+ */
24
+ strict?: boolean;
25
+ /**
26
+ * The length of the queue of the connections not accepted yet, 511 by default.
27
+ */
28
+ backlog?: number;
29
+ }
30
+ /**
31
+ * The events of an `InterfaceListener` and their arguments.
32
+ */
33
+ export interface InterfaceListenerEvents {
34
+ /**
35
+ * The interface is listened on, after `listen()` and each time it is listened on again (an address added, the
36
+ * interface plugged back).
37
+ */
38
+ listening: [];
39
+ /**
40
+ * An error of a listening again (the port taken meanwhile…), retried a little later; with `strict`, the guarantee
41
+ * lost (a `NetIfNotEnforcedException`). Without a listener of `error`, the error is thrown, as for a `net.Server`.
42
+ */
43
+ error: [error: Error];
44
+ /**
45
+ * Whether the connections coming through another interface are refused changed: its new value.
46
+ */
47
+ enforced: [enforced: boolean];
48
+ /**
49
+ * The listener was closed.
50
+ */
51
+ close: [];
52
+ }
53
+ /**
54
+ * The listening of a server on a network interface: `NetworkInterface.listen()`. The listener accepts the connections
55
+ * and gives them to the server (`server.emit('connection', socket)`), which handles them as its own: the server itself
56
+ * does not listen (its `address()` is `null`, its `close()` does not stop the listener; use the ones of the listener).
57
+ * The interface is listened on again when its addresses change and when it is unplugged and plugged back; the
58
+ * connections established are left to the server. It implements `IInterfaceListener` of `@lakutata/core`.
59
+ * @example
60
+ * ```typescript
61
+ * import {createServer} from 'node:http'
62
+ * import {type InterfaceListener, NetworkInterface} from '@lakutata/netif'
63
+ *
64
+ * const server = createServer((request, response) => response.end('ok'))
65
+ * const listener: InterfaceListener = await new NetworkInterface('eth1').listen(server, {port: 8080})
66
+ * console.log(listener.enforced, listener.addresses)
67
+ * listener.on('error', error => console.error(error))
68
+ * await listener.close()
69
+ * ```
70
+ */
71
+ export declare class InterfaceListener extends Attachment<InterfaceListenerEvents, Server> implements IInterfaceListener {
72
+ #private;
73
+ /**
74
+ * The server the connections are given to.
75
+ */
76
+ readonly server: Server;
77
+ protected readonly stream: boolean;
78
+ /**
79
+ * Internal: made by `NetworkInterface.listen()` and `listenOn()`; `start()` listens.
80
+ * @param networkInterface The interface.
81
+ * @param server The server.
82
+ * @param options The options of `listen()`.
83
+ * @param ownsInterface Whether the interface is closed with the listener (`listenOn()`).
84
+ */
85
+ constructor(networkInterface: NetworkInterface, server: Server, options: ListenOptions, ownsInterface?: boolean);
86
+ /**
87
+ * Listens on the target: a server of the listener, the connections it accepts given to the server of the user
88
+ */
89
+ protected openHandle(target: Target, _family: Family): Promise<Server>;
90
+ protected portOf(handle: Server): number | undefined;
91
+ protected closeHandle(handle: Server): void;
92
+ }
@@ -0,0 +1,119 @@
1
+ import { type RemoteInfo, type Socket } from 'node:dgram';
2
+ import { Attachment, type Endpoint, type Target } from './Attachment.js';
3
+ import { type Family } from './Enforcement.js';
4
+ import { type NetworkInterface } from './NetworkInterface.js';
5
+ /**
6
+ * The options of `createUDPSocket()`.
7
+ */
8
+ export interface UDPSocketOptions {
9
+ /**
10
+ * The port. 0: one the system chooses, kept when the socket is bound again.
11
+ */
12
+ port: number;
13
+ /**
14
+ * The families: `'IPv4'`, `'IPv6'` or `'both'` (by default, a socket of each family inside). With `'both'`, a system
15
+ * without IPv6 is bound in IPv4.
16
+ */
17
+ family?: 'IPv4' | 'IPv6' | 'both';
18
+ /**
19
+ * `true`: refused (a `NetIfNotEnforcedException`) where the system cannot refuse the datagrams reaching the addresses
20
+ * of the interface through another interface, and stopped while that guarantee is lost. `false` by default.
21
+ */
22
+ strict?: boolean;
23
+ }
24
+ /**
25
+ * The events of an `InterfaceUDPSocket` and their arguments.
26
+ */
27
+ export interface InterfaceUDPSocketEvents {
28
+ /**
29
+ * A datagram received: its content, and where it came from (as `dgram` gives it).
30
+ */
31
+ message: [message: Buffer, remote: RemoteInfo];
32
+ /**
33
+ * The interface is bound, after `createUDPSocket()` and each time it is bound again (an address added, the interface
34
+ * plugged back).
35
+ */
36
+ listening: [];
37
+ /**
38
+ * An error of a binding again, retried a little later, or of a socket; with `strict`, the guarantee lost (a
39
+ * `NetIfNotEnforcedException`). Without a listener of `error`, the error is thrown, as for a `dgram` socket.
40
+ */
41
+ error: [error: Error];
42
+ /**
43
+ * Whether the datagrams coming through another interface are refused changed: its new value.
44
+ */
45
+ enforced: [enforced: boolean];
46
+ /**
47
+ * The socket was closed.
48
+ */
49
+ close: [];
50
+ }
51
+ /**
52
+ * A UDP socket of a network interface: `NetworkInterface.createUDPSocket()`. Its methods and events are the ones of a
53
+ * `dgram` socket. On Linux its sockets (one by family) are bound to the interface: they receive what comes through it,
54
+ * its broadcasts and the multicast of the groups joined there, whatever its addresses, and send through it. On Windows
55
+ * and macOS a socket is bound to each address of the interface, again when they change. The datagrams that arrive while
56
+ * the socket is bound again are lost (UDP never guarantees their delivery).
57
+ * @example
58
+ * ```typescript
59
+ * import {type InterfaceUDPSocket, NetworkInterface} from '@lakutata/netif'
60
+ *
61
+ * const lan: NetworkInterface = new NetworkInterface('eth1')
62
+ * const socket: InterfaceUDPSocket = await lan.createUDPSocket({port: 5353})
63
+ * socket.addMembership('224.0.0.251')
64
+ * socket.on('message', (message, remote) => console.log(`${remote.address}:${remote.port}`, message.length))
65
+ * socket.send('hello', 5353, '224.0.0.251')
66
+ * ```
67
+ */
68
+ export declare class InterfaceUDPSocket extends Attachment<InterfaceUDPSocketEvents, Socket> {
69
+ #private;
70
+ protected readonly stream: boolean;
71
+ /**
72
+ * Internal: made by `NetworkInterface.createUDPSocket()`; `start()` binds it.
73
+ * @param networkInterface The interface.
74
+ * @param options The options of `createUDPSocket()`.
75
+ * @param ownsInterface Whether the interface is closed with the socket.
76
+ */
77
+ constructor(networkInterface: NetworkInterface, options: UDPSocketOptions, ownsInterface?: boolean);
78
+ protected openHandle(target: Target, family: Family): Promise<Socket>;
79
+ protected portOf(handle: Socket): number | undefined;
80
+ protected closeHandle(handle: Socket): void;
81
+ /**
82
+ * A socket made: the broadcasts and the groups of the socket applied to it
83
+ */
84
+ protected prepare(endpoint: Endpoint<Socket>): void;
85
+ /**
86
+ * A socket closed: the groups it joined for its family joined by another one
87
+ */
88
+ protected released(endpoint: Endpoint<Socket>): void;
89
+ /**
90
+ * Sends a datagram through the interface, from the socket of the family of the address (from the address of the
91
+ * interface in the network of the destination, where its addresses are bound).
92
+ * @param message The content.
93
+ * @param port The port of the destination.
94
+ * @param address The address of the destination (a broadcast address with `setBroadcast(true)`, a multicast group).
95
+ * @param callback Called once it is sent, with the error if it could not be; without it, the error is an `error`
96
+ * event.
97
+ */
98
+ send(message: string | Uint8Array, port: number, address: string, callback?: (error: Error | null, bytes?: number) => void): void;
99
+ /**
100
+ * Whether the datagrams may be sent to broadcast addresses (`SO_BROADCAST`), kept when the socket is bound again.
101
+ * Where the addresses are bound (macOS, and Linux without the permission to bind to the interface) the broadcasts can
102
+ * be sent, not received.
103
+ * @param flag Whether they may.
104
+ */
105
+ setBroadcast(flag: boolean): void;
106
+ /**
107
+ * Joins a multicast group on the interface, kept when the socket is bound again: its datagrams are received.
108
+ * @param group The address of the group: `'224.0.0.251'`, `'ff02::fb'`.
109
+ * @throws NetIfNotSupportedException Where the addresses are bound on macOS and Linux: a socket bound to an address
110
+ * receives no multicast.
111
+ * @throws NetIfException The system refused, its code as `errno`.
112
+ */
113
+ addMembership(group: string): void;
114
+ /**
115
+ * Leaves a multicast group joined.
116
+ * @param group The address of the group.
117
+ */
118
+ dropMembership(group: string): void;
119
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * The key of the internal method of a NetworkInterface its listeners follow it by: the observer given is called with
3
+ * 'update' after each reading of the interfaces, with 'close' when the NetworkInterface is closed; the function returned
4
+ * removes it
5
+ */
6
+ export declare const OBSERVE: unique symbol;
7
+ /**
8
+ * An observer of a NetworkInterface
9
+ */
10
+ export type Observer = (event: 'update' | 'close') => void;
@@ -0,0 +1,54 @@
1
+ /**
2
+ * An address of an interface as the addon reads it: `tentative` while an IPv6 address is in its duplicate address
3
+ * detection (not usable yet)
4
+ */
5
+ export interface NativeAddress {
6
+ address: string;
7
+ family: 'IPv4' | 'IPv6';
8
+ prefixLength: number;
9
+ tentative: boolean;
10
+ scopeid?: number;
11
+ }
12
+ /**
13
+ * An interface as the addon reads it
14
+ */
15
+ export interface NativeInterface {
16
+ name: string;
17
+ index: number;
18
+ mac?: string;
19
+ up: boolean;
20
+ running: boolean;
21
+ loopback: boolean;
22
+ addresses: NativeAddress[];
23
+ }
24
+ /**
25
+ * The interfaces of the machine as the addon reads them
26
+ */
27
+ export declare function nativeList(): NativeInterface[];
28
+ /**
29
+ * Starts the notifications of the changes of the interfaces: changed() called at each one (once by thread)
30
+ */
31
+ export declare function nativeWatch(changed: () => void): void;
32
+ /**
33
+ * Stops the notifications
34
+ */
35
+ export declare function nativeUnwatch(): void;
36
+ /**
37
+ * A socket bound to the interface of the name (Linux): its descriptor and port
38
+ */
39
+ export declare function nativeBindSocket(name: string, family: 4 | 6, stream: boolean, port: number, backlog: number): {
40
+ fd: number;
41
+ port: number;
42
+ };
43
+ /**
44
+ * The socket of the descriptor joins or leaves the multicast group on the interface of the index (Linux)
45
+ */
46
+ export declare function nativeMembership(fd: number, group: string, index: number, join: boolean): void;
47
+ /**
48
+ * The setting that makes the system accept, through another interface, the packets for the addresses of the interface of
49
+ * the index; null when it refuses them (the strong host model of Windows and macOS)
50
+ */
51
+ export declare function nativeWeakReception(index: number, family: 4 | 6): {
52
+ interface: string;
53
+ setting: string;
54
+ } | null;