diff --git a/common/counter/conn.go b/common/counter/conn.go index 8f9db03..e90c1ef 100644 --- a/common/counter/conn.go +++ b/common/counter/conn.go @@ -24,23 +24,23 @@ func NewConnCounter(conn net.Conn, s *TrafficStorage) net.Conn { ExtendedConn: bufio.NewExtendedConn(conn), storage: s, readFunc: func(n int64) { - s.DownCounter.Add(n) + s.UpCounter.Add(n) }, writeFunc: func(n int64) { - s.UpCounter.Add(n) + s.DownCounter.Add(n) }, } } func (c *ConnCounter) Read(b []byte) (n int, err error) { n, err = c.ExtendedConn.Read(b) - c.storage.DownCounter.Store(int64(n)) + c.storage.UpCounter.Store(int64(n)) return } func (c *ConnCounter) Write(b []byte) (n int, err error) { n, err = c.ExtendedConn.Write(b) - c.storage.UpCounter.Store(int64(n)) + c.storage.DownCounter.Store(int64(n)) return } @@ -50,7 +50,7 @@ func (c *ConnCounter) ReadBuffer(buffer *buf.Buffer) error { return err } if buffer.Len() > 0 { - c.storage.DownCounter.Add(int64(buffer.Len())) + c.storage.UpCounter.Add(int64(buffer.Len())) } return nil } @@ -62,7 +62,7 @@ func (c *ConnCounter) WriteBuffer(buffer *buf.Buffer) error { return err } if dataLen > 0 { - c.storage.UpCounter.Add(dataLen) + c.storage.DownCounter.Add(dataLen) } return nil } @@ -95,10 +95,10 @@ func NewPacketConnCounter(conn network.PacketConn, s *TrafficStorage) network.Pa PacketConn: conn, storage: s, readFunc: func(n int64) { - s.DownCounter.Add(n) + s.UpCounter.Add(n) }, writeFunc: func(n int64) { - s.UpCounter.Add(n) + s.DownCounter.Add(n) }, } } @@ -108,7 +108,7 @@ func (p *PacketConnCounter) ReadPacket(buff *buf.Buffer) (destination M.Socksadd if err != nil { return } - p.storage.DownCounter.Add(int64(buff.Len())) + p.storage.UpCounter.Add(int64(buff.Len())) return } @@ -119,7 +119,7 @@ func (p *PacketConnCounter) WritePacket(buff *buf.Buffer, destination M.Socksadd return } if n > 0 { - p.storage.UpCounter.Add(int64(n)) + p.storage.DownCounter.Add(int64(n)) } return } diff --git a/conf/node.go b/conf/node.go index 9a5d815..aa00ddd 100644 --- a/conf/node.go +++ b/conf/node.go @@ -33,9 +33,9 @@ type Options struct { CertConfig *CertConfig `json:"CertConfig"` } -func (n *NodeConfig) UnmarshalJSON(b []byte) (err error) { +func (n *NodeConfig) UnmarshalJSON(data []byte) (err error) { r := rawNodeConfig{} - err = json.Unmarshal(b, &r) + err = json.Unmarshal(data, &r) if err != nil { return err } @@ -48,14 +48,14 @@ func (n *NodeConfig) UnmarshalJSON(b []byte) (err error) { n.ApiConfig = ApiConfig{ Timeout: 30, } - err = json.Unmarshal(b, &n.ApiConfig) + err = json.Unmarshal(data, &n.ApiConfig) if err != nil { return } } - if r.OptRaw != nil { - err = json.Unmarshal(*r.OptRaw, &n.Options) + data = *r.OptRaw + err = json.Unmarshal(data, &n.Options) if err != nil { return } @@ -65,18 +65,18 @@ func (n *NodeConfig) UnmarshalJSON(b []byte) (err error) { ListenIP: "0.0.0.0", SendIP: "0.0.0.0", } - err = json.Unmarshal(b, &n.Options) + err = json.Unmarshal(data, &n.Options) if err != nil { return } - switch n.Options.Core { - case "xray": - n.Options.XrayOptions = NewXrayOptions() - return json.Unmarshal(b, n.Options.XrayOptions) - case "sing": - n.Options.SingOptions = NewSingOptions() - return json.Unmarshal(b, n.Options.SingOptions) - } + } + switch n.Options.Core { + case "xray": + n.Options.XrayOptions = NewXrayOptions() + return json.Unmarshal(data, n.Options.XrayOptions) + case "sing": + n.Options.SingOptions = NewSingOptions() + return json.Unmarshal(data, n.Options.SingOptions) } return } diff --git a/conf/sing.go b/conf/sing.go index cdf4159..9501e67 100644 --- a/conf/sing.go +++ b/conf/sing.go @@ -1,7 +1,12 @@ package conf +import ( + "github.com/inazumav/sing-box/option" +) + type SingConfig struct { LogConfig SingLogConfig `json:"Log"` + NtpConfig SingNtpConfig `json:"NTP"` OriginalPath string `json:"OriginalPath"` } @@ -18,6 +23,11 @@ func NewSingConfig() *SingConfig { Level: "error", Timestamp: true, }, + NtpConfig: SingNtpConfig{ + Enable: false, + Server: "time.apple.com", + ServerPort: 0, + }, } } @@ -25,10 +35,17 @@ type SingOptions struct { EnableProxyProtocol bool `json:"EnableProxyProtocol"` TCPFastOpen bool `json:"EnableTFO"` SniffEnabled bool `json:"EnableSniff"` + DomainStrategy option.DomainStrategy `json:"DomainStrategy"` SniffOverrideDestination bool `json:"SniffOverrideDestination"` FallBackConfigs *FallBackConfigForSing `json:"FallBackConfigs"` } +type SingNtpConfig struct { + Enable bool `json:"Enable"` + Server string `json:"Server"` + ServerPort uint16 `json:"ServerPort"` +} + type FallBackConfigForSing struct { // sing-box FallBack FallBack `json:"FallBack"` diff --git a/core/sing/node.go b/core/sing/node.go index 8670c48..ea8bd69 100644 --- a/core/sing/node.go +++ b/core/sing/node.go @@ -38,6 +38,7 @@ func getInboundOptions(tag string, info *panel.NodeInfo, c *conf.Options) (optio InboundOptions: option.InboundOptions{ SniffEnabled: c.SingOptions.SniffEnabled, SniffOverrideDestination: c.SingOptions.SniffOverrideDestination, + DomainStrategy: c.SingOptions.DomainStrategy, }, } var tls option.InboundTLSOptions @@ -86,33 +87,43 @@ func getInboundOptions(tag string, info *panel.NodeInfo, c *conf.Options) (optio case "tcp": t.Type = "" case "ws": - network := WsNetworkConfig{} - err := json.Unmarshal(n.NetworkSettings, &network) - if err != nil { - return option.Inbound{}, fmt.Errorf("decode NetworkSettings error: %s", err) - } - var u *url.URL - u, err = url.Parse(network.Path) - if err != nil { - 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, + var ( + path string + ed int + headers map[string]option.Listable[string] + ) + if len(n.NetworkSettings) != 0 { + network := WsNetworkConfig{} + err := json.Unmarshal(n.NetworkSettings, &network) + if err != nil { + return option.Inbound{}, fmt.Errorf("decode NetworkSettings error: %s", err) + } + var u *url.URL + u, err = url.Parse(network.Path) + if err != nil { + return option.Inbound{}, fmt.Errorf("parse path error: %s", err) + } + path = u.Path + ed, _ = strconv.Atoi(u.Query().Get("ed")) + headers = make(map[string]option.Listable[string], len(network.Headers)) + for k, v := range network.Headers { + headers[k] = option.Listable[string]{ + v, + } } } t.WebsocketOptions = option.V2RayWebsocketOptions{ - Path: u.Path, + Path: path, EarlyDataHeaderName: "Sec-WebSocket-Protocol", MaxEarlyData: uint32(ed), - Headers: h, + Headers: headers, } case "grpc": - err := json.Unmarshal(n.NetworkSettings, &t.GRPCOptions) - if err != nil { - return option.Inbound{}, fmt.Errorf("decode NetworkSettings error: %s", err) + if len(n.NetworkSettings) != 0 { + err := json.Unmarshal(n.NetworkSettings, &t.GRPCOptions) + if err != nil { + return option.Inbound{}, fmt.Errorf("decode NetworkSettings error: %s", err) + } } } if info.Type == "vless" { diff --git a/core/sing/sing.go b/core/sing/sing.go index 30bece9..8c50855 100644 --- a/core/sing/sing.go +++ b/core/sing/sing.go @@ -48,7 +48,7 @@ func New(c *conf.CoreConfig) (vCore.Core, error) { return nil, fmt.Errorf("open original config error: %s", err) } defer f.Close() - err = json.NewDecoder(f).Decode(options) + err = json.NewDecoder(f).Decode(&options) if err != nil { return nil, fmt.Errorf("decode original config error: %s", err) } @@ -59,6 +59,14 @@ func New(c *conf.CoreConfig) (vCore.Core, error) { Timestamp: c.SingConfig.LogConfig.Timestamp, Output: c.SingConfig.LogConfig.Output, } + options.NTP = &option.NTPOptions{ + Enabled: c.SingConfig.NtpConfig.Enable, + WriteToSystem: true, + ServerOptions: option.ServerOptions{ + Server: c.SingConfig.NtpConfig.Server, + ServerPort: c.SingConfig.NtpConfig.ServerPort, + }, + } ctx := context.Background() ctx = pause.ContextWithDefaultManager(ctx) createdAt := time.Now() diff --git a/core/xray/inbound.go b/core/xray/inbound.go index 79268d3..68e9f52 100644 --- a/core/xray/inbound.go +++ b/core/xray/inbound.go @@ -22,7 +22,7 @@ func buildInbound(option *conf.Options, nodeInfo *panel.NodeInfo, tag string) (* var err error var network string switch nodeInfo.Type { - case "v2ray": + case "vmess", "vless": err = buildV2ray(option, nodeInfo, in) network = nodeInfo.VAllss.Network case "trojan": diff --git a/example/config.json b/example/config.json index 3d087f7..51ee651 100644 --- a/example/config.json +++ b/example/config.json @@ -16,6 +16,13 @@ "Level": "error", "Timestamp": true + }, + "NTP": { + // 同 SingBox ntp 部分配置 + // VMess VLESS 建议开启 + "Enable": true, + "Server": "time.apple.com", + "ServerPort": 0 } // More }, @@ -56,7 +63,12 @@ // 开启 Proxy Protocol,参见 https://github.com/haproxy/haproxy/blob/master/doc/proxy-protocol.txt "EnableProxyProtocol": false, // 开启 TCP Fast Open - "EnableTFO": true + "EnableTFO": true, + + // 设置 Domain Strategy + // 可选 prefer_ipv4 / prefer_ipv6 / ipv4_only / ipv6_only + "DomainStrategy": "ipv4_only", + // More } /*, @@ -74,6 +86,7 @@ "Core": "sing", "EnableProxyProtocol": true, "EnableTFO": true + "DomainStrategy": "ipv4_only", } }, {