refactor core

This commit is contained in:
arm64v8a
2023-03-04 17:25:18 +09:00
parent f66d63b597
commit 5db3a30ab1
47 changed files with 88 additions and 1033 deletions

View File

@@ -1,7 +1,7 @@
find_package(Protobuf CONFIG REQUIRED) find_package(Protobuf CONFIG REQUIRED)
set(PROTO_FILES set(PROTO_FILES
go/gen/libcore.proto go/grpc_server/gen/libcore.proto
) )
add_library(myproto STATIC ${PROTO_FILES}) add_library(myproto STATIC ${PROTO_FILES})

View File

@@ -1,37 +0,0 @@
package box_main
import (
"context"
box "github.com/sagernet/sing-box"
"github.com/sagernet/sing-box/log"
"github.com/spf13/cobra"
)
var commandCheck = &cobra.Command{
Use: "check",
Short: "Check configuration",
Run: func(cmd *cobra.Command, args []string) {
err := check()
if err != nil {
log.Fatal(err)
}
},
Args: cobra.NoArgs,
}
func init() {
mainCommand.AddCommand(commandCheck)
}
func check() error {
options, err := readConfig(nil)
if err != nil {
return err
}
ctx, cancel := context.WithCancel(context.Background())
_, err = box.New(ctx, options, nil)
cancel()
return err
}

View File

@@ -1,71 +0,0 @@
package box_main
import (
"bytes"
"os"
"path/filepath"
"github.com/sagernet/sing-box/common/json"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
E "github.com/sagernet/sing/common/exceptions"
"github.com/spf13/cobra"
)
var commandFormatFlagWrite bool
var commandFormat = &cobra.Command{
Use: "format",
Short: "Format configuration",
Run: func(cmd *cobra.Command, args []string) {
err := format()
if err != nil {
log.Fatal(err)
}
},
Args: cobra.NoArgs,
}
func init() {
commandFormat.Flags().BoolVarP(&commandFormatFlagWrite, "write", "w", false, "write result to (source) file instead of stdout")
mainCommand.AddCommand(commandFormat)
}
func format() error {
configContent, err := os.ReadFile(configPath)
if err != nil {
return E.Cause(err, "read config")
}
var options option.Options
err = options.UnmarshalJSON(configContent)
if err != nil {
return E.Cause(err, "decode config")
}
buffer := new(bytes.Buffer)
encoder := json.NewEncoder(buffer)
encoder.SetIndent("", " ")
err = encoder.Encode(options)
if err != nil {
return E.Cause(err, "encode config")
}
if !commandFormatFlagWrite {
os.Stdout.WriteString(buffer.String() + "\n")
return nil
}
if bytes.Equal(configContent, buffer.Bytes()) {
return nil
}
output, err := os.Create(configPath)
if err != nil {
return E.Cause(err, "open output")
}
_, err = output.Write(buffer.Bytes())
output.Close()
if err != nil {
return E.Cause(err, "write output")
}
outputPath, _ := filepath.Abs(configPath)
os.Stderr.WriteString(outputPath + "\n")
return nil
}

View File

@@ -1,130 +0,0 @@
package box_main
import (
"context"
"io"
"neko/pkg/protect_server"
"os"
"os/signal"
runtimeDebug "runtime/debug"
"syscall"
box "github.com/sagernet/sing-box"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
E "github.com/sagernet/sing/common/exceptions"
"github.com/spf13/cobra"
)
var commandRun = &cobra.Command{
Use: "run",
Short: "Run service",
Run: func(cmd *cobra.Command, args []string) {
if protectListenPath != "" {
// for v2ray now
go protect_server.ServeProtect(protectListenPath, protectFwMark)
}
err := run()
if err != nil {
log.Fatal(err)
}
},
}
func init() {
mainCommand.AddCommand(commandRun)
}
func readConfig(nekoConfigContent []byte) (option.Options, error) {
var (
configContent []byte
err error
)
if nekoConfigContent == nil {
if configPath == "stdin" {
configContent, err = io.ReadAll(os.Stdin)
} else {
configContent, err = os.ReadFile(configPath)
}
} else {
configContent = nekoConfigContent
}
if err != nil {
return option.Options{}, E.Cause(err, "read config")
}
var options option.Options
err = options.UnmarshalJSON(configContent)
if err != nil {
return option.Options{}, E.Cause(err, "decode config")
}
return options, nil
}
func Create(nekoConfigContent []byte, forceDisableColor bool) (*box.Box, context.CancelFunc, error) {
options, err := readConfig(nekoConfigContent)
if err != nil {
return nil, nil, err
}
if disableColor || forceDisableColor {
if options.Log == nil {
options.Log = &option.LogOptions{}
}
options.Log.DisableColor = true
}
ctx, cancel := context.WithCancel(context.Background())
instance, err := box.New(ctx, options, nil)
if err != nil {
cancel()
return nil, nil, E.Cause(err, "create service")
}
osSignals := make(chan os.Signal, 1)
signal.Notify(osSignals, os.Interrupt, syscall.SIGTERM, syscall.SIGHUP)
defer func() {
signal.Stop(osSignals)
close(osSignals)
}()
go func() {
_, loaded := <-osSignals
if loaded {
cancel()
}
}()
err = instance.Start()
if err != nil {
cancel()
return nil, nil, E.Cause(err, "start service")
}
return instance, cancel, nil
}
func run() error {
osSignals := make(chan os.Signal, 1)
signal.Notify(osSignals, os.Interrupt, syscall.SIGTERM, syscall.SIGHUP)
defer signal.Stop(osSignals)
for {
instance, cancel, err := Create(nil, false)
if err != nil {
return err
}
runtimeDebug.FreeOSMemory()
for {
osSignal := <-osSignals
if osSignal == syscall.SIGHUP {
err = check()
if err != nil {
log.Error(E.Cause(err, "reload service"))
continue
}
}
cancel()
instance.Close()
if osSignal != syscall.SIGHUP {
return nil
}
break
}
}
}

View File

@@ -1,64 +0,0 @@
package box_main
import (
"os"
"runtime"
"runtime/debug"
C "github.com/sagernet/sing-box/constant"
"github.com/spf13/cobra"
)
var commandVersion = &cobra.Command{
Use: "version",
Short: "Print current version of sing-box",
Run: printVersion,
Args: cobra.NoArgs,
}
var nameOnly bool
func init() {
commandVersion.Flags().BoolVarP(&nameOnly, "name", "n", false, "print version name only")
mainCommand.AddCommand(commandVersion)
}
func printVersion(cmd *cobra.Command, args []string) {
if nameOnly {
os.Stdout.WriteString(C.Version + "\n")
return
}
version := "sing-box version " + C.Version + "\n\n"
version += "Environment: " + runtime.Version() + " " + runtime.GOOS + "/" + runtime.GOARCH + "\n"
var tags string
var revision string
debugInfo, loaded := debug.ReadBuildInfo()
if loaded {
for _, setting := range debugInfo.Settings {
switch setting.Key {
case "-tags":
tags = setting.Value
case "vcs.revision":
revision = setting.Value
}
}
}
if tags != "" {
version += "Tags: " + tags + "\n"
}
if revision != "" {
version += "Revision: " + revision + "\n"
}
if C.CGO_ENABLED {
version += "CGO: enabled\n"
} else {
version += "CGO: disabled\n"
}
os.Stdout.WriteString(version)
}

