forked from scionproto/scion
-
Notifications
You must be signed in to change notification settings - Fork 0
/
handler.go
96 lines (85 loc) · 3.31 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
// Copyright 2019 Anapaya Systems
//
// 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 revocation implements a revocation handler for the beacon server.
package revocation
import (
"context"
"time"
"github.com/scionproto/scion/go/beacon_srv/internal/metrics"
"github.com/scionproto/scion/go/lib/common"
"github.com/scionproto/scion/go/lib/ctrl/path_mgmt"
"github.com/scionproto/scion/go/lib/infra"
"github.com/scionproto/scion/go/lib/infra/messenger"
"github.com/scionproto/scion/go/lib/log"
"github.com/scionproto/scion/go/proto"
)
// Store is the store in which to save the revocations.
type Store interface {
InsertRevocations(ctx context.Context, verifiedRevs ...*path_mgmt.SignedRevInfo) error
}
type handler struct {
verifier infra.Verifier
revStore Store
timeout time.Duration
}
// NewHandler returns an infra.Handler for revocation.
func NewHandler(revStore Store, verifier infra.Verifier, timeout time.Duration) infra.Handler {
return &handler{
verifier: verifier,
revStore: revStore,
timeout: timeout,
}
}
// FIXME(karampok): add support for revocation received over SCMP
// https://github.com/scionproto/scion/issues/3166.
// Handle handles receiving revocations.
func (h *handler) Handle(request *infra.Request) *infra.HandlerResult {
logger := log.FromCtx(request.Context())
labels := metrics.RevocationLabels{Method: metrics.RevFromCtrl, Result: metrics.ErrProcess}
revocation, ok := request.Message.(*path_mgmt.SignedRevInfo)
if !ok {
logger.Error("[RevHandler] wrong message type, expected path_mgmt.SignedRevInfo",
"msg", request.Message, "type", common.TypeOf(request.Message))
metrics.Revocation.Received(labels).Inc()
return infra.MetricsErrInternal
}
rw, ok := infra.ResponseWriterFromContext(request.Context())
if !ok {
logger.Error("[RevHandler] Unable to service request, no ResponseWriter found",
"msg", request.Message)
metrics.Revocation.Received(labels).Inc()
return infra.MetricsErrInternal
}
subCtx, cancelF := context.WithTimeout(request.Context(), h.timeout)
defer cancelF()
sendAck := messenger.SendAckHelper(subCtx, rw)
revInfo, err := revocation.VerifiedRevInfo(subCtx, h.verifier)
if err != nil {
logger.Warn("[RevHandler] Parsing/Verifying failed",
"signer", revocation.Sign.Src, "err", err)
sendAck(proto.Ack_ErrCode_reject, messenger.AckRejectFailedToVerify)
metrics.Revocation.Received(labels).Inc()
return infra.MetricsErrInvalid
}
if err = h.revStore.InsertRevocations(subCtx, revocation); err != nil {
logger.Error("[RevHandler] Failed to store", "rev", revInfo, "err", err)
sendAck(proto.Ack_ErrCode_retry, messenger.AckRetryDBError)
metrics.Revocation.Received(labels).Inc()
return ErrBeaconStore(err)
}
sendAck(proto.Ack_ErrCode_ok, "")
labels.Result = metrics.Success
metrics.Revocation.Received(labels).Inc()
return infra.MetricsResultOk
}