Add RemoteCandidateCache for better performance

Check sourceAddress from first packet validation of STUNTraffic.
If validation is true, store it in the cache.
Use cache for performance.
This commit is contained in:
San9H0
2023-04-18 19:20:52 +02:00
committed by Steffen Vogel
parent 5ef81b65f4
commit f07b6d16ad
7 changed files with 61 additions and 17 deletions
+21 -1
View File
@@ -3,7 +3,9 @@
package ice
import "net"
import (
"net"
)
func parseMulticastAnswerAddr(in net.Addr) (net.IP, bool) {
switch addr := in.(type) {
@@ -49,3 +51,21 @@ func addrEqual(a, b net.Addr) bool {
return aType == bType && aIP.Equal(bIP) && aPort == bPort
}
// AddrPort is an IP and a port number.
type AddrPort [18]byte
func toAddrPort(addr net.Addr) AddrPort {
var ap AddrPort
switch addr := addr.(type) {
case *net.UDPAddr:
copy(ap[:16], addr.IP.To16())
ap[16] = uint8(addr.Port >> 8)
ap[17] = uint8(addr.Port)
case *net.TCPAddr:
copy(ap[:16], addr.IP.To16())
ap[16] = uint8(addr.Port >> 8)
ap[17] = uint8(addr.Port)
}
return ap
}
+4 -5
View File
@@ -1138,19 +1138,18 @@ func (a *Agent) handleInbound(m *stun.Message, local Candidate, remote net.Addr)
// validateNonSTUNTraffic processes non STUN traffic from a remote candidate,
// and returns true if it is an actual remote candidate
func (a *Agent) validateNonSTUNTraffic(local Candidate, remote net.Addr) bool {
var isValidCandidate uint64
func (a *Agent) validateNonSTUNTraffic(local Candidate, remote net.Addr) (Candidate, bool) {
var remoteCandidate Candidate
if err := a.run(local.context(), func(ctx context.Context, agent *Agent) {
remoteCandidate := a.findRemoteCandidate(local.NetworkType(), remote)
remoteCandidate = a.findRemoteCandidate(local.NetworkType(), remote)
if remoteCandidate != nil {
remoteCandidate.seen(false)
atomic.AddUint64(&isValidCandidate, 1)
}
}); err != nil {
a.log.Warnf("failed to validate remote candidate: %v", err)
}
return atomic.LoadUint64(&isValidCandidate) == 1
return remoteCandidate, remoteCandidate != nil
}
// GetSelectedCandidatePair returns the selected pair or nil if there is none
+24 -3
View File
@@ -41,6 +41,8 @@ type candidateBase struct {
foundationOverride string
priorityOverride uint32
remoteCandidateCaches map[AddrPort]Candidate
}
// Done implements context.Context
@@ -234,6 +236,21 @@ func (c *candidateBase) recvLoop(initializedCh <-chan struct{}) {
}
}
func (c *candidateBase) validateSTUNTrafficCache(addr net.Addr) bool {
if candidate, ok := c.remoteCandidateCaches[toAddrPort(addr)]; ok {
candidate.seen(false)
return true
}
return false
}
func (c *candidateBase) addRemoteCandidateCache(candidate Candidate, srcAddr net.Addr) {
if c.validateSTUNTrafficCache(srcAddr) {
return
}
c.remoteCandidateCaches[toAddrPort(srcAddr)] = candidate
}
func (c *candidateBase) handleInboundPacket(buf []byte, srcAddr net.Addr) {
a := c.agent()
@@ -259,9 +276,13 @@ func (c *candidateBase) handleInboundPacket(buf []byte, srcAddr net.Addr) {
return
}
if !a.validateNonSTUNTraffic(c, srcAddr) { //nolint:contextcheck
a.log.Warnf("Discarded message from %s, not a valid remote candidate", c.addr())
return
if !c.validateSTUNTrafficCache(srcAddr) {
remoteCandidate, valid := a.validateNonSTUNTraffic(c, srcAddr) //nolint:contextcheck
if !valid {
a.log.Warnf("Discarded message from %s, not a valid remote candidate", c.addr())
return
}
c.addRemoteCandidateCache(remoteCandidate, srcAddr)
}
// Note: This will return packetio.ErrFull if the buffer ever manages to fill up.
+9 -8
View File
@@ -37,14 +37,15 @@ func NewCandidateHost(config *CandidateHostConfig) (*CandidateHost, error) {
c := &CandidateHost{
candidateBase: candidateBase{
id: candidateID,
address: config.Address,
candidateType: CandidateTypeHost,
component: config.Component,
port: config.Port,
tcpType: config.TCPType,
foundationOverride: config.Foundation,
priorityOverride: config.Priority,
id: candidateID,
address: config.Address,
candidateType: CandidateTypeHost,
component: config.Component,
port: config.Port,
tcpType: config.TCPType,
foundationOverride: config.Foundation,
priorityOverride: config.Priority,
remoteCandidateCaches: map[AddrPort]Candidate{},
},
network: config.Network,
}
+1
View File
@@ -59,6 +59,7 @@ func NewCandidatePeerReflexive(config *CandidatePeerReflexiveConfig) (*Candidate
Address: config.RelAddr,
Port: config.RelPort,
},
remoteCandidateCaches: map[AddrPort]Candidate{},
},
}, nil
}
+1
View File
@@ -63,6 +63,7 @@ func NewCandidateRelay(config *CandidateRelayConfig) (*CandidateRelay, error) {
Address: config.RelAddr,
Port: config.RelPort,
},
remoteCandidateCaches: map[AddrPort]Candidate{},
},
relayProtocol: config.RelayProtocol,
onClose: config.OnClose,
+1
View File
@@ -55,6 +55,7 @@ func NewCandidateServerReflexive(config *CandidateServerReflexiveConfig) (*Candi
Address: config.RelAddr,
Port: config.RelPort,
},
remoteCandidateCaches: map[AddrPort]Candidate{},
},
}, nil
}