forked from Velocidex/velociraptor
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlimits.go
79 lines (69 loc) · 2.69 KB
/
limits.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
package flows
import (
errors "github.com/pkg/errors"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
config_proto "www.velocidex.com/golang/velociraptor/config/proto"
constants "www.velocidex.com/golang/velociraptor/constants"
crypto_proto "www.velocidex.com/golang/velociraptor/crypto/proto"
"www.velocidex.com/golang/velociraptor/datastore"
flows_proto "www.velocidex.com/golang/velociraptor/flows/proto"
"www.velocidex.com/golang/velociraptor/services"
)
var (
rowCounter = promauto.NewCounter(prometheus.CounterOpts{
Name: "received_rows",
Help: "Total number of rows received from clients.",
})
)
// Sometimes it is hard to predict exactly how much data a client is
// going to send. Velociraptor implements a number of limits to
// protect the server from being overloaded. This function checks
// that the collection is still within the allowed quota, otherwise
// the collection is terminated and the client is notified that it is
// cancelled.
func checkContextResourceLimits(config_obj *config_proto.Config,
collection_context *flows_proto.ArtifactCollectorContext) (err error) {
// There are no resource limits on event flows.
if collection_context.SessionId == constants.MONITORING_WELL_KNOWN_FLOW {
return nil
}
if collection_context.Request == nil {
return errors.New("Invalid context.")
}
// We exceeded our total number of rows.
if collection_context.Request.MaxRows > 0 &&
collection_context.TotalCollectedRows > collection_context.Request.MaxRows {
collection_context.State = flows_proto.ArtifactCollectorContext_ERROR
collection_context.Status = "Row count exceeded limit"
err = cancelCollection(config_obj, collection_context.ClientId,
collection_context.SessionId)
}
// Check for total uploaded bytes.
if collection_context.Request.MaxUploadBytes > 0 &&
collection_context.TotalUploadedBytes > collection_context.Request.MaxUploadBytes {
collection_context.State = flows_proto.ArtifactCollectorContext_ERROR
collection_context.Status = "Collection exceeded upload limits"
err = cancelCollection(config_obj, collection_context.ClientId,
collection_context.SessionId)
}
return err
}
func cancelCollection(config_obj *config_proto.Config, client_id, flow_id string) error {
// Cancel the collection to stop the client from generating
// more data.
db, err := datastore.GetDB(config_obj)
if err != nil {
return err
}
err = db.QueueMessageForClient(config_obj, client_id,
&crypto_proto.VeloMessage{
Cancel: &crypto_proto.Cancel{},
SessionId: flow_id,
})
if err != nil {
return err
}
// Notify the client immediately.
return services.GetNotifier().NotifyListener(config_obj, client_id)
}