forked from Velocidex/velociraptor
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathflows.go
80 lines (64 loc) · 2.27 KB
/
flows.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
package executor
import (
"context"
"sync"
"www.velocidex.com/golang/velociraptor/actions"
actions_proto "www.velocidex.com/golang/velociraptor/actions/proto"
config_proto "www.velocidex.com/golang/velociraptor/config/proto"
crypto_proto "www.velocidex.com/golang/velociraptor/crypto/proto"
"www.velocidex.com/golang/velociraptor/responder"
)
// New servers issue a FlowRequest message forcing the client to
// process and track the entire collection at once.
func (self *ClientExecutor) ProcessFlowRequest(
ctx context.Context,
config_obj *config_proto.Config, req *crypto_proto.VeloMessage) {
flow_context := self.flow_manager.FlowContext(self.Outbound, req)
defer flow_context.Close()
// Control concurrency for the entire collection at once. If a
// collection has many queries, they all run concurrently.
if !req.Urgent {
cancel, err := self.concurrency.StartConcurrencyControl(ctx)
if err != nil {
responder.MakeErrorResponse(
self.Outbound, req.SessionId, err.Error())
return
}
defer cancel()
}
// Wait for the trace to finish recording all its data.
trace_wg := &sync.WaitGroup{}
defer trace_wg.Wait()
// Cancel traces when the entire collection exist.
trace_ctx, cancel := context.WithCancel(ctx)
defer cancel()
// Run trace queries now but do not wait for them to exit before
// cancelling them.
for _, arg := range req.FlowRequest.Trace {
trace_wg.Add(1)
go func(arg *actions_proto.VQLCollectorArgs) {
defer trace_wg.Done()
_, responder_obj := flow_context.NewResponder(arg)
defer responder_obj.Close()
actions.VQLClientAction{}.StartQuery(
config_obj, trace_ctx, responder_obj, arg)
}(arg)
}
// Wait for all subqueries before closing the collection.
wg := &sync.WaitGroup{}
defer wg.Wait()
for _, arg := range req.FlowRequest.VQLClientActions {
wg.Add(1)
// Run each VQLClientActions in another goroutine.
go func(arg *actions_proto.VQLCollectorArgs) {
defer wg.Done()
// A responder is used to track each specific query within the
// entire flow. There can be multiple queries run in parallel
// within the same flow.
sub_ctx, responder_obj := flow_context.NewResponder(arg)
defer responder_obj.Close()
actions.VQLClientAction{}.StartQuery(
config_obj, sub_ctx, responder_obj, arg)
}(arg)
}
}