mirror of
https://github.com/kubeshark/kubeshark.git
synced 2025-07-08 13:54:28 +00:00
Unify Golang and OpenSSL under a single perf event buffer and tls_chunk
struct
This commit is contained in:
parent
bab23303ae
commit
71c4b592e8
@ -11,13 +11,6 @@ Copyright (C) UP9 Inc.
|
||||
#include "include/logger_messages.h"
|
||||
|
||||
|
||||
struct {
|
||||
__uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
|
||||
__uint(max_entries, 1);
|
||||
__type(key, int);
|
||||
__type(value, struct golang_event);
|
||||
} golang_heap SEC(".maps");
|
||||
|
||||
SEC("uprobe/golang_crypto_tls_write")
|
||||
static __always_inline int golang_crypto_tls_write_uprobe(struct pt_regs *ctx) {
|
||||
__u64 pid_tgid = bpf_get_current_pid_tgid();
|
||||
@ -42,31 +35,31 @@ static __always_inline int golang_crypto_tls_write_uprobe(struct pt_regs *ctx) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct golang_event *event = NULL;
|
||||
struct tls_chunk *chunk = NULL;
|
||||
int zero = 0;
|
||||
|
||||
event = bpf_map_lookup_elem(&golang_heap, &zero);
|
||||
chunk = bpf_map_lookup_elem(&heap, &zero);
|
||||
|
||||
if (!event) {
|
||||
if (!chunk) {
|
||||
log_error(ctx, LOG_ERROR_GOLANG_ALLOCATING_EVENT, pid, 0l, 0l);
|
||||
return 0;
|
||||
}
|
||||
|
||||
event->pid = pid;
|
||||
event->fd = s->fd;
|
||||
chunk->type = Golang_type;
|
||||
chunk->pid = pid;
|
||||
chunk->fd = s->fd;
|
||||
// ctx->rsi is common between golang_crypto_tls_write_uprobe and golang_crypto_tls_read_uprobe
|
||||
event->conn_addr = ctx->rsi; // go.itab.*net.TCPConn,net.Conn address
|
||||
event->is_request = true;
|
||||
event->len = ctx->rcx;
|
||||
event->cap = ctx->rdi;
|
||||
chunk->flags = ctx->rsi; // go.itab.*net.TCPConn,net.Conn address
|
||||
chunk->is_request = true;
|
||||
chunk->len = ctx->rcx;
|
||||
|
||||
status = bpf_probe_read(&event->data, CHUNK_SIZE, (void*)ctx->rbx);
|
||||
status = bpf_probe_read(&chunk->data, CHUNK_SIZE, (void*)ctx->rbx);
|
||||
if (status < 0) {
|
||||
log_error(ctx, LOG_ERROR_GOLANG_WRITE_READING_DATA, pid_tgid, status, 0l);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bpf_perf_event_output(ctx, &golang_events, BPF_F_CURRENT_CPU, event, sizeof(struct golang_event));
|
||||
bpf_perf_event_output(ctx, &chunks_buffer, BPF_F_CURRENT_CPU, chunk, sizeof(struct tls_chunk));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -88,30 +81,30 @@ static __always_inline int golang_crypto_tls_read_uprobe(struct pt_regs *ctx) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct golang_event *event = NULL;
|
||||
struct tls_chunk *chunk = NULL;
|
||||
int zero = 0;
|
||||
|
||||
event = bpf_map_lookup_elem(&golang_heap, &zero);
|
||||
chunk = bpf_map_lookup_elem(&heap, &zero);
|
||||
|
||||
if (!event) {
|
||||
if (!chunk) {
|
||||
log_error(ctx, LOG_ERROR_GOLANG_ALLOCATING_EVENT, pid, 0l, 0l);
|
||||
return 0;
|
||||
}
|
||||
|
||||
event->pid = pid;
|
||||
chunk->type = Golang_type;
|
||||
chunk->pid = pid;
|
||||
// ctx->rsi is common between golang_crypto_tls_write_uprobe and golang_crypto_tls_read_uprobe
|
||||
event->conn_addr = ctx->rsi; // go.itab.*net.TCPConn,net.Conn address
|
||||
event->is_request = false;
|
||||
event->len = ctx->rcx;
|
||||
event->cap = ctx->rcx; // no cap info
|
||||
chunk->flags = ctx->rsi; // go.itab.*net.TCPConn,net.Conn address
|
||||
chunk->is_request = false;
|
||||
chunk->len = ctx->rcx;
|
||||
|
||||
status = bpf_probe_read(&event->data, CHUNK_SIZE, (void*)(data_p));
|
||||
status = bpf_probe_read(&chunk->data, CHUNK_SIZE, (void*)(data_p));
|
||||
if (status < 0) {
|
||||
log_error(ctx, LOG_ERROR_GOLANG_READ_READING_DATA, pid_tgid, status, 0l);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bpf_perf_event_output(ctx, &golang_events, BPF_F_CURRENT_CPU, event, sizeof(struct golang_event));
|
||||
bpf_perf_event_output(ctx, &chunks_buffer, BPF_F_CURRENT_CPU, chunk, sizeof(struct tls_chunk));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -21,11 +21,16 @@ Copyright (C) UP9 Inc.
|
||||
#define MAX_ENTRIES_LRU_HASH (1 << 14) // 16384
|
||||
#define MAX_ENTRIES_RINGBUFF (1 << 24) // 16777216
|
||||
|
||||
enum ChunkType {
|
||||
OpenSSL_type=1,
|
||||
Golang_type=2,
|
||||
};
|
||||
|
||||
// The same struct can be found in chunk.go
|
||||
//
|
||||
// Be careful when editing, alignment and padding should be exactly the same in go/c.
|
||||
//
|
||||
struct tlsChunk {
|
||||
struct tls_chunk {
|
||||
__u32 pid;
|
||||
__u32 tgid;
|
||||
__u32 len;
|
||||
@ -33,6 +38,8 @@ struct tlsChunk {
|
||||
__u32 recorded;
|
||||
__u32 fd;
|
||||
__u32 flags;
|
||||
enum ChunkType type;
|
||||
bool is_request;
|
||||
__u8 address[16];
|
||||
__u8 data[CHUNK_SIZE]; // Must be N^2
|
||||
};
|
||||
@ -64,20 +71,20 @@ struct golang_socket {
|
||||
__u64 conn_addr;
|
||||
};
|
||||
|
||||
struct golang_event {
|
||||
__u32 pid;
|
||||
__u32 fd;
|
||||
__u32 conn_addr;
|
||||
bool is_request;
|
||||
__u32 len;
|
||||
__u32 cap;
|
||||
__u8 data[CHUNK_SIZE];
|
||||
};
|
||||
|
||||
const struct golang_event *unused1 __attribute__((unused));
|
||||
const struct sys_close *unused2 __attribute__((unused));
|
||||
|
||||
|
||||
// Heap-like area for eBPF programs - stack size limited to 512 bytes, we must use maps for bigger (chunk) objects.
|
||||
//
|
||||
struct {
|
||||
__uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
|
||||
__uint(max_entries, 1);
|
||||
__type(key, int);
|
||||
__type(value, struct tls_chunk);
|
||||
} heap SEC(".maps");
|
||||
|
||||
|
||||
#define BPF_MAP(_name, _type, _key_type, _value_type, _max_entries) \
|
||||
struct bpf_map_def SEC("maps") _name = { \
|
||||
.type = _type, \
|
||||
@ -99,16 +106,15 @@ const struct sys_close *unused2 __attribute__((unused));
|
||||
BPF_HASH(pids_map, __u32, __u32);
|
||||
BPF_PERF_OUTPUT(log_buffer);
|
||||
BPF_PERF_OUTPUT(sys_closes);
|
||||
BPF_PERF_OUTPUT(chunks_buffer);
|
||||
|
||||
// OpenSSL specific
|
||||
BPF_LRU_HASH(ssl_write_context, __u64, struct ssl_info);
|
||||
BPF_LRU_HASH(ssl_read_context, __u64, struct ssl_info);
|
||||
BPF_LRU_HASH(file_descriptor_to_ipv4, __u64, struct fd_info);
|
||||
BPF_PERF_OUTPUT(chunks_buffer);
|
||||
|
||||
// Golang specific
|
||||
BPF_LRU_HASH(golang_dial_to_socket, __u64, struct golang_socket);
|
||||
BPF_LRU_HASH(golang_socket_to_write, __u64, struct golang_socket);
|
||||
BPF_PERF_OUTPUT(golang_events);
|
||||
|
||||
#endif /* __MAPS__ */
|
||||
|
@ -11,14 +11,6 @@ Copyright (C) UP9 Inc.
|
||||
#include "include/logger_messages.h"
|
||||
#include "include/pids.h"
|
||||
|
||||
// Heap-like area for eBPF programs - stack size limited to 512 bytes, we must use maps for bigger (chunk) objects.
|
||||
//
|
||||
struct {
|
||||
__uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
|
||||
__uint(max_entries, 1);
|
||||
__type(key, int);
|
||||
__type(value, struct tlsChunk);
|
||||
} heap SEC(".maps");
|
||||
|
||||
static __always_inline int get_count_bytes(struct pt_regs *ctx, struct ssl_info* info, __u64 id) {
|
||||
int returnValue = PT_REGS_RC(ctx);
|
||||
@ -48,7 +40,7 @@ static __always_inline int get_count_bytes(struct pt_regs *ctx, struct ssl_info*
|
||||
return countBytes;
|
||||
}
|
||||
|
||||
static __always_inline int add_address_to_chunk(struct pt_regs *ctx, struct tlsChunk* chunk, __u64 id, __u32 fd) {
|
||||
static __always_inline int add_address_to_chunk(struct pt_regs *ctx, struct tls_chunk* chunk, __u64 id, __u32 fd) {
|
||||
__u32 pid = id >> 32;
|
||||
__u64 key = (__u64) pid << 32 | fd;
|
||||
|
||||
@ -70,7 +62,7 @@ static __always_inline int add_address_to_chunk(struct pt_regs *ctx, struct tlsC
|
||||
}
|
||||
|
||||
static __always_inline void send_chunk_part(struct pt_regs *ctx, __u8* buffer, __u64 id,
|
||||
struct tlsChunk* chunk, int start, int end) {
|
||||
struct tls_chunk* chunk, int start, int end) {
|
||||
size_t recorded = MIN(end - start, sizeof(chunk->data));
|
||||
|
||||
if (recorded <= 0) {
|
||||
@ -95,10 +87,10 @@ static __always_inline void send_chunk_part(struct pt_regs *ctx, __u8* buffer, _
|
||||
return;
|
||||
}
|
||||
|
||||
bpf_perf_event_output(ctx, &chunks_buffer, BPF_F_CURRENT_CPU, chunk, sizeof(struct tlsChunk));
|
||||
bpf_perf_event_output(ctx, &chunks_buffer, BPF_F_CURRENT_CPU, chunk, sizeof(struct tls_chunk));
|
||||
}
|
||||
|
||||
static __always_inline void send_chunk(struct pt_regs *ctx, __u8* buffer, __u64 id, struct tlsChunk* chunk) {
|
||||
static __always_inline void send_chunk(struct pt_regs *ctx, __u8* buffer, __u64 id, struct tls_chunk* chunk) {
|
||||
// ebpf loops must be bounded at compile time, we can't use (i < chunk->len / CHUNK_SIZE)
|
||||
//
|
||||
// https://lwn.net/Articles/794934/
|
||||
@ -127,7 +119,7 @@ static __always_inline void output_ssl_chunk(struct pt_regs *ctx, struct ssl_inf
|
||||
return;
|
||||
}
|
||||
|
||||
struct tlsChunk* chunk;
|
||||
struct tls_chunk* chunk;
|
||||
int zero = 0;
|
||||
|
||||
// If other thread, running on the same CPU get to this point at the same time like us (context switch)
|
||||
@ -140,6 +132,7 @@ static __always_inline void output_ssl_chunk(struct pt_regs *ctx, struct ssl_inf
|
||||
return;
|
||||
}
|
||||
|
||||
chunk->type = OpenSSL_type;
|
||||
chunk->flags = flags;
|
||||
chunk->pid = id >> 32;
|
||||
chunk->tgid = id;
|
||||
|
@ -12,23 +12,7 @@ import (
|
||||
const FLAGS_IS_CLIENT_BIT uint32 = (1 << 0)
|
||||
const FLAGS_IS_READ_BIT uint32 = (1 << 1)
|
||||
|
||||
// The same struct can be found in maps.h
|
||||
//
|
||||
// Be careful when editing, alignment and padding should be exactly the same in go/c.
|
||||
//
|
||||
type tlsChunk struct {
|
||||
Pid uint32 // process id
|
||||
Tgid uint32 // thread id inside the process
|
||||
Len uint32 // the size of the native buffer used to read/write the tls data (may be bigger than tlsChunk.Data[])
|
||||
Start uint32 // the start offset withing the native buffer
|
||||
Recorded uint32 // number of bytes copied from the native buffer to tlsChunk.Data[]
|
||||
Fd uint32 // the file descriptor used to read/write the tls data (probably socket file descriptor)
|
||||
Flags uint32 // bitwise flags
|
||||
Address [16]byte // ipv4 address and port
|
||||
Data [4096]byte // actual tls data
|
||||
}
|
||||
|
||||
func (c *tlsChunk) getAddress() (net.IP, uint16, error) {
|
||||
func (c *tlsTapperTlsChunk) getAddress() (net.IP, uint16, error) {
|
||||
address := bytes.NewReader(c.Address[:])
|
||||
var family uint16
|
||||
var port uint16
|
||||
@ -51,31 +35,31 @@ func (c *tlsChunk) getAddress() (net.IP, uint16, error) {
|
||||
return ip, port, nil
|
||||
}
|
||||
|
||||
func (c *tlsChunk) isClient() bool {
|
||||
func (c *tlsTapperTlsChunk) isClient() bool {
|
||||
return c.Flags&FLAGS_IS_CLIENT_BIT != 0
|
||||
}
|
||||
|
||||
func (c *tlsChunk) isServer() bool {
|
||||
func (c *tlsTapperTlsChunk) isServer() bool {
|
||||
return !c.isClient()
|
||||
}
|
||||
|
||||
func (c *tlsChunk) isRead() bool {
|
||||
func (c *tlsTapperTlsChunk) isRead() bool {
|
||||
return c.Flags&FLAGS_IS_READ_BIT != 0
|
||||
}
|
||||
|
||||
func (c *tlsChunk) isWrite() bool {
|
||||
func (c *tlsTapperTlsChunk) isWrite() bool {
|
||||
return !c.isRead()
|
||||
}
|
||||
|
||||
func (c *tlsChunk) getRecordedData() []byte {
|
||||
func (c *tlsTapperTlsChunk) getRecordedData() []byte {
|
||||
return c.Data[:c.Recorded]
|
||||
}
|
||||
|
||||
func (c *tlsChunk) isRequest() bool {
|
||||
func (c *tlsTapperTlsChunk) isRequest() bool {
|
||||
return (c.isClient() && c.isWrite()) || (c.isServer() && c.isRead())
|
||||
}
|
||||
|
||||
func (c *tlsChunk) getAddressPair() (addressPair, error) {
|
||||
func (c *tlsTapperTlsChunk) getAddressPair() (addressPair, error) {
|
||||
ip, port, err := c.getAddress()
|
||||
|
||||
if err != nil {
|
||||
|
@ -4,7 +4,6 @@ import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"log"
|
||||
"sync"
|
||||
"time"
|
||||
"unsafe"
|
||||
@ -75,12 +74,6 @@ func (p *tlsPoller) init(bpfObjects *tlsTapperObjects, bufferSize int) error {
|
||||
return errors.Wrap(err, 0)
|
||||
}
|
||||
|
||||
p.golangReader, err = perf.NewReader(bpfObjects.GolangEvents, bufferSize)
|
||||
|
||||
if err != nil {
|
||||
return errors.Wrap(err, 0)
|
||||
}
|
||||
|
||||
p.sysCloses, err = perf.NewReader(bpfObjects.SysCloses, bufferSize)
|
||||
|
||||
if err != nil {
|
||||
@ -97,9 +90,11 @@ func (p *tlsPoller) close() error {
|
||||
}
|
||||
|
||||
func (p *tlsPoller) pollSsllib(emitter api.Emitter, options *api.TrafficFilteringOptions, streamsMap api.TcpStreamMap) {
|
||||
chunks := make(chan *tlsChunk)
|
||||
// tlsTapperTlsChunk is generated by bpf2go.
|
||||
chunks := make(chan *tlsTapperTlsChunk)
|
||||
|
||||
go p.pollChunksPerfBuffer(chunks)
|
||||
go p.pollSysClose(p.sysCloses)
|
||||
|
||||
for {
|
||||
select {
|
||||
@ -108,8 +103,15 @@ func (p *tlsPoller) pollSsllib(emitter api.Emitter, options *api.TrafficFilterin
|
||||
return
|
||||
}
|
||||
|
||||
if err := p.handleTlsChunk(chunk, p.extension, emitter, options, streamsMap); err != nil {
|
||||
LogError(err)
|
||||
switch chunk.Type {
|
||||
case 1:
|
||||
if err := p.handleOpenSslTlsChunk(chunk, p.extension, emitter, options, streamsMap); err != nil {
|
||||
LogError(err)
|
||||
}
|
||||
case 2:
|
||||
if err := p.handleGolangTlsChunk(chunk, emitter, options, streamsMap); err != nil {
|
||||
LogError(err)
|
||||
}
|
||||
}
|
||||
case key := <-p.closedReaders:
|
||||
delete(p.readers, key)
|
||||
@ -117,91 +119,63 @@ func (p *tlsPoller) pollSsllib(emitter api.Emitter, options *api.TrafficFilterin
|
||||
}
|
||||
}
|
||||
|
||||
func (p *tlsPoller) pollGolang(emitter api.Emitter, options *api.TrafficFilteringOptions, streamsMap api.TcpStreamMap) {
|
||||
go p.pollGolangReadWrite(p.golangReader, emitter, options, streamsMap)
|
||||
go p.pollSysClose(p.sysCloses)
|
||||
}
|
||||
|
||||
func (p *tlsPoller) pollGolangReadWrite(rd *perf.Reader, emitter api.Emitter, options *api.TrafficFilteringOptions,
|
||||
streamsMap api.TcpStreamMap) {
|
||||
nativeEndian := p.getByteOrder()
|
||||
// tlsTapperGolangEvent is generated by bpf2go.
|
||||
var b tlsTapperGolangEvent
|
||||
for {
|
||||
record, err := rd.Read()
|
||||
if err != nil {
|
||||
if errors.Is(err, perf.ErrClosed) {
|
||||
return
|
||||
}
|
||||
logger.Log.Errorf("reading from Golang tls reader: %s", err)
|
||||
continue
|
||||
}
|
||||
|
||||
if record.LostSamples != 0 {
|
||||
logger.Log.Infof("Golang perf event ring buffer full, dropped %d samples", record.LostSamples)
|
||||
continue
|
||||
}
|
||||
|
||||
if err := binary.Read(bytes.NewBuffer(record.RawSample), nativeEndian, &b); err != nil {
|
||||
logger.Log.Errorf("parsing Golang perf event: %s", err)
|
||||
continue
|
||||
}
|
||||
|
||||
if p.golangConnectionMap.Len()+1 > golangMapLimit {
|
||||
pair := p.golangConnectionMap.Oldest()
|
||||
pair.Value.(*golangConnection).close()
|
||||
p.golangConnectionMap.Delete(pair.Key)
|
||||
}
|
||||
|
||||
pid := uint64(b.Pid)
|
||||
identifier := pid<<32 + uint64(b.ConnAddr)
|
||||
|
||||
var connection *golangConnection
|
||||
var _connection interface{}
|
||||
var ok bool
|
||||
if _connection, ok = p.golangConnectionMap.Get(identifier); !ok {
|
||||
tlsEmitter := &tlsEmitter{
|
||||
delegate: emitter,
|
||||
namespace: p.getNamespace(b.Pid),
|
||||
}
|
||||
|
||||
connection = NewGolangConnection(b.Pid, b.ConnAddr, p.extension, tlsEmitter)
|
||||
p.golangConnectionMap.Set(identifier, connection)
|
||||
streamsMap.Store(streamsMap.NextId(), connection.stream)
|
||||
} else {
|
||||
connection = _connection.(*golangConnection)
|
||||
}
|
||||
|
||||
if b.IsRequest {
|
||||
connection.fd = b.Fd
|
||||
|
||||
err := connection.setAddressBySockfd(p.procfs, b.Pid, b.Fd)
|
||||
if err != nil {
|
||||
log.Printf("Error resolving address pair from fd: %s", err)
|
||||
continue
|
||||
}
|
||||
|
||||
tcpid := p.buildTcpId(&connection.addressPair)
|
||||
connection.clientReader.tcpID = &tcpid
|
||||
connection.serverReader.tcpID = &api.TcpID{
|
||||
SrcIP: tcpid.DstIP,
|
||||
DstIP: tcpid.SrcIP,
|
||||
SrcPort: tcpid.DstPort,
|
||||
DstPort: tcpid.SrcPort,
|
||||
}
|
||||
|
||||
go dissect(p.extension, connection.clientReader, options)
|
||||
go dissect(p.extension, connection.serverReader, options)
|
||||
|
||||
request := make([]byte, len(b.Data[:b.Len]))
|
||||
copy(request, b.Data[:b.Len])
|
||||
connection.clientReader.send(request)
|
||||
} else {
|
||||
response := make([]byte, len(b.Data[:b.Len]))
|
||||
copy(response, b.Data[:b.Len])
|
||||
connection.serverReader.send(response)
|
||||
}
|
||||
func (p *tlsPoller) handleGolangTlsChunk(chunk *tlsTapperTlsChunk, emitter api.Emitter, options *api.TrafficFilteringOptions,
|
||||
streamsMap api.TcpStreamMap) error {
|
||||
if p.golangConnectionMap.Len()+1 > golangMapLimit {
|
||||
pair := p.golangConnectionMap.Oldest()
|
||||
pair.Value.(*golangConnection).close()
|
||||
p.golangConnectionMap.Delete(pair.Key)
|
||||
}
|
||||
|
||||
pid := uint64(chunk.Pid)
|
||||
identifier := pid<<32 + uint64(chunk.Flags)
|
||||
|
||||
var connection *golangConnection
|
||||
var _connection interface{}
|
||||
var ok bool
|
||||
if _connection, ok = p.golangConnectionMap.Get(identifier); !ok {
|
||||
tlsEmitter := &tlsEmitter{
|
||||
delegate: emitter,
|
||||
namespace: p.getNamespace(chunk.Pid),
|
||||
}
|
||||
|
||||
connection = NewGolangConnection(chunk.Pid, chunk.Flags, p.extension, tlsEmitter)
|
||||
p.golangConnectionMap.Set(identifier, connection)
|
||||
streamsMap.Store(streamsMap.NextId(), connection.stream)
|
||||
} else {
|
||||
connection = _connection.(*golangConnection)
|
||||
}
|
||||
|
||||
if chunk.IsRequest {
|
||||
connection.fd = chunk.Fd
|
||||
|
||||
err := connection.setAddressBySockfd(p.procfs, chunk.Pid, chunk.Fd)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error resolving address pair from fd: %s", err)
|
||||
}
|
||||
|
||||
tcpid := p.buildTcpId(&connection.addressPair)
|
||||
connection.clientReader.tcpID = &tcpid
|
||||
connection.serverReader.tcpID = &api.TcpID{
|
||||
SrcIP: tcpid.DstIP,
|
||||
DstIP: tcpid.SrcIP,
|
||||
SrcPort: tcpid.DstPort,
|
||||
DstPort: tcpid.SrcPort,
|
||||
}
|
||||
|
||||
go dissect(p.extension, connection.clientReader, options)
|
||||
go dissect(p.extension, connection.serverReader, options)
|
||||
|
||||
request := make([]byte, len(chunk.Data[:chunk.Len]))
|
||||
copy(request, chunk.Data[:chunk.Len])
|
||||
connection.clientReader.send(request)
|
||||
} else {
|
||||
response := make([]byte, len(chunk.Data[:chunk.Len]))
|
||||
copy(response, chunk.Data[:chunk.Len])
|
||||
connection.serverReader.send(response)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *tlsPoller) pollSysClose(rd *perf.Reader) {
|
||||
@ -239,7 +213,7 @@ func (p *tlsPoller) pollSysClose(rd *perf.Reader) {
|
||||
}
|
||||
}
|
||||
|
||||
func (p *tlsPoller) pollChunksPerfBuffer(chunks chan<- *tlsChunk) {
|
||||
func (p *tlsPoller) pollChunksPerfBuffer(chunks chan<- *tlsTapperTlsChunk) {
|
||||
logger.Log.Infof("Start polling for tls events")
|
||||
|
||||
for {
|
||||
@ -263,7 +237,7 @@ func (p *tlsPoller) pollChunksPerfBuffer(chunks chan<- *tlsChunk) {
|
||||
|
||||
buffer := bytes.NewReader(record.RawSample)
|
||||
|
||||
var chunk tlsChunk
|
||||
var chunk tlsTapperTlsChunk
|
||||
|
||||
if err := binary.Read(buffer, binary.LittleEndian, &chunk); err != nil {
|
||||
LogError(errors.Errorf("Error parsing chunk %v", err))
|
||||
@ -274,7 +248,7 @@ func (p *tlsPoller) pollChunksPerfBuffer(chunks chan<- *tlsChunk) {
|
||||
}
|
||||
}
|
||||
|
||||
func (p *tlsPoller) handleTlsChunk(chunk *tlsChunk, extension *api.Extension, emitter api.Emitter,
|
||||
func (p *tlsPoller) handleOpenSslTlsChunk(chunk *tlsTapperTlsChunk, extension *api.Extension, emitter api.Emitter,
|
||||
options *api.TrafficFilteringOptions, streamsMap api.TcpStreamMap) error {
|
||||
address, err := p.getSockfdAddressPair(chunk)
|
||||
|
||||
@ -303,7 +277,7 @@ func (p *tlsPoller) handleTlsChunk(chunk *tlsChunk, extension *api.Extension, em
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *tlsPoller) startNewTlsReader(chunk *tlsChunk, address *addressPair, key string,
|
||||
func (p *tlsPoller) startNewTlsReader(chunk *tlsTapperTlsChunk, address *addressPair, key string,
|
||||
emitter api.Emitter, extension *api.Extension, options *api.TrafficFilteringOptions,
|
||||
streamsMap api.TcpStreamMap) *tlsReader {
|
||||
|
||||
@ -320,7 +294,7 @@ func (p *tlsPoller) startNewTlsReader(chunk *tlsChunk, address *addressPair, key
|
||||
|
||||
reader := &tlsReader{
|
||||
key: key,
|
||||
chunks: make(chan *tlsChunk, 1),
|
||||
chunks: make(chan *tlsTapperTlsChunk, 1),
|
||||
doneHandler: doneHandler,
|
||||
progress: &api.ReadProgress{},
|
||||
tcpID: &tcpid,
|
||||
@ -358,7 +332,7 @@ func (p *tlsPoller) closeReader(key string, r *tlsReader) {
|
||||
p.closedReaders <- key
|
||||
}
|
||||
|
||||
func (p *tlsPoller) getSockfdAddressPair(chunk *tlsChunk) (addressPair, error) {
|
||||
func (p *tlsPoller) getSockfdAddressPair(chunk *tlsTapperTlsChunk) (addressPair, error) {
|
||||
address, err := getAddressBySockfd(p.procfs, chunk.Pid, chunk.Fd)
|
||||
fdCacheKey := fmt.Sprintf("%d:%d", chunk.Pid, chunk.Fd)
|
||||
|
||||
@ -434,7 +408,7 @@ func (p *tlsPoller) clearPids() {
|
||||
})
|
||||
}
|
||||
|
||||
func (p *tlsPoller) logTls(chunk *tlsChunk, key string, reader *tlsReader) {
|
||||
func (p *tlsPoller) logTls(chunk *tlsTapperTlsChunk, key string, reader *tlsReader) {
|
||||
var flagsStr string
|
||||
|
||||
if chunk.isClient() {
|
||||
|
@ -9,7 +9,7 @@ import (
|
||||
|
||||
type tlsReader struct {
|
||||
key string
|
||||
chunks chan *tlsChunk
|
||||
chunks chan *tlsTapperTlsChunk
|
||||
seenChunks int
|
||||
data []byte
|
||||
doneHandler func(r *tlsReader)
|
||||
@ -24,14 +24,14 @@ type tlsReader struct {
|
||||
reqResMatcher api.RequestResponseMatcher
|
||||
}
|
||||
|
||||
func (r *tlsReader) newChunk(chunk *tlsChunk) {
|
||||
func (r *tlsReader) newChunk(chunk *tlsTapperTlsChunk) {
|
||||
r.captureTime = time.Now()
|
||||
r.seenChunks = r.seenChunks + 1
|
||||
r.chunks <- chunk
|
||||
}
|
||||
|
||||
func (r *tlsReader) Read(p []byte) (int, error) {
|
||||
var chunk *tlsChunk
|
||||
var chunk *tlsTapperTlsChunk
|
||||
|
||||
for len(r.data) == 0 {
|
||||
var ok bool
|
||||
|
@ -12,7 +12,7 @@ import (
|
||||
|
||||
const GLOABL_TAP_PID = 0
|
||||
|
||||
//go:generate go run github.com/cilium/ebpf/cmd/bpf2go@0d0727ef53e2f53b1731c73f4c61e0f58693083a -type golang_event -type sys_close tlsTapper bpf/tls_tapper.c -- -O2 -g -D__TARGET_ARCH_x86
|
||||
//go:generate go run github.com/cilium/ebpf/cmd/bpf2go@0d0727ef53e2f53b1731c73f4c61e0f58693083a -type tls_chunk -type sys_close tlsTapper bpf/tls_tapper.c -- -O2 -g -D__TARGET_ARCH_x86
|
||||
|
||||
type TlsTapper struct {
|
||||
bpfObjects tlsTapperObjects
|
||||
@ -59,7 +59,6 @@ func (t *TlsTapper) Init(chunksBufferSize int, logBufferSize int, procfs string,
|
||||
}
|
||||
|
||||
func (t *TlsTapper) Poll(emitter api.Emitter, options *api.TrafficFilteringOptions, streamsMap api.TcpStreamMap) {
|
||||
t.poller.pollGolang(emitter, options, streamsMap)
|
||||
t.poller.pollSsllib(emitter, options, streamsMap)
|
||||
}
|
||||
|
||||
|
@ -13,29 +13,21 @@ import (
|
||||
"github.com/cilium/ebpf"
|
||||
)
|
||||
|
||||
type tlsTapperGolangEvent struct {
|
||||
Pid uint32
|
||||
Fd uint32
|
||||
ConnAddr uint32
|
||||
IsRequest bool
|
||||
_ [3]byte
|
||||
Len uint32
|
||||
Cap uint32
|
||||
Data [4096]uint8
|
||||
}
|
||||
|
||||
type tlsTapperSysClose struct{ Fd uint32 }
|
||||
|
||||
type tlsTapperTlsChunk struct {
|
||||
Pid uint32
|
||||
Tgid uint32
|
||||
Len uint32
|
||||
Start uint32
|
||||
Recorded uint32
|
||||
Fd uint32
|
||||
Flags uint32
|
||||
Address [16]uint8
|
||||
Data [4096]uint8
|
||||
Pid uint32
|
||||
Tgid uint32
|
||||
Len uint32
|
||||
Start uint32
|
||||
Recorded uint32
|
||||
Fd uint32
|
||||
Flags uint32
|
||||
Type int32
|
||||
IsRequest bool
|
||||
Address [16]uint8
|
||||
Data [4096]uint8
|
||||
_ [3]byte
|
||||
}
|
||||
|
||||
// loadTlsTapper returns the embedded CollectionSpec for tlsTapper.
|
||||
@ -109,8 +101,6 @@ type tlsTapperMapSpecs struct {
|
||||
ConnectSyscallInfo *ebpf.MapSpec `ebpf:"connect_syscall_info"`
|
||||
FileDescriptorToIpv4 *ebpf.MapSpec `ebpf:"file_descriptor_to_ipv4"`
|
||||
GolangDialToSocket *ebpf.MapSpec `ebpf:"golang_dial_to_socket"`
|
||||
GolangEvents *ebpf.MapSpec `ebpf:"golang_events"`
|
||||
GolangHeap *ebpf.MapSpec `ebpf:"golang_heap"`
|
||||
GolangSocketToWrite *ebpf.MapSpec `ebpf:"golang_socket_to_write"`
|
||||
Heap *ebpf.MapSpec `ebpf:"heap"`
|
||||
LogBuffer *ebpf.MapSpec `ebpf:"log_buffer"`
|
||||
@ -144,8 +134,6 @@ type tlsTapperMaps struct {
|
||||
ConnectSyscallInfo *ebpf.Map `ebpf:"connect_syscall_info"`
|
||||
FileDescriptorToIpv4 *ebpf.Map `ebpf:"file_descriptor_to_ipv4"`
|
||||
GolangDialToSocket *ebpf.Map `ebpf:"golang_dial_to_socket"`
|
||||
GolangEvents *ebpf.Map `ebpf:"golang_events"`
|
||||
GolangHeap *ebpf.Map `ebpf:"golang_heap"`
|
||||
GolangSocketToWrite *ebpf.Map `ebpf:"golang_socket_to_write"`
|
||||
Heap *ebpf.Map `ebpf:"heap"`
|
||||
LogBuffer *ebpf.Map `ebpf:"log_buffer"`
|
||||
@ -162,8 +150,6 @@ func (m *tlsTapperMaps) Close() error {
|
||||
m.ConnectSyscallInfo,
|
||||
m.FileDescriptorToIpv4,
|
||||
m.GolangDialToSocket,
|
||||
m.GolangEvents,
|
||||
m.GolangHeap,
|
||||
m.GolangSocketToWrite,
|
||||
m.Heap,
|
||||
m.LogBuffer,
|
||||
|
Binary file not shown.
@ -13,29 +13,21 @@ import (
|
||||
"github.com/cilium/ebpf"
|
||||
)
|
||||
|
||||
type tlsTapperGolangEvent struct {
|
||||
Pid uint32
|
||||
Fd uint32
|
||||
ConnAddr uint32
|
||||
IsRequest bool
|
||||
_ [3]byte
|
||||
Len uint32
|
||||
Cap uint32
|
||||
Data [4096]uint8
|
||||
}
|
||||
|
||||
type tlsTapperSysClose struct{ Fd uint32 }
|
||||
|
||||
type tlsTapperTlsChunk struct {
|
||||
Pid uint32
|
||||
Tgid uint32
|
||||
Len uint32
|
||||
Start uint32
|
||||
Recorded uint32
|
||||
Fd uint32
|
||||
Flags uint32
|
||||
Address [16]uint8
|
||||
Data [4096]uint8
|
||||
Pid uint32
|
||||
Tgid uint32
|
||||
Len uint32
|
||||
Start uint32
|
||||
Recorded uint32
|
||||
Fd uint32
|
||||
Flags uint32
|
||||
Type int32
|
||||
IsRequest bool
|
||||
Address [16]uint8
|
||||
Data [4096]uint8
|
||||
_ [3]byte
|
||||
}
|
||||
|
||||
// loadTlsTapper returns the embedded CollectionSpec for tlsTapper.
|
||||
@ -109,8 +101,6 @@ type tlsTapperMapSpecs struct {
|
||||
ConnectSyscallInfo *ebpf.MapSpec `ebpf:"connect_syscall_info"`
|
||||
FileDescriptorToIpv4 *ebpf.MapSpec `ebpf:"file_descriptor_to_ipv4"`
|
||||
GolangDialToSocket *ebpf.MapSpec `ebpf:"golang_dial_to_socket"`
|
||||
GolangEvents *ebpf.MapSpec `ebpf:"golang_events"`
|
||||
GolangHeap *ebpf.MapSpec `ebpf:"golang_heap"`
|
||||
GolangSocketToWrite *ebpf.MapSpec `ebpf:"golang_socket_to_write"`
|
||||
Heap *ebpf.MapSpec `ebpf:"heap"`
|
||||
LogBuffer *ebpf.MapSpec `ebpf:"log_buffer"`
|
||||
@ -144,8 +134,6 @@ type tlsTapperMaps struct {
|
||||
ConnectSyscallInfo *ebpf.Map `ebpf:"connect_syscall_info"`
|
||||
FileDescriptorToIpv4 *ebpf.Map `ebpf:"file_descriptor_to_ipv4"`
|
||||
GolangDialToSocket *ebpf.Map `ebpf:"golang_dial_to_socket"`
|
||||
GolangEvents *ebpf.Map `ebpf:"golang_events"`
|
||||
GolangHeap *ebpf.Map `ebpf:"golang_heap"`
|
||||
GolangSocketToWrite *ebpf.Map `ebpf:"golang_socket_to_write"`
|
||||
Heap *ebpf.Map `ebpf:"heap"`
|
||||
LogBuffer *ebpf.Map `ebpf:"log_buffer"`
|
||||
@ -162,8 +150,6 @@ func (m *tlsTapperMaps) Close() error {
|
||||
m.ConnectSyscallInfo,
|
||||
m.FileDescriptorToIpv4,
|
||||
m.GolangDialToSocket,
|
||||
m.GolangEvents,
|
||||
m.GolangHeap,
|
||||
m.GolangSocketToWrite,
|
||||
m.Heap,
|
||||
m.LogBuffer,
|
||||
|
Binary file not shown.
Loading…
Reference in New Issue
Block a user