Merge pull request #646 from safing/fix/max-windows-table-entries

Increase supported size of windows network state table entries
This commit is contained in:
Daniel 2022-05-16 08:56:53 +02:00 committed by GitHub
commit 73e05e7c5c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 46 additions and 12 deletions

View file

@ -1,4 +1,4 @@
// +build windows //go:build windows
package iphelper package iphelper

View file

@ -1,4 +1,4 @@
// +build windows //go:build windows
package iphelper package iphelper

View file

@ -1,4 +1,4 @@
// +build windows //go:build windows
package iphelper package iphelper
@ -10,6 +10,7 @@ import (
"sync" "sync"
"unsafe" "unsafe"
"github.com/safing/portbase/log"
"github.com/safing/portmaster/network/socket" "github.com/safing/portmaster/network/socket"
"golang.org/x/sys/windows" "golang.org/x/sys/windows"
@ -28,7 +29,7 @@ const (
type iphelperTCPTable struct { type iphelperTCPTable struct {
// docs: https://msdn.microsoft.com/en-us/library/windows/desktop/aa366921(v=vs.85).aspx // docs: https://msdn.microsoft.com/en-us/library/windows/desktop/aa366921(v=vs.85).aspx
numEntries uint32 numEntries uint32
table [4096]iphelperTCPRow table [maxStateTableEntries]iphelperTCPRow
} }
type iphelperTCPRow struct { type iphelperTCPRow struct {
@ -44,7 +45,7 @@ type iphelperTCPRow struct {
type iphelperTCP6Table struct { type iphelperTCP6Table struct {
// docs: https://msdn.microsoft.com/en-us/library/windows/desktop/aa366905(v=vs.85).aspx // docs: https://msdn.microsoft.com/en-us/library/windows/desktop/aa366905(v=vs.85).aspx
numEntries uint32 numEntries uint32
table [4096]iphelperTCP6Row table [maxStateTableEntries]iphelperTCP6Row
} }
type iphelperTCP6Row struct { type iphelperTCP6Row struct {
@ -62,7 +63,7 @@ type iphelperTCP6Row struct {
type iphelperUDPTable struct { type iphelperUDPTable struct {
// docs: https://msdn.microsoft.com/en-us/library/windows/desktop/aa366932(v=vs.85).aspx // docs: https://msdn.microsoft.com/en-us/library/windows/desktop/aa366932(v=vs.85).aspx
numEntries uint32 numEntries uint32
table [4096]iphelperUDPRow table [maxStateTableEntries]iphelperUDPRow
} }
type iphelperUDPRow struct { type iphelperUDPRow struct {
@ -75,7 +76,7 @@ type iphelperUDPRow struct {
type iphelperUDP6Table struct { type iphelperUDP6Table struct {
// docs: https://msdn.microsoft.com/en-us/library/windows/desktop/aa366925(v=vs.85).aspx // docs: https://msdn.microsoft.com/en-us/library/windows/desktop/aa366925(v=vs.85).aspx
numEntries uint32 numEntries uint32
table [4096]iphelperUDP6Row table [maxStateTableEntries]iphelperUDP6Row
} }
type iphelperUDP6Row struct { type iphelperUDP6Row struct {
@ -125,6 +126,11 @@ const (
// maxBufSize is the maximum size we will allocate for responses. This was // maxBufSize is the maximum size we will allocate for responses. This was
// previously set at 65k, which was too little for some production cases. // previously set at 65k, which was too little for some production cases.
maxBufSize = 1048576 // 2^20B, 1MB 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 ( var (
@ -261,7 +267,14 @@ func (ipHelper *IPHelper) getTable(ipVersion, protocol uint8) (connections []*so
case protocol == TCP && ipVersion == IPv4: case protocol == TCP && ipVersion == IPv4:
tcpTable := (*iphelperTCPTable)(unsafe.Pointer(&buf[0])) 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 { for _, row := range table {
if row.state == iphelperTCPStateListen { if row.state == iphelperTCPStateListen {
@ -290,7 +303,14 @@ func (ipHelper *IPHelper) getTable(ipVersion, protocol uint8) (connections []*so
case protocol == TCP && ipVersion == IPv6: case protocol == TCP && ipVersion == IPv6:
tcpTable := (*iphelperTCP6Table)(unsafe.Pointer(&buf[0])) 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 { for _, row := range table {
if row.state == iphelperTCPStateListen { if row.state == iphelperTCPStateListen {
@ -319,7 +339,14 @@ func (ipHelper *IPHelper) getTable(ipVersion, protocol uint8) (connections []*so
case protocol == UDP && ipVersion == IPv4: case protocol == UDP && ipVersion == IPv4:
udpTable := (*iphelperUDPTable)(unsafe.Pointer(&buf[0])) 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 { for _, row := range table {
binds = append(binds, &socket.BindInfo{ binds = append(binds, &socket.BindInfo{
@ -334,7 +361,14 @@ func (ipHelper *IPHelper) getTable(ipVersion, protocol uint8) (connections []*so
case protocol == UDP && ipVersion == IPv6: case protocol == UDP && ipVersion == IPv6:
udpTable := (*iphelperUDP6Table)(unsafe.Pointer(&buf[0])) 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 { for _, row := range table {
binds = append(binds, &socket.BindInfo{ binds = append(binds, &socket.BindInfo{

View file

@ -1,4 +1,4 @@
// +build windows //go:build windows
package iphelper package iphelper