forked from scionproto/scion
-
Notifications
You must be signed in to change notification settings - Fork 0
/
ctrl.go
158 lines (136 loc) · 4.18 KB
/
ctrl.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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
// Copyright 2017 ETH Zurich
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Package ctrl handles SCION control-plane payloads, which are encoded as capnp proto messages.
// Each ctrl payload has a 4B length field prefixed to the start of the capnp message.
package ctrl
import (
"fmt"
"strings"
//log "github.com/inconshreveable/log15"
"github.com/scionproto/scion/go/lib/common"
"github.com/scionproto/scion/go/lib/ctrl/cert_mgmt"
"github.com/scionproto/scion/go/lib/ctrl/path_mgmt"
"github.com/scionproto/scion/go/proto"
)
var _ proto.Cerealizable = (*Pld)(nil)
type Pld struct {
union
*Data
}
// NewPld creates a new control payload, containing the supplied Cerealizable instance.
func NewPld(u proto.Cerealizable, d *Data) (*Pld, error) {
p := &Pld{Data: d}
return p, p.union.set(u)
}
// NewPathMgmtPld creates a new control payload, containing a new path_mgmt payload,
// which in turn contains the supplied Cerealizable instance.
func NewPathMgmtPld(u proto.Cerealizable, pathD *path_mgmt.Data, ctrlD *Data) (*Pld, error) {
ppld, err := path_mgmt.NewPld(u, pathD)
if err != nil {
return nil, err
}
return NewPld(ppld, ctrlD)
}
// NewCertMgmtPld creates a new control payload, containing a new cert_mgmt payload,
// which in turn contains the supplied Cerealizable instance.
func NewCertMgmtPld(u proto.Cerealizable, certD *cert_mgmt.Data, ctrlD *Data) (*Pld, error) {
cpld, err := cert_mgmt.NewPld(u, certD)
if err != nil {
return nil, err
}
return NewPld(cpld, ctrlD)
}
func NewPldFromRaw(b common.RawBytes) (*Pld, error) {
p := &Pld{Data: &Data{}}
return p, proto.ParseFromRaw(p, proto.CtrlPld_TypeID, b)
}
func (p *Pld) Union() (proto.Cerealizable, error) {
return p.union.get()
}
// GetCertMgmt returns the CertMgmt payload and the CtrlPld's non-union Data.
// If the union type is not CertMgmt, an error is returned.
func (p *Pld) GetCertMgmt() (*cert_mgmt.Pld, *Data, error) {
u, err := p.Union()
if err != nil {
return nil, nil, err
}
certP, ok := u.(*cert_mgmt.Pld)
if !ok {
return nil, nil, common.NewBasicError("Non-matching ctrl pld contents", nil,
"expected", "*cert_mgmt.Pld", "actual", common.TypeOf(u))
}
return certP, p.Data, nil
}
// GetCertMgmt returns the PathMgmt payload and the CtrlPld's non-union Data.
// If the union type is not PathMgmt, an error is returned.
func (p *Pld) GetPathMgmt() (*path_mgmt.Pld, *Data, error) {
u, err := p.Union()
if err != nil {
return nil, nil, err
}
pathP, ok := u.(*path_mgmt.Pld)
if !ok {
return nil, nil, common.NewBasicError("Non-matching ctrl pld contents", nil,
"expected", "*path_mgmt.Pld", "actual", common.TypeOf(u))
}
return pathP, p.Data, nil
}
func (p *Pld) Len() int {
return -1
}
func (p *Pld) Copy() (common.Payload, error) {
raw, err := proto.PackRoot(p)
if err != nil {
return nil, err
}
return NewPldFromRaw(raw)
}
func (p *Pld) Write(b common.RawBytes) (int, error) {
return proto.WriteRoot(p, b)
}
func (p *Pld) SignedPld(signer Signer) (*SignedPld, error) {
return signer.Sign(p)
}
func (p *Pld) WritePld(b common.RawBytes) (int, error) {
sp, err := newSignedPld(p, nil, nil)
if err != nil {
return 0, err
}
return sp.WritePld(b)
}
func (p *Pld) PackPld() (common.RawBytes, error) {
sp, err := newSignedPld(p, nil, nil)
if err != nil {
return nil, err
}
return sp.PackPld()
}
func (p *Pld) ProtoId() proto.ProtoIdType {
return proto.CtrlPld_TypeID
}
func (p *Pld) String() string {
desc := []string{"Ctrl: Union:"}
u, err := p.Union()
if err != nil {
desc = append(desc, err.Error())
} else {
desc = append(desc, fmt.Sprintf("%+v", u))
}
return strings.Join(desc, " ")
}
// Data holds all non-union entries from CtrlPld
type Data struct {
ReqId uint64
TraceId common.RawBytes
}