Xray-core/app/router/strategy_leastping.go
yuhan6665 7c240e8630 Fix null pointer exception for observatory
Core setup router object first, when InjectContext() is called, observatory object is still null,
so observatory need to be injected after InjectContext()
2021-11-20 00:48:02 -05:00

62 lines
1.4 KiB
Go

package router
import (
"context"
"github.com/xtls/xray-core/core"
"github.com/xtls/xray-core/app/observatory"
"github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/features/extension"
)
type LeastPingStrategy struct {
ctx context.Context
observatory extension.Observatory
}
func (l *LeastPingStrategy) InjectContext(ctx context.Context) {
l.ctx = ctx
}
func (l *LeastPingStrategy) PickOutbound(strings []string) string {
if l.observatory == nil {
common.Must(core.RequireFeatures(l.ctx, func(observatory extension.Observatory) error {
l.observatory = observatory
return nil
}))
}
observeReport, err := l.observatory.GetObservation(l.ctx)
if err != nil {
newError("cannot get observe report").Base(err).WriteToLog()
return ""
}
outboundsList := outboundList(strings)
if result, ok := observeReport.(*observatory.ObservationResult); ok {
status := result.Status
leastPing := int64(99999999)
selectedOutboundName := ""
for _, v := range status {
if outboundsList.contains(v.OutboundTag) && v.Alive && v.Delay < leastPing {
selectedOutboundName = v.OutboundTag
leastPing = v.Delay
}
}
return selectedOutboundName
}
//No way to understand observeReport
return ""
}
type outboundList []string
func (o outboundList) contains(name string) bool {
for _, v := range o {
if v == name {
return true
}
}
return false
}