main ece7682

binding.go RawHistoryFolder

1package daemonmux
2
3import (
4	"errors"
5
6	"github.com/bnema/vev/internal/ports"
7)
8
9// ErrInvalidBinding reports an invalid daemon authority. An authority must
10// contain a valid identity, a non-zero incarnation, and a non-empty closed set
11// of distinct, valid provisioned admissions.
12var ErrInvalidBinding = errors.New("daemonmux: invalid server bindings")
13
14// ServerPolicyAdmission is one provisioned carriage shape the daemon accepts:
15// the exact connection policy for that shape and the locality it serves. A
16// daemon serves its own local carriage and each provisioned remote transport, so
17// one binding legitimately carries several entries; the origin makes the
18// accepted locality explicit rather than inferring it from the peer's Open.
19//
20// The origin is per policy, not globally unique: two remote transport policies
21// (for example quic and stdio) share the one remote locality, so admission
22// resolves origin from the accepted policy entry rather than a global origin
23// table.
24type ServerPolicyAdmission struct {
25	Policy ports.BrokerPolicy
26	Origin ports.SessionConnectionOrigin
27}
28
29// Validate enforces the closed provisioned-entry contract: a valid exact policy
30// and a known locality. A missing or invalid origin is refused, so an accepted
31// entry can never inherit an implicit locality.
32func (e ServerPolicyAdmission) Validate() error {
33	if err := e.Policy.Validate(); err != nil {
34		return err
35	}
36	return e.Origin.Validate()
37}
38
39// ServerBinding is an immutable daemon authority. The entry slice is cloned at
40// construction and is never exposed, making the admitted set safe to share
41// between concurrent handshakes.
42type ServerBinding struct {
43	identity    ports.BrokerDaemonIdentity
44	incarnation ports.BrokerDaemonIncarnation
45	entries     []ServerPolicyAdmission
46}
47
48// NewServerBindings constructs a closed admission authority from provisioned
49// entries. An empty set, a duplicate policy, an invalid policy, and an unknown
50// origin are rejected. Entries are cloned, so a later change to the caller's
51// slice cannot weaken what the handshake already enforced.
52func NewServerBindings(identity ports.BrokerDaemonIdentity, incarnation ports.BrokerDaemonIncarnation, entries []ServerPolicyAdmission) (ServerBinding, error) {
53	binding := ServerBinding{identity: identity, incarnation: incarnation, entries: append([]ServerPolicyAdmission(nil), entries...)}
54	if err := binding.Validate(); err != nil {
55		return ServerBinding{}, err
56	}
57	return binding, nil
58}
59
60// NewServerBinding is retained as a source-compatible shorthand for fixtures
61// that provision exactly one local policy. It is never used by production
62// composition, which builds the daemon's whole closed set with NewServerBindings.
63func NewServerBinding(identity ports.BrokerDaemonIdentity, incarnation ports.BrokerDaemonIncarnation, policy ports.BrokerPolicy) (ServerBinding, error) {
64	return NewServerBindings(identity, incarnation, []ServerPolicyAdmission{{Policy: policy, Origin: ports.SessionOriginLocal}})
65}
66
67func (b ServerBinding) Identity() ports.BrokerDaemonIdentity       { return b.identity }
68func (b ServerBinding) Incarnation() ports.BrokerDaemonIncarnation { return b.incarnation }
69
70func (b ServerBinding) Validate() error {
71	if b.identity.Validate() != nil || b.incarnation.Validate() != nil || len(b.entries) == 0 {
72		return ErrInvalidBinding
73	}
74	for i, entry := range b.entries {
75		if entry.Validate() != nil {
76			return ErrInvalidBinding
77		}
78		for j := 0; j < i; j++ {
79			// Duplicate policy - and therefore a duplicated entry - is refused:
80			// one policy is one carriage shape, so a second entry naming the
81			// same policy would make the accepted locality and policy ambiguous.
82			if entry.Policy.Compatible(b.entries[j].Policy) {
83				return ErrInvalidBinding
84			}
85		}
86	}
87	return nil
88}
89
90// Accepted returns the exact provisioned entry matching policy, carrying that
91// entry's policy and origin. No merging, inheritance, echo, or fallback is
92// performed: a request differing in one field is refused.
93func (b ServerBinding) Accepted(policy ports.BrokerPolicy) (ServerPolicyAdmission, bool) {
94	for _, provisioned := range b.entries {
95		if provisioned.Policy.Compatible(policy) {
96			return provisioned, true
97		}
98	}
99	return ServerPolicyAdmission{}, false
100}

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