mirror of
https://github.com/bolucat/Archive.git
synced 2025-10-07 00:53:18 +08:00
Update On Mon Aug 11 20:44:01 CEST 2025
This commit is contained in:
1
.github/update.log
vendored
1
.github/update.log
vendored
@@ -1086,3 +1086,4 @@ Update On Thu Aug 7 20:45:01 CEST 2025
|
||||
Update On Fri Aug 8 20:38:56 CEST 2025
|
||||
Update On Sat Aug 9 20:40:00 CEST 2025
|
||||
Update On Sun Aug 10 20:40:02 CEST 2025
|
||||
Update On Mon Aug 11 20:43:53 CEST 2025
|
||||
|
@@ -456,7 +456,7 @@ func NewVless(option VlessOption) (*Vless, error) {
|
||||
option: &option,
|
||||
}
|
||||
|
||||
if s := strings.Split(option.Encryption, "-mlkem768client-"); len(s) == 2 {
|
||||
if s := strings.SplitN(option.Encryption, "-", 4); len(s) == 4 && s[2] == "mlkem768client" {
|
||||
var minutes uint32
|
||||
if s[0] != "1rtt" {
|
||||
t := strings.TrimSuffix(s[0], "min")
|
||||
@@ -470,14 +470,22 @@ func NewVless(option VlessOption) (*Vless, error) {
|
||||
}
|
||||
minutes = uint32(i)
|
||||
}
|
||||
var xor uint32
|
||||
switch s[1] {
|
||||
case "vless":
|
||||
case "aes128xor":
|
||||
xor = 1
|
||||
default:
|
||||
return nil, fmt.Errorf("invaild vless encryption value: %s", option.Encryption)
|
||||
}
|
||||
var b []byte
|
||||
b, err = base64.RawURLEncoding.DecodeString(s[1])
|
||||
b, err = base64.RawURLEncoding.DecodeString(s[3])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invaild vless encryption value: %s", option.Encryption)
|
||||
}
|
||||
if len(b) == 1184 {
|
||||
if len(b) == encryption.MLKEM768ClientLength {
|
||||
v.encryption = &encryption.ClientInstance{}
|
||||
if err = v.encryption.Init(b, time.Duration(minutes)*time.Minute); err != nil {
|
||||
if err = v.encryption.Init(b, xor, time.Duration(minutes)*time.Minute); err != nil {
|
||||
return nil, fmt.Errorf("failed to use mlkem768seed: %w", err)
|
||||
}
|
||||
} else {
|
||||
|
@@ -221,6 +221,9 @@ func ConvertsV2Ray(buf []byte) ([]map[string]any, error) {
|
||||
if flow := query.Get("flow"); flow != "" {
|
||||
vless["flow"] = strings.ToLower(flow)
|
||||
}
|
||||
if encryption := query.Get("encryption"); encryption != "" {
|
||||
vless["encryption"] = encryption
|
||||
}
|
||||
proxies = append(proxies, vless)
|
||||
|
||||
case "vmess":
|
||||
|
@@ -46,16 +46,16 @@ func Main(args []string) {
|
||||
}
|
||||
fmt.Println("Config:", configBase64)
|
||||
fmt.Println("Key:", keyPem)
|
||||
case "vless-mlkem768-keypair":
|
||||
case "vless-mlkem768":
|
||||
var seed string
|
||||
if len(args) > 1 {
|
||||
seed = args[1]
|
||||
}
|
||||
seedBase64, pubBase64, err := encryption.GenMLKEM768(seed)
|
||||
seedBase64, clientBase64, err := encryption.GenMLKEM768(seed)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Println("Seed: " + seedBase64)
|
||||
fmt.Println("Client: " + pubBase64)
|
||||
fmt.Println("Client: " + clientBase64)
|
||||
}
|
||||
}
|
||||
|
@@ -170,7 +170,7 @@ type realityVerifier struct {
|
||||
//var pOffset = utils.MustOK(reflect.TypeOf((*utls.Conn)(nil)).Elem().FieldByName("peerCertificates")).Offset
|
||||
|
||||
func (c *realityVerifier) VerifyPeerCertificate(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error {
|
||||
//log.Debugln("REALITY localAddr: %v\t is using X25519MLKEM768 for TLS' communication: %v", c.RemoteAddr(), c.HandshakeState.ServerHello.SelectedGroup == utls.X25519MLKEM768)
|
||||
log.Debugln("REALITY localAddr: %v is using X25519MLKEM768 for TLS' communication: %v", c.RemoteAddr(), c.HandshakeState.ServerHello.ServerShare.Group == utls.X25519MLKEM768)
|
||||
//p, _ := reflect.TypeOf(c.Conn).Elem().FieldByName("peerCertificates")
|
||||
//certs := *(*[]*x509.Certificate)(unsafe.Add(unsafe.Pointer(c.Conn), pOffset))
|
||||
certs := c.Conn.PeerCertificates()
|
||||
|
@@ -1,3 +1,12 @@
|
||||
// Package wildcard modified IGLOU-EU/go-wildcard to support:
|
||||
//
|
||||
// `*` matches zero or more characters
|
||||
// `?` matches exactly one character
|
||||
//
|
||||
// The original go-wildcard library used `.` to match exactly one character, and `?` to match zero or one character.
|
||||
// `.` is a valid delimiter in domain name matching and should not be used as a wildcard.
|
||||
// The `?` matching logic strictly matches only one character in most scenarios.
|
||||
// So, the `?` matching logic in the original go-wildcard library has been removed and its wildcard `.` has been replaced with `?`.
|
||||
package wildcard
|
||||
|
||||
// copy and modified from https://github.com/IGLOU-EU/go-wildcard/tree/ce22b7af48e487517a492d3727d9386492043e21
|
||||
@@ -16,12 +25,10 @@ func Match(pattern, s string) bool {
|
||||
}
|
||||
|
||||
func matchByString(pattern, s string) bool {
|
||||
var lastErotemeCluster byte
|
||||
var patternIndex, sIndex, lastStar, lastEroteme int
|
||||
var patternIndex, sIndex, lastStar int
|
||||
patternLen := len(pattern)
|
||||
sLen := len(s)
|
||||
star := -1
|
||||
eroteme := -1
|
||||
|
||||
Loop:
|
||||
if sIndex >= sLen {
|
||||
@@ -38,14 +45,8 @@ Loop:
|
||||
return false
|
||||
}
|
||||
switch pattern[patternIndex] {
|
||||
// Removed dot matching as it conflicts with dot in domains.
|
||||
// case '.':
|
||||
// It matches any single character. So, we don't need to check anything.
|
||||
case '?':
|
||||
// '?' matches one character. Store its position and match exactly one character in the string.
|
||||
eroteme = patternIndex
|
||||
lastEroteme = sIndex
|
||||
lastErotemeCluster = byte(s[sIndex])
|
||||
// It matches any single character. So, we don't need to check anything.
|
||||
case '*':
|
||||
// '*' matches zero or more characters. Store its position and increment the pattern index.
|
||||
star = patternIndex
|
||||
@@ -53,15 +54,8 @@ Loop:
|
||||
patternIndex++
|
||||
goto Loop
|
||||
default:
|
||||
// If the characters don't match, check if there was a previous '?' or '*' to backtrack.
|
||||
// If the characters don't match, check if there was a previous '*' to backtrack.
|
||||
if pattern[patternIndex] != s[sIndex] {
|
||||
if eroteme != -1 {
|
||||
patternIndex = eroteme + 1
|
||||
sIndex = lastEroteme
|
||||
eroteme = -1
|
||||
goto Loop
|
||||
}
|
||||
|
||||
if star != -1 {
|
||||
patternIndex = star + 1
|
||||
lastStar++
|
||||
@@ -71,29 +65,18 @@ Loop:
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// If the characters match, check if it was not the same to validate the eroteme.
|
||||
if eroteme != -1 && lastErotemeCluster != byte(s[sIndex]) {
|
||||
eroteme = -1
|
||||
}
|
||||
}
|
||||
|
||||
patternIndex++
|
||||
sIndex++
|
||||
goto Loop
|
||||
|
||||
// Check if the remaining pattern characters are '*' or '?', which can match the end of the string.
|
||||
// Check if the remaining pattern characters are '*', which can match the end of the string.
|
||||
checkPattern:
|
||||
if patternIndex < patternLen {
|
||||
if pattern[patternIndex] == '*' {
|
||||
patternIndex++
|
||||
goto checkPattern
|
||||
} else if pattern[patternIndex] == '?' {
|
||||
if sIndex >= sLen {
|
||||
sIndex--
|
||||
}
|
||||
patternIndex++
|
||||
goto checkPattern
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -25,31 +25,17 @@ func TestMatch(t *testing.T) {
|
||||
{"", "", true},
|
||||
{"", "*", true},
|
||||
{"", "**", true},
|
||||
{"", "?", true},
|
||||
{"", "??", true},
|
||||
{"", "?*", true},
|
||||
{"", "*?", true},
|
||||
{"", ".", false},
|
||||
{"", ".?", false},
|
||||
{"", "?.", false},
|
||||
{"", ".*", false},
|
||||
{"", "*.", false},
|
||||
{"", "*.?", false},
|
||||
{"", "?.*", false},
|
||||
{"", "?", false},
|
||||
{"", "?*", false},
|
||||
{"", "*?", false},
|
||||
|
||||
{"a", "", false},
|
||||
{"a", "a", true},
|
||||
{"a", "*", true},
|
||||
{"a", "**", true},
|
||||
{"a", "?", true},
|
||||
{"a", "??", true},
|
||||
{"a", ".", false},
|
||||
{"a", ".?", false},
|
||||
{"a", "?.", false},
|
||||
{"a", ".*", false},
|
||||
{"a", "*.", false},
|
||||
{"a", "*.?", false},
|
||||
{"a", "?.*", false},
|
||||
{"a", "?*", true},
|
||||
{"a", "*?", true},
|
||||
|
||||
{"match the exact string", "match the exact string", true},
|
||||
{"do not match a different string", "this is a different string", false},
|
||||
@@ -68,22 +54,27 @@ func TestMatch(t *testing.T) {
|
||||
|
||||
{"match a string with a ?", "match ? string with a ?", true},
|
||||
{"match a string with a ? at the beginning", "?atch a string with a ? at the beginning", true},
|
||||
{"match a string with two ?", "match a string with two ??", true},
|
||||
{"match a optional char with a ?", "match a optional? char with a ?", true},
|
||||
{"match a optional char with a ?", "match a optional? char with a ?", true},
|
||||
{"do not match a string with extra and a ?", "do not match ? string with extra and a ? like this", false},
|
||||
{"match a string with two ?", "match a ??ring with two ?", true},
|
||||
{"do not match a string with extra ?", "do not match a string with extra ??", false},
|
||||
|
||||
{"do not match a string with a .", "do not match . string with a .", false},
|
||||
{"do not match a string with a . at the beginning", "do not .atch a string with a . at the beginning", false},
|
||||
{"do not match a string with two .", "do not match a ..ring with two .", false},
|
||||
{"do not match a string with extra .", "do not match a string with extra ..", false},
|
||||
{"abc.edf.hjg", "abc.edf.hjg", true},
|
||||
{"abc.edf.hjg", "ab.cedf.hjg", false},
|
||||
{"abc.edf.hjg", "abc.edfh.jg", false},
|
||||
{"abc.edf.hjg", "abc.edf.hjq", false},
|
||||
|
||||
{"A big brown fox jumps over the lazy dog, with all there wildcards friends", ". big?brown fox jumps over * wildcard. friend??", false},
|
||||
{"A big brown fox fails to jump over the lazy dog, with all there wildcards friends", ". big?brown fox jumps over * wildcard. friend??", false},
|
||||
{"abc.edf.hjg", "abc.*.hjg", true},
|
||||
{"abc.edf.hjg", "abc.*.hjq", false},
|
||||
{"abc.edf.hjg", "abc*hjg", true},
|
||||
{"abc.edf.hjg", "abc*hjq", false},
|
||||
{"abc.edf.hjg", "a*g", true},
|
||||
{"abc.edf.hjg", "a*q", false},
|
||||
|
||||
{"domain a.b.c", "domain a.b.c", true},
|
||||
{"domain adb.c", "domain a.b.c", false},
|
||||
{"aaaa", "a*a", true},
|
||||
{"abc.edf.hjg", "ab?.edf.hjg", true},
|
||||
{"abc.edf.hjg", "?b?.edf.hjg", true},
|
||||
{"abc.edf.hjg", "??c.edf.hjg", true},
|
||||
{"abc.edf.hjg", "a??.edf.hjg", true},
|
||||
{"abc.edf.hjg", "ab??.edf.hjg", false},
|
||||
{"abc.edf.hjg", "??.edf.hjg", false},
|
||||
}
|
||||
|
||||
for i, c := range cases {
|
||||
@@ -96,10 +87,106 @@ func TestMatch(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func match(pattern, name string) bool { // https://research.swtch.com/glob
|
||||
px := 0
|
||||
nx := 0
|
||||
nextPx := 0
|
||||
nextNx := 0
|
||||
for px < len(pattern) || nx < len(name) {
|
||||
if px < len(pattern) {
|
||||
c := pattern[px]
|
||||
switch c {
|
||||
default: // ordinary character
|
||||
if nx < len(name) && name[nx] == c {
|
||||
px++
|
||||
nx++
|
||||
continue
|
||||
}
|
||||
case '?': // single-character wildcard
|
||||
if nx < len(name) {
|
||||
px++
|
||||
nx++
|
||||
continue
|
||||
}
|
||||
case '*': // zero-or-more-character wildcard
|
||||
// Try to match at nx.
|
||||
// If that doesn't work out,
|
||||
// restart at nx+1 next.
|
||||
nextPx = px
|
||||
nextNx = nx + 1
|
||||
px++
|
||||
continue
|
||||
}
|
||||
}
|
||||
// Mismatch. Maybe restart.
|
||||
if 0 < nextNx && nextNx <= len(name) {
|
||||
px = nextPx
|
||||
nx = nextNx
|
||||
continue
|
||||
}
|
||||
return false
|
||||
}
|
||||
// Matched all of pattern to all of name. Success.
|
||||
return true
|
||||
}
|
||||
|
||||
func FuzzMatch(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, s string) {
|
||||
if !Match(string(s), string(s)) {
|
||||
t.Fatalf("%s does not match %s", s, s)
|
||||
f.Fuzz(func(t *testing.T, pattern, name string) {
|
||||
result1 := Match(pattern, name)
|
||||
result2 := match(pattern, name)
|
||||
if result1 != result2 {
|
||||
t.Fatalf("Match failed for pattern `%s` and name `%s`", pattern, name)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkMatch(b *testing.B) {
|
||||
cases := []struct {
|
||||
s string
|
||||
pattern string
|
||||
result bool
|
||||
}{
|
||||
{"abc.edf.hjg", "abc.edf.hjg", true},
|
||||
{"abc.edf.hjg", "ab.cedf.hjg", false},
|
||||
{"abc.edf.hjg", "abc.edfh.jg", false},
|
||||
{"abc.edf.hjg", "abc.edf.hjq", false},
|
||||
|
||||
{"abc.edf.hjg", "abc.*.hjg", true},
|
||||
{"abc.edf.hjg", "abc.*.hjq", false},
|
||||
{"abc.edf.hjg", "abc*hjg", true},
|
||||
{"abc.edf.hjg", "abc*hjq", false},
|
||||
{"abc.edf.hjg", "a*g", true},
|
||||
{"abc.edf.hjg", "a*q", false},
|
||||
|
||||
{"abc.edf.hjg", "ab?.edf.hjg", true},
|
||||
{"abc.edf.hjg", "?b?.edf.hjg", true},
|
||||
{"abc.edf.hjg", "??c.edf.hjg", true},
|
||||
{"abc.edf.hjg", "a??.edf.hjg", true},
|
||||
{"abc.edf.hjg", "ab??.edf.hjg", false},
|
||||
{"abc.edf.hjg", "??.edf.hjg", false},
|
||||
|
||||
{"r4.cdn-aa-wow-this-is-long-a1.video-yajusenpai1145141919810-oh-hell-yeah-this-is-also-very-long-and-sukka-the-fox-has-a-very-big-fluffy-fox-tail-ao-wu-ao-wu-regex-and-wildcard-both-might-have-deadly-back-tracing-issue-be-careful-or-use-linear-matching.com", "*.cdn-*-*.video**.com", true},
|
||||
}
|
||||
|
||||
b.Run("Match", func(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
for _, c := range cases {
|
||||
result := Match(c.pattern, c.s)
|
||||
if c.result != result {
|
||||
b.Errorf("Test %d: Expected `%v`, found `%v`; With Pattern: `%s` and String: `%s`", i+1, c.result, result, c.pattern, c.s)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
b.Run("match", func(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
for _, c := range cases {
|
||||
result := match(c.pattern, c.s)
|
||||
if c.result != result {
|
||||
b.Errorf("Test %d: Expected `%v`, found `%v`; With Pattern: `%s` and String: `%s`", i+1, c.result, result, c.pattern, c.s)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@@ -638,7 +638,8 @@ proxies: # socks5
|
||||
port: 443
|
||||
uuid: uuid
|
||||
network: tcp
|
||||
encryption: "8min-mlkem768client-bas64RawURLEncoding" # 复用八分钟后协商新的 sharedKey,需小于服务端的值
|
||||
encryption: "8min-vless-mlkem768client-bas64RawURLEncoding" # 复用八分钟后协商新的 sharedKey,需小于服务端的值
|
||||
# encryption: "8min-aes128xor-mlkem768client-bas64RawURLEncoding"
|
||||
tls: false #可以不开启tls
|
||||
udp: true
|
||||
|
||||
@@ -1346,7 +1347,8 @@ listeners:
|
||||
flow: xtls-rprx-vision
|
||||
# ws-path: "/" # 如果不为空则开启 websocket 传输层
|
||||
# grpc-service-name: "GunService" # 如果不为空则开启 grpc 传输层
|
||||
# decryption: "10min-mlkem768seed-bas64RawURLEncoding" # 同时允许 1-RTT 模式与十分钟复用的 0-RTT 模式, 后面base64字符串可由可由 mihomo generate vless-mlkem768 命令生成
|
||||
# decryption: "10min-vless-mlkem768seed-bas64RawURLEncoding" # 同时允许 1-RTT 模式与十分钟复用的 0-RTT 模式, 后面base64字符串可由可由 mihomo generate vless-mlkem768 命令生成
|
||||
# decryption: "10min-aes128xor-mlkem768seed-bas64RawURLEncoding"
|
||||
# 下面两项如果填写则开启 tls(需要同时填写)
|
||||
# certificate: ./server.crt
|
||||
# private-key: ./server.key
|
||||
|
@@ -35,7 +35,7 @@ require (
|
||||
github.com/metacubex/sing-wireguard v0.0.0-20250503063753-2dc62acc626f
|
||||
github.com/metacubex/smux v0.0.0-20250503055512-501391591dee
|
||||
github.com/metacubex/tfo-go v0.0.0-20250516165257-e29c16ae41d4
|
||||
github.com/metacubex/utls v1.8.1-0.20250810142204-d0e55ab2e852
|
||||
github.com/metacubex/utls v1.8.1-0.20250811145843-49b4f106169a
|
||||
github.com/metacubex/wireguard-go v0.0.0-20240922131502-c182e7471181
|
||||
github.com/miekg/dns v1.1.63 // lastest version compatible with golang1.20
|
||||
github.com/mroth/weightedrand/v2 v2.1.0
|
||||
|
@@ -139,10 +139,8 @@ github.com/metacubex/smux v0.0.0-20250503055512-501391591dee h1:lp6hJ+4wCLZu113a
|
||||
github.com/metacubex/smux v0.0.0-20250503055512-501391591dee/go.mod h1:4bPD8HWx9jPJ9aE4uadgyN7D1/Wz3KmPy+vale8sKLE=
|
||||
github.com/metacubex/tfo-go v0.0.0-20250516165257-e29c16ae41d4 h1:j1VRTiC9JLR4nUbSikx9OGdu/3AgFDqgcLj4GoqyQkc=
|
||||
github.com/metacubex/tfo-go v0.0.0-20250516165257-e29c16ae41d4/go.mod h1:l9oLnLoEXyGZ5RVLsh7QCC5XsouTUyKk4F2nLm2DHLw=
|
||||
github.com/metacubex/utls v1.8.0 h1:mSYi6FMnmc5riARl5UZDmWVy710z+P5b7xuGW0lV9ac=
|
||||
github.com/metacubex/utls v1.8.0/go.mod h1:FdjYzVfCtgtna19hX0ER1Xsa5uJInwdQ4IcaaI98lEQ=
|
||||
github.com/metacubex/utls v1.8.1-0.20250810142204-d0e55ab2e852 h1:MLHUGmASNH7/AeoGmSrVM2RutRZAqIDSbQWBp0P7ItE=
|
||||
github.com/metacubex/utls v1.8.1-0.20250810142204-d0e55ab2e852/go.mod h1:FdjYzVfCtgtna19hX0ER1Xsa5uJInwdQ4IcaaI98lEQ=
|
||||
github.com/metacubex/utls v1.8.1-0.20250811145843-49b4f106169a h1:IIzlVmDoB4+7b0BUcLZaY5+AirhhLFep3PhwkAFMRnQ=
|
||||
github.com/metacubex/utls v1.8.1-0.20250811145843-49b4f106169a/go.mod h1:FdjYzVfCtgtna19hX0ER1Xsa5uJInwdQ4IcaaI98lEQ=
|
||||
github.com/metacubex/wireguard-go v0.0.0-20240922131502-c182e7471181 h1:hJLQviGySBuaynlCwf/oYgIxbVbGRUIKZCxdya9YrbQ=
|
||||
github.com/metacubex/wireguard-go v0.0.0-20240922131502-c182e7471181/go.mod h1:phewKljNYiTVT31Gcif8RiCKnTUOgVWFJjccqYM8s+Y=
|
||||
github.com/miekg/dns v1.1.63 h1:8M5aAw6OMZfFXTT7K5V0Eu5YiiL8l7nUAkyN6C9YwaY=
|
||||
|
@@ -89,18 +89,29 @@ func TestInboundVless_TLS(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestInboundVless_Encryption(t *testing.T) {
|
||||
seedBase64, pubBase64, err := encryption.GenMLKEM768("")
|
||||
seedBase64, clientBase64, err := encryption.GenMLKEM768("")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
return
|
||||
}
|
||||
t.Run("-vless-", func(t *testing.T) {
|
||||
inboundOptions := inbound.VlessOption{
|
||||
Decryption: "10min-mlkem768seed-" + seedBase64,
|
||||
Decryption: "10min-vless-mlkem768seed-" + seedBase64,
|
||||
}
|
||||
outboundOptions := outbound.VlessOption{
|
||||
Encryption: "8min-mlkem768client-" + pubBase64,
|
||||
Encryption: "8min-vless-mlkem768client-" + clientBase64,
|
||||
}
|
||||
testInboundVless(t, inboundOptions, outboundOptions)
|
||||
})
|
||||
t.Run("-aes128xor-", func(t *testing.T) {
|
||||
inboundOptions := inbound.VlessOption{
|
||||
Decryption: "10min-aes128xor-mlkem768seed-" + seedBase64,
|
||||
}
|
||||
outboundOptions := outbound.VlessOption{
|
||||
Encryption: "8min-aes128xor-mlkem768client-" + clientBase64,
|
||||
}
|
||||
testInboundVless(t, inboundOptions, outboundOptions)
|
||||
})
|
||||
}
|
||||
|
||||
func TestInboundVless_Wss1(t *testing.T) {
|
||||
|
@@ -88,7 +88,7 @@ func New(config LC.VlessServer, tunnel C.Tunnel, additions ...inbound.Addition)
|
||||
|
||||
sl = &Listener{config: config, service: service}
|
||||
|
||||
if s := strings.Split(config.Decryption, "-mlkem768seed-"); len(s) == 2 {
|
||||
if s := strings.SplitN(config.Decryption, "-", 4); len(s) == 4 && s[2] == "mlkem768seed" {
|
||||
var minutes uint32
|
||||
if s[0] != "1rtt" {
|
||||
t := strings.TrimSuffix(s[0], "min")
|
||||
@@ -102,14 +102,22 @@ func New(config LC.VlessServer, tunnel C.Tunnel, additions ...inbound.Addition)
|
||||
}
|
||||
minutes = uint32(i)
|
||||
}
|
||||
var xor uint32
|
||||
switch s[1] {
|
||||
case "vless":
|
||||
case "aes128xor":
|
||||
xor = 1
|
||||
default:
|
||||
return nil, fmt.Errorf("invaild vless decryption value: %s", config.Decryption)
|
||||
}
|
||||
var b []byte
|
||||
b, err = base64.RawURLEncoding.DecodeString(s[1])
|
||||
b, err = base64.RawURLEncoding.DecodeString(s[3])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invaild vless decryption value: %s", config.Decryption)
|
||||
}
|
||||
if len(b) == 64 {
|
||||
if len(b) == encryption.MLKEM768SeedLength {
|
||||
sl.decryption = &encryption.ServerInstance{}
|
||||
if err = sl.decryption.Init(b, time.Duration(minutes)*time.Minute); err != nil {
|
||||
if err = sl.decryption.Init(b, xor, time.Duration(minutes)*time.Minute); err != nil {
|
||||
return nil, fmt.Errorf("failed to use mlkem768seed: %w", err)
|
||||
}
|
||||
} else {
|
||||
|
@@ -38,17 +38,18 @@ func init() {
|
||||
type ClientInstance struct {
|
||||
sync.RWMutex
|
||||
eKeyNfs *mlkem.EncapsulationKey768
|
||||
xor uint32
|
||||
minutes time.Duration
|
||||
expire time.Time
|
||||
baseKey []byte
|
||||
reuse []byte
|
||||
ticket []byte
|
||||
}
|
||||
|
||||
type ClientConn struct {
|
||||
net.Conn
|
||||
instance *ClientInstance
|
||||
baseKey []byte
|
||||
reuse []byte
|
||||
ticket []byte
|
||||
random []byte
|
||||
aead cipher.AEAD
|
||||
nonce []byte
|
||||
@@ -57,8 +58,9 @@ type ClientConn struct {
|
||||
peerCache []byte
|
||||
}
|
||||
|
||||
func (i *ClientInstance) Init(eKeyNfsData []byte, minutes time.Duration) (err error) {
|
||||
func (i *ClientInstance) Init(eKeyNfsData []byte, xor uint32, minutes time.Duration) (err error) {
|
||||
i.eKeyNfs, err = mlkem.NewEncapsulationKey768(eKeyNfsData)
|
||||
i.xor = xor
|
||||
i.minutes = minutes
|
||||
return
|
||||
}
|
||||
@@ -67,6 +69,9 @@ func (i *ClientInstance) Handshake(conn net.Conn) (net.Conn, error) {
|
||||
if i.eKeyNfs == nil {
|
||||
return nil, errors.New("uninitialized")
|
||||
}
|
||||
if i.xor == 1 {
|
||||
conn = NewXorConn(conn, i.eKeyNfs.Bytes())
|
||||
}
|
||||
c := &ClientConn{Conn: conn}
|
||||
|
||||
if i.minutes > 0 {
|
||||
@@ -74,7 +79,7 @@ func (i *ClientInstance) Handshake(conn net.Conn) (net.Conn, error) {
|
||||
if time.Now().Before(i.expire) {
|
||||
c.instance = i
|
||||
c.baseKey = i.baseKey
|
||||
c.reuse = i.reuse
|
||||
c.ticket = i.ticket
|
||||
i.RUnlock()
|
||||
return c, nil
|
||||
}
|
||||
@@ -104,7 +109,7 @@ func (i *ClientInstance) Handshake(conn net.Conn) (net.Conn, error) {
|
||||
return nil, err
|
||||
}
|
||||
encapsulatedPfsKey := peerServerHello[:1088]
|
||||
c.reuse = peerServerHello[1088:]
|
||||
c.ticket = peerServerHello[1088:]
|
||||
|
||||
pfsKey, err := dKeyPfs.Decapsulate(encapsulatedPfsKey)
|
||||
if err != nil {
|
||||
@@ -115,7 +120,7 @@ func (i *ClientInstance) Handshake(conn net.Conn) (net.Conn, error) {
|
||||
authKey := make([]byte, 32)
|
||||
hkdf.New(sha256.New, c.baseKey, encapsulatedNfsKey, eKeyPfs).Read(authKey)
|
||||
nonce := make([]byte, 12)
|
||||
VLESS, _ := newAead(ClientCipher, authKey).Open(nil, nonce, c.reuse, encapsulatedPfsKey)
|
||||
VLESS, _ := newAead(ClientCipher, authKey).Open(nil, nonce, c.ticket, encapsulatedPfsKey)
|
||||
if !bytes.Equal(VLESS, []byte("VLESS")) { // TODO: more message
|
||||
return nil, errors.New("invalid server")
|
||||
}
|
||||
@@ -124,7 +129,7 @@ func (i *ClientInstance) Handshake(conn net.Conn) (net.Conn, error) {
|
||||
i.Lock()
|
||||
i.expire = time.Now().Add(i.minutes)
|
||||
i.baseKey = c.baseKey
|
||||
i.reuse = c.reuse
|
||||
i.ticket = c.ticket
|
||||
i.Unlock()
|
||||
}
|
||||
|
||||
@@ -140,12 +145,12 @@ func (c *ClientConn) Write(b []byte) (int, error) {
|
||||
c.random = make([]byte, 32)
|
||||
rand.Read(c.random)
|
||||
key := make([]byte, 32)
|
||||
hkdf.New(sha256.New, c.baseKey, c.random, c.reuse).Read(key)
|
||||
hkdf.New(sha256.New, c.baseKey, c.random, c.ticket).Read(key)
|
||||
c.aead = newAead(ClientCipher, key)
|
||||
c.nonce = make([]byte, 12)
|
||||
|
||||
data = make([]byte, 21+32+5+len(b)+16)
|
||||
copy(data, c.reuse)
|
||||
copy(data, c.ticket)
|
||||
copy(data[21:], c.random)
|
||||
encodeHeader(data[53:], len(b)+16)
|
||||
c.aead.Seal(data[:58], c.nonce, b, data[53:58])
|
||||
@@ -210,7 +215,7 @@ func (c *ClientConn) Read(b []byte) (int, error) { // after first Write()
|
||||
if err != nil {
|
||||
if c.instance != nil {
|
||||
c.instance.Lock()
|
||||
if bytes.Equal(c.reuse, c.instance.reuse) {
|
||||
if bytes.Equal(c.ticket, c.instance.ticket) {
|
||||
c.instance.expire = time.Now() // expired
|
||||
}
|
||||
c.instance.Unlock()
|
||||
|
@@ -1,3 +1,5 @@
|
||||
// Package encryption copy and modify from xray-core
|
||||
// https://github.com/XTLS/Xray-core/commit/f61c14e9c63dc41a8a09135db3aea337974f3f37
|
||||
// https://github.com/XTLS/Xray-core/commit/3e19bf9233bdd9bafc073a71c65b737cc1ffba5e
|
||||
// https://github.com/XTLS/Xray-core/commit/7ffb555fc8ec51bd1e3e60f26f1d6957984dba80
|
||||
package encryption
|
||||
|
@@ -8,7 +8,10 @@ import (
|
||||
"github.com/metacubex/utls/mlkem"
|
||||
)
|
||||
|
||||
func GenMLKEM768(seedStr string) (seedBase64, pubBase64 string, err error) {
|
||||
const MLKEM768SeedLength = mlkem.SeedSize
|
||||
const MLKEM768ClientLength = mlkem.EncapsulationKeySize768
|
||||
|
||||
func GenMLKEM768(seedStr string) (seedBase64, clientBase64 string, err error) {
|
||||
var seed [64]byte
|
||||
if len(seedStr) > 0 {
|
||||
s, _ := base64.RawURLEncoding.DecodeString(seedStr)
|
||||
@@ -27,6 +30,6 @@ func GenMLKEM768(seedStr string) (seedBase64, pubBase64 string, err error) {
|
||||
key, _ := mlkem.NewDecapsulationKey768(seed[:])
|
||||
pub := key.EncapsulationKey()
|
||||
seedBase64 = base64.RawURLEncoding.EncodeToString(seed[:])
|
||||
pubBase64 = base64.RawURLEncoding.EncodeToString(pub.Bytes())
|
||||
clientBase64 = base64.RawURLEncoding.EncodeToString(pub.Bytes())
|
||||
return
|
||||
}
|
||||
|
@@ -25,6 +25,7 @@ type ServerSession struct {
|
||||
type ServerInstance struct {
|
||||
sync.RWMutex
|
||||
dKeyNfs *mlkem.DecapsulationKey768
|
||||
xor uint32
|
||||
minutes time.Duration
|
||||
sessions map[[21]byte]*ServerSession
|
||||
stop bool
|
||||
@@ -34,7 +35,7 @@ type ServerConn struct {
|
||||
net.Conn
|
||||
cipher byte
|
||||
baseKey []byte
|
||||
reuse []byte
|
||||
ticket []byte
|
||||
peerRandom []byte
|
||||
peerAead cipher.AEAD
|
||||
peerNonce []byte
|
||||
@@ -43,8 +44,9 @@ type ServerConn struct {
|
||||
nonce []byte
|
||||
}
|
||||
|
||||
func (i *ServerInstance) Init(dKeyNfsData []byte, minutes time.Duration) (err error) {
|
||||
func (i *ServerInstance) Init(dKeyNfsData []byte, xor uint32, minutes time.Duration) (err error) {
|
||||
i.dKeyNfs, err = mlkem.NewDecapsulationKey768(dKeyNfsData)
|
||||
i.xor = xor
|
||||
if minutes > 0 {
|
||||
i.minutes = minutes
|
||||
i.sessions = make(map[[21]byte]*ServerSession)
|
||||
@@ -79,22 +81,25 @@ func (i *ServerInstance) Handshake(conn net.Conn) (net.Conn, error) {
|
||||
if i.dKeyNfs == nil {
|
||||
return nil, errors.New("uninitialized")
|
||||
}
|
||||
if i.xor == 1 {
|
||||
conn = NewXorConn(conn, i.dKeyNfs.EncapsulationKey().Bytes())
|
||||
}
|
||||
c := &ServerConn{Conn: conn}
|
||||
|
||||
peerReuseHello := make([]byte, 21+32)
|
||||
if _, err := io.ReadFull(c.Conn, peerReuseHello); err != nil {
|
||||
peerTicketHello := make([]byte, 21+32)
|
||||
if _, err := io.ReadFull(c.Conn, peerTicketHello); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if i.minutes > 0 {
|
||||
i.RLock()
|
||||
s := i.sessions[[21]byte(peerReuseHello)]
|
||||
s := i.sessions[[21]byte(peerTicketHello)]
|
||||
i.RUnlock()
|
||||
if s != nil {
|
||||
if _, replay := s.randoms.LoadOrStore([32]byte(peerReuseHello[21:]), true); !replay {
|
||||
if _, replay := s.randoms.LoadOrStore([32]byte(peerTicketHello[21:]), true); !replay {
|
||||
c.cipher = s.cipher
|
||||
c.baseKey = s.baseKey
|
||||
c.reuse = peerReuseHello[:21]
|
||||
c.peerRandom = peerReuseHello[21:]
|
||||
c.ticket = peerTicketHello[:21]
|
||||
c.peerRandom = peerTicketHello[21:]
|
||||
return c, nil
|
||||
}
|
||||
}
|
||||
@@ -106,11 +111,11 @@ func (i *ServerInstance) Handshake(conn net.Conn) (net.Conn, error) {
|
||||
}
|
||||
if l, _ := decodeHeader(peerHeader); l != 0 {
|
||||
c.Conn.Write(make([]byte, randBetween(100, 1000))) // make client do new handshake
|
||||
return nil, errors.New("invalid reuse")
|
||||
return nil, errors.New("invalid ticket")
|
||||
}
|
||||
|
||||
peerClientHello := make([]byte, 1088+1184+1)
|
||||
copy(peerClientHello, peerReuseHello)
|
||||
copy(peerClientHello, peerTicketHello)
|
||||
copy(peerClientHello[53:], peerHeader)
|
||||
if _, err := io.ReadFull(c.Conn, peerClientHello[58:]); err != nil {
|
||||
return nil, err
|
||||
@@ -136,13 +141,13 @@ func (i *ServerInstance) Handshake(conn net.Conn) (net.Conn, error) {
|
||||
authKey := make([]byte, 32)
|
||||
hkdf.New(sha256.New, c.baseKey, encapsulatedNfsKey, eKeyPfsData).Read(authKey)
|
||||
nonce := make([]byte, 12)
|
||||
c.reuse = newAead(c.cipher, authKey).Seal(nil, nonce, []byte("VLESS"), encapsulatedPfsKey)
|
||||
c.ticket = newAead(c.cipher, authKey).Seal(nil, nonce, []byte("VLESS"), encapsulatedPfsKey)
|
||||
|
||||
padding := randBetween(100, 1000)
|
||||
|
||||
serverHello := make([]byte, 1088+21+5+padding)
|
||||
copy(serverHello, encapsulatedPfsKey)
|
||||
copy(serverHello[1088:], c.reuse)
|
||||
copy(serverHello[1088:], c.ticket)
|
||||
encodeHeader(serverHello[1109:], int(padding))
|
||||
|
||||
if _, err := c.Conn.Write(serverHello); err != nil {
|
||||
@@ -151,7 +156,7 @@ func (i *ServerInstance) Handshake(conn net.Conn) (net.Conn, error) {
|
||||
|
||||
if i.minutes > 0 {
|
||||
i.Lock()
|
||||
i.sessions[[21]byte(c.reuse)] = &ServerSession{
|
||||
i.sessions[[21]byte(c.ticket)] = &ServerSession{
|
||||
expire: time.Now().Add(i.minutes),
|
||||
cipher: c.cipher,
|
||||
baseKey: c.baseKey,
|
||||
@@ -181,12 +186,12 @@ func (c *ServerConn) Read(b []byte) (int, error) {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
peerIndex := make([]byte, 21)
|
||||
copy(peerIndex, peerHeader)
|
||||
if _, err := io.ReadFull(c.Conn, peerIndex[5:]); err != nil {
|
||||
peerTicket := make([]byte, 21)
|
||||
copy(peerTicket, peerHeader)
|
||||
if _, err := io.ReadFull(c.Conn, peerTicket[5:]); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if !bytes.Equal(peerIndex, c.reuse) {
|
||||
if !bytes.Equal(peerTicket, c.ticket) {
|
||||
return 0, errors.New("naughty boy")
|
||||
}
|
||||
c.peerRandom = make([]byte, 32)
|
||||
@@ -195,7 +200,7 @@ func (c *ServerConn) Read(b []byte) (int, error) {
|
||||
}
|
||||
}
|
||||
peerKey := make([]byte, 32)
|
||||
hkdf.New(sha256.New, c.baseKey, c.peerRandom, c.reuse).Read(peerKey)
|
||||
hkdf.New(sha256.New, c.baseKey, c.peerRandom, c.ticket).Read(peerKey)
|
||||
c.peerAead = newAead(c.cipher, peerKey)
|
||||
c.peerNonce = make([]byte, 12)
|
||||
}
|
||||
|
63
clash-meta/transport/vless/encryption/xor.go
Normal file
63
clash-meta/transport/vless/encryption/xor.go
Normal file
@@ -0,0 +1,63 @@
|
||||
package encryption
|
||||
|
||||
import (
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"crypto/rand"
|
||||
"io"
|
||||
"net"
|
||||
)
|
||||
|
||||
type XorConn struct {
|
||||
net.Conn
|
||||
key []byte
|
||||
ctr cipher.Stream
|
||||
peerCtr cipher.Stream
|
||||
}
|
||||
|
||||
func NewXorConn(conn net.Conn, key []byte) *XorConn {
|
||||
return &XorConn{Conn: conn, key: key[:16]}
|
||||
}
|
||||
|
||||
func (c *XorConn) Write(b []byte) (int, error) {
|
||||
if len(b) == 0 {
|
||||
return 0, nil
|
||||
}
|
||||
var iv []byte
|
||||
if c.ctr == nil {
|
||||
block, _ := aes.NewCipher(c.key)
|
||||
iv = make([]byte, 16)
|
||||
rand.Read(iv)
|
||||
c.ctr = cipher.NewCTR(block, iv)
|
||||
}
|
||||
c.ctr.XORKeyStream(b, b) // caller MUST discard b
|
||||
if iv != nil {
|
||||
b = append(iv, b...)
|
||||
}
|
||||
if _, err := c.Conn.Write(b); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if iv != nil {
|
||||
b = b[16:]
|
||||
}
|
||||
return len(b), nil
|
||||
}
|
||||
|
||||
func (c *XorConn) Read(b []byte) (int, error) {
|
||||
if len(b) == 0 {
|
||||
return 0, nil
|
||||
}
|
||||
if c.peerCtr == nil {
|
||||
peerIv := make([]byte, 16)
|
||||
if _, err := io.ReadFull(c.Conn, peerIv); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
block, _ := aes.NewCipher(c.key)
|
||||
c.peerCtr = cipher.NewCTR(block, peerIv)
|
||||
}
|
||||
n, err := c.Conn.Read(b)
|
||||
if n > 0 {
|
||||
c.peerCtr.XORKeyStream(b[:n], b[:n])
|
||||
}
|
||||
return n, err
|
||||
}
|
@@ -32,8 +32,8 @@
|
||||
"country-emoji": "1.5.6",
|
||||
"dayjs": "1.11.13",
|
||||
"framer-motion": "12.23.12",
|
||||
"i18next": "25.3.2",
|
||||
"jotai": "2.13.0",
|
||||
"i18next": "25.3.4",
|
||||
"jotai": "2.13.1",
|
||||
"json-schema": "0.4.0",
|
||||
"material-react-table": "3.2.1",
|
||||
"monaco-editor": "0.52.2",
|
||||
@@ -56,12 +56,12 @@
|
||||
"@csstools/normalize.css": "12.1.1",
|
||||
"@emotion/babel-plugin": "11.13.5",
|
||||
"@emotion/react": "11.14.0",
|
||||
"@iconify/json": "2.2.368",
|
||||
"@iconify/json": "2.2.371",
|
||||
"@monaco-editor/react": "4.7.0",
|
||||
"@tanstack/react-query": "5.84.2",
|
||||
"@tanstack/react-router": "1.131.2",
|
||||
"@tanstack/react-router-devtools": "1.131.2",
|
||||
"@tanstack/router-plugin": "1.131.2",
|
||||
"@tanstack/react-router": "1.131.3",
|
||||
"@tanstack/react-router-devtools": "1.131.3",
|
||||
"@tanstack/router-plugin": "1.131.3",
|
||||
"@tauri-apps/plugin-clipboard-manager": "2.3.0",
|
||||
"@tauri-apps/plugin-dialog": "2.3.0",
|
||||
"@tauri-apps/plugin-fs": "2.4.0",
|
||||
|
@@ -2,10 +2,10 @@
|
||||
"manifest_version": 1,
|
||||
"latest": {
|
||||
"mihomo": "v1.19.12",
|
||||
"mihomo_alpha": "alpha-e89af72",
|
||||
"mihomo_alpha": "alpha-3a0d267",
|
||||
"clash_rs": "v0.8.2",
|
||||
"clash_premium": "2023-09-05-gdcc8d87",
|
||||
"clash_rs_alpha": "0.8.2-alpha+sha.2a8be3b"
|
||||
"clash_rs_alpha": "0.8.2-alpha+sha.ec9134e"
|
||||
},
|
||||
"arch_template": {
|
||||
"mihomo": {
|
||||
@@ -69,5 +69,5 @@
|
||||
"linux-armv7hf": "clash-armv7-unknown-linux-gnueabihf"
|
||||
}
|
||||
},
|
||||
"updated_at": "2025-08-09T22:21:17.093Z"
|
||||
"updated_at": "2025-08-10T22:21:15.754Z"
|
||||
}
|
||||
|
116
clash-nyanpasu/pnpm-lock.yaml
generated
116
clash-nyanpasu/pnpm-lock.yaml
generated
@@ -250,7 +250,7 @@ importers:
|
||||
version: 4.1.11
|
||||
'@tanstack/router-zod-adapter':
|
||||
specifier: 1.81.5
|
||||
version: 1.81.5(@tanstack/react-router@1.131.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(zod@4.0.17)
|
||||
version: 1.81.5(@tanstack/react-router@1.131.3(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(zod@4.0.17)
|
||||
'@tauri-apps/api':
|
||||
specifier: 2.6.0
|
||||
version: 2.6.0
|
||||
@@ -276,11 +276,11 @@ importers:
|
||||
specifier: 12.23.12
|
||||
version: 12.23.12(@emotion/is-prop-valid@1.3.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)
|
||||
i18next:
|
||||
specifier: 25.3.2
|
||||
version: 25.3.2(typescript@5.9.2)
|
||||
specifier: 25.3.4
|
||||
version: 25.3.4(typescript@5.9.2)
|
||||
jotai:
|
||||
specifier: 2.13.0
|
||||
version: 2.13.0(@babel/core@7.28.0)(@babel/template@7.27.2)(@types/react@19.1.9)(react@19.1.1)
|
||||
specifier: 2.13.1
|
||||
version: 2.13.1(@babel/core@7.28.0)(@babel/template@7.27.2)(@types/react@19.1.9)(react@19.1.1)
|
||||
json-schema:
|
||||
specifier: 0.4.0
|
||||
version: 0.4.0
|
||||
@@ -310,7 +310,7 @@ importers:
|
||||
version: 7.6.2(dc790e3d871a3fe7e1d22dc6e321e397)
|
||||
react-i18next:
|
||||
specifier: 15.6.1
|
||||
version: 15.6.1(i18next@25.3.2(typescript@5.9.2))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(typescript@5.9.2)
|
||||
version: 15.6.1(i18next@25.3.4(typescript@5.9.2))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(typescript@5.9.2)
|
||||
react-markdown:
|
||||
specifier: 10.1.0
|
||||
version: 10.1.0(@types/react@19.1.9)(react@19.1.1)
|
||||
@@ -343,8 +343,8 @@ importers:
|
||||
specifier: 11.14.0
|
||||
version: 11.14.0(@types/react@19.1.9)(react@19.1.1)
|
||||
'@iconify/json':
|
||||
specifier: 2.2.368
|
||||
version: 2.2.368
|
||||
specifier: 2.2.371
|
||||
version: 2.2.371
|
||||
'@monaco-editor/react':
|
||||
specifier: 4.7.0
|
||||
version: 4.7.0(monaco-editor@0.52.2)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)
|
||||
@@ -352,14 +352,14 @@ importers:
|
||||
specifier: 5.84.2
|
||||
version: 5.84.2(react@19.1.1)
|
||||
'@tanstack/react-router':
|
||||
specifier: 1.131.2
|
||||
version: 1.131.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1)
|
||||
specifier: 1.131.3
|
||||
version: 1.131.3(react-dom@19.1.1(react@19.1.1))(react@19.1.1)
|
||||
'@tanstack/react-router-devtools':
|
||||
specifier: 1.131.2
|
||||
version: 1.131.2(@tanstack/react-router@1.131.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(@tanstack/router-core@1.131.2)(csstype@3.1.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(solid-js@1.9.5)(tiny-invariant@1.3.3)
|
||||
specifier: 1.131.3
|
||||
version: 1.131.3(@tanstack/react-router@1.131.3(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(@tanstack/router-core@1.131.3)(csstype@3.1.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(solid-js@1.9.5)(tiny-invariant@1.3.3)
|
||||
'@tanstack/router-plugin':
|
||||
specifier: 1.131.2
|
||||
version: 1.131.2(@tanstack/react-router@1.131.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(vite@7.1.1(@types/node@22.17.1)(jiti@2.4.2)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.90.0)(sass@1.90.0)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.3)(yaml@2.8.0))
|
||||
specifier: 1.131.3
|
||||
version: 1.131.3(@tanstack/react-router@1.131.3(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(vite@7.1.1(@types/node@22.17.1)(jiti@2.4.2)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.90.0)(sass@1.90.0)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.3)(yaml@2.8.0))
|
||||
'@tauri-apps/plugin-clipboard-manager':
|
||||
specifier: 2.3.0
|
||||
version: 2.3.0
|
||||
@@ -509,7 +509,7 @@ importers:
|
||||
version: 6.0.0(react@19.1.1)
|
||||
react-i18next:
|
||||
specifier: 15.6.1
|
||||
version: 15.6.1(i18next@25.3.2(typescript@5.9.2))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(typescript@5.9.2)
|
||||
version: 15.6.1(i18next@25.3.4(typescript@5.9.2))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(typescript@5.9.2)
|
||||
react-use:
|
||||
specifier: 17.6.0
|
||||
version: 17.6.0(react-dom@19.1.1(react@19.1.1))(react@19.1.1)
|
||||
@@ -1753,8 +1753,8 @@ packages:
|
||||
'@vue/compiler-sfc':
|
||||
optional: true
|
||||
|
||||
'@iconify/json@2.2.368':
|
||||
resolution: {integrity: sha512-gxz87+V5og+kYRc8jp0YTGgImusCpZLFVd+QzIVH5GwA9zQlMe2BvK9dhIHKSWlP1fZ7blKFKVqKKaCNoRCEiA==}
|
||||
'@iconify/json@2.2.371':
|
||||
resolution: {integrity: sha512-dnamUrgw8aDWz4STJOkQqqCz6GB2s7SHGPIY84EVQmlVXzM7T1V7L/csdL7r9bkA3AHF80+OXhx7o4FXn5L8pQ==}
|
||||
|
||||
'@iconify/types@2.0.0':
|
||||
resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==}
|
||||
@@ -2939,16 +2939,16 @@ packages:
|
||||
peerDependencies:
|
||||
react: ^18 || ^19
|
||||
|
||||
'@tanstack/react-router-devtools@1.131.2':
|
||||
resolution: {integrity: sha512-7bJxZadqjZrsdPOcKWp2+sc8cnARHzrgr/eduDJDA79Rbx7qEh8TgAY7xFqlhShCxA90/a9y4wastbs8AqnDcA==}
|
||||
'@tanstack/react-router-devtools@1.131.3':
|
||||
resolution: {integrity: sha512-opouR8dbBrDnkHdiyTVPb3rTfSRxWN+ZGi1YuEXNGUXgirvnpQUTWNP6kzDv1at29DxymwwfRRYD602MjZOOlA==}
|
||||
engines: {node: '>=12'}
|
||||
peerDependencies:
|
||||
'@tanstack/react-router': ^1.131.2
|
||||
'@tanstack/react-router': ^1.131.3
|
||||
react: '>=18.0.0 || >=19.0.0'
|
||||
react-dom: '>=18.0.0 || >=19.0.0'
|
||||
|
||||
'@tanstack/react-router@1.131.2':
|
||||
resolution: {integrity: sha512-MGkCPA/7HJ9UWIV27CtKb5i3Sizxywx43/h+ifrEC+2guzQR8yBcI4ibwMmSpsuGqKOzkuvX63RU1SVeCwbg+g==}
|
||||
'@tanstack/react-router@1.131.3':
|
||||
resolution: {integrity: sha512-1wxsStYJai0/ssOQeO+8mh5VmMmJWIZOtIEEqDxIhQX4dHyurKl6khl34+qLtDvWFsj6zgiMwjID3GQj5SMz1w==}
|
||||
engines: {node: '>=12'}
|
||||
peerDependencies:
|
||||
react: '>=18.0.0 || >=19.0.0'
|
||||
@@ -2973,15 +2973,15 @@ packages:
|
||||
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
|
||||
react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
|
||||
|
||||
'@tanstack/router-core@1.131.2':
|
||||
resolution: {integrity: sha512-ITnzlVk9iZTYNe/1FuLnDhpDTml1PfzUZk3V5He+NrXIcPGd2h3plZlv6NqZirNZMhCoiX52jfM1BOHGuy1ICA==}
|
||||
'@tanstack/router-core@1.131.3':
|
||||
resolution: {integrity: sha512-8sby4n2pgRJ7qZrFvuS6v21oBDHCRoFM8p+/HAIra2d32cD5wS5k9DeNltWFUAJFXdsdwpdGVA0iXSAc0WfIHw==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
'@tanstack/router-devtools-core@1.131.2':
|
||||
resolution: {integrity: sha512-j7++EKhxbB8JXFqbZH6fRdCge7pujqrFrBEDDpNX7ms3EY7MwAcqiYE4qqY9YsJhfAOjZWo+88KEzX9AB09twA==}
|
||||
'@tanstack/router-devtools-core@1.131.3':
|
||||
resolution: {integrity: sha512-GQHVCE0ywJ0ajz9K52RLAhbDSuziD3MVRYYp5S5w2i31Mb9xkzITJe/CZ7WIgOuY+XQm18P8drbJnxdHTNOcWQ==}
|
||||
engines: {node: '>=12'}
|
||||
peerDependencies:
|
||||
'@tanstack/router-core': ^1.131.2
|
||||
'@tanstack/router-core': ^1.131.3
|
||||
csstype: ^3.0.10
|
||||
solid-js: '>=1.9.5'
|
||||
tiny-invariant: ^1.3.3
|
||||
@@ -2989,16 +2989,16 @@ packages:
|
||||
csstype:
|
||||
optional: true
|
||||
|
||||
'@tanstack/router-generator@1.131.2':
|
||||
resolution: {integrity: sha512-A4IW5zmAV5NrRCf2UXONA47DLSEXPaIcPL3Bmi6MHmA8QaWkoJ7frTHv82QE8DmyIsv2Y7c0CfINy2K5KET0Tw==}
|
||||
'@tanstack/router-generator@1.131.3':
|
||||
resolution: {integrity: sha512-sTsi9lSxBCpAExQWyh3k2X40biiRHjIRISxVvko5sPG/+NKYFjGaQwgXQ/1jiDSTqe8i7/b/2l94ZJPTa6VPxQ==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
'@tanstack/router-plugin@1.131.2':
|
||||
resolution: {integrity: sha512-+F/Orgn4Gi69WBn+aRmVezGbbk/Uk8viciSkdeQUpU2cWtMSR2EFU2xjFG06YCTX92jcZAYfSRQMpStncRXJQQ==}
|
||||
'@tanstack/router-plugin@1.131.3':
|
||||
resolution: {integrity: sha512-PLCjxTTHBf5H9TqH+jTNvgSnnCZhvrLj61C5XAtONA7NUv+Lh4xJ/u0nn83ZYb7uFM4rMg1JmpU5mG8iNbGHZw==}
|
||||
engines: {node: '>=12'}
|
||||
peerDependencies:
|
||||
'@rsbuild/core': '>=1.0.2'
|
||||
'@tanstack/react-router': ^1.131.2
|
||||
'@tanstack/react-router': ^1.131.3
|
||||
vite: '>=5.0.0 || >=6.0.0'
|
||||
vite-plugin-solid: ^2.11.2
|
||||
webpack: '>=5.92.0'
|
||||
@@ -5482,8 +5482,8 @@ packages:
|
||||
hyphenate-style-name@1.1.0:
|
||||
resolution: {integrity: sha512-WDC/ui2VVRrz3jOVi+XtjqkDjiVjTtFaAGiW37k6b+ohyQ5wYDOGkvCZa8+H0nx3gyvv0+BST9xuOgIyGQ00gw==}
|
||||
|
||||
i18next@25.3.2:
|
||||
resolution: {integrity: sha512-JSnbZDxRVbphc5jiptxr3o2zocy5dEqpVm9qCGdJwRNO+9saUJS0/u4LnM/13C23fUEWxAylPqKU/NpMV/IjqA==}
|
||||
i18next@25.3.4:
|
||||
resolution: {integrity: sha512-AHklEYFLiRRxW1Cb6zE9lfnEtYvsydRC8nRS3RSKGX3zCqZ8nLZwMaUsrb80YuccPNv2RNokDL8LkTNnp+6mDw==}
|
||||
peerDependencies:
|
||||
typescript: ^5
|
||||
peerDependenciesMeta:
|
||||
@@ -5896,8 +5896,8 @@ packages:
|
||||
jju@1.4.0:
|
||||
resolution: {integrity: sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==}
|
||||
|
||||
jotai@2.13.0:
|
||||
resolution: {integrity: sha512-H43zXdanNTdpfOEJ4NVbm4hgmrctpXLZagjJNcqAywhUv+sTE7esvFjwm5oBg/ywT9Qw63lIkM6fjrhFuW8UDg==}
|
||||
jotai@2.13.1:
|
||||
resolution: {integrity: sha512-cRsw6kFeGC9Z/D3egVKrTXRweycZ4z/k7i2MrfCzPYsL9SIWcPXTyqv258/+Ay8VUEcihNiE/coBLE6Kic6b8A==}
|
||||
engines: {node: '>=12.20.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': '>=7.0.0'
|
||||
@@ -9953,7 +9953,7 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@iconify/json@2.2.368':
|
||||
'@iconify/json@2.2.371':
|
||||
dependencies:
|
||||
'@iconify/types': 2.0.0
|
||||
pathe: 1.1.2
|
||||
@@ -11040,10 +11040,10 @@ snapshots:
|
||||
'@tanstack/query-core': 5.83.1
|
||||
react: 19.1.1
|
||||
|
||||
'@tanstack/react-router-devtools@1.131.2(@tanstack/react-router@1.131.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(@tanstack/router-core@1.131.2)(csstype@3.1.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(solid-js@1.9.5)(tiny-invariant@1.3.3)':
|
||||
'@tanstack/react-router-devtools@1.131.3(@tanstack/react-router@1.131.3(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(@tanstack/router-core@1.131.3)(csstype@3.1.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(solid-js@1.9.5)(tiny-invariant@1.3.3)':
|
||||
dependencies:
|
||||
'@tanstack/react-router': 1.131.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1)
|
||||
'@tanstack/router-devtools-core': 1.131.2(@tanstack/router-core@1.131.2)(csstype@3.1.3)(solid-js@1.9.5)(tiny-invariant@1.3.3)
|
||||
'@tanstack/react-router': 1.131.3(react-dom@19.1.1(react@19.1.1))(react@19.1.1)
|
||||
'@tanstack/router-devtools-core': 1.131.3(@tanstack/router-core@1.131.3)(csstype@3.1.3)(solid-js@1.9.5)(tiny-invariant@1.3.3)
|
||||
react: 19.1.1
|
||||
react-dom: 19.1.1(react@19.1.1)
|
||||
transitivePeerDependencies:
|
||||
@@ -11052,11 +11052,11 @@ snapshots:
|
||||
- solid-js
|
||||
- tiny-invariant
|
||||
|
||||
'@tanstack/react-router@1.131.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1)':
|
||||
'@tanstack/react-router@1.131.3(react-dom@19.1.1(react@19.1.1))(react@19.1.1)':
|
||||
dependencies:
|
||||
'@tanstack/history': 1.131.2
|
||||
'@tanstack/react-store': 0.7.0(react-dom@19.1.1(react@19.1.1))(react@19.1.1)
|
||||
'@tanstack/router-core': 1.131.2
|
||||
'@tanstack/router-core': 1.131.3
|
||||
isbot: 5.1.28
|
||||
react: 19.1.1
|
||||
react-dom: 19.1.1(react@19.1.1)
|
||||
@@ -11082,7 +11082,7 @@ snapshots:
|
||||
react: 19.1.1
|
||||
react-dom: 19.1.1(react@19.1.1)
|
||||
|
||||
'@tanstack/router-core@1.131.2':
|
||||
'@tanstack/router-core@1.131.3':
|
||||
dependencies:
|
||||
'@tanstack/history': 1.131.2
|
||||
'@tanstack/store': 0.7.0
|
||||
@@ -11092,9 +11092,9 @@ snapshots:
|
||||
tiny-invariant: 1.3.3
|
||||
tiny-warning: 1.0.3
|
||||
|
||||
'@tanstack/router-devtools-core@1.131.2(@tanstack/router-core@1.131.2)(csstype@3.1.3)(solid-js@1.9.5)(tiny-invariant@1.3.3)':
|
||||
'@tanstack/router-devtools-core@1.131.3(@tanstack/router-core@1.131.3)(csstype@3.1.3)(solid-js@1.9.5)(tiny-invariant@1.3.3)':
|
||||
dependencies:
|
||||
'@tanstack/router-core': 1.131.2
|
||||
'@tanstack/router-core': 1.131.3
|
||||
clsx: 2.1.1
|
||||
goober: 2.1.16(csstype@3.1.3)
|
||||
solid-js: 1.9.5
|
||||
@@ -11102,9 +11102,9 @@ snapshots:
|
||||
optionalDependencies:
|
||||
csstype: 3.1.3
|
||||
|
||||
'@tanstack/router-generator@1.131.2':
|
||||
'@tanstack/router-generator@1.131.3':
|
||||
dependencies:
|
||||
'@tanstack/router-core': 1.131.2
|
||||
'@tanstack/router-core': 1.131.3
|
||||
'@tanstack/router-utils': 1.131.2
|
||||
'@tanstack/virtual-file-routes': 1.131.2
|
||||
prettier: 3.6.2
|
||||
@@ -11115,7 +11115,7 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@tanstack/router-plugin@1.131.2(@tanstack/react-router@1.131.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(vite@7.1.1(@types/node@22.17.1)(jiti@2.4.2)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.90.0)(sass@1.90.0)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.3)(yaml@2.8.0))':
|
||||
'@tanstack/router-plugin@1.131.3(@tanstack/react-router@1.131.3(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(vite@7.1.1(@types/node@22.17.1)(jiti@2.4.2)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.90.0)(sass@1.90.0)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.3)(yaml@2.8.0))':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.0
|
||||
'@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.0)
|
||||
@@ -11123,8 +11123,8 @@ snapshots:
|
||||
'@babel/template': 7.27.2
|
||||
'@babel/traverse': 7.28.0
|
||||
'@babel/types': 7.28.1
|
||||
'@tanstack/router-core': 1.131.2
|
||||
'@tanstack/router-generator': 1.131.2
|
||||
'@tanstack/router-core': 1.131.3
|
||||
'@tanstack/router-generator': 1.131.3
|
||||
'@tanstack/router-utils': 1.131.2
|
||||
'@tanstack/virtual-file-routes': 1.131.2
|
||||
babel-dead-code-elimination: 1.0.10
|
||||
@@ -11132,7 +11132,7 @@ snapshots:
|
||||
unplugin: 2.3.5
|
||||
zod: 3.25.76
|
||||
optionalDependencies:
|
||||
'@tanstack/react-router': 1.131.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1)
|
||||
'@tanstack/react-router': 1.131.3(react-dom@19.1.1(react@19.1.1))(react@19.1.1)
|
||||
vite: 7.1.1(@types/node@22.17.1)(jiti@2.4.2)(less@4.2.0)(lightningcss@1.30.1)(sass-embedded@1.90.0)(sass@1.90.0)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.3)(yaml@2.8.0)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
@@ -11148,9 +11148,9 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@tanstack/router-zod-adapter@1.81.5(@tanstack/react-router@1.131.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(zod@4.0.17)':
|
||||
'@tanstack/router-zod-adapter@1.81.5(@tanstack/react-router@1.131.3(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(zod@4.0.17)':
|
||||
dependencies:
|
||||
'@tanstack/react-router': 1.131.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1)
|
||||
'@tanstack/react-router': 1.131.3(react-dom@19.1.1(react@19.1.1))(react@19.1.1)
|
||||
zod: 4.0.17
|
||||
|
||||
'@tanstack/store@0.7.0': {}
|
||||
@@ -14090,9 +14090,9 @@ snapshots:
|
||||
|
||||
hyphenate-style-name@1.1.0: {}
|
||||
|
||||
i18next@25.3.2(typescript@5.9.2):
|
||||
i18next@25.3.4(typescript@5.9.2):
|
||||
dependencies:
|
||||
'@babel/runtime': 7.27.6
|
||||
'@babel/runtime': 7.28.2
|
||||
optionalDependencies:
|
||||
typescript: 5.9.2
|
||||
|
||||
@@ -14464,7 +14464,7 @@ snapshots:
|
||||
|
||||
jju@1.4.0: {}
|
||||
|
||||
jotai@2.13.0(@babel/core@7.28.0)(@babel/template@7.27.2)(@types/react@19.1.9)(react@19.1.1):
|
||||
jotai@2.13.1(@babel/core@7.28.0)(@babel/template@7.27.2)(@types/react@19.1.9)(react@19.1.1):
|
||||
optionalDependencies:
|
||||
'@babel/core': 7.28.0
|
||||
'@babel/template': 7.27.2
|
||||
@@ -15717,11 +15717,11 @@ snapshots:
|
||||
dependencies:
|
||||
react: 19.1.1
|
||||
|
||||
react-i18next@15.6.1(i18next@25.3.2(typescript@5.9.2))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(typescript@5.9.2):
|
||||
react-i18next@15.6.1(i18next@25.3.4(typescript@5.9.2))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(typescript@5.9.2):
|
||||
dependencies:
|
||||
'@babel/runtime': 7.27.6
|
||||
html-parse-stringify: 3.0.1
|
||||
i18next: 25.3.2(typescript@5.9.2)
|
||||
i18next: 25.3.4(typescript@5.9.2)
|
||||
react: 19.1.1
|
||||
optionalDependencies:
|
||||
react-dom: 19.1.1(react@19.1.1)
|
||||
|
@@ -2304,6 +2304,7 @@ CONFIG_HARDEN_BRANCH_HISTORY=y
|
||||
# CONFIG_HI6421V600_IRQ is not set
|
||||
# CONFIG_HI8435 is not set
|
||||
# CONFIG_HIBERNATION is not set
|
||||
# CONFIG_HIBERNATION_COMP_LZ4 is not set
|
||||
# CONFIG_HID is not set
|
||||
# CONFIG_HIDRAW is not set
|
||||
# CONFIG_HID_A4TECH is not set
|
||||
|
@@ -11,6 +11,7 @@ FEATURES:=audio display ext4 pcie boot-part rootfs-part rtc usb targz
|
||||
SUBTARGETS:=generic
|
||||
|
||||
KERNEL_PATCHVER:=6.6
|
||||
KERNEL_TESTING_PATCHVER:=6.12
|
||||
|
||||
KERNELNAME:=vmlinuz.efi dtbs
|
||||
|
||||
|
754
lede/target/linux/loongarch64/config-6.12
Normal file
754
lede/target/linux/loongarch64/config-6.12
Normal file
@@ -0,0 +1,754 @@
|
||||
# CONFIG_16KB_2LEVEL is not set
|
||||
CONFIG_16KB_3LEVEL=y
|
||||
# CONFIG_4KB_3LEVEL is not set
|
||||
# CONFIG_4KB_4LEVEL is not set
|
||||
CONFIG_64BIT=y
|
||||
# CONFIG_64KB_2LEVEL is not set
|
||||
# CONFIG_64KB_3LEVEL is not set
|
||||
CONFIG_AC97_BUS=y
|
||||
CONFIG_ACPI=y
|
||||
CONFIG_ACPI_AC=y
|
||||
CONFIG_ACPI_BATTERY=y
|
||||
# CONFIG_ACPI_BGRT is not set
|
||||
CONFIG_ACPI_BUTTON=y
|
||||
CONFIG_ACPI_CONTAINER=y
|
||||
CONFIG_ACPI_CPU_FREQ_PSS=y
|
||||
# CONFIG_ACPI_DEBUG is not set
|
||||
# CONFIG_ACPI_DEBUGGER is not set
|
||||
# CONFIG_ACPI_DOCK is not set
|
||||
# CONFIG_ACPI_EC_DEBUGFS is not set
|
||||
CONFIG_ACPI_FAN=y
|
||||
# CONFIG_ACPI_FFH is not set
|
||||
CONFIG_ACPI_GENERIC_GSI=y
|
||||
CONFIG_ACPI_HOTPLUG_CPU=y
|
||||
CONFIG_ACPI_I2C_OPREGION=y
|
||||
CONFIG_ACPI_MCFG=y
|
||||
CONFIG_ACPI_NHLT=y
|
||||
# CONFIG_ACPI_PCI_SLOT is not set
|
||||
# CONFIG_ACPI_PFRUT is not set
|
||||
CONFIG_ACPI_PPTT=y
|
||||
CONFIG_ACPI_PROCESSOR=y
|
||||
CONFIG_ACPI_PROCESSOR_IDLE=y
|
||||
CONFIG_ACPI_SLEEP=y
|
||||
# CONFIG_ACPI_SPCR_TABLE is not set
|
||||
CONFIG_ACPI_SYSTEM_POWER_STATES_SUPPORT=y
|
||||
CONFIG_ACPI_TABLE_UPGRADE=y
|
||||
# CONFIG_ACPI_TAD is not set
|
||||
CONFIG_ACPI_THERMAL=y
|
||||
CONFIG_ACPI_THERMAL_LIB=y
|
||||
CONFIG_ACPI_VIDEO=y
|
||||
CONFIG_APERTURE_HELPERS=y
|
||||
CONFIG_ARCH_DISABLE_KASAN_INLINE=y
|
||||
CONFIG_ARCH_DMA_ADDR_T_64BIT=y
|
||||
CONFIG_ARCH_HIBERNATION_POSSIBLE=y
|
||||
# CONFIG_ARCH_IOREMAP is not set
|
||||
CONFIG_ARCH_KEEP_MEMBLOCK=y
|
||||
CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
|
||||
CONFIG_ARCH_MIGHT_HAVE_PC_SERIO=y
|
||||
CONFIG_ARCH_MMAP_RND_BITS=12
|
||||
CONFIG_ARCH_MMAP_RND_BITS_MAX=18
|
||||
CONFIG_ARCH_MMAP_RND_BITS_MIN=12
|
||||
CONFIG_ARCH_SELECT_MEMORY_MODEL=y
|
||||
CONFIG_ARCH_SPARSEMEM_ENABLE=y
|
||||
CONFIG_ARCH_STACKWALK=y
|
||||
CONFIG_ARCH_STRICT_ALIGN=y
|
||||
CONFIG_ARCH_SUSPEND_POSSIBLE=y
|
||||
CONFIG_ARCH_WANTS_NO_INSTR=y
|
||||
CONFIG_ARCH_WANTS_THP_SWAP=y
|
||||
# CONFIG_ARCH_WRITECOMBINE is not set
|
||||
CONFIG_ASN1=y
|
||||
CONFIG_ASSOCIATIVE_ARRAY=y
|
||||
CONFIG_ATA=y
|
||||
CONFIG_ATA_ACPI=y
|
||||
CONFIG_ATA_FORCE=y
|
||||
# CONFIG_ATA_SFF is not set
|
||||
CONFIG_ATA_VERBOSE_ERROR=y
|
||||
CONFIG_AUDIT=y
|
||||
CONFIG_AUDITSYSCALL=y
|
||||
CONFIG_AUDIT_GENERIC=y
|
||||
CONFIG_BACKLIGHT_CLASS_DEVICE=y
|
||||
CONFIG_BLK_CGROUP=y
|
||||
CONFIG_BLK_CGROUP_IOCOST=y
|
||||
CONFIG_BLK_CGROUP_RWSTAT=y
|
||||
CONFIG_BLK_DEBUG_FS=y
|
||||
CONFIG_BLK_DEV_BSGLIB=y
|
||||
CONFIG_BLK_DEV_BSG_COMMON=y
|
||||
CONFIG_BLK_DEV_INTEGRITY=y
|
||||
CONFIG_BLK_DEV_LOOP=y
|
||||
CONFIG_BLK_DEV_NVME=y
|
||||
CONFIG_BLK_DEV_SD=y
|
||||
CONFIG_BLK_DEV_SR=y
|
||||
CONFIG_BLK_DEV_THROTTLING=y
|
||||
CONFIG_BLK_DEV_ZONED=y
|
||||
CONFIG_BLK_MQ_PCI=y
|
||||
CONFIG_BLK_PM=y
|
||||
CONFIG_BLK_RQ_ALLOC_TIME=y
|
||||
CONFIG_BLK_SED_OPAL=y
|
||||
CONFIG_BLK_WBT=y
|
||||
CONFIG_BLK_WBT_MQ=y
|
||||
CONFIG_BLOCK_LEGACY_AUTOLOAD=y
|
||||
CONFIG_BOOT_PRINTK_DELAY=y
|
||||
CONFIG_BSD_PROCESS_ACCT=y
|
||||
CONFIG_BSD_PROCESS_ACCT_V3=y
|
||||
CONFIG_BUFFER_HEAD=y
|
||||
CONFIG_BUG_ON_DATA_CORRUPTION=y
|
||||
# CONFIG_BUILTIN_DTB is not set
|
||||
CONFIG_CACHESTAT_SYSCALL=y
|
||||
CONFIG_CDROM=y
|
||||
CONFIG_CFS_BANDWIDTH=y
|
||||
CONFIG_CGROUPS=y
|
||||
# CONFIG_CGROUP_BPF is not set
|
||||
# CONFIG_CGROUP_CPUACCT is not set
|
||||
# CONFIG_CGROUP_DEBUG is not set
|
||||
# CONFIG_CGROUP_DEVICE is not set
|
||||
# CONFIG_CGROUP_FREEZER is not set
|
||||
# CONFIG_CGROUP_HUGETLB is not set
|
||||
# CONFIG_CGROUP_NET_CLASSID is not set
|
||||
# CONFIG_CGROUP_NET_PRIO is not set
|
||||
# CONFIG_CGROUP_PIDS is not set
|
||||
# CONFIG_CGROUP_RDMA is not set
|
||||
CONFIG_CGROUP_SCHED=y
|
||||
CONFIG_CHECKPOINT_RESTORE=y
|
||||
CONFIG_CHR_DEV_SG=y
|
||||
CONFIG_CLZ_TAB=y
|
||||
CONFIG_CMA=y
|
||||
CONFIG_CMA_ALIGNMENT=8
|
||||
CONFIG_CMA_AREAS=7
|
||||
# CONFIG_CMA_DEBUGFS is not set
|
||||
CONFIG_CMA_SIZE_MBYTES=16
|
||||
# CONFIG_CMA_SIZE_SEL_MAX is not set
|
||||
CONFIG_CMA_SIZE_SEL_MBYTES=y
|
||||
# CONFIG_CMA_SIZE_SEL_MIN is not set
|
||||
# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set
|
||||
# CONFIG_CMA_SYSFS is not set
|
||||
CONFIG_CMDLINE_BOOTLOADER=y
|
||||
CONFIG_COMMON_CLK=y
|
||||
# CONFIG_COMMON_CLK_LOONGSON2 is not set
|
||||
CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
|
||||
# CONFIG_COMPAT_32BIT_TIME is not set
|
||||
CONFIG_CONNECTOR=y
|
||||
CONFIG_CONSOLE_TRANSLATIONS=y
|
||||
CONFIG_CONTEXT_TRACKING=y
|
||||
CONFIG_CONTEXT_TRACKING_IDLE=y
|
||||
CONFIG_CONTIG_ALLOC=y
|
||||
CONFIG_COREDUMP=y
|
||||
CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
|
||||
CONFIG_CPUSETS=y
|
||||
# CONFIG_CPUSETS_V1 is not set
|
||||
CONFIG_CPU_HAS_FPU=y
|
||||
CONFIG_CPU_HAS_LASX=y
|
||||
CONFIG_CPU_HAS_LBT=y
|
||||
CONFIG_CPU_HAS_LSX=y
|
||||
CONFIG_CPU_HAS_PREFETCH=y
|
||||
CONFIG_CPU_ISOLATION=y
|
||||
CONFIG_CPU_MITIGATIONS=y
|
||||
CONFIG_CPU_PM=y
|
||||
CONFIG_CPU_RMAP=y
|
||||
CONFIG_CRC16=y
|
||||
CONFIG_CRC64=y
|
||||
CONFIG_CRC64_ROCKSOFT=y
|
||||
CONFIG_CRC_T10DIF=y
|
||||
CONFIG_CROSS_MEMORY_ATTACH=y
|
||||
CONFIG_CRYPTO_CBC=y
|
||||
CONFIG_CRYPTO_CRC32=y
|
||||
CONFIG_CRYPTO_CRC32C=y
|
||||
# CONFIG_CRYPTO_CRC32_LOONGARCH is not set
|
||||
CONFIG_CRYPTO_CRC64_ROCKSOFT=y
|
||||
CONFIG_CRYPTO_CRCT10DIF=y
|
||||
CONFIG_CRYPTO_ECB=y
|
||||
CONFIG_CRYPTO_HMAC=y
|
||||
CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
|
||||
CONFIG_CRYPTO_LIB_GF128MUL=y
|
||||
CONFIG_CRYPTO_LIB_POLY1305_RSIZE=1
|
||||
CONFIG_CRYPTO_LIB_SHA1=y
|
||||
CONFIG_CRYPTO_LIB_SHA256=y
|
||||
CONFIG_CRYPTO_LIB_UTILS=y
|
||||
CONFIG_CRYPTO_LZO=y
|
||||
CONFIG_CRYPTO_MD5=y
|
||||
CONFIG_CRYPTO_RNG=y
|
||||
CONFIG_CRYPTO_RNG2=y
|
||||
CONFIG_CRYPTO_RSA=y
|
||||
CONFIG_CRYPTO_SHA1=y
|
||||
CONFIG_CRYPTO_SHA256=y
|
||||
CONFIG_DEBUG_BUGVERBOSE=y
|
||||
CONFIG_DEBUG_INFO=y
|
||||
CONFIG_DEBUG_LIST=y
|
||||
CONFIG_DEBUG_MEMORY_INIT=y
|
||||
CONFIG_DEBUG_MISC=y
|
||||
CONFIG_DETECT_HUNG_TASK=y
|
||||
# CONFIG_DEVFREQ_GOV_PASSIVE is not set
|
||||
# CONFIG_DEVFREQ_GOV_PERFORMANCE is not set
|
||||
# CONFIG_DEVFREQ_GOV_POWERSAVE is not set
|
||||
# CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND is not set
|
||||
# CONFIG_DEVFREQ_GOV_USERSPACE is not set
|
||||
CONFIG_DEVFREQ_THERMAL=y
|
||||
CONFIG_DEVMEM=y
|
||||
CONFIG_DEVTMPFS=y
|
||||
CONFIG_DMA_CMA=y
|
||||
CONFIG_DMA_NEED_SYNC=y
|
||||
CONFIG_DMA_SHARED_BUFFER=y
|
||||
CONFIG_DMI=y
|
||||
CONFIG_DMIID=y
|
||||
CONFIG_DMI_SCAN_MACHINE_NON_EFI_FALLBACK=y
|
||||
CONFIG_DMI_SYSFS=y
|
||||
CONFIG_DRM=y
|
||||
CONFIG_DRM_BRIDGE=y
|
||||
CONFIG_DRM_FBDEV_EMULATION=y
|
||||
CONFIG_DRM_FBDEV_OVERALLOC=100
|
||||
CONFIG_DRM_KMS_HELPER=y
|
||||
CONFIG_DRM_LOAD_EDID_FIRMWARE=y
|
||||
CONFIG_DRM_LOONGSON=y
|
||||
CONFIG_DRM_PANEL=y
|
||||
CONFIG_DRM_PANEL_BRIDGE=y
|
||||
CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y
|
||||
CONFIG_DRM_TTM=y
|
||||
CONFIG_DRM_TTM_HELPER=y
|
||||
# CONFIG_DRM_WERROR is not set
|
||||
CONFIG_DTC=y
|
||||
CONFIG_DUMMY_CONSOLE=y
|
||||
CONFIG_EFI=y
|
||||
CONFIG_EFIVAR_FS=m
|
||||
# CONFIG_EFI_BOOTLOADER_CONTROL is not set
|
||||
# CONFIG_EFI_CAPSULE_LOADER is not set
|
||||
# CONFIG_EFI_COCO_SECRET is not set
|
||||
CONFIG_EFI_CUSTOM_SSDT_OVERLAYS=y
|
||||
# CONFIG_EFI_DISABLE_PCI_DMA is not set
|
||||
# CONFIG_EFI_DISABLE_RUNTIME is not set
|
||||
CONFIG_EFI_EARLYCON=y
|
||||
CONFIG_EFI_ESRT=y
|
||||
CONFIG_EFI_GENERIC_STUB=y
|
||||
CONFIG_EFI_RUNTIME_WRAPPERS=y
|
||||
CONFIG_EFI_STUB=y
|
||||
# CONFIG_EFI_TEST is not set
|
||||
CONFIG_EFI_ZBOOT=y
|
||||
CONFIG_ELF_CORE=y
|
||||
CONFIG_ENCRYPTED_KEYS=y
|
||||
CONFIG_EXCLUSIVE_SYSTEM_RAM=y
|
||||
CONFIG_EXPORTFS_BLOCK_OPS=y
|
||||
CONFIG_EXT4_FS=y
|
||||
CONFIG_FAILOVER=y
|
||||
CONFIG_FAIR_GROUP_SCHED=y
|
||||
CONFIG_FANOTIFY=y
|
||||
CONFIG_FB=y
|
||||
CONFIG_FB_CFB_COPYAREA=y
|
||||
CONFIG_FB_CFB_FILLRECT=y
|
||||
CONFIG_FB_CFB_IMAGEBLIT=y
|
||||
CONFIG_FB_CORE=y
|
||||
CONFIG_FB_DEFERRED_IO=y
|
||||
CONFIG_FB_DEVICE=y
|
||||
CONFIG_FB_EFI=y
|
||||
CONFIG_FB_IOMEM_FOPS=y
|
||||
CONFIG_FB_IOMEM_HELPERS=y
|
||||
CONFIG_FB_MODE_HELPERS=y
|
||||
CONFIG_FB_SIMPLE=y
|
||||
CONFIG_FB_SYSMEM_FOPS=y
|
||||
CONFIG_FB_SYSMEM_HELPERS=y
|
||||
CONFIG_FB_SYSMEM_HELPERS_DEFERRED=y
|
||||
CONFIG_FB_SYS_COPYAREA=y
|
||||
CONFIG_FB_SYS_FILLRECT=y
|
||||
CONFIG_FB_SYS_IMAGEBLIT=y
|
||||
CONFIG_FB_TILEBLITTING=y
|
||||
CONFIG_FHANDLE=y
|
||||
CONFIG_FIRMWARE_EDID=y
|
||||
CONFIG_FIRMWARE_TABLE=y
|
||||
CONFIG_FIX_EARLYCON_MEM=y
|
||||
# CONFIG_FLATMEM_MANUAL is not set
|
||||
CONFIG_FONTS=y
|
||||
# CONFIG_FONT_10x18 is not set
|
||||
# CONFIG_FONT_6x10 is not set
|
||||
# CONFIG_FONT_6x11 is not set
|
||||
# CONFIG_FONT_7x14 is not set
|
||||
CONFIG_FONT_8x16=y
|
||||
CONFIG_FONT_8x8=y
|
||||
# CONFIG_FONT_ACORN_8x8 is not set
|
||||
# CONFIG_FONT_MINI_4x6 is not set
|
||||
# CONFIG_FONT_PEARL_8x8 is not set
|
||||
# CONFIG_FONT_SUN12x22 is not set
|
||||
# CONFIG_FONT_SUN8x16 is not set
|
||||
CONFIG_FONT_SUPPORT=y
|
||||
CONFIG_FONT_TER16x32=y
|
||||
CONFIG_FRAMEBUFFER_CONSOLE=y
|
||||
CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
|
||||
CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
|
||||
CONFIG_FREEZER=y
|
||||
CONFIG_FS_IOMAP=y
|
||||
CONFIG_FS_MBCACHE=y
|
||||
CONFIG_FUNCTION_ALIGNMENT=0
|
||||
CONFIG_FW_CACHE=y
|
||||
CONFIG_FW_LOADER_PAGED_BUF=y
|
||||
CONFIG_FW_LOADER_SYSFS=y
|
||||
CONFIG_GENERIC_ALLOCATOR=y
|
||||
CONFIG_GENERIC_BUG=y
|
||||
CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y
|
||||
CONFIG_GENERIC_CLOCKEVENTS=y
|
||||
CONFIG_GENERIC_CMOS_UPDATE=y
|
||||
CONFIG_GENERIC_CPU_AUTOPROBE=y
|
||||
CONFIG_GENERIC_CPU_DEVICES=y
|
||||
CONFIG_GENERIC_CPU_VULNERABILITIES=y
|
||||
CONFIG_GENERIC_CSUM=y
|
||||
CONFIG_GENERIC_ENTRY=y
|
||||
CONFIG_GENERIC_GETTIMEOFDAY=y
|
||||
CONFIG_GENERIC_IOREMAP=y
|
||||
CONFIG_GENERIC_IRQ_CHIP=y
|
||||
CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
|
||||
CONFIG_GENERIC_IRQ_MATRIX_ALLOCATOR=y
|
||||
CONFIG_GENERIC_IRQ_MIGRATION=y
|
||||
CONFIG_GENERIC_IRQ_MULTI_HANDLER=y
|
||||
CONFIG_GENERIC_IRQ_SHOW=y
|
||||
CONFIG_GENERIC_LIB_ASHLDI3=y
|
||||
CONFIG_GENERIC_LIB_ASHRDI3=y
|
||||
CONFIG_GENERIC_LIB_CMPDI2=y
|
||||
CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED=y
|
||||
CONFIG_GENERIC_LIB_LSHRDI3=y
|
||||
CONFIG_GENERIC_LIB_UCMPDI2=y
|
||||
CONFIG_GENERIC_MSI_IRQ=y
|
||||
CONFIG_GENERIC_PCI_IOMAP=y
|
||||
CONFIG_GENERIC_PHY=y
|
||||
CONFIG_GENERIC_SCHED_CLOCK=y
|
||||
CONFIG_GENERIC_SMP_IDLE_THREAD=y
|
||||
CONFIG_GENERIC_STRNCPY_FROM_USER=y
|
||||
CONFIG_GENERIC_STRNLEN_USER=y
|
||||
CONFIG_GENERIC_TIME_VSYSCALL=y
|
||||
CONFIG_GLOB=y
|
||||
CONFIG_GPIO_ACPI=y
|
||||
CONFIG_GPIO_CDEV=y
|
||||
CONFIG_GPIO_CDEV_V1=y
|
||||
# CONFIG_GPIO_LOONGSON_64BIT is not set
|
||||
CONFIG_GROUP_SCHED_WEIGHT=y
|
||||
CONFIG_HAMRADIO=y
|
||||
CONFIG_HAS_DMA=y
|
||||
CONFIG_HAS_IOMEM=y
|
||||
CONFIG_HAS_IOPORT=y
|
||||
CONFIG_HAS_IOPORT_MAP=y
|
||||
CONFIG_HDMI=y
|
||||
CONFIG_HIBERNATE_CALLBACKS=y
|
||||
CONFIG_HIBERNATION=y
|
||||
CONFIG_HIBERNATION_COMP_LZO=y
|
||||
CONFIG_HIBERNATION_DEF_COMP="lzo"
|
||||
CONFIG_HIBERNATION_SNAPSHOT_DEV=y
|
||||
CONFIG_HID=y
|
||||
CONFIG_HIDRAW=y
|
||||
CONFIG_HID_GENERIC=y
|
||||
CONFIG_HID_SUPPORT=y
|
||||
CONFIG_HOTPLUG_CPU=y
|
||||
CONFIG_HUGETLBFS=y
|
||||
CONFIG_HUGETLB_PAGE=y
|
||||
CONFIG_HUGETLB_PAGE_OPTIMIZE_VMEMMAP=y
|
||||
CONFIG_HWMON=y
|
||||
CONFIG_HZ=250
|
||||
# CONFIG_HZ_100 is not set
|
||||
CONFIG_HZ_250=y
|
||||
CONFIG_HZ_PERIODIC=y
|
||||
CONFIG_I2C=y
|
||||
CONFIG_I2C_ALGOBIT=y
|
||||
# CONFIG_I2C_AMD_MP2 is not set
|
||||
CONFIG_I2C_BOARDINFO=y
|
||||
# CONFIG_I2C_LS2X is not set
|
||||
# CONFIG_I2C_ZHAOXIN is not set
|
||||
CONFIG_INITRAMFS_PRESERVE_MTIME=y
|
||||
CONFIG_INITRAMFS_SOURCE=""
|
||||
CONFIG_INIT_STACK_ALL_ZERO=y
|
||||
# CONFIG_INIT_STACK_NONE is not set
|
||||
CONFIG_INPUT=y
|
||||
CONFIG_INPUT_KEYBOARD=y
|
||||
CONFIG_INPUT_LEDS=y
|
||||
# CONFIG_INPUT_MISC is not set
|
||||
CONFIG_INPUT_MOUSE=y
|
||||
CONFIG_INPUT_MOUSEDEV=y
|
||||
CONFIG_INPUT_MOUSEDEV_PSAUX=y
|
||||
CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
|
||||
CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
|
||||
CONFIG_INPUT_SPARSEKMAP=y
|
||||
# CONFIG_IOMMUFD is not set
|
||||
# CONFIG_IOMMU_DEBUGFS is not set
|
||||
CONFIG_IOMMU_SUPPORT=y
|
||||
CONFIG_IO_URING=y
|
||||
CONFIG_IRQCHIP=y
|
||||
CONFIG_IRQ_DOMAIN=y
|
||||
CONFIG_IRQ_DOMAIN_HIERARCHY=y
|
||||
CONFIG_IRQ_FASTEOI_HIERARCHY_HANDLERS=y
|
||||
CONFIG_IRQ_FORCED_THREADING=y
|
||||
CONFIG_IRQ_LOONGARCH_CPU=y
|
||||
CONFIG_IRQ_MSI_LIB=y
|
||||
CONFIG_IRQ_POLL=y
|
||||
CONFIG_IRQ_WORK=y
|
||||
# CONFIG_ISCSI_IBFT is not set
|
||||
CONFIG_ISO9660_FS=y
|
||||
CONFIG_JBD2=y
|
||||
CONFIG_JUMP_LABEL=y
|
||||
CONFIG_KALLSYMS=y
|
||||
CONFIG_KCMP=y
|
||||
CONFIG_KERNEL_GZIP=y
|
||||
CONFIG_KEYS=y
|
||||
CONFIG_KSM=y
|
||||
CONFIG_L1_CACHE_SHIFT=6
|
||||
CONFIG_LEDS_TRIGGER_CPU=y
|
||||
CONFIG_LEDS_TRIGGER_DISK=y
|
||||
CONFIG_LEDS_TRIGGER_MTD=y
|
||||
CONFIG_LEDS_TRIGGER_PANIC=y
|
||||
CONFIG_LEGACY_TIOCSTI=y
|
||||
CONFIG_LIBFDT=y
|
||||
CONFIG_LOCKUP_DETECTOR=y
|
||||
CONFIG_LOCK_DEBUGGING_SUPPORT=y
|
||||
CONFIG_LOCK_SPIN_ON_OWNER=y
|
||||
CONFIG_LOONGARCH=y
|
||||
CONFIG_LOONGARCH_PLATFORM_DEVICES=y
|
||||
# CONFIG_LOONGSON2_GUTS is not set
|
||||
# CONFIG_LOONGSON2_PM is not set
|
||||
# CONFIG_LOONGSON2_THERMAL is not set
|
||||
CONFIG_LOONGSON_EIOINTC=y
|
||||
CONFIG_LOONGSON_HTVEC=y
|
||||
CONFIG_LOONGSON_LAPTOP=y
|
||||
CONFIG_LOONGSON_LIOINTC=y
|
||||
CONFIG_LOONGSON_PCH_LPC=y
|
||||
CONFIG_LOONGSON_PCH_MSI=y
|
||||
CONFIG_LOONGSON_PCH_PIC=y
|
||||
CONFIG_LSM="landlock,lockdown,yama,loadpin,safesetid,integrity,apparmor,selinux,smack,tomoyo,bpf"
|
||||
CONFIG_LZO_COMPRESS=y
|
||||
CONFIG_LZO_DECOMPRESS=y
|
||||
CONFIG_MACH_LOONGSON64=y
|
||||
CONFIG_MAGIC_SYSRQ=y
|
||||
CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0x01b6
|
||||
CONFIG_MAGIC_SYSRQ_SERIAL=y
|
||||
# CONFIG_MEMCG is not set
|
||||
CONFIG_MEMORY=y
|
||||
CONFIG_MEMORY_ISOLATION=y
|
||||
CONFIG_MIGRATION=y
|
||||
CONFIG_MMU_GATHER_MERGE_VMAS=y
|
||||
CONFIG_MMU_LAZY_TLB_REFCOUNT=y
|
||||
CONFIG_MODULES_USE_ELF_RELA=y
|
||||
CONFIG_MODULE_FORCE_LOAD=y
|
||||
CONFIG_MODULE_FORCE_UNLOAD=y
|
||||
# CONFIG_MOUSE_BCM5974 is not set
|
||||
# CONFIG_MOUSE_CYAPA is not set
|
||||
CONFIG_MOUSE_PS2=y
|
||||
CONFIG_MOUSE_PS2_ALPS=y
|
||||
CONFIG_MOUSE_PS2_BYD=y
|
||||
CONFIG_MOUSE_PS2_CYPRESS=y
|
||||
# CONFIG_MOUSE_PS2_ELANTECH is not set
|
||||
CONFIG_MOUSE_PS2_LOGIPS2PP=y
|
||||
CONFIG_MOUSE_PS2_SMBUS=y
|
||||
CONFIG_MOUSE_PS2_SYNAPTICS=y
|
||||
CONFIG_MOUSE_PS2_SYNAPTICS_SMBUS=y
|
||||
# CONFIG_MOUSE_PS2_TOUCHKIT is not set
|
||||
CONFIG_MOUSE_PS2_TRACKPOINT=y
|
||||
# CONFIG_MOUSE_SERIAL is not set
|
||||
# CONFIG_MOUSE_VSXXXAA is not set
|
||||
# CONFIG_MOXA_INTELLIO is not set
|
||||
# CONFIG_MOXA_SMARTIO is not set
|
||||
CONFIG_MPILIB=y
|
||||
CONFIG_MQ_IOSCHED_DEADLINE=y
|
||||
CONFIG_MUTEX_SPIN_ON_OWNER=y
|
||||
CONFIG_NEED_DMA_MAP_STATE=y
|
||||
CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y
|
||||
CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y
|
||||
# CONFIG_NET_CLS_CGROUP is not set
|
||||
CONFIG_NET_DEVMEM=y
|
||||
CONFIG_NET_EGRESS=y
|
||||
CONFIG_NET_FAILOVER=y
|
||||
CONFIG_NET_FLOW_LIMIT=y
|
||||
CONFIG_NET_INGRESS=y
|
||||
CONFIG_NET_PTP_CLASSIFY=y
|
||||
CONFIG_NET_XGRESS=y
|
||||
CONFIG_NLS=y
|
||||
CONFIG_NR_CPUS=64
|
||||
CONFIG_NVMEM=y
|
||||
CONFIG_NVMEM_LAYOUTS=y
|
||||
CONFIG_NVMEM_SYSFS=y
|
||||
CONFIG_NVME_CORE=y
|
||||
CONFIG_NVME_HWMON=y
|
||||
CONFIG_NVME_MULTIPATH=y
|
||||
CONFIG_NVME_VERBOSE_ERRORS=y
|
||||
# CONFIG_N_HDLC is not set
|
||||
CONFIG_OF=y
|
||||
CONFIG_OF_ADDRESS=y
|
||||
CONFIG_OF_EARLY_FLATTREE=y
|
||||
CONFIG_OF_FLATTREE=y
|
||||
CONFIG_OF_GPIO=y
|
||||
CONFIG_OF_IRQ=y
|
||||
CONFIG_OF_KOBJ=y
|
||||
CONFIG_OID_REGISTRY=y
|
||||
CONFIG_PADATA=y
|
||||
CONFIG_PAGE_EXTENSION=y
|
||||
CONFIG_PAGE_POISONING=y
|
||||
CONFIG_PAGE_POOL=y
|
||||
CONFIG_PAGE_POOL_STATS=y
|
||||
CONFIG_PAGE_REPORTING=y
|
||||
CONFIG_PAGE_SHIFT=14
|
||||
CONFIG_PAGE_SIZE_16KB=y
|
||||
CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
|
||||
CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
|
||||
# CONFIG_PANIC_ON_OOPS is not set
|
||||
CONFIG_PANIC_ON_OOPS_VALUE=0
|
||||
CONFIG_PATA_TIMINGS=y
|
||||
CONFIG_PCI=y
|
||||
CONFIG_PCIEAER=y
|
||||
CONFIG_PCIEASPM=y
|
||||
CONFIG_PCIEASPM_DEFAULT=y
|
||||
# CONFIG_PCIEASPM_PERFORMANCE is not set
|
||||
# CONFIG_PCIEASPM_POWERSAVE is not set
|
||||
# CONFIG_PCIEASPM_POWER_SUPERSAVE is not set
|
||||
CONFIG_PCIEPORTBUS=y
|
||||
CONFIG_PCIE_DPC=y
|
||||
# CONFIG_PCIE_EDR is not set
|
||||
CONFIG_PCIE_PME=y
|
||||
CONFIG_PCIE_PTM=y
|
||||
CONFIG_PCI_ATS=y
|
||||
CONFIG_PCI_DOMAINS=y
|
||||
CONFIG_PCI_DOMAINS_GENERIC=y
|
||||
CONFIG_PCI_ECAM=y
|
||||
CONFIG_PCI_IOV=y
|
||||
CONFIG_PCI_LABEL=y
|
||||
CONFIG_PCI_LOONGSON=y
|
||||
CONFIG_PCI_MSI=y
|
||||
CONFIG_PCI_MSI_ARCH_FALLBACKS=y
|
||||
CONFIG_PCI_REALLOC_ENABLE_AUTO=y
|
||||
CONFIG_PERF_USE_VMALLOC=y
|
||||
CONFIG_PGTABLE_3LEVEL=y
|
||||
CONFIG_PGTABLE_HAS_HUGE_LEAVES=y
|
||||
CONFIG_PGTABLE_LEVELS=3
|
||||
CONFIG_PHYS_ADDR_T_64BIT=y
|
||||
CONFIG_PM=y
|
||||
# CONFIG_PMIC_OPREGION is not set
|
||||
CONFIG_PM_ADVANCED_DEBUG=y
|
||||
CONFIG_PM_CLK=y
|
||||
CONFIG_PM_DEBUG=y
|
||||
CONFIG_PM_DEVFREQ=y
|
||||
# CONFIG_PM_DEVFREQ_EVENT is not set
|
||||
CONFIG_PM_OPP=y
|
||||
CONFIG_PM_SLEEP=y
|
||||
CONFIG_PM_SLEEP_DEBUG=y
|
||||
CONFIG_PM_SLEEP_SMP=y
|
||||
CONFIG_PM_STD_PARTITION=""
|
||||
# CONFIG_PM_TEST_SUSPEND is not set
|
||||
CONFIG_PNP=y
|
||||
CONFIG_PNPACPI=y
|
||||
# CONFIG_PNP_DEBUG_MESSAGES is not set
|
||||
CONFIG_POSIX_MQUEUE=y
|
||||
CONFIG_POSIX_MQUEUE_SYSCTL=y
|
||||
CONFIG_POWER_SUPPLY=y
|
||||
CONFIG_POWER_SUPPLY_HWMON=y
|
||||
CONFIG_PPS=y
|
||||
# CONFIG_PREEMPT_NONE is not set
|
||||
CONFIG_PREEMPT_VOLUNTARY=y
|
||||
CONFIG_PREEMPT_VOLUNTARY_BUILD=y
|
||||
CONFIG_PRINTK_TIME=y
|
||||
CONFIG_PROC_CHILDREN=y
|
||||
CONFIG_PROC_EVENTS=y
|
||||
CONFIG_PROC_PAGE_MONITOR=y
|
||||
CONFIG_PROC_PID_CPUSET=y
|
||||
CONFIG_PTP_1588_CLOCK=y
|
||||
CONFIG_PTP_1588_CLOCK_OPTIONAL=y
|
||||
CONFIG_QUEUED_RWLOCKS=y
|
||||
CONFIG_QUEUED_SPINLOCKS=y
|
||||
CONFIG_RANDSTRUCT_NONE=y
|
||||
CONFIG_RAS=y
|
||||
CONFIG_RATIONAL=y
|
||||
# CONFIG_RAVE_SP_CORE is not set
|
||||
CONFIG_REGMAP=y
|
||||
CONFIG_REGMAP_I2C=y
|
||||
CONFIG_REGMAP_MMIO=y
|
||||
CONFIG_REGMAP_SPI=y
|
||||
CONFIG_RELAY=y
|
||||
CONFIG_RELOCATABLE=y
|
||||
CONFIG_RESET_ATTACK_MITIGATION=y
|
||||
CONFIG_RFS_ACCEL=y
|
||||
CONFIG_RPS=y
|
||||
CONFIG_RSEQ=y
|
||||
CONFIG_RTC_CLASS=y
|
||||
CONFIG_RTC_DRV_LOONGSON=y
|
||||
CONFIG_RTC_I2C_AND_SPI=y
|
||||
# CONFIG_RT_GROUP_SCHED is not set
|
||||
CONFIG_RWSEM_SPIN_ON_OWNER=y
|
||||
CONFIG_SATA_AHCI=y
|
||||
CONFIG_SATA_HOST=y
|
||||
# CONFIG_SATA_ZPODD is not set
|
||||
CONFIG_SCHEDSTATS=y
|
||||
CONFIG_SCHED_AUTOGROUP=y
|
||||
# CONFIG_SCHED_CORE is not set
|
||||
CONFIG_SCHED_DEBUG=y
|
||||
CONFIG_SCHED_INFO=y
|
||||
CONFIG_SCHED_MM_CID=y
|
||||
CONFIG_SCHED_SMT=y
|
||||
CONFIG_SCREEN_INFO=y
|
||||
CONFIG_SCSI=y
|
||||
CONFIG_SCSI_COMMON=y
|
||||
CONFIG_SECCOMP=y
|
||||
CONFIG_SECCOMP_FILTER=y
|
||||
CONFIG_SERIAL_8250_EXTENDED=y
|
||||
CONFIG_SERIAL_8250_MANY_PORTS=y
|
||||
CONFIG_SERIAL_8250_NR_UARTS=4
|
||||
CONFIG_SERIAL_8250_PCI=y
|
||||
CONFIG_SERIAL_8250_PCILIB=y
|
||||
CONFIG_SERIAL_8250_PERICOM=y
|
||||
CONFIG_SERIAL_8250_PNP=y
|
||||
CONFIG_SERIAL_8250_RSA=y
|
||||
CONFIG_SERIAL_8250_RUNTIME_UARTS=4
|
||||
CONFIG_SERIAL_8250_SHARE_IRQ=y
|
||||
CONFIG_SERIAL_DEV_BUS=y
|
||||
CONFIG_SERIAL_DEV_CTRL_TTYPORT=y
|
||||
CONFIG_SERIAL_MCTRL_GPIO=y
|
||||
CONFIG_SERIAL_NONSTANDARD=y
|
||||
CONFIG_SERIAL_OF_PLATFORM=y
|
||||
CONFIG_SERIO=y
|
||||
CONFIG_SERIO_I8042=y
|
||||
CONFIG_SERIO_LIBPS2=y
|
||||
CONFIG_SERIO_SERPORT=y
|
||||
CONFIG_SGL_ALLOC=y
|
||||
CONFIG_SG_POOL=y
|
||||
CONFIG_SMP=y
|
||||
CONFIG_SND=y
|
||||
CONFIG_SND_AC97_CODEC=y
|
||||
CONFIG_SND_COMPRESS_OFFLOAD=y
|
||||
CONFIG_SND_CTL_LED=y
|
||||
CONFIG_SND_DYNAMIC_MINORS=y
|
||||
CONFIG_SND_HDA=y
|
||||
# CONFIG_SND_HDA_CODEC_ANALOG is not set
|
||||
# CONFIG_SND_HDA_CODEC_CA0110 is not set
|
||||
# CONFIG_SND_HDA_CODEC_CA0132 is not set
|
||||
# CONFIG_SND_HDA_CODEC_CIRRUS is not set
|
||||
# CONFIG_SND_HDA_CODEC_CMEDIA is not set
|
||||
CONFIG_SND_HDA_CODEC_CONEXANT=y
|
||||
CONFIG_SND_HDA_CODEC_HDMI=y
|
||||
# CONFIG_SND_HDA_CODEC_REALTEK is not set
|
||||
# CONFIG_SND_HDA_CODEC_SI3054 is not set
|
||||
# CONFIG_SND_HDA_CODEC_SIGMATEL is not set
|
||||
# CONFIG_SND_HDA_CODEC_VIA is not set
|
||||
CONFIG_SND_HDA_CORE=y
|
||||
CONFIG_SND_HDA_GENERIC=y
|
||||
CONFIG_SND_HDA_GENERIC_LEDS=y
|
||||
CONFIG_SND_HDA_HWDEP=y
|
||||
# CONFIG_SND_HDA_INPUT_BEEP is not set
|
||||
CONFIG_SND_HDA_INTEL=y
|
||||
# CONFIG_SND_HDA_PATCH_LOADER is not set
|
||||
# CONFIG_SND_HDA_RECONFIG is not set
|
||||
CONFIG_SND_HWDEP=y
|
||||
CONFIG_SND_INTEL_DSP_CONFIG=y
|
||||
CONFIG_SND_INTEL_NHLT=y
|
||||
CONFIG_SND_INTEL_SOUNDWIRE_ACPI=y
|
||||
CONFIG_SND_JACK=y
|
||||
CONFIG_SND_JACK_INPUT_DEV=y
|
||||
CONFIG_SND_MIXER_OSS=y
|
||||
CONFIG_SND_PCM=y
|
||||
CONFIG_SND_PCM_OSS=y
|
||||
CONFIG_SND_PCM_TIMER=y
|
||||
CONFIG_SND_RAWMIDI=y
|
||||
CONFIG_SND_SEQUENCER=y
|
||||
CONFIG_SND_SEQUENCER_OSS=y
|
||||
CONFIG_SND_SEQ_DEVICE=y
|
||||
CONFIG_SND_SEQ_DUMMY=y
|
||||
CONFIG_SND_SEQ_MIDI=y
|
||||
CONFIG_SND_SEQ_MIDI_EVENT=y
|
||||
CONFIG_SND_SEQ_VIRMIDI=y
|
||||
CONFIG_SND_SOC=y
|
||||
CONFIG_SND_SOC_AC97_BUS=y
|
||||
CONFIG_SND_SOC_AC97_CODEC=y
|
||||
CONFIG_SND_SOC_I2C_AND_SPI=y
|
||||
CONFIG_SND_SOC_LOONGSON_CARD=y
|
||||
CONFIG_SND_SOC_LOONGSON_I2S_PCI=y
|
||||
CONFIG_SND_TIMER=y
|
||||
CONFIG_SND_VIRMIDI=y
|
||||
CONFIG_SND_VMASTER=y
|
||||
CONFIG_SOCK_RX_QUEUE_MAPPING=y
|
||||
CONFIG_SOFTLOCKUP_DETECTOR=y
|
||||
CONFIG_SOUND=y
|
||||
CONFIG_SOUND_OSS_CORE=y
|
||||
CONFIG_SOUND_OSS_CORE_PRECLAIM=y
|
||||
CONFIG_SPARSEMEM=y
|
||||
CONFIG_SPARSEMEM_EXTREME=y
|
||||
CONFIG_SPARSEMEM_MANUAL=y
|
||||
CONFIG_SPARSEMEM_VMEMMAP=y
|
||||
CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
|
||||
CONFIG_SPARSE_IRQ=y
|
||||
CONFIG_SPI=y
|
||||
CONFIG_SPI_DYNAMIC=y
|
||||
CONFIG_SPI_LOONGSON_CORE=y
|
||||
CONFIG_SPI_LOONGSON_PCI=y
|
||||
CONFIG_SPI_LOONGSON_PLATFORM=y
|
||||
CONFIG_SPI_MASTER=y
|
||||
CONFIG_SPI_MEM=y
|
||||
CONFIG_SPI_SPIDEV=y
|
||||
CONFIG_SPLIT_PTE_PTLOCKS=y
|
||||
# CONFIG_SQUASHFS_COMPILE_DECOMP_MULTI_PERCPU is not set
|
||||
CONFIG_SQUASHFS_COMPILE_DECOMP_SINGLE=y
|
||||
CONFIG_SQUASHFS_DECOMP_SINGLE=y
|
||||
CONFIG_STACKPROTECTOR=y
|
||||
CONFIG_STACKPROTECTOR_STRONG=y
|
||||
CONFIG_STACKTRACE=y
|
||||
CONFIG_STRICT_DEVMEM=y
|
||||
CONFIG_SUSPEND=y
|
||||
CONFIG_SUSPEND_FREEZER=y
|
||||
CONFIG_SWIOTLB=y
|
||||
CONFIG_SYNC_FILE=y
|
||||
CONFIG_SYSCTL_ARCH_UNALIGN_ALLOW=y
|
||||
CONFIG_SYSCTL_ARCH_UNALIGN_NO_WARN=y
|
||||
CONFIG_SYSCTL_EXCEPTION_TRACE=y
|
||||
CONFIG_SYSFB=y
|
||||
# CONFIG_SYSFB_SIMPLEFB is not set
|
||||
CONFIG_TASKSTATS=y
|
||||
CONFIG_TASK_DELAY_ACCT=y
|
||||
CONFIG_TASK_IO_ACCOUNTING=y
|
||||
CONFIG_TASK_XACCT=y
|
||||
CONFIG_THERMAL=y
|
||||
CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
|
||||
CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0
|
||||
CONFIG_THERMAL_GOV_BANG_BANG=y
|
||||
CONFIG_THERMAL_GOV_FAIR_SHARE=y
|
||||
CONFIG_THERMAL_GOV_STEP_WISE=y
|
||||
CONFIG_THERMAL_GOV_USER_SPACE=y
|
||||
CONFIG_THERMAL_HWMON=y
|
||||
CONFIG_THERMAL_OF=y
|
||||
CONFIG_THERMAL_STATISTICS=y
|
||||
CONFIG_THP_SWAP=y
|
||||
CONFIG_TICK_CPU_ACCOUNTING=y
|
||||
CONFIG_TMPFS_INODE64=y
|
||||
CONFIG_TRANSPARENT_HUGEPAGE=y
|
||||
CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y
|
||||
# CONFIG_TRANSPARENT_HUGEPAGE_MADVISE is not set
|
||||
# CONFIG_TRANSPARENT_HUGEPAGE_NEVER is not set
|
||||
CONFIG_TREE_RCU=y
|
||||
CONFIG_TREE_SRCU=y
|
||||
CONFIG_UCS2_STRING=y
|
||||
# CONFIG_UEVENT_HELPER is not set
|
||||
# CONFIG_UNWINDER_GUESS is not set
|
||||
# CONFIG_UNWINDER_ORC is not set
|
||||
CONFIG_UNWINDER_PROLOGUE=y
|
||||
CONFIG_USB=y
|
||||
CONFIG_USB_COMMON=y
|
||||
CONFIG_USB_EHCI_HCD=y
|
||||
# CONFIG_USB_EHCI_HCD_PLATFORM is not set
|
||||
CONFIG_USB_EHCI_PCI=y
|
||||
CONFIG_USB_HID=y
|
||||
CONFIG_USB_HIDDEV=y
|
||||
# CONFIG_USB_LJCA is not set
|
||||
CONFIG_USB_OHCI_HCD=y
|
||||
CONFIG_USB_OHCI_HCD_PCI=y
|
||||
# CONFIG_USB_OHCI_HCD_PLATFORM is not set
|
||||
CONFIG_USB_PCI=y
|
||||
CONFIG_USB_STORAGE=y
|
||||
CONFIG_USB_SUPPORT=y
|
||||
CONFIG_USB_UAS=y
|
||||
# CONFIG_USB_UHCI_HCD is not set
|
||||
CONFIG_USB_XHCI_HCD=y
|
||||
CONFIG_USB_XHCI_PCI=y
|
||||
# CONFIG_USB_XHCI_PLATFORM is not set
|
||||
CONFIG_USERFAULTFD=y
|
||||
CONFIG_USER_STACKTRACE_SUPPORT=y
|
||||
CONFIG_USE_PERCPU_NUMA_NODE_ID=y
|
||||
CONFIG_VDSO_GETRANDOM=y
|
||||
CONFIG_VGA_ARB=y
|
||||
CONFIG_VGA_ARB_MAX_GPUS=16
|
||||
CONFIG_VIDEO=y
|
||||
CONFIG_VIRTIO_VSOCKETS_COMMON=y
|
||||
CONFIG_VM_EVENT_COUNTERS=y
|
||||
CONFIG_VSOCKETS=y
|
||||
CONFIG_VSOCKETS_LOOPBACK=y
|
||||
CONFIG_VT=y
|
||||
CONFIG_VT_CONSOLE=y
|
||||
CONFIG_VT_CONSOLE_SLEEP=y
|
||||
CONFIG_VT_HW_CONSOLE_BINDING=y
|
||||
CONFIG_XARRAY_MULTI=y
|
||||
CONFIG_XPS=y
|
||||
CONFIG_XXHASH=y
|
||||
# CONFIG_ZONEFS_FS is not set
|
||||
CONFIG_ZONE_DMA32=y
|
@@ -32,7 +32,7 @@ PROJECT_NAME=$(shell basename "${ROOT}")
|
||||
# - pkg/version/current.go
|
||||
#
|
||||
# Use `tools/bump_version.sh` script to change all those files at one shot.
|
||||
VERSION="3.17.1"
|
||||
VERSION="3.18.0"
|
||||
|
||||
# Build binaries and installation packages.
|
||||
.PHONY: build
|
||||
|
@@ -1,5 +1,5 @@
|
||||
Package: mieru
|
||||
Version: 3.17.1
|
||||
Version: 3.18.0
|
||||
Section: net
|
||||
Priority: optional
|
||||
Architecture: amd64
|
||||
|
@@ -1,5 +1,5 @@
|
||||
Name: mieru
|
||||
Version: 3.17.1
|
||||
Version: 3.18.0
|
||||
Release: 1%{?dist}
|
||||
Summary: Mieru proxy client
|
||||
License: GPLv3+
|
||||
|
@@ -1,5 +1,5 @@
|
||||
Package: mieru
|
||||
Version: 3.17.1
|
||||
Version: 3.18.0
|
||||
Section: net
|
||||
Priority: optional
|
||||
Architecture: arm64
|
||||
|
@@ -1,5 +1,5 @@
|
||||
Name: mieru
|
||||
Version: 3.17.1
|
||||
Version: 3.18.0
|
||||
Release: 1%{?dist}
|
||||
Summary: Mieru proxy client
|
||||
License: GPLv3+
|
||||
|
@@ -1,5 +1,5 @@
|
||||
Package: mita
|
||||
Version: 3.17.1
|
||||
Version: 3.18.0
|
||||
Section: net
|
||||
Priority: optional
|
||||
Architecture: amd64
|
||||
|
@@ -1,5 +1,5 @@
|
||||
Name: mita
|
||||
Version: 3.17.1
|
||||
Version: 3.18.0
|
||||
Release: 1%{?dist}
|
||||
Summary: Mieru proxy server
|
||||
License: GPLv3+
|
||||
|
@@ -1,5 +1,5 @@
|
||||
Package: mita
|
||||
Version: 3.17.1
|
||||
Version: 3.18.0
|
||||
Section: net
|
||||
Priority: optional
|
||||
Architecture: arm64
|
||||
|
@@ -1,5 +1,5 @@
|
||||
Name: mita
|
||||
Version: 3.17.1
|
||||
Version: 3.18.0
|
||||
Release: 1%{?dist}
|
||||
Summary: Mieru proxy server
|
||||
License: GPLv3+
|
||||
|
@@ -25,7 +25,8 @@
|
||||
"mtu": 1400,
|
||||
"multiplexing": {
|
||||
"level": "MULTIPLEXING_HIGH"
|
||||
}
|
||||
},
|
||||
"handshakeMode": "HANDSHAKE_NO_WAIT"
|
||||
}
|
||||
],
|
||||
"activeProfile": "default",
|
||||
|
@@ -25,7 +25,8 @@
|
||||
"mtu": 1400,
|
||||
"multiplexing": {
|
||||
"level": "MULTIPLEXING_HIGH"
|
||||
}
|
||||
},
|
||||
"handshakeMode": "HANDSHAKE_NO_WAIT"
|
||||
}
|
||||
],
|
||||
"activeProfile": "default",
|
||||
|
@@ -46,7 +46,8 @@ An example of client configuration is as follows.
|
||||
"mtu": 1400,
|
||||
"multiplexing": {
|
||||
"level": "MULTIPLEXING_HIGH"
|
||||
}
|
||||
},
|
||||
"handshakeMode": "HANDSHAKE_NO_WAIT"
|
||||
}
|
||||
],
|
||||
"activeProfile": "default",
|
||||
@@ -67,11 +68,12 @@ Please use a text editor to modify the following fields.
|
||||
4. [Optional] If you have registered a domain name for the proxy server, please fill in the domain name in `profiles` -> `servers` -> `domainName`. Otherwise, do not modify this property.
|
||||
5. Fill in `profiles` -> `servers` -> `portBindings` -> `port` with the TCP or UDP port number that mita is listening to. The port number must be the same as the one set in the proxy server. If you want to listen to a range of consecutive port numbers, you can also use the `portRange` property instead.
|
||||
6. [Optional] Specify a value between 1280 and 1400 for the `profiles` -> `mtu` property. The default value is 1400. This value must be the same as proxy server.
|
||||
7. [Optional] If you want to adjust the frequency of multiplexing, you can set a value for the `profiles` -> `multiplexing` -> `level` property. The values you can use here include `MULTIPLEXING_OFF`, `MULTIPLEXING_LOW`, `MULTIPLEXING_MIDDLE`, and `MULTIPLEXING_HIGH`. `MULTIPLEXING_OFF` will disable multiplexing, and the default value is `MULTIPLEXING_LOW`.
|
||||
8. Please specify a value between 1025 and 65535 for the `rpcPort` property.
|
||||
9. Please specify a value between 1025 and 65535 for the `socks5Port` property. This port cannot be the same as `rpcPort`.
|
||||
10. [Optional] If the client needs to provide proxy services to other devices on the LAN, set the `socks5ListenLAN` property to `true`.
|
||||
11. [Optional] If you want to enable HTTP / HTTPS proxy, Please specify a value between 1025 and 65535 for the `httpProxyPort` property. This port cannot be the same as `rpcPort` or `socks5Port`. If the client needs to provide HTTP / HTTPS proxy services to other devices on the LAN, set the `httpProxyListenLAN` property to `true`. If you want to disable HTTP / HTTPS proxy, please delete `httpProxyPort` and `httpProxyListenLAN` property.
|
||||
7. [Optional] If you want to adjust the frequency of multiplexing, you can set a value for the `profiles` -> `multiplexing` -> `level` property. The values you can use here include `MULTIPLEXING_OFF`, `MULTIPLEXING_LOW`, `MULTIPLEXING_MIDDLE`, and `MULTIPLEXING_HIGH`. `MULTIPLEXING_OFF` will disable multiplexing. The default value is `MULTIPLEXING_LOW`.
|
||||
8. [Optional] If you want to enable 0-RTT handshake, you can set the value of `profiles` -> `handshakeMode` property to `HANDSHAKE_NO_WAIT`, otherwise set it to `HANDSHAKE_STANDARD`. The default value is `HANDSHAKE_STANDARD`.
|
||||
9. Please specify a value between 1025 and 65535 for the `rpcPort` property.
|
||||
10. Please specify a value between 1025 and 65535 for the `socks5Port` property. This port cannot be the same as `rpcPort`.
|
||||
11. [Optional] If the client needs to provide proxy services to other devices on the LAN, set the `socks5ListenLAN` property to `true`.
|
||||
12. [Optional] If you want to enable HTTP / HTTPS proxy, Please specify a value between 1025 and 65535 for the `httpProxyPort` property. This port cannot be the same as `rpcPort` or `socks5Port`. If the client needs to provide HTTP / HTTPS proxy services to other devices on the LAN, set the `httpProxyListenLAN` property to `true`. If you want to disable HTTP / HTTPS proxy, please delete `httpProxyPort` and `httpProxyListenLAN` property.
|
||||
|
||||
If you have multiple proxy servers installed, or one server listening on multiple ports, you can add them all to the client settings. Each time a new connection is created, mieru will randomly select one of the servers and one of the ports. **If you are using multiple servers, make sure that each server has the mita proxy service started.**
|
||||
|
||||
|
@@ -46,7 +46,8 @@ mieru apply config <FILE>
|
||||
"mtu": 1400,
|
||||
"multiplexing": {
|
||||
"level": "MULTIPLEXING_HIGH"
|
||||
}
|
||||
},
|
||||
"handshakeMode": "HANDSHAKE_NO_WAIT"
|
||||
}
|
||||
],
|
||||
"activeProfile": "default",
|
||||
@@ -68,10 +69,11 @@ mieru apply config <FILE>
|
||||
5. 在 `profiles` -> `servers` -> `portBindings` -> `port` 中填写 mita 监听的 TCP 或 UDP 端口号。这个端口号必须与代理服务器中的设置相同。如果想要监听连续的端口号,也可以改为使用 `portRange` 属性。
|
||||
6. 【可选】请为 `profiles` -> `mtu` 属性中指定一个从 1280 到 1400 之间的值。默认值为 1400。这个值必须与代理服务器相同。
|
||||
7. 【可选】如果想要调整多路复用的频率,是更多地创建新连接,还是更多地重用旧连接,可以为 `profiles` -> `multiplexing` -> `level` 属性设定一个值。这里可以使用的值包括 `MULTIPLEXING_OFF`, `MULTIPLEXING_LOW`, `MULTIPLEXING_MIDDLE`, `MULTIPLEXING_HIGH`。其中 `MULTIPLEXING_OFF` 会关闭多路复用功能。默认值为 `MULTIPLEXING_LOW`。
|
||||
8. 请为 `rpcPort` 属性指定一个从 1025 到 65535 之间的数值。
|
||||
9. 请为 `socks5Port` 属性指定一个从 1025 到 65535 之间的数值。该端口不能与 `rpcPort` 相同。
|
||||
10. 【可选】如果客户端需要为局域网中的其他设备提供代理服务,请将 `socks5ListenLAN` 属性设置为 `true`。
|
||||
11. 【可选】如果要启动 HTTP / HTTPS 代理,请为 `httpProxyPort` 属性指定一个从 1025 到 65535 之间的数值。该端口不能与 `rpcPort` 和 `socks5Port` 相同。如果需要为局域网中的其他设备提供 HTTP / HTTPS 代理,请将 `httpProxyListenLAN` 属性设置为 `true`。如果不需要 HTTP / HTTPS 代理,请删除 `httpProxyPort` 和 `httpProxyListenLAN` 属性。
|
||||
8. 【可选】如果想开启 0-RTT 握手,请将 `profiles` -> `handshakeMode` 属性的值设置为 `HANDSHAKE_NO_WAIT`,否则请设置为 `HANDSHAKE_STANDARD`。默认值为 `HANDSHAKE_STANDARD`。
|
||||
9. 请为 `rpcPort` 属性指定一个从 1025 到 65535 之间的数值。
|
||||
10. 请为 `socks5Port` 属性指定一个从 1025 到 65535 之间的数值。该端口不能与 `rpcPort` 相同。
|
||||
11. 【可选】如果客户端需要为局域网中的其他设备提供代理服务,请将 `socks5ListenLAN` 属性设置为 `true`。
|
||||
12. 【可选】如果要启动 HTTP / HTTPS 代理,请为 `httpProxyPort` 属性指定一个从 1025 到 65535 之间的数值。该端口不能与 `rpcPort` 和 `socks5Port` 相同。如果需要为局域网中的其他设备提供 HTTP / HTTPS 代理,请将 `httpProxyListenLAN` 属性设置为 `true`。如果不需要 HTTP / HTTPS 代理,请删除 `httpProxyPort` 和 `httpProxyListenLAN` 属性。
|
||||
|
||||
如果你安装了多台代理服务器,或者一台服务器监听多个端口,可以把它们都添加到客户端设置中。每次发起新的连接时,mieru 会随机选取其中的一台服务器和一个端口。**如果使用了多台服务器,请确保每一台服务器都启动了 mita 代理服务。**
|
||||
|
||||
|
@@ -18,32 +18,32 @@ Or you can manually install and configure proxy server using the steps below.
|
||||
|
||||
```sh
|
||||
# Debian / Ubuntu - X86_64
|
||||
curl -LSO https://github.com/enfein/mieru/releases/download/v3.17.1/mita_3.17.1_amd64.deb
|
||||
curl -LSO https://github.com/enfein/mieru/releases/download/v3.18.0/mita_3.18.0_amd64.deb
|
||||
|
||||
# Debian / Ubuntu - ARM 64
|
||||
curl -LSO https://github.com/enfein/mieru/releases/download/v3.17.1/mita_3.17.1_arm64.deb
|
||||
curl -LSO https://github.com/enfein/mieru/releases/download/v3.18.0/mita_3.18.0_arm64.deb
|
||||
|
||||
# RedHat / CentOS / Rocky Linux - X86_64
|
||||
curl -LSO https://github.com/enfein/mieru/releases/download/v3.17.1/mita-3.17.1-1.x86_64.rpm
|
||||
curl -LSO https://github.com/enfein/mieru/releases/download/v3.18.0/mita-3.18.0-1.x86_64.rpm
|
||||
|
||||
# RedHat / CentOS / Rocky Linux - ARM 64
|
||||
curl -LSO https://github.com/enfein/mieru/releases/download/v3.17.1/mita-3.17.1-1.aarch64.rpm
|
||||
curl -LSO https://github.com/enfein/mieru/releases/download/v3.18.0/mita-3.18.0-1.aarch64.rpm
|
||||
```
|
||||
|
||||
## Install mita package
|
||||
|
||||
```sh
|
||||
# Debian / Ubuntu - X86_64
|
||||
sudo dpkg -i mita_3.17.1_amd64.deb
|
||||
sudo dpkg -i mita_3.18.0_amd64.deb
|
||||
|
||||
# Debian / Ubuntu - ARM 64
|
||||
sudo dpkg -i mita_3.17.1_arm64.deb
|
||||
sudo dpkg -i mita_3.18.0_arm64.deb
|
||||
|
||||
# RedHat / CentOS / Rocky Linux - X86_64
|
||||
sudo rpm -Uvh --force mita-3.17.1-1.x86_64.rpm
|
||||
sudo rpm -Uvh --force mita-3.18.0-1.x86_64.rpm
|
||||
|
||||
# RedHat / CentOS / Rocky Linux - ARM 64
|
||||
sudo rpm -Uvh --force mita-3.17.1-1.aarch64.rpm
|
||||
sudo rpm -Uvh --force mita-3.18.0-1.aarch64.rpm
|
||||
```
|
||||
|
||||
Those instructions can also be used to upgrade the version of mita software package.
|
||||
@@ -230,7 +230,7 @@ Below is an example to configure a proxy chain.
|
||||
```
|
||||
|
||||
1. In the `egress` -> `proxies` property, list the information of outbound proxy servers. The current version only supports socks5 outbound, so the value of `protocol` must be set to `SOCKS5_PROXY_PROTOCOL`. If the outbound proxy server requires socks5 username and password authentication, please fill in the `socks5Authentication` property. Otherwise, please remove the `socks5Authentication` property.
|
||||
2. In the `egress` -> `rules` property, list outbound rules. Outbound actions include `DIRECT`, `PROXY` and `REJECT`. `proxyNames` must be set if `PROXY` action is used. `proxyNames` needs to point to proxies that exist in `egress` -> `proxies` property.
|
||||
2. In the `egress` -> `rules` property, list outbound rules. From begin to end, the first rule that matches IP address range or DNS suffix is executed. Use wildcard `"*"` to match all IP addresses or domain names. Outbound actions include `DIRECT`, `PROXY` and `REJECT`. `proxyNames` must be set if `PROXY` action is used. `proxyNames` needs to point to proxies that exist in `egress` -> `proxies` property. The default outbound action is `DIRECT`.
|
||||
|
||||
If you want to turn off the outbound proxy feature, simply set the `egress` property to an empty value `{}`.
|
||||
|
||||
|
@@ -18,32 +18,32 @@ sudo python3 setup.py --lang=zh
|
||||
|
||||
```sh
|
||||
# Debian / Ubuntu - X86_64
|
||||
curl -LSO https://github.com/enfein/mieru/releases/download/v3.17.1/mita_3.17.1_amd64.deb
|
||||
curl -LSO https://github.com/enfein/mieru/releases/download/v3.18.0/mita_3.18.0_amd64.deb
|
||||
|
||||
# Debian / Ubuntu - ARM 64
|
||||
curl -LSO https://github.com/enfein/mieru/releases/download/v3.17.1/mita_3.17.1_arm64.deb
|
||||
curl -LSO https://github.com/enfein/mieru/releases/download/v3.18.0/mita_3.18.0_arm64.deb
|
||||
|
||||
# RedHat / CentOS / Rocky Linux - X86_64
|
||||
curl -LSO https://github.com/enfein/mieru/releases/download/v3.17.1/mita-3.17.1-1.x86_64.rpm
|
||||
curl -LSO https://github.com/enfein/mieru/releases/download/v3.18.0/mita-3.18.0-1.x86_64.rpm
|
||||
|
||||
# RedHat / CentOS / Rocky Linux - ARM 64
|
||||
curl -LSO https://github.com/enfein/mieru/releases/download/v3.17.1/mita-3.17.1-1.aarch64.rpm
|
||||
curl -LSO https://github.com/enfein/mieru/releases/download/v3.18.0/mita-3.18.0-1.aarch64.rpm
|
||||
```
|
||||
|
||||
## 安装 mita 软件包
|
||||
|
||||
```sh
|
||||
# Debian / Ubuntu - X86_64
|
||||
sudo dpkg -i mita_3.17.1_amd64.deb
|
||||
sudo dpkg -i mita_3.18.0_amd64.deb
|
||||
|
||||
# Debian / Ubuntu - ARM 64
|
||||
sudo dpkg -i mita_3.17.1_arm64.deb
|
||||
sudo dpkg -i mita_3.18.0_arm64.deb
|
||||
|
||||
# RedHat / CentOS / Rocky Linux - X86_64
|
||||
sudo rpm -Uvh --force mita-3.17.1-1.x86_64.rpm
|
||||
sudo rpm -Uvh --force mita-3.18.0-1.x86_64.rpm
|
||||
|
||||
# RedHat / CentOS / Rocky Linux - ARM 64
|
||||
sudo rpm -Uvh --force mita-3.17.1-1.aarch64.rpm
|
||||
sudo rpm -Uvh --force mita-3.18.0-1.aarch64.rpm
|
||||
```
|
||||
|
||||
上述指令也可以用来升级 mita 软件包的版本。
|
||||
@@ -230,7 +230,7 @@ mieru 客户端 -> GFW -> mita 服务器 -> cloudflare 代理客户端 -> cloudf
|
||||
```
|
||||
|
||||
1. 在 `egress` -> `proxies` 属性中列举出站代理服务器的信息。当前版本只支持 socks5 出站,因此 `protocol` 的值必须设定为 `SOCKS5_PROXY_PROTOCOL`。如果出站代理服务器需要 socks5 用户名和密码验证,请填写 `socks5Authentication` 属性。否则,请删除 `socks5Authentication` 属性。
|
||||
2. 在 `egress` -> `rules` 属性中列举出站规则。出站行为包括 `DIRECT`,`PROXY` 和 `REJECT`。其中 `PROXY` 行为必须指定 `proxyNames`。`proxyNames` 需要指向 `egress` -> `proxies` 属性中存在的代理。
|
||||
2. 在 `egress` -> `rules` 属性中列举出站规则。从上到下,第一条匹配 IP 地址段或 DNS 后缀的规则会被执行。使用通配符 `"*"` 匹配所有 IP 地址或域名。出站行为包括 `DIRECT`,`PROXY` 和 `REJECT`。其中 `PROXY` 行为必须指定 `proxyNames`。`proxyNames` 需要指向 `egress` -> `proxies` 属性中存在的代理。默认的出站行为是 `DIRECT`。
|
||||
|
||||
如果想要关闭出站代理功能,将 `egress` 属性设置为空 `{}` 即可。
|
||||
|
||||
|
@@ -16,5 +16,5 @@
|
||||
package version
|
||||
|
||||
const (
|
||||
AppVersion = "3.17.1"
|
||||
AppVersion = "3.18.0"
|
||||
)
|
||||
|
@@ -461,7 +461,8 @@ class ClientConfig:
|
||||
'servers': [{
|
||||
'ipAddress': '',
|
||||
'portBindings': [{}],
|
||||
}]
|
||||
}],
|
||||
'handshakeMode': 'HANDSHAKE_NO_WAIT'
|
||||
}],
|
||||
'activeProfile': 'default',
|
||||
'rpcPort': 0,
|
||||
|
@@ -456,7 +456,7 @@ func NewVless(option VlessOption) (*Vless, error) {
|
||||
option: &option,
|
||||
}
|
||||
|
||||
if s := strings.Split(option.Encryption, "-mlkem768client-"); len(s) == 2 {
|
||||
if s := strings.SplitN(option.Encryption, "-", 4); len(s) == 4 && s[2] == "mlkem768client" {
|
||||
var minutes uint32
|
||||
if s[0] != "1rtt" {
|
||||
t := strings.TrimSuffix(s[0], "min")
|
||||
@@ -470,14 +470,22 @@ func NewVless(option VlessOption) (*Vless, error) {
|
||||
}
|
||||
minutes = uint32(i)
|
||||
}
|
||||
var xor uint32
|
||||
switch s[1] {
|
||||
case "vless":
|
||||
case "aes128xor":
|
||||
xor = 1
|
||||
default:
|
||||
return nil, fmt.Errorf("invaild vless encryption value: %s", option.Encryption)
|
||||
}
|
||||
var b []byte
|
||||
b, err = base64.RawURLEncoding.DecodeString(s[1])
|
||||
b, err = base64.RawURLEncoding.DecodeString(s[3])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invaild vless encryption value: %s", option.Encryption)
|
||||
}
|
||||
if len(b) == 1184 {
|
||||
if len(b) == encryption.MLKEM768ClientLength {
|
||||
v.encryption = &encryption.ClientInstance{}
|
||||
if err = v.encryption.Init(b, time.Duration(minutes)*time.Minute); err != nil {
|
||||
if err = v.encryption.Init(b, xor, time.Duration(minutes)*time.Minute); err != nil {
|
||||
return nil, fmt.Errorf("failed to use mlkem768seed: %w", err)
|
||||
}
|
||||
} else {
|
||||
|
@@ -221,6 +221,9 @@ func ConvertsV2Ray(buf []byte) ([]map[string]any, error) {
|
||||
if flow := query.Get("flow"); flow != "" {
|
||||
vless["flow"] = strings.ToLower(flow)
|
||||
}
|
||||
if encryption := query.Get("encryption"); encryption != "" {
|
||||
vless["encryption"] = encryption
|
||||
}
|
||||
proxies = append(proxies, vless)
|
||||
|
||||
case "vmess":
|
||||
|
@@ -46,16 +46,16 @@ func Main(args []string) {
|
||||
}
|
||||
fmt.Println("Config:", configBase64)
|
||||
fmt.Println("Key:", keyPem)
|
||||
case "vless-mlkem768-keypair":
|
||||
case "vless-mlkem768":
|
||||
var seed string
|
||||
if len(args) > 1 {
|
||||
seed = args[1]
|
||||
}
|
||||
seedBase64, pubBase64, err := encryption.GenMLKEM768(seed)
|
||||
seedBase64, clientBase64, err := encryption.GenMLKEM768(seed)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Println("Seed: " + seedBase64)
|
||||
fmt.Println("Client: " + pubBase64)
|
||||
fmt.Println("Client: " + clientBase64)
|
||||
}
|
||||
}
|
||||
|
@@ -170,7 +170,7 @@ type realityVerifier struct {
|
||||
//var pOffset = utils.MustOK(reflect.TypeOf((*utls.Conn)(nil)).Elem().FieldByName("peerCertificates")).Offset
|
||||
|
||||
func (c *realityVerifier) VerifyPeerCertificate(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error {
|
||||
//log.Debugln("REALITY localAddr: %v\t is using X25519MLKEM768 for TLS' communication: %v", c.RemoteAddr(), c.HandshakeState.ServerHello.SelectedGroup == utls.X25519MLKEM768)
|
||||
log.Debugln("REALITY localAddr: %v is using X25519MLKEM768 for TLS' communication: %v", c.RemoteAddr(), c.HandshakeState.ServerHello.ServerShare.Group == utls.X25519MLKEM768)
|
||||
//p, _ := reflect.TypeOf(c.Conn).Elem().FieldByName("peerCertificates")
|
||||
//certs := *(*[]*x509.Certificate)(unsafe.Add(unsafe.Pointer(c.Conn), pOffset))
|
||||
certs := c.Conn.PeerCertificates()
|
||||
|
@@ -1,3 +1,12 @@
|
||||
// Package wildcard modified IGLOU-EU/go-wildcard to support:
|
||||
//
|
||||
// `*` matches zero or more characters
|
||||
// `?` matches exactly one character
|
||||
//
|
||||
// The original go-wildcard library used `.` to match exactly one character, and `?` to match zero or one character.
|
||||
// `.` is a valid delimiter in domain name matching and should not be used as a wildcard.
|
||||
// The `?` matching logic strictly matches only one character in most scenarios.
|
||||
// So, the `?` matching logic in the original go-wildcard library has been removed and its wildcard `.` has been replaced with `?`.
|
||||
package wildcard
|
||||
|
||||
// copy and modified from https://github.com/IGLOU-EU/go-wildcard/tree/ce22b7af48e487517a492d3727d9386492043e21
|
||||
@@ -16,12 +25,10 @@ func Match(pattern, s string) bool {
|
||||
}
|
||||
|
||||
func matchByString(pattern, s string) bool {
|
||||
var lastErotemeCluster byte
|
||||
var patternIndex, sIndex, lastStar, lastEroteme int
|
||||
var patternIndex, sIndex, lastStar int
|
||||
patternLen := len(pattern)
|
||||
sLen := len(s)
|
||||
star := -1
|
||||
eroteme := -1
|
||||
|
||||
Loop:
|
||||
if sIndex >= sLen {
|
||||
@@ -38,14 +45,8 @@ Loop:
|
||||
return false
|
||||
}
|
||||
switch pattern[patternIndex] {
|
||||
// Removed dot matching as it conflicts with dot in domains.
|
||||
// case '.':
|
||||
// It matches any single character. So, we don't need to check anything.
|
||||
case '?':
|
||||
// '?' matches one character. Store its position and match exactly one character in the string.
|
||||
eroteme = patternIndex
|
||||
lastEroteme = sIndex
|
||||
lastErotemeCluster = byte(s[sIndex])
|
||||
// It matches any single character. So, we don't need to check anything.
|
||||
case '*':
|
||||
// '*' matches zero or more characters. Store its position and increment the pattern index.
|
||||
star = patternIndex
|
||||
@@ -53,15 +54,8 @@ Loop:
|
||||
patternIndex++
|
||||
goto Loop
|
||||
default:
|
||||
// If the characters don't match, check if there was a previous '?' or '*' to backtrack.
|
||||
// If the characters don't match, check if there was a previous '*' to backtrack.
|
||||
if pattern[patternIndex] != s[sIndex] {
|
||||
if eroteme != -1 {
|
||||
patternIndex = eroteme + 1
|
||||
sIndex = lastEroteme
|
||||
eroteme = -1
|
||||
goto Loop
|
||||
}
|
||||
|
||||
if star != -1 {
|
||||
patternIndex = star + 1
|
||||
lastStar++
|
||||
@@ -71,29 +65,18 @@ Loop:
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// If the characters match, check if it was not the same to validate the eroteme.
|
||||
if eroteme != -1 && lastErotemeCluster != byte(s[sIndex]) {
|
||||
eroteme = -1
|
||||
}
|
||||
}
|
||||
|
||||
patternIndex++
|
||||
sIndex++
|
||||
goto Loop
|
||||
|
||||
// Check if the remaining pattern characters are '*' or '?', which can match the end of the string.
|
||||
// Check if the remaining pattern characters are '*', which can match the end of the string.
|
||||
checkPattern:
|
||||
if patternIndex < patternLen {
|
||||
if pattern[patternIndex] == '*' {
|
||||
patternIndex++
|
||||
goto checkPattern
|
||||
} else if pattern[patternIndex] == '?' {
|
||||
if sIndex >= sLen {
|
||||
sIndex--
|
||||
}
|
||||
patternIndex++
|
||||
goto checkPattern
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -25,31 +25,17 @@ func TestMatch(t *testing.T) {
|
||||
{"", "", true},
|
||||
{"", "*", true},
|
||||
{"", "**", true},
|
||||
{"", "?", true},
|
||||
{"", "??", true},
|
||||
{"", "?*", true},
|
||||
{"", "*?", true},
|
||||
{"", ".", false},
|
||||
{"", ".?", false},
|
||||
{"", "?.", false},
|
||||
{"", ".*", false},
|
||||
{"", "*.", false},
|
||||
{"", "*.?", false},
|
||||
{"", "?.*", false},
|
||||
{"", "?", false},
|
||||
{"", "?*", false},
|
||||
{"", "*?", false},
|
||||
|
||||
{"a", "", false},
|
||||
{"a", "a", true},
|
||||
{"a", "*", true},
|
||||
{"a", "**", true},
|
||||
{"a", "?", true},
|
||||
{"a", "??", true},
|
||||
{"a", ".", false},
|
||||
{"a", ".?", false},
|
||||
{"a", "?.", false},
|
||||
{"a", ".*", false},
|
||||
{"a", "*.", false},
|
||||
{"a", "*.?", false},
|
||||
{"a", "?.*", false},
|
||||
{"a", "?*", true},
|
||||
{"a", "*?", true},
|
||||
|
||||
{"match the exact string", "match the exact string", true},
|
||||
{"do not match a different string", "this is a different string", false},
|
||||
@@ -68,22 +54,27 @@ func TestMatch(t *testing.T) {
|
||||
|
||||
{"match a string with a ?", "match ? string with a ?", true},
|
||||
{"match a string with a ? at the beginning", "?atch a string with a ? at the beginning", true},
|
||||
{"match a string with two ?", "match a string with two ??", true},
|
||||
{"match a optional char with a ?", "match a optional? char with a ?", true},
|
||||
{"match a optional char with a ?", "match a optional? char with a ?", true},
|
||||
{"do not match a string with extra and a ?", "do not match ? string with extra and a ? like this", false},
|
||||
{"match a string with two ?", "match a ??ring with two ?", true},
|
||||
{"do not match a string with extra ?", "do not match a string with extra ??", false},
|
||||
|
||||
{"do not match a string with a .", "do not match . string with a .", false},
|
||||
{"do not match a string with a . at the beginning", "do not .atch a string with a . at the beginning", false},
|
||||
{"do not match a string with two .", "do not match a ..ring with two .", false},
|
||||
{"do not match a string with extra .", "do not match a string with extra ..", false},
|
||||
{"abc.edf.hjg", "abc.edf.hjg", true},
|
||||
{"abc.edf.hjg", "ab.cedf.hjg", false},
|
||||
{"abc.edf.hjg", "abc.edfh.jg", false},
|
||||
{"abc.edf.hjg", "abc.edf.hjq", false},
|
||||
|
||||
{"A big brown fox jumps over the lazy dog, with all there wildcards friends", ". big?brown fox jumps over * wildcard. friend??", false},
|
||||
{"A big brown fox fails to jump over the lazy dog, with all there wildcards friends", ". big?brown fox jumps over * wildcard. friend??", false},
|
||||
{"abc.edf.hjg", "abc.*.hjg", true},
|
||||
{"abc.edf.hjg", "abc.*.hjq", false},
|
||||
{"abc.edf.hjg", "abc*hjg", true},
|
||||
{"abc.edf.hjg", "abc*hjq", false},
|
||||
{"abc.edf.hjg", "a*g", true},
|
||||
{"abc.edf.hjg", "a*q", false},
|
||||
|
||||
{"domain a.b.c", "domain a.b.c", true},
|
||||
{"domain adb.c", "domain a.b.c", false},
|
||||
{"aaaa", "a*a", true},
|
||||
{"abc.edf.hjg", "ab?.edf.hjg", true},
|
||||
{"abc.edf.hjg", "?b?.edf.hjg", true},
|
||||
{"abc.edf.hjg", "??c.edf.hjg", true},
|
||||
{"abc.edf.hjg", "a??.edf.hjg", true},
|
||||
{"abc.edf.hjg", "ab??.edf.hjg", false},
|
||||
{"abc.edf.hjg", "??.edf.hjg", false},
|
||||
}
|
||||
|
||||
for i, c := range cases {
|
||||
@@ -96,10 +87,106 @@ func TestMatch(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func match(pattern, name string) bool { // https://research.swtch.com/glob
|
||||
px := 0
|
||||
nx := 0
|
||||
nextPx := 0
|
||||
nextNx := 0
|
||||
for px < len(pattern) || nx < len(name) {
|
||||
if px < len(pattern) {
|
||||
c := pattern[px]
|
||||
switch c {
|
||||
default: // ordinary character
|
||||
if nx < len(name) && name[nx] == c {
|
||||
px++
|
||||
nx++
|
||||
continue
|
||||
}
|
||||
case '?': // single-character wildcard
|
||||
if nx < len(name) {
|
||||
px++
|
||||
nx++
|
||||
continue
|
||||
}
|
||||
case '*': // zero-or-more-character wildcard
|
||||
// Try to match at nx.
|
||||
// If that doesn't work out,
|
||||
// restart at nx+1 next.
|
||||
nextPx = px
|
||||
nextNx = nx + 1
|
||||
px++
|
||||
continue
|
||||
}
|
||||
}
|
||||
// Mismatch. Maybe restart.
|
||||
if 0 < nextNx && nextNx <= len(name) {
|
||||
px = nextPx
|
||||
nx = nextNx
|
||||
continue
|
||||
}
|
||||
return false
|
||||
}
|
||||
// Matched all of pattern to all of name. Success.
|
||||
return true
|
||||
}
|
||||
|
||||
func FuzzMatch(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, s string) {
|
||||
if !Match(string(s), string(s)) {
|
||||
t.Fatalf("%s does not match %s", s, s)
|
||||
f.Fuzz(func(t *testing.T, pattern, name string) {
|
||||
result1 := Match(pattern, name)
|
||||
result2 := match(pattern, name)
|
||||
if result1 != result2 {
|
||||
t.Fatalf("Match failed for pattern `%s` and name `%s`", pattern, name)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkMatch(b *testing.B) {
|
||||
cases := []struct {
|
||||
s string
|
||||
pattern string
|
||||
result bool
|
||||
}{
|
||||
{"abc.edf.hjg", "abc.edf.hjg", true},
|
||||
{"abc.edf.hjg", "ab.cedf.hjg", false},
|
||||
{"abc.edf.hjg", "abc.edfh.jg", false},
|
||||
{"abc.edf.hjg", "abc.edf.hjq", false},
|
||||
|
||||
{"abc.edf.hjg", "abc.*.hjg", true},
|
||||
{"abc.edf.hjg", "abc.*.hjq", false},
|
||||
{"abc.edf.hjg", "abc*hjg", true},
|
||||
{"abc.edf.hjg", "abc*hjq", false},
|
||||
{"abc.edf.hjg", "a*g", true},
|
||||
{"abc.edf.hjg", "a*q", false},
|
||||
|
||||
{"abc.edf.hjg", "ab?.edf.hjg", true},
|
||||
{"abc.edf.hjg", "?b?.edf.hjg", true},
|
||||
{"abc.edf.hjg", "??c.edf.hjg", true},
|
||||
{"abc.edf.hjg", "a??.edf.hjg", true},
|
||||
{"abc.edf.hjg", "ab??.edf.hjg", false},
|
||||
{"abc.edf.hjg", "??.edf.hjg", false},
|
||||
|
||||
{"r4.cdn-aa-wow-this-is-long-a1.video-yajusenpai1145141919810-oh-hell-yeah-this-is-also-very-long-and-sukka-the-fox-has-a-very-big-fluffy-fox-tail-ao-wu-ao-wu-regex-and-wildcard-both-might-have-deadly-back-tracing-issue-be-careful-or-use-linear-matching.com", "*.cdn-*-*.video**.com", true},
|
||||
}
|
||||
|
||||
b.Run("Match", func(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
for _, c := range cases {
|
||||
result := Match(c.pattern, c.s)
|
||||
if c.result != result {
|
||||
b.Errorf("Test %d: Expected `%v`, found `%v`; With Pattern: `%s` and String: `%s`", i+1, c.result, result, c.pattern, c.s)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
b.Run("match", func(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
for _, c := range cases {
|
||||
result := match(c.pattern, c.s)
|
||||
if c.result != result {
|
||||
b.Errorf("Test %d: Expected `%v`, found `%v`; With Pattern: `%s` and String: `%s`", i+1, c.result, result, c.pattern, c.s)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@@ -638,7 +638,8 @@ proxies: # socks5
|
||||
port: 443
|
||||
uuid: uuid
|
||||
network: tcp
|
||||
encryption: "8min-mlkem768client-bas64RawURLEncoding" # 复用八分钟后协商新的 sharedKey,需小于服务端的值
|
||||
encryption: "8min-vless-mlkem768client-bas64RawURLEncoding" # 复用八分钟后协商新的 sharedKey,需小于服务端的值
|
||||
# encryption: "8min-aes128xor-mlkem768client-bas64RawURLEncoding"
|
||||
tls: false #可以不开启tls
|
||||
udp: true
|
||||
|
||||
@@ -1346,7 +1347,8 @@ listeners:
|
||||
flow: xtls-rprx-vision
|
||||
# ws-path: "/" # 如果不为空则开启 websocket 传输层
|
||||
# grpc-service-name: "GunService" # 如果不为空则开启 grpc 传输层
|
||||
# decryption: "10min-mlkem768seed-bas64RawURLEncoding" # 同时允许 1-RTT 模式与十分钟复用的 0-RTT 模式, 后面base64字符串可由可由 mihomo generate vless-mlkem768 命令生成
|
||||
# decryption: "10min-vless-mlkem768seed-bas64RawURLEncoding" # 同时允许 1-RTT 模式与十分钟复用的 0-RTT 模式, 后面base64字符串可由可由 mihomo generate vless-mlkem768 命令生成
|
||||
# decryption: "10min-aes128xor-mlkem768seed-bas64RawURLEncoding"
|
||||
# 下面两项如果填写则开启 tls(需要同时填写)
|
||||
# certificate: ./server.crt
|
||||
# private-key: ./server.key
|
||||
|
@@ -35,7 +35,7 @@ require (
|
||||
github.com/metacubex/sing-wireguard v0.0.0-20250503063753-2dc62acc626f
|
||||
github.com/metacubex/smux v0.0.0-20250503055512-501391591dee
|
||||
github.com/metacubex/tfo-go v0.0.0-20250516165257-e29c16ae41d4
|
||||
github.com/metacubex/utls v1.8.1-0.20250810142204-d0e55ab2e852
|
||||
github.com/metacubex/utls v1.8.1-0.20250811145843-49b4f106169a
|
||||
github.com/metacubex/wireguard-go v0.0.0-20240922131502-c182e7471181
|
||||
github.com/miekg/dns v1.1.63 // lastest version compatible with golang1.20
|
||||
github.com/mroth/weightedrand/v2 v2.1.0
|
||||
|
@@ -139,10 +139,8 @@ github.com/metacubex/smux v0.0.0-20250503055512-501391591dee h1:lp6hJ+4wCLZu113a
|
||||
github.com/metacubex/smux v0.0.0-20250503055512-501391591dee/go.mod h1:4bPD8HWx9jPJ9aE4uadgyN7D1/Wz3KmPy+vale8sKLE=
|
||||
github.com/metacubex/tfo-go v0.0.0-20250516165257-e29c16ae41d4 h1:j1VRTiC9JLR4nUbSikx9OGdu/3AgFDqgcLj4GoqyQkc=
|
||||
github.com/metacubex/tfo-go v0.0.0-20250516165257-e29c16ae41d4/go.mod h1:l9oLnLoEXyGZ5RVLsh7QCC5XsouTUyKk4F2nLm2DHLw=
|
||||
github.com/metacubex/utls v1.8.0 h1:mSYi6FMnmc5riARl5UZDmWVy710z+P5b7xuGW0lV9ac=
|
||||
github.com/metacubex/utls v1.8.0/go.mod h1:FdjYzVfCtgtna19hX0ER1Xsa5uJInwdQ4IcaaI98lEQ=
|
||||
github.com/metacubex/utls v1.8.1-0.20250810142204-d0e55ab2e852 h1:MLHUGmASNH7/AeoGmSrVM2RutRZAqIDSbQWBp0P7ItE=
|
||||
github.com/metacubex/utls v1.8.1-0.20250810142204-d0e55ab2e852/go.mod h1:FdjYzVfCtgtna19hX0ER1Xsa5uJInwdQ4IcaaI98lEQ=
|
||||
github.com/metacubex/utls v1.8.1-0.20250811145843-49b4f106169a h1:IIzlVmDoB4+7b0BUcLZaY5+AirhhLFep3PhwkAFMRnQ=
|
||||
github.com/metacubex/utls v1.8.1-0.20250811145843-49b4f106169a/go.mod h1:FdjYzVfCtgtna19hX0ER1Xsa5uJInwdQ4IcaaI98lEQ=
|
||||
github.com/metacubex/wireguard-go v0.0.0-20240922131502-c182e7471181 h1:hJLQviGySBuaynlCwf/oYgIxbVbGRUIKZCxdya9YrbQ=
|
||||
github.com/metacubex/wireguard-go v0.0.0-20240922131502-c182e7471181/go.mod h1:phewKljNYiTVT31Gcif8RiCKnTUOgVWFJjccqYM8s+Y=
|
||||
github.com/miekg/dns v1.1.63 h1:8M5aAw6OMZfFXTT7K5V0Eu5YiiL8l7nUAkyN6C9YwaY=
|
||||
|
@@ -89,18 +89,29 @@ func TestInboundVless_TLS(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestInboundVless_Encryption(t *testing.T) {
|
||||
seedBase64, pubBase64, err := encryption.GenMLKEM768("")
|
||||
seedBase64, clientBase64, err := encryption.GenMLKEM768("")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
return
|
||||
}
|
||||
t.Run("-vless-", func(t *testing.T) {
|
||||
inboundOptions := inbound.VlessOption{
|
||||
Decryption: "10min-mlkem768seed-" + seedBase64,
|
||||
Decryption: "10min-vless-mlkem768seed-" + seedBase64,
|
||||
}
|
||||
outboundOptions := outbound.VlessOption{
|
||||
Encryption: "8min-mlkem768client-" + pubBase64,
|
||||
Encryption: "8min-vless-mlkem768client-" + clientBase64,
|
||||
}
|
||||
testInboundVless(t, inboundOptions, outboundOptions)
|
||||
})
|
||||
t.Run("-aes128xor-", func(t *testing.T) {
|
||||
inboundOptions := inbound.VlessOption{
|
||||
Decryption: "10min-aes128xor-mlkem768seed-" + seedBase64,
|
||||
}
|
||||
outboundOptions := outbound.VlessOption{
|
||||
Encryption: "8min-aes128xor-mlkem768client-" + clientBase64,
|
||||
}
|
||||
testInboundVless(t, inboundOptions, outboundOptions)
|
||||
})
|
||||
}
|
||||
|
||||
func TestInboundVless_Wss1(t *testing.T) {
|
||||
|
@@ -88,7 +88,7 @@ func New(config LC.VlessServer, tunnel C.Tunnel, additions ...inbound.Addition)
|
||||
|
||||
sl = &Listener{config: config, service: service}
|
||||
|
||||
if s := strings.Split(config.Decryption, "-mlkem768seed-"); len(s) == 2 {
|
||||
if s := strings.SplitN(config.Decryption, "-", 4); len(s) == 4 && s[2] == "mlkem768seed" {
|
||||
var minutes uint32
|
||||
if s[0] != "1rtt" {
|
||||
t := strings.TrimSuffix(s[0], "min")
|
||||
@@ -102,14 +102,22 @@ func New(config LC.VlessServer, tunnel C.Tunnel, additions ...inbound.Addition)
|
||||
}
|
||||
minutes = uint32(i)
|
||||
}
|
||||
var xor uint32
|
||||
switch s[1] {
|
||||
case "vless":
|
||||
case "aes128xor":
|
||||
xor = 1
|
||||
default:
|
||||
return nil, fmt.Errorf("invaild vless decryption value: %s", config.Decryption)
|
||||
}
|
||||
var b []byte
|
||||
b, err = base64.RawURLEncoding.DecodeString(s[1])
|
||||
b, err = base64.RawURLEncoding.DecodeString(s[3])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invaild vless decryption value: %s", config.Decryption)
|
||||
}
|
||||
if len(b) == 64 {
|
||||
if len(b) == encryption.MLKEM768SeedLength {
|
||||
sl.decryption = &encryption.ServerInstance{}
|
||||
if err = sl.decryption.Init(b, time.Duration(minutes)*time.Minute); err != nil {
|
||||
if err = sl.decryption.Init(b, xor, time.Duration(minutes)*time.Minute); err != nil {
|
||||
return nil, fmt.Errorf("failed to use mlkem768seed: %w", err)
|
||||
}
|
||||
} else {
|
||||
|
@@ -38,17 +38,18 @@ func init() {
|
||||
type ClientInstance struct {
|
||||
sync.RWMutex
|
||||
eKeyNfs *mlkem.EncapsulationKey768
|
||||
xor uint32
|
||||
minutes time.Duration
|
||||
expire time.Time
|
||||
baseKey []byte
|
||||
reuse []byte
|
||||
ticket []byte
|
||||
}
|
||||
|
||||
type ClientConn struct {
|
||||
net.Conn
|
||||
instance *ClientInstance
|
||||
baseKey []byte
|
||||
reuse []byte
|
||||
ticket []byte
|
||||
random []byte
|
||||
aead cipher.AEAD
|
||||
nonce []byte
|
||||
@@ -57,8 +58,9 @@ type ClientConn struct {
|
||||
peerCache []byte
|
||||
}
|
||||
|
||||
func (i *ClientInstance) Init(eKeyNfsData []byte, minutes time.Duration) (err error) {
|
||||
func (i *ClientInstance) Init(eKeyNfsData []byte, xor uint32, minutes time.Duration) (err error) {
|
||||
i.eKeyNfs, err = mlkem.NewEncapsulationKey768(eKeyNfsData)
|
||||
i.xor = xor
|
||||
i.minutes = minutes
|
||||
return
|
||||
}
|
||||
@@ -67,6 +69,9 @@ func (i *ClientInstance) Handshake(conn net.Conn) (net.Conn, error) {
|
||||
if i.eKeyNfs == nil {
|
||||
return nil, errors.New("uninitialized")
|
||||
}
|
||||
if i.xor == 1 {
|
||||
conn = NewXorConn(conn, i.eKeyNfs.Bytes())
|
||||
}
|
||||
c := &ClientConn{Conn: conn}
|
||||
|
||||
if i.minutes > 0 {
|
||||
@@ -74,7 +79,7 @@ func (i *ClientInstance) Handshake(conn net.Conn) (net.Conn, error) {
|
||||
if time.Now().Before(i.expire) {
|
||||
c.instance = i
|
||||
c.baseKey = i.baseKey
|
||||
c.reuse = i.reuse
|
||||
c.ticket = i.ticket
|
||||
i.RUnlock()
|
||||
return c, nil
|
||||
}
|
||||
@@ -104,7 +109,7 @@ func (i *ClientInstance) Handshake(conn net.Conn) (net.Conn, error) {
|
||||
return nil, err
|
||||
}
|
||||
encapsulatedPfsKey := peerServerHello[:1088]
|
||||
c.reuse = peerServerHello[1088:]
|
||||
c.ticket = peerServerHello[1088:]
|
||||
|
||||
pfsKey, err := dKeyPfs.Decapsulate(encapsulatedPfsKey)
|
||||
if err != nil {
|
||||
@@ -115,7 +120,7 @@ func (i *ClientInstance) Handshake(conn net.Conn) (net.Conn, error) {
|
||||
authKey := make([]byte, 32)
|
||||
hkdf.New(sha256.New, c.baseKey, encapsulatedNfsKey, eKeyPfs).Read(authKey)
|
||||
nonce := make([]byte, 12)
|
||||
VLESS, _ := newAead(ClientCipher, authKey).Open(nil, nonce, c.reuse, encapsulatedPfsKey)
|
||||
VLESS, _ := newAead(ClientCipher, authKey).Open(nil, nonce, c.ticket, encapsulatedPfsKey)
|
||||
if !bytes.Equal(VLESS, []byte("VLESS")) { // TODO: more message
|
||||
return nil, errors.New("invalid server")
|
||||
}
|
||||
@@ -124,7 +129,7 @@ func (i *ClientInstance) Handshake(conn net.Conn) (net.Conn, error) {
|
||||
i.Lock()
|
||||
i.expire = time.Now().Add(i.minutes)
|
||||
i.baseKey = c.baseKey
|
||||
i.reuse = c.reuse
|
||||
i.ticket = c.ticket
|
||||
i.Unlock()
|
||||
}
|
||||
|
||||
@@ -140,12 +145,12 @@ func (c *ClientConn) Write(b []byte) (int, error) {
|
||||
c.random = make([]byte, 32)
|
||||
rand.Read(c.random)
|
||||
key := make([]byte, 32)
|
||||
hkdf.New(sha256.New, c.baseKey, c.random, c.reuse).Read(key)
|
||||
hkdf.New(sha256.New, c.baseKey, c.random, c.ticket).Read(key)
|
||||
c.aead = newAead(ClientCipher, key)
|
||||
c.nonce = make([]byte, 12)
|
||||
|
||||
data = make([]byte, 21+32+5+len(b)+16)
|
||||
copy(data, c.reuse)
|
||||
copy(data, c.ticket)
|
||||
copy(data[21:], c.random)
|
||||
encodeHeader(data[53:], len(b)+16)
|
||||
c.aead.Seal(data[:58], c.nonce, b, data[53:58])
|
||||
@@ -210,7 +215,7 @@ func (c *ClientConn) Read(b []byte) (int, error) { // after first Write()
|
||||
if err != nil {
|
||||
if c.instance != nil {
|
||||
c.instance.Lock()
|
||||
if bytes.Equal(c.reuse, c.instance.reuse) {
|
||||
if bytes.Equal(c.ticket, c.instance.ticket) {
|
||||
c.instance.expire = time.Now() // expired
|
||||
}
|
||||
c.instance.Unlock()
|
||||
|
@@ -1,3 +1,5 @@
|
||||
// Package encryption copy and modify from xray-core
|
||||
// https://github.com/XTLS/Xray-core/commit/f61c14e9c63dc41a8a09135db3aea337974f3f37
|
||||
// https://github.com/XTLS/Xray-core/commit/3e19bf9233bdd9bafc073a71c65b737cc1ffba5e
|
||||
// https://github.com/XTLS/Xray-core/commit/7ffb555fc8ec51bd1e3e60f26f1d6957984dba80
|
||||
package encryption
|
||||
|
@@ -8,7 +8,10 @@ import (
|
||||
"github.com/metacubex/utls/mlkem"
|
||||
)
|
||||
|
||||
func GenMLKEM768(seedStr string) (seedBase64, pubBase64 string, err error) {
|
||||
const MLKEM768SeedLength = mlkem.SeedSize
|
||||
const MLKEM768ClientLength = mlkem.EncapsulationKeySize768
|
||||
|
||||
func GenMLKEM768(seedStr string) (seedBase64, clientBase64 string, err error) {
|
||||
var seed [64]byte
|
||||
if len(seedStr) > 0 {
|
||||
s, _ := base64.RawURLEncoding.DecodeString(seedStr)
|
||||
@@ -27,6 +30,6 @@ func GenMLKEM768(seedStr string) (seedBase64, pubBase64 string, err error) {
|
||||
key, _ := mlkem.NewDecapsulationKey768(seed[:])
|
||||
pub := key.EncapsulationKey()
|
||||
seedBase64 = base64.RawURLEncoding.EncodeToString(seed[:])
|
||||
pubBase64 = base64.RawURLEncoding.EncodeToString(pub.Bytes())
|
||||
clientBase64 = base64.RawURLEncoding.EncodeToString(pub.Bytes())
|
||||
return
|
||||
}
|
||||
|
@@ -25,6 +25,7 @@ type ServerSession struct {
|
||||
type ServerInstance struct {
|
||||
sync.RWMutex
|
||||
dKeyNfs *mlkem.DecapsulationKey768
|
||||
xor uint32
|
||||
minutes time.Duration
|
||||
sessions map[[21]byte]*ServerSession
|
||||
stop bool
|
||||
@@ -34,7 +35,7 @@ type ServerConn struct {
|
||||
net.Conn
|
||||
cipher byte
|
||||
baseKey []byte
|
||||
reuse []byte
|
||||
ticket []byte
|
||||
peerRandom []byte
|
||||
peerAead cipher.AEAD
|
||||
peerNonce []byte
|
||||
@@ -43,8 +44,9 @@ type ServerConn struct {
|
||||
nonce []byte
|
||||
}
|
||||
|
||||
func (i *ServerInstance) Init(dKeyNfsData []byte, minutes time.Duration) (err error) {
|
||||
func (i *ServerInstance) Init(dKeyNfsData []byte, xor uint32, minutes time.Duration) (err error) {
|
||||
i.dKeyNfs, err = mlkem.NewDecapsulationKey768(dKeyNfsData)
|
||||
i.xor = xor
|
||||
if minutes > 0 {
|
||||
i.minutes = minutes
|
||||
i.sessions = make(map[[21]byte]*ServerSession)
|
||||
@@ -79,22 +81,25 @@ func (i *ServerInstance) Handshake(conn net.Conn) (net.Conn, error) {
|
||||
if i.dKeyNfs == nil {
|
||||
return nil, errors.New("uninitialized")
|
||||
}
|
||||
if i.xor == 1 {
|
||||
conn = NewXorConn(conn, i.dKeyNfs.EncapsulationKey().Bytes())
|
||||
}
|
||||
c := &ServerConn{Conn: conn}
|
||||
|
||||
peerReuseHello := make([]byte, 21+32)
|
||||
if _, err := io.ReadFull(c.Conn, peerReuseHello); err != nil {
|
||||
peerTicketHello := make([]byte, 21+32)
|
||||
if _, err := io.ReadFull(c.Conn, peerTicketHello); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if i.minutes > 0 {
|
||||
i.RLock()
|
||||
s := i.sessions[[21]byte(peerReuseHello)]
|
||||
s := i.sessions[[21]byte(peerTicketHello)]
|
||||
i.RUnlock()
|
||||
if s != nil {
|
||||
if _, replay := s.randoms.LoadOrStore([32]byte(peerReuseHello[21:]), true); !replay {
|
||||
if _, replay := s.randoms.LoadOrStore([32]byte(peerTicketHello[21:]), true); !replay {
|
||||
c.cipher = s.cipher
|
||||
c.baseKey = s.baseKey
|
||||
c.reuse = peerReuseHello[:21]
|
||||
c.peerRandom = peerReuseHello[21:]
|
||||
c.ticket = peerTicketHello[:21]
|
||||
c.peerRandom = peerTicketHello[21:]
|
||||
return c, nil
|
||||
}
|
||||
}
|
||||
@@ -106,11 +111,11 @@ func (i *ServerInstance) Handshake(conn net.Conn) (net.Conn, error) {
|
||||
}
|
||||
if l, _ := decodeHeader(peerHeader); l != 0 {
|
||||
c.Conn.Write(make([]byte, randBetween(100, 1000))) // make client do new handshake
|
||||
return nil, errors.New("invalid reuse")
|
||||
return nil, errors.New("invalid ticket")
|
||||
}
|
||||
|
||||
peerClientHello := make([]byte, 1088+1184+1)
|
||||
copy(peerClientHello, peerReuseHello)
|
||||
copy(peerClientHello, peerTicketHello)
|
||||
copy(peerClientHello[53:], peerHeader)
|
||||
if _, err := io.ReadFull(c.Conn, peerClientHello[58:]); err != nil {
|
||||
return nil, err
|
||||
@@ -136,13 +141,13 @@ func (i *ServerInstance) Handshake(conn net.Conn) (net.Conn, error) {
|
||||
authKey := make([]byte, 32)
|
||||
hkdf.New(sha256.New, c.baseKey, encapsulatedNfsKey, eKeyPfsData).Read(authKey)
|
||||
nonce := make([]byte, 12)
|
||||
c.reuse = newAead(c.cipher, authKey).Seal(nil, nonce, []byte("VLESS"), encapsulatedPfsKey)
|
||||
c.ticket = newAead(c.cipher, authKey).Seal(nil, nonce, []byte("VLESS"), encapsulatedPfsKey)
|
||||
|
||||
padding := randBetween(100, 1000)
|
||||
|
||||
serverHello := make([]byte, 1088+21+5+padding)
|
||||
copy(serverHello, encapsulatedPfsKey)
|
||||
copy(serverHello[1088:], c.reuse)
|
||||
copy(serverHello[1088:], c.ticket)
|
||||
encodeHeader(serverHello[1109:], int(padding))
|
||||
|
||||
if _, err := c.Conn.Write(serverHello); err != nil {
|
||||
@@ -151,7 +156,7 @@ func (i *ServerInstance) Handshake(conn net.Conn) (net.Conn, error) {
|
||||
|
||||
if i.minutes > 0 {
|
||||
i.Lock()
|
||||
i.sessions[[21]byte(c.reuse)] = &ServerSession{
|
||||
i.sessions[[21]byte(c.ticket)] = &ServerSession{
|
||||
expire: time.Now().Add(i.minutes),
|
||||
cipher: c.cipher,
|
||||
baseKey: c.baseKey,
|
||||
@@ -181,12 +186,12 @@ func (c *ServerConn) Read(b []byte) (int, error) {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
peerIndex := make([]byte, 21)
|
||||
copy(peerIndex, peerHeader)
|
||||
if _, err := io.ReadFull(c.Conn, peerIndex[5:]); err != nil {
|
||||
peerTicket := make([]byte, 21)
|
||||
copy(peerTicket, peerHeader)
|
||||
if _, err := io.ReadFull(c.Conn, peerTicket[5:]); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if !bytes.Equal(peerIndex, c.reuse) {
|
||||
if !bytes.Equal(peerTicket, c.ticket) {
|
||||
return 0, errors.New("naughty boy")
|
||||
}
|
||||
c.peerRandom = make([]byte, 32)
|
||||
@@ -195,7 +200,7 @@ func (c *ServerConn) Read(b []byte) (int, error) {
|
||||
}
|
||||
}
|
||||
peerKey := make([]byte, 32)
|
||||
hkdf.New(sha256.New, c.baseKey, c.peerRandom, c.reuse).Read(peerKey)
|
||||
hkdf.New(sha256.New, c.baseKey, c.peerRandom, c.ticket).Read(peerKey)
|
||||
c.peerAead = newAead(c.cipher, peerKey)
|
||||
c.peerNonce = make([]byte, 12)
|
||||
}
|
||||
|
63
mihomo/transport/vless/encryption/xor.go
Normal file
63
mihomo/transport/vless/encryption/xor.go
Normal file
@@ -0,0 +1,63 @@
|
||||
package encryption
|
||||
|
||||
import (
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"crypto/rand"
|
||||
"io"
|
||||
"net"
|
||||
)
|
||||
|
||||
type XorConn struct {
|
||||
net.Conn
|
||||
key []byte
|
||||
ctr cipher.Stream
|
||||
peerCtr cipher.Stream
|
||||
}
|
||||
|
||||
func NewXorConn(conn net.Conn, key []byte) *XorConn {
|
||||
return &XorConn{Conn: conn, key: key[:16]}
|
||||
}
|
||||
|
||||
func (c *XorConn) Write(b []byte) (int, error) {
|
||||
if len(b) == 0 {
|
||||
return 0, nil
|
||||
}
|
||||
var iv []byte
|
||||
if c.ctr == nil {
|
||||
block, _ := aes.NewCipher(c.key)
|
||||
iv = make([]byte, 16)
|
||||
rand.Read(iv)
|
||||
c.ctr = cipher.NewCTR(block, iv)
|
||||
}
|
||||
c.ctr.XORKeyStream(b, b) // caller MUST discard b
|
||||
if iv != nil {
|
||||
b = append(iv, b...)
|
||||
}
|
||||
if _, err := c.Conn.Write(b); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if iv != nil {
|
||||
b = b[16:]
|
||||
}
|
||||
return len(b), nil
|
||||
}
|
||||
|
||||
func (c *XorConn) Read(b []byte) (int, error) {
|
||||
if len(b) == 0 {
|
||||
return 0, nil
|
||||
}
|
||||
if c.peerCtr == nil {
|
||||
peerIv := make([]byte, 16)
|
||||
if _, err := io.ReadFull(c.Conn, peerIv); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
block, _ := aes.NewCipher(c.key)
|
||||
c.peerCtr = cipher.NewCTR(block, peerIv)
|
||||
}
|
||||
n, err := c.Conn.Read(b)
|
||||
if n > 0 {
|
||||
c.peerCtr.XORKeyStream(b[:n], b[:n])
|
||||
}
|
||||
return n, err
|
||||
}
|
@@ -16,7 +16,7 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-amlogic
|
||||
PKG_VERSION:=3.1.265
|
||||
PKG_VERSION:=3.1.266
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_LICENSE:=GPL-2.0 License
|
||||
|
@@ -173,7 +173,7 @@ check_kernel() {
|
||||
latest_version="$(
|
||||
curl -fsSL -m 10 \
|
||||
${kernel_api}/releases/expanded_assets/kernel_${kernel_tag} |
|
||||
grep -oE "${main_line_version}\.[0-9]+.*\.tar\.gz" | sed 's/.tar.gz//' |
|
||||
grep -oE "${main_line_version}\.[0-9]+\.tar\.gz" | sed 's/.tar.gz//' |
|
||||
sort -urV | head -n 1
|
||||
)"
|
||||
[[ -n "${latest_version}" ]] || tolog "02.03 No kernel available, please use another kernel branch." "1"
|
||||
|
@@ -7,7 +7,7 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
LUCI_TITLE:=Argon Theme
|
||||
LUCI_DEPENDS:=+curl +jsonfilter
|
||||
LUCI_DEPENDS:=+wget +jsonfilter
|
||||
PKG_VERSION:=2.4.3
|
||||
PKG_RELEASE:=20250722
|
||||
|
||||
|
@@ -27,7 +27,6 @@
|
||||
local fs = require "nixio.fs"
|
||||
local nutil = require "nixio.util"
|
||||
local json = require "luci.jsonc"
|
||||
local sys = require "luci.sys"
|
||||
local uci = require 'luci.model.uci'.cursor()
|
||||
|
||||
-- Fetch Local Background Media
|
||||
@@ -74,9 +73,9 @@
|
||||
if fs.access("/etc/config/argon") then
|
||||
local online_wallpaper = uci:get_first('argon', 'global', 'online_wallpaper') or (uci:get_first('argon', 'global', 'bing_background') == '1' and 'bing')
|
||||
if (online_wallpaper and online_wallpaper ~= "none") then
|
||||
local picurl = sys.exec("/usr/libexec/argon/online_wallpaper")
|
||||
if (picurl and picurl ~= '') then
|
||||
return picurl, "Image", ""
|
||||
local picurl = util.ubus("luci.argon_wallpaper", "get_url") or {}
|
||||
if (picurl.url and picurl.url ~= '') then
|
||||
return picurl.url, "Image", ""
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@@ -1,105 +0,0 @@
|
||||
#!/bin/sh
|
||||
# author jjm2473
|
||||
|
||||
# the script will be excuted when `argon.@global[0].bing_background == '1'`
|
||||
# defaults to 'bing' to be compatible with old config
|
||||
WEB_PIC_SRC=$(uci -q get argon.@global[0].online_wallpaper || echo 'bing')
|
||||
# For now, the next two variables are used for wallhaven.cc with specified Tag ID
|
||||
# API_KEY if user has an account with wallhaven and want to use their apikey to allow for more images
|
||||
# EXACT_RESO is used for exact resolution by default, if not use 'atleast' instead of 'resolutions'
|
||||
API_KEY=$(uci -q get argon.@global[0].use_api_key)
|
||||
EXACT_RESO=$(uci -q get argon.@global[0].use_exact_resolution || echo '1')
|
||||
CACHE=/var/run/argon_${WEB_PIC_SRC}.url
|
||||
WRLOCK=/var/lock/argon_${WEB_PIC_SRC}.lock
|
||||
|
||||
fetch_pic_url() {
|
||||
case $WEB_PIC_SRC in
|
||||
bing)
|
||||
local picpath=$(curl -fks --max-time 3 \
|
||||
"https://www.bing.com/HPImageArchive.aspx?format=js&n=1" |
|
||||
jsonfilter -qe '@.images[0].url')
|
||||
[ -n "${picpath}" ] && echo "//www.bing.com${picpath}"
|
||||
;;
|
||||
unsplash)
|
||||
if [ -z "$API_KEY" ]; then
|
||||
curl -fks --max-time 3 \
|
||||
"https://source.unsplash.com/1920x1080/daily?wallpapers" |
|
||||
sed -E 's#^.*href="([^?]+)\?.*$#\1?fm=jpg\&fit=crop\&w=1920\&h=1080#'
|
||||
else
|
||||
curl -fks --max-time 3 \
|
||||
"https://api.unsplash.com/photos/random?client_id=${API_KEY}" |
|
||||
jsonfilter -qe '@["urls"]["regular"]'
|
||||
fi
|
||||
;;
|
||||
unsplash_*)
|
||||
local collection_id=${WEB_PIC_SRC#unsplash_}
|
||||
if [ -z "$API_KEY" ]; then
|
||||
curl -fks --max-time 3 \
|
||||
"https://source.unsplash.com/collection/${collection_id}/1920x1080" |
|
||||
sed -E 's#^.*href="([^?]+)\?.*$#\1?fm=jpg\&fit=crop\&w=1920\&h=1080#'
|
||||
else
|
||||
curl -fks --max-time 3 \
|
||||
"https://api.unsplash.com/photos/random?client_id=${API_KEY}&collections=${collection_id}" |
|
||||
jsonfilter -qe '@["urls"]["regular"]'
|
||||
fi
|
||||
;;
|
||||
wallhaven)
|
||||
curl -fks --max-time 3 \
|
||||
"https://wallhaven.cc/api/v1/search?resolutions=1920x1080&sorting=random" |
|
||||
jsonfilter -qe '@.data[0].path'
|
||||
;;
|
||||
wallhaven_*)
|
||||
local tag_id=${WEB_PIC_SRC#wallhaven_}
|
||||
local has_api_key=""
|
||||
[ -n "$API_KEY" ] && has_api_key="apikey=$API_KEY&" || has_api_key=""
|
||||
local use_reso="resolutions"
|
||||
[ "$EXACT_RESO" -eq "1" ] && use_reso='resolutions' || use_reso='atleast'
|
||||
curl -fks --max-time 3 \
|
||||
"https://wallhaven.cc/api/v1/search?${has_api_key}q=id%3A${tag_id}&${use_reso}=1920x1080&sorting=random" |
|
||||
jsonfilter -qe '@.data[0].path'
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
try_update() {
|
||||
local lock="$WRLOCK"
|
||||
exec 200>$lock
|
||||
|
||||
if flock -n 200 >/dev/null 2>&1; then
|
||||
local picurl=$(fetch_pic_url)
|
||||
if [[ "$WEB_PIC_SRC" == wallhave* ]] ; then
|
||||
curl -fks --max-time 3 --url "${picurl}" > /dev/null
|
||||
fi
|
||||
if [ -n "$picurl" ]; then
|
||||
echo "${picurl}" | tee "$CACHE"
|
||||
else
|
||||
if [ -s "$CACHE" ]; then
|
||||
cat "$CACHE"
|
||||
else
|
||||
touch "$CACHE"
|
||||
fi
|
||||
fi
|
||||
flock -u 200 >/dev/null 2>&1
|
||||
elif [ -s "$CACHE" ]; then
|
||||
cat "$CACHE"
|
||||
fi
|
||||
}
|
||||
|
||||
get_url() {
|
||||
if [ -f "$CACHE" ]; then
|
||||
local idle_t=$(($(date '+%s') - $(date -r "$CACHE" '+%s' 2>/dev/null || echo '0')))
|
||||
if [ -s "$CACHE" ]; then
|
||||
if [ $idle_t -le 43200 ]; then
|
||||
cat "$CACHE"
|
||||
return
|
||||
fi
|
||||
else
|
||||
if [ $idle_t -le 120 ]; then
|
||||
return
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
try_update
|
||||
}
|
||||
|
||||
get_url
|
129
openwrt-packages/luci-theme-argon/root/usr/libexec/rpcd/luci.argon_wallpaper
Executable file
129
openwrt-packages/luci-theme-argon/root/usr/libexec/rpcd/luci.argon_wallpaper
Executable file
@@ -0,0 +1,129 @@
|
||||
#!/bin/sh
|
||||
# author jjm2473
|
||||
|
||||
. /lib/functions.sh
|
||||
. /usr/share/libubox/jshn.sh
|
||||
|
||||
# the script will be excuted when `argon.@global[0].bing_background == '1'`
|
||||
# defaults to 'bing' to be compatible with old config
|
||||
WEB_PIC_SRC="$(uci -q get argon.@global[0].online_wallpaper || echo 'bing')"
|
||||
|
||||
# For now, the next two variables are used for wallhaven.cc with specified Tag ID
|
||||
# API_KEY if user has an account with wallhaven and want to use their apikey to allow for more images
|
||||
# EXACT_RESO is used for exact resolution by default, if not use 'atleast' instead of 'resolutions'
|
||||
API_KEY="$(uci -q get argon.@global[0].use_api_key)"
|
||||
EXACT_RESO="$(uci -q get argon.@global[0].use_exact_resolution || echo '1')"
|
||||
|
||||
CACHE="/var/run/argon_${WEB_PIC_SRC}.url"
|
||||
WRLOCK="/var/lock/argon_${WEB_PIC_SRC}.lock"
|
||||
|
||||
fetch_pic_url() {
|
||||
case "$WEB_PIC_SRC" in
|
||||
bing)
|
||||
local picpath="$(wget -T3 -qO- \
|
||||
"https://www.bing.com/HPImageArchive.aspx?format=js&n=1" |
|
||||
jsonfilter -qe '@.images[0].url' |
|
||||
sed 's/1920x1080/UHD/g')"
|
||||
[ -n "${picpath}" ] && echo "//www.bing.com${picpath}"
|
||||
;;
|
||||
unsplash)
|
||||
if [ -z "$API_KEY" ]; then
|
||||
local pic_id="$(wget -T3 --spider \
|
||||
"https://source.unsplash.com/1920x1080/daily?wallpapers" 2>&1 |
|
||||
grep -Eo "photo-\w+-\w+" | head -n1)"
|
||||
[ -n "${pic_id}" ] && echo "https://images.unsplash.com/${pic_id}?fm=jpg&fit=crop&w=1920&h=1080"
|
||||
else
|
||||
wget -T3 -qO- "https://api.unsplash.com/photos/random?client_id=${API_KEY}" |
|
||||
jsonfilter -qe '@["urls"]["regular"]'
|
||||
fi
|
||||
;;
|
||||
unsplash_*)
|
||||
local collection_id="${WEB_PIC_SRC#unsplash_}"
|
||||
if [ -z "$API_KEY" ]; then
|
||||
local pic_id="$(wget -T3 --spider \
|
||||
"https://source.unsplash.com/collection/${collection_id}/1920x1080" 2>&1 |
|
||||
grep -Eo "photo-\w+-\w+" | head -n1)"
|
||||
[ -n "${pic_id}" ] && echo "https://images.unsplash.com/${pic_id}?fm=jpg&fit=crop&w=1920&h=1080"
|
||||
else
|
||||
wget -T3 -qO- \
|
||||
"https://api.unsplash.com/photos/random?client_id=${API_KEY}&collections=${collection_id}" |
|
||||
jsonfilter -qe '@["urls"]["regular"]'
|
||||
fi
|
||||
;;
|
||||
wallhaven)
|
||||
wget -T3 -qO- \
|
||||
"https://wallhaven.cc/api/v1/search?resolutions=1920x1080&sorting=random" |
|
||||
jsonfilter -qe "@.data[0].path"
|
||||
;;
|
||||
wallhaven_*)
|
||||
local tag_id="${WEB_PIC_SRC#wallhaven_}"
|
||||
local use_reso="resolutions"
|
||||
[ "$EXACT_RESO" -eq "1" ] || use_reso="atleast"
|
||||
[ -z "$API_KEY" ] || API_KEY="apikey=$API_KEY&"
|
||||
wget -T3 -qO- \
|
||||
"https://wallhaven.cc/api/v1/search?${API_KEY}q=id%3A${tag_id}&${use_reso}=1920x1080&sorting=random" |
|
||||
jsonfilter -qe '@.data[0].path'
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
try_update() {
|
||||
local lock="$WRLOCK"
|
||||
exec 200>"$lock"
|
||||
|
||||
if flock -n 200 >"/dev/null" 2>&1; then
|
||||
local picurl="$(fetch_pic_url)"
|
||||
if [ -n "$picurl" ]; then
|
||||
echo "$picurl" | tee "$CACHE"
|
||||
else
|
||||
if [ -s "$CACHE" ]; then
|
||||
cat "$CACHE"
|
||||
else
|
||||
touch "$CACHE"
|
||||
fi
|
||||
fi
|
||||
flock -u 200 >"/dev/null" 2>&1
|
||||
elif [ -s "$CACHE" ]; then
|
||||
cat "$CACHE"
|
||||
fi
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
"list")
|
||||
json_init
|
||||
json_add_object "get_url"
|
||||
json_close_object
|
||||
json_dump
|
||||
json_cleanup
|
||||
;;
|
||||
"call")
|
||||
case "$2" in
|
||||
"get_url")
|
||||
read -r input
|
||||
if [ -f "$CACHE" ]; then
|
||||
idle_t="$(($(date '+%s') - $(date -r "$CACHE" '+%s' 2>/dev/null || echo '0')))"
|
||||
if [ -s "$CACHE" ]; then
|
||||
if [ "$idle_t" -le "43200" ]; then
|
||||
json_init
|
||||
json_add_string "url" "$(cat "$CACHE")"
|
||||
json_dump
|
||||
json_cleanup
|
||||
return 0
|
||||
fi
|
||||
else
|
||||
if [ "$idle_t" -le 120 ]; then
|
||||
echo '{ "url": "" }'
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
json_init
|
||||
json_add_string "url" "$(try_update)"
|
||||
json_dump
|
||||
json_cleanup
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
@@ -10,11 +10,11 @@ include $(TOPDIR)/rules.mk
|
||||
PKG_ARCH_quickstart:=$(ARCH)
|
||||
|
||||
PKG_NAME:=quickstart
|
||||
PKG_VERSION:=0.11.1
|
||||
PKG_VERSION:=0.11.2
|
||||
PKG_RELEASE:=1
|
||||
PKG_SOURCE:=$(PKG_NAME)-binary-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=https://github.com/linkease/istore-packages/releases/download/prebuilt/
|
||||
PKG_HASH:=5f59e69dc1a8dc5606e53936cc7a34f6d37c9102cbf378576420ef9fdd7e7d2f
|
||||
PKG_HASH:=b22f430f08fb12739179e4b983133afb84a37be1e702d5b4e9fb30b1e701824d
|
||||
|
||||
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-binary-$(PKG_VERSION)
|
||||
|
||||
|
@@ -475,30 +475,30 @@ if singbox_tags:find("with_utls") then
|
||||
o:value("firefox")
|
||||
o:value("edge")
|
||||
o:value("safari")
|
||||
-- o:value("360")
|
||||
o:value("360")
|
||||
o:value("qq")
|
||||
o:value("ios")
|
||||
-- o:value("android")
|
||||
o:value("android")
|
||||
o:value("random")
|
||||
-- o:value("randomized")
|
||||
o:value("randomized")
|
||||
o.default = "chrome"
|
||||
o:depends({ [_n("tls")] = true, [_n("utls")] = true })
|
||||
o:depends({ [_n("utls")] = true })
|
||||
|
||||
-- [[ REALITY部分 ]] --
|
||||
o = s:option(Flag, _n("reality"), translate("REALITY"))
|
||||
o.default = 0
|
||||
o:depends({ [_n("protocol")] = "vless", [_n("utls")] = true })
|
||||
o:depends({ [_n("protocol")] = "vmess", [_n("utls")] = true })
|
||||
o:depends({ [_n("protocol")] = "shadowsocks", [_n("utls")] = true })
|
||||
o:depends({ [_n("protocol")] = "socks", [_n("utls")] = true })
|
||||
o:depends({ [_n("protocol")] = "trojan", [_n("utls")] = true })
|
||||
o:depends({ [_n("protocol")] = "anytls", [_n("utls")] = true })
|
||||
o:depends({ [_n("protocol")] = "vless", [_n("tls")] = true })
|
||||
o:depends({ [_n("protocol")] = "vmess", [_n("tls")] = true })
|
||||
o:depends({ [_n("protocol")] = "shadowsocks", [_n("tls")] = true })
|
||||
o:depends({ [_n("protocol")] = "socks", [_n("tls")] = true })
|
||||
o:depends({ [_n("protocol")] = "trojan", [_n("tls")] = true })
|
||||
o:depends({ [_n("protocol")] = "anytls", [_n("tls")] = true })
|
||||
|
||||
o = s:option(Value, _n("reality_publicKey"), translate("Public Key"))
|
||||
o:depends({ [_n("utls")] = true, [_n("reality")] = true })
|
||||
o:depends({ [_n("reality")] = true })
|
||||
|
||||
o = s:option(Value, _n("reality_shortId"), translate("Short Id"))
|
||||
o:depends({ [_n("utls")] = true, [_n("reality")] = true })
|
||||
o:depends({ [_n("reality")] = true })
|
||||
end
|
||||
|
||||
o = s:option(ListValue, _n("transport"), translate("Transport"))
|
||||
|
@@ -21,7 +21,7 @@ const (
|
||||
|
||||
func NewClient(addr string, server string, target string, timeout int, key int,
|
||||
tcpmode int, tcpmode_buffersize int, tcpmode_maxwin int, tcpmode_resend_timems int, tcpmode_compress int,
|
||||
tcpmode_stat int, open_sock5 int, maxconn int, sock5_filter *func(addr string) bool) (*Client, error) {
|
||||
tcpmode_stat int, open_sock5 int, maxconn int, sock5_filter *func(addr string) bool, cryptoConfig *CryptoConfig) (*Client, error) {
|
||||
|
||||
var ipaddr *net.UDPAddr
|
||||
var tcpaddr *net.TCPAddr
|
||||
@@ -67,6 +67,7 @@ func NewClient(addr string, server string, target string, timeout int, key int,
|
||||
maxconn: maxconn,
|
||||
pongTime: time.Now(),
|
||||
sock5_filter: sock5_filter,
|
||||
cryptoConfig: cryptoConfig,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -92,6 +93,7 @@ type Client struct {
|
||||
|
||||
open_sock5 int
|
||||
sock5_filter *func(addr string) bool
|
||||
cryptoConfig *CryptoConfig
|
||||
|
||||
ipaddr *net.UDPAddr
|
||||
tcpaddr *net.TCPAddr
|
||||
@@ -214,7 +216,7 @@ func (p *Client) Run() error {
|
||||
|
||||
recv := make(chan *Packet, 10000)
|
||||
p.recvcontrol = make(chan int, 1)
|
||||
go recvICMP(&p.workResultLock, &p.exit, *p.conn, recv)
|
||||
go recvICMP(&p.workResultLock, &p.exit, *p.conn, recv, p.cryptoConfig)
|
||||
|
||||
go func() {
|
||||
defer common.CrashLog()
|
||||
@@ -346,7 +348,7 @@ func (p *Client) AcceptTcpConn(conn *net.TCPConn, targetAddr string) {
|
||||
sendICMP(p.id, p.sequence, *p.conn, p.ipaddrServer, targetAddr, clientConn.id, (uint32)(MyMsg_DATA), mb,
|
||||
SEND_PROTO, RECV_PROTO, p.key,
|
||||
p.tcpmode, p.tcpmode_buffersize, p.tcpmode_maxwin, p.tcpmode_resend_timems, p.tcpmode_compress, p.tcpmode_stat,
|
||||
p.timeout)
|
||||
p.timeout, p.cryptoConfig)
|
||||
p.sendPacket++
|
||||
p.sendPacketSize += (uint64)(len(mb))
|
||||
}
|
||||
@@ -409,7 +411,7 @@ func (p *Client) AcceptTcpConn(conn *net.TCPConn, targetAddr string) {
|
||||
sendICMP(p.id, p.sequence, *p.conn, p.ipaddrServer, targetAddr, clientConn.id, (uint32)(MyMsg_DATA), mb,
|
||||
SEND_PROTO, RECV_PROTO, p.key,
|
||||
p.tcpmode, 0, 0, 0, 0, 0,
|
||||
0)
|
||||
0, p.cryptoConfig)
|
||||
p.sendPacket++
|
||||
p.sendPacketSize += (uint64)(len(mb))
|
||||
}
|
||||
@@ -472,7 +474,7 @@ func (p *Client) AcceptTcpConn(conn *net.TCPConn, targetAddr string) {
|
||||
sendICMP(p.id, p.sequence, *p.conn, p.ipaddrServer, targetAddr, clientConn.id, (uint32)(MyMsg_DATA), mb,
|
||||
SEND_PROTO, RECV_PROTO, p.key,
|
||||
p.tcpmode, 0, 0, 0, 0, 0,
|
||||
0)
|
||||
0, p.cryptoConfig)
|
||||
p.sendPacket++
|
||||
p.sendPacketSize += (uint64)(len(mb))
|
||||
}
|
||||
@@ -550,7 +552,7 @@ func (p *Client) Accept() error {
|
||||
sendICMP(p.id, p.sequence, *p.conn, p.ipaddrServer, p.targetAddr, clientConn.id, (uint32)(MyMsg_DATA), bytes[:n],
|
||||
SEND_PROTO, RECV_PROTO, p.key,
|
||||
p.tcpmode, 0, 0, 0, 0, 0,
|
||||
p.timeout)
|
||||
p.timeout, p.cryptoConfig)
|
||||
|
||||
p.sequence++
|
||||
|
||||
@@ -675,7 +677,7 @@ func (p *Client) ping() {
|
||||
sendICMP(p.id, p.sequence, *p.conn, p.ipaddrServer, "", "", (uint32)(MyMsg_PING), b,
|
||||
SEND_PROTO, RECV_PROTO, p.key,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0)
|
||||
0, p.cryptoConfig)
|
||||
loggo.Info("ping %s %s %d %d %d %d", p.addrServer, now.String(), p.sproto, p.rproto, p.id, p.sequence)
|
||||
p.sequence++
|
||||
if now.Sub(p.pongTime) > time.Second*3 {
|
||||
@@ -775,7 +777,7 @@ func (p *Client) remoteError(uuid string) {
|
||||
sendICMP(p.id, p.sequence, *p.conn, p.ipaddrServer, "", uuid, (uint32)(MyMsg_KICK), []byte{},
|
||||
SEND_PROTO, RECV_PROTO, p.key,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0)
|
||||
0, p.cryptoConfig)
|
||||
}
|
||||
|
||||
func (p *Client) AcceptDirectTcpConn(conn *net.TCPConn, targetAddr string) {
|
||||
|
@@ -78,6 +78,12 @@ Usage:
|
||||
-key 设置的密码,默认0
|
||||
Set password, default 0
|
||||
|
||||
-encrypt 加密模式,支持aes128, aes256, chacha20
|
||||
Encryption mode: aes128, aes256, chacha20
|
||||
|
||||
-encrypt-key 加密密钥,支持base64编码或密码短语
|
||||
Encryption key, supports base64 encoded key or passphrase
|
||||
|
||||
-tcp 设置是否转发tcp,默认0
|
||||
Set the switch to forward tcp, the default is 0
|
||||
|
||||
@@ -128,6 +134,8 @@ func main() {
|
||||
server := flag.String("s", "", "server addr")
|
||||
timeout := flag.Int("timeout", 60, "conn timeout")
|
||||
key := flag.Int("key", 0, "key")
|
||||
encryption := flag.String("encrypt", "", "encryption mode: aes128, aes256, chacha20")
|
||||
encryptionKey := flag.String("encrypt-key", "", "encryption key (base64 or passphrase)")
|
||||
tcpmode := flag.Int("tcp", 0, "tcp mode")
|
||||
tcpmode_buffersize := flag.Int("tcp_bs", 1*1024*1024, "tcp mode buffer size")
|
||||
tcpmode_maxwin := flag.Int("tcp_mw", 20000, "tcp mode max win")
|
||||
@@ -173,6 +181,28 @@ func main() {
|
||||
return
|
||||
}
|
||||
|
||||
// Validate encryption parameters
|
||||
encryptionMode, err := pingtunnel.ParseEncryptionMode(*encryption)
|
||||
if err != nil {
|
||||
fmt.Printf("Invalid encryption mode: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
if encryptionMode != pingtunnel.NoEncryption && *encryptionKey == "" {
|
||||
fmt.Println("Encryption key is required when encryption mode is specified")
|
||||
return
|
||||
}
|
||||
|
||||
// Create crypto configuration
|
||||
var cryptoConfig *pingtunnel.CryptoConfig
|
||||
if encryptionMode != pingtunnel.NoEncryption {
|
||||
cryptoConfig, err = pingtunnel.NewCryptoConfig(encryptionMode, *encryptionKey)
|
||||
if err != nil {
|
||||
fmt.Printf("Failed to create crypto config: %v\n", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
level := loggo.LEVEL_INFO
|
||||
if loggo.NameToLevel(*loglevel) >= 0 {
|
||||
level = loggo.NameToLevel(*loglevel)
|
||||
@@ -188,7 +218,7 @@ func main() {
|
||||
loggo.Info("key %d", *key)
|
||||
|
||||
if *t == "server" {
|
||||
s, err := pingtunnel.NewServer(*key, *maxconn, *max_process_thread, *max_process_buffer, *conntt)
|
||||
s, err := pingtunnel.NewServer(*key, *maxconn, *max_process_thread, *max_process_buffer, *conntt, cryptoConfig)
|
||||
if err != nil {
|
||||
loggo.Error("ERROR: %s", err.Error())
|
||||
return
|
||||
@@ -243,7 +273,7 @@ func main() {
|
||||
|
||||
c, err := pingtunnel.NewClient(*listen, *server, *target, *timeout, *key,
|
||||
*tcpmode, *tcpmode_buffersize, *tcpmode_maxwin, *tcpmode_resend_timems, *tcpmode_compress,
|
||||
*tcpmode_stat, *open_sock5, *maxconn, &filter)
|
||||
*tcpmode_stat, *open_sock5, *maxconn, &filter, cryptoConfig)
|
||||
if err != nil {
|
||||
loggo.Error("ERROR: %s", err.Error())
|
||||
return
|
||||
|
191
pingtunnel/crypto.go
Normal file
191
pingtunnel/crypto.go
Normal file
@@ -0,0 +1,191 @@
|
||||
package pingtunnel
|
||||
|
||||
import (
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"crypto/rand"
|
||||
"crypto/sha256"
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"fmt"
|
||||
"golang.org/x/crypto/chacha20poly1305"
|
||||
"golang.org/x/crypto/pbkdf2"
|
||||
)
|
||||
|
||||
// EncryptionMode represents the encryption mode
|
||||
type EncryptionMode int
|
||||
|
||||
const (
|
||||
NoEncryption EncryptionMode = iota
|
||||
AES128
|
||||
AES256
|
||||
CHACHA20
|
||||
)
|
||||
|
||||
// CryptoConfig holds encryption configuration
|
||||
type CryptoConfig struct {
|
||||
Mode EncryptionMode
|
||||
Key []byte
|
||||
Cipher cipher.AEAD
|
||||
}
|
||||
|
||||
// NewCryptoConfig creates a new crypto configuration
|
||||
func NewCryptoConfig(mode EncryptionMode, keyInput string) (*CryptoConfig, error) {
|
||||
if mode == NoEncryption {
|
||||
return &CryptoConfig{Mode: NoEncryption}, nil
|
||||
}
|
||||
|
||||
var keySize int
|
||||
switch mode {
|
||||
case AES128:
|
||||
keySize = 16 // 128 bits
|
||||
case AES256:
|
||||
keySize = 32 // 256 bits
|
||||
case CHACHA20:
|
||||
keySize = chacha20poly1305.KeySize // 32 bytes
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported encryption mode: %d", mode)
|
||||
}
|
||||
|
||||
key, err := deriveKey(keyInput, keySize)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to derive key: %v", err)
|
||||
}
|
||||
|
||||
// Create AEAD based on mode
|
||||
var aead cipher.AEAD
|
||||
switch mode {
|
||||
case AES128, AES256:
|
||||
// AES-GCM
|
||||
block, err := aes.NewCipher(key)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create AES cipher: %v", err)
|
||||
}
|
||||
gcm, err := cipher.NewGCM(block)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create GCM: %v", err)
|
||||
}
|
||||
aead = gcm
|
||||
case CHACHA20:
|
||||
// ChaCha20-Poly1305
|
||||
cc20, err := chacha20poly1305.New(key)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create ChaCha20-Poly1305: %v", err)
|
||||
}
|
||||
aead = cc20
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported encryption mode: %d", mode)
|
||||
}
|
||||
|
||||
return &CryptoConfig{
|
||||
Mode: mode,
|
||||
Key: key,
|
||||
Cipher: aead,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// deriveKey derives an encryption key from the input string
|
||||
func deriveKey(keyInput string, keySize int) ([]byte, error) {
|
||||
if keyInput == "" {
|
||||
return nil, errors.New("encryption key cannot be empty")
|
||||
}
|
||||
|
||||
// First, try to decode as base64
|
||||
if decoded, err := base64.StdEncoding.DecodeString(keyInput); err == nil {
|
||||
if len(decoded) == keySize {
|
||||
return decoded, nil
|
||||
}
|
||||
}
|
||||
|
||||
// If not valid base64 or wrong size, use PBKDF2 to derive key
|
||||
salt := []byte("pingtunnel-salt") // Fixed salt for deterministic key derivation
|
||||
iterations := 10000 // Standard iteration count
|
||||
return pbkdf2.Key([]byte(keyInput), salt, iterations, keySize, sha256.New), nil
|
||||
}
|
||||
|
||||
// Encrypt encrypts the given data
|
||||
func (c *CryptoConfig) Encrypt(data []byte) ([]byte, error) {
|
||||
if c.Mode == NoEncryption {
|
||||
return data, nil
|
||||
}
|
||||
|
||||
if c.Cipher == nil {
|
||||
return nil, errors.New("cipher not initialized")
|
||||
}
|
||||
|
||||
// Generate a random nonce
|
||||
nonce := make([]byte, c.Cipher.NonceSize())
|
||||
if _, err := rand.Read(nonce); err != nil {
|
||||
return nil, fmt.Errorf("failed to generate nonce: %v", err)
|
||||
}
|
||||
|
||||
// Encrypt the data
|
||||
ciphertext := c.Cipher.Seal(nil, nonce, data, nil)
|
||||
|
||||
// Prepend nonce to ciphertext
|
||||
result := make([]byte, len(nonce)+len(ciphertext))
|
||||
copy(result, nonce)
|
||||
copy(result[len(nonce):], ciphertext)
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// Decrypt decrypts the given data
|
||||
func (c *CryptoConfig) Decrypt(data []byte) ([]byte, error) {
|
||||
if c.Mode == NoEncryption {
|
||||
return data, nil
|
||||
}
|
||||
|
||||
if c.Cipher == nil {
|
||||
return nil, errors.New("cipher not initialized")
|
||||
}
|
||||
|
||||
nonceSize := c.Cipher.NonceSize()
|
||||
if len(data) < nonceSize {
|
||||
return nil, errors.New("ciphertext too short")
|
||||
}
|
||||
|
||||
// Extract nonce and ciphertext
|
||||
nonce := data[:nonceSize]
|
||||
ciphertext := data[nonceSize:]
|
||||
|
||||
// Decrypt the data
|
||||
plaintext, err := c.Cipher.Open(nil, nonce, ciphertext, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("decryption failed: %v", err)
|
||||
}
|
||||
|
||||
return plaintext, nil
|
||||
}
|
||||
|
||||
// String returns a string representation of the encryption mode
|
||||
func (m EncryptionMode) String() string {
|
||||
switch m {
|
||||
case NoEncryption:
|
||||
return "none"
|
||||
case AES128:
|
||||
return "aes128"
|
||||
case AES256:
|
||||
return "aes256"
|
||||
case CHACHA20:
|
||||
return "chacha20"
|
||||
default:
|
||||
return "unknown"
|
||||
}
|
||||
}
|
||||
|
||||
// ParseEncryptionMode parses a string into an EncryptionMode
|
||||
func ParseEncryptionMode(s string) (EncryptionMode, error) {
|
||||
switch s {
|
||||
case "", "none":
|
||||
return NoEncryption, nil
|
||||
case "aes128":
|
||||
return AES128, nil
|
||||
case "aes256":
|
||||
return AES256, nil
|
||||
case "chacha20", "chacha20-poly1305":
|
||||
return CHACHA20, nil
|
||||
default:
|
||||
return NoEncryption, fmt.Errorf("invalid encryption mode: %s", s)
|
||||
}
|
||||
}
|
183
pingtunnel/crypto_test.go
Normal file
183
pingtunnel/crypto_test.go
Normal file
@@ -0,0 +1,183 @@
|
||||
package pingtunnel
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestCryptoConfig_AES128(t *testing.T) {
|
||||
// Test with a base64 encoded key
|
||||
key := "MTIzNDU2Nzg5MDEyMzQ1Ng==" // "1234567890123456" in base64
|
||||
config, err := NewCryptoConfig(AES128, key)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create crypto config: %v", err)
|
||||
}
|
||||
|
||||
testData := []byte("Hello, World! This is a test message for encryption.")
|
||||
|
||||
// Test encryption
|
||||
encrypted, err := config.Encrypt(testData)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to encrypt data: %v", err)
|
||||
}
|
||||
|
||||
// Encrypted data should be different from original
|
||||
if bytes.Equal(testData, encrypted) {
|
||||
t.Fatal("Encrypted data should be different from original")
|
||||
}
|
||||
|
||||
// Test decryption
|
||||
decrypted, err := config.Decrypt(encrypted)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to decrypt data: %v", err)
|
||||
}
|
||||
|
||||
// Decrypted data should match original
|
||||
if !bytes.Equal(testData, decrypted) {
|
||||
t.Fatalf("Decrypted data doesn't match original. Got: %s, Expected: %s", string(decrypted), string(testData))
|
||||
}
|
||||
}
|
||||
|
||||
func TestCryptoConfig_AES256(t *testing.T) {
|
||||
// Test with a passphrase (will be derived using PBKDF2)
|
||||
config, err := NewCryptoConfig(AES256, "my-secret-passphrase")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create crypto config: %v", err)
|
||||
}
|
||||
|
||||
testData := []byte("This is a longer test message to verify AES-256 encryption works correctly with derived keys.")
|
||||
|
||||
// Test encryption
|
||||
encrypted, err := config.Encrypt(testData)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to encrypt data: %v", err)
|
||||
}
|
||||
|
||||
// Test decryption
|
||||
decrypted, err := config.Decrypt(encrypted)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to decrypt data: %v", err)
|
||||
}
|
||||
|
||||
// Decrypted data should match original
|
||||
if !bytes.Equal(testData, decrypted) {
|
||||
t.Fatalf("Decrypted data doesn't match original. Got: %s, Expected: %s", string(decrypted), string(testData))
|
||||
}
|
||||
}
|
||||
|
||||
func TestCryptoConfig_ChaCha20(t *testing.T) {
|
||||
// Test with a passphrase (PBKDF2 to 32 bytes)
|
||||
config, err := NewCryptoConfig(CHACHA20, "another-secret-passphrase")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create crypto config: %v", err)
|
||||
}
|
||||
|
||||
testData := []byte("Testing ChaCha20-Poly1305 AEAD for encryption and decryption correctness.")
|
||||
|
||||
encrypted, err := config.Encrypt(testData)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to encrypt data: %v", err)
|
||||
}
|
||||
|
||||
if bytes.Equal(testData, encrypted) {
|
||||
t.Fatal("Encrypted data should be different from original")
|
||||
}
|
||||
|
||||
decrypted, err := config.Decrypt(encrypted)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to decrypt data: %v", err)
|
||||
}
|
||||
|
||||
if !bytes.Equal(testData, decrypted) {
|
||||
t.Fatalf("Decrypted data doesn't match original. Got: %s, Expected: %s", string(decrypted), string(testData))
|
||||
}
|
||||
}
|
||||
|
||||
func TestCryptoConfig_NoEncryption(t *testing.T) {
|
||||
config, err := NewCryptoConfig(NoEncryption, "")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create crypto config: %v", err)
|
||||
}
|
||||
|
||||
testData := []byte("This should not be encrypted")
|
||||
|
||||
// Test "encryption" (should return original data)
|
||||
encrypted, err := config.Encrypt(testData)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to encrypt data: %v", err)
|
||||
}
|
||||
|
||||
if !bytes.Equal(testData, encrypted) {
|
||||
t.Fatal("No encryption should return original data")
|
||||
}
|
||||
|
||||
// Test "decryption" (should return original data)
|
||||
decrypted, err := config.Decrypt(encrypted)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to decrypt data: %v", err)
|
||||
}
|
||||
|
||||
if !bytes.Equal(testData, decrypted) {
|
||||
t.Fatal("No encryption should return original data")
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseEncryptionMode(t *testing.T) {
|
||||
tests := []struct {
|
||||
input string
|
||||
expected EncryptionMode
|
||||
hasError bool
|
||||
}{
|
||||
{"", NoEncryption, false},
|
||||
{"none", NoEncryption, false},
|
||||
{"aes128", AES128, false},
|
||||
{"aes256", AES256, false},
|
||||
{"chacha20", CHACHA20, false},
|
||||
{"chacha20-poly1305", CHACHA20, false},
|
||||
{"invalid", NoEncryption, true},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
result, err := ParseEncryptionMode(test.input)
|
||||
if test.hasError && err == nil {
|
||||
t.Fatalf("Expected error for input %s, but got none", test.input)
|
||||
}
|
||||
if !test.hasError && err != nil {
|
||||
t.Fatalf("Unexpected error for input %s: %v", test.input, err)
|
||||
}
|
||||
if result != test.expected {
|
||||
t.Fatalf("For input %s, expected %v, got %v", test.input, test.expected, result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestKeyDerivation(t *testing.T) {
|
||||
// Test with valid base64 key
|
||||
validBase64 := "MTIzNDU2Nzg5MDEyMzQ1Ng==" // 16 bytes when decoded
|
||||
key, err := deriveKey(validBase64, 16)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to derive key from valid base64: %v", err)
|
||||
}
|
||||
if len(key) != 16 {
|
||||
t.Fatalf("Expected key length 16, got %d", len(key))
|
||||
}
|
||||
|
||||
// Test with passphrase (should use PBKDF2)
|
||||
passphrase := "my-secret-passphrase"
|
||||
key2, err := deriveKey(passphrase, 32)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to derive key from passphrase: %v", err)
|
||||
}
|
||||
if len(key2) != 32 {
|
||||
t.Fatalf("Expected key length 32, got %d", len(key2))
|
||||
}
|
||||
|
||||
// Same passphrase should produce same key (deterministic)
|
||||
key3, err := deriveKey(passphrase, 32)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to derive key from passphrase (second time): %v", err)
|
||||
}
|
||||
if !bytes.Equal(key2, key3) {
|
||||
t.Fatal("Same passphrase should produce same derived key")
|
||||
}
|
||||
}
|
@@ -5,6 +5,7 @@ go 1.24.1
|
||||
require (
|
||||
github.com/esrrhs/gohome v0.0.0-20250426022937-504d912bccf7
|
||||
github.com/golang/protobuf v1.5.4
|
||||
golang.org/x/crypto v0.37.0
|
||||
golang.org/x/net v0.39.0
|
||||
)
|
||||
|
||||
@@ -27,8 +28,6 @@ require (
|
||||
github.com/xtaci/smux v1.5.34 // indirect
|
||||
go.uber.org/automaxprocs v1.6.0 // indirect
|
||||
go.uber.org/mock v0.5.1 // indirect
|
||||
golang.org/x/crypto v0.37.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0 // indirect
|
||||
golang.org/x/mod v0.24.0 // indirect
|
||||
golang.org/x/sync v0.13.0 // indirect
|
||||
golang.org/x/sys v0.32.0 // indirect
|
||||
|
@@ -14,7 +14,6 @@ github.com/esrrhs/gohome v0.0.0-20250426022937-504d912bccf7 h1:EpgZzfBgtv89nRgnp
|
||||
github.com/esrrhs/gohome v0.0.0-20250426022937-504d912bccf7/go.mod h1:4kAeSdLmMeWMOpzi/Jx82YvDnrBHcbWcLT18FwTujFA=
|
||||
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
|
||||
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
@@ -34,27 +33,20 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/pprof v0.0.0-20241101162523-b92577c0c142 h1:sAGdeJj0bnMgUNVeUpp6AYlVdCt3/GdI3pGRqsNSQLs=
|
||||
github.com/google/pprof v0.0.0-20241101162523-b92577c0c142/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/google/pprof v0.0.0-20250423184734-337e5dd93bb4 h1:gD0vax+4I+mAj+jEChEf25Ia07Jq7kYOFO5PPhAxFl4=
|
||||
github.com/google/pprof v0.0.0-20250423184734-337e5dd93bb4/go.mod h1:5hDyRhoBCxViHszMt12TnOpEI4VVi+U8Gm9iphldiMA=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/klauspost/cpuid/v2 v2.2.9 h1:66ze0taIn2H33fBvCkXuv9BmCwDfafmiIVpKV9kKGuY=
|
||||
github.com/klauspost/cpuid/v2 v2.2.9/go.mod h1:rqkxqrZ1EhYM9G+hXH7YdowN5R5RGN6NK4QwQ3WMXF8=
|
||||
github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE=
|
||||
github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
|
||||
github.com/klauspost/reedsolomon v1.12.4 h1:5aDr3ZGoJbgu/8+j45KtUJxzYm8k08JGtB9Wx1VQ4OA=
|
||||
github.com/klauspost/reedsolomon v1.12.4/go.mod h1:d3CzOMOt0JXGIFZm1StgkyF14EYr3xneR2rNWo7NcMU=
|
||||
github.com/onsi/ginkgo/v2 v2.21.0 h1:7rg/4f3rB88pb5obDgNZrNHrQ4e6WpjonchcpuBRnZM=
|
||||
github.com/onsi/ginkgo/v2 v2.21.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo=
|
||||
github.com/onsi/ginkgo/v2 v2.23.4 h1:ktYTpKJAVZnDT4VjxSbiBenUjmlL/5QkBEocaWXiQus=
|
||||
github.com/onsi/ginkgo/v2 v2.23.4/go.mod h1:Bt66ApGPBFzHyR+JO10Zbt0Gsp4uWxu5mIOTusL46e8=
|
||||
github.com/onsi/gomega v1.34.2 h1:pNCwDkzrsv7MS9kpaQvVb1aVLahQXyJ/Tv5oAZMI3i8=
|
||||
github.com/onsi/gomega v1.34.2/go.mod h1:v1xfxRgk0KIsG+QOdm7p8UosrOzPYRo60fd3B/1Dukc=
|
||||
github.com/onsi/gomega v1.36.3 h1:hID7cr8t3Wp26+cYnfcjR6HpJ00fdogN6dqZ1t6IylU=
|
||||
github.com/onsi/gomega v1.36.3/go.mod h1:8D9+Txp43QWKhM24yyOBEdpkzN8FvJyAwecBgsU4KU0=
|
||||
github.com/oschwald/geoip2-golang v1.11.0 h1:hNENhCn1Uyzhf9PTmquXENiWS6AlxAEnBII6r8krA3w=
|
||||
github.com/oschwald/geoip2-golang v1.11.0/go.mod h1:P9zG+54KPEFOliZ29i7SeYZ/GM6tfEL+rgSn03hYuUo=
|
||||
github.com/oschwald/maxminddb-golang v1.13.1 h1:G3wwjdN9JmIK2o/ermkHM+98oX5fS+k5MbwsmL4MRQE=
|
||||
@@ -63,9 +55,9 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g=
|
||||
github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/quic-go/quic-go v0.48.1 h1:y/8xmfWI9qmGTc+lBr4jKRUWLGSlSigv847ULJ4hYXA=
|
||||
github.com/quic-go/quic-go v0.48.1/go.mod h1:yBgs3rWBOADpga7F+jJsb6Ybg1LSYiQvwWlLX+/6HMs=
|
||||
github.com/quic-go/quic-go v0.51.0 h1:K8exxe9zXxeRKxaXxi/GpUqYiTrtdiWP8bo1KFya6Wc=
|
||||
github.com/quic-go/quic-go v0.51.0/go.mod h1:MFlGGpcpJqRAfmYi6NC2cptDPSxRWTOGNuP4wqrWmzQ=
|
||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||
@@ -80,33 +72,21 @@ github.com/xtaci/kcp-go v5.4.20+incompatible h1:TN1uey3Raw0sTz0Fg8GkfM0uH3YwzhnZ
|
||||
github.com/xtaci/kcp-go v5.4.20+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
|
||||
github.com/xtaci/lossyconn v0.0.0-20200209145036-adba10fffc37 h1:EWU6Pktpas0n8lLQwDsRyZfmkPeRbdgPtW609es+/9E=
|
||||
github.com/xtaci/lossyconn v0.0.0-20200209145036-adba10fffc37/go.mod h1:HpMP7DB2CyokmAh4lp0EQnnWhmycP/TvwBGzvuie+H0=
|
||||
github.com/xtaci/smux v1.5.31 h1:3ha7sHtH46h85Iv7MfQogxasuRt1KPRhoFB3S4rmHgU=
|
||||
github.com/xtaci/smux v1.5.31/go.mod h1:OMlQbT5vcgl2gb49mFkYo6SMf+zP3rcjcwQz7ZU7IGY=
|
||||
github.com/xtaci/smux v1.5.34 h1:OUA9JaDFHJDT8ZT3ebwLWPAgEfE6sWo2LaTy3anXqwg=
|
||||
github.com/xtaci/smux v1.5.34/go.mod h1:OMlQbT5vcgl2gb49mFkYo6SMf+zP3rcjcwQz7ZU7IGY=
|
||||
go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs=
|
||||
go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8=
|
||||
go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU=
|
||||
go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM=
|
||||
go.uber.org/mock v0.5.1 h1:ASgazW/qBmR+A32MYFDB6E2POoTgOwT509VP0CT/fjs=
|
||||
go.uber.org/mock v0.5.1/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34=
|
||||
golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc=
|
||||
golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE=
|
||||
golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f h1:XdNn9LlyWAhLVp6P/i8QYBW+hlyhrhei9uErw2B5GJo=
|
||||
golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f/go.mod h1:D5SMRVC3C2/4+F/DB1wZsLRnSNimn2Sp/NPsCrsv8ak=
|
||||
golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0 h1:R84qjqJb5nVJMxqWYb3np9L5ZsaDtB+a39EqjV0JSUM=
|
||||
golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0/go.mod h1:S9Xr4PYopiDyqSyp5NjCrhFrqg6A5zA2E/iPHPhqnS8=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4=
|
||||
golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
|
||||
golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU=
|
||||
golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
@@ -115,40 +95,29 @@ golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73r
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8=
|
||||
golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
|
||||
golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY=
|
||||
golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ=
|
||||
golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610=
|
||||
golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
|
||||
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20=
|
||||
golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
|
||||
golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
|
||||
golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0=
|
||||
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
|
||||
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||
golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.27.0 h1:qEKojBykQkQ4EynWy4S8Weg69NumxKdn40Fce3uc/8o=
|
||||
golang.org/x/tools v0.27.0/go.mod h1:sUi0ZgbwW9ZPAq26Ekut+weQPR5eIM6GQLQ1Yjm1H0Q=
|
||||
golang.org/x/tools v0.32.0 h1:Q7N1vhpkQv7ybVzLFtTjvQya2ewbwNDZzUgfXGqtMWU=
|
||||
golang.org/x/tools v0.32.0/go.mod h1:ZxrU41P/wAbZD8EDa6dDCa6XfpkhJ7HFMjHJXfBDu8s=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
@@ -166,8 +135,6 @@ google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQ
|
||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA=
|
||||
google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
|
||||
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
|
BIN
pingtunnel/pingtunnel
Executable file
BIN
pingtunnel/pingtunnel
Executable file
Binary file not shown.
@@ -15,7 +15,7 @@ import (
|
||||
func sendICMP(id int, sequence int, conn icmp.PacketConn, server *net.IPAddr, target string,
|
||||
connId string, msgType uint32, data []byte, sproto int, rproto int, key int,
|
||||
tcpmode int, tcpmode_buffer_size int, tcpmode_maxwin int, tcpmode_resend_time int, tcpmode_compress int, tcpmode_stat int,
|
||||
timeout int) {
|
||||
timeout int, cryptoConfig *CryptoConfig) {
|
||||
|
||||
m := &MyMsg{
|
||||
Id: connId,
|
||||
@@ -40,6 +40,15 @@ func sendICMP(id int, sequence int, conn icmp.PacketConn, server *net.IPAddr, ta
|
||||
return
|
||||
}
|
||||
|
||||
// Encrypt the marshaled data if encryption is enabled
|
||||
if cryptoConfig != nil {
|
||||
mb, err = cryptoConfig.Encrypt(mb)
|
||||
if err != nil {
|
||||
loggo.Error("sendICMP Encrypt error %s %s", server.String(), err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
body := &icmp.Echo{
|
||||
ID: id,
|
||||
Seq: sequence,
|
||||
@@ -61,7 +70,7 @@ func sendICMP(id int, sequence int, conn icmp.PacketConn, server *net.IPAddr, ta
|
||||
conn.WriteTo(bytes, server)
|
||||
}
|
||||
|
||||
func recvICMP(workResultLock *sync.WaitGroup, exit *bool, conn icmp.PacketConn, recv chan<- *Packet) {
|
||||
func recvICMP(workResultLock *sync.WaitGroup, exit *bool, conn icmp.PacketConn, recv chan<- *Packet, cryptoConfig *CryptoConfig) {
|
||||
|
||||
defer common.CrashLog()
|
||||
|
||||
@@ -88,8 +97,20 @@ func recvICMP(workResultLock *sync.WaitGroup, exit *bool, conn icmp.PacketConn,
|
||||
echoId := int(binary.BigEndian.Uint16(bytes[4:6]))
|
||||
echoSeq := int(binary.BigEndian.Uint16(bytes[6:8]))
|
||||
|
||||
// Extract the payload data
|
||||
payloadData := bytes[8:n]
|
||||
|
||||
// Decrypt the data if encryption is enabled
|
||||
if cryptoConfig != nil {
|
||||
payloadData, err = cryptoConfig.Decrypt(payloadData)
|
||||
if err != nil {
|
||||
loggo.Debug("recvICMP Decrypt error: %s", err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
my := &MyMsg{}
|
||||
err = proto.Unmarshal(bytes[8:n], my)
|
||||
err = proto.Unmarshal(payloadData, my)
|
||||
if err != nil {
|
||||
loggo.Debug("Unmarshal MyMsg error: %s", err)
|
||||
continue
|
||||
|
@@ -12,7 +12,7 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
func NewServer(key int, maxconn int, maxprocessthread int, maxprocessbuffer int, connecttmeout int) (*Server, error) {
|
||||
func NewServer(key int, maxconn int, maxprocessthread int, maxprocessbuffer int, connecttmeout int, cryptoConfig *CryptoConfig) (*Server, error) {
|
||||
s := &Server{
|
||||
exit: false,
|
||||
key: key,
|
||||
@@ -20,6 +20,7 @@ func NewServer(key int, maxconn int, maxprocessthread int, maxprocessbuffer int,
|
||||
maxprocessthread: maxprocessthread,
|
||||
maxprocessbuffer: maxprocessbuffer,
|
||||
connecttmeout: connecttmeout,
|
||||
cryptoConfig: cryptoConfig,
|
||||
}
|
||||
|
||||
if maxprocessthread > 0 {
|
||||
@@ -40,6 +41,7 @@ type Server struct {
|
||||
maxprocessthread int
|
||||
maxprocessbuffer int
|
||||
connecttmeout int
|
||||
cryptoConfig *CryptoConfig
|
||||
|
||||
conn *icmp.PacketConn
|
||||
|
||||
@@ -85,7 +87,7 @@ func (p *Server) Run() error {
|
||||
|
||||
recv := make(chan *Packet, 10000)
|
||||
p.recvcontrol = make(chan int, 1)
|
||||
go recvICMP(&p.workResultLock, &p.exit, *p.conn, recv)
|
||||
go recvICMP(&p.workResultLock, &p.exit, *p.conn, recv, p.cryptoConfig)
|
||||
|
||||
go func() {
|
||||
defer common.CrashLog()
|
||||
@@ -141,7 +143,7 @@ func (p *Server) processPacket(packet *Packet) {
|
||||
sendICMP(packet.echoId, packet.echoSeq, *p.conn, packet.src, "", "", (uint32)(MyMsg_PING), packet.my.Data,
|
||||
(int)(packet.my.Rproto), -1, p.key,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0)
|
||||
0, p.cryptoConfig)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -297,9 +299,9 @@ func (p *Server) RecvTCP(conn *ServerConn, id string, src *net.IPAddr) {
|
||||
f := e.Value.(*network.Frame)
|
||||
mb, _ := conn.fm.MarshalFrame(f)
|
||||
sendICMP(conn.echoId, conn.echoSeq, *p.conn, src, "", id, (uint32)(MyMsg_DATA), mb,
|
||||
conn.rproto, -1, p.key,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0)
|
||||
conn.rproto, -1, p.key, 0,
|
||||
0, 0, 0, 0, 0,
|
||||
0, p.cryptoConfig)
|
||||
p.sendPacket++
|
||||
p.sendPacketSize += (uint64)(len(mb))
|
||||
}
|
||||
@@ -360,9 +362,9 @@ func (p *Server) RecvTCP(conn *ServerConn, id string, src *net.IPAddr) {
|
||||
continue
|
||||
}
|
||||
sendICMP(conn.echoId, conn.echoSeq, *p.conn, src, "", id, (uint32)(MyMsg_DATA), mb,
|
||||
conn.rproto, -1, p.key,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0)
|
||||
conn.rproto, -1, p.key, 0,
|
||||
0, 0, 0, 0, 0,
|
||||
0, p.cryptoConfig)
|
||||
p.sendPacket++
|
||||
p.sendPacketSize += (uint64)(len(mb))
|
||||
}
|
||||
@@ -422,9 +424,9 @@ func (p *Server) RecvTCP(conn *ServerConn, id string, src *net.IPAddr) {
|
||||
f := e.Value.(*network.Frame)
|
||||
mb, _ := conn.fm.MarshalFrame(f)
|
||||
sendICMP(conn.echoId, conn.echoSeq, *p.conn, src, "", id, (uint32)(MyMsg_DATA), mb,
|
||||
conn.rproto, -1, p.key,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0)
|
||||
conn.rproto, -1, p.key, 0,
|
||||
0, 0, 0, 0, 0,
|
||||
0, p.cryptoConfig)
|
||||
p.sendPacket++
|
||||
p.sendPacketSize += (uint64)(len(mb))
|
||||
}
|
||||
@@ -489,9 +491,9 @@ func (p *Server) Recv(conn *ServerConn, id string, src *net.IPAddr) {
|
||||
conn.activeSendTime = now
|
||||
|
||||
sendICMP(conn.echoId, conn.echoSeq, *p.conn, src, "", id, (uint32)(MyMsg_DATA), bytes[:n],
|
||||
conn.rproto, -1, p.key,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0)
|
||||
conn.rproto, -1, p.key, 0,
|
||||
0, 0, 0, 0, 0,
|
||||
0, p.cryptoConfig)
|
||||
|
||||
p.sendPacket++
|
||||
p.sendPacketSize += (uint64)(n)
|
||||
@@ -577,8 +579,8 @@ func (p *Server) deleteServerConn(uuid string) {
|
||||
func (p *Server) remoteError(echoId int, echoSeq int, uuid string, rprpto int, src *net.IPAddr) {
|
||||
sendICMP(echoId, echoSeq, *p.conn, src, "", uuid, (uint32)(MyMsg_KICK), []byte{},
|
||||
rprpto, -1, p.key,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0)
|
||||
0, 0, 0, 0, 0, 0, 0,
|
||||
p.cryptoConfig)
|
||||
}
|
||||
|
||||
func (p *Server) addConnError(addr string) {
|
||||
|
72
shadowsocks-rust/Cargo.lock
generated
72
shadowsocks-rust/Cargo.lock
generated
@@ -269,38 +269,18 @@ checksum = "55248b47b0caf0546f7988906588779981c43bb1bc9d0c44087278f80cdb44ba"
|
||||
|
||||
[[package]]
|
||||
name = "bindgen"
|
||||
version = "0.69.5"
|
||||
version = "0.72.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088"
|
||||
checksum = "4f72209734318d0b619a5e0f5129918b848c416e122a3c4ce054e03cb87b726f"
|
||||
dependencies = [
|
||||
"bitflags 2.9.1",
|
||||
"cexpr",
|
||||
"clang-sys",
|
||||
"itertools 0.12.1",
|
||||
"lazy_static",
|
||||
"lazycell",
|
||||
"itertools",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"regex",
|
||||
"rustc-hash 1.1.0",
|
||||
"shlex",
|
||||
"syn 2.0.104",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bindgen"
|
||||
version = "0.71.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5f58bf3d7db68cfbac37cfc485a8d711e87e064c3d0fe0435b92f7a407f9d6b3"
|
||||
dependencies = [
|
||||
"bitflags 2.9.1",
|
||||
"cexpr",
|
||||
"clang-sys",
|
||||
"itertools 0.13.0",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"regex",
|
||||
"rustc-hash 2.1.1",
|
||||
"rustc-hash",
|
||||
"shlex",
|
||||
"syn 2.0.104",
|
||||
]
|
||||
@@ -1833,15 +1813,6 @@ version = "1.70.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569"
|
||||
dependencies = [
|
||||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.13.0"
|
||||
@@ -1958,17 +1929,11 @@ version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
|
||||
|
||||
[[package]]
|
||||
name = "lazycell"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.174"
|
||||
version = "0.2.175"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776"
|
||||
checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543"
|
||||
|
||||
[[package]]
|
||||
name = "libloading"
|
||||
@@ -1977,7 +1942,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"windows-targets 0.48.5",
|
||||
"windows-targets 0.53.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2002,11 +1967,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "librocksdb-sys"
|
||||
version = "0.17.1+9.9.3"
|
||||
version = "0.17.3+10.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b7869a512ae9982f4d46ba482c2a304f1efd80c6412a3d4bf57bb79a619679f"
|
||||
checksum = "cef2a00ee60fe526157c9023edab23943fae1ce2ab6f4abb2a807c1746835de9"
|
||||
dependencies = [
|
||||
"bindgen 0.69.5",
|
||||
"bindgen",
|
||||
"bzip2-sys",
|
||||
"cc",
|
||||
"libc",
|
||||
@@ -2700,7 +2665,7 @@ dependencies = [
|
||||
"pin-project-lite",
|
||||
"quinn-proto",
|
||||
"quinn-udp",
|
||||
"rustc-hash 2.1.1",
|
||||
"rustc-hash",
|
||||
"rustls",
|
||||
"socket2 0.5.10",
|
||||
"thiserror 2.0.12",
|
||||
@@ -2720,7 +2685,7 @@ dependencies = [
|
||||
"lru-slab",
|
||||
"rand 0.9.2",
|
||||
"ring",
|
||||
"rustc-hash 2.1.1",
|
||||
"rustc-hash",
|
||||
"rustls",
|
||||
"rustls-pki-types",
|
||||
"slab",
|
||||
@@ -2976,9 +2941,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rocksdb"
|
||||
version = "0.23.0"
|
||||
version = "0.24.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26ec73b20525cb235bad420f911473b69f9fe27cc856c5461bccd7e4af037f43"
|
||||
checksum = "ddb7af00d2b17dbd07d82c0063e25411959748ff03e8d4f96134c2ff41fce34f"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"librocksdb-sys",
|
||||
@@ -3031,12 +2996,6 @@ version = "0.1.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "989e6739f80c4ad5b13e0fd7fe89531180375b18520cc8c82080e4dc4035b84f"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
version = "2.1.1"
|
||||
@@ -4384,7 +4343,7 @@ version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
|
||||
dependencies = [
|
||||
"windows-sys 0.48.0",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4941,7 +4900,6 @@ version = "2.0.15+zstd.1.5.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eb81183ddd97d0c74cedf1d50d85c8d08c1b8b68ee863bdee9e706eedba1a237"
|
||||
dependencies = [
|
||||
"bindgen 0.71.1",
|
||||
"cc",
|
||||
"pkg-config",
|
||||
]
|
||||
|
@@ -134,7 +134,7 @@ bytes = "1.7"
|
||||
byte_string = "1.0"
|
||||
byteorder = "1.5"
|
||||
rand = { version = "0.9", features = ["small_rng"] }
|
||||
rocksdb = { version = "0.23", optional = true }
|
||||
rocksdb = { version = "0.24", optional = true }
|
||||
|
||||
futures = "0.3"
|
||||
tokio = { version = "1.38", features = [
|
||||
|
@@ -543,7 +543,7 @@ impl AccessControl {
|
||||
|
||||
/// Returns the ASCII representation a domain name,
|
||||
/// if conversion fails returns original string
|
||||
fn convert_to_ascii(host: &str) -> Cow<str> {
|
||||
fn convert_to_ascii(host: &str) -> Cow<'_, str> {
|
||||
idna::domain_to_ascii(host)
|
||||
.map(From::from)
|
||||
.unwrap_or_else(|_| host.into())
|
||||
|
10
sing-box/.github/workflows/build.yml
vendored
10
sing-box/.github/workflows/build.yml
vendored
@@ -46,7 +46,7 @@ jobs:
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: ^1.24.5
|
||||
go-version: ^1.24.6
|
||||
- name: Check input version
|
||||
if: github.event_name == 'workflow_dispatch'
|
||||
run: |-
|
||||
@@ -109,7 +109,7 @@ jobs:
|
||||
if: ${{ ! matrix.legacy_go }}
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: ^1.24.5
|
||||
go-version: ^1.24.6
|
||||
- name: Cache Legacy Go
|
||||
if: matrix.require_legacy_go
|
||||
id: cache-legacy-go
|
||||
@@ -294,7 +294,7 @@ jobs:
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: ^1.24.5
|
||||
go-version: ^1.24.6
|
||||
- name: Setup Android NDK
|
||||
id: setup-ndk
|
||||
uses: nttld/setup-ndk@v1
|
||||
@@ -374,7 +374,7 @@ jobs:
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: ^1.24.5
|
||||
go-version: ^1.24.6
|
||||
- name: Setup Android NDK
|
||||
id: setup-ndk
|
||||
uses: nttld/setup-ndk@v1
|
||||
@@ -472,7 +472,7 @@ jobs:
|
||||
if: matrix.if
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: ^1.24.5
|
||||
go-version: ^1.24.6
|
||||
- name: Setup Xcode stable
|
||||
if: matrix.if && github.ref == 'refs/heads/main-next'
|
||||
run: |-
|
||||
|
2
sing-box/.github/workflows/lint.yml
vendored
2
sing-box/.github/workflows/lint.yml
vendored
@@ -28,7 +28,7 @@ jobs:
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: ^1.24.5
|
||||
go-version: ^1.24.6
|
||||
- name: golangci-lint
|
||||
uses: golangci/golangci-lint-action@v6
|
||||
with:
|
||||
|
13
sing-box/.github/workflows/linux.yml
vendored
13
sing-box/.github/workflows/linux.yml
vendored
@@ -7,6 +7,11 @@ on:
|
||||
description: "Version name"
|
||||
required: true
|
||||
type: string
|
||||
forceBeta:
|
||||
description: "Force beta"
|
||||
required: false
|
||||
type: boolean
|
||||
default: false
|
||||
release:
|
||||
types:
|
||||
- published
|
||||
@@ -25,7 +30,7 @@ jobs:
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: ^1.24.5
|
||||
go-version: ^1.24.6
|
||||
- name: Check input version
|
||||
if: github.event_name == 'workflow_dispatch'
|
||||
run: |-
|
||||
@@ -66,7 +71,7 @@ jobs:
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: ^1.24.5
|
||||
go-version: ^1.24.6
|
||||
- name: Setup Android NDK
|
||||
if: matrix.os == 'android'
|
||||
uses: nttld/setup-ndk@v1
|
||||
@@ -99,11 +104,11 @@ jobs:
|
||||
run: |-
|
||||
TZ=UTC touch -t '197001010000' dist/sing-box
|
||||
- name: Set name
|
||||
if: ${{ ! contains(needs.calculate_version.outputs.version, '-') }}
|
||||
if: (! contains(needs.calculate_version.outputs.version, '-')) && !inputs.forceBeta
|
||||
run: |-
|
||||
echo "NAME=sing-box" >> "$GITHUB_ENV"
|
||||
- name: Set beta name
|
||||
if: contains(needs.calculate_version.outputs.version, '-')
|
||||
if: contains(needs.calculate_version.outputs.version, '-') || inputs.forceBeta
|
||||
run: |-
|
||||
echo "NAME=sing-box-beta" >> "$GITHUB_ENV"
|
||||
- name: Set version
|
||||
|
@@ -5,12 +5,13 @@ plugins {
|
||||
id "kotlin-android"
|
||||
id "kotlin-parcelize"
|
||||
id "com.google.devtools.ksp"
|
||||
id "org.jetbrains.kotlin.plugin.compose"
|
||||
id "com.github.triplet.play"
|
||||
}
|
||||
|
||||
android {
|
||||
namespace "io.nekohasekai.sfa"
|
||||
compileSdk 35
|
||||
compileSdk 36
|
||||
|
||||
ndkVersion "28.0.13004108"
|
||||
|
||||
@@ -85,6 +86,7 @@ android {
|
||||
buildFeatures {
|
||||
viewBinding true
|
||||
aidl true
|
||||
compose true
|
||||
}
|
||||
|
||||
applicationVariants.configureEach { variant ->
|
||||
@@ -103,10 +105,10 @@ dependencies {
|
||||
implementation "androidx.appcompat:appcompat:1.7.1"
|
||||
implementation "com.google.android.material:material:1.12.0"
|
||||
implementation "androidx.constraintlayout:constraintlayout:2.2.1"
|
||||
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.9.1"
|
||||
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.9.1"
|
||||
implementation "androidx.navigation:navigation-fragment-ktx:2.9.1"
|
||||
implementation "androidx.navigation:navigation-ui-ktx:2.9.1"
|
||||
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.9.2"
|
||||
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.9.2"
|
||||
implementation "androidx.navigation:navigation-fragment-ktx:2.9.3"
|
||||
implementation "androidx.navigation:navigation-ui-ktx:2.9.3"
|
||||
implementation "com.google.zxing:core:3.5.3"
|
||||
implementation "androidx.room:room-runtime:2.7.2"
|
||||
implementation "androidx.coordinatorlayout:coordinatorlayout:1.3.0"
|
||||
@@ -115,8 +117,8 @@ dependencies {
|
||||
implementation "androidx.camera:camera-lifecycle:1.4.2"
|
||||
implementation "androidx.camera:camera-camera2:1.4.2"
|
||||
ksp "androidx.room:room-compiler:2.7.2"
|
||||
implementation "androidx.work:work-runtime-ktx:2.10.2"
|
||||
implementation "androidx.browser:browser:1.8.0"
|
||||
implementation "androidx.work:work-runtime-ktx:2.10.3"
|
||||
implementation "androidx.browser:browser:1.9.0"
|
||||
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.10.2"
|
||||
|
||||
// DO NOT UPDATE (minSdkVersion updated)
|
||||
@@ -129,6 +131,19 @@ dependencies {
|
||||
implementation "com.google.guava:guava:33.4.8-android"
|
||||
playImplementation "com.google.android.play:app-update-ktx:2.1.0"
|
||||
playImplementation "com.google.android.gms:play-services-mlkit-barcode-scanning:18.3.1"
|
||||
|
||||
def composeBom = platform('androidx.compose:compose-bom:2025.07.00')
|
||||
implementation composeBom
|
||||
androidTestImplementation composeBom
|
||||
implementation 'androidx.compose.material3:material3'
|
||||
implementation 'androidx.compose.ui:ui-tooling-preview'
|
||||
debugImplementation 'androidx.compose.ui:ui-tooling'
|
||||
androidTestImplementation 'androidx.compose.ui:ui-test-junit4'
|
||||
debugImplementation 'androidx.compose.ui:ui-test-manifest'
|
||||
implementation 'androidx.compose.material:material-icons-extended'
|
||||
implementation 'androidx.activity:activity-compose:1.10.1'
|
||||
implementation 'me.zhanghai.compose.preference:library:1.1.1'
|
||||
implementation "androidx.navigation:navigation-compose:2.9.3"
|
||||
}
|
||||
|
||||
def playCredentialsJSON = rootProject.file("service-account-credentials.json")
|
||||
|
@@ -5,10 +5,11 @@ buildscript {
|
||||
}
|
||||
|
||||
plugins {
|
||||
id 'com.android.application' version '8.11.0' apply false
|
||||
id 'com.android.library' version '8.11.0' apply false
|
||||
id 'org.jetbrains.kotlin.android' version '2.1.0' apply false
|
||||
id 'com.google.devtools.ksp' version '2.1.0-1.0.29' apply false
|
||||
id 'com.github.triplet.play' version '3.8.4' apply false
|
||||
id 'com.android.application' version '8.11.1' apply false
|
||||
id 'com.android.library' version '8.11.1' apply false
|
||||
id 'org.jetbrains.kotlin.android' version '2.2.0' apply false
|
||||
id 'com.google.devtools.ksp' version '2.2.0-2.0.2' apply false
|
||||
id 'com.github.triplet.play' version '3.12.1' apply false
|
||||
id 'org.jetbrains.kotlin.plugin.compose' version '2.2.0' apply false
|
||||
}
|
||||
|
||||
|
@@ -1,3 +1,3 @@
|
||||
VERSION_CODE=549
|
||||
VERSION_NAME=1.12.0
|
||||
GO_VERSION=go1.24.5
|
||||
VERSION_CODE=550
|
||||
VERSION_NAME=1.12.1
|
||||
GO_VERSION=go1.24.6
|
||||
|
@@ -423,4 +423,12 @@ public class ExtensionPlatformInterface: NSObject, LibboxPlatformInterfaceProtoc
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
public func localDNSTransport() -> (any LibboxLocalDNSTransportProtocol)? {
|
||||
nil
|
||||
}
|
||||
|
||||
public func systemCertificates() -> (any LibboxStringIteratorProtocol)? {
|
||||
nil
|
||||
}
|
||||
}
|
||||
|
@@ -2163,7 +2163,7 @@
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.11.5;
|
||||
MARKETING_VERSION = 1.12.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = io.nekohasekai.sfavt;
|
||||
PRODUCT_NAME = "sing-box";
|
||||
SDKROOT = appletvos;
|
||||
@@ -2198,7 +2198,7 @@
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.11.5;
|
||||
MARKETING_VERSION = 1.12.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = io.nekohasekai.sfavt;
|
||||
PRODUCT_NAME = "sing-box";
|
||||
SDKROOT = appletvos;
|
||||
@@ -2503,7 +2503,7 @@
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.11.5;
|
||||
MARKETING_VERSION = 1.12.10;
|
||||
OTHER_CODE_SIGN_FLAGS = "--deep";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = io.nekohasekai.sfavt;
|
||||
PRODUCT_NAME = "sing-box";
|
||||
@@ -2545,7 +2545,7 @@
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.11.5;
|
||||
MARKETING_VERSION = 1.12.10;
|
||||
OTHER_CODE_SIGN_FLAGS = "--deep";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = io.nekohasekai.sfavt;
|
||||
PRODUCT_NAME = "sing-box";
|
||||
@@ -2586,7 +2586,7 @@
|
||||
"@executable_path/../Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 13.0;
|
||||
MARKETING_VERSION = 1.11.5;
|
||||
MARKETING_VERSION = 1.12.0;
|
||||
OTHER_CODE_SIGN_FLAGS = "";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = io.nekohasekai.sfavt;
|
||||
PRODUCT_NAME = "sing-box";
|
||||
@@ -2626,7 +2626,7 @@
|
||||
"@executable_path/../Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 13.0;
|
||||
MARKETING_VERSION = 1.11.5;
|
||||
MARKETING_VERSION = 1.12.0;
|
||||
OTHER_CODE_SIGN_FLAGS = "";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = io.nekohasekai.sfavt;
|
||||
PRODUCT_NAME = "sing-box";
|
||||
@@ -2754,7 +2754,7 @@
|
||||
"@executable_path/../../../../Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 13.0;
|
||||
MARKETING_VERSION = 1.11.5;
|
||||
MARKETING_VERSION = "1.12.0-beta.2";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = io.nekohasekai.sfavt.system;
|
||||
PRODUCT_NAME = "$(inherited)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
@@ -2790,7 +2790,7 @@
|
||||
"@executable_path/../../../../Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 13.0;
|
||||
MARKETING_VERSION = 1.11.5;
|
||||
MARKETING_VERSION = "1.12.0-beta.2";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = io.nekohasekai.sfavt.system;
|
||||
PRODUCT_NAME = "$(inherited)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
@@ -2832,7 +2832,7 @@
|
||||
"@executable_path/../Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 13.0;
|
||||
MARKETING_VERSION = 1.11.5;
|
||||
MARKETING_VERSION = "1.12.0-beta.2";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = io.nekohasekai.sfavt.standalone;
|
||||
PRODUCT_NAME = SFM;
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
@@ -2873,7 +2873,7 @@
|
||||
"@executable_path/../Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 13.0;
|
||||
MARKETING_VERSION = 1.11.5;
|
||||
MARKETING_VERSION = "1.12.0-beta.2";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = io.nekohasekai.sfavt.standalone;
|
||||
PRODUCT_NAME = SFM;
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
|
@@ -107,13 +107,13 @@ func buildAndroid() {
|
||||
}
|
||||
|
||||
if !debugEnabled {
|
||||
sharedFlags[3] = sharedFlags[3] + " -checklinkname=0"
|
||||
args = append(args, sharedFlags...)
|
||||
} else {
|
||||
debugFlags[1] = debugFlags[1] + " -checklinkname=0"
|
||||
args = append(args, debugFlags...)
|
||||
}
|
||||
|
||||
args = append(args, "-ldflags", "-checklinkname=0")
|
||||
|
||||
tags := append(sharedTags, memcTags...)
|
||||
if debugEnabled {
|
||||
tags = append(tags, debugTags...)
|
||||
|
@@ -454,5 +454,5 @@ func parseADGuardIPCIDRLine(ruleLine string) (netip.Prefix, error) {
|
||||
for len(ruleParts) < 4 {
|
||||
ruleParts = append(ruleParts, 0)
|
||||
}
|
||||
return netip.PrefixFrom(netip.AddrFrom4(*(*[4]byte)(ruleParts)), bitLen), nil
|
||||
return netip.PrefixFrom(netip.AddrFrom4([4]byte(ruleParts)), bitLen), nil
|
||||
}
|
||||
|
@@ -111,7 +111,7 @@ func NewWithOptions(options Options) (N.Dialer, error) {
|
||||
dnsQueryOptions.Transport = dnsTransport.Default()
|
||||
} else if options.NewDialer {
|
||||
return nil, E.New("missing domain resolver for domain server address")
|
||||
} else if !options.DirectOutbound {
|
||||
} else {
|
||||
deprecated.Report(options.Context, deprecated.OptionMissingDomainResolver)
|
||||
}
|
||||
}
|
||||
|
@@ -96,11 +96,11 @@ func findProcessName(network string, ip netip.Addr, port int) (string, error) {
|
||||
switch {
|
||||
case flag&0x1 > 0 && isIPv4:
|
||||
// ipv4
|
||||
srcIP = netip.AddrFrom4(*(*[4]byte)(buf[inp+76 : inp+80]))
|
||||
srcIP = netip.AddrFrom4([4]byte(buf[inp+76 : inp+80]))
|
||||
srcIsIPv4 = true
|
||||
case flag&0x2 > 0 && !isIPv4:
|
||||
// ipv6
|
||||
srcIP = netip.AddrFrom16(*(*[16]byte)(buf[inp+64 : inp+80]))
|
||||
srcIP = netip.AddrFrom16([16]byte(buf[inp+64 : inp+80]))
|
||||
default:
|
||||
continue
|
||||
}
|
||||
|
@@ -2,6 +2,8 @@ package tls
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"errors"
|
||||
"net"
|
||||
"os"
|
||||
|
||||
@@ -41,6 +43,13 @@ func ClientHandshake(ctx context.Context, conn net.Conn, config Config) (Conn, e
|
||||
ctx, cancel := context.WithTimeout(ctx, C.TCPTimeout)
|
||||
defer cancel()
|
||||
tlsConn, err := aTLS.ClientHandshake(ctx, conn, config)
|
||||
var echErr *tls.ECHRejectionError
|
||||
if errors.As(err, &echErr) && len(echErr.RetryConfigList) > 0 {
|
||||
if echConfig, isECH := config.(ECHCapableConfig); isECH {
|
||||
echConfig.SetECHConfigList(echErr.RetryConfigList)
|
||||
tlsConn, err = aTLS.ClientHandshake(ctx, conn, config)
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@@ -20,8 +20,8 @@ import (
|
||||
)
|
||||
|
||||
func dnsReadConfig(_ context.Context, _ string) *dnsConfig {
|
||||
var state C.res_state
|
||||
if C.res_ninit(state) != 0 {
|
||||
var state C.struct___res_state
|
||||
if C.res_ninit(&state) != 0 {
|
||||
return &dnsConfig{
|
||||
servers: defaultNS,
|
||||
search: dnsDefaultSearch(),
|
||||
|
13
sing-box/dns/transport/local/resolv_test.go
Normal file
13
sing-box/dns/transport/local/resolv_test.go
Normal file
@@ -0,0 +1,13 @@
|
||||
package local
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestDNSReadConfig(t *testing.T) {
|
||||
t.Parallel()
|
||||
require.NoError(t, dnsReadConfig(context.Background(), "/etc/resolv.conf").err)
|
||||
}
|
@@ -2,6 +2,10 @@
|
||||
icon: material/alert-decagram
|
||||
---
|
||||
|
||||
#### 1.12.1
|
||||
|
||||
* Fixes and improvements
|
||||
|
||||
#### 1.12.0
|
||||
|
||||
* Refactor DNS servers **1**
|
||||
|
@@ -61,7 +61,7 @@ WireGuard MTU。
|
||||
|
||||
==必填==
|
||||
|
||||
接口的 IPv4/IPv6 地址或地址段的列表您。
|
||||
接口的 IPv4/IPv6 地址或地址段的列表。
|
||||
|
||||
要分配给接口的 IP(v4 或 v6)地址段列表。
|
||||
|
||||
|
@@ -88,7 +88,7 @@ icon: material/delete-clock
|
||||
|
||||
==必填==
|
||||
|
||||
接口的 IPv4/IPv6 地址或地址段的列表您。
|
||||
接口的 IPv4/IPv6 地址或地址段的列表。
|
||||
|
||||
要分配给接口的 IP(v4 或 v6)地址段列表。
|
||||
|
||||
|
@@ -108,7 +108,7 @@ flowchart TB
|
||||
"inbounds": [
|
||||
{
|
||||
"type": "tun",
|
||||
"inet4_address": "172.19.0.1/30",
|
||||
"address": ["172.19.0.1/30"],
|
||||
"auto_route": true,
|
||||
// "auto_redirect": true, // On linux
|
||||
"strict_route": true
|
||||
@@ -162,8 +162,7 @@ flowchart TB
|
||||
"inbounds": [
|
||||
{
|
||||
"type": "tun",
|
||||
"inet4_address": "172.19.0.1/30",
|
||||
"inet6_address": "fdfe:dcba:9876::1/126",
|
||||
"address": ["172.19.0.1/30", "fdfe:dcba:9876::1/126"],
|
||||
"auto_route": true,
|
||||
// "auto_redirect": true, // On linux
|
||||
"strict_route": true
|
||||
@@ -233,8 +232,7 @@ flowchart TB
|
||||
"inbounds": [
|
||||
{
|
||||
"type": "tun",
|
||||
"inet4_address": "172.19.0.1/30",
|
||||
"inet6_address": "fdfe:dcba:9876::1/126",
|
||||
"address": ["172.19.0.1/30","fdfe:dcba:9876::1/126"],
|
||||
"auto_route": true,
|
||||
// "auto_redirect": true, // On linux
|
||||
"strict_route": true
|
||||
|
@@ -8,7 +8,7 @@ icon: material/arrange-bring-forward
|
||||
|
||||
DNS 服务器已经重构。
|
||||
|
||||
!!! info "饮用"
|
||||
!!! info "引用"
|
||||
|
||||
[DNS 服务器](/configuration/dns/server/) /
|
||||
[旧 DNS 服务器](/configuration/dns/server/legacy/)
|
||||
|
@@ -14,6 +14,7 @@ import (
|
||||
func cacheRouter(ctx context.Context) http.Handler {
|
||||
r := chi.NewRouter()
|
||||
r.Post("/fakeip/flush", flushFakeip(ctx))
|
||||
r.Post("/dns/flush", flushDNS(ctx))
|
||||
return r
|
||||
}
|
||||
|
||||
@@ -31,3 +32,13 @@ func flushFakeip(ctx context.Context) func(w http.ResponseWriter, r *http.Reques
|
||||
render.NoContent(w, r)
|
||||
}
|
||||
}
|
||||
|
||||
func flushDNS(ctx context.Context) func(w http.ResponseWriter, r *http.Request) {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
dnsRouter := service.FromContext[adapter.DNSRouter](ctx)
|
||||
if dnsRouter != nil {
|
||||
dnsRouter.ClearCache()
|
||||
}
|
||||
render.NoContent(w, r)
|
||||
}
|
||||
}
|
||||
|
@@ -27,7 +27,7 @@ require (
|
||||
github.com/sagernet/gomobile v0.1.7
|
||||
github.com/sagernet/gvisor v0.0.0-20250325023245-7a9c0f5725fb
|
||||
github.com/sagernet/quic-go v0.52.0-beta.1
|
||||
github.com/sagernet/sing v0.7.0-beta.2
|
||||
github.com/sagernet/sing v0.7.5
|
||||
github.com/sagernet/sing-mux v0.3.2
|
||||
github.com/sagernet/sing-quic v0.5.0-beta.3
|
||||
github.com/sagernet/sing-shadowsocks v0.2.8
|
||||
|
@@ -167,8 +167,8 @@ github.com/sagernet/nftables v0.3.0-beta.4/go.mod h1:OQXAjvjNGGFxaTgVCSTRIhYB5/l
|
||||
github.com/sagernet/quic-go v0.52.0-beta.1 h1:hWkojLg64zjV+MJOvJU/kOeWndm3tiEfBLx5foisszs=
|
||||
github.com/sagernet/quic-go v0.52.0-beta.1/go.mod h1:OV+V5kEBb8kJS7k29MzDu6oj9GyMc7HA07sE1tedxz4=
|
||||
github.com/sagernet/sing v0.6.9/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak=
|
||||
github.com/sagernet/sing v0.7.0-beta.2 h1:UImAKtHGQX205lGYYXKA2qnEeVSml+hKS1oaOwvA14c=
|
||||
github.com/sagernet/sing v0.7.0-beta.2/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak=
|
||||
github.com/sagernet/sing v0.7.5 h1:gNMwZCLPqR+4e0g6dwi0sSsrvOmoMjpZgqxKsuJZatc=
|
||||
github.com/sagernet/sing v0.7.5/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak=
|
||||
github.com/sagernet/sing-mux v0.3.2 h1:meZVFiiStvHThb/trcpAkCrmtJOuItG5Dzl1RRP5/NE=
|
||||
github.com/sagernet/sing-mux v0.3.2/go.mod h1:pht8iFY4c9Xltj7rhVd208npkNaeCxzyXCgulDPLUDA=
|
||||
github.com/sagernet/sing-quic v0.5.0-beta.3 h1:X/acRNsqQNfDlmwE7SorHfaZiny5e67hqIzM/592ric=
|
||||
|
@@ -26,7 +26,7 @@ func defaultRouteIP() (netip.Addr, error) {
|
||||
for _, addr := range addrs {
|
||||
ip := addr.(*net.IPNet).IP
|
||||
if ip.To4() != nil {
|
||||
return netip.AddrFrom4(*(*[4]byte)(ip)), nil
|
||||
return netip.AddrFrom4([4]byte(ip)), nil
|
||||
}
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user