update sing-box support

This commit is contained in:
Yuzuki616
2023-07-29 18:47:47 +08:00
parent 2812b366b3
commit 96493346f9
34 changed files with 418 additions and 297 deletions

View File

@@ -2,6 +2,12 @@ package sing
import (
"net"
"strings"
"sync"
"github.com/Yuzuki616/V2bX/common/rate"
"github.com/Yuzuki616/V2bX/limiter"
"github.com/Yuzuki616/V2bX/common/counter"
"github.com/inazumav/sing-box/adapter"
@@ -17,7 +23,7 @@ func NewHookServer(logger log.Logger) *HookServer {
return &HookServer{
hooker: &Hooker{
logger: logger,
counter: make(map[string]*counter.TrafficCounter),
counter: sync.Map{},
},
}
}
@@ -40,19 +46,37 @@ func (h *HookServer) Hooker() *Hooker {
type Hooker struct {
logger log.Logger
counter map[string]*counter.TrafficCounter
counter sync.Map
}
func (h *Hooker) RoutedConnection(inbound string, outbound string, user string, conn net.Conn) net.Conn {
if c, ok := h.counter[inbound]; ok {
l, err := limiter.GetLimiter(inbound)
if err != nil {
log.Error("get limiter for ", inbound, " error: ", err)
}
ip, _, _ := strings.Cut(conn.RemoteAddr().String(), ":")
if b, r := l.CheckLimit(user, ip, true); r {
conn.Close()
h.logger.Error("[", inbound, "] ", "Limited ", user, " by ip or conn")
return conn
} else if b != nil {
conn = rate.NewConnRateLimiter(conn, b)
}
if c, ok := h.counter.Load(inbound); ok {
return counter.NewConnCounter(conn, c.(*counter.TrafficCounter).GetCounter(user))
} else {
c := counter.NewTrafficCounter()
h.counter.Store(inbound, c)
return counter.NewConnCounter(conn, c.GetCounter(user))
}
return conn
}
func (h *Hooker) RoutedPacketConnection(inbound string, outbound string, user string, conn N.PacketConn) N.PacketConn {
if c, ok := h.counter[inbound]; ok {
if c, ok := h.counter.Load(inbound); ok {
return counter.NewPacketConnCounter(conn, c.(*counter.TrafficCounter).GetCounter(user))
} else {
c := counter.NewTrafficCounter()
h.counter.Store(inbound, c)
return counter.NewPacketConnCounter(conn, c.GetCounter(user))
}
return conn
}

View File

@@ -21,12 +21,17 @@ import (
)
type WsNetworkConfig struct {
Path string `json:"path"`
Path string `json:"path"`
Headers map[string]string `json:"headers"`
}
func getInboundOptions(tag string, info *panel.NodeInfo, c *conf.ControllerConfig) (option.Inbound, error) {
addr, _ := netip.ParseAddr("0.0.0.0")
func getInboundOptions(tag string, info *panel.NodeInfo, c *conf.Options) (option.Inbound, error) {
addr, err := netip.ParseAddr(c.ListenIP)
if err != nil {
return option.Inbound{}, fmt.Errorf("the listen ip not vail")
}
listen := option.ListenOptions{
//ProxyProtocol: true,
Listen: (*option.ListenAddress)(&addr),
ListenPort: uint16(info.Port),
}
@@ -47,6 +52,7 @@ func getInboundOptions(tag string, info *panel.NodeInfo, c *conf.ControllerConfi
}
switch info.Network {
case "tcp":
t.Type = ""
case "ws":
network := WsNetworkConfig{}
err := json.Unmarshal(info.NetworkSettings, &network)
@@ -59,14 +65,22 @@ func getInboundOptions(tag string, info *panel.NodeInfo, c *conf.ControllerConfi
return option.Inbound{}, fmt.Errorf("parse path error: %s", err)
}
ed, _ := strconv.Atoi(u.Query().Get("ed"))
h := make(map[string]option.Listable[string], len(network.Headers))
for k, v := range network.Headers {
h[k] = option.Listable[string]{
v,
}
}
t.WebsocketOptions = option.V2RayWebsocketOptions{
Path: u.Path,
EarlyDataHeaderName: "Sec-WebSocket-Protocol",
MaxEarlyData: uint32(ed),
Headers: h,
}
case "grpc":
t.GRPCOptions = option.V2RayGRPCOptions{
ServiceName: info.ServerName,
err := json.Unmarshal(info.NetworkSettings, &t.GRPCOptions)
if err != nil {
return option.Inbound{}, fmt.Errorf("decode NetworkSettings error: %s", err)
}
}
in.VMessOptions = option.VMessInboundOptions{
@@ -96,7 +110,7 @@ func getInboundOptions(tag string, info *panel.NodeInfo, c *conf.ControllerConfi
return in, nil
}
func (b *Box) AddNode(tag string, info *panel.NodeInfo, config *conf.ControllerConfig) error {
func (b *Box) AddNode(tag string, info *panel.NodeInfo, config *conf.Options) error {
c, err := getInboundOptions(tag, info, config)
if err != nil {
return err

View File

@@ -39,8 +39,14 @@ func init() {
vCore.RegisterCore("sing", New)
}
func New(_ *conf.CoreConfig) (vCore.Core, error) {
func New(c *conf.CoreConfig) (vCore.Core, error) {
options := option.Options{}
options.Log = &option.LogOptions{
Disabled: c.SingConfig.LogConfig.Disabled,
Level: c.SingConfig.LogConfig.Level,
Timestamp: c.SingConfig.LogConfig.Timestamp,
Output: c.SingConfig.LogConfig.Output,
}
ctx := context.Background()
createdAt := time.Now()
experimentalOptions := common.PtrValueOrDefault(options.Experimental)

View File

@@ -4,6 +4,7 @@ import (
"errors"
"github.com/Yuzuki616/V2bX/api/panel"
"github.com/Yuzuki616/V2bX/common/counter"
"github.com/Yuzuki616/V2bX/core"
"github.com/inazumav/sing-box/inbound"
"github.com/inazumav/sing-box/option"
@@ -36,7 +37,8 @@ func (b *Box) AddUsers(p *core.AddUsersParams) (added int, err error) {
}
func (b *Box) GetUserTraffic(tag, uuid string, reset bool) (up int64, down int64) {
if c, ok := b.hookServer.Hooker().counter[tag]; ok {
if v, ok := b.hookServer.Hooker().counter.Load(tag); ok {
c := v.(*counter.TrafficCounter)
up = c.GetUpCount(uuid)
down = c.GetDownCount(uuid)
if reset {