Skip to content

Commit c82dadd

Browse files
ebpf dns improvements
- Better handling of burst messages. - Empty the queue if it gets full.
1 parent 7eb1cbf commit c82dadd

File tree

1 file changed

+36
-17
lines changed

1 file changed

+36
-17
lines changed

daemon/dns/ebpfhook.go

Lines changed: 36 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,7 @@ import (
99
"net"
1010
"os"
1111
"os/signal"
12-
"runtime"
1312
"syscall"
14-
"time"
1513

1614
"github.com/cilium/ebpf"
1715
"github.com/cilium/ebpf/link"
@@ -116,6 +114,7 @@ func lookupSymbol(elffile *elf.File, symbolName string) (uint64, error) {
116114
// ListenerEbpf starts listening for DNS events.
117115
func ListenerEbpf(ebpfModPath string) error {
118116
probesAttached := 0
117+
probesList := []link.Link{}
119118
m, err := core.LoadEbpfModule("opensnitch-dns.o", ebpfModPath)
120119
if err != nil {
121120
return err
@@ -159,23 +158,23 @@ func ListenerEbpf(ebpfModPath string) error {
159158
if err != nil {
160159
log.Error("[eBPF DNS] uretprobe__gethostbyname: %s", err)
161160
} else {
162-
defer urg.Close()
161+
probesList = append(probesList, urg)
163162
probesAttached++
164163
}
165164

166165
up, err := ex.Uprobe("getaddrinfo", ebpfMod.UProbeGetAddrinfo, nil)
167166
if err != nil {
168167
log.Error("[eBPF DNS] uprobe__getaddrinfo: %s", err)
169168
} else {
170-
defer up.Close()
169+
probesList = append(probesList, up)
171170
probesAttached++
172171
}
173172

174173
urp, err := ex.Uretprobe("getaddrinfo", ebpfMod.URProbeGetAddrinfo, nil)
175174
if err != nil {
176175
log.Error("[eBPF-DNS] uretprobe__getaddrinfo: %s", err)
177176
} else {
178-
defer urp.Close()
177+
probesList = append(probesList, urp)
179178
probesAttached++
180179
}
181180

@@ -187,13 +186,27 @@ func ListenerEbpf(ebpfModPath string) error {
187186
// --------------
188187

189188
exitChannel := make(chan struct{})
190-
perfChan := make(chan []byte, 0)
191189

192-
for i := 0; i < runtime.NumCPU(); i++ {
193-
go spawnDNSWorker(i, perfChan, exitChannel)
190+
// TODO: make these options configurable
191+
192+
// 30 is the maximum amount of IPs sent from kernel to user-space.
193+
// Defined in opensnitch-dns.c.
194+
perfChan := make(chan []byte, 30)
195+
for i := 0; i < 4; i++ {
196+
go dnsWorker(i, perfChan, exitChannel)
194197
}
195198

196199
go func(perfChan chan []byte, rd *ringbuf.Reader) {
200+
drainPerfChan := func() {
201+
for {
202+
select {
203+
case <-perfChan:
204+
default:
205+
return
206+
}
207+
}
208+
}
209+
197210
for {
198211
select {
199212
case <-exitChannel:
@@ -207,7 +220,12 @@ func ListenerEbpf(ebpfModPath string) error {
207220
log.Debug("[eBPF DNS] reader error: %s", err)
208221
continue
209222
}
210-
perfChan <- record.RawSample
223+
select {
224+
case perfChan <- record.RawSample:
225+
default:
226+
log.Debug("[eBPF DNS] events queue full, emptying queue (if you see this error too often, report it to the developers).")
227+
drainPerfChan()
228+
}
211229
}
212230
}
213231
Exit:
@@ -224,27 +242,28 @@ func ListenerEbpf(ebpfModPath string) error {
224242

225243
<-sig
226244
log.Info("[eBPF DNS]: Received signal: terminating ebpf dns hook.")
227-
exitChannel <- struct{}{}
228-
for i := 0; i < runtime.NumCPU(); i++ {
245+
for _, p := range probesList {
246+
p.Close()
247+
}
248+
for i := 0; i < 4; i++ {
229249
exitChannel <- struct{}{}
230250
}
231251
return nil
232252
}
233253

234-
func spawnDNSWorker(id int, channel chan []byte, exitChannel chan struct{}) {
254+
func dnsWorker(id int, channel chan []byte, exitChannel chan struct{}) {
235255

236256
log.Debug("[eBPF DNS] worker initialized #%d", id)
237257
var event nameLookupEvent
238258
var ip net.IP
239-
for {
240-
select {
241259

242-
case <-time.After(1 * time.Millisecond):
243-
continue
260+
for data := range channel {
261+
select {
244262
case <-exitChannel:
245263
goto Exit
264+
// case data := <-channel:
246265
default:
247-
data := <-channel
266+
event = nameLookupEvent{}
248267
if len(data) > 0 {
249268
log.Trace("(%d) [eBPF DNS]: LookupEvent %d %x %x %x", id, len(data), data[:4], data[4:20], data[20:])
250269
}

0 commit comments

Comments
 (0)