appium-ios-tuntap 0.3.0 → 0.4.1

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 (36) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +20 -3
  3. package/binding.gyp +1 -1
  4. package/lib/index.d.ts +1 -1
  5. package/lib/index.js +1 -1
  6. package/lib/platform/create-platform.js +3 -0
  7. package/lib/platform/require-admin.d.ts +17 -0
  8. package/lib/platform/require-admin.js +32 -0
  9. package/lib/platform/windows.d.ts +13 -0
  10. package/lib/platform/windows.js +195 -0
  11. package/lib/tunnel/constants.d.ts +10 -0
  12. package/lib/tunnel/constants.js +10 -0
  13. package/lib/tunnel/index.d.ts +2 -0
  14. package/lib/tunnel/index.js +1 -0
  15. package/lib/{tunnel.d.ts → tunnel/manager.d.ts} +9 -59
  16. package/lib/{tunnel.js → tunnel/manager.js} +231 -226
  17. package/lib/tunnel/types.d.ts +71 -0
  18. package/lib/tunnel/types.js +1 -0
  19. package/package.json +8 -4
  20. package/prebuilds/darwin-arm64/appium-ios-tuntap.node +0 -0
  21. package/prebuilds/darwin-x64/appium-ios-tuntap.node +0 -0
  22. package/prebuilds/linux-arm64/appium-ios-tuntap.node +0 -0
  23. package/prebuilds/linux-x64/appium-ios-tuntap.node +0 -0
  24. package/prebuilds/win32-arm64/appium-ios-tuntap.node +0 -0
  25. package/prebuilds/win32-x64/appium-ios-tuntap.node +0 -0
  26. package/scripts/fetch-wintun.mjs +70 -0
  27. package/src/native/posix_uv_poll_loop.cc +21 -18
  28. package/src/native/tun_backend_darwin.cc +6 -4
  29. package/src/native/wintun_loader.cc +26 -0
  30. package/src/tuntap.cc +9 -2
  31. package/vendor/wintun/LICENSE.txt +84 -0
  32. package/vendor/wintun/README.md +37 -0
  33. package/vendor/wintun/bin/amd64/wintun.dll +0 -0
  34. package/vendor/wintun/bin/arm/wintun.dll +0 -0
  35. package/vendor/wintun/bin/arm64/wintun.dll +0 -0
  36. package/vendor/wintun/bin/x86/wintun.dll +0 -0
