Compare commits

..

80 Commits

Author SHA1 Message Date
世界
49261c5521
documentation: Bump version 2025-04-28 23:28:57 +08:00
世界
b41ed2eec2
documentation: Fix anytls padding scheme description 2025-04-28 23:28:56 +08:00
安容
3f04e91aa0
Report invalid DNS address early 2025-04-28 23:28:56 +08:00
世界
14d901f291
Fix wireguard listen_port 2025-04-28 23:28:56 +08:00
世界
fefd910b12
clash-api: Add more meta api 2025-04-28 23:28:55 +08:00
世界
1d52f19101
Fix DNS lookup 2025-04-28 23:28:55 +08:00
世界
eedbde1181
Fix tailscale sending unexpected stuff 2025-04-28 23:28:55 +08:00
世界
f9af5a62f0
Fix fetch ECH configs 2025-04-28 23:28:55 +08:00
reletor
e994fbc76e
documentation: Minor fixes 2025-04-28 23:28:55 +08:00
caelansar
3f2213c313
Fix callback deletion in UDP transport 2025-04-28 23:28:54 +08:00
世界
07fe8fbe58
documentation: Try to make the play review happy 2025-04-28 23:28:54 +08:00
世界
f53bd4c1c5
Fix missing handling of legacy domain_strategy options 2025-04-28 23:28:54 +08:00
世界
a03688274e
Improve local DNS server 2025-04-28 23:28:54 +08:00
anytls
b64dfc5e80
Update anytls
Co-authored-by: anytls <anytls>
2025-04-28 23:27:10 +08:00
世界
1a0fc33044
Fix DNS dialer 2025-04-28 23:27:09 +08:00
世界
7eb2abcd27
release: Skip override version for iOS 2025-04-28 23:27:09 +08:00
iikira
2e80f08bcb
Fix UDP DNS server crash
Signed-off-by: iikira <i2@mail.iikira.com>
2025-04-28 23:27:09 +08:00
ReleTor
37764db502
Fix fetch ECH configs 2025-04-28 23:27:08 +08:00
世界
e5a569aeda
release: Update Go to 1.24.2 2025-04-28 23:27:08 +08:00
世界
581d3ffdae
Allow direct outbounds without domain_resolver 2025-04-28 23:27:08 +08:00
世界
0143ae2975
Fix Tailscale dialer 2025-04-28 23:27:08 +08:00
dyhkwong
2c0d4a3a18
Fix DNS over QUIC stream close 2025-04-28 23:27:08 +08:00
anytls
24d5ed47c9
Update anytls
Co-authored-by: anytls <anytls>
2025-04-28 23:27:08 +08:00
Rambling2076
b37c1fe556
Fix missing with_tailscale in Dockerfile
Signed-off-by: Rambling2076 <Rambling2076@proton.me>
2025-04-28 23:27:08 +08:00
世界
04065cb4a3
Fail when default DNS server not found 2025-04-28 23:27:08 +08:00
世界
51bc4dacc4
Update gVisor to 20250319.0 2025-04-28 23:27:07 +08:00
世界
145bef7531
release: Do not build tailscale on iOS and tvOS 2025-04-28 23:27:07 +08:00
世界
fa5360d0c9
Explicitly reject detour to empty direct outbounds 2025-04-28 23:27:07 +08:00
世界
cb102cc1dd
Add netns support 2025-04-28 23:27:07 +08:00
世界
a54ec5dd86
Add wildcard name support for predefined records 2025-04-28 23:27:07 +08:00
世界
1576b05084
Remove map usage in options 2025-04-28 23:27:07 +08:00
世界
8a06697bcb
Fix unhandled DNS loop 2025-04-28 23:27:07 +08:00
世界
6a8b97962b
Add wildcard-sni support for shadow-tls inbound 2025-04-28 23:27:07 +08:00
世界
2cf98d6d38
Fix Tailscale DNS 2025-04-28 23:26:59 +08:00
k9982874
b5f241c07c
Add ntp protocol sniffing 2025-04-28 23:26:59 +08:00
世界
a9852bd2a7
option: Fix marshal legacy DNS options 2025-04-28 23:26:59 +08:00
世界
d355591199
Make domain_resolver optional when only one DNS server is configured 2025-04-28 23:26:59 +08:00
世界
bfd5ffdbc2
Fix DNS lookup context pollution 2025-04-28 23:26:59 +08:00
世界
9f77fecf6d
Fix http3 DNS server connecting to wrong address 2025-04-28 23:26:59 +08:00
Restia-Ashbell
1ed61a6c79
documentation: Fix typo 2025-04-28 23:26:58 +08:00
anytls
7b0bec9d88
Update sing-anytls
Co-authored-by: anytls <anytls>
2025-04-28 23:26:58 +08:00
k9982874
db9a94de8a
Fix hosts DNS server 2025-04-28 23:26:58 +08:00
世界
8a9e07f3dc
Fix UDP DNS server crash 2025-04-28 23:26:58 +08:00
世界
26d49eab2c
documentation: Fix missing ip_accept_any DNS rule option 2025-04-28 23:26:58 +08:00
世界
0761d4297e
Fix anytls dialer usage 2025-04-28 23:26:58 +08:00
世界
5860cdfa8c
Move predefined DNS server to rule action 2025-04-28 23:26:58 +08:00
世界
989d8313ac
Fix domain resolver on direct outbound 2025-04-28 23:26:58 +08:00
Zephyruso
630339950c
Fix missing AnyTLS display name 2025-04-28 23:26:58 +08:00
anytls
a3e45c8fc1
Update sing-anytls
Co-authored-by: anytls <anytls>
2025-04-28 23:26:58 +08:00
Estel
9e54805fa4
documentation: Fix typo
Signed-off-by: Estel <callmebedrockdigger@gmail.com>
2025-04-28 23:26:57 +08:00
TargetLocked
d76da925bb
Fix parsing legacy DNS options 2025-04-28 23:26:57 +08:00
世界
fc5b4b7a1c
Fix DNS fallback 2025-04-28 23:26:57 +08:00
世界
df6709bea0
documentation: Fix missing hosts DNS server 2025-04-28 23:26:57 +08:00
anytls
d13063b3ce
Add MinIdleSession option to AnyTLS outbound
Co-authored-by: anytls <anytls>
2025-04-28 23:26:57 +08:00
ReleTor
48ec45c3b7
documentation: Minor fixes 2025-04-28 23:26:57 +08:00
libtry486
bcc75a6bfe
documentation: Fix typo
fix typo

