-
Notifications
You must be signed in to change notification settings - Fork 9
/
frame.ts
64 lines (57 loc) · 2.42 KB
/
frame.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
export enum FrameType {
/** Used to transmit data. May transmit zero length payloads depending on the flags. */
Data = 0x0,
/** Used to updated the senders receive window size. This is used to implement per-session flow control. */
WindowUpdate = 0x1,
/** Used to measure RTT. It can also be used to heart-beat and do keep-alives over TCP. */
Ping = 0x2,
/** Used to close a session. */
GoAway = 0x3,
}
export enum Flag {
/** Signals the start of a new stream. May be sent with a data or window update message. Also sent with a ping to indicate outbound. */
SYN = 0x1,
/** Acknowledges the start of a new stream. May be sent with a data or window update message. Also sent with a ping to indicate response. */
ACK = 0x2,
/** Performs a half-close of a stream. May be sent with a data message or window update. */
FIN = 0x4,
/** Reset a stream immediately. May be sent with a data or window update message. */
RST = 0x8,
}
const flagCodes = Object.values(Flag).filter((x) => typeof x !== 'string') as Flag[]
export const YAMUX_VERSION = 0
export enum GoAwayCode {
NormalTermination = 0x0,
ProtocolError = 0x1,
InternalError = 0x2,
}
export const HEADER_LENGTH = 12
export interface FrameHeader {
/**
* The version field is used for future backward compatibility.
* At the current time, the field is always set to 0, to indicate the initial version.
*/
version?: number
/** The type field is used to switch the frame message type. */
type: FrameType
/** The flags field is used to provide additional information related to the message type. */
flag: number
/**
* The StreamID field is used to identify the logical stream the frame is addressing.
* The client side should use odd ID's, and the server even.
* This prevents any collisions. Additionally, the 0 ID is reserved to represent the session.
*/
streamID: number
/**
* The meaning of the length field depends on the message type:
* * Data - provides the length of bytes following the header
* * Window update - provides a delta update to the window size
* * Ping - Contains an opaque value, echoed back
* * Go Away - Contains an error code
*/
length: number
}
export function stringifyHeader (header: FrameHeader): string {
const flags = flagCodes.filter(f => (header.flag & f) === f).map(f => Flag[f]).join('|')
return `streamID=${header.streamID} type=${FrameType[header.type]} flag=${flags} length=${header.length}`
}