package/CHANGELOG.md CHANGED
@@ -1,3 +1,15 @@
1
+ ## [0.4.1](https://github.com/appium/appium-ios-tuntap/compare/v0.4.0...v0.4.1) (2026-05-31)
2
+
3
+ ### Bug Fixes
4
+
5
+ * Improve tunnel performance ([#45](https://github.com/appium/appium-ios-tuntap/issues/45)) ([576d353](https://github.com/appium/appium-ios-tuntap/commit/576d3535137bb0cf79634ab820b3675db6cbbb86))
6
+
7
+ ## [0.4.0](https://github.com/appium/appium-ios-tuntap/compare/v0.3.0...v0.4.0) (2026-05-30)
8
+
9
+ ### Features
10
+
11
+ * implement Windows (WinTun) JavaScript platform layer ([#44](https://github.com/appium/appium-ios-tuntap/issues/44)) ([da2a9bb](https://github.com/appium/appium-ios-tuntap/commit/da2a9bba1d7226f67ce0f00c533df72164aac858))
12
+
1
13
  ## [0.3.0](https://github.com/appium/appium-ios-tuntap/compare/v0.2.5...v0.3.0) (2026-05-22)
2
14
 
3
15
  ### Features
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # TunTap Bridge
2
2
 
3
- A native TUN/TAP interface module for Node.js that works on both macOS and Linux, with enhanced error handling, signal management, and thread safety.
3
+ A native TUN/TAP interface module for Node.js that works on macOS, Linux, and Windows, with enhanced error handling, signal management, and thread safety.
4
4
 
5
5
  ## Description
6
6
 
@@ -8,7 +8,7 @@ This module provides a Node.js interface to TUN/TAP virtual network devices, all
8
8
 
9
9
  ## Features
10
10
 
11
- - **Cross-platform**: Works on macOS (utun) and Linux (TUN/TAP)
11
+ - **Cross-platform**: Works on macOS (utun), Linux (TUN/TAP), and Windows (WinTun)
12
12
  - **TypeScript support**: Full TypeScript definitions included
13
13
  - **Signal handling**: Graceful shutdown on SIGINT/SIGTERM
14
14
  - **Thread safety**: Safe to use from multiple Node.js worker threads
@@ -88,6 +88,14 @@ On Linux, the module requires:
88
88
  sudo pacman -S linux-headers
89
89
  ```
90
90
 
91
+ ### Windows
92
+
93
+ On Windows the module uses [WinTun](https://www.wintun.net/) (the same userspace TUN driver shipped with WireGuard). Requirements:
94
+
95
+ 1. **`wintun.dll`**: ships with the package. The official signed binaries for `amd64`, `arm64`, `x86`, and `arm` are bundled under `vendor/wintun/bin/<arch>/wintun.dll`; the addon discovers the right one automatically based on its own compile-time architecture. No download or copy step is required.
96
+ 2. **Administrator privileges**: required to create the kernel adapter and configure addresses/routes via `netsh`. Launch your shell with **Run as administrator**.
97
+ 3. **Build toolchain (only if compiling from source)**: Visual Studio Build Tools 2022 with the C++ workload, the Windows 10 SDK, and Python 3.x on `PATH`.
98
+
91
99
  ## Usage
92
100
 
93
101
  ### Basic Usage
@@ -207,7 +215,7 @@ socket.connect(port, host, async () => {
207
215
 
208
216
  #### Properties
209
217
  - `name: string` - The device name (e.g., 'utun0', 'tun0')
210
- - `fd: number` - The file descriptor of the device
218
+ - `fd: number` - The native file descriptor on POSIX (macOS/Linux). Returns `-1` on Windows; Wintun does not expose a numeric file descriptor.
211
219
 
212
220
  ### Error Types
213
221
 
@@ -294,3 +302,12 @@ This ensures the signal handler works as intended.
294
302
  ## License
295
303
 
296
304
  Apache-2.0
305
+
306
+ ### Third-party software
307
+
308
+ This package redistributes the official signed **WinTun** DLLs (version 0.14.1) from [wintun.net](https://www.wintun.net/) under the bundled-binary license shipped by the WinTun project. The unmodified binaries and the upstream license live under [vendor/wintun/](vendor/wintun/):
309
+
310
+ - `vendor/wintun/bin/{amd64,arm64,x86,arm}/wintun.dll`
311
+ - `vendor/wintun/LICENSE.txt` &mdash; the upstream WinTun license; required when redistributing the DLL
312
+
313
+ Maintainers can refresh the bundled binaries with `npm run refresh:wintun` after bumping `WINTUN_VERSION` in [scripts/fetch-wintun.mjs](scripts/fetch-wintun.mjs).
package/binding.gyp CHANGED
@@ -51,7 +51,7 @@
51
51
  "VCCLCompilerTool": {
52
52
  "ExceptionHandling": 1,
53
53
  "AdditionalOptions": [
54
- "/std:c++17",
54
+ "/std:c++20",
55
55
  "/O2"
56
56
  ]
57
57
  }
package/lib/index.d.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  export { TunTapDeviceError, TunTapError, TunTapPermissionError } from './errors.js';
2
2
  export { TunTap, type PacketCallback } from './TunTap.js';
3
- export * from './tunnel.js';
3
+ export * from './tunnel/index.js';
package/lib/index.js CHANGED
@@ -1,3 +1,3 @@
1
1
  export { TunTapDeviceError, TunTapError, TunTapPermissionError } from './errors.js';
2
2
  export { TunTap } from './TunTap.js';
3
- export * from './tunnel.js';
3
+ export * from './tunnel/index.js';
@@ -1,6 +1,7 @@
1
1
  import { DarwinTunTapPlatform } from './darwin.js';
2
2
  import { LinuxTunTapPlatform } from './linux.js';
3
3
  import { UnsupportedTunTapPlatform } from './unsupported.js';
4
+ import { WindowsTunTapPlatform } from './windows.js';
4
5
  /** @internal Built-in {@link TunTapPlatform} for a Node `process.platform` value. */
5
6
  export function createTunTapPlatform(platform) {
6
7
  switch (platform) {
@@ -8,6 +9,8 @@ export function createTunTapPlatform(platform) {
8
9
  return new DarwinTunTapPlatform();
9
10
  case 'linux':
10
11
  return new LinuxTunTapPlatform();
12
+ case 'win32':
13
+ return new WindowsTunTapPlatform();
11
14
  default:
12
15
  return new UnsupportedTunTapPlatform(platform);
13
16
  }
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Throws {@link TunTapPermissionError} unless the current process is an
3
+ * elevated (Administrator) Windows process. Mirrors `assertEffectiveRoot`
4
+ * from {@link ./require-root.ts} for POSIX.
5
+ */
6
+ export declare function assertAdminOnWindows(): Promise<void>;
7
+ /**
8
+ * Returns true when the current process is running with Administrator
9
+ * privileges on Windows. Implementation runs `net session` (which always
10
+ * exists, regardless of locale) and inspects the exit code.
11
+ *
12
+ * The result is memoized for the lifetime of the process; admin status cannot
13
+ * change between calls without restarting the shell.
14
+ */
15
+ export declare const isAdministrator: (() => Promise<boolean>) & {
16
+ cache: Map<unknown, Promise<boolean>>;
17
+ };
@@ -0,0 +1,32 @@
1
+ import { util } from '@appium/support';
2
+ import { TunTapPermissionError } from '../errors.js';
3
+ import { execFileAsync } from './exec.js';
4
+ /**
5
+ * Throws {@link TunTapPermissionError} unless the current process is an
6
+ * elevated (Administrator) Windows process. Mirrors `assertEffectiveRoot`
7
+ * from {@link ./require-root.ts} for POSIX.
8
+ */
9
+ export async function assertAdminOnWindows() {
10
+ if (await isAdministrator()) {
11
+ return;
12
+ }
13
+ throw new TunTapPermissionError('TUN interface configuration and routing require Administrator privileges on Windows. ' +
14
+ 'Re-launch the shell with "Run as administrator".');
15
+ }
16
+ /**
17
+ * Returns true when the current process is running with Administrator
18
+ * privileges on Windows. Implementation runs `net session` (which always
19
+ * exists, regardless of locale) and inspects the exit code.
20
+ *
21
+ * The result is memoized for the lifetime of the process; admin status cannot
22
+ * change between calls without restarting the shell.
23
+ */
24
+ export const isAdministrator = util.memoize(async function isAdministratorUncached() {
25
+ try {
26
+ await execFileAsync('net', ['session'], { windowsHide: true });
27
+ return true;
28
+ }
29
+ catch {
30
+ return false;
31
+ }
32
+ });
@@ -0,0 +1,13 @@
1
+ import type { TunTapInterfaceStats, TunTapPlatform } from './types.js';
2
+ /** Windows implementation backed by `netsh` for configuration/routing and
3
+ * PowerShell `Get-NetAdapterStatistics` for byte counters. */
4
+ export declare class WindowsTunTapPlatform implements TunTapPlatform {
5
+ /** @inheritdoc */
6
+ configure(interfaceName: string, address: string, mtu: number): Promise<void>;
7
+ /** @inheritdoc */
8
+ addRoute(interfaceName: string, destination: string): Promise<void>;
9
+ /** @inheritdoc */
10
+ removeRoute(interfaceName: string, destination: string): Promise<void>;
11
+ /** @inheritdoc */
12
+ getStats(interfaceName: string): Promise<TunTapInterfaceStats>;
13
+ }
@@ -0,0 +1,195 @@
1
+ import { TunTapError } from '../errors.js';
2
+ import { log } from '../logger.js';
3
+ import { assertAdminOnWindows } from './require-admin.js';
4
+ import { execFileAsync } from './exec.js';
5
+ /** Tightly-restricted character set for adapter names passed into PowerShell. */
6
+ const SAFE_NAME_RE = /^[A-Za-z0-9_\- ]+$/;
7
+ /** Phrases that indicate `netsh` could not find the requested route/address. */
8
+ const MISSING_TARGET_HINTS = [
9
+ 'element not found',
10
+ 'cannot find',
11
+ 'no matching',
12
+ 'does not exist',
13
+ 'not found',
14
+ ];
15
+ /** Windows implementation backed by `netsh` for configuration/routing and
16
+ * PowerShell `Get-NetAdapterStatistics` for byte counters. */
17
+ export class WindowsTunTapPlatform {
18
+ /** @inheritdoc */
19
+ async configure(interfaceName, address, mtu) {
20
+ await assertAdminOnWindows();
21
+ assertSafeAdapterName(interfaceName);
22
+ log.debug(`[win] configure: interface=${interfaceName} address=${address} mtu=${mtu}`);
23
+ await addIpv6Address(interfaceName, address);
24
+ await setIpv6Mtu(interfaceName, mtu);
25
+ }
26
+ /** @inheritdoc */
27
+ async addRoute(interfaceName, destination) {
28
+ await assertAdminOnWindows();
29
+ assertSafeAdapterName(interfaceName);
30
+ log.debug(`[win] addRoute: interface=${interfaceName} destination=${destination}`);
31
+ await addIpv6Route(interfaceName, destination);
32
+ // WinTun presents as an Ethernet adapter, so Windows requires Neighbor
33
+ // Discovery (NDP) before it will send packets through the interface.
34
+ // For /128 host routes we seed a static neighbor entry so NDP is bypassed
35
+ // and the first connection attempt is not silently dropped.
36
+ if (destination.endsWith('/128')) {
37
+ const address = destination.slice(0, -4);
38
+ await addStaticNeighbor(interfaceName, address);
39
+ }
40
+ }
41
+ /** @inheritdoc */
42
+ async removeRoute(interfaceName, destination) {
43
+ await assertAdminOnWindows();
44
+ assertSafeAdapterName(interfaceName);
45
+ await deleteIpv6Route(interfaceName, destination);
46
+ }
47
+ /** @inheritdoc */
48
+ async getStats(interfaceName) {
49
+ assertSafeAdapterName(interfaceName);
50
+ const script = `Get-NetAdapterStatistics -Name '${interfaceName}' ` +
51
+ '| Select-Object ReceivedBytes,SentBytes,ReceivedUnicastPackets,' +
52
+ 'SentUnicastPackets,ReceivedDiscardedPackets,OutboundDiscardedPackets ' +
53
+ '| ConvertTo-Json -Compress';
54
+ const { stdout } = await execFileAsync('powershell', [
55
+ '-NoProfile',
56
+ '-NonInteractive',
57
+ '-ExecutionPolicy',
58
+ 'Bypass',
59
+ '-Command',
60
+ script,
61
+ ]);
62
+ let parsed;
63
+ try {
64
+ parsed = JSON.parse(stdout);
65
+ }
66
+ catch {
67
+ throw new TunTapError(`Failed to parse Get-NetAdapterStatistics output: ${stdout.trim()}`);
68
+ }
69
+ const num = (key) => {
70
+ const value = parsed[key];
71
+ const n = typeof value === 'number' ? value : parseInt(String(value ?? ''), 10);
72
+ return Number.isFinite(n) ? n : 0;
73
+ };
74
+ return {
75
+ rxBytes: num('ReceivedBytes'),
76
+ rxPackets: num('ReceivedUnicastPackets'),
77
+ rxErrors: num('ReceivedDiscardedPackets'),
78
+ txBytes: num('SentBytes'),
79
+ txPackets: num('SentUnicastPackets'),
80
+ txErrors: num('OutboundDiscardedPackets'),
81
+ };
82
+ }
83
+ }
84
+ /** Validates an adapter name before embedding in a PowerShell expression. */
85
+ function assertSafeAdapterName(interfaceName) {
86
+ if (!SAFE_NAME_RE.test(interfaceName)) {
87
+ throw new TunTapError(`Refusing to use adapter name with unsupported characters: ${JSON.stringify(interfaceName)}`);
88
+ }
89
+ }
90
+ function isMissingTargetError(err) {
91
+ const message = String(err?.message ?? '').toLowerCase();
92
+ return MISSING_TARGET_HINTS.some((hint) => message.includes(hint));
93
+ }
94
+ async function addIpv6Address(interfaceName, address) {
95
+ try {
96
+ const r = await execFileAsync('netsh', [
97
+ 'interface',
98
+ 'ipv6',
99
+ 'add',
100
+ 'address',
101
+ `interface=${interfaceName}`,
102
+ `address=${address}/64`,
103
+ 'store=active',
104
+ ]);
105
+ log.debug(`[win] add address ok: ${r.stdout.trim() || '(no output)'}`);
106
+ }
107
+ catch (err) {
108
+ const message = err.message ?? '';
109
+ log.warn(`[win] add address err: ${message}`);
110
+ if (!/already exists|object already/i.test(message)) {
111
+ throw err;
112
+ }
113
+ log.warn(`Address ${address} may already be configured on ${interfaceName}`);
114
+ }
115
+ }
116
+ async function setIpv6Mtu(interfaceName, mtu) {
117
+ try {
118
+ const r = await execFileAsync('netsh', [
119
+ 'interface',
120
+ 'ipv6',
121
+ 'set',
122
+ 'subinterface',
123
+ interfaceName,
124
+ `mtu=${mtu}`,
125
+ 'store=active',
126
+ ]);
127
+ log.debug(`[win] set mtu ok: ${r.stdout.trim() || '(no output)'}`);
128
+ }
129
+ catch (err) {
130
+ log.warn(`[win] set mtu err: ${err.message ?? err}`);
131
+ throw err;
132
+ }
133
+ }
134
+ async function addIpv6Route(interfaceName, destination) {
135
+ try {
136
+ const r = await execFileAsync('netsh', [
137
+ 'interface',
138
+ 'ipv6',
139
+ 'add',
140
+ 'route',
141
+ destination,
142
+ interfaceName,
143
+ 'store=active',
144
+ ]);
145
+ log.debug(`[win] add route ok: ${r.stdout.trim() || '(no output)'}`);
146
+ }
147
+ catch (err) {
148
+ const message = err.message ?? '';
149
+ log.warn(`[win] add route err: ${message}`);
150
+ if (/already exists|object already/i.test(message)) {
151
+ log.debug(`Route to ${destination} already exists`);
152
+ return;
153
+ }
154
+ throw err;
155
+ }
156
+ }
157
+ async function deleteIpv6Route(interfaceName, destination) {
158
+ try {
159
+ await execFileAsync('netsh', [
160
+ 'interface',
161
+ 'ipv6',
162
+ 'delete',
163
+ 'route',
164
+ destination,
165
+ interfaceName,
166
+ 'store=active',
167
+ ]);
168
+ }
169
+ catch (err) {
170
+ if (isMissingTargetError(err)) {
171
+ return;
172
+ }
173
+ throw err;
174
+ }
175
+ }
176
+ async function addStaticNeighbor(interfaceName, address) {
177
+ log.debug(`[win] addStaticNeighbor: interface=${interfaceName} address=${address}`);
178
+ try {
179
+ const r = await execFileAsync('netsh', [
180
+ 'interface',
181
+ 'ipv6',
182
+ 'add',
183
+ 'neighbor',
184
+ interfaceName,
185
+ address,
186
+ '00-00-00-00-00-01',
187
+ 'store=active',
188
+ ]);
189
+ log.debug(`[win] add neighbor ok: ${r.stdout.trim() || '(no output)'}`);
190
+ }
191
+ catch (err) {
192
+ const msg = err.message ?? String(err);
193
+ log.warn(`[win] add neighbor err: ${msg}`);
194
+ }
195
+ }
@@ -0,0 +1,10 @@
1
+ /** CDTunnel lockdown handshake MTU (IPv6 minimum). */
2
+ export declare const CD_TUNNEL_MTU = 1280;
3
+ export declare const CD_TUNNEL_MAGIC = "CDTunnel";
4
+ export declare const CD_TUNNEL_MAGIC_SIZE = 8;
5
+ export declare const CD_TUNNEL_HEADER_SIZE: number;
6
+ export declare const CD_TUNNEL_HANDSHAKE_TIMEOUT_MS = 30000;
7
+ export declare const IPV6_HEADER_SIZE = 40;
8
+ export declare const IPV6_VERSION = 6;
9
+ export declare const IPPROTO_TCP = 6;
10
+ export declare const IPPROTO_UDP = 17;
@@ -0,0 +1,10 @@
1
+ /** CDTunnel lockdown handshake MTU (IPv6 minimum). */
2
+ export const CD_TUNNEL_MTU = 1280;
3
+ export const CD_TUNNEL_MAGIC = 'CDTunnel';
4
+ export const CD_TUNNEL_MAGIC_SIZE = 8;
5
+ export const CD_TUNNEL_HEADER_SIZE = CD_TUNNEL_MAGIC_SIZE + 2;
6
+ export const CD_TUNNEL_HANDSHAKE_TIMEOUT_MS = 30_000;
7
+ export const IPV6_HEADER_SIZE = 40;
8
+ export const IPV6_VERSION = 6;
9
+ export const IPPROTO_TCP = 6;
10
+ export const IPPROTO_UDP = 17;
@@ -0,0 +1,2 @@
1
+ export type { PacketConsumer, PacketData, TunnelConnection, TunnelManagerEvents } from './types.js';
2
+ export { TunnelManager, connectToTunnelLockdown, exchangeCoreTunnelParameters } from './manager.js';
@@ -0,0 +1 @@
1
+ export { TunnelManager, connectToTunnelLockdown, exchangeCoreTunnelParameters } from './manager.js';
@@ -1,57 +1,7 @@
1
- import { TunTap } from './TunTap.js';
1
+ import { TunTap } from '../TunTap.js';
2
2
  import { EventEmitter } from 'node:events';
3
- import { Socket } from 'node:net';
4
- import { Buffer } from 'node:buffer';
5
- export interface PacketData {
6
- protocol: 'TCP' | 'UDP';
7
- src: string;
8
- dst: string;
9
- sourcePort: number;
10
- destPort: number;
11
- payload: Buffer;
12
- }
13
- /**
14
- * Event names and listener argument tuples for {@link TunnelManager}
15
- * (matches Node’s `EventEmitter` event map shape).
16
- *
17
- * @example
18
- * tunnelManager.on('data', (packet) => {
19
- * // `packet` is PacketData
20
- * });
21
- */
22
- export interface PacketConsumer {
23
- /**
24
- * Invoked for each parsed TCP/UDP payload extracted from the tunnel stream.
25
- *
26
- * @param packet — decoded addresses, ports, and payload
27
- */
28
- onPacket(packet: PacketData): void;
29
- }
30
- export interface TunnelManagerEvents {
31
- data: [packet: PacketData];
32
- }
33
- export interface TunnelConnection {
34
- Address: string;
35
- RsdPort?: number;
36
- tunnelManager: TunnelManager;
37
- /** Tear down the tunnel, close the TUN device, and end the socket when appropriate. */
38
- closer: () => Promise<void>;
39
- /** @param consumer — receives packets for the lifetime of the registration */
40
- addPacketConsumer(consumer: PacketConsumer): void;
41
- /** @param consumer — must be the same reference passed to {@link TunnelConnection.addPacketConsumer} */
42
- removePacketConsumer(consumer: PacketConsumer): void;
43
- /** @returns async iterator of packets until the tunnel is stopped */
44
- getPacketStream(): AsyncIterable<PacketData>;
45
- }
46
- interface TunnelClientParameters {
47
- address: string;
48
- mtu: number;
49
- }
50
- interface TunnelInfo {
51
- clientParameters: TunnelClientParameters;
52
- serverAddress: string;
53
- serverRSDPort?: number;
54
- }
3
+ import type { Socket } from 'node:net';
4
+ import type { PacketConsumer, PacketData, TunnelConnection, TunnelInfo, TunnelManagerEvents } from './types.js';
55
5
  /**
56
6
  * Bridges a CoreDevice tunnel `Socket` and a {@link TunTap} interface: IPv6 framing, TUN I/O, and packet fan-out.
57
7
  * Emits {@link TunnelManagerEvents} (currently `data` with {@link PacketData}) for TCP/UDP packets, same as registered consumers.
@@ -59,14 +9,11 @@ interface TunnelInfo {
59
9
  export declare class TunnelManager extends EventEmitter<TunnelManagerEvents> {
60
10
  private tun;
61
11
  private cancelled;
62
- private readInterval;
12
+ private mtu;
63
13
  private buffer;
64
- private packetConsumers;
65
- private packetQueue;
14
+ private readonly packetConsumers;
66
15
  private deviceConn;
67
16
  private cleanupPromise;
68
- /** Creates a manager with no TUN device until {@link TunnelManager.setupInterface} succeeds. */
69
- constructor();
70
17
  /**
71
18
  * Register a listener for parsed tunnel packets (in addition to the `data` event).
72
19
  *
@@ -108,7 +55,11 @@ export declare class TunnelManager extends EventEmitter<TunnelManagerEvents> {
108
55
  * @returns the same promise if already stopping/stopped
109
56
  */
110
57
  stop(): Promise<void>;
58
+ private hasPacketTap;
111
59
  private processBuffer;
60
+ private writeDeviceFrameToTun;
61
+ private tapL4Packet;
62
+ private dispatchPacketData;
112
63
  private startTunReadLoop;
113
64
  private _performStop;
114
65
  }
@@ -126,4 +77,3 @@ export declare function exchangeCoreTunnelParameters(socket: Socket): Promise<Tu
126
77
  * @returns connection handle with {@link TunnelConnection.closer} and packet APIs
127
78
  */
128
79
  export declare function connectToTunnelLockdown(secureServiceSocket: Socket): Promise<TunnelConnection>;
129
- export {};