@amritk/nish-x86_64-linux 0.18.0 → 0.21.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/INSTALL.md +58 -28
- package/bin/nish +0 -0
- package/docs/AI.md +2759 -0
- package/package.json +3 -2
- package/runtime/browser.d.ts +14 -0
- package/runtime/browser.mjs +88 -0
- package/runtime/core/arrays.d.ts +18 -0
- package/runtime/core/arrays.mjs +125 -0
- package/runtime/core/checks.mjs +20 -0
- package/runtime/core/host.d.ts +70 -0
- package/runtime/core/host.mjs +311 -0
- package/runtime/core/numbers.d.ts +53 -0
- package/runtime/core/numbers.mjs +316 -0
- package/runtime/core/result.d.ts +41 -0
- package/runtime/core/result.mjs +127 -0
- package/runtime/core/strings.d.ts +14 -0
- package/runtime/core/strings.mjs +169 -0
- package/runtime/core.d.ts +9 -0
- package/runtime/core.mjs +55 -0
- package/runtime/host.d.ts +6 -0
- package/runtime/nish.d.ts +99 -5
- package/runtime/nish.h +289 -19
- package/runtime/nish.mjs +39 -3
- package/runtime/node.mjs +383 -0
- package/runtime/runtime-aes.c +490 -0
- package/runtime/runtime-bytes.c +401 -0
- package/runtime/runtime-cross.c +366 -0
- package/runtime/runtime-host.c +8 -7
- package/runtime/runtime-net.c +93 -34
- package/runtime/runtime-os.c +214 -16
- package/runtime/runtime-parallel.c +590 -107
- package/runtime/runtime-simd.c +235 -11
- package/runtime/runtime-term.c +504 -0
- package/runtime/runtime-wasm.c +5 -14
- package/runtime/runtime.c +257 -17
- package/runtime/shim.mjs +6 -915
- package/runtime/sqlite/LICENSE.md +85 -0
- package/runtime/sqlite/README.md +45 -0
- package/runtime/sqlite/nish-sqlite.c +359 -0
- package/runtime/sqlite/sqlite3.c +271131 -0
- package/runtime/sqlite/sqlite3.h +14447 -0
- package/scripts/build.sh +437 -28
- package/std/LICENSE-fast-float +23 -0
- package/std/LICENSE-fdlibm +8 -0
- package/std/README.md +108 -58
- package/std/base64.ts +116 -0
- package/std/bytes.ts +419 -0
- package/std/cli.ts +328 -0
- package/std/collections.ts +6 -5
- package/std/crypto/LICENSE-crypt_blowfish +26 -0
- package/std/crypto/LICENSE-libsecp256k1 +19 -0
- package/std/crypto/aes.ts +238 -76
- package/std/crypto/base64url.ts +125 -0
- package/std/crypto/bcrypt.ts +760 -0
- package/std/crypto/chacha20poly1305.ts +43 -9
- package/std/crypto/ed25519.ts +840 -0
- package/std/crypto/hkdf.ts +304 -12
- package/std/crypto/hmac.ts +382 -54
- package/std/crypto/p256.ts +932 -61
- package/std/crypto/x25519.ts +55 -37
- package/std/crypto/x509-random.ts +71 -0
- package/std/crypto/x509.ts +20 -131
- package/std/json-tokenizer.ts +4237 -0
- package/std/json-typed.ts +1014 -0
- package/std/json-value.ts +1182 -0
- package/std/json.ts +1202 -34
- package/std/math.ts +608 -0
- package/std/net/buffer-pool.ts +151 -0
- package/std/net/hpack.ts +416 -112
- package/std/net/http-fields.ts +93 -0
- package/std/net/http1-server.ts +501 -62
- package/std/net/http1.ts +31 -6
- package/std/net/http2-tls.ts +112 -24
- package/std/net/http2.ts +333 -75
- package/std/net/http3-server.ts +261 -43
- package/std/net/http3.ts +187 -28
- package/std/net/postgres.ts +1875 -0
- package/std/net/prefork.ts +412 -0
- package/std/net/quic-listener.ts +108 -11
- package/std/net/quic-packet.ts +243 -82
- package/std/net/quic-recovery.ts +361 -30
- package/std/net/quic-stream.ts +424 -24
- package/std/net/quic.ts +519 -167
- package/std/net/router.ts +676 -0
- package/std/net/tls/codec.ts +426 -27
- package/std/net/tls/record-server.ts +478 -132
- package/std/net/tls/record.ts +133 -42
- package/std/net/tls/schedule.ts +464 -55
- package/std/net/tls/ticket.ts +610 -0
- package/std/net/tls-tcp.ts +196 -53
- package/std/net/tls.ts +1018 -260
- package/std/net/url.ts +571 -0
- package/std/random.ts +94 -0
- package/std/regex.ts +4274 -0
- package/std/sqlite.ts +391 -0
- package/std/term-io.ts +978 -0
- package/std/term-pixels.ts +874 -0
- package/std/term-probe.ts +459 -0
- package/std/term-rate.ts +993 -0
- package/std/term.ts +2453 -0
- package/std/text.ts +90 -7
- package/std/threads.ts +438 -14
- package/std/yaml-lines.ts +141 -0
- package/std/yaml.ts +4675 -0
package/std/net/tls-tcp.ts
CHANGED
|
@@ -26,13 +26,20 @@
|
|
|
26
26
|
* stops asking to be written. An event with the hang-up bit (4) goes to
|
|
27
27
|
* `readable`, which is where a closed or failed socket is noticed.
|
|
28
28
|
*
|
|
29
|
-
* **Slots,
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
29
|
+
* **Slots, built on first use; record buffers, borrowed.** The pool's size
|
|
30
|
+
* is a cap: the constructor builds no slot, and the first `accept` into a
|
|
31
|
+
* slot builds its handshake state and keys (TLS-3) and keeps them, so a pool
|
|
32
|
+
* sized for its peak costs at start-up only what does not depend on the
|
|
33
|
+
* size. `accept` hands the next connection the slot closed last, or failing
|
|
34
|
+
* that the next never used, and reuses it once the program `close`s it
|
|
35
|
+
* (WP34 N9). The record buffers — the bytes to send, the plaintext waiting
|
|
36
|
+
* for the program, the record being opened and the record being read — are
|
|
37
|
+
* borrowed from pools this server owns while a connection uses the slot, and
|
|
38
|
+
* given back zeroed (`BufferPool.giveSecret`) when it ends, so a free slot
|
|
39
|
+
* holds none of them ("What moves between connections" in
|
|
40
|
+
* `docs/security/tls.md`). When every slot is busy a new connection is
|
|
41
|
+
* accepted and closed at once, so the listener does not stay readable; the
|
|
42
|
+
* program sees `TLS_TCP_POOL_FULL`. Each slot keeps its own `TlsServer`, which `accept` restarts for the connection, so neither the
|
|
36
43
|
* handshake nor application data allocates anything that outlives a call:
|
|
37
44
|
* a thousand connections through one slot leave `Arena.mark()` where the
|
|
38
45
|
* first left it, under every suite (TLS-3 in `docs/security/tls.md`,
|
|
@@ -50,6 +57,15 @@
|
|
|
50
57
|
* borrows for the call, and `signatureInput` / `sign` hand the input out and
|
|
51
58
|
* take any signature back.
|
|
52
59
|
*
|
|
60
|
+
* **Resumption is opt-in, and its keys are the caller's.** After
|
|
61
|
+
* `enableTickets`, a slot whose interest says `TLS_RECORD_TICKET` waits on
|
|
62
|
+
* the program: in the handshake, `resume` reads the ClientHello's tickets
|
|
63
|
+
* under the current and previous ticket keys and a strike register the
|
|
64
|
+
* program lends for the call, and answers the hello resumed or in full; once
|
|
65
|
+
* the connection is open, `issue` seals it one ticket. The pool keeps no
|
|
66
|
+
* ticket key and no register of its own (`docs/security/tls.md`,
|
|
67
|
+
* "Resumption").
|
|
68
|
+
*
|
|
53
69
|
* `read`, `write` and `close` answer as `nish:net`'s calls do — a count, `0`
|
|
54
70
|
* at the end of the stream, `-11` to wait — so a program written against a
|
|
55
71
|
* plain socket moves over with the `slot` in place of the descriptor.
|
|
@@ -64,11 +80,13 @@ import { netClose, netRead, netWrite, tcpAccept } from "nish:net"
|
|
|
64
80
|
import { TlsP256Signer, TlsServer, TlsServerConfig } from "nish/net/tls"
|
|
65
81
|
import { TLS_ALERT_INTERNAL_ERROR } from "nish/net/tls/codec"
|
|
66
82
|
import { TLS_MAX_RECORD } from "nish/net/tls/record"
|
|
83
|
+
import { TlsTicketKeyInfo, TlsTicketStrikes } from "nish/net/tls/ticket"
|
|
67
84
|
import {
|
|
68
85
|
TLS_RECORD_AGAIN,
|
|
69
86
|
TLS_RECORD_DONE,
|
|
70
87
|
TLS_RECORD_INVALID,
|
|
71
88
|
TLS_RECORD_STATE_FAILED,
|
|
89
|
+
TlsRecordPools,
|
|
72
90
|
TlsRecordServer,
|
|
73
91
|
} from "nish/net/tls/record-server"
|
|
74
92
|
|
|
@@ -95,10 +113,24 @@ const TLS_TCP_ADDRESS_SIZE: i32 = 18
|
|
|
95
113
|
*/
|
|
96
114
|
export class TlsTcpServer {
|
|
97
115
|
config: TlsServerConfig
|
|
98
|
-
/**
|
|
116
|
+
/**
|
|
117
|
+
* The connections built so far, slot `k`'s at `k`: one per slot ever
|
|
118
|
+
* accepted into. `connection` never adds to it; a slot never built reads
|
|
119
|
+
* `vacant` instead.
|
|
120
|
+
*/
|
|
99
121
|
connections: TlsRecordServer[]
|
|
100
|
-
/**
|
|
122
|
+
/**
|
|
123
|
+
* Each slot's descriptor, or -1 while the slot is free, for the slots
|
|
124
|
+
* accepted into so far: its length is the high-water mark, and a slot past
|
|
125
|
+
* it has never been used.
|
|
126
|
+
*/
|
|
101
127
|
fds: i32[]
|
|
128
|
+
/**
|
|
129
|
+
* The slots closed since they were used, a stack whose top `accept` takes
|
|
130
|
+
* before it builds a slot past the high-water mark, so finding one costs
|
|
131
|
+
* the same with every slot free as with all but one busy.
|
|
132
|
+
*/
|
|
133
|
+
free: i32[]
|
|
102
134
|
/** Where the socket is read into before a connection takes the bytes: the largest record. */
|
|
103
135
|
scratch: u8[]
|
|
104
136
|
/** The last accepted peer's address, in `nish:net`'s 18-byte form. */
|
|
@@ -106,49 +138,92 @@ export class TlsTcpServer {
|
|
|
106
138
|
/** Signs every slot's CertificateVerify in `signP256`, one for the pool, keeping nothing per signature. */
|
|
107
139
|
signer: TlsP256Signer
|
|
108
140
|
/**
|
|
109
|
-
* Each slot's own copy of its connection's
|
|
110
|
-
*
|
|
141
|
+
* Each slot's own copy of its connection's server random: `TlsServer`
|
|
142
|
+
* keeps the array it is given and writes it into the ServerHello only once
|
|
143
|
+
* the ClientHello arrives, so the program's array may be refilled for the
|
|
144
|
+
* next one. The ephemeral key needs no copy here: `TlsServer.restart`
|
|
145
|
+
* copies it into the server's own `Secret` and wipes the array it was
|
|
146
|
+
* handed.
|
|
111
147
|
*/
|
|
112
|
-
|
|
148
|
+
randoms: u8[][]
|
|
149
|
+
/** How many slots the pool may hold, which `size` answers. */
|
|
150
|
+
slots: i32 = 1
|
|
151
|
+
/** Whether `enableTickets` has run, so a slot built after it resumes too. */
|
|
152
|
+
tickets: boolean = false
|
|
113
153
|
/**
|
|
114
|
-
*
|
|
115
|
-
*
|
|
116
|
-
*
|
|
154
|
+
* What `connection` answers for every slot never built: one failed
|
|
155
|
+
* connection no slot holds and every such slot shares, so the slot reads
|
|
156
|
+
* as a free one does (no ALPN, not open) and never as another slot's live
|
|
157
|
+
* session. Its first read allocates it, once per server; it has no
|
|
158
|
+
* tickets, and a caller must not change it.
|
|
117
159
|
*/
|
|
118
|
-
|
|
160
|
+
vacant: TlsRecordServer | null = null
|
|
161
|
+
/**
|
|
162
|
+
* The pools every slot borrows its record buffers from, each with a
|
|
163
|
+
* ceiling of one per slot: `lent()` is 0 once every connection has ended,
|
|
164
|
+
* and `made()` is the most connections that were ever open at once.
|
|
165
|
+
*/
|
|
166
|
+
pools: TlsRecordPools
|
|
119
167
|
/** The listening socket, which the program made with `tcpListen` and still owns. */
|
|
120
168
|
listener: i32 = -1
|
|
121
169
|
|
|
122
170
|
/**
|
|
123
171
|
* A pool of `size` slots, at least one, serving `config` on `listener`, a
|
|
124
|
-
* socket `tcpListen` made.
|
|
172
|
+
* socket `tcpListen` made. No slot is built here: a slot's handshake state
|
|
173
|
+
* and its server random are allocated by the first `accept` into it and
|
|
174
|
+
* kept, and its record buffers are borrowed from `pools` while a
|
|
175
|
+
* connection uses them, so a pool sized for a peak costs at start-up only
|
|
176
|
+
* the read scratch, the signer and the empty pools.
|
|
125
177
|
*/
|
|
126
178
|
constructor(config: TlsServerConfig, listener: i32, size: i32) {
|
|
127
179
|
this.config = config
|
|
128
180
|
this.listener = listener
|
|
129
181
|
this.connections = []
|
|
130
182
|
this.fds = []
|
|
131
|
-
this.
|
|
183
|
+
this.free = []
|
|
132
184
|
this.randoms = []
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
for (let k: i32 = 0; k < slots; k++) {
|
|
136
|
-
// Each slot's own handshake, refused by `TlsServer` for its empty
|
|
137
|
-
// randomness, so the slot starts out failed until `accept` restarts it
|
|
138
|
-
// for a connection; every later connection reuses its buffers.
|
|
139
|
-
this.connections.push(new TlsRecordServer(new TlsServer(config, none, none)))
|
|
140
|
-
this.fds.push(TLS_TCP_FREE)
|
|
141
|
-
this.keys.push(new Array<u8>(TLS_TCP_KEY_SIZE))
|
|
142
|
-
this.randoms.push(new Array<u8>(TLS_TCP_KEY_SIZE))
|
|
143
|
-
}
|
|
185
|
+
this.slots = size < 1 ? 1 : size
|
|
186
|
+
this.pools = new TlsRecordPools(this.slots)
|
|
144
187
|
this.scratch = new Array<u8>(TLS_MAX_RECORD)
|
|
145
188
|
this.peer = new Array<u8>(TLS_TCP_ADDRESS_SIZE)
|
|
146
189
|
this.signer = new TlsP256Signer()
|
|
147
190
|
}
|
|
148
191
|
|
|
149
|
-
/**
|
|
192
|
+
/**
|
|
193
|
+
* The next slot's connection and server random, for the slot built next.
|
|
194
|
+
* Called by `accept` alone, as the pool's high-water mark rises: slot `k`'s
|
|
195
|
+
* entry must sit at index `k` of `connections` and `randoms`. Its handshake
|
|
196
|
+
* is never given a ClientHello: `accept` restarts it for a connection with
|
|
197
|
+
* real randomness, and every later connection reuses its state.
|
|
198
|
+
*/
|
|
199
|
+
build(): TlsRecordServer {
|
|
200
|
+
const random: u8[] = new Array<u8>(TLS_TCP_KEY_SIZE)
|
|
201
|
+
this.randoms.push(random)
|
|
202
|
+
const conn: TlsRecordServer = this.make(random)
|
|
203
|
+
if (this.tickets) {
|
|
204
|
+
conn.tls.enableTickets()
|
|
205
|
+
}
|
|
206
|
+
this.connections.push(conn)
|
|
207
|
+
return conn
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* A connection over `random` that is marked failed without sealing an
|
|
212
|
+
* alert, so a stray call on it fails closed, and that borrows no buffer
|
|
213
|
+
* until a connection moves bytes through it.
|
|
214
|
+
*/
|
|
215
|
+
make(random: u8[]): TlsRecordServer {
|
|
216
|
+
// A placeholder key for a first handshake, which never runs.
|
|
217
|
+
const zeros: u8[] = new Array<u8>(TLS_TCP_KEY_SIZE)
|
|
218
|
+
const conn: TlsRecordServer = new TlsRecordServer(new TlsServer(this.config, random, zeros))
|
|
219
|
+
conn.borrowFrom(this.pools)
|
|
220
|
+
conn.state = TLS_RECORD_STATE_FAILED
|
|
221
|
+
return conn
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/** How many slots the pool has, built or not. */
|
|
150
225
|
size(): i32 {
|
|
151
|
-
return
|
|
226
|
+
return this.slots
|
|
152
227
|
}
|
|
153
228
|
|
|
154
229
|
/** How many slots hold a connection. */
|
|
@@ -175,11 +250,22 @@ export class TlsTcpServer {
|
|
|
175
250
|
/**
|
|
176
251
|
* The connection in `slot`: its state, its handshake (`tls`: suite, ALPN,
|
|
177
252
|
* server name) and the alerts sent and received. A free slot answers the
|
|
178
|
-
* last connection it held.
|
|
253
|
+
* last connection it held. A slot never accepted into answers `vacant`,
|
|
254
|
+
* failed, as a free slot does, and builds no slot; a slot out of range
|
|
255
|
+
* names slot 0's.
|
|
179
256
|
*/
|
|
180
257
|
connection(slot: i32): TlsRecordServer {
|
|
181
|
-
const
|
|
182
|
-
|
|
258
|
+
const index: i32 = slot >= 0 && slot < this.slots ? slot : 0
|
|
259
|
+
if (index >= 0 && index < toI32(this.connections.length)) {
|
|
260
|
+
return this.connections[index]
|
|
261
|
+
}
|
|
262
|
+
const vacant: TlsRecordServer | null = this.vacant
|
|
263
|
+
if (vacant !== null) {
|
|
264
|
+
return vacant
|
|
265
|
+
}
|
|
266
|
+
const made: TlsRecordServer = this.make(new Array<u8>(TLS_TCP_KEY_SIZE))
|
|
267
|
+
this.vacant = made
|
|
268
|
+
return made
|
|
183
269
|
}
|
|
184
270
|
|
|
185
271
|
/**
|
|
@@ -205,20 +291,25 @@ export class TlsTcpServer {
|
|
|
205
291
|
if (fd < 0) {
|
|
206
292
|
return fd
|
|
207
293
|
}
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
294
|
+
// A slot closed before is taken first, then the next never used, so the
|
|
295
|
+
// first accepts take slots 0, 1, 2 ... and a pool that never fills never
|
|
296
|
+
// builds its last slots.
|
|
297
|
+
let slot: i32 = TLS_TCP_POOL_FULL
|
|
298
|
+
if (this.free.length > 0) {
|
|
299
|
+
slot = this.free[this.free.length - 1]
|
|
300
|
+
this.free.pop()
|
|
301
|
+
} else if (toI32(this.fds.length) < this.slots) {
|
|
302
|
+
slot = toI32(this.fds.length)
|
|
303
|
+
this.fds.push(TLS_TCP_FREE)
|
|
214
304
|
}
|
|
215
|
-
if (slot < 0) {
|
|
305
|
+
if (slot < 0 || slot >= toI32(this.fds.length)) {
|
|
216
306
|
netClose(fd)
|
|
217
307
|
return TLS_TCP_POOL_FULL
|
|
218
308
|
}
|
|
309
|
+
const conn: TlsRecordServer =
|
|
310
|
+
slot < toI32(this.connections.length) ? this.connections[slot] : this.build()
|
|
219
311
|
this.fds[slot] = fd
|
|
220
312
|
const random: u8[] = this.randoms[slot]
|
|
221
|
-
const key: u8[] = this.keys[slot]
|
|
222
313
|
for (
|
|
223
314
|
let k: i32 = 0;
|
|
224
315
|
k < TLS_TCP_KEY_SIZE && k < toI32(random.length) && k < toI32(serverRandom.length);
|
|
@@ -226,16 +317,8 @@ export class TlsTcpServer {
|
|
|
226
317
|
) {
|
|
227
318
|
random[k] = serverRandom[k]
|
|
228
319
|
}
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
k < TLS_TCP_KEY_SIZE && k < toI32(key.length) && k < toI32(ephemeralPrivate.length);
|
|
232
|
-
k++
|
|
233
|
-
) {
|
|
234
|
-
key[k] = ephemeralPrivate[k]
|
|
235
|
-
}
|
|
236
|
-
secureZero(ephemeralPrivate)
|
|
237
|
-
const conn: TlsRecordServer = this.connections[slot]
|
|
238
|
-
conn.tls.restart(random, key)
|
|
320
|
+
// `restart` copies the key into the server's own `Secret` and wipes this array.
|
|
321
|
+
conn.tls.restart(random, ephemeralPrivate)
|
|
239
322
|
conn.start(conn.tls)
|
|
240
323
|
return slot
|
|
241
324
|
}
|
|
@@ -280,8 +363,15 @@ export class TlsTcpServer {
|
|
|
280
363
|
return this.flush(slot)
|
|
281
364
|
}
|
|
282
365
|
|
|
283
|
-
/**
|
|
366
|
+
/**
|
|
367
|
+
* Writes the connection's output until the socket would block or it is all
|
|
368
|
+
* sent, and answers its `interest`; a slot never built answers
|
|
369
|
+
* `TLS_RECORD_DONE`.
|
|
370
|
+
*/
|
|
284
371
|
flush(slot: i32): i32 {
|
|
372
|
+
if (slot < 0 || slot >= toI32(this.fds.length) || slot >= toI32(this.connections.length)) {
|
|
373
|
+
return TLS_RECORD_DONE
|
|
374
|
+
}
|
|
285
375
|
const fd: i32 = this.fds[slot]
|
|
286
376
|
const conn: TlsRecordServer = this.connections[slot]
|
|
287
377
|
while (conn.outputEnd > conn.outputStart) {
|
|
@@ -336,6 +426,56 @@ export class TlsTcpServer {
|
|
|
336
426
|
return this.sign(slot, signature)
|
|
337
427
|
}
|
|
338
428
|
|
|
429
|
+
/**
|
|
430
|
+
* Turns session resumption on for every slot (`TlsServer.enableTickets`):
|
|
431
|
+
* from the next `accept`, a connection offering a ticket, or one that may
|
|
432
|
+
* be issued one, says `TLS_RECORD_TICKET` in its interest. A slot built
|
|
433
|
+
* later is built with them on.
|
|
434
|
+
*/
|
|
435
|
+
enableTickets(): void {
|
|
436
|
+
this.tickets = true
|
|
437
|
+
for (let k: i32 = 0; k < toI32(this.connections.length); k++) {
|
|
438
|
+
this.connections[k].tls.enableTickets()
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
/**
|
|
443
|
+
* While `slot`'s interest says `TLS_RECORD_TICKET` in the handshake: reads
|
|
444
|
+
* its ClientHello's tickets under `current` and `previous`, with what each
|
|
445
|
+
* `info` says of them, records the one it resumes in `strikes`, and sends
|
|
446
|
+
* the flight that answers the hello, resumed or in full
|
|
447
|
+
* (`TlsRecordServer.resume`). The keys and the register are borrowed for
|
|
448
|
+
* the call. Answers the slot's interest.
|
|
449
|
+
*/
|
|
450
|
+
resume(
|
|
451
|
+
slot: i32,
|
|
452
|
+
current: Secret<u8[]>,
|
|
453
|
+
currentInfo: TlsTicketKeyInfo,
|
|
454
|
+
previous: Secret<u8[]>,
|
|
455
|
+
previousInfo: TlsTicketKeyInfo,
|
|
456
|
+
strikes: TlsTicketStrikes,
|
|
457
|
+
now: i64
|
|
458
|
+
): i32 {
|
|
459
|
+
if (!this.holds(slot)) {
|
|
460
|
+
return TLS_RECORD_DONE
|
|
461
|
+
}
|
|
462
|
+
this.connections[slot].resume(current, currentInfo, previous, previousInfo, strikes, now)
|
|
463
|
+
return this.flush(slot)
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
/**
|
|
467
|
+
* While `slot`'s interest says `TLS_RECORD_TICKET` on an open connection:
|
|
468
|
+
* seals one ticket under the borrowed `key` and sends its
|
|
469
|
+
* NewSessionTicket (`TlsRecordServer.issue`). Answers the slot's interest.
|
|
470
|
+
*/
|
|
471
|
+
issue(slot: i32, key: Secret<u8[]>, info: TlsTicketKeyInfo, now: i64): i32 {
|
|
472
|
+
if (!this.holds(slot)) {
|
|
473
|
+
return TLS_RECORD_DONE
|
|
474
|
+
}
|
|
475
|
+
this.connections[slot].issue(key, info, now)
|
|
476
|
+
return this.flush(slot)
|
|
477
|
+
}
|
|
478
|
+
|
|
339
479
|
/**
|
|
340
480
|
* Application data from `slot`'s client into `buf[off .. off + len)`: the
|
|
341
481
|
* count, 0 at the end of its stream, -11 when nothing is waiting, -104 once
|
|
@@ -409,6 +549,9 @@ export class TlsTcpServer {
|
|
|
409
549
|
this.flush(slot)
|
|
410
550
|
netClose(this.fds[slot])
|
|
411
551
|
this.fds[slot] = TLS_TCP_FREE
|
|
552
|
+
this.free.push(slot)
|
|
412
553
|
conn.wipeKeys()
|
|
554
|
+
// Whatever the last flush could not send is dropped with its buffer.
|
|
555
|
+
conn.release()
|
|
413
556
|
}
|
|
414
557
|
}
|