Skip to content

Commit 7dcf057

Browse files
committed
updates for consumer integration
1 parent c02a284 commit 7dcf057

File tree

3 files changed

+109
-46
lines changed

3 files changed

+109
-46
lines changed

packet_sorter.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,9 @@ func (s *PacketSorter) initCbufPcap() {
152152
}
153153

154154
func (s *PacketSorter) initSocketPcap() {
155-
s.socketPcap = NewSocketPcap(misc.GetPacketSocketPath())
155+
unixSocketFile := misc.GetPacketSocketPath()
156+
_ = os.Remove(unixSocketFile)
157+
s.socketPcap = NewSocketPcap(unixSocketFile)
156158
}
157159

158160
func (s *PacketSorter) Close() {

packet_unix_socket.go

Lines changed: 82 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,21 @@ import (
66
"sync"
77
"syscall"
88
"time"
9-
"unsafe"
109

1110
"github.com/kubeshark/gopacket"
11+
"github.com/kubeshark/tracer/pkg/unixpacket"
1212
"github.com/rs/zerolog/log"
1313
)
1414

1515
const (
1616
maxUnixPacketClients = 10
17-
packetHeaderSize = int(unsafe.Sizeof(PacketHeader{}))
1817
)
1918

2019
type SocketPcapConnection struct {
2120
packetCounter uint64
21+
writeChannel chan []byte
22+
packetSent uint64
23+
packetDropped uint64
2224
}
2325

2426
type SocketPcap struct {
@@ -28,9 +30,81 @@ type SocketPcap struct {
2830
sync.Mutex
2931
}
3032

31-
type PacketHeader struct {
32-
packetCounter uint64
33-
timestamp uint64
33+
func (s *SocketPcapConnection) Run(conn *net.UnixConn, sock *SocketPcap) {
34+
for {
35+
select {
36+
case buf := <-s.writeChannel:
37+
_, err := conn.Write(buf)
38+
if err != nil {
39+
if errors.Is(err, syscall.EPIPE) {
40+
log.Info().Str("Address", conn.RemoteAddr().String()).Msg("Unix socket connection closed:")
41+
} else {
42+
log.Error().Err(err).Str("Address", conn.RemoteAddr().String()).Msg("Unix socket connection error:")
43+
}
44+
sock.Disconnected(conn)
45+
return
46+
}
47+
48+
}
49+
}
50+
}
51+
52+
func (s *SocketPcap) WritePacket(pkt gopacket.SerializeBuffer) error {
53+
s.Lock()
54+
defer s.Unlock()
55+
defer func() {
56+
s.packetCounter++
57+
}()
58+
if len(s.connections) == 0 {
59+
return nil
60+
}
61+
62+
hdrBytes, err := pkt.PrependBytes(unixpacket.PacketHeaderSize)
63+
if err != nil {
64+
return err
65+
}
66+
67+
p := unixpacket.PacketUnixSocket(hdrBytes)
68+
hdr := p.GetHeader()
69+
hdr.Timestamp = uint64(time.Now().UnixNano())
70+
// clear buffer at the end as soon as it is prepended with specific data
71+
defer func() {
72+
_ = pkt.Clear()
73+
}()
74+
75+
buf := pkt.Bytes()
76+
for _, conn := range s.connections {
77+
copyBuf := make([]byte, len(buf))
78+
copy(copyBuf, buf)
79+
p = unixpacket.PacketUnixSocket(copyBuf)
80+
hdr = p.GetHeader()
81+
hdr.PacketCounter = conn.packetCounter
82+
conn.packetCounter++
83+
select {
84+
case conn.writeChannel <- copyBuf:
85+
conn.packetSent++
86+
default:
87+
conn.packetDropped++
88+
}
89+
}
90+
return nil
91+
}
92+
93+
func (s *SocketPcap) Connected(conn *net.UnixConn) {
94+
ch := make(chan []byte, 8)
95+
s.Lock()
96+
defer s.Unlock()
97+
c := &SocketPcapConnection{
98+
writeChannel: ch,
99+
}
100+
s.connections[conn] = c
101+
go c.Run(conn, s)
102+
}
103+
104+
func (s *SocketPcap) Disconnected(conn *net.UnixConn) {
105+
s.Lock()
106+
defer s.Unlock()
107+
delete(s.connections, conn)
34108
}
35109

36110
func NewSocketPcap(unixSocketFileName string) *SocketPcap {
@@ -61,47 +135,10 @@ func (c *SocketPcap) acceptClients(l *net.UnixListener) {
61135
if c.clientsConnected == maxUnixPacketClients {
62136
log.Info().Str("Address", conn.RemoteAddr().String()).Msg("Unix socket max connections exceeded, closing:")
63137
conn.Close()
64-
} else {
65-
c.connections[conn] = &SocketPcapConnection{}
66-
c.clientsConnected++
67-
}
68-
c.Unlock()
69-
}
70-
}
71-
72-
func (c *SocketPcap) WritePacket(buf gopacket.SerializeBuffer) error {
73-
var err error
74-
var hdrBytes []byte
75-
c.Lock()
76-
defer c.Unlock()
77-
c.packetCounter++
78-
if len(c.connections) > 0 {
79-
hdrBytes, err = buf.PrependBytes(packetHeaderSize)
80-
if err != nil {
81-
return err
82-
}
83-
// clear buffer at the end as soon as it is prepended with specific data
84-
defer func() {
85-
_ = buf.Clear()
86-
}()
87-
}
88-
for sock, conn := range c.connections {
89-
hdr := (*PacketHeader)(unsafe.Pointer(&hdrBytes))
90-
hdr.packetCounter = conn.packetCounter
91-
92-
_, err = sock.Write(buf.Bytes())
93-
94-
if err != nil {
95-
if errors.Is(err, syscall.EPIPE) {
96-
log.Info().Str("Address", sock.RemoteAddr().String()).Msg("Unix socket connection closed:")
97-
} else {
98-
log.Error().Err(err).Str("Address", sock.RemoteAddr().String()).Msg("Unix socket connection error:")
99-
}
100-
delete(c.connections, sock)
138+
c.Unlock()
101139
continue
102140
}
103-
conn.packetCounter++
141+
c.Unlock()
142+
c.Connected(conn)
104143
}
105-
106-
return nil
107144
}

pkg/unixpacket/pkt.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package unixpacket
2+
3+
import (
4+
"unsafe"
5+
)
6+
7+
const PacketHeaderSize = int(unsafe.Sizeof(PacketUnixSocketHeader{}))
8+
9+
type PacketUnixSocketHeader struct {
10+
PacketCounter uint64
11+
Timestamp uint64
12+
}
13+
14+
type PacketUnixSocket []byte
15+
16+
func (pkt *PacketUnixSocket) GetHeader() *PacketUnixSocketHeader {
17+
data := []byte(*pkt)
18+
return (*PacketUnixSocketHeader)(unsafe.Pointer(&data[0]))
19+
}
20+
21+
func (pkt *PacketUnixSocket) GetData() []byte {
22+
data := []byte(*pkt)
23+
return data[PacketHeaderSize:]
24+
}

0 commit comments

Comments
 (0)