浏览代码

Fix hysteria bytes format

世界 5 月之前
父节点
当前提交
2d7df1e1f2
共有 10 个文件被更改,包括 53 次插入253 次删除
  1. 0 158
      common/humanize/bytes.go
  2. 3 3
      debug.go
  3. 4 4
      debug_http.go
  4. 3 3
      experimental/libbox/setup.go
  5. 1 1
      go.mod
  6. 2 2
      go.sum
  7. 9 38
      option/debug.go
  8. 23 21
      option/hysteria.go
  9. 4 12
      protocol/hysteria/inbound.go
  10. 4 11
      protocol/hysteria/outbound.go

+ 0 - 158
common/humanize/bytes.go

@@ -1,158 +0,0 @@
-package humanize
-
-import (
-	"fmt"
-	"math"
-	"strconv"
-	"strings"
-	"unicode"
-)
-
-// IEC Sizes.
-// kibis of bits
-const (
-	Byte = 1 << (iota * 10)
-	KiByte
-	MiByte
-	GiByte
-	TiByte
-	PiByte
-	EiByte
-)
-
-// SI Sizes.
-const (
-	IByte = 1
-	KByte = IByte * 1000
-	MByte = KByte * 1000
-	GByte = MByte * 1000
-	TByte = GByte * 1000
-	PByte = TByte * 1000
-	EByte = PByte * 1000
-)
-
-var defaultSizeTable = map[string]uint64{
-	"b":   Byte,
-	"kib": KiByte,
-	"kb":  KByte,
-	"mib": MiByte,
-	"mb":  MByte,
-	"gib": GiByte,
-	"gb":  GByte,
-	"tib": TiByte,
-	"tb":  TByte,
-	"pib": PiByte,
-	"pb":  PByte,
-	"eib": EiByte,
-	"eb":  EByte,
-	// Without suffix
-	"":   Byte,
-	"ki": KiByte,
-	"k":  KByte,
-	"mi": MiByte,
-	"m":  MByte,
-	"gi": GiByte,
-	"g":  GByte,
-	"ti": TiByte,
-	"t":  TByte,
-	"pi": PiByte,
-	"p":  PByte,
-	"ei": EiByte,
-	"e":  EByte,
-}
-
-var memorysSizeTable = map[string]uint64{
-	"b":  Byte,
-	"kb": KiByte,
-	"mb": MiByte,
-	"gb": GiByte,
-	"tb": TiByte,
-	"pb": PiByte,
-	"eb": EiByte,
-	"":   Byte,
-	"k":  KiByte,
-	"m":  MiByte,
-	"g":  GiByte,
-	"t":  TiByte,
-	"p":  PiByte,
-	"e":  EiByte,
-}
-
-var (
-	defaultSizes = []string{"B", "kB", "MB", "GB", "TB", "PB", "EB"}
-	iSizes       = []string{"B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB"}
-)
-
-func Bytes(s uint64) string {
-	return humanateBytes(s, 1000, defaultSizes)
-}
-
-func MemoryBytes(s uint64) string {
-	return humanateBytes(s, 1024, defaultSizes)
-}
-
-func IBytes(s uint64) string {
-	return humanateBytes(s, 1024, iSizes)
-}
-
-func logn(n, b float64) float64 {
-	return math.Log(n) / math.Log(b)
-}
-
-func humanateBytes(s uint64, base float64, sizes []string) string {
-	if s < 10 {
-		return fmt.Sprintf("%d B", s)
-	}
-	e := math.Floor(logn(float64(s), base))
-	suffix := sizes[int(e)]
-	val := math.Floor(float64(s)/math.Pow(base, e)*10+0.5) / 10
-	f := "%.0f %s"
-	if val < 10 {
-		f = "%.1f %s"
-	}
-
-	return fmt.Sprintf(f, val, suffix)
-}
-
-func ParseBytes(s string) (uint64, error) {
-	return parseBytes0(s, defaultSizeTable)
-}
-
-func ParseMemoryBytes(s string) (uint64, error) {
-	return parseBytes0(s, memorysSizeTable)
-}
-
-func parseBytes0(s string, sizeTable map[string]uint64) (uint64, error) {
-	lastDigit := 0
-	hasComma := false
-	for _, r := range s {
-		if !(unicode.IsDigit(r) || r == '.' || r == ',') {
-			break
-		}
-		if r == ',' {
-			hasComma = true
-		}
-		lastDigit++
-	}
-
-	num := s[:lastDigit]
-	if hasComma {
-		num = strings.Replace(num, ",", "", -1)
-	}
-
-	f, err := strconv.ParseFloat(num, 64)
-	if err != nil {
-		return 0, err
-	}
-
-	extra := strings.ToLower(strings.TrimSpace(s[lastDigit:]))
-	if m, ok := sizeTable[extra]; ok {
-		f *= float64(m)
-		if f >= math.MaxUint64 {
-			return 0, fmt.Errorf("too large: %v", s)
-		}
-		return uint64(f), nil
-	}
-
-	return 0, fmt.Errorf("unhandled size name: %v", extra)
-}

