-
Notifications
You must be signed in to change notification settings - Fork 7
/
interfaces.go
108 lines (85 loc) · 3.36 KB
/
interfaces.go
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
// Package ont defines interfaces for the engine: Ngin and Onion coding.Codec subtypes, and some helpers that use the abstraction.
package ont
import (
"github.com/indra-labs/indra/pkg/crypto"
"github.com/indra-labs/indra/pkg/engine/responses"
"github.com/indra-labs/indra/pkg/engine/sess"
"github.com/indra-labs/indra/pkg/engine/sessions"
"github.com/indra-labs/indra/pkg/hidden"
log2 "github.com/indra-labs/indra/pkg/proc/log"
"github.com/indra-labs/indra/pkg/util/splice"
)
var (
log = log2.GetLogger()
fails = log.E.Chk
)
// Codec is a unit of data that can be read and written from a binary form. All
// Onion are Codec but not all Codec are Onion. Codec is also used for the
// Dispatcher's message headers.
type Codec interface {
// Magic is a 4 byte string identifying the type of the following message bytes.
Magic() string
// Encode uses the Codec's contents to encode into the splice.Splice next bytes.
Encode(s *splice.Splice) (e error)
// Decode reads in the data in the next bytes of the splice.Splice to populate this Codec.
Decode(s *splice.Splice) (e error)
// Len returns the number of bytes required to encode this Codec message (including Magic).
Len() int
// Unwrap gives access to any further layers embedded inside this (specifically, the Onion inside).
Unwrap() interface{}
}
// Ngin is the generic interface for onion encoders to access the engine without
// tying the dependencies together.
type Ngin interface {
// HandleMessage sets an engine to process an Onion.
HandleMessage(s *splice.Splice, pr Onion)
// GetLoad returns the current engine load level.
GetLoad() byte
// SetLoad sets the current engine load level.
SetLoad(byte)
// Mgr returns the pointer to the Session Manager of this Ngin.
Mgr() *sess.Manager
// Pending returns the pending responses handler.
Pending() *responses.Pending
// GetHidden returns the hidden services manager.
GetHidden() *hidden.Hidden
// WaitForShutdown returns a signal channel that returns after the shutdown
// breaker is triggered.
WaitForShutdown() <-chan struct{}
// Keyset returns the scalar addition fast private key generator in use by the Ngin.
Keyset() *crypto.KeySet
}
// Onion are messages that can be layered over each other and have
// a set of processing instructions for the data in them, and, if relevant,
// how to account for them in sessions.
type Onion interface {
Codec
// Wrap places another onion inside this onion's inner layer.
Wrap(inner Onion)
// Handle is the relay switching logic used by the Ngin on the Onion.
Handle(s *splice.Splice, p Onion, ni Ngin) (e error)
// Account sets up the bandwidth accounting for sending out an Onion.
Account(res *sess.Data, sm *sess.Manager, s *sessions.Data,
last bool) (skip bool, sd *sessions.Data)
}
// Encode is the generic encoder for an onion, all onions can be encoded with it.
func Encode(d Codec) (s *splice.Splice) {
s = splice.New(d.Len())
fails(d.Encode(s))
return
}
// Assemble takes a slice and inserts the tail into the onion of the head until
// there is no tail left.
func Assemble(o []Onion) (on Onion) {
// First item is the outer crypt.
on = o[0]
// Iterate through the remaining layers.
for _, oc := range o[1:] {
on.Wrap(oc)
// Next step we are inserting inside the one we just inserted.
on = oc
}
// At the end, the first element contains references to every element
// inside it.
return o[0]
}