kubeshark/tap/tlstapper/chunk.go
David Levanon 57f8a8dca9
Feature/fix tls not listening (#1046)
* avoid chunks with invalid address

* tls tapper should distict between pids

* prettfy tls verbose log and tls key

* support tls from multi threads + duplicate calls to the same target

* introduce fdCache and user address pair as tls key

* remove unused comment

* fix merge conflicts

* use lru for fdcache

* pr fixes - renaming

* fix conflict issue
2022-05-02 21:33:26 +03:00

101 lines
2.4 KiB
Go

package tlstapper
import (
"bytes"
"encoding/binary"
"net"
"github.com/go-errors/errors"
"github.com/up9inc/mizu/tap/api"
)
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) {
address := bytes.NewReader(c.Address[:])
var family uint16
var port uint16
var ip32 uint32
if err := binary.Read(address, binary.BigEndian, &family); err != nil {
return nil, 0, errors.Wrap(err, 0)
}
if err := binary.Read(address, binary.BigEndian, &port); err != nil {
return nil, 0, errors.Wrap(err, 0)
}
if err := binary.Read(address, binary.BigEndian, &ip32); err != nil {
return nil, 0, errors.Wrap(err, 0)
}
ip := net.IP{uint8(ip32 >> 24), uint8(ip32 >> 16), uint8(ip32 >> 8), uint8(ip32)}
return ip, port, nil
}
func (c *tlsChunk) isClient() bool {
return c.Flags&FLAGS_IS_CLIENT_BIT != 0
}
func (c *tlsChunk) isServer() bool {
return !c.isClient()
}
func (c *tlsChunk) isRead() bool {
return c.Flags&FLAGS_IS_READ_BIT != 0
}
func (c *tlsChunk) isWrite() bool {
return !c.isRead()
}
func (c *tlsChunk) getRecordedData() []byte {
return c.Data[:c.Recorded]
}
func (c *tlsChunk) isRequest() bool {
return (c.isClient() && c.isWrite()) || (c.isServer() && c.isRead())
}
func (c *tlsChunk) getAddressPair() (addressPair, error) {
ip, port, err := c.getAddress()
if err != nil {
return addressPair{}, err
}
if c.isRequest() {
return addressPair{
srcIp: api.UnknownIp,
srcPort: api.UnknownPort,
dstIp: ip,
dstPort: port,
}, nil
} else {
return addressPair{
srcIp: ip,
srcPort: port,
dstIp: api.UnknownIp,
dstPort: api.UnknownPort,
}, nil
}
}