sing-box/experimental/libbox/command_urltest.go

90 lines
2.4 KiB
Go
Raw Normal View History

2023-07-02 16:45:30 +08:00
package libbox
import (
"encoding/binary"
"net"
"time"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/common/urltest"
2024-11-02 00:39:02 +08:00
"github.com/sagernet/sing-box/protocol/group"
2023-07-02 16:45:30 +08:00
"github.com/sagernet/sing/common"
"github.com/sagernet/sing/common/batch"
E "github.com/sagernet/sing/common/exceptions"
2024-06-24 09:49:15 +08:00
"github.com/sagernet/sing/common/varbin"
2023-11-28 12:00:28 +08:00
"github.com/sagernet/sing/service"
2023-07-02 16:45:30 +08:00
)
func (c *CommandClient) URLTest(groupTag string) error {
conn, err := c.directConnect()
if err != nil {
return err
}
defer conn.Close()
err = binary.Write(conn, binary.BigEndian, uint8(CommandURLTest))
if err != nil {
return err
}
2024-06-24 09:49:15 +08:00
err = varbin.Write(conn, binary.BigEndian, groupTag)
2023-07-02 16:45:30 +08:00
if err != nil {
return err
}
return readError(conn)
}
func (s *CommandServer) handleURLTest(conn net.Conn) error {
2024-06-24 09:49:15 +08:00
groupTag, err := varbin.ReadValue[string](conn, binary.BigEndian)
2023-07-02 16:45:30 +08:00
if err != nil {
return err
}
2023-11-28 12:00:28 +08:00
serviceNow := s.service
if serviceNow == nil {
2023-07-02 16:45:30 +08:00
return nil
}
2023-11-28 12:00:28 +08:00
abstractOutboundGroup, isLoaded := serviceNow.instance.Router().Outbound(groupTag)
2023-07-02 16:45:30 +08:00
if !isLoaded {
return writeError(conn, E.New("outbound group not found: ", groupTag))
}
outboundGroup, isOutboundGroup := abstractOutboundGroup.(adapter.OutboundGroup)
if !isOutboundGroup {
return writeError(conn, E.New("outbound is not a group: ", groupTag))
}
2024-11-02 00:39:02 +08:00
urlTest, isURLTest := abstractOutboundGroup.(*group.URLTest)
2023-07-02 16:45:30 +08:00
if isURLTest {
go urlTest.CheckOutbounds()
} else {
2023-11-28 12:00:28 +08:00
historyStorage := service.PtrFromContext[urltest.HistoryStorage](serviceNow.ctx)
2023-07-02 16:45:30 +08:00
outbounds := common.Filter(common.Map(outboundGroup.All(), func(it string) adapter.Outbound {
2023-11-28 12:00:28 +08:00
itOutbound, _ := serviceNow.instance.Router().Outbound(it)
2023-07-02 16:45:30 +08:00
return itOutbound
}), func(it adapter.Outbound) bool {
if it == nil {
return false
}
_, isGroup := it.(adapter.OutboundGroup)
if isGroup {
return false
}
return true
})
2023-11-28 12:00:28 +08:00
b, _ := batch.New(serviceNow.ctx, batch.WithConcurrencyNum[any](10))
2023-07-02 16:45:30 +08:00
for _, detour := range outbounds {
outboundToTest := detour
outboundTag := outboundToTest.Tag()
b.Go(outboundTag, func() (any, error) {
2023-11-28 12:00:28 +08:00
t, err := urltest.URLTest(serviceNow.ctx, "", outboundToTest)
2023-07-02 16:45:30 +08:00
if err != nil {
historyStorage.DeleteURLTestHistory(outboundTag)
} else {
historyStorage.StoreURLTestHistory(outboundTag, &urltest.History{
Time: time.Now(),
Delay: t,
})
}
return nil, nil
})
}
}
return writeError(conn, nil)
}