diff --git a/adapter/traffic_controller.go b/adapter/experimental.go similarity index 85% rename from adapter/traffic_controller.go rename to adapter/experimental.go index 8d61fb1e..0f6104c2 100644 --- a/adapter/traffic_controller.go +++ b/adapter/experimental.go @@ -7,6 +7,11 @@ import ( N "github.com/sagernet/sing/common/network" ) +type ClashServer interface { + Service + TrafficController +} + type TrafficController interface { RoutedConnection(ctx context.Context, conn net.Conn, metadata InboundContext, matchedRule Rule) net.Conn RoutedPacketConnection(ctx context.Context, conn N.PacketConn, metadata InboundContext, matchedRule Rule) N.PacketConn diff --git a/box.go b/box.go index c1816dbd..8a84aae2 100644 --- a/box.go +++ b/box.go @@ -7,7 +7,7 @@ import ( "time" "github.com/sagernet/sing-box/adapter" - "github.com/sagernet/sing-box/experimental/clashapi" + "github.com/sagernet/sing-box/experimental" "github.com/sagernet/sing-box/inbound" "github.com/sagernet/sing-box/log" "github.com/sagernet/sing-box/option" @@ -28,7 +28,7 @@ type Box struct { logFactory log.Factory logger log.ContextLogger logFile *os.File - clashServer *clashapi.Server + clashServer adapter.ClashServer } func New(ctx context.Context, options option.Options) (*Box, error) { @@ -141,9 +141,12 @@ func New(ctx context.Context, options option.Options) (*Box, error) { return nil, err } - var clashServer *clashapi.Server + var clashServer adapter.ClashServer if needClashAPI { - clashServer = clashapi.NewServer(router, observableLogFactory, common.PtrValueOrDefault(options.Experimental.ClashAPI)) + clashServer, err = experimental.NewClashServer(router, observableLogFactory, common.PtrValueOrDefault(options.Experimental.ClashAPI)) + if err != nil { + return nil, E.Cause(err, "create clash api server") + } router.SetTrafficController(clashServer) } return &Box{ @@ -175,7 +178,7 @@ func (s *Box) Start() error { if s.clashServer != nil { err = s.clashServer.Start() if err != nil { - return E.Cause(err, "start clash api") + return E.Cause(err, "start clash api server") } } s.logger.Info("sing-box started (", F.Seconds(time.Since(s.createdAt).Seconds()), "s)") @@ -191,7 +194,7 @@ func (s *Box) Close() error { } return common.Close( s.router, + s.clashServer, common.PtrOrNil(s.logFile), - common.PtrOrNil(s.clashServer), ) } diff --git a/experimental/clashapi.go b/experimental/clashapi.go new file mode 100644 index 00000000..f5373501 --- /dev/null +++ b/experimental/clashapi.go @@ -0,0 +1,14 @@ +//go:build with_clash_api + +package experimental + +import ( + "github.com/sagernet/sing-box/adapter" + "github.com/sagernet/sing-box/experimental/clashapi" + "github.com/sagernet/sing-box/log" + "github.com/sagernet/sing-box/option" +) + +func NewClashServer(router adapter.Router, logFactory log.ObservableFactory, options option.ClashAPIOptions) (adapter.ClashServer, error) { + return clashapi.NewServer(router, logFactory, options), nil +} diff --git a/experimental/clashapi/server.go b/experimental/clashapi/server.go index 50b9d4cc..d7a4cfd0 100644 --- a/experimental/clashapi/server.go +++ b/experimental/clashapi/server.go @@ -24,10 +24,7 @@ import ( "github.com/gorilla/websocket" ) -var ( - _ adapter.Service = (*Server)(nil) - _ adapter.TrafficController = (*Server)(nil) -) +var _ adapter.ClashServer = (*Server)(nil) type Server struct { logger log.Logger @@ -81,7 +78,7 @@ func (s *Server) Start() error { go func() { err = s.httpServer.Serve(listener) if err != nil && !E.IsClosed(err) { - log.Error("external controller serve error: ", err) + s.logger.Error("external controller serve error: ", err) } }() return nil @@ -294,5 +291,5 @@ func getLogs(logFactory log.ObservableFactory) func(w http.ResponseWriter, r *ht } func version(w http.ResponseWriter, r *http.Request) { - render.JSON(w, r, render.M{"version": "sing-box " + C.Version, "premium": false}) + render.JSON(w, r, render.M{"version": "sing-box " + C.Version, "premium": true}) } diff --git a/experimental/clashapi_stub.go b/experimental/clashapi_stub.go new file mode 100644 index 00000000..50fb89f0 --- /dev/null +++ b/experimental/clashapi_stub.go @@ -0,0 +1,14 @@ +//go:build !with_clash_api + +package experimental + +import ( + "github.com/sagernet/sing-box/adapter" + "github.com/sagernet/sing-box/log" + "github.com/sagernet/sing-box/option" + E "github.com/sagernet/sing/common/exceptions" +) + +func NewClashServer(router adapter.Router, logFactory log.ObservableFactory, options option.ClashAPIOptions) (adapter.ClashServer, error) { + return nil, E.New(`clash api is not included in this build, rebuild with -tags with_clash_api`) +} diff --git a/inbound/tun.go b/inbound/tun.go index 06a5e49c..8a9942d6 100644 --- a/inbound/tun.go +++ b/inbound/tun.go @@ -1,4 +1,4 @@ -//go:build linux || windows +//go:build (linux || windows) && !no_gvisor package inbound diff --git a/inbound/tun_stub.go b/inbound/tun_stub.go index e04e2494..76ff9727 100644 --- a/inbound/tun_stub.go +++ b/inbound/tun_stub.go @@ -1,4 +1,4 @@ -//go:build !linux && !windows +//go:build !(linux || windows) || no_gvisor package inbound diff --git a/route/iface_stub.go b/route/iface_stub.go index 7f14f1b4..e139cd46 100644 --- a/route/iface_stub.go +++ b/route/iface_stub.go @@ -1,4 +1,4 @@ -//go:build !linux && !windows +//go:build !(linux || windows) || no_gvisor package route diff --git a/route/iface_tun.go b/route/iface_tun.go index 62b5d141..2a318de6 100644 --- a/route/iface_tun.go +++ b/route/iface_tun.go @@ -1,4 +1,4 @@ -//go:build linux || windows +//go:build (linux || windows) && !no_gvisor package route