Unify Golang and OpenSSL under a single perf event buffer and tls_chunk struct

This commit is contained in:
M. Mert Yildiran 2022-06-07 16:35:16 +03:00
parent bab23303ae
commit 71c4b592e8
No known key found for this signature in database
GPG Key ID: D42ADB236521BF7A
11 changed files with 157 additions and 236 deletions

View File

@ -11,13 +11,6 @@ Copyright (C) UP9 Inc.
#include "include/logger_messages.h" #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") SEC("uprobe/golang_crypto_tls_write")
static __always_inline int golang_crypto_tls_write_uprobe(struct pt_regs *ctx) { static __always_inline int golang_crypto_tls_write_uprobe(struct pt_regs *ctx) {
__u64 pid_tgid = bpf_get_current_pid_tgid(); __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; return 0;
} }
struct golang_event *event = NULL; struct tls_chunk *chunk = NULL;
int zero = 0; 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); log_error(ctx, LOG_ERROR_GOLANG_ALLOCATING_EVENT, pid, 0l, 0l);
return 0; return 0;
} }
event->pid = pid; chunk->type = Golang_type;
event->fd = s->fd; chunk->pid = pid;
chunk->fd = s->fd;
// ctx->rsi is common between golang_crypto_tls_write_uprobe and golang_crypto_tls_read_uprobe // 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 chunk->flags = ctx->rsi; // go.itab.*net.TCPConn,net.Conn address
event->is_request = true; chunk->is_request = true;
event->len = ctx->rcx; chunk->len = ctx->rcx;
event->cap = ctx->rdi;
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) { if (status < 0) {
log_error(ctx, LOG_ERROR_GOLANG_WRITE_READING_DATA, pid_tgid, status, 0l); log_error(ctx, LOG_ERROR_GOLANG_WRITE_READING_DATA, pid_tgid, status, 0l);
return 0; 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; return 0;
} }
@ -88,30 +81,30 @@ static __always_inline int golang_crypto_tls_read_uprobe(struct pt_regs *ctx) {
return 0; return 0;
} }
struct golang_event *event = NULL; struct tls_chunk *chunk = NULL;
int zero = 0; 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); log_error(ctx, LOG_ERROR_GOLANG_ALLOCATING_EVENT, pid, 0l, 0l);
return 0; 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 // 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 chunk->flags = ctx->rsi; // go.itab.*net.TCPConn,net.Conn address
event->is_request = false; chunk->is_request = false;
event->len = ctx->rcx; chunk->len = ctx->rcx;
event->cap = ctx->rcx; // no cap info
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) { if (status < 0) {
log_error(ctx, LOG_ERROR_GOLANG_READ_READING_DATA, pid_tgid, status, 0l); log_error(ctx, LOG_ERROR_GOLANG_READ_READING_DATA, pid_tgid, status, 0l);
return 0; 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; return 0;
} }

View File

