-
Notifications
You must be signed in to change notification settings - Fork 0
/
intf.go
89 lines (76 loc) · 2.28 KB
/
intf.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
package probe
import (
"syscall"
"time"
log "github.com/sirupsen/logrus"
"github.com/zhyocean/neuvector/share/container"
"github.com/zhyocean/neuvector/share/utils"
)
var intfMonitorPollTimeoutLong = syscall.Timeval{5, 0}
var intfMonitorPollTimeoutShort = syscall.Timeval{0, 500000}
type intfMonitorInterface interface {
WaitAddrChange(*syscall.Timeval) (bool, error)
Close()
}
func (p *Probe) intfMonitorLoop(id string, m intfMonitorInterface, timeout time.Duration, stopCh chan struct{}) {
toNotify := false
pollTimeout := intfMonitorPollTimeoutLong
expire := time.After(timeout)
for {
select {
case <-stopCh:
log.WithFields(log.Fields{"id": container.ShortContainerId(id)}).Debug("Stopped")
m.Close()
return
case <-expire:
log.WithFields(log.Fields{"id": container.ShortContainerId(id)}).Debug("Timeout")
m.Close()
p.intfMonMux.Lock()
delete(p.intfMonMap, id)
p.intfMonMux.Unlock()
return
default:
// Aggregate addr/route change notification.
changed, err := m.WaitAddrChange(&pollTimeout)
if err != nil {
log.WithFields(log.Fields{"error": err}).Debug("Receive error")
} else if changed {
toNotify = true
pollTimeout = intfMonitorPollTimeoutShort
} else if toNotify {
log.WithFields(log.Fields{"id": container.ShortContainerId(id)}).Debug("Notify addr or route changed")
toNotify = false
msg := ProbeMessage{Type: PROBE_CONTAINER_NEW_IP, ContainerIDs: utils.NewSet(id)}
p.notifyTaskChan <- &msg
pollTimeout = intfMonitorPollTimeoutLong
} else {
pollTimeout = intfMonitorPollTimeoutLong
}
}
}
}
func (p *Probe) StartMonitorInterface(id string, pid int, timeout time.Duration) {
log.WithFields(log.Fields{"id": container.ShortContainerId(id)}).Debug("")
m := p.openIntfMonitor(pid)
if m == nil {
log.WithFields(log.Fields{"id": container.ShortContainerId(id)}).Debug("start fail")
return
}
stopCh := make(chan struct{})
p.intfMonMux.Lock()
p.intfMonMap[id] = stopCh
p.intfMonMux.Unlock()
go p.intfMonitorLoop(id, m, timeout, stopCh)
}
func (p *Probe) StopMonitorInterface(id string) {
log.WithFields(log.Fields{"id": container.ShortContainerId(id)}).Debug("")
p.intfMonMux.Lock()
ch, ok := p.intfMonMap[id]
if ok {
delete(p.intfMonMap, id)
}
p.intfMonMux.Unlock()
if ok {
close(ch)
}
}