v0.9.0 e5e4ded

limits.go RawHistoryFolder

1package brokerwire
2
3// Stateless bound refusals.
4//
5// The broker preamble negotiates one immutable pair of ceilings per
6// connection: MaxReceiveEnvelopeBytes bounds every envelope this side
7// accepts, and StreamChunkLimit bounds one opaque ClientStreamData or
8// ServerStreamData frame. Envelope ceilings are fixed: ordinary envelopes
9// never exceed the advertised floor, and the preamble advertisement itself
10// rides inside BrokerPreambleLimit.
11//
12// The broker has no Output/image/picker bulk category: every application
13// envelope is control-class and shares one ceiling. Stream chunk payloads
14// are bounded separately so hostile lengths never allocate.
15
16import (
17	"github.com/bnema/vev/internal/protocol/wire"
18)
19
20const (
21	// BrokerRoleClient is the broker preamble client role. It is disjoint
22	// from the session preamble roles 1/2.
23	BrokerRoleClient uint32 = 3
24	// BrokerRoleServer is the broker preamble server role.
25	BrokerRoleServer uint32 = 4
26
27	// BrokerPreambleLimit bounds the serialized broker preamble envelope.
28	BrokerPreambleLimit = 4 << 10
29
30	// MinBrokerEnvelopeBytes is the advertised-envelope floor: a broker
31	// peer must accept at least 1 MiB per envelope.
32	MinBrokerEnvelopeBytes uint64 = 1 << 20
33	// MaxBrokerEnvelopeBytes is the advertised-envelope ceiling: a broker
34	// peer must never advertise above 16 MiB (wire.AbsoluteEnvelopeLimit).
35	MaxBrokerEnvelopeBytes uint64 = wire.AbsoluteEnvelopeLimit
36
37	// MinStreamChunkBytes is the smallest legal stream chunk ceiling.
38	MinStreamChunkBytes uint64 = 1
39	// MaxStreamChunkBytes is the largest legal stream chunk ceiling:
40	// 64 KiB per opaque stream frame.
41	MaxStreamChunkBytes uint64 = 64 << 10
42
43	// StreamWindowBytes is the stream-data credit each side of one logical
44	// stream grants its peer per direction. A sender spends StreamChunkCredit
45	// per data frame and waits when it has too little, so the receiver never
46	// queues more than this per stream; StreamWindowUpdate returns the credit
47	// of consumed frames.
48	StreamWindowBytes uint64 = 4 << 20
49	// StreamChunkCreditOverhead is the fixed credit one data frame costs on top
50	// of its payload, so a burst of tiny frames is bounded in count as well.
51	StreamChunkCreditOverhead uint64 = 64
52)
53
54// StreamChunkCredit is the flow-control cost of one stream data frame of n
55// payload bytes.
56func StreamChunkCredit(n int) uint64 { return uint64(n) + StreamChunkCreditOverhead }
57
58// Ceilings are the immutable per-connection ceilings negotiated once by the
59// broker preamble. MaxReceiveEnvelopeBytes bounds every envelope this side
60// accepts; StreamChunkLimit bounds one opaque stream data frame in either
61// direction.
62//
63// The preamble helpers and the connection dispatcher share this value: a
64// caller that completed the preamble reads the negotiated limits from
65// BrokerPreambleRequest or BrokerPreambleResponse and passes them to
66// EncodeClient/DecodeClient and EncodeServer/DecodeServer.
67type Ceilings struct {
68	MaxReceiveEnvelopeBytes uint64
69	StreamChunkLimit        uint64
70}
71
72// brokerCeilings is the in-package alias for Ceilings. It exists only so
73// The codec tests keep their short spelling; production code uses Ceilings.
74type brokerCeilings = Ceilings
75
76// defaultBrokerCeilings advertises the local broker receive policy: the
77// full absolute envelope ceiling and the maximum stream chunk.
78func defaultBrokerCeilings() Ceilings {
79	return Ceilings{
80		MaxReceiveEnvelopeBytes: wire.AbsoluteEnvelopeLimit,
81		StreamChunkLimit:        MaxStreamChunkBytes,
82	}
83}
84
85// DefaultCeilings returns the local broker receive policy: the full absolute
86// envelope ceiling and the maximum stream chunk. It is the offer a broker IPC
87// client or server advertises before negotiation.
88func DefaultCeilings() Ceilings { return defaultBrokerCeilings() }
89
90// effectiveBrokerCeilings takes the minima of both sides' advertisements.
91func effectiveBrokerCeilings(local, remote Ceilings) Ceilings {
92	return Ceilings{
93		MaxReceiveEnvelopeBytes: min(local.MaxReceiveEnvelopeBytes, remote.MaxReceiveEnvelopeBytes),
94		StreamChunkLimit:        min(local.StreamChunkLimit, remote.StreamChunkLimit),
95	}
96}
97
98// EffectiveCeilings returns the element-wise minima of the two advertised
99// ceilings: one byte stream carries exactly the limits both peers accepted.
100func EffectiveCeilings(local, remote Ceilings) Ceilings {
101	return effectiveBrokerCeilings(local, remote)
102}
103
104// checkBrokerCeilings refuses a zero, below-floor, or above-ceiling
105// advertisement. Envelope bounds are the 1 MiB..16 MiB advertised window;
106// chunk bounds are 1..64 KiB.
107func checkBrokerCeilings(remote Ceilings) error {
108	if remote.MaxReceiveEnvelopeBytes < MinBrokerEnvelopeBytes ||
109		remote.MaxReceiveEnvelopeBytes > MaxBrokerEnvelopeBytes {
110		return ErrPreambleRejected
111	}
112	if remote.StreamChunkLimit < MinStreamChunkBytes ||
113		remote.StreamChunkLimit > MaxStreamChunkBytes {
114		return ErrPreambleRejected
115	}
116	return nil
117}
118
119// Validate reports whether one advertised ceiling is negotiable: an envelope
120// window inside 1 MiB..16 MiB and a stream chunk inside 1..64 KiB.
121func (c Ceilings) Validate() error { return checkBrokerCeilings(c) }
122
123// checkBrokerEnvelopeCeiling rejects one serialized broker envelope above
124// the negotiated ceiling. All broker envelopes are control-class: the
125// negotiated ceiling always applies in full.
126func checkBrokerEnvelopeCeiling(payload []byte, ceiling uint64) error {
127	if uint64(len(payload)) > ceiling {
128		return wire.ErrScanLength
129	}
130	return nil
131}
132
133// CheckPreambleSize refuses one serialized broker preamble above the 4 KiB
134// bound before scanning or allocation. Callers apply it to an encoded
135// preamble before sending and to a received payload before decode; the
136// session contract applies the identical wire.PreambleLimit.
137func CheckPreambleSize(payload []byte) error {
138	if len(payload) > BrokerPreambleLimit {
139		return ErrPreambleRejected
140	}
141	return nil
142}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 12

Tags 11

↑↓ moveenter openesc close