mirror of
https://github.com/daeuniverse/dae.git
synced 2025-07-21 13:19:10 +07:00
fix: latency comparison had potential arithmetic overflow problem
This commit is contained in:
@ -6,9 +6,11 @@
|
|||||||
package dialer
|
package dialer
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"github.com/mzz2017/softwind/pkg/fastrand"
|
"github.com/mzz2017/softwind/pkg/fastrand"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"github.com/v2rayA/dae/common/consts"
|
"github.com/v2rayA/dae/common/consts"
|
||||||
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
@ -87,6 +89,19 @@ func (a *AliveDialerSet) GetMinLatency() (d *Dialer, latency time.Duration) {
|
|||||||
return a.minLatency.dialer, a.minLatency.latency
|
return a.minLatency.dialer, a.minLatency.latency
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *AliveDialerSet) printLatencies() {
|
||||||
|
var builder strings.Builder
|
||||||
|
builder.WriteString(fmt.Sprintf("%v (%v):\n", a.dialerGroupName, a.CheckTyp.String()))
|
||||||
|
for _, d := range a.inorderedAliveDialerSet {
|
||||||
|
latency, ok := a.dialerToLatency[d]
|
||||||
|
if !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
builder.WriteString(fmt.Sprintf("%v: %v\n", d.Name(), latency.String()))
|
||||||
|
}
|
||||||
|
a.log.Traceln(builder.String())
|
||||||
|
}
|
||||||
|
|
||||||
// NotifyLatencyChange should be invoked when dialer every time latency and alive state changes.
|
// NotifyLatencyChange should be invoked when dialer every time latency and alive state changes.
|
||||||
func (a *AliveDialerSet) NotifyLatencyChange(dialer *Dialer, alive bool) {
|
func (a *AliveDialerSet) NotifyLatencyChange(dialer *Dialer, alive bool) {
|
||||||
a.mu.Lock()
|
a.mu.Lock()
|
||||||
@ -146,7 +161,9 @@ func (a *AliveDialerSet) NotifyLatencyChange(dialer *Dialer, alive bool) {
|
|||||||
bakOldBestDialer := a.minLatency.dialer
|
bakOldBestDialer := a.minLatency.dialer
|
||||||
// Calc minLatency.
|
// Calc minLatency.
|
||||||
a.dialerToLatency[dialer] = latency
|
a.dialerToLatency[dialer] = latency
|
||||||
if alive && latency <= a.minLatency.latency-a.tolerance {
|
if alive &&
|
||||||
|
latency <= a.minLatency.latency && // To avoid arithmetic overflow.
|
||||||
|
latency <= a.minLatency.latency-a.tolerance {
|
||||||
a.minLatency.latency = latency
|
a.minLatency.latency = latency
|
||||||
a.minLatency.dialer = dialer
|
a.minLatency.dialer = dialer
|
||||||
} else if a.minLatency.dialer == dialer {
|
} else if a.minLatency.dialer == dialer {
|
||||||
@ -189,6 +206,9 @@ func (a *AliveDialerSet) NotifyLatencyChange(dialer *Dialer, alive bool) {
|
|||||||
"network": a.CheckTyp.String(),
|
"network": a.CheckTyp.String(),
|
||||||
}).Infof("Group has no dialer alive")
|
}).Infof("Group has no dialer alive")
|
||||||
}
|
}
|
||||||
|
if a.log.IsLevelEnabled(logrus.TraceLevel) {
|
||||||
|
a.printLatencies()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if alive && minPolicy && a.minLatency.dialer == nil {
|
if alive && minPolicy && a.minLatency.dialer == nil {
|
||||||
@ -219,7 +239,9 @@ func (a *AliveDialerSet) calcMinLatency() {
|
|||||||
if a.minLatency.dialer == nil {
|
if a.minLatency.dialer == nil {
|
||||||
a.minLatency.latency = minLatency
|
a.minLatency.latency = minLatency
|
||||||
a.minLatency.dialer = minDialer
|
a.minLatency.dialer = minDialer
|
||||||
} else if minDialer != nil && minLatency <= a.minLatency.latency-a.tolerance {
|
} else if minDialer != nil &&
|
||||||
|
minLatency <= a.minLatency.latency && // To avoid arithmetic overflow.
|
||||||
|
minLatency <= a.minLatency.latency-a.tolerance {
|
||||||
a.minLatency.latency = minLatency
|
a.minLatency.latency = minLatency
|
||||||
a.minLatency.dialer = minDialer
|
a.minLatency.dialer = minDialer
|
||||||
}
|
}
|
||||||
|
@ -73,6 +73,7 @@ func (c *ControlPlane) handleConn(lConn net.Conn) (err error) {
|
|||||||
c.log.WithFields(logrus.Fields{
|
c.log.WithFields(logrus.Fields{
|
||||||
"network": networkType.String(),
|
"network": networkType.String(),
|
||||||
"outbound": outbound.Name,
|
"outbound": outbound.Name,
|
||||||
|
"policy": outbound.GetSelectionPolicy(),
|
||||||
"dialer": d.Name(),
|
"dialer": d.Name(),
|
||||||
}).Infof("%v <-> %v", RefineSourceToShow(src, dst.Addr(), consts.LanWanFlag_NotApplicable), RefineAddrPortToShow(dst))
|
}).Infof("%v <-> %v", RefineSourceToShow(src, dst.Addr(), consts.LanWanFlag_NotApplicable), RefineAddrPortToShow(dst))
|
||||||
rConn, err := d.Dial("tcp", dst.String())
|
rConn, err := d.Dial("tcp", dst.String())
|
||||||
|
@ -309,7 +309,7 @@ func (c *ControlPlane) handlePkt(lConn *net.UDPConn, data []byte, src, pktDst, r
|
|||||||
Target: destToSend,
|
Target: destToSend,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to GetOrCreate (%v): %w", outbound.GetSelectionPolicy(), err)
|
return fmt.Errorf("failed to GetOrCreate (policy: %v): %w", outbound.GetSelectionPolicy(), err)
|
||||||
}
|
}
|
||||||
// If the udp endpoint has been not alive, remove it from pool and get a new one.
|
// If the udp endpoint has been not alive, remove it from pool and get a new one.
|
||||||
if !isNew && !ue.Dialer.MustGetAlive(networkType) {
|
if !isNew && !ue.Dialer.MustGetAlive(networkType) {
|
||||||
@ -396,6 +396,7 @@ func (c *ControlPlane) handlePkt(lConn *net.UDPConn, data []byte, src, pktDst, r
|
|||||||
c.log.WithFields(logrus.Fields{
|
c.log.WithFields(logrus.Fields{
|
||||||
"network": string(l4proto) + string(ipversion) + "(DNS)",
|
"network": string(l4proto) + string(ipversion) + "(DNS)",
|
||||||
"outbound": outbound.Name,
|
"outbound": outbound.Name,
|
||||||
|
"policy": outbound.GetSelectionPolicy(),
|
||||||
"dialer": realDialer.Name(),
|
"dialer": realDialer.Name(),
|
||||||
"qname": strings.ToLower(q.Name.String()),
|
"qname": strings.ToLower(q.Name.String()),
|
||||||
"qtype": q.Type,
|
"qtype": q.Type,
|
||||||
@ -407,6 +408,7 @@ func (c *ControlPlane) handlePkt(lConn *net.UDPConn, data []byte, src, pktDst, r
|
|||||||
c.log.WithFields(logrus.Fields{
|
c.log.WithFields(logrus.Fields{
|
||||||
"network": string(l4proto) + string(ipversion),
|
"network": string(l4proto) + string(ipversion),
|
||||||
"outbound": outbound.Name,
|
"outbound": outbound.Name,
|
||||||
|
"policy": outbound.GetSelectionPolicy(),
|
||||||
"dialer": realDialer.Name(),
|
"dialer": realDialer.Name(),
|
||||||
}).Infof("%v <-> %v",
|
}).Infof("%v <-> %v",
|
||||||
RefineSourceToShow(realSrc, realDst.Addr(), lanWanFlag), RefineAddrPortToShow(destToSend),
|
RefineSourceToShow(realSrc, realDst.Addr(), lanWanFlag), RefineAddrPortToShow(destToSend),
|
||||||
|
Reference in New Issue
Block a user