Signed-off-by: libtry486 <89328481+libtry486@users.noreply.github.com>
2025-04-28 23:26:57 +08:00
Alireza Ahmadi
b2ff65d8d8
Fix Outbound deadlock 2025-04-28 23:26:57 +08:00
世界
41b53bd469
documentation: Fix AnyTLS doc 2025-04-28 23:26:57 +08:00
anytls
4ca1c45d55
Add AnyTLS protocol 2025-04-28 23:26:56 +08:00
世界
2361270b03
Migrate to stdlib ECH support 2025-04-28 23:26:56 +08:00
世界
2e8fc1c977
Add fallback local DNS server for iOS 2025-04-28 23:26:56 +08:00
世界
32c01e3622
Get darwin local DNS server from libresolv 2025-04-28 23:26:56 +08:00
世界
faa72ea440
Improve resolve action 2025-04-28 23:26:56 +08:00
世界
3a216e2ab3
Fix toolchain version 2025-04-28 23:26:56 +08:00
世界
d71fdde92c
Add back port hopping to hysteria 1 2025-04-28 23:26:56 +08:00
世界
d50a874a3b
Update dependencies 2025-04-28 23:26:19 +08:00
xchacha20-poly1305
b4eb6a8783
Remove single quotes of raw Moziila certs 2025-04-28 23:26:19 +08:00
世界
1407bd8ebf
Add Tailscale endpoint 2025-04-28 23:26:19 +08:00
世界
291da506ad
Build legacy binaries with latest Go 2025-04-28 23:26:19 +08:00
世界
aa6ad05eb5
documentation: Remove outdated icons 2025-04-28 23:26:19 +08:00
世界
9c1b41cfe3
documentation: Certificate store 2025-04-28 23:26:19 +08:00
世界
657d81b4dd
documentation: TLS fragment 2025-04-28 23:26:19 +08:00
世界
eaf6e35cbf
documentation: Outbound domain resolver 2025-04-28 23:26:19 +08:00
世界
e386fd2ded
documentation: Refactor DNS 2025-04-28 23:26:18 +08:00
世界
3e9735bdcc
Add certificate store 2025-04-28 23:26:18 +08:00
世界
d820b2e030
Add TLS fragment support 2025-04-28 23:26:18 +08:00
世界
22e49abc3d
refactor: Outbound domain resolver 2025-04-28 23:25:43 +08:00
世界
ff11656735
refactor: DNS 2025-04-28 23:25:30 +08:00
世界
aaecd67c24
Fix hysteria bytes format 2025-04-28 23:24:46 +08:00
世界
1c0ffcf5b1
Fix counter position in auto redirect dnat rules 2025-04-28 11:20:23 +08:00
19 changed files with 109 additions and 298 deletions

