-
-
Notifications
You must be signed in to change notification settings - Fork 481
/
alerts.go
128 lines (113 loc) · 3.68 KB
/
alerts.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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package ui
import (
"time"
"github.com/evilsocket/opensnitch/daemon/conman"
"github.com/evilsocket/opensnitch/daemon/log"
"github.com/evilsocket/opensnitch/daemon/procmon"
"github.com/evilsocket/opensnitch/daemon/ui/protocol"
"golang.org/x/net/context"
"google.golang.org/grpc"
"google.golang.org/grpc/encoding/gzip"
)
// NewWarningAlert builts a new warning alert
func NewWarningAlert(what protocol.Alert_What, data interface{}) *protocol.Alert {
return NewAlert(protocol.Alert_WARNING, what, protocol.Alert_SHOW_ALERT, protocol.Alert_MEDIUM, data)
}
// NewErrorAlert builts a new error alert
func NewErrorAlert(what protocol.Alert_What, data interface{}) *protocol.Alert {
return NewAlert(protocol.Alert_ERROR, what, protocol.Alert_SHOW_ALERT, protocol.Alert_HIGH, data)
}
// NewAlert builts a new generic alert
func NewAlert(atype protocol.Alert_Type, what protocol.Alert_What, action protocol.Alert_Action, prio protocol.Alert_Priority, data interface{}) *protocol.Alert {
a := &protocol.Alert{
Id: uint64(time.Now().UnixNano()),
Type: atype,
Action: action,
What: what,
Priority: prio,
}
switch what {
case protocol.Alert_KERNEL_EVENT:
switch data.(type) {
case procmon.Process:
a.Data = &protocol.Alert_Proc{
data.(*procmon.Process).Serialize(),
}
case string:
a.Data = &protocol.Alert_Text{data.(string)}
a.Action = protocol.Alert_SHOW_ALERT
}
case protocol.Alert_CONNECTION:
a.Data = &protocol.Alert_Conn{
data.(*conman.Connection).Serialize(),
}
case protocol.Alert_GENERIC:
a.Data = &protocol.Alert_Text{data.(string)}
}
return a
}
// SendInfoAlert sends an info alert
func (c *Client) SendInfoAlert(data interface{}) {
c.PostAlert(protocol.Alert_INFO, protocol.Alert_GENERIC, protocol.Alert_SHOW_ALERT, protocol.Alert_LOW, data)
}
// SendWarningAlert sends an warning alert
func (c *Client) SendWarningAlert(data interface{}) {
c.PostAlert(protocol.Alert_WARNING, protocol.Alert_GENERIC, protocol.Alert_SHOW_ALERT, protocol.Alert_MEDIUM, data)
}
// SendErrorAlert sends an error alert
func (c *Client) SendErrorAlert(data interface{}) {
c.PostAlert(protocol.Alert_ERROR, protocol.Alert_GENERIC, protocol.Alert_SHOW_ALERT, protocol.Alert_HIGH, data)
}
// alertsDispatcher waits to be connected to the GUI.
// Once connected, dispatches all the queued alerts.
func (c *Client) alertsDispatcher() {
queuedAlerts := make(chan protocol.Alert, 32)
connected := false
isQueueFull := func(qdAlerts chan protocol.Alert) bool { return len(qdAlerts) > 31 }
isQueueEmpty := func(qdAlerts chan protocol.Alert) bool { return len(qdAlerts) == 0 }
queueAlert := func(qdAlerts chan protocol.Alert, pbAlert protocol.Alert) {
if isQueueFull(qdAlerts) {
v := <-qdAlerts
// empty queue before adding a new one
log.Debug("Discarding queued alert (%d): %v", len(qdAlerts), v)
}
select {
case qdAlerts <- pbAlert:
default:
log.Debug("Alert not sent to queue, full? (%d)", len(qdAlerts))
}
}
for {
select {
case pbAlert := <-c.alertsChan:
if !connected {
queueAlert(queuedAlerts, pbAlert)
continue
}
c.dispatchAlert(pbAlert)
case ready := <-c.isConnected:
connected = ready
if ready {
log.Important("UI connected, dispathing queued alerts: %d", len(c.alertsChan))
for {
if isQueueEmpty(queuedAlerts) {
// no more queued alerts, exit
break
}
c.dispatchAlert(<-queuedAlerts)
}
}
}
}
}
func (c *Client) dispatchAlert(pbAlert protocol.Alert) {
c.RLock()
isDisconnected := c.client == nil
c.RUnlock()
if isDisconnected {
return
}
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
c.client.PostAlert(ctx, &pbAlert, grpc.UseCompressor(gzip.Name))
cancel()
}