Skip to content

Commit

Permalink
Prevent heap allocations in FiveTuple Fingerprint
Browse files Browse the repository at this point in the history
  • Loading branch information
paulwe committed Apr 20, 2024
1 parent 4c00345 commit 5df28f1
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 5 deletions.
4 changes: 2 additions & 2 deletions internal/allocation/allocation_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ type Manager struct {
lock sync.RWMutex
log logging.LeveledLogger

allocations map[string]*Allocation
allocations map[FiveTupleFingerprint]*Allocation
reservations []*reservation

This comment has been minimized.

Copy link
@AnshulMalik

AnshulMalik May 6, 2024

Hey @paulwe , how does this prevent heap allocations, can you shed some light?


allocatePacketConn func(network string, requestedPort int) (net.PacketConn, net.Addr, error)
Expand All @@ -51,7 +51,7 @@ func NewManager(config ManagerConfig) (*Manager, error) {

return &Manager{
log: config.LeveledLogger,
allocations: make(map[string]*Allocation, 64),
allocations: make(map[FiveTupleFingerprint]*Allocation, 64),
allocatePacketConn: config.AllocatePacketConn,
allocateConn: config.AllocateConn,
permissionHandler: config.PermissionHandler,
Expand Down
30 changes: 27 additions & 3 deletions internal/allocation/five_tuple.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
package allocation

import (
"fmt"
"net"
)

Expand Down Expand Up @@ -33,7 +32,32 @@ func (f *FiveTuple) Equal(b *FiveTuple) bool {
return f.Fingerprint() == b.Fingerprint()
}

// FiveTupleFingerprint is a comparable representation of a FiveTuple
type FiveTupleFingerprint struct {
srcIP, dstIP [16]byte
srcPort, dstPort uint16
protocol Protocol
}

// Fingerprint is the identity of a FiveTuple
func (f *FiveTuple) Fingerprint() string {
return fmt.Sprintf("%d_%s_%s", f.Protocol, f.SrcAddr.String(), f.DstAddr.String())
func (f *FiveTuple) Fingerprint() (fp FiveTupleFingerprint) {
srcIP, srcPort := netAddrIPAndPort(f.SrcAddr)
copy(fp.srcIP[:], srcIP)
fp.srcPort = srcPort
dstIP, dstPort := netAddrIPAndPort(f.DstAddr)
copy(fp.dstIP[:], dstIP)
fp.dstPort = dstPort
fp.protocol = f.Protocol
return
}

func netAddrIPAndPort(addr net.Addr) (net.IP, uint16) {
switch a := addr.(type) {
case *net.UDPAddr:
return a.IP.To16(), uint16(a.Port)
case *net.TCPAddr:
return a.IP.To16(), uint16(a.Port)
default:
return nil, 0
}
}

0 comments on commit 5df28f1

Please sign in to comment.