@agoric/network 0.1.1-dev-501c093.0 → 0.1.1-dev-db972d4.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/package.json +9 -9
- package/src/bytes.d.ts +8 -6
- package/src/bytes.d.ts.map +1 -1
- package/src/bytes.js +35 -25
- package/src/index.d.ts +1 -0
- package/src/index.js +1 -0
- package/src/network.d.ts +16 -126
- package/src/network.d.ts.map +1 -1
- package/src/network.js +289 -443
- package/src/router.d.ts +5 -9
- package/src/router.d.ts.map +1 -1
- package/src/router.js +7 -10
- package/src/shapes.d.ts +117 -0
- package/src/shapes.d.ts.map +1 -0
- package/src/shapes.js +191 -0
- package/src/types.d.ts +36 -27
- package/src/types.d.ts.map +1 -1
- package/src/types.js +54 -45
package/src/network.js
CHANGED
|
@@ -4,6 +4,7 @@ import { E } from '@endo/far';
|
|
|
4
4
|
import { M } from '@endo/patterns';
|
|
5
5
|
import { Fail } from '@agoric/assert';
|
|
6
6
|
import { toBytes } from './bytes.js';
|
|
7
|
+
import { Shape } from './shapes.js';
|
|
7
8
|
|
|
8
9
|
import '@agoric/store/exported.js';
|
|
9
10
|
/// <reference path="./types.js" />
|
|
@@ -14,202 +15,13 @@ import '@agoric/store/exported.js';
|
|
|
14
15
|
*/
|
|
15
16
|
export const ENDPOINT_SEPARATOR = '/';
|
|
16
17
|
|
|
17
|
-
const Shape1 = /** @type {const} */ ({
|
|
18
|
-
/**
|
|
19
|
-
* Data is string | Buffer | ArrayBuffer
|
|
20
|
-
* but only string is passable
|
|
21
|
-
*/
|
|
22
|
-
Data: M.string(),
|
|
23
|
-
Bytes: M.string(),
|
|
24
|
-
Endpoint: M.string(),
|
|
25
|
-
Vow: M.tagged(
|
|
26
|
-
'Vow',
|
|
27
|
-
harden({
|
|
28
|
-
vowV0: M.remotable('VowV0'),
|
|
29
|
-
}),
|
|
30
|
-
),
|
|
31
|
-
ConnectionHandler: M.remotable('ConnectionHandler'),
|
|
32
|
-
Connection: M.remotable('Connection'),
|
|
33
|
-
InboundAttempt: M.remotable('InboundAttempt'),
|
|
34
|
-
Listener: M.remotable('Listener'),
|
|
35
|
-
ListenHandler: M.remotable('ListenHandler'),
|
|
36
|
-
Port: M.remotable('Port'),
|
|
37
|
-
ProtocolHandler: M.remotable('ProtocolHandler'),
|
|
38
|
-
ProtocolImpl: M.remotable('ProtocolImpl'),
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
const Shape2 = /** @type {const} */ ({
|
|
42
|
-
...Shape1,
|
|
43
|
-
Vow$: shape => M.or(shape, Shape1.Vow),
|
|
44
|
-
AttemptDescription: M.splitRecord(
|
|
45
|
-
{ handler: Shape1.ConnectionHandler },
|
|
46
|
-
{ remoteAddress: Shape1.Endpoint, localAddress: Shape1.Endpoint },
|
|
47
|
-
),
|
|
48
|
-
Opts: M.recordOf(M.string(), M.any()),
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
export const Shape = /** @type {const} */ harden({
|
|
52
|
-
...Shape2,
|
|
53
|
-
ConnectionI: {
|
|
54
|
-
connection: M.interface('Connection', {
|
|
55
|
-
send: M.callWhen(Shape2.Data)
|
|
56
|
-
.optional(Shape2.Opts)
|
|
57
|
-
.returns(Shape2.Vow$(Shape2.Bytes)),
|
|
58
|
-
close: M.callWhen().returns(Shape2.Vow$(M.undefined())),
|
|
59
|
-
getLocalAddress: M.call().returns(Shape2.Endpoint),
|
|
60
|
-
getRemoteAddress: M.call().returns(Shape2.Endpoint),
|
|
61
|
-
}),
|
|
62
|
-
openConnectionAckWatcher: M.interface('OpenConnectionAckWatcher', {
|
|
63
|
-
onFulfilled: M.call(M.any()).rest(M.any()).returns(M.any()),
|
|
64
|
-
}),
|
|
65
|
-
rethrowUnlessMissingWatcher: M.interface('RethrowUnlessMissingWatcher', {
|
|
66
|
-
onRejected: M.call(M.any()).rest(M.any()).returns(M.any()),
|
|
67
|
-
}),
|
|
68
|
-
sinkWatcher: M.interface('SinkWatcher', {
|
|
69
|
-
onFulfilled: M.call(M.any()).rest(M.any()).returns(),
|
|
70
|
-
}),
|
|
71
|
-
},
|
|
72
|
-
InboundAttemptI: {
|
|
73
|
-
inboundAttempt: M.interface('InboundAttempt', {
|
|
74
|
-
accept: M.callWhen(Shape2.AttemptDescription).returns(
|
|
75
|
-
Shape2.Vow$(Shape2.Connection),
|
|
76
|
-
),
|
|
77
|
-
getLocalAddress: M.call().returns(Shape2.Endpoint),
|
|
78
|
-
getRemoteAddress: M.call().returns(Shape2.Endpoint),
|
|
79
|
-
close: M.callWhen().returns(Shape2.Vow$(M.undefined())),
|
|
80
|
-
}),
|
|
81
|
-
inboundAttemptAcceptWatcher: M.interface('InboundAttemptAcceptWatcher', {
|
|
82
|
-
onFulfilled: M.call(M.any()).rest(M.any()).returns(M.any()),
|
|
83
|
-
}),
|
|
84
|
-
rethrowUnlessMissingWatcher: M.interface('RethrowUnlessMissingWatcher', {
|
|
85
|
-
onRejected: M.call(M.any()).rest(M.any()).returns(M.any()),
|
|
86
|
-
}),
|
|
87
|
-
sinkWatcher: M.interface('SinkWatcher', {
|
|
88
|
-
onFulfilled: M.call(M.any()).rest(M.any()).returns(),
|
|
89
|
-
}),
|
|
90
|
-
},
|
|
91
|
-
PortI: {
|
|
92
|
-
port: M.interface('Port', {
|
|
93
|
-
getLocalAddress: M.call().returns(Shape2.Endpoint),
|
|
94
|
-
addListener: M.callWhen(Shape2.Listener).returns(
|
|
95
|
-
Shape2.Vow$(M.undefined()),
|
|
96
|
-
),
|
|
97
|
-
connect: M.callWhen(Shape2.Endpoint)
|
|
98
|
-
.optional(Shape2.ConnectionHandler)
|
|
99
|
-
.returns(Shape2.Vow$(Shape2.Connection)),
|
|
100
|
-
removeListener: M.callWhen(Shape2.Listener).returns(
|
|
101
|
-
Shape2.Vow$(M.undefined()),
|
|
102
|
-
),
|
|
103
|
-
revoke: M.callWhen().returns(Shape2.Vow$(M.undefined())),
|
|
104
|
-
}),
|
|
105
|
-
portAddListenerWatcher: M.interface('PortAddListenerWatcher', {
|
|
106
|
-
onFulfilled: M.call(M.any()).rest(M.any()).returns(M.any()),
|
|
107
|
-
}),
|
|
108
|
-
portRemoveListenerWatcher: M.interface('PortRemoveListenerWatcher', {
|
|
109
|
-
onFulfilled: M.call(M.any()).rest(M.any()).returns(M.any()),
|
|
110
|
-
}),
|
|
111
|
-
portConnectWatcher: M.interface('PortConnectWatcher', {
|
|
112
|
-
onFulfilled: M.call(M.any()).rest(M.any()).returns(M.any()),
|
|
113
|
-
}),
|
|
114
|
-
portRevokeWatcher: M.interface('PortRevokeWatcher', {
|
|
115
|
-
onFulfilled: M.call(M.any()).rest(M.any()).returns(M.any()),
|
|
116
|
-
}),
|
|
117
|
-
portRevokeCleanupWatcher: M.interface('PortRevokeCleanupWatcher', {
|
|
118
|
-
onFulfilled: M.call(M.any()).rest(M.any()).returns(M.any()),
|
|
119
|
-
}),
|
|
120
|
-
rethrowUnlessMissingWatcher: M.interface('RethrowUnlessMissingWatcher', {
|
|
121
|
-
onRejected: M.call(M.any()).rest(M.any()).returns(M.any()),
|
|
122
|
-
}),
|
|
123
|
-
sinkWatcher: M.interface('SinkWatcher', {
|
|
124
|
-
onFulfilled: M.call(M.any()).rest(M.any()).returns(),
|
|
125
|
-
onRejected: M.call(M.any()).rest(M.any()).returns(M.any()),
|
|
126
|
-
}),
|
|
127
|
-
},
|
|
128
|
-
ProtocolHandlerI: {
|
|
129
|
-
protocolHandler: M.interface('ProtocolHandler', {
|
|
130
|
-
onCreate: M.callWhen(M.remotable(), Shape2.ProtocolHandler).returns(
|
|
131
|
-
Shape2.Vow$(M.undefined()),
|
|
132
|
-
),
|
|
133
|
-
generatePortID: M.callWhen(
|
|
134
|
-
Shape2.Endpoint,
|
|
135
|
-
Shape2.ProtocolHandler,
|
|
136
|
-
).returns(Shape2.Vow$(M.string())),
|
|
137
|
-
onBind: M.callWhen(
|
|
138
|
-
Shape2.Port,
|
|
139
|
-
Shape2.Endpoint,
|
|
140
|
-
Shape2.ProtocolHandler,
|
|
141
|
-
).returns(Shape2.Vow$(M.undefined())),
|
|
142
|
-
onListen: M.callWhen(
|
|
143
|
-
Shape2.Port,
|
|
144
|
-
Shape2.Endpoint,
|
|
145
|
-
Shape2.ListenHandler,
|
|
146
|
-
Shape2.ProtocolHandler,
|
|
147
|
-
).returns(Shape2.Vow$(M.undefined())),
|
|
148
|
-
onListenRemove: M.callWhen(
|
|
149
|
-
Shape2.Port,
|
|
150
|
-
Shape2.Endpoint,
|
|
151
|
-
Shape2.ListenHandler,
|
|
152
|
-
Shape2.ProtocolHandler,
|
|
153
|
-
).returns(Shape2.Vow$(M.undefined())),
|
|
154
|
-
onInstantiate: M.callWhen(
|
|
155
|
-
Shape2.Port,
|
|
156
|
-
Shape2.Endpoint,
|
|
157
|
-
Shape2.Endpoint,
|
|
158
|
-
Shape2.ProtocolHandler,
|
|
159
|
-
).returns(Shape2.Vow$(Shape2.Endpoint)),
|
|
160
|
-
onConnect: M.callWhen(
|
|
161
|
-
Shape2.Port,
|
|
162
|
-
Shape2.Endpoint,
|
|
163
|
-
Shape2.Endpoint,
|
|
164
|
-
Shape2.ConnectionHandler,
|
|
165
|
-
Shape2.ProtocolHandler,
|
|
166
|
-
).returns(Shape2.Vow$(Shape2.AttemptDescription)),
|
|
167
|
-
onRevoke: M.callWhen(
|
|
168
|
-
Shape2.Port,
|
|
169
|
-
Shape2.Endpoint,
|
|
170
|
-
Shape2.ProtocolHandler,
|
|
171
|
-
).returns(Shape2.Vow$(M.undefined())),
|
|
172
|
-
}),
|
|
173
|
-
protocolHandlerAcceptWatcher: M.interface('ProtocolHandlerAcceptWatcher', {
|
|
174
|
-
onFulfilled: M.call(M.any()).rest(M.any()).returns(),
|
|
175
|
-
}),
|
|
176
|
-
protocolHandlerInstantiateWatcher: M.interface(
|
|
177
|
-
'ProtocolHandlerInstantiateWatcher',
|
|
178
|
-
{
|
|
179
|
-
onFulfilled: M.call(M.any()).rest(M.any()).returns(),
|
|
180
|
-
},
|
|
181
|
-
),
|
|
182
|
-
protocolHandlerConnectWatcher: M.interface(
|
|
183
|
-
'ProtocolHandlerConnectWatcher',
|
|
184
|
-
{
|
|
185
|
-
onFulfilled: M.call(M.any()).rest(M.any()).returns(),
|
|
186
|
-
},
|
|
187
|
-
),
|
|
188
|
-
rethrowUnlessMissingWatcher: M.interface('RethrowUnlessMissingWatcher', {
|
|
189
|
-
onRejected: M.call(M.any()).rest(M.any()).returns(M.any()),
|
|
190
|
-
}),
|
|
191
|
-
},
|
|
192
|
-
|
|
193
|
-
ProtocolImplI: M.interface('ProtocolImpl', {
|
|
194
|
-
bind: M.callWhen(Shape2.Endpoint).returns(Shape2.Vow$(Shape2.Port)),
|
|
195
|
-
inbound: M.callWhen(Shape2.Endpoint, Shape2.Endpoint).returns(
|
|
196
|
-
Shape2.Vow$(Shape2.InboundAttempt),
|
|
197
|
-
),
|
|
198
|
-
outbound: M.callWhen(
|
|
199
|
-
Shape2.Port,
|
|
200
|
-
Shape2.Endpoint,
|
|
201
|
-
Shape2.ConnectionHandler,
|
|
202
|
-
).returns(Shape2.Vow$(Shape2.Connection)),
|
|
203
|
-
}),
|
|
204
|
-
});
|
|
205
|
-
|
|
206
18
|
/** @param {unknown} err */
|
|
207
19
|
export const rethrowUnlessMissing = err => {
|
|
208
20
|
// Ugly hack rather than being able to determine if the function
|
|
209
21
|
// exists.
|
|
210
22
|
if (
|
|
211
23
|
!(err instanceof TypeError) ||
|
|
212
|
-
!err.message.match(/target has no method|is not a function$/)
|
|
24
|
+
!String(err.message).match(/target has no method|is not a function$/)
|
|
213
25
|
) {
|
|
214
26
|
throw err;
|
|
215
27
|
}
|
|
@@ -237,7 +49,7 @@ export function getPrefixes(addr) {
|
|
|
237
49
|
/**
|
|
238
50
|
* @typedef {object} ConnectionOpts
|
|
239
51
|
* @property {Endpoint[]} addrs
|
|
240
|
-
* @property {ConnectionHandler[]} handlers
|
|
52
|
+
* @property {import('@agoric/vow').Remote<Required<ConnectionHandler>>[]} handlers
|
|
241
53
|
* @property {MapStore<number, Connection>} conns
|
|
242
54
|
* @property {WeakSetStore<Closable>} current
|
|
243
55
|
* @property {0|1} l
|
|
@@ -254,9 +66,6 @@ const prepareHalfConnection = (zone, { watch }) => {
|
|
|
254
66
|
Shape.ConnectionI,
|
|
255
67
|
/** @param {ConnectionOpts} opts */
|
|
256
68
|
({ addrs, handlers, conns, current, l, r }) => {
|
|
257
|
-
/** @type {string | undefined} */
|
|
258
|
-
let closed;
|
|
259
|
-
|
|
260
69
|
return {
|
|
261
70
|
addrs,
|
|
262
71
|
handlers,
|
|
@@ -264,7 +73,8 @@ const prepareHalfConnection = (zone, { watch }) => {
|
|
|
264
73
|
current,
|
|
265
74
|
l,
|
|
266
75
|
r,
|
|
267
|
-
|
|
76
|
+
/** @type {string | undefined} */
|
|
77
|
+
closed: undefined,
|
|
268
78
|
};
|
|
269
79
|
},
|
|
270
80
|
{
|
|
@@ -277,11 +87,11 @@ const prepareHalfConnection = (zone, { watch }) => {
|
|
|
277
87
|
const { addrs, r } = this.state;
|
|
278
88
|
return addrs[r];
|
|
279
89
|
},
|
|
280
|
-
/** @param {
|
|
90
|
+
/** @param {Bytes} packetBytes */
|
|
281
91
|
async send(packetBytes) {
|
|
282
92
|
const { closed, handlers, r, conns } = this.state;
|
|
283
93
|
if (closed) {
|
|
284
|
-
throw closed;
|
|
94
|
+
throw Error(closed);
|
|
285
95
|
}
|
|
286
96
|
|
|
287
97
|
const innerVow = watch(
|
|
@@ -348,12 +158,12 @@ const prepareHalfConnection = (zone, { watch }) => {
|
|
|
348
158
|
|
|
349
159
|
/**
|
|
350
160
|
* @param {import('@agoric/zone').Zone} zone
|
|
351
|
-
* @param {ConnectionHandler} handler0
|
|
161
|
+
* @param {import('@agoric/vow').Remote<Required<ConnectionHandler>>} handler0
|
|
352
162
|
* @param {Endpoint} addr0
|
|
353
|
-
* @param {ConnectionHandler} handler1
|
|
163
|
+
* @param {import('@agoric/vow').Remote<Required<ConnectionHandler>>} handler1
|
|
354
164
|
* @param {Endpoint} addr1
|
|
355
165
|
* @param {(opts: ConnectionOpts) => Connection} makeConnection
|
|
356
|
-
* @param {WeakSetStore<Closable>} current
|
|
166
|
+
* @param {WeakSetStore<Closable>} [current]
|
|
357
167
|
*/
|
|
358
168
|
export const crossoverConnection = (
|
|
359
169
|
zone,
|
|
@@ -369,7 +179,7 @@ export const crossoverConnection = (
|
|
|
369
179
|
/** @type {MapStore<number, Connection>} */
|
|
370
180
|
const conns = detached.mapStore('addrToConnections');
|
|
371
181
|
|
|
372
|
-
/** @type {ConnectionHandler[]} */
|
|
182
|
+
/** @type {import('@agoric/vow').Remote<Required<ConnectionHandler>>[]} */
|
|
373
183
|
const handlers = harden([handler0, handler1]);
|
|
374
184
|
/** @type {Endpoint[]} */
|
|
375
185
|
const addrs = harden([addr0, addr1]);
|
|
@@ -415,9 +225,9 @@ const prepareInboundAttempt = (zone, makeConnection, { watch }) => {
|
|
|
415
225
|
* @param {object} opts
|
|
416
226
|
* @param {string} opts.localAddr
|
|
417
227
|
* @param {string} opts.remoteAddr
|
|
418
|
-
* @param {
|
|
228
|
+
* @param {MapStore<Port, SetStore<Closable>>} opts.currentConnections
|
|
419
229
|
* @param {string} opts.listenPrefix
|
|
420
|
-
* @param {MapStore<Endpoint, [Port, ListenHandler]>} opts.listening
|
|
230
|
+
* @param {MapStore<Endpoint, [Port, import('@agoric/vow').Remote<Required<ListenHandler>>]>} opts.listening
|
|
421
231
|
*/
|
|
422
232
|
({
|
|
423
233
|
localAddr,
|
|
@@ -472,7 +282,7 @@ const prepareInboundAttempt = (zone, makeConnection, { watch }) => {
|
|
|
472
282
|
* @param {object} opts
|
|
473
283
|
* @param {string} [opts.localAddress]
|
|
474
284
|
* @param {string} [opts.remoteAddress]
|
|
475
|
-
* @param {ConnectionHandler} opts.handler
|
|
285
|
+
* @param {import('@agoric/vow').Remote<ConnectionHandler>} opts.handler
|
|
476
286
|
*/
|
|
477
287
|
async accept({ localAddress, remoteAddress, handler: rchandler }) {
|
|
478
288
|
const { consummated, localAddr, remoteAddr } = this.state;
|
|
@@ -514,9 +324,13 @@ const prepareInboundAttempt = (zone, makeConnection, { watch }) => {
|
|
|
514
324
|
|
|
515
325
|
return crossoverConnection(
|
|
516
326
|
zone,
|
|
517
|
-
|
|
327
|
+
/** @type {import('@agoric/vow').Remote<Required<ConnectionHandler>>} */ (
|
|
328
|
+
lchandler
|
|
329
|
+
),
|
|
518
330
|
localAddress,
|
|
519
|
-
|
|
331
|
+
/** @type {import('@agoric/vow').Remote<Required<ConnectionHandler>>} */ (
|
|
332
|
+
rchandler
|
|
333
|
+
),
|
|
520
334
|
remoteAddress,
|
|
521
335
|
makeConnection,
|
|
522
336
|
current,
|
|
@@ -573,217 +387,222 @@ const preparePort = (zone, powers) => {
|
|
|
573
387
|
|
|
574
388
|
const { watch, allVows } = powers;
|
|
575
389
|
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
390
|
+
/**
|
|
391
|
+
* @param {object} opts
|
|
392
|
+
* @param {Endpoint} opts.localAddr
|
|
393
|
+
* @param {MapStore<Endpoint, [Port, import('@agoric/vow').Remote<Required<ListenHandler>>]>} opts.listening
|
|
394
|
+
* @param {SetStore<import('@agoric/vow').Remote<Connection>>} opts.openConnections
|
|
395
|
+
* @param {MapStore<Port, SetStore<Closable>>} opts.currentConnections
|
|
396
|
+
* @param {MapStore<string, Port>} opts.boundPorts
|
|
397
|
+
* @param {import('@agoric/vow').Remote<ProtocolHandler>} opts.protocolHandler
|
|
398
|
+
* @param {Remote<ProtocolImpl>} opts.protocolImpl
|
|
399
|
+
*/
|
|
400
|
+
const initPort = ({
|
|
401
|
+
localAddr,
|
|
402
|
+
listening,
|
|
403
|
+
openConnections,
|
|
404
|
+
currentConnections,
|
|
405
|
+
boundPorts,
|
|
406
|
+
protocolHandler,
|
|
407
|
+
protocolImpl,
|
|
408
|
+
}) => {
|
|
409
|
+
return {
|
|
591
410
|
listening,
|
|
592
411
|
openConnections,
|
|
593
412
|
currentConnections,
|
|
594
413
|
boundPorts,
|
|
414
|
+
localAddr,
|
|
595
415
|
protocolHandler,
|
|
596
416
|
protocolImpl,
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
currentConnections,
|
|
602
|
-
boundPorts,
|
|
603
|
-
localAddr,
|
|
604
|
-
protocolHandler,
|
|
605
|
-
protocolImpl,
|
|
606
|
-
/** @type {RevokeState | undefined} */
|
|
607
|
-
revoked: undefined,
|
|
608
|
-
};
|
|
609
|
-
},
|
|
610
|
-
{
|
|
611
|
-
port: {
|
|
612
|
-
getLocalAddress() {
|
|
613
|
-
// Works even after revoke().
|
|
614
|
-
return this.state.localAddr;
|
|
615
|
-
},
|
|
616
|
-
/** @param {ListenHandler} listenHandler */
|
|
617
|
-
async addListener(listenHandler) {
|
|
618
|
-
const { revoked, listening, localAddr, protocolHandler } = this.state;
|
|
619
|
-
|
|
620
|
-
!revoked || Fail`Port ${this.state.localAddr} is revoked`;
|
|
621
|
-
listenHandler || Fail`listenHandler is not defined`;
|
|
622
|
-
|
|
623
|
-
if (listening.has(localAddr)) {
|
|
624
|
-
// Last one wins.
|
|
625
|
-
const [lport, lhandler] = listening.get(localAddr);
|
|
626
|
-
if (lhandler === listenHandler) {
|
|
627
|
-
return;
|
|
628
|
-
}
|
|
629
|
-
listening.set(localAddr, [this.facets.port, listenHandler]);
|
|
630
|
-
E(lhandler).onRemove(lport, lhandler).catch(rethrowUnlessMissing);
|
|
631
|
-
} else {
|
|
632
|
-
listening.init(
|
|
633
|
-
localAddr,
|
|
634
|
-
harden([this.facets.port, listenHandler]),
|
|
635
|
-
);
|
|
636
|
-
}
|
|
637
|
-
|
|
638
|
-
// ASSUME: that the listener defines onAccept.
|
|
417
|
+
/** @type {RevokeState | undefined} */
|
|
418
|
+
revoked: undefined,
|
|
419
|
+
};
|
|
420
|
+
};
|
|
639
421
|
|
|
640
|
-
|
|
641
|
-
|
|
422
|
+
const makePortKit = zone.exoClassKit('Port', Shape.PortI, initPort, {
|
|
423
|
+
port: {
|
|
424
|
+
getLocalAddress() {
|
|
425
|
+
// Works even after revoke().
|
|
426
|
+
return this.state.localAddr;
|
|
427
|
+
},
|
|
428
|
+
/** @param {import('@agoric/vow').Remote<ListenHandler>} listenHandler */
|
|
429
|
+
async addListener(listenHandler) {
|
|
430
|
+
const { revoked, listening, localAddr, protocolHandler } = this.state;
|
|
431
|
+
|
|
432
|
+
!revoked || Fail`Port ${this.state.localAddr} is revoked`;
|
|
433
|
+
listenHandler || Fail`listenHandler is not defined`;
|
|
434
|
+
|
|
435
|
+
if (listening.has(localAddr)) {
|
|
436
|
+
// Last one wins.
|
|
437
|
+
const [lport, lhandler] = listening.get(localAddr);
|
|
438
|
+
if (lhandler === listenHandler) {
|
|
439
|
+
return;
|
|
440
|
+
}
|
|
441
|
+
listening.set(localAddr, [
|
|
442
|
+
this.facets.port,
|
|
443
|
+
/** @type {Remote<Required<ListenHandler>>} */ (listenHandler),
|
|
444
|
+
]);
|
|
445
|
+
E(lhandler).onRemove(lport, lhandler).catch(rethrowUnlessMissing);
|
|
446
|
+
} else {
|
|
447
|
+
listening.init(
|
|
448
|
+
localAddr,
|
|
449
|
+
harden([
|
|
642
450
|
this.facets.port,
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
protocolHandler,
|
|
646
|
-
),
|
|
647
|
-
this.facets.portAddListenerWatcher,
|
|
648
|
-
{ listenHandler },
|
|
451
|
+
/** @type {Remote<Required<ListenHandler>>} */ (listenHandler),
|
|
452
|
+
]),
|
|
649
453
|
);
|
|
650
|
-
|
|
651
|
-
},
|
|
652
|
-
/** @param {ListenHandler} listenHandler */
|
|
653
|
-
async removeListener(listenHandler) {
|
|
654
|
-
const { listening, localAddr, protocolHandler } = this.state;
|
|
655
|
-
listening.has(localAddr) || Fail`Port ${localAddr} is not listening`;
|
|
656
|
-
listening.get(localAddr)[1] === listenHandler ||
|
|
657
|
-
Fail`Port ${localAddr} handler to remove is not listening`;
|
|
658
|
-
listening.delete(localAddr);
|
|
454
|
+
}
|
|
659
455
|
|
|
660
|
-
|
|
661
|
-
E(protocolHandler).onListenRemove(
|
|
662
|
-
this.facets.port,
|
|
663
|
-
localAddr,
|
|
664
|
-
listenHandler,
|
|
665
|
-
protocolHandler,
|
|
666
|
-
),
|
|
667
|
-
this.facets.portRemoveListenerWatcher,
|
|
668
|
-
{ listenHandler },
|
|
669
|
-
);
|
|
670
|
-
return watch(innerVow, this.facets.rethrowUnlessMissingWatcher);
|
|
671
|
-
},
|
|
672
|
-
/**
|
|
673
|
-
* @param {Endpoint} remotePort
|
|
674
|
-
* @param {ConnectionHandler} connectionHandler
|
|
675
|
-
*/
|
|
676
|
-
async connect(
|
|
677
|
-
remotePort,
|
|
678
|
-
connectionHandler = /** @type {any} */ (makeIncapable()),
|
|
679
|
-
) {
|
|
680
|
-
const { revoked, localAddr, protocolImpl } = this.state;
|
|
681
|
-
|
|
682
|
-
!revoked || Fail`Port ${localAddr} is revoked`;
|
|
683
|
-
/** @type {Endpoint} */
|
|
684
|
-
const dst = harden(remotePort);
|
|
685
|
-
return watch(
|
|
686
|
-
protocolImpl.outbound(this.facets.port, dst, connectionHandler),
|
|
687
|
-
this.facets.portConnectWatcher,
|
|
688
|
-
{ revoked },
|
|
689
|
-
);
|
|
690
|
-
},
|
|
691
|
-
async revoke() {
|
|
692
|
-
const { revoked, localAddr } = this.state;
|
|
693
|
-
const { protocolHandler } = this.state;
|
|
456
|
+
// ASSUME: that the listener defines onAccept.
|
|
694
457
|
|
|
695
|
-
|
|
696
|
-
|
|
458
|
+
const innerVow = watch(
|
|
459
|
+
E(protocolHandler).onListen(
|
|
460
|
+
this.facets.port,
|
|
461
|
+
localAddr,
|
|
462
|
+
listenHandler,
|
|
463
|
+
protocolHandler,
|
|
464
|
+
),
|
|
465
|
+
this.facets.portAddListenerWatcher,
|
|
466
|
+
{ listenHandler },
|
|
467
|
+
);
|
|
468
|
+
return watch(innerVow, this.facets.rethrowUnlessMissingWatcher);
|
|
469
|
+
},
|
|
470
|
+
/** @param {Remote<ListenHandler>} listenHandler */
|
|
471
|
+
async removeListener(listenHandler) {
|
|
472
|
+
const { listening, localAddr, protocolHandler } = this.state;
|
|
473
|
+
listening.has(localAddr) || Fail`Port ${localAddr} is not listening`;
|
|
474
|
+
listening.get(localAddr)[1] === listenHandler ||
|
|
475
|
+
Fail`Port ${localAddr} handler to remove is not listening`;
|
|
476
|
+
listening.delete(localAddr);
|
|
477
|
+
|
|
478
|
+
const innerVow = watch(
|
|
479
|
+
E(protocolHandler).onListenRemove(
|
|
480
|
+
this.facets.port,
|
|
481
|
+
localAddr,
|
|
482
|
+
listenHandler,
|
|
483
|
+
protocolHandler,
|
|
484
|
+
),
|
|
485
|
+
this.facets.portRemoveListenerWatcher,
|
|
486
|
+
{ listenHandler },
|
|
487
|
+
);
|
|
488
|
+
return watch(innerVow, this.facets.rethrowUnlessMissingWatcher);
|
|
489
|
+
},
|
|
490
|
+
/**
|
|
491
|
+
* @param {Endpoint} remotePort
|
|
492
|
+
* @param {Remote<ConnectionHandler>} [connectionHandler]
|
|
493
|
+
*/
|
|
494
|
+
async connect(
|
|
495
|
+
remotePort,
|
|
496
|
+
connectionHandler = /** @type {Remote<ConnectionHandler>} */ (
|
|
497
|
+
makeIncapable()
|
|
498
|
+
),
|
|
499
|
+
) {
|
|
500
|
+
const { revoked, localAddr, protocolImpl } = this.state;
|
|
501
|
+
|
|
502
|
+
!revoked || Fail`Port ${localAddr} is revoked`;
|
|
503
|
+
/** @type {Endpoint} */
|
|
504
|
+
const dst = harden(remotePort);
|
|
505
|
+
return watch(
|
|
506
|
+
E(protocolImpl).outbound(this.facets.port, dst, connectionHandler),
|
|
507
|
+
this.facets.portConnectWatcher,
|
|
508
|
+
{ revoked },
|
|
509
|
+
);
|
|
510
|
+
},
|
|
511
|
+
async revoke() {
|
|
512
|
+
const { revoked, localAddr } = this.state;
|
|
513
|
+
const { protocolHandler } = this.state;
|
|
697
514
|
|
|
698
|
-
|
|
515
|
+
revoked !== RevokeState.REVOKED ||
|
|
516
|
+
Fail`Port ${localAddr} is already revoked`;
|
|
699
517
|
|
|
700
|
-
|
|
701
|
-
E(protocolHandler).onRevoke(
|
|
702
|
-
this.facets.port,
|
|
703
|
-
localAddr,
|
|
704
|
-
protocolHandler,
|
|
705
|
-
),
|
|
706
|
-
this.facets.portRevokeWatcher,
|
|
707
|
-
);
|
|
518
|
+
this.state.revoked = RevokeState.REVOKING;
|
|
708
519
|
|
|
709
|
-
|
|
710
|
-
|
|
520
|
+
const revokeVow = watch(
|
|
521
|
+
E(protocolHandler).onRevoke(
|
|
522
|
+
this.facets.port,
|
|
523
|
+
localAddr,
|
|
524
|
+
protocolHandler,
|
|
525
|
+
),
|
|
526
|
+
this.facets.portRevokeWatcher,
|
|
527
|
+
);
|
|
528
|
+
|
|
529
|
+
return watch(revokeVow, this.facets.portRevokeCleanupWatcher);
|
|
711
530
|
},
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
531
|
+
},
|
|
532
|
+
portAddListenerWatcher: {
|
|
533
|
+
onFulfilled(_value, watcherContext) {
|
|
534
|
+
const { listenHandler } = watcherContext;
|
|
535
|
+
return E(listenHandler).onListen(this.facets.port, listenHandler);
|
|
717
536
|
},
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
537
|
+
},
|
|
538
|
+
portRemoveListenerWatcher: {
|
|
539
|
+
onFulfilled(_value, watcherContext) {
|
|
540
|
+
const { listenHandler } = watcherContext;
|
|
541
|
+
return E(listenHandler).onRemove(this.facets.port, listenHandler);
|
|
723
542
|
},
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
543
|
+
},
|
|
544
|
+
portConnectWatcher: {
|
|
545
|
+
onFulfilled(conn, watchContext) {
|
|
546
|
+
const { revoked } = watchContext;
|
|
547
|
+
const { openConnections } = this.state;
|
|
548
|
+
|
|
549
|
+
if (revoked) {
|
|
550
|
+
void E(conn).close();
|
|
551
|
+
} else {
|
|
552
|
+
openConnections.add(conn);
|
|
553
|
+
}
|
|
554
|
+
return conn;
|
|
736
555
|
},
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
556
|
+
},
|
|
557
|
+
portRevokeWatcher: {
|
|
558
|
+
onFulfilled(_value) {
|
|
559
|
+
const { currentConnections, listening, localAddr } = this.state;
|
|
560
|
+
const port = this.facets.port;
|
|
741
561
|
|
|
742
|
-
|
|
743
|
-
|
|
562
|
+
// Clean up everything we did.
|
|
563
|
+
const values = [...currentConnections.get(port).values()];
|
|
744
564
|
|
|
745
|
-
|
|
746
|
-
|
|
565
|
+
/** @type {import('@agoric/vow').Specimen[]} */
|
|
566
|
+
const ps = [];
|
|
747
567
|
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
568
|
+
ps.push(
|
|
569
|
+
...values.map(conn =>
|
|
570
|
+
watch(E(conn).close(), this.facets.sinkWatcher),
|
|
571
|
+
),
|
|
572
|
+
);
|
|
753
573
|
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
574
|
+
if (listening.has(localAddr)) {
|
|
575
|
+
const listener = listening.get(localAddr)[1];
|
|
576
|
+
ps.push(port.removeListener(listener));
|
|
577
|
+
}
|
|
758
578
|
|
|
759
|
-
|
|
760
|
-
},
|
|
579
|
+
return watch(allVows(ps), this.facets.rethrowUnlessMissingWatcher);
|
|
761
580
|
},
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
onRejected() {
|
|
767
|
-
return undefined;
|
|
768
|
-
},
|
|
581
|
+
},
|
|
582
|
+
sinkWatcher: {
|
|
583
|
+
onFulfilled() {
|
|
584
|
+
return undefined;
|
|
769
585
|
},
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
586
|
+
onRejected() {
|
|
587
|
+
return undefined;
|
|
588
|
+
},
|
|
589
|
+
},
|
|
590
|
+
portRevokeCleanupWatcher: {
|
|
591
|
+
onFulfilled(_value) {
|
|
592
|
+
const { currentConnections, boundPorts, localAddr } = this.state;
|
|
773
593
|
|
|
774
|
-
|
|
594
|
+
this.state.revoked = RevokeState.REVOKED;
|
|
775
595
|
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
},
|
|
596
|
+
currentConnections.delete(this.facets.port);
|
|
597
|
+
boundPorts.delete(localAddr);
|
|
779
598
|
},
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
599
|
+
},
|
|
600
|
+
rethrowUnlessMissingWatcher: {
|
|
601
|
+
onRejected(e) {
|
|
602
|
+
rethrowUnlessMissing(e);
|
|
784
603
|
},
|
|
785
604
|
},
|
|
786
|
-
);
|
|
605
|
+
});
|
|
787
606
|
|
|
788
607
|
const makePort = ({
|
|
789
608
|
localAddr,
|
|
@@ -833,7 +652,7 @@ const prepareBinder = (zone, powers) => {
|
|
|
833
652
|
{
|
|
834
653
|
protocolImpl: Shape.ProtocolImplI,
|
|
835
654
|
binder: M.interface('Binder', {
|
|
836
|
-
bind: M.callWhen(Shape.Endpoint).returns(
|
|
655
|
+
bind: M.callWhen(Shape.Endpoint).returns(Shape.Vow$(Shape.Port)),
|
|
837
656
|
}),
|
|
838
657
|
binderInboundInstantiateWatcher: M.interface(
|
|
839
658
|
'BinderInboundInstantiateWatcher',
|
|
@@ -889,10 +708,10 @@ const prepareBinder = (zone, powers) => {
|
|
|
889
708
|
},
|
|
890
709
|
/**
|
|
891
710
|
* @param {object} opts
|
|
892
|
-
* @param {
|
|
711
|
+
* @param {MapStore<Port, SetStore<Closable>>} opts.currentConnections
|
|
893
712
|
* @param {MapStore<string, Port>} opts.boundPorts
|
|
894
|
-
* @param {MapStore<Endpoint, [Port, ListenHandler]>} opts.listening
|
|
895
|
-
* @param {ProtocolHandler} opts.protocolHandler
|
|
713
|
+
* @param {MapStore<Endpoint, [Port, Remote<Required<ListenHandler>>]>} opts.listening
|
|
714
|
+
* @param {Remote<ProtocolHandler>} opts.protocolHandler
|
|
896
715
|
*/
|
|
897
716
|
({ currentConnections, boundPorts, listening, protocolHandler }) => {
|
|
898
717
|
/** @type {SetStore<Connection>} */
|
|
@@ -937,7 +756,11 @@ const prepareBinder = (zone, powers) => {
|
|
|
937
756
|
const [port] = listening.get(/** @type {string} **/ (listenPrefix));
|
|
938
757
|
|
|
939
758
|
const innerVow = watch(
|
|
940
|
-
E(
|
|
759
|
+
E(
|
|
760
|
+
/** @type {Remote<Required<ProtocolHandler>>} */ (
|
|
761
|
+
protocolHandler
|
|
762
|
+
),
|
|
763
|
+
).onInstantiate(
|
|
941
764
|
/** @type {Port} **/ (port),
|
|
942
765
|
prefixes[listenPrefixIndex],
|
|
943
766
|
remoteAddr,
|
|
@@ -975,12 +798,11 @@ const prepareBinder = (zone, powers) => {
|
|
|
975
798
|
|
|
976
799
|
// Allocate a local address.
|
|
977
800
|
const instantiateInnerVow = watch(
|
|
978
|
-
E(
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
),
|
|
801
|
+
E(
|
|
802
|
+
/** @type {Remote<Required<ProtocolHandler>>} */ (
|
|
803
|
+
protocolHandler
|
|
804
|
+
),
|
|
805
|
+
).onInstantiate(port, localAddr, remoteAddr, protocolHandler),
|
|
984
806
|
this.facets.binderOutboundInstantiateWatcher,
|
|
985
807
|
{
|
|
986
808
|
port,
|
|
@@ -1102,7 +924,11 @@ const prepareBinder = (zone, powers) => {
|
|
|
1102
924
|
const [port] = listening.get(/** @type {string} */ (listenPrefix));
|
|
1103
925
|
|
|
1104
926
|
const innerVow = watch(
|
|
1105
|
-
E(
|
|
927
|
+
E(
|
|
928
|
+
/** @type {Remote<Required<ProtocolHandler>>} */ (
|
|
929
|
+
protocolHandler
|
|
930
|
+
),
|
|
931
|
+
).onInstantiate(
|
|
1106
932
|
port,
|
|
1107
933
|
prefixes[listenPrefixIndex],
|
|
1108
934
|
remoteAddr,
|
|
@@ -1150,9 +976,13 @@ const prepareBinder = (zone, powers) => {
|
|
|
1150
976
|
|
|
1151
977
|
return crossoverConnection(
|
|
1152
978
|
zone,
|
|
1153
|
-
|
|
979
|
+
/** @type {import('@agoric/vow').Remote<Required<ConnectionHandler>>} */ (
|
|
980
|
+
lchandler
|
|
981
|
+
),
|
|
1154
982
|
localAddr,
|
|
1155
|
-
|
|
983
|
+
/** @type {import('@agoric/vow').Remote<Required<ConnectionHandler>>} */ (
|
|
984
|
+
rchandler
|
|
985
|
+
),
|
|
1156
986
|
remoteAddr,
|
|
1157
987
|
makeConnection,
|
|
1158
988
|
current,
|
|
@@ -1210,7 +1040,7 @@ const prepareBinder = (zone, powers) => {
|
|
|
1210
1040
|
binderOutboundAcceptWatcher: {
|
|
1211
1041
|
onFulfilled(attempt, watchContext) {
|
|
1212
1042
|
const { handler } = watchContext;
|
|
1213
|
-
return attempt.accept({ handler });
|
|
1043
|
+
return E(attempt).accept({ handler });
|
|
1214
1044
|
},
|
|
1215
1045
|
},
|
|
1216
1046
|
binderBindGeneratePortWatcher: {
|
|
@@ -1238,7 +1068,7 @@ const prepareBinder = (zone, powers) => {
|
|
|
1238
1068
|
const { port, localAddr } = watchContext;
|
|
1239
1069
|
const { boundPorts, currentConnections } = this.state;
|
|
1240
1070
|
|
|
1241
|
-
boundPorts.init(localAddr,
|
|
1071
|
+
boundPorts.init(localAddr, port);
|
|
1242
1072
|
currentConnections.init(
|
|
1243
1073
|
port,
|
|
1244
1074
|
zone.detached().setStore('connections'),
|
|
@@ -1313,7 +1143,7 @@ export const prepareNetworkProtocol = (zone, powers) => {
|
|
|
1313
1143
|
const makeBinderKit = prepareBinder(zone, powers);
|
|
1314
1144
|
|
|
1315
1145
|
/**
|
|
1316
|
-
* @param {ProtocolHandler} protocolHandler
|
|
1146
|
+
* @param {Remote<ProtocolHandler>} protocolHandler
|
|
1317
1147
|
* @returns {Protocol}
|
|
1318
1148
|
*/
|
|
1319
1149
|
const makeNetworkProtocol = protocolHandler => {
|
|
@@ -1325,7 +1155,7 @@ export const prepareNetworkProtocol = (zone, powers) => {
|
|
|
1325
1155
|
/** @type {MapStore<string, Port>} */
|
|
1326
1156
|
const boundPorts = detached.mapStore('addrToPort');
|
|
1327
1157
|
|
|
1328
|
-
/** @type {MapStore<Endpoint, [Port, ListenHandler]>} */
|
|
1158
|
+
/** @type {MapStore<Endpoint, [Port, Remote<Required<ListenHandler>>]>} */
|
|
1329
1159
|
const listening = detached.mapStore('listening');
|
|
1330
1160
|
|
|
1331
1161
|
const { binder, protocolImpl } = makeBinderKit({
|
|
@@ -1354,14 +1184,14 @@ export const prepareEchoConnectionKit = zone => {
|
|
|
1354
1184
|
{
|
|
1355
1185
|
handler: M.interface('ConnectionHandler', {
|
|
1356
1186
|
onReceive: M.callWhen(
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1187
|
+
Shape.Connection,
|
|
1188
|
+
Shape.Bytes,
|
|
1189
|
+
Shape.ConnectionHandler,
|
|
1360
1190
|
)
|
|
1361
|
-
.optional(
|
|
1362
|
-
.returns(
|
|
1363
|
-
onClose: M.callWhen(
|
|
1364
|
-
.optional(M.any(),
|
|
1191
|
+
.optional(Shape.Opts)
|
|
1192
|
+
.returns(Shape.Data),
|
|
1193
|
+
onClose: M.callWhen(Shape.Connection)
|
|
1194
|
+
.optional(M.any(), Shape.ConnectionHandler)
|
|
1365
1195
|
.returns(M.undefined()),
|
|
1366
1196
|
}),
|
|
1367
1197
|
listener: M.interface('Listener', {
|
|
@@ -1377,10 +1207,9 @@ export const prepareEchoConnectionKit = zone => {
|
|
|
1377
1207
|
}),
|
|
1378
1208
|
},
|
|
1379
1209
|
() => {
|
|
1380
|
-
/** @type {string | undefined} */
|
|
1381
|
-
let closed;
|
|
1382
1210
|
return {
|
|
1383
|
-
|
|
1211
|
+
/** @type {string | undefined} */
|
|
1212
|
+
closed: undefined,
|
|
1384
1213
|
};
|
|
1385
1214
|
},
|
|
1386
1215
|
{
|
|
@@ -1394,7 +1223,7 @@ export const prepareEchoConnectionKit = zone => {
|
|
|
1394
1223
|
const { closed } = this.state;
|
|
1395
1224
|
|
|
1396
1225
|
if (closed) {
|
|
1397
|
-
throw closed;
|
|
1226
|
+
throw Error(closed);
|
|
1398
1227
|
}
|
|
1399
1228
|
return bytes;
|
|
1400
1229
|
},
|
|
@@ -1415,7 +1244,7 @@ export const prepareEchoConnectionKit = zone => {
|
|
|
1415
1244
|
},
|
|
1416
1245
|
listener: {
|
|
1417
1246
|
async onAccept(_port, _localAddr, _remoteAddr, _listenHandler) {
|
|
1418
|
-
return
|
|
1247
|
+
return this.facets.handler;
|
|
1419
1248
|
},
|
|
1420
1249
|
async onListen(port, _listenHandler) {
|
|
1421
1250
|
console.debug(`listening on echo port: ${port}`);
|
|
@@ -1433,24 +1262,27 @@ export const prepareEchoConnectionKit = zone => {
|
|
|
1433
1262
|
* @param {import('@agoric/base-zone').Zone} zone
|
|
1434
1263
|
* @param {ReturnType<import('@agoric/vow').prepareVowTools>} powers
|
|
1435
1264
|
*/
|
|
1436
|
-
export function prepareLoopbackProtocolHandler(zone, { watch }) {
|
|
1265
|
+
export function prepareLoopbackProtocolHandler(zone, { watch, allVows }) {
|
|
1437
1266
|
const detached = zone.detached();
|
|
1438
1267
|
|
|
1268
|
+
/** @param {string} [instancePrefix] */
|
|
1269
|
+
const initHandler = (instancePrefix = 'nonce/') => {
|
|
1270
|
+
/** @type {MapStore<string, [Remote<Port>, Remote<Required<ListenHandler>>]>} */
|
|
1271
|
+
const listeners = detached.mapStore('localAddr');
|
|
1272
|
+
|
|
1273
|
+
return {
|
|
1274
|
+
listeners,
|
|
1275
|
+
portNonce: 0n,
|
|
1276
|
+
instancePrefix,
|
|
1277
|
+
instanceNonce: 0n,
|
|
1278
|
+
};
|
|
1279
|
+
};
|
|
1280
|
+
|
|
1439
1281
|
const makeLoopbackProtocolHandlerKit = zone.exoClassKit(
|
|
1440
1282
|
'ProtocolHandler',
|
|
1441
1283
|
Shape.ProtocolHandlerI,
|
|
1442
1284
|
/** @param {string} [instancePrefix] */
|
|
1443
|
-
|
|
1444
|
-
/** @type {MapStore<string, [Port, ListenHandler]>} */
|
|
1445
|
-
const listeners = detached.mapStore('localAddr');
|
|
1446
|
-
|
|
1447
|
-
return {
|
|
1448
|
-
listeners,
|
|
1449
|
-
portNonce: 0n,
|
|
1450
|
-
instancePrefix,
|
|
1451
|
-
instanceNonce: 0n,
|
|
1452
|
-
};
|
|
1453
|
-
},
|
|
1285
|
+
initHandler,
|
|
1454
1286
|
{
|
|
1455
1287
|
protocolHandler: {
|
|
1456
1288
|
async onCreate(_impl, _protocolHandler) {
|
|
@@ -1463,13 +1295,13 @@ export function prepareLoopbackProtocolHandler(zone, { watch }) {
|
|
|
1463
1295
|
async onBind(_port, _localAddr, _protocolHandler) {
|
|
1464
1296
|
// noop, for now; Maybe handle a bind?
|
|
1465
1297
|
},
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
) {
|
|
1298
|
+
/**
|
|
1299
|
+
* @param {*} _port
|
|
1300
|
+
* @param {Endpoint} localAddr
|
|
1301
|
+
* @param {Endpoint} remoteAddr
|
|
1302
|
+
* @returns {PromiseVow<AttemptDescription>}}
|
|
1303
|
+
*/
|
|
1304
|
+
async onConnect(_port, localAddr, remoteAddr) {
|
|
1473
1305
|
const { listeners } = this.state;
|
|
1474
1306
|
const [lport, lhandler] = listeners.get(remoteAddr);
|
|
1475
1307
|
|
|
@@ -1479,11 +1311,11 @@ export function prepareLoopbackProtocolHandler(zone, { watch }) {
|
|
|
1479
1311
|
);
|
|
1480
1312
|
|
|
1481
1313
|
const instantiateInnerVow = watch(
|
|
1482
|
-
E(protocolHandler).onInstantiate(
|
|
1314
|
+
E(this.facets.protocolHandler).onInstantiate(
|
|
1483
1315
|
lport,
|
|
1484
1316
|
remoteAddr,
|
|
1485
1317
|
localAddr,
|
|
1486
|
-
protocolHandler,
|
|
1318
|
+
this.facets.protocolHandler,
|
|
1487
1319
|
),
|
|
1488
1320
|
this.facets.protocolHandlerInstantiateWatcher,
|
|
1489
1321
|
);
|
|
@@ -1493,7 +1325,7 @@ export function prepareLoopbackProtocolHandler(zone, { watch }) {
|
|
|
1493
1325
|
this.facets.rethrowUnlessMissingWatcher,
|
|
1494
1326
|
);
|
|
1495
1327
|
return watch(
|
|
1496
|
-
|
|
1328
|
+
allVows([acceptVow, instantiateVow]),
|
|
1497
1329
|
this.facets.protocolHandlerConnectWatcher,
|
|
1498
1330
|
);
|
|
1499
1331
|
},
|
|
@@ -1510,16 +1342,30 @@ export function prepareLoopbackProtocolHandler(zone, { watch }) {
|
|
|
1510
1342
|
if (listeners.has(localAddr)) {
|
|
1511
1343
|
const lhandler = listeners.get(localAddr)[1];
|
|
1512
1344
|
if (lhandler !== listenHandler) {
|
|
1513
|
-
listeners.set(
|
|
1345
|
+
listeners.set(
|
|
1346
|
+
localAddr,
|
|
1347
|
+
harden([
|
|
1348
|
+
port,
|
|
1349
|
+
/** @type {Remote<Required<ListenHandler>>} */ (
|
|
1350
|
+
listenHandler
|
|
1351
|
+
),
|
|
1352
|
+
]),
|
|
1353
|
+
);
|
|
1514
1354
|
}
|
|
1515
1355
|
} else {
|
|
1516
|
-
listeners.init(
|
|
1356
|
+
listeners.init(
|
|
1357
|
+
localAddr,
|
|
1358
|
+
harden([
|
|
1359
|
+
port,
|
|
1360
|
+
/** @type {Remote<Required<ListenHandler>>} */ (listenHandler),
|
|
1361
|
+
]),
|
|
1362
|
+
);
|
|
1517
1363
|
}
|
|
1518
1364
|
},
|
|
1519
1365
|
/**
|
|
1520
|
-
* @param {Port} port
|
|
1366
|
+
* @param {Remote<Port>} port
|
|
1521
1367
|
* @param {Endpoint} localAddr
|
|
1522
|
-
* @param {ListenHandler} listenHandler
|
|
1368
|
+
* @param {Remote<ListenHandler>} listenHandler
|
|
1523
1369
|
* @param {*} _protocolHandler
|
|
1524
1370
|
*/
|
|
1525
1371
|
async onListenRemove(port, localAddr, listenHandler, _protocolHandler) {
|