Revamp connection handling flow to fix race condition and support info-only packets
This commit is contained in:
@@ -13,6 +13,12 @@ type infoPacket struct {
|
||||
pmpacket.Base
|
||||
}
|
||||
|
||||
// InfoOnly returns whether the packet is informational only and does not
|
||||
// represent an actual packet.
|
||||
func (pkt *infoPacket) InfoOnly() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// LoadPacketData does nothing on Linux, as data is always fully parsed.
|
||||
func (pkt *infoPacket) LoadPacketData() error {
|
||||
return fmt.Errorf("can't load data in info only packet")
|
||||
|
||||
@@ -5,11 +5,13 @@ import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"net"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"github.com/cilium/ebpf/link"
|
||||
"github.com/cilium/ebpf/ringbuf"
|
||||
"github.com/cilium/ebpf/rlimit"
|
||||
|
||||
"github.com/safing/portbase/log"
|
||||
"github.com/safing/portmaster/network/packet"
|
||||
)
|
||||
@@ -17,6 +19,7 @@ import (
|
||||
//go:generate go run github.com/cilium/ebpf/cmd/bpf2go -cc clang -cflags "-O2 -g -Wall -Werror" -type Event bpf program/monitor.c
|
||||
var stopper chan struct{}
|
||||
|
||||
// StartEBPFWorker starts the ebpf worker.
|
||||
func StartEBPFWorker(ch chan packet.Packet) {
|
||||
stopper = make(chan struct{})
|
||||
go func() {
|
||||
@@ -32,7 +35,7 @@ func StartEBPFWorker(ch chan packet.Packet) {
|
||||
log.Errorf("ebpf: failed to load ebpf object: %s", err)
|
||||
return
|
||||
}
|
||||
defer objs.Close()
|
||||
defer objs.Close() //nolint:errcheck
|
||||
|
||||
// Create a link to the tcp_connect program.
|
||||
linkTCPConnect, err := link.AttachTracing(link.TracingOptions{
|
||||
@@ -42,7 +45,7 @@ func StartEBPFWorker(ch chan packet.Packet) {
|
||||
log.Errorf("ebpf: failed to attach to tcp_v4_connect: %s ", err)
|
||||
return
|
||||
}
|
||||
defer linkTCPConnect.Close()
|
||||
defer linkTCPConnect.Close() //nolint:errcheck
|
||||
|
||||
// Create a link to the udp_v4_connect program.
|
||||
linkUDPV4, err := link.AttachTracing(link.TracingOptions{
|
||||
@@ -52,7 +55,7 @@ func StartEBPFWorker(ch chan packet.Packet) {
|
||||
log.Errorf("ebpf: failed to attach to udp_v4_connect: %s ", err)
|
||||
return
|
||||
}
|
||||
defer linkUDPV4.Close()
|
||||
defer linkUDPV4.Close() //nolint:errcheck
|
||||
|
||||
// Create a link to the udp_v6_connect program.
|
||||
linkUDPV6, err := link.AttachTracing(link.TracingOptions{
|
||||
@@ -62,14 +65,14 @@ func StartEBPFWorker(ch chan packet.Packet) {
|
||||
log.Errorf("ebpf: failed to attach to udp_v6_connect: %s ", err)
|
||||
return
|
||||
}
|
||||
defer linkUDPV6.Close()
|
||||
defer linkUDPV6.Close() //nolint:errcheck
|
||||
|
||||
rd, err := ringbuf.NewReader(objs.bpfMaps.Events)
|
||||
if err != nil {
|
||||
log.Errorf("ebpf: failed to open ring buffer: %s", err)
|
||||
return
|
||||
}
|
||||
defer rd.Close()
|
||||
defer rd.Close() //nolint:errcheck
|
||||
|
||||
go func() {
|
||||
<-stopper
|
||||
@@ -107,7 +110,8 @@ func StartEBPFWorker(ch chan packet.Packet) {
|
||||
DstPort: event.Dport,
|
||||
Src: arrayToIP(event.Saddr, packet.IPVersion(event.IpVersion)),
|
||||
Dst: arrayToIP(event.Daddr, packet.IPVersion(event.IpVersion)),
|
||||
PID: event.Pid,
|
||||
PID: int(event.Pid),
|
||||
SeenAt: time.Now(),
|
||||
}
|
||||
if isEventValid(event) {
|
||||
log.Debugf("ebpf: PID: %d conn: %s:%d -> %s:%d %s %s", info.PID, info.LocalIP(), info.LocalPort(), info.RemoteIP(), info.RemotePort(), info.Version.String(), info.Protocol.String())
|
||||
@@ -123,6 +127,7 @@ func StartEBPFWorker(ch chan packet.Packet) {
|
||||
}()
|
||||
}
|
||||
|
||||
// StopEBPFWorker stops the ebpf worker.
|
||||
func StopEBPFWorker() {
|
||||
close(stopper)
|
||||
}
|
||||
@@ -148,11 +153,12 @@ func isEventValid(event bpfEvent) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// arrayToIP converts IP number array to net.IP
|
||||
// arrayToIP converts IP number array to net.IP.
|
||||
func arrayToIP(ipNum [4]uint32, ipVersion packet.IPVersion) net.IP {
|
||||
if ipVersion == packet.IPv4 {
|
||||
// FIXME: maybe convertIPv4 from windowskext package
|
||||
return unsafe.Slice((*byte)(unsafe.Pointer(&ipNum)), 4)
|
||||
} else {
|
||||
return unsafe.Slice((*byte)(unsafe.Pointer(&ipNum)), 16)
|
||||
}
|
||||
// FIXME: maybe use convertIPv6 from windowskext package
|
||||
return unsafe.Slice((*byte)(unsafe.Pointer(&ipNum)), 16)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user