-
Notifications
You must be signed in to change notification settings - Fork 107
/
handler.go
112 lines (95 loc) · 2.91 KB
/
handler.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
package keymanager
import (
"context"
"errors"
"sync"
"github.com/oasisprotocol/oasis-core/go/common/cbor"
"github.com/oasisprotocol/oasis-core/go/keymanager/api"
"github.com/oasisprotocol/oasis-core/go/keymanager/client"
"github.com/oasisprotocol/oasis-core/go/runtime/host/protocol"
"github.com/oasisprotocol/oasis-core/go/runtime/localstorage"
workerCommon "github.com/oasisprotocol/oasis-core/go/worker/common"
)
var (
errEndpointNotSupported = errors.New("worker/keymanager: RPC endpoint not supported")
errMethodNotSupported = errors.New("worker/keymanager: method not supported")
_ protocol.Handler = (*hostHandler)(nil)
)
type hostHandler struct {
sync.Mutex
w *Worker
remoteClient *client.Client
localStorage localstorage.LocalStorage
}
func (h *hostHandler) initRemoteClient(commonWorker *workerCommon.Worker) {
remoteClient, err := client.New(h.w.ctx, h.w.runtime, commonWorker.Consensus, commonWorker.Identity)
if err != nil {
h.w.logger.Error("failed to create remote client",
"err", err,
)
return
}
select {
case <-h.w.ctx.Done():
h.w.logger.Error("failed to wait for key manager",
"err", h.w.ctx.Err(),
)
case <-remoteClient.Initialized():
h.Lock()
defer h.Unlock()
h.remoteClient = remoteClient
}
}
func (h *hostHandler) getRemoteClient() (*client.Client, error) {
h.Lock()
defer h.Unlock()
if h.remoteClient != nil {
return h.remoteClient, nil
}
return nil, errEndpointNotSupported
}
func (h *hostHandler) Handle(ctx context.Context, body *protocol.Body) (*protocol.Body, error) {
// Local storage.
if body.HostLocalStorageGetRequest != nil {
value, err := h.localStorage.Get(body.HostLocalStorageGetRequest.Key)
if err != nil {
return nil, err
}
return &protocol.Body{HostLocalStorageGetResponse: &protocol.HostLocalStorageGetResponse{Value: value}}, nil
}
if body.HostLocalStorageSetRequest != nil {
if err := h.localStorage.Set(body.HostLocalStorageSetRequest.Key, body.HostLocalStorageSetRequest.Value); err != nil {
return nil, err
}
return &protocol.Body{HostLocalStorageSetResponse: &protocol.Empty{}}, nil
}
// RPC.
if body.HostRPCCallRequest != nil {
switch body.HostRPCCallRequest.Endpoint {
case api.EnclaveRPCEndpoint:
remoteClient, err := h.getRemoteClient()
if err != nil {
return nil, err
}
// Call into the remote key manager.
res, err := remoteClient.CallRemote(ctx, body.HostRPCCallRequest.Request)
if err != nil {
return nil, err
}
return &protocol.Body{HostRPCCallResponse: &protocol.HostRPCCallResponse{
Response: cbor.FixSliceForSerde(res),
}}, nil
default:
return nil, errEndpointNotSupported
}
}
return nil, errMethodNotSupported
}
func newHostHandler(w *Worker, commonWorker *workerCommon.Worker, localStorage localstorage.LocalStorage) protocol.Handler {
h := &hostHandler{
w: w,
localStorage: localStorage,
}
go h.initRemoteClient(commonWorker)
return h
}