Update network state tables if state is older than given packet

This commit is contained in:
Daniel 2023-08-18 16:52:15 +02:00
parent f3e7abf908
commit 6f9fce39bb
5 changed files with 27 additions and 5 deletions

View file

@ -48,6 +48,7 @@ func cleanConnections() (activePIDs map[int]struct{}) {
_ = module.RunMicroTask("clean connections", 0, func(ctx context.Context) error {
now := time.Now().UTC()
nowUnix := now.Unix()
ignoreNewer := nowUnix - 1
deleteOlderThan := now.Add(-DeleteConnsAfterEndedThreshold).Unix()
deleteIncompleteOlderThan := now.Add(-DeleteIncompleteConnsAfterStartedThreshold).Unix()
@ -57,6 +58,8 @@ func cleanConnections() (activePIDs map[int]struct{}) {
// delete inactive connections
switch {
case conn.Started >= ignoreNewer:
// Skip very fresh connections to evade edge cases.
case !conn.DataIsComplete():
// Step 0: delete old incomplete connections
if conn.Started < deleteIncompleteOlderThan {
@ -76,6 +79,7 @@ func cleanConnections() (activePIDs map[int]struct{}) {
Dst: conn.Entity.IP,
DstPort: conn.Entity.Port,
PID: process.UndefinedProcessID,
SeenAt: time.Unix(conn.Started, 0), // State tables will be updated if older than this.
}, now)
// Step 2: mark as ended

View file

@ -35,6 +35,11 @@ func Exists(pktInfo *packet.Info, now time.Time) (exists bool) {
}
func (table *tcpTable) exists(pktInfo *packet.Info) (exists bool) {
// Update tables if older than the connection that is checked.
if table.lastUpdateAt.Load() < pktInfo.SeenAt.UnixNano() {
table.updateTables(table.updateIter.Load())
}
table.lock.RLock()
defer table.lock.RUnlock()
@ -57,6 +62,11 @@ func (table *tcpTable) exists(pktInfo *packet.Info) (exists bool) {
}
func (table *udpTable) exists(pktInfo *packet.Info, now time.Time) (exists bool) {
// Update tables if older than the connection that is checked.
if table.lastUpdateAt.Load() < pktInfo.SeenAt.UnixNano() {
table.updateTables(table.updateIter.Load())
}
table.lock.RLock()
defer table.lock.RUnlock()

View file

@ -76,7 +76,7 @@ func (table *tcpTable) lookup(pktInfo *packet.Info, fast bool) (
// Search for the socket until found.
for i := 1; i <= lookupTries; i++ {
// Get or update tables.
if i == 1 {
if i == 1 && pktInfo.SeenAt.UnixNano() >= table.lastUpdateAt.Load() {
connections, listeners, updateIter = table.getCurrentTables()
} else {
connections, listeners, updateIter = table.updateTables(updateIter)
@ -179,7 +179,7 @@ func (table *udpTable) lookup(pktInfo *packet.Info, fast bool) (
// Search for the socket until found.
for i := 1; i <= lookupTries; i++ {
// Get or update tables.
if i == 1 {
if i == 1 && pktInfo.SeenAt.UnixNano() >= table.lastUpdateAt.Load() {
binds, updateIter = table.getCurrentTables()
} else {
binds, updateIter = table.updateTables(updateIter)

View file

@ -17,9 +17,12 @@ type tcpTable struct {
connections []*socket.ConnectionInfo
listeners []*socket.BindInfo
updateIter atomic.Uint64
lock sync.RWMutex
updateIter atomic.Uint64
// lastUpdateAt stores the time when the tables where last updated as unix nanoseconds.
lastUpdateAt atomic.Int64
fetchingLock sync.Mutex
fetchingInProgress bool
fetchingDoneSignal chan struct{}
@ -133,6 +136,7 @@ func (table *tcpTable) updateTables(previousUpdateIter uint64) (
table.connections = connections
table.listeners = listeners
table.updateIter.Add(1)
table.lastUpdateAt.Store(time.Now().UnixNano())
// Return new tables immediately.
return table.connections, table.listeners, table.updateIter.Load()

View file

@ -17,9 +17,12 @@ import (
type udpTable struct {
version int
binds []*socket.BindInfo
binds []*socket.BindInfo
lock sync.RWMutex
updateIter atomic.Uint64
lock sync.RWMutex
// lastUpdateAt stores the time when the tables where last updated as unix nanoseconds.
lastUpdateAt atomic.Int64
fetchingLock sync.Mutex
fetchingInProgress bool
@ -152,6 +155,7 @@ func (table *udpTable) updateTables(previousUpdateIter uint64) (
defer table.lock.Unlock()
table.binds = binds
table.updateIter.Add(1)
table.lastUpdateAt.Store(time.Now().UnixNano())
// Return new tables immediately.
return table.binds, table.updateIter.Load()