View File

@@ -1,44 +0,0 @@
//go:build debug
package box_main
import (
"encoding/json"
"net/http"
_ "net/http/pprof"
"runtime"
"runtime/debug"
"github.com/sagernet/sing-box/common/badjson"
"github.com/sagernet/sing-box/log"
"github.com/dustin/go-humanize"
)
func init() {
http.HandleFunc("/debug/gc", func(writer http.ResponseWriter, request *http.Request) {
writer.WriteHeader(http.StatusNoContent)
go debug.FreeOSMemory()
})
http.HandleFunc("/debug/memory", func(writer http.ResponseWriter, request *http.Request) {
var memStats runtime.MemStats
runtime.ReadMemStats(&memStats)
var memObject badjson.JSONObject
memObject.Put("heap", humanize.Bytes(memStats.HeapInuse))
memObject.Put("stack", humanize.Bytes(memStats.StackInuse))
memObject.Put("idle", humanize.Bytes(memStats.HeapIdle-memStats.HeapReleased))
memObject.Put("goroutines", runtime.NumGoroutine())
memObject.Put("rss", rusageMaxRSS())
encoder := json.NewEncoder(writer)
encoder.SetIndent("", " ")
encoder.Encode(memObject)
})
go func() {
err := http.ListenAndServe("0.0.0.0:8964", nil)
if err != nil {
log.Debug(err)
}
}()
}

View File

@@ -1,25 +0,0 @@
//go:build debug
package box_main
import (
"runtime"
"syscall"
)
func rusageMaxRSS() float64 {
ru := syscall.Rusage{}
err := syscall.Getrusage(syscall.RUSAGE_SELF, &ru)
if err != nil {
return 0
}
rss := float64(ru.Maxrss)
if runtime.GOOS == "darwin" || runtime.GOOS == "ios" {
rss /= 1 << 20 // ru_maxrss is bytes on darwin
} else {
// ru_maxrss is kilobytes elsewhere (linux, openbsd, etc)
rss /= 1 << 10
}
return rss
}

View File

@@ -1,7 +0,0 @@
//go:build debug && !linux
package box_main
func rusageMaxRSS() float64 {
return -1
}

View File

@@ -1,43 +0,0 @@
package box_main
import (
"os"
_ "github.com/sagernet/sing-box/include"
"github.com/sagernet/sing-box/log"
"github.com/spf13/cobra"
)
var (
configPath string
workingDir string
disableColor bool
//
protectListenPath string
protectFwMark int
)
var mainCommand = &cobra.Command{
Use: "sing-box",
PersistentPreRun: preRun,
}
func Main() {
mainCommand.PersistentFlags().StringVarP(&configPath, "config", "c", "config.json", "set configuration file path")
mainCommand.PersistentFlags().StringVarP(&workingDir, "directory", "D", "", "set working directory")
mainCommand.PersistentFlags().BoolVarP(&disableColor, "disable-color", "", false, "disable color output")
mainCommand.PersistentFlags().StringVarP(&protectListenPath, "protect-listen-path", "", "", "Linux Only")
mainCommand.PersistentFlags().IntVarP(&protectFwMark, "protect-fwmark", "", 0, "Linux Only")
if err := mainCommand.Execute(); err != nil {
log.Fatal(err)
}
}
func preRun(cmd *cobra.Command, args []string) {
if workingDir != "" {
if err := os.Chdir(workingDir); err != nil {
log.Fatal(err)
}
}
}

View File

