From beefc836f6a24fc6073c77cbd41c534370b88ab9 Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 11 May 2022 13:22:25 +0200 Subject: [PATCH] Increase supported size of windows network state table entries --- network/iphelper/get.go | 2 +- network/iphelper/iphelper.go | 2 +- network/iphelper/tables.go | 52 +++++++++++++++++++++++++++------ network/iphelper/tables_test.go | 2 +- 4 files changed, 46 insertions(+), 12 deletions(-) diff --git a/network/iphelper/get.go b/network/iphelper/get.go index e92f929c..31f1c925 100644 --- a/network/iphelper/get.go +++ b/network/iphelper/get.go @@ -1,4 +1,4 @@ -// +build windows +//go:build windows package iphelper diff --git a/network/iphelper/iphelper.go b/network/iphelper/iphelper.go index 5498879a..5fa1ea12 100644 --- a/network/iphelper/iphelper.go +++ b/network/iphelper/iphelper.go @@ -1,4 +1,4 @@ -// +build windows +//go:build windows package iphelper diff --git a/network/iphelper/tables.go b/network/iphelper/tables.go index 9d59f7d7..94998d7e 100644 --- a/network/iphelper/tables.go +++ b/network/iphelper/tables.go @@ -1,4 +1,4 @@ -// +build windows +//go:build windows package iphelper @@ -10,6 +10,7 @@ import ( "sync" "unsafe" + "github.com/safing/portbase/log" "github.com/safing/portmaster/network/socket" "golang.org/x/sys/windows" @@ -28,7 +29,7 @@ const ( type iphelperTCPTable struct { // docs: https://msdn.microsoft.com/en-us/library/windows/desktop/aa366921(v=vs.85).aspx numEntries uint32 - table [4096]iphelperTCPRow + table [maxStateTableEntries]iphelperTCPRow } type iphelperTCPRow struct { @@ -44,7 +45,7 @@ type iphelperTCPRow struct { type iphelperTCP6Table struct { // docs: https://msdn.microsoft.com/en-us/library/windows/desktop/aa366905(v=vs.85).aspx numEntries uint32 - table [4096]iphelperTCP6Row + table [maxStateTableEntries]iphelperTCP6Row } type iphelperTCP6Row struct { @@ -62,7 +63,7 @@ type iphelperTCP6Row struct { type iphelperUDPTable struct { // docs: https://msdn.microsoft.com/en-us/library/windows/desktop/aa366932(v=vs.85).aspx numEntries uint32 - table [4096]iphelperUDPRow + table [maxStateTableEntries]iphelperUDPRow } type iphelperUDPRow struct { @@ -75,7 +76,7 @@ type iphelperUDPRow struct { type iphelperUDP6Table struct { // docs: https://msdn.microsoft.com/en-us/library/windows/desktop/aa366925(v=vs.85).aspx numEntries uint32 - table [4096]iphelperUDP6Row + table [maxStateTableEntries]iphelperUDP6Row } type iphelperUDP6Row struct { @@ -125,6 +126,11 @@ const ( // maxBufSize is the maximum size we will allocate for responses. This was // previously set at 65k, which was too little for some production cases. maxBufSize = 1048576 // 2^20B, 1MB + + // maxStateTableEntries is the maximum supported amount of entries of the + // state tables. + // This is never allocated, but just casted to from an unsafe pointer. + maxStateTableEntries = 65535 ) var ( @@ -261,7 +267,14 @@ func (ipHelper *IPHelper) getTable(ipVersion, protocol uint8) (connections []*so case protocol == TCP && ipVersion == IPv4: tcpTable := (*iphelperTCPTable)(unsafe.Pointer(&buf[0])) - table := tcpTable.table[:tcpTable.numEntries] + // Check if we got more entries than supported. + tableEntries := tcpTable.numEntries + if tableEntries > maxStateTableEntries { + tableEntries = maxStateTableEntries + log.Warningf("network/iphelper: received TCPv4 table with more entries than supported: %d/%d", tcpTable.numEntries, maxStateTableEntries) + } + // Cap table to actual entries. + table := tcpTable.table[:tableEntries] for _, row := range table { if row.state == iphelperTCPStateListen { @@ -290,7 +303,14 @@ func (ipHelper *IPHelper) getTable(ipVersion, protocol uint8) (connections []*so case protocol == TCP && ipVersion == IPv6: tcpTable := (*iphelperTCP6Table)(unsafe.Pointer(&buf[0])) - table := tcpTable.table[:tcpTable.numEntries] + // Check if we got more entries than supported. + tableEntries := tcpTable.numEntries + if tableEntries > maxStateTableEntries { + tableEntries = maxStateTableEntries + log.Warningf("network/iphelper: received TCPv6 table with more entries than supported: %d/%d", tcpTable.numEntries, maxStateTableEntries) + } + // Cap table to actual entries. + table := tcpTable.table[:tableEntries] for _, row := range table { if row.state == iphelperTCPStateListen { @@ -319,7 +339,14 @@ func (ipHelper *IPHelper) getTable(ipVersion, protocol uint8) (connections []*so case protocol == UDP && ipVersion == IPv4: udpTable := (*iphelperUDPTable)(unsafe.Pointer(&buf[0])) - table := udpTable.table[:udpTable.numEntries] + // Check if we got more entries than supported. + tableEntries := udpTable.numEntries + if tableEntries > maxStateTableEntries { + tableEntries = maxStateTableEntries + log.Warningf("network/iphelper: received UDPv4 table with more entries than supported: %d/%d", udpTable.numEntries, maxStateTableEntries) + } + // Cap table to actual entries. + table := udpTable.table[:tableEntries] for _, row := range table { binds = append(binds, &socket.BindInfo{ @@ -334,7 +361,14 @@ func (ipHelper *IPHelper) getTable(ipVersion, protocol uint8) (connections []*so case protocol == UDP && ipVersion == IPv6: udpTable := (*iphelperUDP6Table)(unsafe.Pointer(&buf[0])) - table := udpTable.table[:udpTable.numEntries] + // Check if we got more entries than supported. + tableEntries := udpTable.numEntries + if tableEntries > maxStateTableEntries { + tableEntries = maxStateTableEntries + log.Warningf("network/iphelper: received UDPv6 table with more entries than supported: %d/%d", udpTable.numEntries, maxStateTableEntries) + } + // Cap table to actual entries. + table := udpTable.table[:tableEntries] for _, row := range table { binds = append(binds, &socket.BindInfo{ diff --git a/network/iphelper/tables_test.go b/network/iphelper/tables_test.go index e996219e..9b8c48f5 100644 --- a/network/iphelper/tables_test.go +++ b/network/iphelper/tables_test.go @@ -1,4 +1,4 @@ -// +build windows +//go:build windows package iphelper