@ -21,11 +21,16 @@ Copyright (C) UP9 Inc.
#define MAX_ENTRIES_LRU_HASH (1 << 14) // 16384 #define MAX_ENTRIES_LRU_HASH (1 << 14) // 16384
#define MAX_ENTRIES_RINGBUFF (1 << 24) // 16777216 #define MAX_ENTRIES_RINGBUFF (1 << 24) // 16777216
enum ChunkType {
OpenSSL_type=1,
Golang_type=2,
};
// The same struct can be found in chunk.go // The same struct can be found in chunk.go
// //
// Be careful when editing, alignment and padding should be exactly the same in go/c. // Be careful when editing, alignment and padding should be exactly the same in go/c.
// //
struct tlsChunk { struct tls_chunk {
__u32 pid; __u32 pid;
__u32 tgid; __u32 tgid;
__u32 len; __u32 len;
@ -33,6 +38,8 @@ struct tlsChunk {
__u32 recorded; __u32 recorded;
__u32 fd; __u32 fd;
__u32 flags; __u32 flags;
enum ChunkType type;
bool is_request;
__u8 address[16]; __u8 address[16];
__u8 data[CHUNK_SIZE]; // Must be N^2 __u8 data[CHUNK_SIZE]; // Must be N^2
}; };
@ -64,20 +71,20 @@ struct golang_socket {
__u64 conn_addr; __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 golang_event *unused1 __attribute__((unused));
const struct sys_close *unused2 __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) \ #define BPF_MAP(_name, _type, _key_type, _value_type, _max_entries) \
struct bpf_map_def SEC("maps") _name = { \ struct bpf_map_def SEC("maps") _name = { \
.type = _type, \ .type = _type, \
@ -99,16 +106,15 @@ const struct sys_close *unused2 __attribute__((unused));
BPF_HASH(pids_map, __u32, __u32); BPF_HASH(pids_map, __u32, __u32);
BPF_PERF_OUTPUT(log_buffer); BPF_PERF_OUTPUT(log_buffer);
BPF_PERF_OUTPUT(sys_closes); BPF_PERF_OUTPUT(sys_closes);
BPF_PERF_OUTPUT(chunks_buffer);
// OpenSSL specific // OpenSSL specific
BPF_LRU_HASH(ssl_write_context, __u64, struct ssl_info); BPF_LRU_HASH(ssl_write_context, __u64, struct ssl_info);
BPF_LRU_HASH(ssl_read_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_LRU_HASH(file_descriptor_to_ipv4, __u64, struct fd_info);
BPF_PERF_OUTPUT(chunks_buffer);
// Golang specific // Golang specific
BPF_LRU_HASH(golang_dial_to_socket, __u64, struct golang_socket); BPF_LRU_HASH(golang_dial_to_socket, __u64, struct golang_socket);
BPF_LRU_HASH(golang_socket_to_write, __u64, struct golang_socket); BPF_LRU_HASH(golang_socket_to_write, __u64, struct golang_socket);
BPF_PERF_OUTPUT(golang_events);
#endif /* __MAPS__ */ #endif /* __MAPS__ */

View File

@ -11,14 +11,6 @@ Copyright (C) UP9 Inc.
#include "include/logger_messages.h" #include "include/logger_messages.h"
#include "include/pids.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) { static __always_inline int get_count_bytes(struct pt_regs *ctx, struct ssl_info* info, __u64 id) {
int returnValue = PT_REGS_RC(ctx); 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; 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; __u32 pid = id >> 32;
__u64 key = (__u64) pid << 32 | fd; __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, 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)); size_t recorded = MIN(end - start, sizeof(chunk->data));
if (recorded <= 0) { if (recorded <= 0) {
@ -95,10 +87,10 @@ static __always_inline void send_chunk_part(struct pt_regs *ctx, __u8* buffer, _
return; 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) // ebpf loops must be bounded at compile time, we can't use (i < chunk->len / CHUNK_SIZE)
// //
// https://lwn.net/Articles/794934/ // https://lwn.net/Articles/794934/
@ -127,7 +119,7 @@ static __always_inline void output_ssl_chunk(struct pt_regs *ctx, struct ssl_inf
return; return;
} }
struct tlsChunk* chunk; struct tls_chunk* chunk;
int zero = 0; int zero = 0;
// If other thread, running on the same CPU get to this point at the same time like us (context switch) // 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; return;
} }
chunk->type = OpenSSL_type;
chunk->flags = flags; chunk->flags = flags;
chunk->pid = id >> 32; chunk->pid = id >> 32;
chunk->tgid = id; chunk->tgid = id;

View File

@ -12,23 +12,7 @@ import (
const FLAGS_IS_CLIENT_BIT uint32 = (1 << 0) const FLAGS_IS_CLIENT_BIT uint32 = (1 << 0)
const FLAGS_IS_READ_BIT uint32 = (1 << 1) const FLAGS_IS_READ_BIT uint32 = (1 << 1)
// The same struct can be found in maps.h func (c *tlsTapperTlsChunk) getAddress() (net.IP, uint16, error) {
//
// 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) {
address := bytes.NewReader(c.Address[:]) address := bytes.NewReader(c.Address[:])
var family uint16 var family uint16
var port uint16 var port uint16
@ -51,31 +35,31 @@ func (c *tlsChunk) getAddress() (net.IP, uint16, error) {
return ip, port, nil return ip, port, nil
} }
func (c *tlsChunk) isClient() bool { func (c *tlsTapperTlsChunk) isClient() bool {
return c.Flags&FLAGS_IS_CLIENT_BIT != 0 return c.Flags&FLAGS_IS_CLIENT_BIT != 0
} }
func (c *tlsChunk) isServer() bool { func (c *tlsTapperTlsChunk) isServer() bool {
return !c.isClient() return !c.isClient()
} }
func (c *tlsChunk) isRead() bool { func (c *tlsTapperTlsChunk) isRead() bool {
return c.Flags&FLAGS_IS_READ_BIT != 0 return c.Flags&FLAGS_IS_READ_BIT != 0
} }
func (c *tlsChunk) isWrite() bool { func (c *tlsTapperTlsChunk) isWrite() bool {
return !c.isRead() return !c.isRead()
} }
func (c *tlsChunk) getRecordedData() []byte { func (c *tlsTapperTlsChunk) getRecordedData() []byte {
return c.Data[:c.Recorded] return c.Data[:c.Recorded]
} }
func (c *tlsChunk) isRequest() bool { func (c *tlsTapperTlsChunk) isRequest() bool {
return (c.isClient() && c.isWrite()) || (c.isServer() && c.isRead()) 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() ip, port, err := c.getAddress()
if err != nil { if err != nil {

View File

@ -4,7 +4,6 @@ import (
"bufio" "bufio"
"bytes" "bytes"
"fmt" "fmt"
"log"
"sync" "sync"
"time" "time"
"unsafe" "unsafe"
@ -75,12 +74,6 @@ func (p *tlsPoller) init(bpfObjects *tlsTapperObjects, bufferSize int) error {
return errors.Wrap(err, 0) 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) p.sysCloses, err = perf.NewReader(bpfObjects.SysCloses, bufferSize)
if err != nil { 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) { 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.pollChunksPerfBuffer(chunks)
go p.pollSysClose(p.sysCloses)
for { for {
select { select {
@ -108,53 +103,32 @@ func (p *tlsPoller) pollSsllib(emitter api.Emitter, options *api.TrafficFilterin
return return
} }
if err := p.handleTlsChunk(chunk, p.extension, emitter, options, streamsMap); err != nil { switch chunk.Type {
case 1:
if err := p.handleOpenSslTlsChunk(chunk, p.extension, emitter, options, streamsMap); err != nil {
LogError(err) LogError(err)
} }
case 2:
if err := p.handleGolangTlsChunk(chunk, emitter, options, streamsMap); err != nil {
LogError(err)
}
}
case key := <-p.closedReaders: case key := <-p.closedReaders:
delete(p.readers, key) delete(p.readers, key)
} }
} }
} }
func (p *tlsPoller) pollGolang(emitter api.Emitter, options *api.TrafficFilteringOptions, streamsMap api.TcpStreamMap) { func (p *tlsPoller) handleGolangTlsChunk(chunk *tlsTapperTlsChunk, emitter api.Emitter, options *api.TrafficFilteringOptions,
go p.pollGolangReadWrite(p.golangReader, emitter, options, streamsMap) streamsMap api.TcpStreamMap) error {
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 { if p.golangConnectionMap.Len()+1 > golangMapLimit {
pair := p.golangConnectionMap.Oldest() pair := p.golangConnectionMap.Oldest()
pair.Value.(*golangConnection).close() pair.Value.(*golangConnection).close()
p.golangConnectionMap.Delete(pair.Key) p.golangConnectionMap.Delete(pair.Key)
} }
pid := uint64(b.Pid) pid := uint64(chunk.Pid)
identifier := pid<<32 + uint64(b.ConnAddr) identifier := pid<<32 + uint64(chunk.Flags)
var connection *golangConnection var connection *golangConnection
var _connection interface{} var _connection interface{}
@ -162,23 +136,22 @@ func (p *tlsPoller) pollGolangReadWrite(rd *perf.Reader, emitter api.Emitter, op
if _connection, ok = p.golangConnectionMap.Get(identifier); !ok { if _connection, ok = p.golangConnectionMap.Get(identifier); !ok {
tlsEmitter := &tlsEmitter{ tlsEmitter := &tlsEmitter{
delegate: emitter, delegate: emitter,
namespace: p.getNamespace(b.Pid), namespace: p.getNamespace(chunk.Pid),
} }
connection = NewGolangConnection(b.Pid, b.ConnAddr, p.extension, tlsEmitter) connection = NewGolangConnection(chunk.Pid, chunk.Flags, p.extension, tlsEmitter)
p.golangConnectionMap.Set(identifier, connection) p.golangConnectionMap.Set(identifier, connection)
streamsMap.Store(streamsMap.NextId(), connection.stream) streamsMap.Store(streamsMap.NextId(), connection.stream)
} else { } else {
connection = _connection.(*golangConnection) connection = _connection.(*golangConnection)
} }
if b.IsRequest { if chunk.IsRequest {
connection.fd = b.Fd connection.fd = chunk.Fd
err := connection.setAddressBySockfd(p.procfs, b.Pid, b.Fd) err := connection.setAddressBySockfd(p.procfs, chunk.Pid, chunk.Fd)
if err != nil { if err != nil {
log.Printf("Error resolving address pair from fd: %s", err) return fmt.Errorf("Error resolving address pair from fd: %s", err)
continue
} }
tcpid := p.buildTcpId(&connection.addressPair) tcpid := p.buildTcpId(&connection.addressPair)
@ -193,15 +166,16 @@ func (p *tlsPoller) pollGolangReadWrite(rd *perf.Reader, emitter api.Emitter, op
go dissect(p.extension, connection.clientReader, options) go dissect(p.extension, connection.clientReader, options)
go dissect(p.extension, connection.serverReader, options) go dissect(p.extension, connection.serverReader, options)
request := make([]byte, len(b.Data[:b.Len])) request := make([]byte, len(chunk.Data[:chunk.Len]))
copy(request, b.Data[:b.Len]) copy(request, chunk.Data[:chunk.Len])
connection.clientReader.send(request) connection.clientReader.send(request)
} else { } else {
response := make([]byte, len(b.Data[:b.Len])) response := make([]byte, len(chunk.Data[:chunk.Len]))
copy(response, b.Data[:b.Len]) copy(response, chunk.Data[:chunk.Len])
connection.serverReader.send(response) connection.serverReader.send(response)
} }
}
return nil
} }
func (p *tlsPoller) pollSysClose(rd *perf.Reader) { 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") logger.Log.Infof("Start polling for tls events")
for { for {
@ -263,7 +237,7 @@ func (p *tlsPoller) pollChunksPerfBuffer(chunks chan<- *tlsChunk) {
buffer := bytes.NewReader(record.RawSample) buffer := bytes.NewReader(record.RawSample)
var chunk tlsChunk var chunk tlsTapperTlsChunk
if err := binary.Read(buffer, binary.LittleEndian, &chunk); err != nil { if err := binary.Read(buffer, binary.LittleEndian, &chunk); err != nil {
LogError(errors.Errorf("Error parsing chunk %v", err)) 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 { options *api.TrafficFilteringOptions, streamsMap api.TcpStreamMap) error {
address, err := p.getSockfdAddressPair(chunk) address, err := p.getSockfdAddressPair(chunk)
@ -303,7 +277,7 @@ func (p *tlsPoller) handleTlsChunk(chunk *tlsChunk, extension *api.Extension, em
return nil 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, emitter api.Emitter, extension *api.Extension, options *api.TrafficFilteringOptions,
streamsMap api.TcpStreamMap) *tlsReader { streamsMap api.TcpStreamMap) *tlsReader {
@ -320,7 +294,7 @@ func (p *tlsPoller) startNewTlsReader(chunk *tlsChunk, address *addressPair, key
reader := &tlsReader{ reader := &tlsReader{
key: key, key: key,
chunks: make(chan *tlsChunk, 1), chunks: make(chan *tlsTapperTlsChunk, 1),
doneHandler: doneHandler, doneHandler: doneHandler,
progress: &api.ReadProgress{}, progress: &api.ReadProgress{},
tcpID: &tcpid, tcpID: &tcpid,
@ -358,7 +332,7 @@ func (p *tlsPoller) closeReader(key string, r *tlsReader) {
p.closedReaders <- key 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) address, err := getAddressBySockfd(p.procfs, chunk.Pid, chunk.Fd)
fdCacheKey := fmt.Sprintf("%d:%d", 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 var flagsStr string
if chunk.isClient() { if chunk.isClient() {

View File

@ -9,7 +9,7 @@ import (
type tlsReader struct { type tlsReader struct {
key string key string
chunks chan *tlsChunk chunks chan *tlsTapperTlsChunk
seenChunks int seenChunks int
data []byte data []byte
doneHandler func(r *tlsReader) doneHandler func(r *tlsReader)
@ -24,14 +24,14 @@ type tlsReader struct {
reqResMatcher api.RequestResponseMatcher reqResMatcher api.RequestResponseMatcher
} }
func (r *tlsReader) newChunk(chunk *tlsChunk) { func (r *tlsReader) newChunk(chunk *tlsTapperTlsChunk) {
r.captureTime = time.Now() r.captureTime = time.Now()
r.seenChunks = r.seenChunks + 1 r.seenChunks = r.seenChunks + 1
r.chunks <- chunk r.chunks <- chunk
} }
func (r *tlsReader) Read(p []byte) (int, error) { func (r *tlsReader) Read(p []byte) (int, error) {
var chunk *tlsChunk var chunk *tlsTapperTlsChunk
for len(r.data) == 0 { for len(r.data) == 0 {
var ok bool var ok bool

View File

@ -12,7 +12,7 @@ import (
const GLOABL_TAP_PID = 0 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 { type TlsTapper struct {
bpfObjects tlsTapperObjects 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) { 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) t.poller.pollSsllib(emitter, options, streamsMap)
} }

View File

@ -13,17 +13,6 @@ import (
"github.com/cilium/ebpf" "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 tlsTapperSysClose struct{ Fd uint32 }
type tlsTapperTlsChunk struct { type tlsTapperTlsChunk struct {
@ -34,8 +23,11 @@ type tlsTapperTlsChunk struct {
Recorded uint32 Recorded uint32
Fd uint32 Fd uint32
Flags uint32 Flags uint32
Type int32
IsRequest bool
Address [16]uint8 Address [16]uint8
Data [4096]uint8 Data [4096]uint8
_ [3]byte
} }
// loadTlsTapper returns the embedded CollectionSpec for tlsTapper. // loadTlsTapper returns the embedded CollectionSpec for tlsTapper.
@ -109,8 +101,6 @@ type tlsTapperMapSpecs struct {
ConnectSyscallInfo *ebpf.MapSpec `ebpf:"connect_syscall_info"` ConnectSyscallInfo *ebpf.MapSpec `ebpf:"connect_syscall_info"`
FileDescriptorToIpv4 *ebpf.MapSpec `ebpf:"file_descriptor_to_ipv4"` FileDescriptorToIpv4 *ebpf.MapSpec `ebpf:"file_descriptor_to_ipv4"`
GolangDialToSocket *ebpf.MapSpec `ebpf:"golang_dial_to_socket"` 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"` GolangSocketToWrite *ebpf.MapSpec `ebpf:"golang_socket_to_write"`
Heap *ebpf.MapSpec `ebpf:"heap"` Heap *ebpf.MapSpec `ebpf:"heap"`
LogBuffer *ebpf.MapSpec `ebpf:"log_buffer"` LogBuffer *ebpf.MapSpec `ebpf:"log_buffer"`
@ -144,8 +134,6 @@ type tlsTapperMaps struct {
ConnectSyscallInfo *ebpf.Map `ebpf:"connect_syscall_info"` ConnectSyscallInfo *ebpf.Map `ebpf:"connect_syscall_info"`
FileDescriptorToIpv4 *ebpf.Map `ebpf:"file_descriptor_to_ipv4"` FileDescriptorToIpv4 *ebpf.Map `ebpf:"file_descriptor_to_ipv4"`
GolangDialToSocket *ebpf.Map `ebpf:"golang_dial_to_socket"` 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"` GolangSocketToWrite *ebpf.Map `ebpf:"golang_socket_to_write"`
Heap *ebpf.Map `ebpf:"heap"` Heap *ebpf.Map `ebpf:"heap"`
LogBuffer *ebpf.Map `ebpf:"log_buffer"` LogBuffer *ebpf.Map `ebpf:"log_buffer"`
@ -162,8 +150,6 @@ func (m *tlsTapperMaps) Close() error {
m.ConnectSyscallInfo, m.ConnectSyscallInfo,
m.FileDescriptorToIpv4, m.FileDescriptorToIpv4,
m.GolangDialToSocket, m.GolangDialToSocket,
m.GolangEvents,
m.GolangHeap,
m.GolangSocketToWrite, m.GolangSocketToWrite,
m.Heap, m.Heap,
m.LogBuffer, m.LogBuffer,

Binary file not shown.

View File

@ -13,17 +13,6 @@ import (
"github.com/cilium/ebpf" "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 tlsTapperSysClose struct{ Fd uint32 }
type tlsTapperTlsChunk struct { type tlsTapperTlsChunk struct {
@ -34,8 +23,11 @@ type tlsTapperTlsChunk struct {
Recorded uint32 Recorded uint32
Fd uint32 Fd uint32
Flags uint32 Flags uint32
Type int32
IsRequest bool
Address [16]uint8 Address [16]uint8
Data [4096]uint8 Data [4096]uint8
_ [3]byte
} }
// loadTlsTapper returns the embedded CollectionSpec for tlsTapper. // loadTlsTapper returns the embedded CollectionSpec for tlsTapper.
@ -109,8 +101,6 @@ type tlsTapperMapSpecs struct {
ConnectSyscallInfo *ebpf.MapSpec `ebpf:"connect_syscall_info"` ConnectSyscallInfo *ebpf.MapSpec `ebpf:"connect_syscall_info"`
FileDescriptorToIpv4 *ebpf.MapSpec `ebpf:"file_descriptor_to_ipv4"` FileDescriptorToIpv4 *ebpf.MapSpec `ebpf:"file_descriptor_to_ipv4"`
GolangDialToSocket *ebpf.MapSpec `ebpf:"golang_dial_to_socket"` 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"` GolangSocketToWrite *ebpf.MapSpec `ebpf:"golang_socket_to_write"`
Heap *ebpf.MapSpec `ebpf:"heap"` Heap *ebpf.MapSpec `ebpf:"heap"`
LogBuffer *ebpf.MapSpec `ebpf:"log_buffer"` LogBuffer *ebpf.MapSpec `ebpf:"log_buffer"`
@ -144,8 +134,6 @@ type tlsTapperMaps struct {
ConnectSyscallInfo *ebpf.Map `ebpf:"connect_syscall_info"` ConnectSyscallInfo *ebpf.Map `ebpf:"connect_syscall_info"`
FileDescriptorToIpv4 *ebpf.Map `ebpf:"file_descriptor_to_ipv4"` FileDescriptorToIpv4 *ebpf.Map `ebpf:"file_descriptor_to_ipv4"`
GolangDialToSocket *ebpf.Map `ebpf:"golang_dial_to_socket"` 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"` GolangSocketToWrite *ebpf.Map `ebpf:"golang_socket_to_write"`
Heap *ebpf.Map `ebpf:"heap"` Heap *ebpf.Map `ebpf:"heap"`
LogBuffer *ebpf.Map `ebpf:"log_buffer"` LogBuffer *ebpf.Map `ebpf:"log_buffer"`
@ -162,8 +150,6 @@ func (m *tlsTapperMaps) Close() error {
m.ConnectSyscallInfo, m.ConnectSyscallInfo,
m.FileDescriptorToIpv4, m.FileDescriptorToIpv4,
m.GolangDialToSocket, m.GolangDialToSocket,
m.GolangEvents,
m.GolangHeap,
m.GolangSocketToWrite, m.GolangSocketToWrite,
m.Heap, m.Heap,
m.LogBuffer, m.LogBuffer,

Binary file not shown.