@@ -3,14 +3,15 @@ package main
import ( import (
"context" "context"
"io" "io"
"neko/pkg/neko_common"
"neko/pkg/neko_log"
"net" "net"
"net/http" "net/http"
"reflect" "reflect"
"time" "time"
"unsafe" "unsafe"
"github.com/matsuridayo/libneko/neko_common"
"github.com/matsuridayo/libneko/neko_log"
box "github.com/sagernet/sing-box" box "github.com/sagernet/sing-box"
"github.com/sagernet/sing-box/adapter" "github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/common/dialer" "github.com/sagernet/sing-box/common/dialer"

View File

@@ -3,15 +3,11 @@ module nekobox_core
go 1.19 go 1.19
require ( require (
github.com/dustin/go-humanize v1.0.1 github.com/matsuridayo/libneko v0.0.0-20230304130313-5ea96b79b3c3
github.com/gofrs/uuid v4.4.0+incompatible github.com/matsuridayo/sing-box-extra v0.0.0-20230304131029-37eeda33b862
github.com/sagernet/sing v0.1.8-0.20230301160041-9fab0a9f4304 github.com/sagernet/sing v0.1.8-0.20230301160041-9fab0a9f4304
github.com/sagernet/sing-box v1.1.6-0.20230301163156-e8802357e1e7 github.com/sagernet/sing-box v1.1.6-0.20230301163156-e8802357e1e7
github.com/sagernet/sing-dns v0.1.4 grpc_server v1.0.0
github.com/sagernet/sing-tun v0.1.2-0.20230226091124-0cdb0eed74d9
github.com/spf13/cobra v1.6.1
golang.org/x/sys v0.5.0
neko v1.0.0
) )
require ( require (
@@ -22,11 +18,13 @@ require (
github.com/caddyserver/certmagic v0.17.2 // indirect github.com/caddyserver/certmagic v0.17.2 // indirect
github.com/cloudflare/circl v1.2.1-0.20221019164342-6ab4dfed8f3c // indirect github.com/cloudflare/circl v1.2.1-0.20221019164342-6ab4dfed8f3c // indirect
github.com/cretz/bine v0.2.0 // indirect github.com/cretz/bine v0.2.0 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/go-chi/chi/v5 v5.0.8 // indirect github.com/go-chi/chi/v5 v5.0.8 // indirect
github.com/go-chi/cors v1.2.1 // indirect github.com/go-chi/cors v1.2.1 // indirect
github.com/go-chi/render v1.0.2 // indirect github.com/go-chi/render v1.0.2 // indirect
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect
github.com/gofrs/uuid v4.4.0+incompatible // indirect
github.com/golang/mock v1.6.0 // indirect github.com/golang/mock v1.6.0 // indirect
github.com/golang/protobuf v1.5.2 // indirect github.com/golang/protobuf v1.5.2 // indirect
github.com/google/btree v1.0.1 // indirect github.com/google/btree v1.0.1 // indirect
@@ -57,14 +55,17 @@ require (
github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97 // indirect github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97 // indirect
github.com/sagernet/quic-go v0.0.0-20230202071646-a8c8afb18b32 // indirect github.com/sagernet/quic-go v0.0.0-20230202071646-a8c8afb18b32 // indirect
github.com/sagernet/reality v0.0.0-20230228045158-d3e085a8e5d1 // indirect github.com/sagernet/reality v0.0.0-20230228045158-d3e085a8e5d1 // indirect
github.com/sagernet/sing-dns v0.1.4 // indirect
github.com/sagernet/sing-shadowsocks v0.1.2-0.20230221080503-769c01d6bba9 // indirect github.com/sagernet/sing-shadowsocks v0.1.2-0.20230221080503-769c01d6bba9 // indirect
github.com/sagernet/sing-shadowtls v0.0.0-20230221123345-78e50cd7b587 // indirect github.com/sagernet/sing-shadowtls v0.0.0-20230221123345-78e50cd7b587 // indirect
github.com/sagernet/sing-tun v0.1.2-0.20230226091124-0cdb0eed74d9 // indirect
github.com/sagernet/sing-vmess v0.1.2 // indirect github.com/sagernet/sing-vmess v0.1.2 // indirect
github.com/sagernet/smux v0.0.0-20220831015742-e0f1988e3195 // indirect github.com/sagernet/smux v0.0.0-20220831015742-e0f1988e3195 // indirect
github.com/sagernet/tfo-go v0.0.0-20230207095944-549363a7327d // indirect github.com/sagernet/tfo-go v0.0.0-20230207095944-549363a7327d // indirect
github.com/sagernet/utls v0.0.0-20230225061716-536a007c8b01 // indirect github.com/sagernet/utls v0.0.0-20230225061716-536a007c8b01 // indirect
github.com/sagernet/websocket v0.0.0-20220913015213-615516348b4e // indirect github.com/sagernet/websocket v0.0.0-20220913015213-615516348b4e // indirect
github.com/sagernet/wireguard-go v0.0.0-20221116151939-c99467f53f2c // indirect github.com/sagernet/wireguard-go v0.0.0-20221116151939-c99467f53f2c // indirect
github.com/spf13/cobra v1.6.1 // indirect
github.com/spf13/pflag v1.0.5 // indirect github.com/spf13/pflag v1.0.5 // indirect
github.com/u-root/uio v0.0.0-20230215032506-9aa6f7e2d72c // indirect github.com/u-root/uio v0.0.0-20230215032506-9aa6f7e2d72c // indirect
github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 // indirect github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 // indirect
@@ -77,6 +78,7 @@ require (
golang.org/x/exp v0.0.0-20230213192124-5e25df0256eb // indirect golang.org/x/exp v0.0.0-20230213192124-5e25df0256eb // indirect
golang.org/x/mod v0.6.0 // indirect golang.org/x/mod v0.6.0 // indirect
golang.org/x/net v0.7.0 // indirect golang.org/x/net v0.7.0 // indirect
golang.org/x/sys v0.5.0 // indirect
golang.org/x/text v0.7.0 // indirect golang.org/x/text v0.7.0 // indirect
golang.org/x/time v0.0.0-20191024005414-555d28b269f0 // indirect golang.org/x/time v0.0.0-20191024005414-555d28b269f0 // indirect
golang.org/x/tools v0.2.0 // indirect golang.org/x/tools v0.2.0 // indirect
@@ -87,6 +89,6 @@ require (
lukechampine.com/blake3 v1.1.7 // indirect lukechampine.com/blake3 v1.1.7 // indirect
) )
replace neko v1.0.0 => ../../ replace grpc_server v1.0.0 => ../../grpc_server
// replace github.com/sagernet/sing-box => ../../../../sing-box // replace github.com/sagernet/sing-box => ../../../../sing-box

View File

@@ -105,6 +105,10 @@ github.com/libdns/libdns v0.2.1 h1:Wu59T7wSHRgtA0cfxC+n1c/e+O3upJGWytknkmFEDis=
github.com/libdns/libdns v0.2.1/go.mod h1:yQCXzk1lEZmmCPa857bnk4TsOiqYasqpyOEeSObbb40= github.com/libdns/libdns v0.2.1/go.mod h1:yQCXzk1lEZmmCPa857bnk4TsOiqYasqpyOEeSObbb40=
github.com/logrusorgru/aurora v2.0.3+incompatible h1:tOpm7WcpBTn4fjmVfgpQq0EfczGlG91VSDkswnjF5A8= github.com/logrusorgru/aurora v2.0.3+incompatible h1:tOpm7WcpBTn4fjmVfgpQq0EfczGlG91VSDkswnjF5A8=
github.com/logrusorgru/aurora v2.0.3+incompatible/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= github.com/logrusorgru/aurora v2.0.3+incompatible/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
github.com/matsuridayo/libneko v0.0.0-20230304130313-5ea96b79b3c3 h1:emqnGHIlezKjm24Lz5aos9Lc1bhxFL8Ynp20EprSNJc=
github.com/matsuridayo/libneko v0.0.0-20230304130313-5ea96b79b3c3/go.mod h1:IRO07Queptz/rGFvEW+3Hmwpx7MCup6WiDs4p5jMt4g=
github.com/matsuridayo/sing-box-extra v0.0.0-20230304131029-37eeda33b862 h1:z8qC1cSVDZrhJbZPgsp1oM8rxnzMb+aU3FxAYG27S+k=
github.com/matsuridayo/sing-box-extra v0.0.0-20230304131029-37eeda33b862/go.mod h1:5YMikmz+Vpr5P7/rSigF92Yf5pBsCzDq9IpQRjoLb3E=
github.com/mdlayher/ethernet v0.0.0-20190606142754-0394541c37b7/go.mod h1:U6ZQobyTjI/tJyq2HG+i/dfSoFUt8/aZCM+GKtmFk/Y= github.com/mdlayher/ethernet v0.0.0-20190606142754-0394541c37b7/go.mod h1:U6ZQobyTjI/tJyq2HG+i/dfSoFUt8/aZCM+GKtmFk/Y=
github.com/mdlayher/netlink v0.0.0-20190409211403-11939a169225/go.mod h1:eQB3mZE4aiYnlUsyGGCOpPETfdQq4Jhsgf1fk3cwQaA= github.com/mdlayher/netlink v0.0.0-20190409211403-11939a169225/go.mod h1:eQB3mZE4aiYnlUsyGGCOpPETfdQq4Jhsgf1fk3cwQaA=
github.com/mdlayher/netlink v1.0.0/go.mod h1:KxeJAFOFLG6AjpyDkQ/iIhxygIUKD+vcwqcnu43w/+M= github.com/mdlayher/netlink v1.0.0/go.mod h1:KxeJAFOFLG6AjpyDkQ/iIhxygIUKD+vcwqcnu43w/+M=

View File

@@ -4,14 +4,18 @@ import (
"context" "context"
"errors" "errors"
"fmt" "fmt"
"grpc_server"
"grpc_server/gen"
"github.com/matsuridayo/libneko/neko_common"
"github.com/matsuridayo/libneko/neko_log"
"github.com/matsuridayo/libneko/speedtest"
"github.com/matsuridayo/sing-box-extra/boxapi"
"github.com/matsuridayo/sing-box-extra/boxmain"
"io" "io"
"log" "log"
"neko/gen"
"neko/pkg/grpc_server"
"neko/pkg/neko_common"
"neko/pkg/neko_log"
"neko/pkg/speedtest"
"nekobox_core/box_main"
"reflect" "reflect"
"time" "time"
"unsafe" "unsafe"
@@ -44,7 +48,7 @@ func (s *server) Start(ctx context.Context, in *gen.LoadConfigReq) (out *gen.Err
return return
} }
instance, instance_cancel, err = box_main.Create([]byte(in.CoreConfig), true) instance, instance_cancel, err = boxmain.Create([]byte(in.CoreConfig), true)
if instance != nil { if instance != nil {
// Logger // Logger
@@ -55,7 +59,7 @@ func (s *server) Start(ctx context.Context, in *gen.LoadConfigReq) (out *gen.Err
writer_ = reflect.NewAt(writer_.Type(), unsafe.Pointer(writer_.UnsafeAddr())).Elem() // get unexported io.Writer writer_ = reflect.NewAt(writer_.Type(), unsafe.Pointer(writer_.UnsafeAddr())).Elem() // get unexported io.Writer
writer_.Set(reflect.ValueOf(neko_log.LogWriter)) writer_.Set(reflect.ValueOf(neko_log.LogWriter))
// V2ray Service // V2ray Service
instance.Router().SetV2RayServer(NewSbV2rayServer()) instance.Router().SetV2RayServer(boxapi.NewSbV2rayServer())
} }
return return
@@ -111,7 +115,7 @@ func (s *server) Test(ctx context.Context, in *gen.TestReq) (out *gen.TestResp,
var i *box.Box var i *box.Box
if in.Config != nil { if in.Config != nil {
// Test instance // Test instance
i, instance_cancel, err = box_main.Create([]byte(in.Config.CoreConfig), true) i, instance_cancel, err = boxmain.Create([]byte(in.Config.CoreConfig), true)
if instance_cancel != nil { if instance_cancel != nil {
defer instance_cancel() defer instance_cancel()
} }
@@ -139,10 +143,10 @@ func (s *server) Test(ctx context.Context, in *gen.TestReq) (out *gen.TestResp,
func (s *server) QueryStats(ctx context.Context, in *gen.QueryStatsReq) (out *gen.QueryStatsResp, _ error) { func (s *server) QueryStats(ctx context.Context, in *gen.QueryStatsReq) (out *gen.QueryStatsResp, _ error) {
out = &gen.QueryStatsResp{} out = &gen.QueryStatsResp{}
var box_v2ray_service *sbV2rayStatsService var box_v2ray_service *boxapi.SbV2rayStatsService
if instance != nil && instance.Router().V2RayServer() != nil { if instance != nil && instance.Router().V2RayServer() != nil {
box_v2ray_service, _ = instance.Router().V2RayServer().StatsService().(*sbV2rayStatsService) box_v2ray_service, _ = instance.Router().V2RayServer().StatsService().(*boxapi.SbV2rayStatsService)
} }
if box_v2ray_service != nil { if box_v2ray_service != nil {

View File

@@ -1,47 +0,0 @@
package main
import (
"context"
"errors"
"net"
"reflect"
"runtime"
"unsafe"
D "github.com/sagernet/sing-dns"
"github.com/sagernet/sing/common/logger"
M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network"
)
var underlyingDNS string
func init() {
D.RegisterTransport([]string{"underlying"}, CreateUnderlyingTransport)
}
func CreateUnderlyingTransport(ctx context.Context, logger logger.ContextLogger, dialer N.Dialer, link string) (D.Transport, error) {
if runtime.GOOS != "windows" {
// Linux no resolv.conf change
return D.CreateLocalTransport(ctx, logger, dialer, "local")
}
// Windows Underlying DNS hook
t, _ := D.CreateUDPTransport(ctx, logger, dialer, link)
udp := t.(*D.UDPTransport)
handler_ := reflect.Indirect(reflect.ValueOf(udp)).FieldByName("handler")
handler_ = reflect.NewAt(handler_.Type(), unsafe.Pointer(handler_.UnsafeAddr())).Elem()
handler_.Set(reflect.ValueOf(&myTransportHandler{udp, dialer}))
return t, nil
}
type myTransportHandler struct {
*D.UDPTransport
dialer N.Dialer
}
func (t *myTransportHandler) DialContext(ctx context.Context, queryCtx context.Context) (net.Conn, error) {
if underlyingDNS == "" {
return nil, errors.New("no underlyingDNS")
}
return t.dialer.DialContext(ctx, "udp", M.ParseSocksaddrHostPort(underlyingDNS, 53))
}

View File

@@ -5,15 +5,17 @@ import (
"os" "os"
_ "unsafe" _ "unsafe"
"neko/pkg/grpc_server" "grpc_server"
"neko/pkg/neko_common"
"nekobox_core/box_main" "github.com/matsuridayo/libneko/neko_common"
"github.com/matsuridayo/sing-box-extra/boxmain"
_ "github.com/matsuridayo/sing-box-extra/distro/all"
"github.com/sagernet/sing-box/constant" "github.com/sagernet/sing-box/constant"
) )
func main() { func main() {
fmt.Println("sing-box:", constant.Version, "Neko:", neko_common.Version_neko) fmt.Println("sing-box:", constant.Version, "NekoBox:", neko_common.Version_neko)
fmt.Println() fmt.Println()
// local DNS transport // local DNS transport
@@ -27,5 +29,5 @@ func main() {
} }
// sing-box // sing-box
box_main.Main() boxmain.Main()
} }

View File

@@ -1,82 +0,0 @@
package main
import (
"context"
"log"
"neko/pkg/iphlpapi"
"net/netip"
"strings"
tun "github.com/sagernet/sing-tun"
"github.com/gofrs/uuid"
"golang.org/x/sys/windows/registry"
)
var monitorNU tun.NetworkUpdateMonitor
var monitorDI tun.DefaultInterfaceMonitor
func init() {
monitorNU, _ = tun.NewNetworkUpdateMonitor(&emptyErrorHandler{})
monitorDI, _ = tun.NewDefaultInterfaceMonitor(monitorNU, tun.DefaultInterfaceMonitorOptions{})
monitorDI.RegisterCallback(monitorForUnderlyingDNS)
monitorDI.Start()
monitorNU.Start()
}
type emptyErrorHandler struct{}
func (e *emptyErrorHandler) NewError(ctx context.Context, err error) {}
func monitorForUnderlyingDNS(event int) error {
index := monitorDI.DefaultInterfaceIndex(netip.IPv4Unspecified())
var guid iphlpapi.GUID
if errno := iphlpapi.Index2GUID(uint64(index), &guid); errno != 0 {
return nil
}
u, _ := uuid.FromBytes([]byte{
guid.Data1[3], guid.Data1[2], guid.Data1[1], guid.Data1[0],
guid.Data2[1], guid.Data2[0],
guid.Data3[1], guid.Data3[0],
guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3],
guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7],
})
guidStr := "{" + u.String() + "}"
underlyingDNS = getFirstDNS(guidStr)
log.Println("underlyingDNS:", guidStr, underlyingDNS)
return nil
}
func getFirstDNS(guid string) string {
dns, err := getNameServersForInterface(guid)
if err != nil || len(dns) == 0 {
return ""
}
return dns[0]
}
func getNameServersForInterface(guid string) ([]string, error) {
key, err := registry.OpenKey(registry.LOCAL_MACHINE, `SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\`+guid, registry.QUERY_VALUE)
if err != nil {
log.Println("getNameServersForInterface OpenKey:", err)
return nil, err
}
defer key.Close()
nameservers := make([]string, 0, 4)
for _, name := range []string{`NameServer`, `DhcpNameServer`} {
s, _, err := key.GetStringValue(name)
if err != nil {
log.Println("getNameServersForInterface GetStringValue:", name, err)
continue
}
s = strings.ReplaceAll(s, ",", " ")
for _, server := range strings.Split(s, " ") {
if server != "" {
nameservers = append(nameservers, server)
}
}
}
return nameservers, nil
}

View File

@@ -0,0 +1,2 @@
go get github.com/matsuridayo/sing-box-extra@"$1"
go mod tidy

View File

@@ -1,41 +0,0 @@
package main
import (
"net"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/experimental/v2rayapi"
"github.com/sagernet/sing-box/option"
"github.com/sagernet/sing/common/network"
)
type sbV2rayServer struct {
ss *sbV2rayStatsService
}
func NewSbV2rayServer() adapter.V2RayServer {
options := option.V2RayStatsServiceOptions{
Enabled: true,
Outbounds: []string{"proxy", "bypass"}, // TODO
}
return &sbV2rayServer{
ss: &sbV2rayStatsService{v2rayapi.NewStatsService(options)},
}
}
func (s *sbV2rayServer) Start() error { return nil }
func (s *sbV2rayServer) Close() error { return nil }
func (s *sbV2rayServer) StatsService() adapter.V2RayStatsService { return s.ss }
type sbV2rayStatsService struct {
*v2rayapi.StatsService
}
func (s *sbV2rayStatsService) RoutedConnection(inbound string, outbound string, user string, conn net.Conn) net.Conn {
// TODO track
return s.StatsService.RoutedConnection(inbound, outbound, user, conn)
}
func (s *sbV2rayStatsService) RoutedPacketConnection(inbound string, outbound string, user string, conn network.PacketConn) network.PacketConn {
return s.StatsService.RoutedPacketConnection(inbound, outbound, user, conn)
}

View File

@@ -4,13 +4,14 @@ import (
"context" "context"
"fmt" "fmt"
"log" "log"
"neko/pkg/neko_common"
"neko/pkg/neko_log"
"net" "net"
"net/http" "net/http"
"os" "os"
"time" "time"
"github.com/matsuridayo/libneko/neko_common"
"github.com/matsuridayo/libneko/neko_log"
core "github.com/v2fly/v2ray-core/v5" core "github.com/v2fly/v2ray-core/v5"
appLog "github.com/v2fly/v2ray-core/v5/app/log" appLog "github.com/v2fly/v2ray-core/v5/app/log"
commonLog "github.com/v2fly/v2ray-core/v5/common/log" commonLog "github.com/v2fly/v2ray-core/v5/common/log"

View File

@@ -5,9 +5,10 @@ go 1.19
require ( require (
github.com/Dreamacro/clash v1.9.0 github.com/Dreamacro/clash v1.9.0
github.com/jsimonetti/rtnetlink v1.2.2 github.com/jsimonetti/rtnetlink v1.2.2
github.com/matsuridayo/libneko v0.0.0-20230304130313-5ea96b79b3c3
github.com/v2fly/v2ray-core/v5 v5.0.0 github.com/v2fly/v2ray-core/v5 v5.0.0
grpc_server v1.0.0
kernel.org/pub/linux/libs/security/libcap/cap v1.2.65 kernel.org/pub/linux/libs/security/libcap/cap v1.2.65
neko v1.0.0
) )
require ( require (
@@ -75,6 +76,8 @@ require (
kernel.org/pub/linux/libs/security/libcap/psx v1.2.65 // indirect kernel.org/pub/linux/libs/security/libcap/psx v1.2.65 // indirect
) )
replace neko v1.0.0 => ../../ replace neko v1.0.0 => ../../neko
replace grpc_server v1.0.0 => ../../grpc_server
replace github.com/v2fly/v2ray-core/v5 v5.0.0 => ../../../../v2ray-core replace github.com/v2fly/v2ray-core/v5 v5.0.0 => ../../../../v2ray-core

View File

@@ -249,6 +249,8 @@ github.com/lunixbochs/struc v0.0.0-20190916212049-a5c72983bc42/go.mod h1:vy1vK6w
github.com/lunixbochs/struc v0.0.0-20200707160740-784aaebc1d40 h1:EnfXoSqDfSNJv0VBNqY/88RNnhSGYkrHaO0mmFGbVsc= github.com/lunixbochs/struc v0.0.0-20200707160740-784aaebc1d40 h1:EnfXoSqDfSNJv0VBNqY/88RNnhSGYkrHaO0mmFGbVsc=
github.com/lunixbochs/struc v0.0.0-20200707160740-784aaebc1d40/go.mod h1:vy1vK6wD6j7xX6O6hXe621WabdtNkou2h7uRtTfRMyg= github.com/lunixbochs/struc v0.0.0-20200707160740-784aaebc1d40/go.mod h1:vy1vK6wD6j7xX6O6hXe621WabdtNkou2h7uRtTfRMyg=
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/matsuridayo/libneko v0.0.0-20230304130313-5ea96b79b3c3 h1:emqnGHIlezKjm24Lz5aos9Lc1bhxFL8Ynp20EprSNJc=
github.com/matsuridayo/libneko v0.0.0-20230304130313-5ea96b79b3c3/go.mod h1:IRO07Queptz/rGFvEW+3Hmwpx7MCup6WiDs4p5jMt4g=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=

View File

@@ -6,16 +6,17 @@ import (
"encoding/json" "encoding/json"
"errors" "errors"
"fmt" "fmt"
"grpc_server"
"grpc_server/gen"
"io" "io"
"log" "log"
"neko/gen"
"neko/pkg/grpc_server"
"neko/pkg/neko_common"
"neko/pkg/speedtest"
"net" "net"
"strings" "strings"
"time" "time"
"github.com/matsuridayo/libneko/neko_common"
"github.com/matsuridayo/libneko/speedtest"
core "github.com/v2fly/v2ray-core/v5" core "github.com/v2fly/v2ray-core/v5"
"github.com/v2fly/v2ray-core/v5/nekoutils" "github.com/v2fly/v2ray-core/v5/nekoutils"
) )

View File

@@ -2,11 +2,12 @@ package main
import ( import (
"fmt" "fmt"
"neko/pkg/grpc_server" "grpc_server"
"neko/pkg/neko_common"
"os" "os"
_ "unsafe" _ "unsafe"
"github.com/matsuridayo/libneko/neko_common"
"github.com/v2fly/v2ray-core/v5/main/commands" "github.com/v2fly/v2ray-core/v5/main/commands"
"github.com/v2fly/v2ray-core/v5/main/commands/base" "github.com/v2fly/v2ray-core/v5/main/commands/base"
) )

View File

@@ -3,13 +3,14 @@ package main
import ( import (
"encoding/binary" "encoding/binary"
"log" "log"
"neko/pkg/iphlpapi"
"net" "net"
"strings" "strings"
"sync" "sync"
"syscall" "syscall"
"unsafe" "unsafe"
"github.com/matsuridayo/libneko/iphlpapi"
"github.com/v2fly/v2ray-core/v5/transport/internet" "github.com/v2fly/v2ray-core/v5/transport/internet"
) )

View File

@@ -4,12 +4,13 @@ import (
"flag" "flag"
"io" "io"
"log" "log"
"neko/pkg/protect_server"
"net" "net"
"net/http" "net/http"
"os" "os"
"syscall" "syscall"
"github.com/matsuridayo/libneko/protect_server"
"github.com/jsimonetti/rtnetlink" "github.com/jsimonetti/rtnetlink"
linuxcap "kernel.org/pub/linux/libs/security/libcap/cap" linuxcap "kernel.org/pub/linux/libs/security/libcap/cap"
) )

View File

@@ -1,4 +1,4 @@
package neko_auth package auth
import ( import (
"context" "context"

View File

@@ -894,8 +894,9 @@ var file_libcore_proto_rawDesc = []byte{
0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x11, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x11, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f,
0x72, 0x65, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x52, 0x65, 0x71, 0x1a, 0x1c, 0x2e, 0x6c, 0x69, 0x72, 0x65, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x52, 0x65, 0x71, 0x1a, 0x1c, 0x2e, 0x6c, 0x69,
0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63,
0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x42, 0x0a, 0x5a, 0x08, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x42, 0x16, 0x5a, 0x14, 0x6e,
0x65, 0x6b, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 0x65, 0x6b, 0x6f, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f,
0x67, 0x65, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
} }
var ( var (

View File

@@ -1,7 +1,7 @@
syntax = "proto3"; syntax = "proto3";
package libcore; package libcore;
option go_package = "neko/gen"; option go_package = "grpc_server/gen";
service LibcoreService { service LibcoreService {
rpc Exit(EmptyReq) returns (EmptyResp) {} rpc Exit(EmptyReq) returns (EmptyResp) {}

View File

@@ -1,9 +1,10 @@
module neko module grpc_server
go 1.19 go 1.19
require ( require (
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 github.com/grpc-ecosystem/go-grpc-middleware v1.3.0
github.com/matsuridayo/libneko v0.0.0-20230304130313-5ea96b79b3c3
google.golang.org/grpc v1.49.0 google.golang.org/grpc v1.49.0
google.golang.org/protobuf v1.28.1 google.golang.org/protobuf v1.28.1
) )

View File

@@ -56,6 +56,8 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/matsuridayo/libneko v0.0.0-20230304130313-5ea96b79b3c3 h1:emqnGHIlezKjm24Lz5aos9Lc1bhxFL8Ynp20EprSNJc=
github.com/matsuridayo/libneko v0.0.0-20230304130313-5ea96b79b3c3/go.mod h1:IRO07Queptz/rGFvEW+3Hmwpx7MCup6WiDs4p5jMt4g=
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=

View File

@@ -5,10 +5,9 @@ import (
"context" "context"
"flag" "flag"
"fmt" "fmt"
"grpc_server/auth"
"grpc_server/gen"
"log" "log"
"neko/gen"
"neko/pkg/neko_auth"
"neko/pkg/neko_common"
"net" "net"
"os" "os"
"runtime" "runtime"
@@ -17,6 +16,8 @@ import (
"syscall" "syscall"
"time" "time"
"github.com/matsuridayo/libneko/neko_common"
grpc_auth "github.com/grpc-ecosystem/go-grpc-middleware/auth" grpc_auth "github.com/grpc-ecosystem/go-grpc-middleware/auth"
"google.golang.org/grpc" "google.golang.org/grpc"
) )
@@ -83,7 +84,7 @@ func RunCore(setupCore func(), server gen.LibcoreServiceServer) {
} }
os.Stderr.WriteString("token is set\n") os.Stderr.WriteString("token is set\n")
auther := neko_auth.Authenticator{ auther := auth.Authenticator{
Token: token, Token: token,
} }

View File

@@ -3,14 +3,15 @@ package grpc_server
import ( import (
"context" "context"
"encoding/json" "encoding/json"
"grpc_server/gen"
"io" "io"
"neko/gen"
"neko/pkg/neko_common"
"net/http" "net/http"
"os" "os"
"runtime" "runtime"
"strings" "strings"
"time" "time"
"github.com/matsuridayo/libneko/neko_common"
) )
var update_download_url string var update_download_url string

View File

@@ -1,18 +0,0 @@
package iphlpapi
import "syscall"
var (
proc_GetIpForwardTable *syscall.LazyProc
proc_NotifyRouteChange2 *syscall.LazyProc
proc_ConvertInterfaceIndexToLuid *syscall.LazyProc
proc_ConvertInterfaceLuidToGuid *syscall.LazyProc
)
func init() {
iphlpapi := syscall.NewLazyDLL("iphlpapi.dll")
proc_GetIpForwardTable = iphlpapi.NewProc("GetIpForwardTable")
proc_NotifyRouteChange2 = iphlpapi.NewProc("NotifyRouteChange2")
proc_ConvertInterfaceIndexToLuid = iphlpapi.NewProc("ConvertInterfaceIndexToLuid")
proc_ConvertInterfaceLuidToGuid = iphlpapi.NewProc("ConvertInterfaceLuidToGuid")
}

View File

@@ -1,20 +0,0 @@
package iphlpapi
import "unsafe"
type GUID struct {
Data1 [4]byte
Data2 [2]byte
Data3 [2]byte
Data4 [8]byte
}
func Index2GUID(index uint64, guid *GUID) uint16 {
var luid uint64
a, _, _ := proc_ConvertInterfaceIndexToLuid.Call(uintptr(index), uintptr(unsafe.Pointer(&luid)))
if a != 0 {
return uint16(a)
}
a, _, _ = proc_ConvertInterfaceLuidToGuid.Call(uintptr(unsafe.Pointer(&luid)), uintptr(unsafe.Pointer(guid)))
return uint16(a)
}

View File

@@ -1,23 +0,0 @@
package iphlpapi
import (
"syscall"
"unsafe"
)
func notifyRouteChange2(family uint16, callback uintptr, callerContext uintptr, initialNotification bool, notificationHandle *syscall.Handle) (ret error) {
var _p0 uint32
if initialNotification {
_p0 = 1
}
r0, _, _ := syscall.Syscall6(proc_NotifyRouteChange2.Addr(), 5, uintptr(family), uintptr(callback), uintptr(callerContext), uintptr(_p0), uintptr(unsafe.Pointer(notificationHandle)), 0)
if r0 != 0 {
ret = syscall.Errno(r0)
}
return
}
func RegisterNotifyRouteChange2(callback func(callerContext uintptr, row uintptr, notificationType uint32) uintptr, initialNotification bool) (handle syscall.Handle) {
notifyRouteChange2(syscall.AF_UNSPEC, syscall.NewCallback(callback), 0, initialNotification, &handle)
return
}

View File

@@ -1,87 +0,0 @@
package iphlpapi
import (
"fmt"
"net"
"unsafe"
)
/*
对于路由表,预期的方法是:
查询 0.0.0.0/0 获得原始默认路由
然后为 vpn 服务器添加默认路由
之后就根据需要下发vpn路由完事。
对于0.0.0.0/0 vpn 路由可以尝试更低的跃点数也可以尝试分为2个。
重新连接时可以删除vpn接口的所有非链路路由表。
路由表格式:
目标网络 uint32 掩码位数 byte低6位 vpn/默认网关 byte 高1位
*/
// 太低的值添加路由时会返回 106 错误
const routeMetric = 93
type RouteRow struct {
ForwardDest [4]byte //目标网络
ForwardMask [4]byte //掩码
ForwardPolicy uint32 //ForwardPolicy:0x0
ForwardNextHop [4]byte //网关
ForwardIfIndex uint32 // 网卡索引 id
ForwardType uint32 //3 本地接口 4 远端接口
ForwardProto uint32 //3静态路由 2本地接口 5EGP网关
ForwardAge uint32 //存在时间 秒
ForwardNextHopAS uint32 //下一跳自治域号码 0
ForwardMetric1 uint32 //度量衡(跃点数),根据 ForwardProto 不同意义不同。
ForwardMetric2 uint32
ForwardMetric3 uint32
ForwardMetric4 uint32
ForwardMetric5 uint32
}
func (rr *RouteRow) GetForwardDest() net.IP {
return net.IP(rr.ForwardDest[:])
}
func (rr *RouteRow) GetForwardMask() net.IP {
return net.IP(rr.ForwardMask[:])
}
func (rr *RouteRow) GetForwardNextHop() net.IP {
return net.IP(rr.ForwardNextHop[:])
}
func GetRoutes() ([]RouteRow, error) {
buf := make([]byte, 4+unsafe.Sizeof(RouteRow{}))
buf_len := uint32(len(buf))
proc_GetIpForwardTable.Call(uintptr(unsafe.Pointer(&buf[0])),
uintptr(unsafe.Pointer(&buf_len)), 0)
var r1 uintptr
for i := 0; i < 5; i++ {
buf = make([]byte, buf_len)
r1, _, _ = proc_GetIpForwardTable.Call(uintptr(unsafe.Pointer(&buf[0])),
uintptr(unsafe.Pointer(&buf_len)), 0)
if r1 == 122 {
continue
}
break
}
if r1 != 0 {
return nil, fmt.Errorf("Failed to get the routing table, return value%v", r1)
}
num := *(*uint32)(unsafe.Pointer(&buf[0]))
routes := make([]RouteRow, num)
sr := uintptr(unsafe.Pointer(&buf[0])) + unsafe.Sizeof(num)
rowSize := unsafe.Sizeof(RouteRow{})
// 安全检查
if len(buf) < int((unsafe.Sizeof(num) + rowSize*uintptr(num))) {
return nil, fmt.Errorf("System error: GetIpForwardTable returns the number is too long, beyond the buffer。")
}
for i := uint32(0); i < num; i++ {
routes[i] = *((*RouteRow)(unsafe.Pointer(sr + (rowSize * uintptr(i)))))
}
return routes, nil
}

View File

@@ -1,20 +0,0 @@
package neko_common
import (
"net/http"
)
var Version_v2ray string = "N/A"
var Version_neko string = "N/A"
var Debug bool
var RunMode int
const (
RunMode_Other = iota
RunMode_NekoRay_Core
RunMode_NekoBox_Core
)
var GetProxyHttpClient func() *http.Client

View File

@@ -1,56 +0,0 @@
package neko_log
import (
"io"
"log"
"os"
)
var f_neko_log *os.File
var LogWriter *logWriter
func SetupLog(maxSize int, path string) {
if f_neko_log != nil && LogWriter != nil {
return
}
// Truncate mod from libcore, simplify because only 1 proccess.
oldBytes, err := os.ReadFile(path)
if err == nil && len(oldBytes) > maxSize {
if os.Truncate(path, 0) == nil {
oldBytes = oldBytes[len(oldBytes)-maxSize:]
}
}
// open
f_neko_log, err = os.OpenFile(path, os.O_RDWR|os.O_APPEND|os.O_CREATE, 0644)
if err == nil {
f_neko_log.Write(oldBytes)
} else {
log.Println("error open log", err)
}
//
LogWriter = &logWriter{
files: []io.Writer{os.Stdout, f_neko_log},
}
// setup std log
log.SetFlags(log.LstdFlags | log.LUTC)
log.SetOutput(LogWriter)
}
type logWriter struct {
files []io.Writer
}
func (w *logWriter) Write(p []byte) (n int, err error) {
for _, file := range w.files {
if file == nil {
continue
}
n, err = file.Write(p)
if err != nil {
return
}
}
return
}

View File

@@ -1,95 +0,0 @@
package protect_server
import (
"fmt"
"log"
"net"
"os"
"os/signal"
"reflect"
"syscall"
)
func getOneFd(socket int) (int, error) {
// recvmsg
buf := make([]byte, syscall.CmsgSpace(4))
_, _, _, _, err := syscall.Recvmsg(socket, nil, buf, 0)
if err != nil {
return 0, err
}
// parse control msgs
var msgs []syscall.SocketControlMessage
msgs, err = syscall.ParseSocketControlMessage(buf)
if len(msgs) != 1 {
return 0, fmt.Errorf("invaild msgs count: %d", len(msgs))
}
var fds []int
fds, err = syscall.ParseUnixRights(&msgs[0])
if len(fds) != 1 {
return 0, fmt.Errorf("invaild fds count: %d", len(fds))
}
return fds[0], nil
}
// GetFdFromConn get net.Conn's file descriptor.
func GetFdFromConn(l net.Conn) int {
v := reflect.ValueOf(l)
netFD := reflect.Indirect(reflect.Indirect(v).FieldByName("fd"))
pfd := reflect.Indirect(netFD.FieldByName("pfd"))
fd := int(pfd.FieldByName("Sysfd").Int())
return fd
}
func ServeProtect(path string, fwmark int) {
fmt.Println("ServeProtect", path, fwmark)
os.Remove(path)
defer os.Remove(path)
l, err := net.ListenUnix("unix", &net.UnixAddr{Name: path, Net: "unix"})
if err != nil {
log.Fatal(err)
}
defer l.Close()
os.Chmod(path, 0777)
go func() {
for {
c, err := l.Accept()
if err != nil {
log.Println("Accept:", err)
return
}
go func() {
socket := GetFdFromConn(c)
defer c.Close()
fd, err := getOneFd(socket)
if err != nil {
log.Println("getOneFd:", err)
return
}
defer syscall.Close(fd)
if err := syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, syscall.SO_MARK, fwmark); err != nil {
log.Println("syscall.SetsockoptInt:", err)
}
if err == nil {
c.Write([]byte{1})
} else {
c.Write([]byte{0})
}
}()
}
}()
sigCh := make(chan os.Signal, 1)
signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM)
<-sigCh
}

View File

@@ -1,5 +0,0 @@
//go:build !linux
package protect_server
func ServeProtect(path string, fwmark int) {}

View File

@@ -1,65 +0,0 @@
package speedtest
import (
"context"
"fmt"
"log"
"math/rand"
"net"
"net/http"
"strings"
"time"
)
func UrlTest(client *http.Client, link string, timeout int32) (int32, error) {
if client == nil {
return 0, fmt.Errorf("no client")
}
// Test handshake time
var time_start time.Time
var times = 1
var rtt_times = 1
// Test RTT "true delay"
if link2 := strings.TrimLeft(link, "true"); link != link2 {
link = link2
times = 3
rtt_times = 2
}
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(timeout)*time.Millisecond)
defer cancel()
req, err := http.NewRequestWithContext(ctx, "GET", link, nil)
req.Header.Set("User-Agent", fmt.Sprintf("curl/7.%d.%d", rand.Int()%84, rand.Int()%2))
if err != nil {
return 0, err
}
for i := 0; i < times; i++ {
if i == 1 || times == 1 {
time_start = time.Now()
}
resp, err := client.Do(req)
if err != nil {
log.Println("Url test failed:", err)
return 0, err
}
resp.Body.Close()
}
return int32(time.Since(time_start).Milliseconds() / int64(rtt_times)), nil
}
func TcpPing(address string, timeout int32) (ms int32, err error) {
startTime := time.Now()
c, err := net.DialTimeout("tcp", address, time.Duration(timeout)*time.Millisecond)
endTime := time.Now()
if err == nil {
ms = int32(endTime.Sub(startTime).Milliseconds())
c.Close()
}
return
}

View File

@@ -22,14 +22,15 @@ pushd go/cmd/updater
popd popd
#### Go: nekoray_core #### #### Go: nekoray_core ####
neko_common="github.com/matsuridayo/libneko/neko_common"
pushd ../v2ray-core pushd ../v2ray-core
version_v2ray=$(git log --pretty=format:'%h' -n 1) version_v2ray=$(git log --pretty=format:'%h' -n 1)
popd popd
pushd go/cmd/nekoray_core pushd go/cmd/nekoray_core
go build -v -o $DEST -trimpath -ldflags "-w -s -X neko/pkg/neko_common.Version_v2ray=$version_v2ray -X neko/pkg/neko_common.Version_neko=$version_standalone" go build -v -o $DEST -trimpath -ldflags "-w -s -X $neko_common.Version_v2ray=$version_v2ray -X $neko_common.Version_neko=$version_standalone"
popd popd
#### Go: nekobox_core #### #### Go: nekobox_core ####
pushd go/cmd/nekobox_core pushd go/cmd/nekobox_core
go build -v -o $DEST -trimpath -ldflags "-w -s -X neko/pkg/neko_common.Version_neko=$version_standalone" -tags "with_gvisor,with_quic,with_wireguard,with_utls,with_v2ray_api" go build -v -o $DEST -trimpath -ldflags "-w -s -X $neko_common.Version_neko=$version_standalone" -tags "with_gvisor,with_quic,with_wireguard,with_utls,with_v2ray_api"
popd popd

View File

@@ -2,7 +2,7 @@
#ifndef NKR_NO_GRPC #ifndef NKR_NO_GRPC
#include "go/gen/libcore.pb.h" #include "go/grpc_server/gen/libcore.pb.h"
#include <QString> #include <QString>
namespace QtGrpc { namespace QtGrpc {

View File

@@ -174,6 +174,9 @@ void MainWindow::speedtest_current() {
last_test_time = QTime::currentTime(); last_test_time = QTime::currentTime();
runOnUiThread([=] { runOnUiThread([=] {
if (!result.error().empty()) {
MW_show_log(QString("UrlTest error: %1").arg(result.error().c_str()));
}
if (latency <= 0) { if (latency <= 0) {
ui->label_running->setText(tr("Test Result") + ": " + tr("Unavailable")); ui->label_running->setText(tr("Test Result") + ": " + tr("Unavailable"));
} else if (latency > 0) { } else if (latency > 0) {