-
Notifications
You must be signed in to change notification settings - Fork 51
/
client.go
93 lines (76 loc) · 2.28 KB
/
client.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
package dnsreportclient
import (
"context"
"errors"
"os"
"go.aporeto.io/trireme-lib/collector"
"go.aporeto.io/trireme-lib/controller/constants"
"go.aporeto.io/trireme-lib/controller/internal/enforcer/utils/rpcwrapper"
"go.aporeto.io/trireme-lib/controller/pkg/remoteenforcer/internal/statscollector"
"go.uber.org/zap"
)
const (
dnsReportContextID = "UNUSED"
dnsRPCCommand = "ProxyRPCServer.DNSReports"
)
// dsnReportClient This is the struct for storing state for the rpc client
// which reports dns requests back to the controller process
type dnsreportsClient struct {
collector statscollector.Collector
rpchdl *rpcwrapper.RPCWrapper
secret string
dnsReportChannel string
stop chan bool
}
// NewDNSReportClient initializes a new dns report client
func NewDNSReportClient(cr statscollector.Collector) (DNSReportClient, error) {
dc := &dnsreportsClient{
collector: cr,
rpchdl: rpcwrapper.NewRPCWrapper(),
secret: os.Getenv(constants.EnvStatsSecret),
dnsReportChannel: os.Getenv(constants.EnvStatsChannel),
stop: make(chan bool),
}
if dc.dnsReportChannel == "" {
return nil, errors.New("no path to stats socket provided")
}
if dc.secret == "" {
return nil, errors.New("no secret provided for stats channel")
}
return dc, nil
}
func (d *dnsreportsClient) sendStats(ctx context.Context) {
for {
select {
case <-ctx.Done():
return
case rep := <-d.collector.GetDNSReports():
d.sendRequest(rep)
}
}
}
func (d *dnsreportsClient) sendRequest(dnsreport *collector.DNSRequestReport) {
request := rpcwrapper.Request{
Payload: &rpcwrapper.DNSReportPayload{
Report: dnsreport,
},
}
if err := d.rpchdl.RemoteCall(
dnsReportContextID,
dnsRPCCommand,
&request,
&rpcwrapper.Response{},
); err != nil {
zap.L().Error("RPC failure in sending dns reports", zap.Error(err))
}
}
// Start This is an private function called by the remoteenforcer to connect back
// to the controller over a stats channel
func (d *dnsreportsClient) Run(ctx context.Context) error {
if err := d.rpchdl.NewRPCClient(dnsReportContextID, d.dnsReportChannel, d.secret); err != nil {
zap.L().Error("Stats RPC client cannot connect", zap.Error(err))
return err
}
go d.sendStats(ctx)
return nil
}