quico 0.4.0 → 0.8.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/README.md +1987 -160
- package/index.d.ts +1034 -77
- package/index.js +59 -36
- package/package.json +8 -5
- package/src/agent.js +306 -36
- package/src/client.js +447 -120
- package/src/client_profile.js +266 -0
- package/src/connect_udp.js +578 -0
- package/src/connect_udp_client.js +779 -0
- package/src/crypto.js +240 -140
- package/src/h1.js +953 -0
- package/src/h1_client.js +731 -0
- package/src/h1_server.js +666 -0
- package/src/h2.js +1325 -0
- package/src/h2_client.js +675 -0
- package/src/h2_fingerprint.js +403 -0
- package/src/h2_frames.js +582 -0
- package/src/h2_server.js +911 -0
- package/src/h3.js +1986 -520
- package/src/h3_client.js +484 -46
- package/src/h3_server.js +1448 -98
- package/src/hpack.js +455 -0
- package/src/hpack_primitives.js +559 -0
- package/src/http_common.js +908 -0
- package/src/ja4h.js +256 -0
- package/src/qpack.js +555 -0
- package/src/quic_connection.js +6702 -665
- package/src/quic_server.js +858 -82
- package/src/quic_socket.js +134 -9
- package/src/quic_version.js +143 -0
- package/src/server.js +1097 -125
- package/src/server_stats.js +93 -0
- package/src/streams.js +542 -43
- package/src/tcp_listener.js +568 -0
- package/src/tls_bridge.js +478 -73
- package/src/tls_options.js +108 -0
- package/src/transport.js +455 -46
- package/src/utils.js +94 -12
- package/src/webtransport.js +784 -417
- package/src/ws.js +744 -0
- package/src/ws_client.js +621 -0
- package/src/ws_server.js +815 -0
- package/src/ws_stream.js +250 -0
- package/src/wt_stream.js +1075 -0
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
// ============================================================
|
|
2
|
+
// The server's counters — server.getStats()
|
|
3
|
+
// ============================================================
|
|
4
|
+
//
|
|
5
|
+
// What an operator watches a server by: how many connections came, over what,
|
|
6
|
+
// how many handshakes failed, how connections ended and with what code, what
|
|
7
|
+
// 0-RTT did, how often the anti-amplification limit held the server back,
|
|
8
|
+
// how many internal errors were caught. Counts only: no addresses, no names,
|
|
9
|
+
// no headers, no payloads — nothing here identifies a client.
|
|
10
|
+
//
|
|
11
|
+
// One object per server, made by createServer and handed to each layer
|
|
12
|
+
// (quic_server, quic_connection, h3_server, tcp_listener, h2_server / h2.js,
|
|
13
|
+
// h1_server) in its options as `stats`; each counts where the thing happens,
|
|
14
|
+
// with a plain increment. A layer used on its own (createQuicServer, an
|
|
15
|
+
// H2Connection) has none and counts nothing.
|
|
16
|
+
//
|
|
17
|
+
// Codes are the protocol's, as hex strings ('0x0', '0x12f'): a map from code
|
|
18
|
+
// to count, only for codes seen.
|
|
19
|
+
|
|
20
|
+
function ServerStats() {
|
|
21
|
+
this.since = Date.now();
|
|
22
|
+
// Connections taken: QUIC, a first Initial that began a handshake; TCP, a
|
|
23
|
+
// socket accepted (before TLS).
|
|
24
|
+
this.connections = { quic: 0, tcp: 0 };
|
|
25
|
+
// TLS handshakes, as they ended: completed (the client's Finished
|
|
26
|
+
// verified) or failed (an alert either way, a timeout, the connection
|
|
27
|
+
// closed first). resumed: completed with a session ticket.
|
|
28
|
+
this.handshakes = { quic: { completed: 0, failed: 0 }, tcp: { completed: 0, failed: 0 }, resumed: 0 };
|
|
29
|
+
// Connections by the protocol they went on to speak (the ALPN agreed; over
|
|
30
|
+
// cleartext TCP, the preface read) — other: an ALPN name of the
|
|
31
|
+
// application's.
|
|
32
|
+
this.protocols = { h3: 0, h2: 0, 'http/1.1': 0, other: 0 };
|
|
33
|
+
// 0-RTT offered by the client: taken, or refused (the ticket's, the replay
|
|
34
|
+
// check, a HelloRetryRequest); tooEarly, requests answered 425 (RFC 8470).
|
|
35
|
+
this.earlyData = { accepted: 0, rejected: 0, tooEarly: 0 };
|
|
36
|
+
// How connections ended, by code:
|
|
37
|
+
// quic CONNECTION_CLOSE of the transport (RFC 9000 §20.1; 0x100 + a TLS
|
|
38
|
+
// alert, RFC 9001 §4.8) — sent by us, received from the client;
|
|
39
|
+
// silent: ended with none either way (the idle timeout, a
|
|
40
|
+
// stateless reset, a handshake abandoned)
|
|
41
|
+
// h3 CONNECTION_CLOSE of the application (RFC 9114 §8.1)
|
|
42
|
+
// h2 GOAWAY (RFC 9113 §7)
|
|
43
|
+
// http1 requests refused before the application saw them, by status
|
|
44
|
+
// (400 a malformed request, 431 headers too large, ...)
|
|
45
|
+
this.closes = {
|
|
46
|
+
quic: { sent: {}, received: {}, silent: 0 },
|
|
47
|
+
h3: { sent: {}, received: {} },
|
|
48
|
+
h2: { sent: {}, received: {} },
|
|
49
|
+
http1: { sent: {} }
|
|
50
|
+
};
|
|
51
|
+
// Streams reset, by code: RESET_STREAM (HTTP/3) and RST_STREAM (HTTP/2),
|
|
52
|
+
// sent and received.
|
|
53
|
+
this.streamResets = { h3: { sent: {}, received: {} }, h2: { sent: {}, received: {} } };
|
|
54
|
+
// Datagrams the server held because the client's address was not yet
|
|
55
|
+
// validated and it had sent three times what it received (RFC 9000 §8.1).
|
|
56
|
+
this.amplificationBlocked = 0;
|
|
57
|
+
// Exceptions caught inside the QUIC and HTTP/3 layers: a bug of ours,
|
|
58
|
+
// never the client's (the packet dropped, or H3_INTERNAL_ERROR).
|
|
59
|
+
this.internalErrors = 0;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** One more of a protocol error `code` in `map`, by its hex. */
|
|
63
|
+
ServerStats.prototype.code = function (map, code) {
|
|
64
|
+
// Up to 62 bits (a QUIC varint — WebTransport's codes are past 2^32): by
|
|
65
|
+
// its value, not cut to 32 bits.
|
|
66
|
+
var k = '0x' + (typeof code === 'bigint' ? code : Number(code)).toString(16);
|
|
67
|
+
map[k] = (map[k] || 0) + 1;
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
/** One more of an HTTP status in `map`. */
|
|
71
|
+
ServerStats.prototype.status = function (map, status) {
|
|
72
|
+
map[status] = (map[status] || 0) + 1;
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
/** A TLS handshake ended ('quic' or 'tcp'): completed or not, resumed. */
|
|
76
|
+
ServerStats.prototype.handshake = function (transport, ok, resumed) {
|
|
77
|
+
this.handshakes[transport][ok ? 'completed' : 'failed']++;
|
|
78
|
+
if (ok && resumed) this.handshakes.resumed++;
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
/** A connection handed to the protocol it speaks. */
|
|
82
|
+
ServerStats.prototype.protocol = function (name) {
|
|
83
|
+
this.protocols[name === 'h3' || name === 'h2' || name === 'http/1.1' ? name : 'other']++;
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
/** A copy, for the caller to keep or change. */
|
|
87
|
+
ServerStats.prototype.snapshot = function () {
|
|
88
|
+
var copy = JSON.parse(JSON.stringify(this));
|
|
89
|
+
copy.uptime = Date.now() - this.since;
|
|
90
|
+
return copy;
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
export { ServerStats };
|