@amritk/nish-x86_64-linux 0.18.0 → 0.20.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 +43 -25
- package/bin/nish +0 -0
- package/package.json +2 -2
- package/runtime/nish.d.ts +55 -5
- package/runtime/nish.h +215 -18
- package/runtime/nish.mjs +16 -0
- package/runtime/runtime-aes.c +490 -0
- package/runtime/runtime-cross.c +366 -0
- package/runtime/runtime-host.c +7 -6
- package/runtime/runtime-net.c +93 -34
- package/runtime/runtime-os.c +213 -15
- package/runtime/runtime-parallel.c +590 -107
- package/runtime/runtime-simd.c +4 -4
- package/runtime/runtime-wasm.c +5 -3
- package/runtime/runtime.c +69 -13
- package/runtime/shim.mjs +71 -1
- package/scripts/build.sh +223 -22
- package/std/README.md +81 -51
- package/std/bytes.ts +163 -0
- package/std/crypto/LICENSE-libsecp256k1 +19 -0
- package/std/crypto/aes.ts +238 -76
- 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 +245 -53
- 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 +9 -9
- package/std/json-tokenizer.ts +1296 -0
- package/std/json-typed.ts +1014 -0
- package/std/json-value.ts +1163 -0
- package/std/json.ts +1120 -34
- 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 +417 -55
- 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 +211 -31
- package/std/net/http3.ts +187 -28
- package/std/net/prefork.ts +412 -0
- package/std/net/quic-listener.ts +88 -7
- 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/threads.ts +438 -14
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `nish/net/buffer-pool` — fixed-size byte buffers a server's connections
|
|
3
|
+
* borrow and give back, so the memory a server holds follows the connections
|
|
4
|
+
* that are moving bytes, not the slots it was sized for.
|
|
5
|
+
*
|
|
6
|
+
* const pool = new BufferPool("TlsTcpServer.output", 33290, slots);
|
|
7
|
+
* // when a connection first needs room:
|
|
8
|
+
* const out: u8[] = pool.take();
|
|
9
|
+
* // ... write out[0 .. used) and send it ...
|
|
10
|
+
* pool.giveSecret(out, used); // or pool.give(out, used) for bytes that were never secret
|
|
11
|
+
*
|
|
12
|
+
* It has the shape of `nish/net/http1-server`'s `Http1OutputPool` (`take`,
|
|
13
|
+
* `give`, `made`, a `u8[][]` free list), so the two read alike and can merge,
|
|
14
|
+
* with three things added:
|
|
15
|
+
*
|
|
16
|
+
* - **A ceiling.** At most `ceiling` buffers ever exist. A server sizes it to
|
|
17
|
+
* what preallocating every slot would have cost, so a full server behaves as
|
|
18
|
+
* it did before and a `take` can never fail for want of memory. Reaching it
|
|
19
|
+
* therefore means some buffer was not given back, and `take` panics rather
|
|
20
|
+
* than allocating past it.
|
|
21
|
+
* - **Give-back zeroes what was used.** The borrower says how far into the
|
|
22
|
+
* buffer it wrote, and `give` zeroes `[0, used)` before the buffer goes on
|
|
23
|
+
* the free list, so nothing one connection wrote is readable by the next one
|
|
24
|
+
* to take it. The cost follows the bytes moved, not the buffer's size.
|
|
25
|
+
* - **Misuse panics.** A buffer of the wrong length, a `used` outside the
|
|
26
|
+
* buffer, or a give-back with nothing lent is a borrower's bug, and each
|
|
27
|
+
* panics with the pool's name rather than corrupting the free list quietly.
|
|
28
|
+
*
|
|
29
|
+
* The pool grows to its high-water mark and never shrinks: after warm-up a
|
|
30
|
+
* `take` pops the free list and a `give` pushes onto capacity it already has,
|
|
31
|
+
* so a warmed take/give loop moves the arena by nothing.
|
|
32
|
+
*
|
|
33
|
+
* Private helpers share the importing program's flat symbol namespace
|
|
34
|
+
* (`docs/wp26-stdlib.md` §3e), which is why each one carries the module's name.
|
|
35
|
+
*/
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* A pool of `size`-byte `u8` buffers, at most `ceiling` of them, lent last
|
|
39
|
+
* given first. Owned by a server and shared by its slots; a slot holds a
|
|
40
|
+
* buffer only between the `take` that borrowed it and the `give` that brings
|
|
41
|
+
* it back.
|
|
42
|
+
*/
|
|
43
|
+
export class BufferPool {
|
|
44
|
+
// References, then 32-bit fields: the order the layout packs without padding.
|
|
45
|
+
/** The buffers given back and not yet taken again; the last one is lent next. */
|
|
46
|
+
free: u8[][]
|
|
47
|
+
/** Names the pool in every panic, so a leak or a stray buffer says whose it is. */
|
|
48
|
+
name: string
|
|
49
|
+
/** The length of every buffer the pool makes and takes back. */
|
|
50
|
+
size: i32 = 0
|
|
51
|
+
/** The most buffers the pool will ever make. */
|
|
52
|
+
ceiling: i32 = 0
|
|
53
|
+
/** How many buffers the pool has made: its high-water mark, since it never frees one. */
|
|
54
|
+
made: i32 = 0
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* An empty pool: it makes nothing until the first `take`. `name` is what
|
|
58
|
+
* its panics print (the owner's type and field reads best,
|
|
59
|
+
* `"Http2TlsServer.output"`). Panics, naming the pool, unless `size` is
|
|
60
|
+
* above 0 and `ceiling` at least 1: a pool of neither makes a buffer
|
|
61
|
+
* nobody can use or none at all.
|
|
62
|
+
*/
|
|
63
|
+
constructor(name: string, size: i32, ceiling: i32) {
|
|
64
|
+
if (size <= 0) {
|
|
65
|
+
panic(`BufferPool ${name}: a buffer size of ${size} bytes is not above 0`)
|
|
66
|
+
}
|
|
67
|
+
if (ceiling < 1) {
|
|
68
|
+
panic(`BufferPool ${name}: a ceiling of ${ceiling} buffers is below 1`)
|
|
69
|
+
}
|
|
70
|
+
this.name = name
|
|
71
|
+
this.size = size
|
|
72
|
+
this.ceiling = ceiling
|
|
73
|
+
this.free = []
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* A buffer of `size` bytes: the one given back last, or a new one, all
|
|
78
|
+
* zeros, while fewer than `ceiling` exist. Every byte a previous borrower
|
|
79
|
+
* reported as used reads 0; bytes past that extent are as it left them,
|
|
80
|
+
* which is nothing when the borrower kept its promise.
|
|
81
|
+
*
|
|
82
|
+
* Panics when all `ceiling` buffers are lent: the ceiling is what every
|
|
83
|
+
* slot holding a buffer at once would need, so one more means a buffer was
|
|
84
|
+
* never given back.
|
|
85
|
+
*/
|
|
86
|
+
take(): u8[] {
|
|
87
|
+
if (this.free.length > 0) {
|
|
88
|
+
const buf: u8[] = this.free[this.free.length - 1]
|
|
89
|
+
this.free.pop()
|
|
90
|
+
return buf
|
|
91
|
+
}
|
|
92
|
+
if (this.made >= this.ceiling) {
|
|
93
|
+
panic(`BufferPool ${this.name}: all ${this.ceiling} buffers are lent, so one was never given back`)
|
|
94
|
+
}
|
|
95
|
+
this.made = this.made + 1
|
|
96
|
+
return new Array<u8>(this.size)
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Takes back a buffer `take` lent, after zeroing `buf[0 .. used)` with a
|
|
101
|
+
* plain fill. `used` is how far the borrower wrote: the zeroing promises
|
|
102
|
+
* nothing about bytes past it. For bytes that were never secret; a buffer
|
|
103
|
+
* that held plaintext or keys under TLS goes back through `giveSecret`.
|
|
104
|
+
*
|
|
105
|
+
* Panics when `buf` is not `size` bytes, when `used` is outside
|
|
106
|
+
* `0 .. size`, or when nothing is lent.
|
|
107
|
+
*/
|
|
108
|
+
give(buf: u8[], used: i32): void {
|
|
109
|
+
bufferPoolCheckGive(this, buf, used)
|
|
110
|
+
buf.fill(0, 0, used)
|
|
111
|
+
this.free.push(buf)
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* `give` for a buffer that held secret bytes: the zeroing is `secureZero`,
|
|
116
|
+
* whose stores no optimisation removes, where `give`'s fill is an ordinary
|
|
117
|
+
* store `-O2` may drop once nothing reads the buffer again. `secureZero`
|
|
118
|
+
* clears a whole array, so this zeroes all `size` bytes whenever `used` is
|
|
119
|
+
* above 0, and costs nothing for a buffer that was never written.
|
|
120
|
+
*
|
|
121
|
+
* Panics as `give` does.
|
|
122
|
+
*/
|
|
123
|
+
giveSecret(buf: u8[], used: i32): void {
|
|
124
|
+
bufferPoolCheckGive(this, buf, used)
|
|
125
|
+
if (used > 0) {
|
|
126
|
+
secureZero(buf)
|
|
127
|
+
}
|
|
128
|
+
this.free.push(buf)
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/** How many buffers are lent now: made, less those waiting on the free list. */
|
|
132
|
+
lent(): i32 {
|
|
133
|
+
return this.made - toI32(this.free.length)
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/** Panics unless `buf` and `used` are a give-back `pool` can take: the borrower's mistake, named. */
|
|
138
|
+
const bufferPoolCheckGive = (pool: BufferPool, buf: u8[], used: i32): void => {
|
|
139
|
+
const length: i32 = toI32(buf.length)
|
|
140
|
+
if (length !== pool.size) {
|
|
141
|
+
panic(
|
|
142
|
+
`BufferPool ${pool.name}: a buffer of ${length} bytes was given back to a pool of ${pool.size}-byte buffers`
|
|
143
|
+
)
|
|
144
|
+
}
|
|
145
|
+
if (used < 0 || used > pool.size) {
|
|
146
|
+
panic(`BufferPool ${pool.name}: a used extent of ${used} bytes is outside 0 to ${pool.size}`)
|
|
147
|
+
}
|
|
148
|
+
if (pool.lent() === 0) {
|
|
149
|
+
panic(`BufferPool ${pool.name}: a buffer was given back with none lent`)
|
|
150
|
+
}
|
|
151
|
+
}
|