@net-mesh/browser 0.37.0 → 0.38.0
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.
- package/CHANGELOG.md +48 -0
- package/dist/errors.d.ts +7 -1
- package/dist/errors.js +15 -7
- package/dist/events.d.ts +6 -0
- package/dist/events.js +13 -0
- package/dist/index.bundle.js +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/net_leaf.d.ts +10 -9
- package/dist/net_leaf.js +52 -39
- package/dist/net_leaf_bg.wasm +0 -0
- package/dist/net_leaf_bg.wasm.d.ts +10 -9
- package/dist/node.d.ts +12 -1
- package/dist/node.js +23 -7
- package/dist/udp-probe.d.ts +68 -0
- package/dist/udp-probe.js +89 -5
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -24,8 +24,8 @@ export { EventHub, fromBase64, parseEvent, parseJsonPreservingU64, toBase64, U64
|
|
|
24
24
|
export type { AnnouncementEvent, ChannelMessageEvent, ConnectedEvent, DisconnectedEvent, DroppedEvent, LeafEvent, LeafEventOf, RpcResponseEvent, RtcFailureEvent, SignalEvent, StreamDataEvent, UnknownEvent, Unsubscribe, } from './events.js';
|
|
25
25
|
export { ControlPlaneError, IceServerConflictError, IdentityError, isUdpBlocked, LeafError, NotLeaderError, OrgAdmissionDeniedError, OrgCancelledError, OrgIndeterminateError, OrgInternalError, OrgLeaderLostError, OrgMalformedError, OrgRefusedError, OrgRevokedError, OrgSessionLostError, OrgStreamError, OrgTimeoutError, ORG_SINK_CLOSED_REFUSAL, coarseAdmissionReason, orgRetireError, orgRetireReason, orgTerminalError, parseLeafError, parseOrgError, parseRpcFailure, parseRtcFailure, RpcError, RtcError, SessionError, udpBlockedEvidence, UnknownLeafError, WireError, fromWasmError, } from './errors.js';
|
|
26
26
|
export type { CoarseAdmissionReason, LeafErrorKind, OrgErrorKind, OrgRetireReason, RpcErrorFailure, RtcErrorFailure, UdpBlockedEvidence, } from './errors.js';
|
|
27
|
-
export { classifyRtcError, classifyRtcFailure, diagnosticStunUrl, probeBootstrapReachable, probeStunBinding, reflexiveAddress, } from './udp-probe.js';
|
|
28
|
-
export type { BootstrapProbeOptions, IceFailureClassification, RtcFailureObservations, StunProbeOptions, StunProbeOutcome, } from './udp-probe.js';
|
|
27
|
+
export { candidateLineIsReflexive, classifyRtcError, classifyRtcFailure, classifyRtcFailureAll, diagnosticStunUrl, probeBootstrapReachable, probeEventAnswers, probeStunBinding, probeStunBindings, reflexiveAddress, stunProbeAnswered, stunProbeVerdict, } from './udp-probe.js';
|
|
28
|
+
export type { BootstrapProbeOptions, EndpointProbe, IceFailureClassification, ProbeEvent, RtcFailureObservations, StunProbeOptions, StunProbeOutcome, } from './udp-probe.js';
|
|
29
29
|
export { loadLeafWasm } from './wasm.js';
|
|
30
30
|
export type { LeafWasmConnectOptions, LeafWasmModule, LeafWasmNode, LeafWasmProxyStream, LeafWasmStream, LeafWasmStreamLike, LeafWasmStreamOptions, StreamCallbackPayload, StreamReliability, WasmSource, } from './wasm.js';
|
|
31
31
|
export { AsyncQueue } from './async-queue.js';
|
package/dist/index.js
CHANGED
|
@@ -23,7 +23,7 @@ export { LeafStream } from './stream.js';
|
|
|
23
23
|
export { OrgDuplex, OrgHandleRegistry, OrgRequests, OrgServe, OrgSink, OrgStream, OrgUpload, parseOrgCaller, toWasmOrgCallOptions, toWasmOrgServeOptions, } from './org.js';
|
|
24
24
|
export { EventHub, fromBase64, parseEvent, parseJsonPreservingU64, toBase64, U64_EVENT_KEYS, } from './events.js';
|
|
25
25
|
export { ControlPlaneError, IceServerConflictError, IdentityError, isUdpBlocked, LeafError, NotLeaderError, OrgAdmissionDeniedError, OrgCancelledError, OrgIndeterminateError, OrgInternalError, OrgLeaderLostError, OrgMalformedError, OrgRefusedError, OrgRevokedError, OrgSessionLostError, OrgStreamError, OrgTimeoutError, ORG_SINK_CLOSED_REFUSAL, coarseAdmissionReason, orgRetireError, orgRetireReason, orgTerminalError, parseLeafError, parseOrgError, parseRpcFailure, parseRtcFailure, RpcError, RtcError, SessionError, udpBlockedEvidence, UnknownLeafError, WireError, fromWasmError, } from './errors.js';
|
|
26
|
-
export { classifyRtcError, classifyRtcFailure, diagnosticStunUrl, probeBootstrapReachable, probeStunBinding, reflexiveAddress, } from './udp-probe.js';
|
|
26
|
+
export { candidateLineIsReflexive, classifyRtcError, classifyRtcFailure, classifyRtcFailureAll, diagnosticStunUrl, probeBootstrapReachable, probeEventAnswers, probeStunBinding, probeStunBindings, reflexiveAddress, stunProbeAnswered, stunProbeVerdict, } from './udp-probe.js';
|
|
27
27
|
export { loadLeafWasm } from './wasm.js';
|
|
28
28
|
export { AsyncQueue } from './async-queue.js';
|
|
29
29
|
// §8's leader/follower surface: `openSession`, `MeshSession`, the five
|
package/dist/net_leaf.d.ts
CHANGED
|
@@ -1453,15 +1453,16 @@ export interface InitOutput {
|
|
|
1453
1453
|
readonly proxystream_send: (a: number, b: number) => number;
|
|
1454
1454
|
readonly proxystream_stream_id_hex: (a: number, b: number) => void;
|
|
1455
1455
|
readonly start: () => void;
|
|
1456
|
-
readonly
|
|
1457
|
-
readonly
|
|
1458
|
-
readonly
|
|
1459
|
-
readonly
|
|
1460
|
-
readonly
|
|
1461
|
-
readonly
|
|
1462
|
-
readonly
|
|
1463
|
-
readonly
|
|
1464
|
-
readonly
|
|
1456
|
+
readonly __wasm_bindgen_func_elem_6603: (a: number, b: number, c: number, d: number) => void;
|
|
1457
|
+
readonly __wasm_bindgen_func_elem_6605: (a: number, b: number, c: number, d: number) => void;
|
|
1458
|
+
readonly __wasm_bindgen_func_elem_2410: (a: number, b: number, c: number) => number;
|
|
1459
|
+
readonly __wasm_bindgen_func_elem_2411: (a: number, b: number, c: number) => void;
|
|
1460
|
+
readonly __wasm_bindgen_func_elem_2411_112: (a: number, b: number, c: number) => void;
|
|
1461
|
+
readonly __wasm_bindgen_func_elem_2411_113: (a: number, b: number, c: number) => void;
|
|
1462
|
+
readonly __wasm_bindgen_func_elem_2411_114: (a: number, b: number, c: number) => void;
|
|
1463
|
+
readonly __wasm_bindgen_func_elem_2411_115: (a: number, b: number, c: number) => void;
|
|
1464
|
+
readonly __wasm_bindgen_func_elem_2411_116: (a: number, b: number, c: number) => void;
|
|
1465
|
+
readonly __wasm_bindgen_func_elem_2411_117: (a: number, b: number, c: number) => void;
|
|
1465
1466
|
readonly __wbindgen_export: (a: number, b: number) => number;
|
|
1466
1467
|
readonly __wbindgen_export2: (a: number, b: number, c: number, d: number) => number;
|
|
1467
1468
|
readonly __wbindgen_export3: (a: number) => void;
|
package/dist/net_leaf.js
CHANGED
|
@@ -2710,11 +2710,15 @@ function __wbg_get_imports() {
|
|
|
2710
2710
|
const ret = getObject(arg0).encrypt(getObject(arg1), getObject(arg2), getArrayU8FromWasm0(arg3, arg4));
|
|
2711
2711
|
return addHeapObject(ret);
|
|
2712
2712
|
}, arguments); },
|
|
2713
|
+
__wbg_errorCode_708483a8c58cdc74: function(arg0) {
|
|
2714
|
+
const ret = getObject(arg0).errorCode;
|
|
2715
|
+
return ret;
|
|
2716
|
+
},
|
|
2713
2717
|
__wbg_error_3da0c81bd4184d52: function(arg0) {
|
|
2714
2718
|
const ret = getObject(arg0).error;
|
|
2715
2719
|
return isLikeNone(ret) ? 0 : addHeapObject(ret);
|
|
2716
2720
|
},
|
|
2717
|
-
|
|
2721
|
+
__wbg_error_454d6c106cd708a7: function(arg0, arg1) {
|
|
2718
2722
|
console.error(getStringFromWasm0(arg0, arg1));
|
|
2719
2723
|
},
|
|
2720
2724
|
__wbg_error_6a23b57453026a47: function() { return handleError(function (arg0) {
|
|
@@ -2910,7 +2914,7 @@ function __wbg_get_imports() {
|
|
|
2910
2914
|
const a = state0.a;
|
|
2911
2915
|
state0.a = 0;
|
|
2912
2916
|
try {
|
|
2913
|
-
return
|
|
2917
|
+
return __wasm_bindgen_func_elem_6605(a, state0.b, arg0, arg1);
|
|
2914
2918
|
} finally {
|
|
2915
2919
|
state0.a = a;
|
|
2916
2920
|
}
|
|
@@ -2952,7 +2956,7 @@ function __wbg_get_imports() {
|
|
|
2952
2956
|
const a = state0.a;
|
|
2953
2957
|
state0.a = 0;
|
|
2954
2958
|
try {
|
|
2955
|
-
return
|
|
2959
|
+
return __wasm_bindgen_func_elem_6605(a, state0.b, arg0, arg1);
|
|
2956
2960
|
} finally {
|
|
2957
2961
|
state0.a = a;
|
|
2958
2962
|
}
|
|
@@ -3261,51 +3265,56 @@ function __wbg_get_imports() {
|
|
|
3261
3265
|
console.warn(getObject(arg0));
|
|
3262
3266
|
},
|
|
3263
3267
|
__wbindgen_generic_0000000000000001: function(arg0, arg1) {
|
|
3264
|
-
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [Externref], shim_idx:
|
|
3265
|
-
const ret = makeMutClosure(arg0, arg1,
|
|
3268
|
+
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [Externref], shim_idx: 34, ret: Externref, inner_ret: Some(Externref) }, mutable: true }) -> Externref`.
|
|
3269
|
+
const ret = makeMutClosure(arg0, arg1, __wasm_bindgen_func_elem_2410);
|
|
3266
3270
|
return addHeapObject(ret);
|
|
3267
3271
|
},
|
|
3268
3272
|
__wbindgen_generic_0000000000000002: function(arg0, arg1) {
|
|
3269
|
-
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [Externref], shim_idx:
|
|
3270
|
-
const ret = makeMutClosure(arg0, arg1,
|
|
3273
|
+
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [Externref], shim_idx: 35, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
|
|
3274
|
+
const ret = makeMutClosure(arg0, arg1, __wasm_bindgen_func_elem_2411);
|
|
3271
3275
|
return addHeapObject(ret);
|
|
3272
3276
|
},
|
|
3273
3277
|
__wbindgen_generic_0000000000000003: function(arg0, arg1) {
|
|
3274
|
-
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [Externref], shim_idx:
|
|
3275
|
-
const ret = makeMutClosure(arg0, arg1,
|
|
3278
|
+
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [Externref], shim_idx: 907, ret: Result(Unit), inner_ret: Some(Result(Unit)) }, mutable: true }) -> Externref`.
|
|
3279
|
+
const ret = makeMutClosure(arg0, arg1, __wasm_bindgen_func_elem_6603);
|
|
3276
3280
|
return addHeapObject(ret);
|
|
3277
3281
|
},
|
|
3278
3282
|
__wbindgen_generic_0000000000000004: function(arg0, arg1) {
|
|
3279
|
-
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [NamedExternref("CloseEvent")], shim_idx:
|
|
3280
|
-
const ret = makeMutClosure(arg0, arg1,
|
|
3283
|
+
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [NamedExternref("CloseEvent")], shim_idx: 35, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
|
|
3284
|
+
const ret = makeMutClosure(arg0, arg1, __wasm_bindgen_func_elem_2411_112);
|
|
3281
3285
|
return addHeapObject(ret);
|
|
3282
3286
|
},
|
|
3283
3287
|
__wbindgen_generic_0000000000000005: function(arg0, arg1) {
|
|
3284
|
-
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [NamedExternref("Event")], shim_idx:
|
|
3285
|
-
const ret = makeMutClosure(arg0, arg1,
|
|
3288
|
+
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [NamedExternref("Event")], shim_idx: 35, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
|
|
3289
|
+
const ret = makeMutClosure(arg0, arg1, __wasm_bindgen_func_elem_2411_113);
|
|
3286
3290
|
return addHeapObject(ret);
|
|
3287
3291
|
},
|
|
3288
3292
|
__wbindgen_generic_0000000000000006: function(arg0, arg1) {
|
|
3289
|
-
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [NamedExternref("MessageEvent")], shim_idx:
|
|
3290
|
-
const ret = makeMutClosure(arg0, arg1,
|
|
3293
|
+
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [NamedExternref("MessageEvent")], shim_idx: 35, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
|
|
3294
|
+
const ret = makeMutClosure(arg0, arg1, __wasm_bindgen_func_elem_2411_114);
|
|
3291
3295
|
return addHeapObject(ret);
|
|
3292
3296
|
},
|
|
3293
3297
|
__wbindgen_generic_0000000000000007: function(arg0, arg1) {
|
|
3294
|
-
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [NamedExternref("RTCDataChannelEvent")], shim_idx:
|
|
3295
|
-
const ret = makeMutClosure(arg0, arg1,
|
|
3298
|
+
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [NamedExternref("RTCDataChannelEvent")], shim_idx: 35, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
|
|
3299
|
+
const ret = makeMutClosure(arg0, arg1, __wasm_bindgen_func_elem_2411_115);
|
|
3296
3300
|
return addHeapObject(ret);
|
|
3297
3301
|
},
|
|
3298
3302
|
__wbindgen_generic_0000000000000008: function(arg0, arg1) {
|
|
3299
|
-
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [NamedExternref("
|
|
3300
|
-
const ret = makeMutClosure(arg0, arg1,
|
|
3303
|
+
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [NamedExternref("RTCPeerConnectionIceErrorEvent")], shim_idx: 35, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
|
|
3304
|
+
const ret = makeMutClosure(arg0, arg1, __wasm_bindgen_func_elem_2411_116);
|
|
3305
|
+
return addHeapObject(ret);
|
|
3306
|
+
},
|
|
3307
|
+
__wbindgen_generic_0000000000000009: function(arg0, arg1) {
|
|
3308
|
+
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [NamedExternref("RTCPeerConnectionIceEvent")], shim_idx: 35, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
|
|
3309
|
+
const ret = makeMutClosure(arg0, arg1, __wasm_bindgen_func_elem_2411_117);
|
|
3301
3310
|
return addHeapObject(ret);
|
|
3302
3311
|
},
|
|
3303
|
-
|
|
3312
|
+
__wbindgen_generic_000000000000000a: function(arg0) {
|
|
3304
3313
|
// Cast intrinsic for `F64 -> Externref`.
|
|
3305
3314
|
const ret = arg0;
|
|
3306
3315
|
return addHeapObject(ret);
|
|
3307
3316
|
},
|
|
3308
|
-
|
|
3317
|
+
__wbindgen_generic_000000000000000b: function(arg0, arg1) {
|
|
3309
3318
|
// Cast intrinsic for `Ref(String) -> Externref`.
|
|
3310
3319
|
const ret = getStringFromWasm0(arg0, arg1);
|
|
3311
3320
|
return addHeapObject(ret);
|
|
@@ -3324,43 +3333,47 @@ function __wbg_get_imports() {
|
|
|
3324
3333
|
};
|
|
3325
3334
|
}
|
|
3326
3335
|
|
|
3327
|
-
function
|
|
3328
|
-
wasm.
|
|
3336
|
+
function __wasm_bindgen_func_elem_2411(arg0, arg1, arg2) {
|
|
3337
|
+
wasm.__wasm_bindgen_func_elem_2411(arg0, arg1, addHeapObject(arg2));
|
|
3338
|
+
}
|
|
3339
|
+
|
|
3340
|
+
function __wasm_bindgen_func_elem_2411_112(arg0, arg1, arg2) {
|
|
3341
|
+
wasm.__wasm_bindgen_func_elem_2411_112(arg0, arg1, addHeapObject(arg2));
|
|
3329
3342
|
}
|
|
3330
3343
|
|
|
3331
|
-
function
|
|
3332
|
-
wasm.
|
|
3344
|
+
function __wasm_bindgen_func_elem_2411_113(arg0, arg1, arg2) {
|
|
3345
|
+
wasm.__wasm_bindgen_func_elem_2411_113(arg0, arg1, addHeapObject(arg2));
|
|
3333
3346
|
}
|
|
3334
3347
|
|
|
3335
|
-
function
|
|
3336
|
-
wasm.
|
|
3348
|
+
function __wasm_bindgen_func_elem_2411_114(arg0, arg1, arg2) {
|
|
3349
|
+
wasm.__wasm_bindgen_func_elem_2411_114(arg0, arg1, addHeapObject(arg2));
|
|
3337
3350
|
}
|
|
3338
3351
|
|
|
3339
|
-
function
|
|
3340
|
-
wasm.
|
|
3352
|
+
function __wasm_bindgen_func_elem_2411_115(arg0, arg1, arg2) {
|
|
3353
|
+
wasm.__wasm_bindgen_func_elem_2411_115(arg0, arg1, addHeapObject(arg2));
|
|
3341
3354
|
}
|
|
3342
3355
|
|
|
3343
|
-
function
|
|
3344
|
-
wasm.
|
|
3356
|
+
function __wasm_bindgen_func_elem_2411_116(arg0, arg1, arg2) {
|
|
3357
|
+
wasm.__wasm_bindgen_func_elem_2411_116(arg0, arg1, addHeapObject(arg2));
|
|
3345
3358
|
}
|
|
3346
3359
|
|
|
3347
|
-
function
|
|
3348
|
-
wasm.
|
|
3360
|
+
function __wasm_bindgen_func_elem_2411_117(arg0, arg1, arg2) {
|
|
3361
|
+
wasm.__wasm_bindgen_func_elem_2411_117(arg0, arg1, addHeapObject(arg2));
|
|
3349
3362
|
}
|
|
3350
3363
|
|
|
3351
|
-
function
|
|
3352
|
-
const ret = wasm.
|
|
3364
|
+
function __wasm_bindgen_func_elem_2410(arg0, arg1, arg2) {
|
|
3365
|
+
const ret = wasm.__wasm_bindgen_func_elem_2410(arg0, arg1, addHeapObject(arg2));
|
|
3353
3366
|
return takeObject(ret);
|
|
3354
3367
|
}
|
|
3355
3368
|
|
|
3356
|
-
function
|
|
3357
|
-
wasm.
|
|
3369
|
+
function __wasm_bindgen_func_elem_6605(arg0, arg1, arg2, arg3) {
|
|
3370
|
+
wasm.__wasm_bindgen_func_elem_6605(arg0, arg1, addHeapObject(arg2), addHeapObject(arg3));
|
|
3358
3371
|
}
|
|
3359
3372
|
|
|
3360
|
-
function
|
|
3373
|
+
function __wasm_bindgen_func_elem_6603(arg0, arg1, arg2) {
|
|
3361
3374
|
try {
|
|
3362
3375
|
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
|
3363
|
-
wasm.
|
|
3376
|
+
wasm.__wasm_bindgen_func_elem_6603(retptr, arg0, arg1, addHeapObject(arg2));
|
|
3364
3377
|
var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
|
|
3365
3378
|
var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
|
|
3366
3379
|
if (r1) {
|
package/dist/net_leaf_bg.wasm
CHANGED
|
Binary file
|
|
@@ -119,15 +119,16 @@ export const proxystream_peer_node_hex: (a: number, b: number) => void;
|
|
|
119
119
|
export const proxystream_send: (a: number, b: number) => number;
|
|
120
120
|
export const proxystream_stream_id_hex: (a: number, b: number) => void;
|
|
121
121
|
export const start: () => void;
|
|
122
|
-
export const
|
|
123
|
-
export const
|
|
124
|
-
export const
|
|
125
|
-
export const
|
|
126
|
-
export const
|
|
127
|
-
export const
|
|
128
|
-
export const
|
|
129
|
-
export const
|
|
130
|
-
export const
|
|
122
|
+
export const __wasm_bindgen_func_elem_6603: (a: number, b: number, c: number, d: number) => void;
|
|
123
|
+
export const __wasm_bindgen_func_elem_6605: (a: number, b: number, c: number, d: number) => void;
|
|
124
|
+
export const __wasm_bindgen_func_elem_2410: (a: number, b: number, c: number) => number;
|
|
125
|
+
export const __wasm_bindgen_func_elem_2411: (a: number, b: number, c: number) => void;
|
|
126
|
+
export const __wasm_bindgen_func_elem_2411_112: (a: number, b: number, c: number) => void;
|
|
127
|
+
export const __wasm_bindgen_func_elem_2411_113: (a: number, b: number, c: number) => void;
|
|
128
|
+
export const __wasm_bindgen_func_elem_2411_114: (a: number, b: number, c: number) => void;
|
|
129
|
+
export const __wasm_bindgen_func_elem_2411_115: (a: number, b: number, c: number) => void;
|
|
130
|
+
export const __wasm_bindgen_func_elem_2411_116: (a: number, b: number, c: number) => void;
|
|
131
|
+
export const __wasm_bindgen_func_elem_2411_117: (a: number, b: number, c: number) => void;
|
|
131
132
|
export const __wbindgen_export: (a: number, b: number) => number;
|
|
132
133
|
export const __wbindgen_export2: (a: number, b: number, c: number, d: number) => number;
|
|
133
134
|
export const __wbindgen_export3: (a: number) => void;
|
package/dist/node.d.ts
CHANGED
|
@@ -302,6 +302,12 @@ export declare class BrowserNode {
|
|
|
302
302
|
private readonly orgHandles;
|
|
303
303
|
/** The last `rtc_addr` an anchor told us about; the probe's subject. */
|
|
304
304
|
private anchorRtcAddr;
|
|
305
|
+
/**
|
|
306
|
+
* Every endpoint that anchor published (one per family on a
|
|
307
|
+
* dual-stack anchor). Empty until a `connected` event names them;
|
|
308
|
+
* the probe then aims at all of them.
|
|
309
|
+
*/
|
|
310
|
+
private anchorRtcAddrs;
|
|
305
311
|
/** Set once the leaf reports a session — a bootstrap that demonstrably worked. */
|
|
306
312
|
private bootstrapObserved;
|
|
307
313
|
/** This node's mesh id, hex. */
|
|
@@ -719,7 +725,7 @@ export declare class BrowserNode {
|
|
|
719
725
|
* `ice-timeout` it gathers the two observations the correction
|
|
720
726
|
* requires — the anchor answering over HTTPS, and a STUN binding to
|
|
721
727
|
* the address that anchor published going unanswered — and returns
|
|
722
|
-
* the classification {@link
|
|
728
|
+
* the classification {@link classifyRtcFailureAll} makes of them. With no
|
|
723
729
|
* address to probe there is no evidence, and the error comes back
|
|
724
730
|
* unchanged.
|
|
725
731
|
*
|
|
@@ -884,6 +890,11 @@ interface RefineContext {
|
|
|
884
890
|
/** The leaf already demonstrated a working bootstrap this session. */
|
|
885
891
|
readonly bootstrapObserved: boolean;
|
|
886
892
|
readonly anchorRtcAddr: string | null;
|
|
893
|
+
/**
|
|
894
|
+
* Every endpoint the anchor published, when known. Absent or empty
|
|
895
|
+
* falls back to `[anchorRtcAddr]`.
|
|
896
|
+
*/
|
|
897
|
+
readonly anchorRtcAddrs?: readonly string[];
|
|
887
898
|
readonly failureTyping: FailureTypingOptions;
|
|
888
899
|
}
|
|
889
900
|
/**
|
package/dist/node.js
CHANGED
|
@@ -12,7 +12,7 @@ import { fromWasmError, IdentityError, OrgCancelledError, RtcError } from './err
|
|
|
12
12
|
import { clientStreamOrgTrampoline, duplexOrgTrampoline, OrgDuplex, OrgHandleRegistry, OrgServe, OrgStream, OrgUpload, streamingOrgTrampoline, toWasmOrgCallOptions, toWasmOrgServeOptions, unaryOrgTrampoline, } from './org.js';
|
|
13
13
|
import { LeafStream } from './stream.js';
|
|
14
14
|
import { acceptPeer as driveAccept, connectPeer as driveConnect, handshakePeer as driveHandshake, } from './peer-driver.js';
|
|
15
|
-
import {
|
|
15
|
+
import { classifyRtcFailureAll, probeBootstrapReachable, probeStunBindings, } from './udp-probe.js';
|
|
16
16
|
import { idArg, loadLeafWasm, } from './wasm.js';
|
|
17
17
|
/**
|
|
18
18
|
* Convert a decimal `u64` node id — {@link NodeDescriptor.nodeId},
|
|
@@ -73,6 +73,12 @@ export class BrowserNode {
|
|
|
73
73
|
orgHandles = new OrgHandleRegistry();
|
|
74
74
|
/** The last `rtc_addr` an anchor told us about; the probe's subject. */
|
|
75
75
|
anchorRtcAddr;
|
|
76
|
+
/**
|
|
77
|
+
* Every endpoint that anchor published (one per family on a
|
|
78
|
+
* dual-stack anchor). Empty until a `connected` event names them;
|
|
79
|
+
* the probe then aims at all of them.
|
|
80
|
+
*/
|
|
81
|
+
anchorRtcAddrs = [];
|
|
76
82
|
/** Set once the leaf reports a session — a bootstrap that demonstrably worked. */
|
|
77
83
|
bootstrapObserved = false;
|
|
78
84
|
/** @internal — use {@link connect}. */
|
|
@@ -701,7 +707,7 @@ export class BrowserNode {
|
|
|
701
707
|
* `ice-timeout` it gathers the two observations the correction
|
|
702
708
|
* requires — the anchor answering over HTTPS, and a STUN binding to
|
|
703
709
|
* the address that anchor published going unanswered — and returns
|
|
704
|
-
* the classification {@link
|
|
710
|
+
* the classification {@link classifyRtcFailureAll} makes of them. With no
|
|
705
711
|
* address to probe there is no evidence, and the error comes back
|
|
706
712
|
* unchanged.
|
|
707
713
|
*
|
|
@@ -714,6 +720,7 @@ export class BrowserNode {
|
|
|
714
720
|
bootstrapUrl: this.bootstrapUrl,
|
|
715
721
|
bootstrapObserved: this.bootstrapObserved,
|
|
716
722
|
anchorRtcAddr: this.anchorRtcAddr,
|
|
723
|
+
anchorRtcAddrs: this.anchorRtcAddrs,
|
|
717
724
|
failureTyping: this.failureTyping,
|
|
718
725
|
});
|
|
719
726
|
}
|
|
@@ -801,6 +808,8 @@ export class BrowserNode {
|
|
|
801
808
|
this.bootstrapObserved = true;
|
|
802
809
|
if (event.rtcAddr !== null)
|
|
803
810
|
this.anchorRtcAddr = event.rtcAddr;
|
|
811
|
+
if (event.rtcAddrs.length > 0)
|
|
812
|
+
this.anchorRtcAddrs = event.rtcAddrs;
|
|
804
813
|
}
|
|
805
814
|
this.hub.dispatch(event);
|
|
806
815
|
}
|
|
@@ -973,19 +982,26 @@ export async function refineIceFailure(error, context) {
|
|
|
973
982
|
return error;
|
|
974
983
|
if (context.failureTyping.probeOnIceTimeout === false)
|
|
975
984
|
return error;
|
|
976
|
-
const
|
|
977
|
-
|
|
985
|
+
const endpoints = context.anchorRtcAddrs !== undefined && context.anchorRtcAddrs.length > 0
|
|
986
|
+
? context.anchorRtcAddrs
|
|
987
|
+
: context.anchorRtcAddr !== null
|
|
988
|
+
? [context.anchorRtcAddr]
|
|
989
|
+
: [];
|
|
990
|
+
if (endpoints.length === 0) {
|
|
978
991
|
// No subject, no claim. The plan's whole point: an ICE timeout
|
|
979
992
|
// alone is never promoted.
|
|
980
993
|
return error;
|
|
981
994
|
}
|
|
982
|
-
|
|
983
|
-
|
|
995
|
+
// Every published endpoint, under one deadline (dual-stack plan,
|
|
996
|
+
// slice 3): one answered family means UDP works, so the failure
|
|
997
|
+
// stays an ICE timeout without even asking HTTPS.
|
|
998
|
+
const probes = await probeStunBindings(endpoints, context.failureTyping.stun);
|
|
999
|
+
if (probes.some((probe) => probe.stunProbe.type !== 'unanswered'))
|
|
984
1000
|
return error;
|
|
985
1001
|
const bootstrapOk = context.bootstrapObserved ||
|
|
986
1002
|
(context.bootstrapUrl !== null &&
|
|
987
1003
|
(await probeBootstrapReachable(context.bootstrapUrl, context.failureTyping.bootstrap)));
|
|
988
|
-
return
|
|
1004
|
+
return new RtcError(classifyRtcFailureAll({ bootstrapOk, probes }));
|
|
989
1005
|
}
|
|
990
1006
|
/**
|
|
991
1007
|
* Parse `query`'s JSON array — `{ node_id, entity_id, capabilities,
|
package/dist/udp-probe.d.ts
CHANGED
|
@@ -63,6 +63,52 @@ export type StunProbeOutcome =
|
|
|
63
63
|
readonly type: 'unsupported';
|
|
64
64
|
readonly detail: string;
|
|
65
65
|
};
|
|
66
|
+
/**
|
|
67
|
+
* One thing a diagnostic probe connection reported: a candidate's SDP
|
|
68
|
+
* line, or an `icecandidateerror`'s STUN error code. The shape of the
|
|
69
|
+
* shared vector file both probes are tested against.
|
|
70
|
+
*/
|
|
71
|
+
export type ProbeEvent = {
|
|
72
|
+
readonly candidate: string;
|
|
73
|
+
} | {
|
|
74
|
+
readonly error: number;
|
|
75
|
+
}
|
|
76
|
+
/** The probe connection's ICE state became `failed`. */
|
|
77
|
+
| {
|
|
78
|
+
readonly ice: 'failed';
|
|
79
|
+
};
|
|
80
|
+
/**
|
|
81
|
+
* Is this candidate line server-reflexive? The `typ` token followed by
|
|
82
|
+
* the `srflx` token, as SDP defines the field, never a substring a
|
|
83
|
+
* foreign attribute could contain. The Rust probe's rule, the same
|
|
84
|
+
* tokens.
|
|
85
|
+
*/
|
|
86
|
+
export declare function candidateLineIsReflexive(line: string): boolean;
|
|
87
|
+
/**
|
|
88
|
+
* **The rule both probes share** (`ANCHOR_DUAL_STACK_PLAN.md`, defect 3):
|
|
89
|
+
* does this one event prove a STUN response came back? A reflexive
|
|
90
|
+
* candidate does, and so does a STUN error *response* (code below 700).
|
|
91
|
+
* Host and relay candidates prove nothing. The Rust (WASM) probe applies
|
|
92
|
+
* the same rule; `test/fixtures/stun-probe-verdicts.json` holds both to
|
|
93
|
+
* it.
|
|
94
|
+
*/
|
|
95
|
+
export declare function probeEventAnswers(event: ProbeEvent): boolean;
|
|
96
|
+
/**
|
|
97
|
+
* The verdict over everything one probe reported: `answered` when any
|
|
98
|
+
* event answers, `notRun` when the engine failed the connection before
|
|
99
|
+
* gathering a single candidate (nothing was sent, so silence is not
|
|
100
|
+
* evidence — measured: Firefox without a media permission on an
|
|
101
|
+
* IPv6-only network with no IPv4 route), `unanswered` otherwise. The
|
|
102
|
+
* Rust probe's `probe_verdict`, the same three answers.
|
|
103
|
+
*/
|
|
104
|
+
export declare function stunProbeVerdict(events: readonly ProbeEvent[]): 'answered' | 'unanswered' | 'notRun';
|
|
105
|
+
/** {@link probeEventAnswers} over everything one probe reported. */
|
|
106
|
+
export declare function stunProbeAnswered(events: readonly ProbeEvent[]): boolean;
|
|
107
|
+
/** One endpoint and what probing it established. */
|
|
108
|
+
export interface EndpointProbe {
|
|
109
|
+
readonly probed: string;
|
|
110
|
+
readonly stunProbe: StunProbeOutcome;
|
|
111
|
+
}
|
|
66
112
|
/** Everything the classification is allowed to look at. */
|
|
67
113
|
export interface RtcFailureObservations {
|
|
68
114
|
/** Did the HTTPS bootstrap to this anchor succeed? */
|
|
@@ -88,6 +134,19 @@ export type IceFailureClassification = {
|
|
|
88
134
|
* response came back" — stays `iceTimeout`.
|
|
89
135
|
*/
|
|
90
136
|
export declare function classifyRtcFailure(observations: RtcFailureObservations): IceFailureClassification;
|
|
137
|
+
/**
|
|
138
|
+
* The rule over **every** endpoint the anchor published (dual-stack
|
|
139
|
+
* plan, slice 3). `udpBlocked` only when the bootstrap answered and
|
|
140
|
+
* every endpoint's probe ran and came back `unanswered`. Everything
|
|
141
|
+
* else stays `iceTimeout`: one answered family (UDP works there), any
|
|
142
|
+
* probe `notRun` or `unsupported` (an unrun probe observed nothing),
|
|
143
|
+
* or no endpoints at all. Even then the claim is the observation, no
|
|
144
|
+
* UDP response from the advertised endpoints, not a proven cause.
|
|
145
|
+
*/
|
|
146
|
+
export declare function classifyRtcFailureAll(observations: {
|
|
147
|
+
readonly bootstrapOk: boolean;
|
|
148
|
+
readonly probes: readonly EndpointProbe[];
|
|
149
|
+
}): IceFailureClassification;
|
|
91
150
|
/** {@link classifyRtcFailure}, as the error a caller will be rejected with. */
|
|
92
151
|
export declare function classifyRtcError(observations: RtcFailureObservations): RtcError;
|
|
93
152
|
/** Injection seam for the probe, so tests never need a real engine. */
|
|
@@ -100,6 +159,8 @@ export interface StunProbeOptions {
|
|
|
100
159
|
*/
|
|
101
160
|
readonly peerConnectionFactory?: (config: RTCConfiguration) => RTCPeerConnection;
|
|
102
161
|
}
|
|
162
|
+
/** Anything at or above this `errorCode` means "no response arrived". */
|
|
163
|
+
export declare const STUN_NO_RESPONSE_CODE = 700;
|
|
103
164
|
/**
|
|
104
165
|
* Aim a STUN binding at `rtcAddr` and report what came back.
|
|
105
166
|
*
|
|
@@ -110,6 +171,13 @@ export interface StunProbeOptions {
|
|
|
110
171
|
* media and is always closed.
|
|
111
172
|
*/
|
|
112
173
|
export declare function probeStunBinding(rtcAddr: string, options?: StunProbeOptions): Promise<StunProbeOutcome>;
|
|
174
|
+
/**
|
|
175
|
+
* Probe **every** endpoint at once, under **one** deadline: the probes
|
|
176
|
+
* run concurrently, so a dual-stack anchor's diagnosis costs what a
|
|
177
|
+
* single-stack one's does. Each result is {@link probeStunBinding}'s,
|
|
178
|
+
* in the order given.
|
|
179
|
+
*/
|
|
180
|
+
export declare function probeStunBindings(rtcAddrs: readonly string[], options?: StunProbeOptions): Promise<EndpointProbe[]>;
|
|
113
181
|
/** Injection seam for the bootstrap observation. */
|
|
114
182
|
export interface BootstrapProbeOptions {
|
|
115
183
|
/** How long to wait for the anchor to answer. Default 3000 ms. */
|
package/dist/udp-probe.js
CHANGED
|
@@ -31,6 +31,50 @@
|
|
|
31
31
|
* no reflexive candidate at all — nothing came back.
|
|
32
32
|
*/
|
|
33
33
|
import { RtcError, udpBlockedEvidence } from './errors.js';
|
|
34
|
+
/**
|
|
35
|
+
* Is this candidate line server-reflexive? The `typ` token followed by
|
|
36
|
+
* the `srflx` token, as SDP defines the field, never a substring a
|
|
37
|
+
* foreign attribute could contain. The Rust probe's rule, the same
|
|
38
|
+
* tokens.
|
|
39
|
+
*/
|
|
40
|
+
export function candidateLineIsReflexive(line) {
|
|
41
|
+
const tokens = line.trim().split(/\s+/);
|
|
42
|
+
return tokens.some((token, index) => token === 'typ' && tokens[index + 1] === 'srflx');
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* **The rule both probes share** (`ANCHOR_DUAL_STACK_PLAN.md`, defect 3):
|
|
46
|
+
* does this one event prove a STUN response came back? A reflexive
|
|
47
|
+
* candidate does, and so does a STUN error *response* (code below 700).
|
|
48
|
+
* Host and relay candidates prove nothing. The Rust (WASM) probe applies
|
|
49
|
+
* the same rule; `test/fixtures/stun-probe-verdicts.json` holds both to
|
|
50
|
+
* it.
|
|
51
|
+
*/
|
|
52
|
+
export function probeEventAnswers(event) {
|
|
53
|
+
if ('candidate' in event)
|
|
54
|
+
return candidateLineIsReflexive(event.candidate);
|
|
55
|
+
if ('error' in event)
|
|
56
|
+
return event.error < STUN_NO_RESPONSE_CODE;
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* The verdict over everything one probe reported: `answered` when any
|
|
61
|
+
* event answers, `notRun` when the engine failed the connection before
|
|
62
|
+
* gathering a single candidate (nothing was sent, so silence is not
|
|
63
|
+
* evidence — measured: Firefox without a media permission on an
|
|
64
|
+
* IPv6-only network with no IPv4 route), `unanswered` otherwise. The
|
|
65
|
+
* Rust probe's `probe_verdict`, the same three answers.
|
|
66
|
+
*/
|
|
67
|
+
export function stunProbeVerdict(events) {
|
|
68
|
+
if (events.some(probeEventAnswers))
|
|
69
|
+
return 'answered';
|
|
70
|
+
const gathered = events.some((event) => 'candidate' in event);
|
|
71
|
+
const failed = events.some((event) => 'ice' in event && event.ice === 'failed');
|
|
72
|
+
return failed && !gathered ? 'notRun' : 'unanswered';
|
|
73
|
+
}
|
|
74
|
+
/** {@link probeEventAnswers} over everything one probe reported. */
|
|
75
|
+
export function stunProbeAnswered(events) {
|
|
76
|
+
return stunProbeVerdict(events) === 'answered';
|
|
77
|
+
}
|
|
34
78
|
/**
|
|
35
79
|
* The rule, pure.
|
|
36
80
|
*
|
|
@@ -41,9 +85,26 @@ import { RtcError, udpBlockedEvidence } from './errors.js';
|
|
|
41
85
|
*/
|
|
42
86
|
export function classifyRtcFailure(observations) {
|
|
43
87
|
const { bootstrapOk, stunProbe, probed } = observations;
|
|
44
|
-
if (
|
|
88
|
+
if (probed === null)
|
|
45
89
|
return { type: 'iceTimeout' };
|
|
46
|
-
|
|
90
|
+
return classifyRtcFailureAll({ bootstrapOk, probes: [{ probed, stunProbe }] });
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* The rule over **every** endpoint the anchor published (dual-stack
|
|
94
|
+
* plan, slice 3). `udpBlocked` only when the bootstrap answered and
|
|
95
|
+
* every endpoint's probe ran and came back `unanswered`. Everything
|
|
96
|
+
* else stays `iceTimeout`: one answered family (UDP works there), any
|
|
97
|
+
* probe `notRun` or `unsupported` (an unrun probe observed nothing),
|
|
98
|
+
* or no endpoints at all. Even then the claim is the observation, no
|
|
99
|
+
* UDP response from the advertised endpoints, not a proven cause.
|
|
100
|
+
*/
|
|
101
|
+
export function classifyRtcFailureAll(observations) {
|
|
102
|
+
const { bootstrapOk, probes } = observations;
|
|
103
|
+
if (probes.length === 0 || probes.some((probe) => probe.stunProbe.type !== 'unanswered')) {
|
|
104
|
+
return { type: 'iceTimeout' };
|
|
105
|
+
}
|
|
106
|
+
const probedAll = probes.map((probe) => probe.probed);
|
|
107
|
+
const evidence = udpBlockedEvidence(bootstrapOk, true, probedAll[0] ?? '', probedAll);
|
|
47
108
|
return evidence === null ? { type: 'iceTimeout' } : { type: 'udpBlocked', evidence };
|
|
48
109
|
}
|
|
49
110
|
/** {@link classifyRtcFailure}, as the error a caller will be rejected with. */
|
|
@@ -52,7 +113,7 @@ export function classifyRtcError(observations) {
|
|
|
52
113
|
}
|
|
53
114
|
const DEFAULT_PROBE_TIMEOUT_MS = 2500;
|
|
54
115
|
/** Anything at or above this `errorCode` means "no response arrived". */
|
|
55
|
-
const STUN_NO_RESPONSE_CODE = 700;
|
|
116
|
+
export const STUN_NO_RESPONSE_CODE = 700;
|
|
56
117
|
const DEFAULT_STUN_PORT = 3478;
|
|
57
118
|
/**
|
|
58
119
|
* Aim a STUN binding at `rtcAddr` and report what came back.
|
|
@@ -99,12 +160,25 @@ export async function probeStunBinding(rtcAddr, options = {}) {
|
|
|
99
160
|
detail: noResponse ?? 'gathering completed with no reflexive candidate',
|
|
100
161
|
});
|
|
101
162
|
};
|
|
163
|
+
// Did the engine gather anything at all? A connection it fails
|
|
164
|
+
// before the first candidate is one it could not gather for, and
|
|
165
|
+
// such a probe did not run (see `stunProbeVerdict`).
|
|
166
|
+
let gathered = false;
|
|
167
|
+
pc.oniceconnectionstatechange = () => {
|
|
168
|
+
if (pc.iceConnectionState === 'failed' && !gathered) {
|
|
169
|
+
settle({
|
|
170
|
+
type: 'notRun',
|
|
171
|
+
reason: 'the engine failed the probe connection before gathering any candidate',
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
};
|
|
102
175
|
pc.onicecandidate = (event) => {
|
|
103
176
|
const candidate = event.candidate;
|
|
104
177
|
if (candidate === null) {
|
|
105
178
|
gatheringDone();
|
|
106
179
|
return;
|
|
107
180
|
}
|
|
181
|
+
gathered = true;
|
|
108
182
|
// Host candidates are gathered regardless of what the network does
|
|
109
183
|
// to UDP — Chromium even hides them behind an mDNS `.local` name —
|
|
110
184
|
// so only a reflexive one is evidence.
|
|
@@ -119,7 +193,7 @@ export async function probeStunBinding(rtcAddr, options = {}) {
|
|
|
119
193
|
// the anchor and the reply got home, so UDP is not blocked. (An
|
|
120
194
|
// anchor's ICE agent refusing an unauthenticated binding lands
|
|
121
195
|
// here; Chromium reports the STUN error number, e.g. `1` for a 401.)
|
|
122
|
-
if (code
|
|
196
|
+
if (probeEventAnswers({ error: code })) {
|
|
123
197
|
settle({ type: 'stunError', code, detail });
|
|
124
198
|
return;
|
|
125
199
|
}
|
|
@@ -144,10 +218,20 @@ export async function probeStunBinding(rtcAddr, options = {}) {
|
|
|
144
218
|
clearTimeout(timer);
|
|
145
219
|
pc.onicecandidate = null;
|
|
146
220
|
pc.onicecandidateerror = null;
|
|
221
|
+
pc.oniceconnectionstatechange = null;
|
|
147
222
|
pc.onicegatheringstatechange = null;
|
|
148
223
|
pc.close();
|
|
149
224
|
}
|
|
150
225
|
}
|
|
226
|
+
/**
|
|
227
|
+
* Probe **every** endpoint at once, under **one** deadline: the probes
|
|
228
|
+
* run concurrently, so a dual-stack anchor's diagnosis costs what a
|
|
229
|
+
* single-stack one's does. Each result is {@link probeStunBinding}'s,
|
|
230
|
+
* in the order given.
|
|
231
|
+
*/
|
|
232
|
+
export async function probeStunBindings(rtcAddrs, options = {}) {
|
|
233
|
+
return Promise.all(rtcAddrs.map(async (probed) => ({ probed, stunProbe: await probeStunBinding(probed, options) })));
|
|
234
|
+
}
|
|
151
235
|
const DEFAULT_BOOTSTRAP_TIMEOUT_MS = 3000;
|
|
152
236
|
/**
|
|
153
237
|
* Did the anchor answer over HTTPS?
|
|
@@ -229,7 +313,7 @@ export function reflexiveAddress(candidate) {
|
|
|
229
313
|
return candidate.address ?? sdpAddress(candidate.candidate);
|
|
230
314
|
if (candidate.type !== null)
|
|
231
315
|
return null;
|
|
232
|
-
return
|
|
316
|
+
return candidateLineIsReflexive(candidate.candidate) ? sdpAddress(candidate.candidate) : null;
|
|
233
317
|
}
|
|
234
318
|
function sdpAddress(line) {
|
|
235
319
|
// candidate:<foundation> <component> <transport> <priority> <ip> <port> typ …
|