+ 3 - 3
debug.go

@@ -24,9 +24,9 @@ func applyDebugOptions(options option.DebugOptions) {
 	if options.TraceBack != "" {
 		debug.SetTraceback(options.TraceBack)
 	}
-	if options.MemoryLimit != 0 {
-		debug.SetMemoryLimit(int64(float64(options.MemoryLimit) / 1.5))
-		conntrack.MemoryLimit = uint64(options.MemoryLimit)
+	if options.MemoryLimit.Value() != 0 {
+		debug.SetMemoryLimit(int64(float64(options.MemoryLimit.Value()) / 1.5))
+		conntrack.MemoryLimit = options.MemoryLimit.Value()
 	}
 	if options.OOMKiller != nil {
 		conntrack.KillerEnabled = *options.OOMKiller

+ 4 - 4
debug_http.go

@@ -7,9 +7,9 @@ import (
 	"runtime/debug"
 	"strings"
 
-	"github.com/sagernet/sing-box/common/humanize"
 	"github.com/sagernet/sing-box/log"
 	"github.com/sagernet/sing-box/option"
+	"github.com/sagernet/sing/common/byteformats"
 	E "github.com/sagernet/sing/common/exceptions"
 	"github.com/sagernet/sing/common/json"
 	"github.com/sagernet/sing/common/json/badjson"
@@ -38,9 +38,9 @@ func applyDebugListenOption(options option.DebugOptions) {
 			runtime.ReadMemStats(&memStats)
 
 			var memObject badjson.JSONObject
-			memObject.Put("heap", humanize.MemoryBytes(memStats.HeapInuse))
-			memObject.Put("stack", humanize.MemoryBytes(memStats.StackInuse))
-			memObject.Put("idle", humanize.MemoryBytes(memStats.HeapIdle-memStats.HeapReleased))
+			memObject.Put("heap", byteformats.FormatMemoryBytes(memStats.HeapInuse))
+			memObject.Put("stack", byteformats.FormatMemoryBytes(memStats.StackInuse))
+			memObject.Put("idle", byteformats.FormatMemoryBytes(memStats.HeapIdle-memStats.HeapReleased))
 			memObject.Put("goroutines", runtime.NumGoroutine())
 			memObject.Put("rss", rusageMaxRSS())
 

+ 3 - 3
experimental/libbox/setup.go

@@ -7,10 +7,10 @@ import (
 	"strconv"
 	"time"
 
-	"github.com/sagernet/sing-box/common/humanize"
 	C "github.com/sagernet/sing-box/constant"
 	"github.com/sagernet/sing-box/experimental/locale"
 	"github.com/sagernet/sing-box/log"
+	"github.com/sagernet/sing/common/byteformats"
 )
 
 var (
@@ -75,11 +75,11 @@ func Version() string {
 }
 
 func FormatBytes(length int64) string {
-	return humanize.Bytes(uint64(length))
+	return byteformats.FormatBytes(uint64(length))
 }
 
 func FormatMemoryBytes(length int64) string {
-	return humanize.MemoryBytes(uint64(length))
+	return byteformats.FormatMemoryBytes(uint64(length))
 }
 
 func FormatDuration(duration int64) string {

+ 1 - 1
go.mod

@@ -26,7 +26,7 @@ require (
 	github.com/sagernet/gvisor v0.0.0-20241123041152-536d05261cff
 	github.com/sagernet/quic-go v0.49.0-beta.1
 	github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691
-	github.com/sagernet/sing v0.6.7
+	github.com/sagernet/sing v0.6.8-0.20250429070844-b63643251ed5
 	github.com/sagernet/sing-dns v0.4.2
 	github.com/sagernet/sing-mux v0.3.1
 	github.com/sagernet/sing-quic v0.4.1-0.20250423030647-0eb05f373a76

+ 2 - 2
go.sum

@@ -119,8 +119,8 @@ github.com/sagernet/quic-go v0.49.0-beta.1/go.mod h1:uesWD1Ihrldq1M3XtjuEvIUqi8W
 github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 h1:5Th31OC6yj8byLGkEnIYp6grlXfo1QYUfiYFGjewIdc=
 github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691/go.mod h1:B8lp4WkQ1PwNnrVMM6KyuFR20pU8jYBD+A4EhJovEXU=
 github.com/sagernet/sing v0.2.18/go.mod h1:OL6k2F0vHmEzXz2KW19qQzu172FDgSbUSODylighuVo=
-github.com/sagernet/sing v0.6.7 h1:NIWBLZ9AUWDXAQBKGleKwsitbQrI9M0nqoheXhUKnrI=
-github.com/sagernet/sing v0.6.7/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak=
+github.com/sagernet/sing v0.6.8-0.20250429070844-b63643251ed5 h1:j5r2x3Lazb1giycHFxICc201LSyDn3ZH+ywa+8duNxo=
+github.com/sagernet/sing v0.6.8-0.20250429070844-b63643251ed5/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak=
 github.com/sagernet/sing-dns v0.4.2 h1:cWe2XPUBFLep2j9kJV4Epg3bctGhMvrrl/sWi9Wszfg=
 github.com/sagernet/sing-dns v0.4.2/go.mod h1:dweQs54ng2YGzoJfz+F9dGuDNdP5pJ3PLeggnK5VWc8=
 github.com/sagernet/sing-mux v0.3.1 h1:kvCc8HyGAskDHDQ0yQvoTi/7J4cZPB/VJMsAM3MmdQI=

+ 9 - 38
option/debug.go

@@ -1,43 +1,14 @@
 package option
 
-import (
-	"github.com/sagernet/sing-box/common/humanize"
-	"github.com/sagernet/sing/common/json"
-)
+import "github.com/sagernet/sing/common/byteformats"
 
 type DebugOptions struct {
-	Listen       string      `json:"listen,omitempty"`
-	GCPercent    *int        `json:"gc_percent,omitempty"`
-	MaxStack     *int        `json:"max_stack,omitempty"`
-	MaxThreads   *int        `json:"max_threads,omitempty"`
-	PanicOnFault *bool       `json:"panic_on_fault,omitempty"`
-	TraceBack    string      `json:"trace_back,omitempty"`
-	MemoryLimit  MemoryBytes `json:"memory_limit,omitempty"`
-	OOMKiller    *bool       `json:"oom_killer,omitempty"`
-}
-
-type MemoryBytes uint64
-
-func (l MemoryBytes) MarshalJSON() ([]byte, error) {
-	return json.Marshal(humanize.MemoryBytes(uint64(l)))
-}
-
-func (l *MemoryBytes) UnmarshalJSON(bytes []byte) error {
-	var valueInteger int64
-	err := json.Unmarshal(bytes, &valueInteger)
-	if err == nil {
-		*l = MemoryBytes(valueInteger)
-		return nil
-	}
-	var valueString string
-	err = json.Unmarshal(bytes, &valueString)
-	if err != nil {
-		return err
-	}
-	parsedValue, err := humanize.ParseMemoryBytes(valueString)
-	if err != nil {
-		return err
-	}
-	*l = MemoryBytes(parsedValue)
-	return nil
+	Listen       string                   `json:"listen,omitempty"`
+	GCPercent    *int                     `json:"gc_percent,omitempty"`
+	MaxStack     *int                     `json:"max_stack,omitempty"`
+	MaxThreads   *int                     `json:"max_threads,omitempty"`
+	PanicOnFault *bool                    `json:"panic_on_fault,omitempty"`
+	TraceBack    string                   `json:"trace_back,omitempty"`
+	MemoryLimit  *byteformats.MemoryBytes `json:"memory_limit,omitempty"`
+	OOMKiller    *bool                    `json:"oom_killer,omitempty"`
 }

+ 23 - 21
option/hysteria.go

@@ -1,17 +1,19 @@
 package option
 
+import "github.com/sagernet/sing/common/byteformats"
+
 type HysteriaInboundOptions struct {
 	ListenOptions
-	Up                  string         `json:"up,omitempty"`
-	UpMbps              int            `json:"up_mbps,omitempty"`
-	Down                string         `json:"down,omitempty"`
-	DownMbps            int            `json:"down_mbps,omitempty"`
-	Obfs                string         `json:"obfs,omitempty"`
-	Users               []HysteriaUser `json:"users,omitempty"`
-	ReceiveWindowConn   uint64         `json:"recv_window_conn,omitempty"`
-	ReceiveWindowClient uint64         `json:"recv_window_client,omitempty"`
-	MaxConnClient       int            `json:"max_conn_client,omitempty"`
-	DisableMTUDiscovery bool           `json:"disable_mtu_discovery,omitempty"`
+	Up                  *byteformats.NetworkBytesCompat `json:"up,omitempty"`
+	UpMbps              int                             `json:"up_mbps,omitempty"`
+	Down                *byteformats.NetworkBytesCompat `json:"down,omitempty"`
+	DownMbps            int                             `json:"down_mbps,omitempty"`
+	Obfs                string                          `json:"obfs,omitempty"`
+	Users               []HysteriaUser                  `json:"users,omitempty"`
+	ReceiveWindowConn   uint64                          `json:"recv_window_conn,omitempty"`
+	ReceiveWindowClient uint64                          `json:"recv_window_client,omitempty"`
+	MaxConnClient       int                             `json:"max_conn_client,omitempty"`
+	DisableMTUDiscovery bool                            `json:"disable_mtu_discovery,omitempty"`
 	InboundTLSOptionsContainer
 }
 
@@ -24,16 +26,16 @@ type HysteriaUser struct {
 type HysteriaOutboundOptions struct {
 	DialerOptions
 	ServerOptions
-	Up                  string      `json:"up,omitempty"`
-	UpMbps              int         `json:"up_mbps,omitempty"`
-	Down                string      `json:"down,omitempty"`
-	DownMbps            int         `json:"down_mbps,omitempty"`
-	Obfs                string      `json:"obfs,omitempty"`
-	Auth                []byte      `json:"auth,omitempty"`
-	AuthString          string      `json:"auth_str,omitempty"`
-	ReceiveWindowConn   uint64      `json:"recv_window_conn,omitempty"`
-	ReceiveWindow       uint64      `json:"recv_window,omitempty"`
-	DisableMTUDiscovery bool        `json:"disable_mtu_discovery,omitempty"`
-	Network             NetworkList `json:"network,omitempty"`
+	Up                  *byteformats.NetworkBytesCompat `json:"up,omitempty"`
+	UpMbps              int                             `json:"up_mbps,omitempty"`
+	Down                *byteformats.NetworkBytesCompat `json:"down,omitempty"`
+	DownMbps            int                             `json:"down_mbps,omitempty"`
+	Obfs                string                          `json:"obfs,omitempty"`
+	Auth                []byte                          `json:"auth,omitempty"`
+	AuthString          string                          `json:"auth_str,omitempty"`
+	ReceiveWindowConn   uint64                          `json:"recv_window_conn,omitempty"`
+	ReceiveWindow       uint64                          `json:"recv_window,omitempty"`
+	DisableMTUDiscovery bool                            `json:"disable_mtu_discovery,omitempty"`
+	Network             NetworkList                     `json:"network,omitempty"`
 	OutboundTLSOptionsContainer
 }

+ 4 - 12
protocol/hysteria/inbound.go

@@ -7,7 +7,6 @@ import (
 
 	"github.com/sagernet/sing-box/adapter"
 	"github.com/sagernet/sing-box/adapter/inbound"
-	"github.com/sagernet/sing-box/common/humanize"
 	"github.com/sagernet/sing-box/common/listener"
 	"github.com/sagernet/sing-box/common/tls"
 	C "github.com/sagernet/sing-box/constant"
@@ -16,7 +15,6 @@ import (
 	"github.com/sagernet/sing-quic/hysteria"
 	"github.com/sagernet/sing/common"
 	"github.com/sagernet/sing/common/auth"
-	E "github.com/sagernet/sing/common/exceptions"
 	M "github.com/sagernet/sing/common/metadata"
 	N "github.com/sagernet/sing/common/network"
 )
@@ -56,19 +54,13 @@ func NewInbound(ctx context.Context, router adapter.Router, logger log.ContextLo
 		tlsConfig: tlsConfig,
 	}
 	var sendBps, receiveBps uint64
-	if len(options.Up) > 0 {
-		sendBps, err = humanize.ParseBytes(options.Up)
-		if err != nil {
-			return nil, E.Cause(err, "invalid up speed format: ", options.Up)
-		}
+	if options.Up.Value() > 0 {
+		sendBps = options.Up.Value()
 	} else {
 		sendBps = uint64(options.UpMbps) * hysteria.MbpsToBps
 	}
-	if len(options.Down) > 0 {
-		receiveBps, err = humanize.ParseBytes(options.Down)
-		if err != nil {
-			return nil, E.Cause(err, "invalid down speed format: ", options.Down)
-		}
+	if options.Down.Value() > 0 {
+		receiveBps = options.Down.Value()
 	} else {
 		receiveBps = uint64(options.DownMbps) * hysteria.MbpsToBps
 	}

+ 4 - 11
protocol/hysteria/outbound.go

@@ -8,7 +8,6 @@ import (
 	"github.com/sagernet/sing-box/adapter"
 	"github.com/sagernet/sing-box/adapter/outbound"
 	"github.com/sagernet/sing-box/common/dialer"
-	"github.com/sagernet/sing-box/common/humanize"
 	"github.com/sagernet/sing-box/common/tls"
 	C "github.com/sagernet/sing-box/constant"
 	"github.com/sagernet/sing-box/log"
@@ -59,19 +58,13 @@ func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextL
 		password = string(options.Auth)
 	}
 	var sendBps, receiveBps uint64
-	if len(options.Up) > 0 {
-		sendBps, err = humanize.ParseBytes(options.Up)
-		if err != nil {
-			return nil, E.Cause(err, "invalid up speed format: ", options.Up)
-		}
+	if options.Up.Value() > 0 {
+		sendBps = options.Up.Value()
 	} else {
 		sendBps = uint64(options.UpMbps) * hysteria.MbpsToBps
 	}
-	if len(options.Down) > 0 {
-		receiveBps, err = humanize.ParseBytes(options.Down)
-		if err != nil {
-			return nil, E.Cause(err, "invalid down speed format: ", options.Down)
-		}
+	if options.Down.Value() > 0 {
+		receiveBps = options.Down.Value()
 	} else {
 		receiveBps = uint64(options.DownMbps) * hysteria.MbpsToBps
 	}