mirror of
https://github.com/XTLS/Xray-core.git
synced 2024-11-10 02:53:11 +00:00
7c240e8630
Core setup router object first, when InjectContext() is called, observatory object is still null, so observatory need to be injected after InjectContext()
62 lines
1.4 KiB
Go
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
|
|
}
|