View File

@ -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)
}

View File

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

View File

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

View File

@ -93,11 +93,12 @@ func NewHTTPS(ctx context.Context, logger log.ContextLogger, tag string, options
return nil, err return nil, err
} }
serverAddr := options.DNSServerAddressOptions.Build() serverAddr := options.DNSServerAddressOptions.Build()
if !serverAddr.Addr.IsValid() { if serverAddr.Port == 0 {
return nil, E.New("invalid server address: ", serverAddr)
} else if serverAddr.Port == 0 {
serverAddr.Port = 443 serverAddr.Port = 443
} }
if !serverAddr.IsValid() {
return nil, E.New("invalid server address: ", serverAddr)
}
return NewHTTPSRaw( return NewHTTPSRaw(
dns.NewTransportAdapterWithRemoteOptions(C.DNSTypeHTTPS, tag, options.RemoteDNSServerOptions), dns.NewTransportAdapterWithRemoteOptions(C.DNSTypeHTTPS, tag, options.RemoteDNSServerOptions),
logger, logger,

View File

@ -89,11 +89,12 @@ func NewHTTP3(ctx context.Context, logger log.ContextLogger, tag string, options
return nil, err return nil, err
} }
serverAddr := options.DNSServerAddressOptions.Build() serverAddr := options.DNSServerAddressOptions.Build()
if !serverAddr.Addr.IsValid() { if serverAddr.Port == 0 {
return nil, E.New("invalid server address: ", serverAddr)
} else if serverAddr.Port == 0 {
serverAddr.Port = 443 serverAddr.Port = 443
} }
if !serverAddr.IsValid() {
return nil, E.New("invalid server address: ", serverAddr)
}
return &HTTP3Transport{ return &HTTP3Transport{
TransportAdapter: dns.NewTransportAdapterWithRemoteOptions(C.DNSTypeHTTP3, tag, options.RemoteDNSServerOptions), TransportAdapter: dns.NewTransportAdapterWithRemoteOptions(C.DNSTypeHTTP3, tag, options.RemoteDNSServerOptions),
logger: logger, logger: logger,

View File

@ -56,11 +56,12 @@ func NewQUIC(ctx context.Context, logger log.ContextLogger, tag string, options
tlsConfig.SetNextProtos([]string{"doq"}) tlsConfig.SetNextProtos([]string{"doq"})
} }
serverAddr := options.DNSServerAddressOptions.Build() serverAddr := options.DNSServerAddressOptions.Build()
if !serverAddr.Addr.IsValid() { if serverAddr.Port == 0 {
return nil, E.New("invalid server address: ", serverAddr)
} else if serverAddr.Port == 0 {
serverAddr.Port = 853 serverAddr.Port = 853
} }
if !serverAddr.IsValid() {
return nil, E.New("invalid server address: ", serverAddr)
}
return &Transport{ return &Transport{
TransportAdapter: dns.NewTransportAdapterWithRemoteOptions(C.DNSTypeQUIC, tag, options.RemoteDNSServerOptions), TransportAdapter: dns.NewTransportAdapterWithRemoteOptions(C.DNSTypeQUIC, tag, options.RemoteDNSServerOptions),
ctx: ctx, ctx: ctx,

View File

@ -38,11 +38,12 @@ func NewTCP(ctx context.Context, logger log.ContextLogger, tag string, options o
return nil, err return nil, err
} }
serverAddr := options.DNSServerAddressOptions.Build() serverAddr := options.DNSServerAddressOptions.Build()
if !serverAddr.Addr.IsValid() { if serverAddr.Port == 0 {
return nil, E.New("invalid server address: ", serverAddr)
} else if serverAddr.Port == 0 {
serverAddr.Port = 53 serverAddr.Port = 53
} }
if !serverAddr.IsValid() {
return nil, E.New("invalid server address: ", serverAddr)
}
return &TCPTransport{ return &TCPTransport{
TransportAdapter: dns.NewTransportAdapterWithRemoteOptions(C.DNSTypeTCP, tag, options), TransportAdapter: dns.NewTransportAdapterWithRemoteOptions(C.DNSTypeTCP, tag, options),
dialer: transportDialer, dialer: transportDialer,

View File

@ -54,11 +54,12 @@ func NewTLS(ctx context.Context, logger log.ContextLogger, tag string, options o
return nil, err return nil, err
} }
serverAddr := options.DNSServerAddressOptions.Build() serverAddr := options.DNSServerAddressOptions.Build()
if !serverAddr.Addr.IsValid() { if serverAddr.Port == 0 {
return nil, E.New("invalid server address: ", serverAddr)
} else if serverAddr.Port == 0 {
serverAddr.Port = 853 serverAddr.Port = 853
} }
if !serverAddr.IsValid() {
return nil, E.New("invalid server address: ", serverAddr)
}
return &TLSTransport{ return &TLSTransport{
TransportAdapter: dns.NewTransportAdapterWithRemoteOptions(C.DNSTypeTLS, tag, options.RemoteDNSServerOptions), TransportAdapter: dns.NewTransportAdapterWithRemoteOptions(C.DNSTypeTLS, tag, options.RemoteDNSServerOptions),
logger: logger, logger: logger,

View File

@ -45,11 +45,12 @@ func NewUDP(ctx context.Context, logger log.ContextLogger, tag string, options o
return nil, err return nil, err
} }
serverAddr := options.DNSServerAddressOptions.Build() serverAddr := options.DNSServerAddressOptions.Build()
if !serverAddr.Addr.IsValid() { if serverAddr.Port == 0 {
return nil, E.New("invalid server address: ", serverAddr)
} else if serverAddr.Port == 0 {
serverAddr.Port = 53 serverAddr.Port = 53
} }
if !serverAddr.IsValid() {
return nil, E.New("invalid server address: ", serverAddr)
}
return NewUDPRaw(logger, dns.NewTransportAdapterWithRemoteOptions(C.DNSTypeUDP, tag, options), transportDialer, serverAddr), nil return NewUDPRaw(logger, dns.NewTransportAdapterWithRemoteOptions(C.DNSTypeUDP, tag, options), transportDialer, serverAddr), nil
} }

View File

@ -2,7 +2,7 @@
icon: material/alert-decagram icon: material/alert-decagram
--- ---
#### 1.12.0-beta.6 #### 1.12.0-beta.7
* Fixes and improvements * Fixes and improvements

View File

@ -42,16 +42,18 @@ AnyTLS padding scheme line array.
Default padding scheme: Default padding scheme:
``` ```json
stop=8 [
0=30-30 "stop=8",
1=100-400 "0=30-30",
2=400-500,c,500-1000,c,500-1000,c,500-1000,c,500-1000 "1=100-400",
3=9-9,500-1000 "2=400-500,c,500-1000,c,500-1000,c,500-1000,c,500-1000",
4=500-1000 "3=9-9,500-1000",
5=500-1000 "4=500-1000",
6=500-1000 "5=500-1000",
7=500-1000 "6=500-1000",
"7=500-1000"
]
``` ```
#### tls #### tls

View File

@ -42,16 +42,18 @@ AnyTLS 填充方案行数组。
默认填充方案: 默认填充方案:
``` ```json
stop=8 [
0=30-30 "stop=8",
1=100-400 "0=30-30",
2=400-500,c,500-1000,c,500-1000,c,500-1000,c,500-1000 "1=100-400",
3=9-9,500-1000 "2=400-500,c,500-1000,c,500-1000,c,500-1000,c,500-1000",
4=500-1000 "3=9-9,500-1000",
5=500-1000 "4=500-1000",
6=500-1000 "5=500-1000",
7=500-1000 "6=500-1000",
"7=500-1000"
]
``` ```
#### tls #### tls

View File

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

4
go.mod
View File

@ -26,13 +26,13 @@ require (
github.com/sagernet/gvisor v0.0.0-20250325023245-7a9c0f5725fb github.com/sagernet/gvisor v0.0.0-20250325023245-7a9c0f5725fb
github.com/sagernet/quic-go v0.49.0-beta.1 github.com/sagernet/quic-go v0.49.0-beta.1
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691
github.com/sagernet/sing v0.6.8-0.20250425035333-84184da91a3a github.com/sagernet/sing v0.6.8-0.20250428152347-91813c8e3960
github.com/sagernet/sing-mux v0.3.1 github.com/sagernet/sing-mux v0.3.1
github.com/sagernet/sing-quic v0.4.1-0.20250423030647-0eb05f373a76 github.com/sagernet/sing-quic v0.4.1-0.20250423030647-0eb05f373a76
github.com/sagernet/sing-shadowsocks v0.2.7 github.com/sagernet/sing-shadowsocks v0.2.7
github.com/sagernet/sing-shadowsocks2 v0.2.0 github.com/sagernet/sing-shadowsocks2 v0.2.0
github.com/sagernet/sing-shadowtls v0.2.1-0.20250316154757-6f9e732e5056 github.com/sagernet/sing-shadowtls v0.2.1-0.20250316154757-6f9e732e5056
github.com/sagernet/sing-tun v0.6.5-0.20250412112220-15069fc1c20a github.com/sagernet/sing-tun v0.6.6-0.20250428031943-0686f8c4f210
github.com/sagernet/sing-vmess v0.2.1 github.com/sagernet/sing-vmess v0.2.1
github.com/sagernet/smux v0.0.0-20231208180855-7041f6ea79e7 github.com/sagernet/smux v0.0.0-20231208180855-7041f6ea79e7
github.com/sagernet/tailscale v1.80.3-mod.4 github.com/sagernet/tailscale v1.80.3-mod.4

8
go.sum
View File

@ -178,8 +178,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 h1:5Th31OC6yj8byLGkEnIYp6grlXfo1QYUfiYFGjewIdc=
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691/go.mod h1:B8lp4WkQ1PwNnrVMM6KyuFR20pU8jYBD+A4EhJovEXU= 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.2.18/go.mod h1:OL6k2F0vHmEzXz2KW19qQzu172FDgSbUSODylighuVo=
github.com/sagernet/sing v0.6.8-0.20250425035333-84184da91a3a h1:oE67hmp5rzLlE6clE7FpK4Hg6yLXsa1Zu3A01vcazb0= github.com/sagernet/sing v0.6.8-0.20250428152347-91813c8e3960 h1:bBSVJ0d5YtbhhwugBXH8GrVaKi1ZIHYdL03LN006Fng=
github.com/sagernet/sing v0.6.8-0.20250425035333-84184da91a3a/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak= github.com/sagernet/sing v0.6.8-0.20250428152347-91813c8e3960/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak=
github.com/sagernet/sing-mux v0.3.1 h1:kvCc8HyGAskDHDQ0yQvoTi/7J4cZPB/VJMsAM3MmdQI= github.com/sagernet/sing-mux v0.3.1 h1:kvCc8HyGAskDHDQ0yQvoTi/7J4cZPB/VJMsAM3MmdQI=
github.com/sagernet/sing-mux v0.3.1/go.mod h1:Mkdz8LnDstthz0HWuA/5foncnDIdcNN5KZ6AdJX+x78= github.com/sagernet/sing-mux v0.3.1/go.mod h1:Mkdz8LnDstthz0HWuA/5foncnDIdcNN5KZ6AdJX+x78=
github.com/sagernet/sing-quic v0.4.1-0.20250423030647-0eb05f373a76 h1:iwpCX6H3nZEOGUGwx0q5azcgYOA9f6v9YssihXoRKHk= github.com/sagernet/sing-quic v0.4.1-0.20250423030647-0eb05f373a76 h1:iwpCX6H3nZEOGUGwx0q5azcgYOA9f6v9YssihXoRKHk=
@ -190,8 +190,8 @@ github.com/sagernet/sing-shadowsocks2 v0.2.0 h1:wpZNs6wKnR7mh1wV9OHwOyUr21VkS3wK
github.com/sagernet/sing-shadowsocks2 v0.2.0/go.mod h1:RnXS0lExcDAovvDeniJ4IKa2IuChrdipolPYWBv9hWQ= github.com/sagernet/sing-shadowsocks2 v0.2.0/go.mod h1:RnXS0lExcDAovvDeniJ4IKa2IuChrdipolPYWBv9hWQ=
github.com/sagernet/sing-shadowtls v0.2.1-0.20250316154757-6f9e732e5056 h1:GFNJQAHhSXqAfxAw1wDG/QWbdpGH5Na3k8qUynqWnEA= github.com/sagernet/sing-shadowtls v0.2.1-0.20250316154757-6f9e732e5056 h1:GFNJQAHhSXqAfxAw1wDG/QWbdpGH5Na3k8qUynqWnEA=
github.com/sagernet/sing-shadowtls v0.2.1-0.20250316154757-6f9e732e5056/go.mod h1:HyacBPIFiKihJQR8LQp56FM4hBtd/7MZXnRxxQIOPsc= github.com/sagernet/sing-shadowtls v0.2.1-0.20250316154757-6f9e732e5056/go.mod h1:HyacBPIFiKihJQR8LQp56FM4hBtd/7MZXnRxxQIOPsc=
github.com/sagernet/sing-tun v0.6.5-0.20250412112220-15069fc1c20a h1:2aLxZFD2HPCLrnFGpH+KBuPqMOk0cuaDE2dgEvANuMk= github.com/sagernet/sing-tun v0.6.6-0.20250428031943-0686f8c4f210 h1:6H4BZaTqKI3YcDMyTV3E576LuJM4S4wY99xoq2T1ECw=
github.com/sagernet/sing-tun v0.6.5-0.20250412112220-15069fc1c20a/go.mod h1:fisFCbC4Vfb6HqQNcwPJi2CDK2bf0Xapyz3j3t4cnHE= github.com/sagernet/sing-tun v0.6.6-0.20250428031943-0686f8c4f210/go.mod h1:fisFCbC4Vfb6HqQNcwPJi2CDK2bf0Xapyz3j3t4cnHE=
github.com/sagernet/sing-vmess v0.2.1 h1:6izHC2+B68aQCxTagki6eZZc+g5eh4dYwxOV5a2Lhug= github.com/sagernet/sing-vmess v0.2.1 h1:6izHC2+B68aQCxTagki6eZZc+g5eh4dYwxOV5a2Lhug=
github.com/sagernet/sing-vmess v0.2.1/go.mod h1:jDAZ0A0St1zVRkyvhAPRySOFfhC+4SQtO5VYyeFotgA= github.com/sagernet/sing-vmess v0.2.1/go.mod h1:jDAZ0A0St1zVRkyvhAPRySOFfhC+4SQtO5VYyeFotgA=
github.com/sagernet/smux v0.0.0-20231208180855-7041f6ea79e7 h1:DImB4lELfQhplLTxeq2z31Fpv8CQqqrUwTbrIRumZqQ= github.com/sagernet/smux v0.0.0-20231208180855-7041f6ea79e7 h1:DImB4lELfQhplLTxeq2z31Fpv8CQqqrUwTbrIRumZqQ=

View File

@ -1,9 +1,6 @@
package option package option
import ( import "github.com/sagernet/sing/common/byteformats"
"github.com/sagernet/sing-box/common/humanize"
"github.com/sagernet/sing/common/json"
)
type DebugOptions struct { type DebugOptions struct {
Listen string `json:"listen,omitempty"` Listen string `json:"listen,omitempty"`
@ -12,32 +9,6 @@ type DebugOptions struct {
MaxThreads *int `json:"max_threads,omitempty"` MaxThreads *int `json:"max_threads,omitempty"`
PanicOnFault *bool `json:"panic_on_fault,omitempty"` PanicOnFault *bool `json:"panic_on_fault,omitempty"`
TraceBack string `json:"trace_back,omitempty"` TraceBack string `json:"trace_back,omitempty"`
MemoryLimit MemoryBytes `json:"memory_limit,omitempty"` MemoryLimit *byteformats.MemoryBytes `json:"memory_limit,omitempty"`
OOMKiller *bool `json:"oom_killer,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
}

View File

@ -1,12 +1,15 @@
package option package option
import "github.com/sagernet/sing/common/json/badoption" import (
"github.com/sagernet/sing/common/byteformats"
"github.com/sagernet/sing/common/json/badoption"
)
type HysteriaInboundOptions struct { type HysteriaInboundOptions struct {
ListenOptions ListenOptions
Up string `json:"up,omitempty"` Up *byteformats.NetworkBytesCompat `json:"up,omitempty"`
UpMbps int `json:"up_mbps,omitempty"` UpMbps int `json:"up_mbps,omitempty"`
Down string `json:"down,omitempty"` Down *byteformats.NetworkBytesCompat `json:"down,omitempty"`
DownMbps int `json:"down_mbps,omitempty"` DownMbps int `json:"down_mbps,omitempty"`
Obfs string `json:"obfs,omitempty"` Obfs string `json:"obfs,omitempty"`
Users []HysteriaUser `json:"users,omitempty"` Users []HysteriaUser `json:"users,omitempty"`
@ -28,9 +31,9 @@ type HysteriaOutboundOptions struct {
ServerOptions ServerOptions
ServerPorts badoption.Listable[string] `json:"server_ports,omitempty"` ServerPorts badoption.Listable[string] `json:"server_ports,omitempty"`
HopInterval badoption.Duration `json:"hop_interval,omitempty"` HopInterval badoption.Duration `json:"hop_interval,omitempty"`
Up string `json:"up,omitempty"` Up *byteformats.NetworkBytesCompat `json:"up,omitempty"`
UpMbps int `json:"up_mbps,omitempty"` UpMbps int `json:"up_mbps,omitempty"`
Down string `json:"down,omitempty"` Down *byteformats.NetworkBytesCompat `json:"down,omitempty"`
DownMbps int `json:"down_mbps,omitempty"` DownMbps int `json:"down_mbps,omitempty"`
Obfs string `json:"obfs,omitempty"` Obfs string `json:"obfs,omitempty"`
Auth []byte `json:"auth,omitempty"` Auth []byte `json:"auth,omitempty"`

View File

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

View File

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