mirror of
https://github.com/SagerNet/sing-box.git
synced 2025-08-29 21:47:36 +08:00
Compare commits
80 Commits
45798b10c8
...
49261c5521
Author | SHA1 | Date | |
---|---|---|---|
![]() |
49261c5521 | ||
![]() |
b41ed2eec2 | ||
![]() |
3f04e91aa0 | ||
![]() |
14d901f291 | ||
![]() |
fefd910b12 | ||
![]() |
1d52f19101 | ||
![]() |
eedbde1181 | ||
![]() |
f9af5a62f0 | ||
![]() |
e994fbc76e | ||
![]() |
3f2213c313 | ||
![]() |
07fe8fbe58 | ||
![]() |
f53bd4c1c5 | ||
![]() |
a03688274e | ||
![]() |
b64dfc5e80 | ||
![]() |
1a0fc33044 | ||
![]() |
7eb2abcd27 | ||
![]() |
2e80f08bcb | ||
![]() |
37764db502 | ||
![]() |
e5a569aeda | ||
![]() |
581d3ffdae | ||
![]() |
0143ae2975 | ||
![]() |
2c0d4a3a18 | ||
![]() |
24d5ed47c9 | ||
![]() |
b37c1fe556 | ||
![]() |
04065cb4a3 | ||
![]() |
51bc4dacc4 | ||
![]() |
145bef7531 | ||
![]() |
fa5360d0c9 | ||
![]() |
cb102cc1dd | ||
![]() |
a54ec5dd86 | ||
![]() |
1576b05084 | ||
![]() |
8a06697bcb | ||
![]() |
6a8b97962b | ||
![]() |
2cf98d6d38 | ||
![]() |
b5f241c07c | ||
![]() |
a9852bd2a7 | ||
![]() |
d355591199 | ||
![]() |
bfd5ffdbc2 | ||
![]() |
9f77fecf6d | ||
![]() |
1ed61a6c79 | ||
![]() |
7b0bec9d88 | ||
![]() |
db9a94de8a | ||
![]() |
8a9e07f3dc | ||
![]() |
26d49eab2c | ||
![]() |
0761d4297e | ||
![]() |
5860cdfa8c | ||
![]() |
989d8313ac | ||
![]() |
630339950c | ||
![]() |
a3e45c8fc1 | ||
![]() |
9e54805fa4 | ||
![]() |
d76da925bb | ||
![]() |
fc5b4b7a1c | ||
![]() |
df6709bea0 | ||
![]() |
d13063b3ce | ||
![]() |
48ec45c3b7 | ||
![]() |
bcc75a6bfe | ||
![]() |
b2ff65d8d8 | ||
![]() |
41b53bd469 | ||
![]() |
4ca1c45d55 | ||
![]() |
2361270b03 | ||
![]() |
2e8fc1c977 | ||
![]() |
32c01e3622 | ||
![]() |
faa72ea440 | ||
![]() |
3a216e2ab3 | ||
![]() |
d71fdde92c | ||
![]() |
d50a874a3b | ||
![]() |
b4eb6a8783 | ||
![]() |
1407bd8ebf | ||
![]() |
291da506ad | ||
![]() |
aa6ad05eb5 | ||
![]() |
9c1b41cfe3 | ||
![]() |
657d81b4dd | ||
![]() |
eaf6e35cbf | ||
![]() |
e386fd2ded | ||
![]() |
3e9735bdcc | ||
![]() |
d820b2e030 | ||
![]() |
22e49abc3d | ||
![]() |
ff11656735 | ||
![]() |
aaecd67c24 | ||
![]() |
1c0ffcf5b1 |
@ -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)
|
|
||||||
}
|
|
6
debug.go
6
debug.go
@ -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
|
||||||
|
@ -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())
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
@ -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,
|
||||||
|
@ -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,
|
||||||
|
@ -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,
|
||||||
|
@ -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,
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
4
go.mod
@ -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
8
go.sum
@ -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=
|
||||||
|
@ -1,43 +1,14 @@
|
|||||||
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"`
|
||||||
GCPercent *int `json:"gc_percent,omitempty"`
|
GCPercent *int `json:"gc_percent,omitempty"`
|
||||||
MaxStack *int `json:"max_stack,omitempty"`
|
MaxStack *int `json:"max_stack,omitempty"`
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
@ -1,19 +1,22 @@
|
|||||||
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"`
|
||||||
ReceiveWindowConn uint64 `json:"recv_window_conn,omitempty"`
|
ReceiveWindowConn uint64 `json:"recv_window_conn,omitempty"`
|
||||||
ReceiveWindowClient uint64 `json:"recv_window_client,omitempty"`
|
ReceiveWindowClient uint64 `json:"recv_window_client,omitempty"`
|
||||||
MaxConnClient int `json:"max_conn_client,omitempty"`
|
MaxConnClient int `json:"max_conn_client,omitempty"`
|
||||||
DisableMTUDiscovery bool `json:"disable_mtu_discovery,omitempty"`
|
DisableMTUDiscovery bool `json:"disable_mtu_discovery,omitempty"`
|
||||||
InboundTLSOptionsContainer
|
InboundTLSOptionsContainer
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -26,18 +29,18 @@ type HysteriaUser struct {
|
|||||||
type HysteriaOutboundOptions struct {
|
type HysteriaOutboundOptions struct {
|
||||||
DialerOptions
|
DialerOptions
|
||||||
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"`
|
||||||
AuthString string `json:"auth_str,omitempty"`
|
AuthString string `json:"auth_str,omitempty"`
|
||||||
ReceiveWindowConn uint64 `json:"recv_window_conn,omitempty"`
|
ReceiveWindowConn uint64 `json:"recv_window_conn,omitempty"`
|
||||||
ReceiveWindow uint64 `json:"recv_window,omitempty"`
|
ReceiveWindow uint64 `json:"recv_window,omitempty"`
|
||||||
DisableMTUDiscovery bool `json:"disable_mtu_discovery,omitempty"`
|
DisableMTUDiscovery bool `json:"disable_mtu_discovery,omitempty"`
|
||||||
Network NetworkList `json:"network,omitempty"`
|
Network NetworkList `json:"network,omitempty"`
|
||||||
OutboundTLSOptionsContainer
|
OutboundTLSOptionsContainer
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user