mirror of
https://github.com/shtorm-7/sing-box-extended.git
synced 2026-07-28 17:51:50 +03:00
Compare commits
7 Commits
v1.13.12-e
...
6f6af8e902
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6f6af8e902 | ||
|
|
6cddffd546 | ||
|
|
a59e9ec9e3 | ||
|
|
9ebec50a72 | ||
|
|
7a0354699a | ||
|
|
978b951169 | ||
|
|
0577c28120 |
@@ -13,7 +13,7 @@ Sing-box with extended features.
|
||||
- **MASQUE** — Cloudflare MASQUE proxy over QUIC / HTTP-2
|
||||
- **MTProxy** — Telegram MTProxy server with FakeTLS and domain fronting
|
||||
- **Mieru** — Secure, hard to classify, hard to probe network protocol
|
||||
- **OpenVPN** — OpenVPN client with tls-auth, tls-crypt, and tls-crypt-v2 support
|
||||
- **OpenVPN** — OpenVPN client with tls-auth, tls-crypt and tls-crypt-v2 support
|
||||
- **TrustTunnel** — AdGuard's obfuscated VPN protocol, indistinguishable from HTTPS traffic
|
||||
- **Sudoku** — Traffic obfuscation protocol based on 4×4 Sudoku puzzles with low-entropy fingerprints
|
||||
- **VPN** — Routed tunnel over any TCP sing-box protocol
|
||||
|
||||
@@ -289,11 +289,21 @@ func uniquifyTags(opts []option.Outbound) {
|
||||
|
||||
func removeEmojisFromTags(opts []option.Outbound) {
|
||||
for i, opt := range opts {
|
||||
cleaned := emojiRegex.ReplaceAllString(opt.Tag, "")
|
||||
cleaned := flagRegex.ReplaceAllStringFunc(opt.Tag, flagToCountryCode)
|
||||
cleaned = emojiRegex.ReplaceAllString(cleaned, "")
|
||||
cleaned = multiSpaceRegex.ReplaceAllString(cleaned, " ")
|
||||
opts[i].Tag = strings.TrimSpace(cleaned)
|
||||
}
|
||||
}
|
||||
|
||||
func flagToCountryCode(flag string) string {
|
||||
runes := []rune(flag)
|
||||
if len(runes) == 2 {
|
||||
return string(rune(runes[0]-0x1F1E6+'A')) + string(rune(runes[1]-0x1F1E6+'A')) + " "
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
var flagRegex = regexp.MustCompile(`[\x{1F1E6}-\x{1F1FF}]{2}`)
|
||||
var emojiRegex = regexp.MustCompile(`[\x{1F1E0}-\x{1F1FF}\x{1F300}-\x{1F9FF}\x{2600}-\x{27BF}\x{FE00}-\x{FE0F}\x{200D}]+`)
|
||||
var multiSpaceRegex = regexp.MustCompile(`\s{2,}`)
|
||||
|
||||
45
adapter/provider/adapter_test.go
Normal file
45
adapter/provider/adapter_test.go
Normal file
@@ -0,0 +1,45 @@
|
||||
package provider
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/sagernet/sing-box/option"
|
||||
)
|
||||
|
||||
func TestFlagToCountryCodeAllFlags(t *testing.T) {
|
||||
for first := 'A'; first <= 'Z'; first++ {
|
||||
for second := 'A'; second <= 'Z'; second++ {
|
||||
flag := string(rune(0x1F1E6+(first-'A'))) + string(rune(0x1F1E6+(second-'A')))
|
||||
expected := string(first) + string(second)
|
||||
result := flagToCountryCode(flag)
|
||||
// flagToCountryCode appends a space
|
||||
if result != expected+" " {
|
||||
t.Errorf("flagToCountryCode(%q) = %q, want %q", expected, result, expected+" ")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemoveEmojisFromTags(t *testing.T) {
|
||||
tests := []struct {
|
||||
input string
|
||||
expected string
|
||||
}{
|
||||
{"🇺🇸 United States", "US United States"},
|
||||
{"🇷🇺 Россия", "RU Россия"},
|
||||
{"🇩🇪 Germany 🚀", "DE Germany"},
|
||||
{"🇫🇷🇬🇧 France-UK", "FR GB France-UK"},
|
||||
{"No emojis here", "No emojis here"},
|
||||
{"🌍 World", "World"},
|
||||
{"🇯🇵 Tokyo ⚡ Fast", "JP Tokyo Fast"},
|
||||
{"Germany 🇩🇪", "Germany DE"},
|
||||
{"Server 🇺🇸 Node", "Server US Node"},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
opts := []option.Outbound{{Tag: tt.input}}
|
||||
removeEmojisFromTags(opts)
|
||||
if opts[0].Tag != tt.expected {
|
||||
t.Errorf("removeEmojisFromTags(%q) = %q, want %q", tt.input, opts[0].Tag, tt.expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -29,6 +29,7 @@
|
||||
"use_ipv6": false,
|
||||
"profile": {
|
||||
"detour": "direct",
|
||||
// For getting existing MASQUE device profile, else sing-box will create new profile
|
||||
"id": "",
|
||||
"auth_token": ""
|
||||
},
|
||||
@@ -36,7 +37,7 @@
|
||||
"udp_keepalive_period": "30s",
|
||||
"udp_initial_packet_size": 0,
|
||||
"reconnect_delay": "5s",
|
||||
"tls": {
|
||||
"tls": { // TLS fields for HTTP2
|
||||
"insecure": false,
|
||||
"cipher_suites": [],
|
||||
"curve_preferences": [],
|
||||
|
||||
2
go.mod
2
go.mod
@@ -1,6 +1,6 @@
|
||||
module github.com/sagernet/sing-box
|
||||
|
||||
go 1.26.1
|
||||
go 1.26.4
|
||||
|
||||
require (
|
||||
github.com/AliRizaAynaci/gorl/v2 v2.2.0
|
||||
|
||||
@@ -89,6 +89,15 @@ func (h *Inbound) Start(stage adapter.StartStage) error {
|
||||
}
|
||||
var err error
|
||||
if common.Contains(h.network, N.NetworkTCP) {
|
||||
h.httpTLSConfig, err = tls.NewServer(h.ctx, h.logger, common.PtrValueOrDefault(h.options.TLS))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(h.httpTLSConfig.NextProtos()) == 0 {
|
||||
h.httpTLSConfig.SetNextProtos([]string{http2.NextProtoTLS})
|
||||
} else if !common.Contains(h.httpTLSConfig.NextProtos(), http2.NextProtoTLS) {
|
||||
h.httpTLSConfig.SetNextProtos(append([]string{http2.NextProtoTLS}, h.httpTLSConfig.NextProtos()...))
|
||||
}
|
||||
listener, err := h.listener.ListenTCP()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -99,15 +108,6 @@ func (h *Inbound) Start(stage adapter.StartStage) error {
|
||||
return h.ctx
|
||||
},
|
||||
}
|
||||
h.httpTLSConfig, err = tls.NewServer(h.ctx, h.logger, common.PtrValueOrDefault(h.options.TLS))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(h.httpTLSConfig.NextProtos()) == 0 {
|
||||
h.httpTLSConfig.SetNextProtos([]string{http2.NextProtoTLS})
|
||||
} else if !common.Contains(h.httpTLSConfig.NextProtos(), http2.NextProtoTLS) {
|
||||
h.httpTLSConfig.SetNextProtos(append([]string{http2.NextProtoTLS}, h.httpTLSConfig.NextProtos()...))
|
||||
}
|
||||
err = h.httpTLSConfig.Start()
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
Reference in New Issue
Block a user