mirror of
https://github.com/bolucat/Archive.git
synced 2026-04-23 00:17:16 +08:00
Update On Thu May 15 20:37:50 CEST 2025
This commit is contained in:
@@ -999,3 +999,4 @@ Update On Sun May 11 20:34:28 CEST 2025
|
||||
Update On Mon May 12 20:36:32 CEST 2025
|
||||
Update On Tue May 13 20:37:30 CEST 2025
|
||||
Update On Wed May 14 20:34:49 CEST 2025
|
||||
Update On Thu May 15 20:37:42 CEST 2025
|
||||
|
||||
@@ -13,11 +13,14 @@ import (
|
||||
type RealityOptions struct {
|
||||
PublicKey string `proxy:"public-key"`
|
||||
ShortID string `proxy:"short-id"`
|
||||
|
||||
SupportX25519MLKEM768 bool `proxy:"support-x25519mlkem768"`
|
||||
}
|
||||
|
||||
func (o RealityOptions) Parse() (*tlsC.RealityConfig, error) {
|
||||
if o.PublicKey != "" {
|
||||
config := new(tlsC.RealityConfig)
|
||||
config.SupportX25519MLKEM768 = o.SupportX25519MLKEM768
|
||||
|
||||
const x25519ScalarSize = 32
|
||||
publicKey, err := base64.RawURLEncoding.DecodeString(o.PublicKey)
|
||||
|
||||
@@ -35,6 +35,8 @@ const RealityMaxShortIDLen = 8
|
||||
type RealityConfig struct {
|
||||
PublicKey *ecdh.PublicKey
|
||||
ShortID [RealityMaxShortIDLen]byte
|
||||
|
||||
SupportX25519MLKEM768 bool
|
||||
}
|
||||
|
||||
func GetRealityConn(ctx context.Context, conn net.Conn, fingerprint UClientHelloID, tlsConfig *tls.Config, realityConfig *RealityConfig) (net.Conn, error) {
|
||||
@@ -48,38 +50,36 @@ func GetRealityConn(ctx context.Context, conn net.Conn, fingerprint UClientHello
|
||||
SessionTicketsDisabled: true,
|
||||
VerifyPeerCertificate: verifier.VerifyPeerCertificate,
|
||||
}
|
||||
clientID := utls.ClientHelloID{
|
||||
Client: fingerprint.Client,
|
||||
Version: fingerprint.Version,
|
||||
Seed: fingerprint.Seed,
|
||||
}
|
||||
uConn := utls.UClient(conn, uConfig, clientID)
|
||||
|
||||
uConn := utls.UClient(conn, uConfig, fingerprint)
|
||||
verifier.UConn = uConn
|
||||
err := uConn.BuildHandshakeState()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// ------for X25519MLKEM768 does not work properly with reality-------
|
||||
// Iterate over extensions and check
|
||||
for _, extension := range uConn.Extensions {
|
||||
if ce, ok := extension.(*utls.SupportedCurvesExtension); ok {
|
||||
ce.Curves = slices.DeleteFunc(ce.Curves, func(curveID utls.CurveID) bool {
|
||||
return curveID == utls.X25519MLKEM768
|
||||
})
|
||||
if !realityConfig.SupportX25519MLKEM768 {
|
||||
// ------for X25519MLKEM768 does not work properly with the old reality server-------
|
||||
// Iterate over extensions and check
|
||||
for _, extension := range uConn.Extensions {
|
||||
if ce, ok := extension.(*utls.SupportedCurvesExtension); ok {
|
||||
ce.Curves = slices.DeleteFunc(ce.Curves, func(curveID utls.CurveID) bool {
|
||||
return curveID == utls.X25519MLKEM768
|
||||
})
|
||||
}
|
||||
if ks, ok := extension.(*utls.KeyShareExtension); ok {
|
||||
ks.KeyShares = slices.DeleteFunc(ks.KeyShares, func(share utls.KeyShare) bool {
|
||||
return share.Group == utls.X25519MLKEM768
|
||||
})
|
||||
}
|
||||
}
|
||||
if ks, ok := extension.(*utls.KeyShareExtension); ok {
|
||||
ks.KeyShares = slices.DeleteFunc(ks.KeyShares, func(share utls.KeyShare) bool {
|
||||
return share.Group == utls.X25519MLKEM768
|
||||
})
|
||||
// Rebuild the client hello
|
||||
err = uConn.BuildHandshakeState()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// --------------------------------------------------------------------
|
||||
}
|
||||
// Rebuild the client hello
|
||||
err = uConn.BuildHandshakeState()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
hello := uConn.HandshakeState.Hello
|
||||
rawSessionID := hello.Raw[39 : 39+32] // the location of session ID
|
||||
@@ -144,7 +144,7 @@ func GetRealityConn(ctx context.Context, conn net.Conn, fingerprint UClientHello
|
||||
log.Debugln("REALITY Authentication: %v, AEAD: %T", verifier.verified, aeadCipher)
|
||||
|
||||
if !verifier.verified {
|
||||
go realityClientFallback(uConn, uConfig.ServerName, clientID)
|
||||
go realityClientFallback(uConn, uConfig.ServerName, fingerprint)
|
||||
return nil, errors.New("REALITY authentication failed")
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -36,7 +36,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-20250503140532-decbcfccbfdf
|
||||
github.com/metacubex/utls v1.7.0-alpha.3
|
||||
github.com/metacubex/utls v1.7.3
|
||||
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
|
||||
|
||||
+2
-2
@@ -138,8 +138,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-20250503140532-decbcfccbfdf h1:LwID1wz4tzypidd412dd4dC1H0m1TgRCQ/XvRvMJDFM=
|
||||
github.com/metacubex/tfo-go v0.0.0-20250503140532-decbcfccbfdf/go.mod h1:l9oLnLoEXyGZ5RVLsh7QCC5XsouTUyKk4F2nLm2DHLw=
|
||||
github.com/metacubex/utls v1.7.0-alpha.3 h1:cp1cEMUnoifiWrGHRzo+nCwPRveN9yPD8QaRFmfcYxA=
|
||||
github.com/metacubex/utls v1.7.0-alpha.3/go.mod h1:oknYT0qTOwE4hjPmZOEpzVdefnW7bAdGLvZcqmk4TLU=
|
||||
github.com/metacubex/utls v1.7.3 h1:yDcMEWojFh+t8rU9X0HPcZDPAoFze/rIIyssqivzj8A=
|
||||
github.com/metacubex/utls v1.7.3/go.mod h1:oknYT0qTOwE4hjPmZOEpzVdefnW7bAdGLvZcqmk4TLU=
|
||||
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=
|
||||
|
||||
@@ -31,7 +31,7 @@ func (l *LogLevel) UnmarshalYAML(unmarshal func(any) error) error {
|
||||
unmarshal(&tp)
|
||||
level, exist := LogLevelMapping[strings.ToLower(tp)]
|
||||
if !exist {
|
||||
return errors.New("invalid mode")
|
||||
return errors.New("invalid log-level")
|
||||
}
|
||||
*l = level
|
||||
return nil
|
||||
@@ -43,7 +43,7 @@ func (l *LogLevel) UnmarshalJSON(data []byte) error {
|
||||
json.Unmarshal(data, &tp)
|
||||
level, exist := LogLevelMapping[strings.ToLower(tp)]
|
||||
if !exist {
|
||||
return errors.New("invalid mode")
|
||||
return errors.New("invalid log-level")
|
||||
}
|
||||
*l = level
|
||||
return nil
|
||||
@@ -53,7 +53,7 @@ func (l *LogLevel) UnmarshalJSON(data []byte) error {
|
||||
func (l *LogLevel) UnmarshalText(data []byte) error {
|
||||
level, exist := LogLevelMapping[strings.ToLower(string(data))]
|
||||
if !exist {
|
||||
return errors.New("invalid mode")
|
||||
return errors.New("invalid log-level")
|
||||
}
|
||||
*l = level
|
||||
return nil
|
||||
|
||||
@@ -30,8 +30,8 @@
|
||||
"country-code-emoji": "2.3.0",
|
||||
"country-emoji": "1.5.6",
|
||||
"dayjs": "1.11.13",
|
||||
"framer-motion": "12.10.5",
|
||||
"i18next": "25.1.2",
|
||||
"framer-motion": "12.11.3",
|
||||
"i18next": "25.1.3",
|
||||
"jotai": "2.12.4",
|
||||
"json-schema": "0.4.0",
|
||||
"material-react-table": "3.2.1",
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
"@vitejs/plugin-react": "4.4.1",
|
||||
"ahooks": "3.8.4",
|
||||
"d3": "7.9.0",
|
||||
"framer-motion": "12.10.5",
|
||||
"framer-motion": "12.11.3",
|
||||
"react": "19.1.0",
|
||||
"react-dom": "19.1.0",
|
||||
"react-error-boundary": "6.0.0",
|
||||
@@ -41,6 +41,6 @@
|
||||
"sass-embedded": "1.88.0",
|
||||
"tailwind-merge": "3.3.0",
|
||||
"typescript-plugin-css-modules": "5.1.0",
|
||||
"vite-plugin-dts": "4.5.3"
|
||||
"vite-plugin-dts": "4.5.4"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@
|
||||
"eslint-plugin-prettier": "5.4.0",
|
||||
"eslint-plugin-promise": "7.2.1",
|
||||
"eslint-plugin-react": "7.37.5",
|
||||
"eslint-plugin-react-compiler": "19.1.0-rc.1",
|
||||
"eslint-plugin-react-compiler": "19.1.0-rc.2",
|
||||
"eslint-plugin-react-hooks": "5.2.0",
|
||||
"globals": "16.1.0",
|
||||
"knip": "5.55.1",
|
||||
|
||||
Generated
+32
-32
@@ -91,8 +91,8 @@ importers:
|
||||
specifier: 7.37.5
|
||||
version: 7.37.5(eslint@9.26.0(jiti@2.4.2))
|
||||
eslint-plugin-react-compiler:
|
||||
specifier: 19.1.0-rc.1
|
||||
version: 19.1.0-rc.1(eslint@9.26.0(jiti@2.4.2))
|
||||
specifier: 19.1.0-rc.2
|
||||
version: 19.1.0-rc.2(eslint@9.26.0(jiti@2.4.2))
|
||||
eslint-plugin-react-hooks:
|
||||
specifier: 5.2.0
|
||||
version: 5.2.0(eslint@9.26.0(jiti@2.4.2))
|
||||
@@ -266,11 +266,11 @@ importers:
|
||||
specifier: 1.11.13
|
||||
version: 1.11.13
|
||||
framer-motion:
|
||||
specifier: 12.10.5
|
||||
version: 12.10.5(@emotion/is-prop-valid@1.3.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
|
||||
specifier: 12.11.3
|
||||
version: 12.11.3(@emotion/is-prop-valid@1.3.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
|
||||
i18next:
|
||||
specifier: 25.1.2
|
||||
version: 25.1.2(typescript@5.8.3)
|
||||
specifier: 25.1.3
|
||||
version: 25.1.3(typescript@5.8.3)
|
||||
jotai:
|
||||
specifier: 2.12.4
|
||||
version: 2.12.4(@types/react@19.1.4)(react@19.1.0)
|
||||
@@ -303,7 +303,7 @@ importers:
|
||||
version: 7.6.0(9b960f55d242927c500fd44155e8e7af)
|
||||
react-i18next:
|
||||
specifier: 15.5.1
|
||||
version: 15.5.1(i18next@25.1.2(typescript@5.8.3))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(typescript@5.8.3)
|
||||
version: 15.5.1(i18next@25.1.3(typescript@5.8.3))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(typescript@5.8.3)
|
||||
react-markdown:
|
||||
specifier: 10.1.0
|
||||
version: 10.1.0(@types/react@19.1.4)(react@19.1.0)
|
||||
@@ -486,8 +486,8 @@ importers:
|
||||
specifier: 7.9.0
|
||||
version: 7.9.0
|
||||
framer-motion:
|
||||
specifier: 12.10.5
|
||||
version: 12.10.5(@emotion/is-prop-valid@1.3.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
|
||||
specifier: 12.11.3
|
||||
version: 12.11.3(@emotion/is-prop-valid@1.3.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
|
||||
react:
|
||||
specifier: 19.1.0
|
||||
version: 19.1.0
|
||||
@@ -499,7 +499,7 @@ importers:
|
||||
version: 6.0.0(react@19.1.0)
|
||||
react-i18next:
|
||||
specifier: 15.5.1
|
||||
version: 15.5.1(i18next@25.1.2(typescript@5.8.3))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(typescript@5.8.3)
|
||||
version: 15.5.1(i18next@25.1.3(typescript@5.8.3))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(typescript@5.8.3)
|
||||
react-use:
|
||||
specifier: 17.6.0
|
||||
version: 17.6.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
|
||||
@@ -535,8 +535,8 @@ importers:
|
||||
specifier: 5.1.0
|
||||
version: 5.1.0(typescript@5.8.3)
|
||||
vite-plugin-dts:
|
||||
specifier: 4.5.3
|
||||
version: 4.5.3(@types/node@22.15.18)(rollup@4.40.0)(typescript@5.8.3)(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(less@4.2.0)(lightningcss@1.29.2)(sass-embedded@1.88.0)(sass@1.83.0)(stylus@0.62.0)(terser@5.36.0)(tsx@4.19.4)(yaml@2.7.0))
|
||||
specifier: 4.5.4
|
||||
version: 4.5.4(@types/node@22.15.18)(rollup@4.40.0)(typescript@5.8.3)(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(less@4.2.0)(lightningcss@1.29.2)(sass-embedded@1.88.0)(sass@1.83.0)(stylus@0.62.0)(terser@5.36.0)(tsx@4.19.4)(yaml@2.7.0))
|
||||
|
||||
scripts:
|
||||
dependencies:
|
||||
@@ -4634,8 +4634,8 @@ packages:
|
||||
peerDependencies:
|
||||
eslint: ^7.0.0 || ^8.0.0 || ^9.0.0
|
||||
|
||||
eslint-plugin-react-compiler@19.1.0-rc.1:
|
||||
resolution: {integrity: sha512-3umw5eqZXapBl7aQGmvcjheKhUbsElb9jTETxRZg371e1LG4EPs/zCHt2JzP+wNcdaZWzjU/R730zPUJblY2zw==}
|
||||
eslint-plugin-react-compiler@19.1.0-rc.2:
|
||||
resolution: {integrity: sha512-oKalwDGcD+RX9mf3NEO4zOoUMeLvjSvcbbEOpquzmzqEEM2MQdp7/FY/Hx9NzmUwFzH1W9SKTz5fihfMldpEYw==}
|
||||
engines: {node: ^14.17.0 || ^16.0.0 || >= 18.0.0}
|
||||
peerDependencies:
|
||||
eslint: '>=7'
|
||||
@@ -4889,8 +4889,8 @@ packages:
|
||||
fraction.js@4.3.7:
|
||||
resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==}
|
||||
|
||||
framer-motion@12.10.5:
|
||||
resolution: {integrity: sha512-p6VF1YkwWvNDFzg5IQ5lqPx11Td4TQ6LqDnshV7sWj0Nrp4dwz2/aEzmgh9WA9ridcTIJ625Fr0oiuhgqIoFwQ==}
|
||||
framer-motion@12.11.3:
|
||||
resolution: {integrity: sha512-ksUtDFBZtrbQFt4bEMFrFgo7camhmXcLeuylKQxEYSd9czkZ4tZmFROxWczWeu51WqC2m91ifpvgGCBLd0uviQ==}
|
||||
peerDependencies:
|
||||
'@emotion/is-prop-valid': '*'
|
||||
react: ^18.0.0 || ^19.0.0
|
||||
@@ -5218,8 +5218,8 @@ packages:
|
||||
hyphenate-style-name@1.1.0:
|
||||
resolution: {integrity: sha512-WDC/ui2VVRrz3jOVi+XtjqkDjiVjTtFaAGiW37k6b+ohyQ5wYDOGkvCZa8+H0nx3gyvv0+BST9xuOgIyGQ00gw==}
|
||||
|
||||
i18next@25.1.2:
|
||||
resolution: {integrity: sha512-SP63m8LzdjkrAjruH7SCI3ndPSgjt4/wX7ouUUOzCW/eY+HzlIo19IQSfYA9X3qRiRP1SYtaTsg/Oz/PGsfD8w==}
|
||||
i18next@25.1.3:
|
||||
resolution: {integrity: sha512-VY1iKox3YWPRTNMHFdgk5TV+Jq6rNKexLCLpPmP5oXXJ5Kl7yDBi3ycZ5fyEKZ1tNBW5gOqD4WV0XqE7rl3JUg==}
|
||||
peerDependencies:
|
||||
typescript: ^5
|
||||
peerDependenciesMeta:
|
||||
@@ -6205,8 +6205,8 @@ packages:
|
||||
peerDependencies:
|
||||
monaco-editor: '>=0.36'
|
||||
|
||||
motion-dom@12.10.5:
|
||||
resolution: {integrity: sha512-F7XKmhxXEH/y3aWWf0N2w69wNSN+6PcJ1seqR1WolClmXpPhj+xwzs9j5CpsMFzeHR1D7irl3JcWMToPRwX6Hg==}
|
||||
motion-dom@12.11.2:
|
||||
resolution: {integrity: sha512-wZ396XNNTI9GOkyrr80wFSbZc1JbIHSHTbLdririSbkEgahWWKmsHzsxyxqBBvuBU/iaQWVu1YCjdpXYNfo2yQ==}
|
||||
|
||||
motion-utils@12.9.4:
|
||||
resolution: {integrity: sha512-BW3I65zeM76CMsfh3kHid9ansEJk9Qvl+K5cu4DVHKGsI52n76OJ4z2CUJUV+Mn3uEP9k1JJA3tClG0ggSrRcg==}
|
||||
@@ -8122,8 +8122,8 @@ packages:
|
||||
engines: {node: ^18.19.0 || >=20.6.0}
|
||||
hasBin: true
|
||||
|
||||
vite-plugin-dts@4.5.3:
|
||||
resolution: {integrity: sha512-P64VnD00dR+e8S26ESoFELqc17+w7pKkwlBpgXteOljFyT0zDwD8hH4zXp49M/kciy//7ZbVXIwQCekBJjfWzA==}
|
||||
vite-plugin-dts@4.5.4:
|
||||
resolution: {integrity: sha512-d4sOM8M/8z7vRXHHq/ebbblfaxENjogAAekcfcDCCwAyvGqnPrc7f4NZbvItS+g4WTgerW0xDwSz5qz11JT3vg==}
|
||||
peerDependencies:
|
||||
typescript: '*'
|
||||
vite: '*'
|
||||
@@ -10373,7 +10373,7 @@ snapshots:
|
||||
|
||||
'@rollup/pluginutils@5.1.4(rollup@4.40.0)':
|
||||
dependencies:
|
||||
'@types/estree': 1.0.6
|
||||
'@types/estree': 1.0.7
|
||||
estree-walker: 2.0.2
|
||||
picomatch: 4.0.2
|
||||
optionalDependencies:
|
||||
@@ -12894,7 +12894,7 @@ snapshots:
|
||||
'@eslint-community/eslint-utils': 4.4.1(eslint@9.26.0(jiti@2.4.2))
|
||||
eslint: 9.26.0(jiti@2.4.2)
|
||||
|
||||
eslint-plugin-react-compiler@19.1.0-rc.1(eslint@9.26.0(jiti@2.4.2)):
|
||||
eslint-plugin-react-compiler@19.1.0-rc.2(eslint@9.26.0(jiti@2.4.2)):
|
||||
dependencies:
|
||||
'@babel/core': 7.26.10
|
||||
'@babel/parser': 7.27.0
|
||||
@@ -13254,9 +13254,9 @@ snapshots:
|
||||
|
||||
fraction.js@4.3.7: {}
|
||||
|
||||
framer-motion@12.10.5(@emotion/is-prop-valid@1.3.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0):
|
||||
framer-motion@12.11.3(@emotion/is-prop-valid@1.3.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0):
|
||||
dependencies:
|
||||
motion-dom: 12.10.5
|
||||
motion-dom: 12.11.2
|
||||
motion-utils: 12.9.4
|
||||
tslib: 2.8.1
|
||||
optionalDependencies:
|
||||
@@ -13663,7 +13663,7 @@ snapshots:
|
||||
|
||||
hyphenate-style-name@1.1.0: {}
|
||||
|
||||
i18next@25.1.2(typescript@5.8.3):
|
||||
i18next@25.1.3(typescript@5.8.3):
|
||||
dependencies:
|
||||
'@babel/runtime': 7.27.1
|
||||
optionalDependencies:
|
||||
@@ -14693,7 +14693,7 @@ snapshots:
|
||||
vscode-uri: 3.0.8
|
||||
yaml: 2.7.0
|
||||
|
||||
motion-dom@12.10.5:
|
||||
motion-dom@12.11.2:
|
||||
dependencies:
|
||||
motion-utils: 12.9.4
|
||||
|
||||
@@ -15314,11 +15314,11 @@ snapshots:
|
||||
dependencies:
|
||||
react: 19.1.0
|
||||
|
||||
react-i18next@15.5.1(i18next@25.1.2(typescript@5.8.3))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(typescript@5.8.3):
|
||||
react-i18next@15.5.1(i18next@25.1.3(typescript@5.8.3))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(typescript@5.8.3):
|
||||
dependencies:
|
||||
'@babel/runtime': 7.26.10
|
||||
html-parse-stringify: 3.0.1
|
||||
i18next: 25.1.2(typescript@5.8.3)
|
||||
i18next: 25.1.3(typescript@5.8.3)
|
||||
react: 19.1.0
|
||||
optionalDependencies:
|
||||
react-dom: 19.1.0(react@19.1.0)
|
||||
@@ -16729,7 +16729,7 @@ snapshots:
|
||||
- rollup
|
||||
- supports-color
|
||||
|
||||
vite-plugin-dts@4.5.3(@types/node@22.15.18)(rollup@4.40.0)(typescript@5.8.3)(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(less@4.2.0)(lightningcss@1.29.2)(sass-embedded@1.88.0)(sass@1.83.0)(stylus@0.62.0)(terser@5.36.0)(tsx@4.19.4)(yaml@2.7.0)):
|
||||
vite-plugin-dts@4.5.4(@types/node@22.15.18)(rollup@4.40.0)(typescript@5.8.3)(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(less@4.2.0)(lightningcss@1.29.2)(sass-embedded@1.88.0)(sass@1.83.0)(stylus@0.62.0)(terser@5.36.0)(tsx@4.19.4)(yaml@2.7.0)):
|
||||
dependencies:
|
||||
'@microsoft/api-extractor': 7.51.0(@types/node@22.15.18)
|
||||
'@rollup/pluginutils': 5.1.4(rollup@4.40.0)
|
||||
@@ -16738,7 +16738,7 @@ snapshots:
|
||||
compare-versions: 6.1.1
|
||||
debug: 4.4.0
|
||||
kolorist: 1.8.0
|
||||
local-pkg: 1.0.0
|
||||
local-pkg: 1.1.1
|
||||
magic-string: 0.30.17
|
||||
typescript: 5.8.3
|
||||
optionalDependencies:
|
||||
|
||||
@@ -8,7 +8,7 @@ use tokio::task::spawn_blocking;
|
||||
/// get the system proxy
|
||||
#[tauri::command]
|
||||
pub async fn get_sys_proxy() -> CmdResult<Mapping> {
|
||||
let current = spawn_blocking(move || Sysproxy::get_system_proxy())
|
||||
let current = spawn_blocking(Sysproxy::get_system_proxy)
|
||||
.await
|
||||
.map_err(|e| format!("Failed to spawn blocking task for sysproxy: {}", e))?
|
||||
.map_err(|e| format!("Failed to get system proxy: {}", e))?;
|
||||
@@ -27,7 +27,7 @@ pub async fn get_sys_proxy() -> CmdResult<Mapping> {
|
||||
/// get the system proxy
|
||||
#[tauri::command]
|
||||
pub async fn get_auto_proxy() -> CmdResult<Mapping> {
|
||||
let current = spawn_blocking(move || Autoproxy::get_auto_proxy())
|
||||
let current = spawn_blocking(Autoproxy::get_auto_proxy)
|
||||
.await
|
||||
.map_err(|e| format!("Failed to spawn blocking task for autoproxy: {}", e))?
|
||||
.map_err(|e| format!("Failed to get auto proxy: {}", e))?;
|
||||
|
||||
@@ -46,7 +46,7 @@ impl IClashTemp {
|
||||
map.insert("mixed-port".into(), 7897.into());
|
||||
map.insert("socks-port".into(), 7898.into());
|
||||
map.insert("port".into(), 7899.into());
|
||||
map.insert("log-level".into(), "warn".into());
|
||||
map.insert("log-level".into(), "warning".into());
|
||||
map.insert("allow-lan".into(), false.into());
|
||||
map.insert("ipv6".into(), true.into());
|
||||
map.insert("mode".into(), "rule".into());
|
||||
|
||||
@@ -259,11 +259,11 @@ impl PrfItem {
|
||||
|
||||
// 选择代理类型
|
||||
let proxy_type = if self_proxy {
|
||||
ProxyType::SelfProxy
|
||||
ProxyType::Localhost
|
||||
} else if with_proxy {
|
||||
ProxyType::SystemProxy
|
||||
ProxyType::System
|
||||
} else {
|
||||
ProxyType::NoProxy
|
||||
ProxyType::None
|
||||
};
|
||||
|
||||
// 使用网络管理器发送请求
|
||||
|
||||
@@ -128,9 +128,10 @@ impl WebDavClient {
|
||||
.build()?;
|
||||
|
||||
// 尝试检查目录是否存在,如果不存在尝试创建,但创建失败不报错
|
||||
if let Err(_) = client
|
||||
if client
|
||||
.list(dirs::BACKUP_DIR, reqwest_dav::Depth::Number(0))
|
||||
.await
|
||||
.is_err()
|
||||
{
|
||||
let _ = client.mkcol(dirs::BACKUP_DIR).await;
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ impl NotificationSystem {
|
||||
let system_guard = handle.notification_system.read();
|
||||
let is_emergency = system_guard
|
||||
.as_ref()
|
||||
.and_then(|sys| Some(*sys.emergency_mode.read()))
|
||||
.map(|sys| *sys.emergency_mode.read())
|
||||
.unwrap_or(false);
|
||||
|
||||
if is_emergency {
|
||||
@@ -110,7 +110,7 @@ impl NotificationSystem {
|
||||
&window,
|
||||
"verge://refresh-clash-config",
|
||||
"yes",
|
||||
&handle,
|
||||
handle,
|
||||
);
|
||||
}
|
||||
FrontendEvent::RefreshVerge => {
|
||||
@@ -118,7 +118,7 @@ impl NotificationSystem {
|
||||
&window,
|
||||
"verge://refresh-verge-config",
|
||||
"yes",
|
||||
&handle,
|
||||
handle,
|
||||
);
|
||||
}
|
||||
FrontendEvent::NoticeMessage {
|
||||
@@ -129,7 +129,7 @@ impl NotificationSystem {
|
||||
&window,
|
||||
"verge://notice-message",
|
||||
(status.clone(), message.clone()),
|
||||
&handle,
|
||||
handle,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -273,7 +273,7 @@ impl Default for Handle {
|
||||
impl Handle {
|
||||
pub fn global() -> &'static Handle {
|
||||
static HANDLE: OnceCell<Handle> = OnceCell::new();
|
||||
HANDLE.get_or_init(|| Handle::default())
|
||||
HANDLE.get_or_init(Handle::default)
|
||||
}
|
||||
|
||||
pub fn init(&self, app_handle: &AppHandle) {
|
||||
|
||||
@@ -538,7 +538,7 @@ pub async fn check_ipc_service_status() -> Result<JsonResponse> {
|
||||
json_response.msg,
|
||||
json_response.data.is_some()
|
||||
);
|
||||
return Ok(json_response);
|
||||
Ok(json_response)
|
||||
} else {
|
||||
// 尝试直接解析
|
||||
match serde_json::from_value::<JsonResponse>(data.clone()) {
|
||||
@@ -551,7 +551,7 @@ pub async fn check_ipc_service_status() -> Result<JsonResponse> {
|
||||
json_response.code,
|
||||
json_response.msg
|
||||
);
|
||||
return Ok(json_response);
|
||||
Ok(json_response)
|
||||
}
|
||||
Err(e) => {
|
||||
logging!(
|
||||
|
||||
@@ -385,10 +385,7 @@ impl Timer {
|
||||
}
|
||||
};
|
||||
|
||||
let profile = match items
|
||||
.iter()
|
||||
.find(|item| item.uid.as_ref().map(|u| u.as_str()) == Some(uid))
|
||||
{
|
||||
let profile = match items.iter().find(|item| item.uid.as_deref() == Some(uid)) {
|
||||
Some(p) => p,
|
||||
None => {
|
||||
logging!(warn, Type::Timer, "找不到对应的配置,uid={}", uid);
|
||||
@@ -441,7 +438,6 @@ impl Timer {
|
||||
}
|
||||
|
||||
/// Async task with better error handling and logging
|
||||
|
||||
async fn async_task(uid: String) {
|
||||
let task_start = std::time::Instant::now();
|
||||
logging!(info, Type::Timer, "Running timer task for profile: {}", uid);
|
||||
|
||||
@@ -442,7 +442,7 @@ impl Tray {
|
||||
traffic_result = stream.next() => {
|
||||
match traffic_result {
|
||||
Some(Ok(traffic)) => {
|
||||
if let Ok(speedrate_result) = tokio::time::timeout(
|
||||
if let Ok(Some(rate)) = tokio::time::timeout(
|
||||
std::time::Duration::from_millis(50),
|
||||
async {
|
||||
let guard = speed_rate.try_lock();
|
||||
@@ -457,12 +457,10 @@ impl Tray {
|
||||
}
|
||||
}
|
||||
).await {
|
||||
if let Some(rate) = speedrate_result {
|
||||
let _ = tokio::time::timeout(
|
||||
std::time::Duration::from_millis(100),
|
||||
async { let _ = Tray::global().update_icon(Some(rate)); }
|
||||
).await;
|
||||
}
|
||||
let _ = tokio::time::timeout(
|
||||
std::time::Duration::from_millis(100),
|
||||
async { let _ = Tray::global().update_icon(Some(rate)); }
|
||||
).await;
|
||||
}
|
||||
},
|
||||
Some(Err(e)) => {
|
||||
|
||||
@@ -271,7 +271,7 @@ impl Traffic {
|
||||
// 设置流超时控制
|
||||
let traffic_stream = ws_stream
|
||||
.take_while(|msg| {
|
||||
let continue_stream = matches!(msg, Ok(_));
|
||||
let continue_stream = msg.is_ok();
|
||||
async move { continue_stream }.boxed()
|
||||
})
|
||||
.filter_map(|msg| async move {
|
||||
|
||||
@@ -98,9 +98,9 @@ pub async fn test_delay(url: String) -> anyhow::Result<u32> {
|
||||
|
||||
// 如果是TUN模式,不使用代理,否则使用自身代理
|
||||
let proxy_type = if !tun_mode {
|
||||
ProxyType::SelfProxy
|
||||
ProxyType::Localhost
|
||||
} else {
|
||||
ProxyType::NoProxy
|
||||
ProxyType::None
|
||||
};
|
||||
|
||||
let user_agent = Some("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 Edg/120.0.0.0".to_string());
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use std::fmt::{self, write};
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum Type {
|
||||
|
||||
@@ -274,10 +274,10 @@ impl NetworkManager {
|
||||
}
|
||||
|
||||
match proxy_type {
|
||||
ProxyType::NoProxy => {
|
||||
ProxyType::None => {
|
||||
builder = builder.no_proxy();
|
||||
}
|
||||
ProxyType::SelfProxy => {
|
||||
ProxyType::Localhost => {
|
||||
let port = Config::verge()
|
||||
.latest()
|
||||
.verge_mixed_port
|
||||
@@ -295,7 +295,7 @@ impl NetworkManager {
|
||||
builder = builder.proxy(proxy);
|
||||
}
|
||||
}
|
||||
ProxyType::SystemProxy => {
|
||||
ProxyType::System => {
|
||||
use sysproxy::Sysproxy;
|
||||
|
||||
if let Ok(p @ Sysproxy { enable: true, .. }) = Sysproxy::get_system_proxy() {
|
||||
@@ -420,7 +420,7 @@ impl NetworkManager {
|
||||
/// 代理类型
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum ProxyType {
|
||||
NoProxy,
|
||||
SelfProxy,
|
||||
SystemProxy,
|
||||
None,
|
||||
Localhost,
|
||||
System,
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ const getLanguagePackMap = (key: string) =>
|
||||
* custom theme
|
||||
*/
|
||||
export const useCustomTheme = () => {
|
||||
const appWindow: WebviewWindow = getCurrentWebviewWindow();
|
||||
const appWindow: WebviewWindow = useMemo(() => getCurrentWebviewWindow(), []);
|
||||
const { verge } = useVerge();
|
||||
const { i18n } = useTranslation();
|
||||
const { theme_mode, theme_setting } = verge ?? {};
|
||||
@@ -37,45 +37,71 @@ export const useCustomTheme = () => {
|
||||
const setMode = useSetThemeMode();
|
||||
|
||||
useEffect(() => {
|
||||
const themeModeSetting = ["light", "dark", "system"].includes(theme_mode!)
|
||||
? theme_mode!
|
||||
: "light";
|
||||
if (theme_mode === "light" || theme_mode === "dark") {
|
||||
setMode(theme_mode);
|
||||
}
|
||||
}, [theme_mode, setMode]);
|
||||
|
||||
if (themeModeSetting !== "system") {
|
||||
setMode(themeModeSetting as 'light' | 'dark');
|
||||
useEffect(() => {
|
||||
if (theme_mode !== "system") {
|
||||
return;
|
||||
}
|
||||
|
||||
appWindow.theme().then((systemTheme: 'light' | 'dark' | null) => {
|
||||
if (systemTheme) {
|
||||
setMode(systemTheme);
|
||||
let isMounted = true;
|
||||
|
||||
const timerId = setTimeout(() => {
|
||||
if (!isMounted) return;
|
||||
appWindow.theme().then((systemTheme) => {
|
||||
if (isMounted && systemTheme) {
|
||||
setMode(systemTheme);
|
||||
}
|
||||
}).catch(err => {
|
||||
console.error("Failed to get initial system theme:", err);
|
||||
});
|
||||
}, 0);
|
||||
|
||||
const unlistenPromise = appWindow.onThemeChanged(({ payload }) => {
|
||||
if (isMounted) {
|
||||
setMode(payload);
|
||||
}
|
||||
});
|
||||
const unlisten = appWindow.onThemeChanged(({ payload }: { payload: 'light' | 'dark' }) => {
|
||||
setMode(payload);
|
||||
});
|
||||
|
||||
return () => {
|
||||
unlisten.then((fn: () => void) => fn());
|
||||
isMounted = false;
|
||||
clearTimeout(timerId);
|
||||
unlistenPromise.then((unlistenFn) => {
|
||||
if (typeof unlistenFn === 'function') {
|
||||
unlistenFn();
|
||||
}
|
||||
}).catch(err => {
|
||||
console.error("Failed to unlisten from theme changes:", err);
|
||||
});
|
||||
};
|
||||
}, [theme_mode, setMode, i18n, theme_setting, appWindow]);
|
||||
}, [theme_mode, appWindow, setMode]);
|
||||
|
||||
useEffect(() => {
|
||||
if (mode) {
|
||||
appWindow.setTheme(mode as TauriOsTheme).catch((err: any) => {
|
||||
console.error("Failed to set window theme:", err);
|
||||
if (theme_mode === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (theme_mode === "system") {
|
||||
appWindow.setTheme(null).catch((err) => {
|
||||
console.error("Failed to set window theme to follow system (setTheme(null)):", err);
|
||||
});
|
||||
} else if (mode) {
|
||||
appWindow.setTheme(mode as TauriOsTheme).catch((err) => {
|
||||
console.error(`Failed to set window theme to ${mode}:`, err);
|
||||
});
|
||||
}
|
||||
}, [mode, appWindow]);
|
||||
}, [mode, appWindow, theme_mode]);
|
||||
|
||||
const theme = useMemo(() => {
|
||||
const setting = theme_setting || {};
|
||||
const dt = mode === "light" ? defaultTheme : defaultDarkTheme;
|
||||
|
||||
let theme: MuiTheme;
|
||||
let muiTheme: MuiTheme;
|
||||
|
||||
try {
|
||||
theme = createTheme(
|
||||
muiTheme = createTheme(
|
||||
{
|
||||
breakpoints: {
|
||||
values: { xs: 0, sm: 650, md: 900, lg: 1200, xl: 1536 },
|
||||
@@ -98,7 +124,6 @@ export const useCustomTheme = () => {
|
||||
},
|
||||
shadows: Array(25).fill("none") as Shadows,
|
||||
typography: {
|
||||
// todo
|
||||
fontFamily: setting.font_family
|
||||
? `${setting.font_family}, ${dt.font_family}`
|
||||
: dt.font_family,
|
||||
@@ -106,9 +131,9 @@ export const useCustomTheme = () => {
|
||||
},
|
||||
getLanguagePackMap(i18n.language),
|
||||
);
|
||||
} catch {
|
||||
// fix #294
|
||||
theme = createTheme({
|
||||
} catch (e) {
|
||||
console.error("Error creating MUI theme, falling back to defaults:", e);
|
||||
muiTheme = createTheme({
|
||||
breakpoints: {
|
||||
values: { xs: 0, sm: 650, md: 900, lg: 1200, xl: 1536 },
|
||||
},
|
||||
@@ -126,38 +151,36 @@ export const useCustomTheme = () => {
|
||||
});
|
||||
}
|
||||
|
||||
// css
|
||||
const backgroundColor = mode === "light" ? "#ECECEC" : "#2e303d";
|
||||
const selectColor = mode === "light" ? "#f5f5f5" : "#d5d5d5";
|
||||
const scrollColor = mode === "light" ? "#90939980" : "#3E3E3Eee";
|
||||
const dividerColor =
|
||||
mode === "light" ? "rgba(0, 0, 0, 0.06)" : "rgba(255, 255, 255, 0.06)";
|
||||
|
||||
const rootEle = document.documentElement;
|
||||
rootEle.style.setProperty("--divider-color", dividerColor);
|
||||
rootEle.style.setProperty("--background-color", backgroundColor);
|
||||
rootEle.style.setProperty("--selection-color", selectColor);
|
||||
rootEle.style.setProperty("--scroller-color", scrollColor);
|
||||
rootEle.style.setProperty("--primary-main", theme.palette.primary.main);
|
||||
rootEle.style.setProperty(
|
||||
"--background-color-alpha",
|
||||
alpha(theme.palette.primary.main, 0.1),
|
||||
);
|
||||
if (rootEle) {
|
||||
const backgroundColor = mode === "light" ? "#ECECEC" : "#2e303d";
|
||||
const selectColor = mode === "light" ? "#f5f5f5" : "#d5d5d5";
|
||||
const scrollColor = mode === "light" ? "#90939980" : "#3E3E3Eee";
|
||||
const dividerColor =
|
||||
mode === "light" ? "rgba(0, 0, 0, 0.06)" : "rgba(255, 255, 255, 0.06)";
|
||||
|
||||
rootEle.style.setProperty("--divider-color", dividerColor);
|
||||
rootEle.style.setProperty("--background-color", backgroundColor);
|
||||
rootEle.style.setProperty("--selection-color", selectColor);
|
||||
rootEle.style.setProperty("--scroller-color", scrollColor);
|
||||
rootEle.style.setProperty("--primary-main", muiTheme.palette.primary.main);
|
||||
rootEle.style.setProperty(
|
||||
"--background-color-alpha",
|
||||
alpha(muiTheme.palette.primary.main, 0.1),
|
||||
);
|
||||
}
|
||||
// inject css
|
||||
let style = document.querySelector("style#verge-theme");
|
||||
if (!style) {
|
||||
style = document.createElement("style");
|
||||
style.id = "verge-theme";
|
||||
document.head.appendChild(style!);
|
||||
let styleElement = document.querySelector("style#verge-theme");
|
||||
if (!styleElement) {
|
||||
styleElement = document.createElement("style");
|
||||
styleElement.id = "verge-theme";
|
||||
document.head.appendChild(styleElement!);
|
||||
}
|
||||
if (style) {
|
||||
style.innerHTML = setting.css_injection || "";
|
||||
if (styleElement) {
|
||||
styleElement.innerHTML = setting.css_injection || "";
|
||||
}
|
||||
|
||||
// update svg icon
|
||||
const { palette } = theme;
|
||||
|
||||
const { palette } = muiTheme;
|
||||
setTimeout(() => {
|
||||
const dom = document.querySelector("#Gradient2");
|
||||
if (dom) {
|
||||
@@ -169,7 +192,7 @@ export const useCustomTheme = () => {
|
||||
}
|
||||
}, 0);
|
||||
|
||||
return theme;
|
||||
return muiTheme;
|
||||
}, [mode, theme_setting, i18n.language]);
|
||||
|
||||
return { theme };
|
||||
|
||||
@@ -201,7 +201,6 @@ const SettingClash = ({ onError }: Props) => {
|
||||
}
|
||||
>
|
||||
<GuardState
|
||||
// clash premium 2022.08.26 值为warn
|
||||
value={logLevel === "warn" ? "warning" : (logLevel ?? "info")}
|
||||
onCatch={onError}
|
||||
onFormat={(e: any) => e.target.value}
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
#
|
||||
# Copyright (C) 2022 OpenWrt.org
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=ivpu-firmware
|
||||
PKG_VERSION:=1.10.1
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL_FILE:=v$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=https://github.com/intel/linux-npu-driver/archive/refs/tags
|
||||
PKG_HASH:=a756de38cde7bd5a0402854d08429d271a33784835b80db3be672ade80570900
|
||||
PKG_BUILD_DIR:=$(BUILD_DIR)/linux-npu-driver-$(PKG_VERSION)
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/ivpu-firmware
|
||||
SECTION:=firmware
|
||||
CATEGORY:=Firmware
|
||||
TITLE:=Intel VPU firmware
|
||||
URL:=$(PKG_SOURCE_URL)
|
||||
DEPENDS:=
|
||||
endef
|
||||
|
||||
define Build/Compile
|
||||
true
|
||||
endef
|
||||
|
||||
define Package/ivpu-firmware/install
|
||||
$(INSTALL_DIR) $(1)/lib/firmware/intel/vpu
|
||||
$(INSTALL_DATA) \
|
||||
$(PKG_BUILD_DIR)/firmware/bin/*.bin \
|
||||
$(1)/lib/firmware/intel/vpu
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,ivpu-firmware))
|
||||
@@ -279,3 +279,15 @@ define Package/i915-firmware-gsc/install
|
||||
done
|
||||
endef
|
||||
$(eval $(call BuildPackage,i915-firmware-gsc))
|
||||
|
||||
Package/ivpu-firmware = $(call Package/firmware-default,Intel VPU firmware)
|
||||
define Package/ivpu-firmware/install
|
||||
$(INSTALL_DIR) $(1)/lib/firmware/intel/vpu
|
||||
$(INSTALL_DATA) $(PKG_BUILD_DIR)/intel/vpu/*.bin $(1)/lib/firmware/intel/vpu
|
||||
for t in `cd $(1)/lib/firmware/intel/vpu && ls vpu_*.bin | cut -d. -f1 | cut -d_ -f2 | sort | uniq`; do \
|
||||
source=`cd $(1)/lib/firmware && ls intel/vpu/vpu_$$$${t}_v*.bin | sort | tail -n1`; \
|
||||
target=$(1)/lib/firmware/vpu_$$$${t}.bin; \
|
||||
if [ -n "$$$$source" ]; then ln -sf $$$$source $$$$target; fi \
|
||||
done
|
||||
endef
|
||||
$(eval $(call BuildPackage,ivpu-firmware))
|
||||
|
||||
@@ -362,6 +362,38 @@ endef
|
||||
|
||||
$(eval $(call KernelPackage,drm-exec))
|
||||
|
||||
define KernelPackage/drm-dma-helper
|
||||
SUBMENU:=$(VIDEO_MENU)
|
||||
HIDDEN:=1
|
||||
TITLE:=GEM DMA helper functions
|
||||
DEPENDS:=@DISPLAY_SUPPORT +kmod-drm-kms-helper
|
||||
KCONFIG:=CONFIG_DRM_GEM_DMA_HELPER
|
||||
FILES:=$(LINUX_DIR)/drivers/gpu/drm/drm_dma_helper.ko
|
||||
AUTOLOAD:=$(call AutoProbe,drm_dma_helper)
|
||||
endef
|
||||
|
||||
define KernelPackage/drm-dma-helper/description
|
||||
GEM DMA helper functions.
|
||||
endef
|
||||
|
||||
$(eval $(call KernelPackage,drm-dma-helper))
|
||||
|
||||
define KernelPackage/drm-mipi-dbi
|
||||
SUBMENU:=$(VIDEO_MENU)
|
||||
HIDDEN:=1
|
||||
TITLE:=MIPI DBI helpers
|
||||
DEPENDS:=@DISPLAY_SUPPORT +kmod-backlight +kmod-drm-kms-helper
|
||||
KCONFIG:=CONFIG_DRM_MIPI_DBI
|
||||
FILES:=$(LINUX_DIR)/drivers/gpu/drm/drm_mipi_dbi.ko
|
||||
AUTOLOAD:=$(call AutoProbe,drm_mipi_dbi)
|
||||
endef
|
||||
|
||||
define KernelPackage/drm-mipi-dbi/description
|
||||
MIPI Display Bus Interface (DBI) LCD controller support.
|
||||
endef
|
||||
|
||||
$(eval $(call KernelPackage,drm-mipi-dbi))
|
||||
|
||||
define KernelPackage/drm-ttm
|
||||
SUBMENU:=$(VIDEO_MENU)
|
||||
TITLE:=GPU memory management subsystem
|
||||
@@ -514,7 +546,7 @@ $(eval $(call KernelPackage,drm-i915))
|
||||
define KernelPackage/drm-ivpu
|
||||
SUBMENU:=$(VIDEO_MENU)
|
||||
TITLE:=Intel VPU DRM support
|
||||
DEPENDS:=@TARGET_x86 +ivpu-firmware
|
||||
DEPENDS:=@TARGET_x86_64 +ivpu-firmware
|
||||
KCONFIG:=CONFIG_DRM_ACCEL_IVPU \
|
||||
CONFIG_DRM_ACCEL_HABANALABS=n \
|
||||
CONFIG_DRM_ACCEL_QAIC=n \
|
||||
@@ -637,6 +669,24 @@ endef
|
||||
|
||||
$(eval $(call KernelPackage,drm-panfrost))
|
||||
|
||||
define KernelPackage/drm-panel-mipi-dbi
|
||||
SUBMENU:=$(VIDEO_MENU)
|
||||
TITLE:=Generic MIPI DBI LCD panel
|
||||
DEPENDS:=+kmod-drm-mipi-dbi +kmod-drm-dma-helper
|
||||
KCONFIG:=CONFIG_DRM_PANEL_MIPI_DBI \
|
||||
CONFIG_DRM_FBDEV_EMULATION=y \
|
||||
CONFIG_DRM_FBDEV_OVERALLOC=100
|
||||
FILES:= \
|
||||
$(LINUX_DIR)/drivers/gpu/drm/tiny/panel-mipi-dbi.ko
|
||||
AUTOLOAD:=$(call AutoProbe,panel-mipi-dbi)
|
||||
endef
|
||||
|
||||
define KernelPackage/drm-panel-mipi-dbi/description
|
||||
Generic driver for MIPI Alliance Display Bus Interface
|
||||
endef
|
||||
|
||||
$(eval $(call KernelPackage,drm-panel-mipi-dbi))
|
||||
|
||||
define KernelPackage/drm-radeon
|
||||
SUBMENU:=$(VIDEO_MENU)
|
||||
TITLE:=Radeon DRM support
|
||||
|
||||
@@ -13,11 +13,14 @@ import (
|
||||
type RealityOptions struct {
|
||||
PublicKey string `proxy:"public-key"`
|
||||
ShortID string `proxy:"short-id"`
|
||||
|
||||
SupportX25519MLKEM768 bool `proxy:"support-x25519mlkem768"`
|
||||
}
|
||||
|
||||
func (o RealityOptions) Parse() (*tlsC.RealityConfig, error) {
|
||||
if o.PublicKey != "" {
|
||||
config := new(tlsC.RealityConfig)
|
||||
config.SupportX25519MLKEM768 = o.SupportX25519MLKEM768
|
||||
|
||||
const x25519ScalarSize = 32
|
||||
publicKey, err := base64.RawURLEncoding.DecodeString(o.PublicKey)
|
||||
|
||||
@@ -35,6 +35,8 @@ const RealityMaxShortIDLen = 8
|
||||
type RealityConfig struct {
|
||||
PublicKey *ecdh.PublicKey
|
||||
ShortID [RealityMaxShortIDLen]byte
|
||||
|
||||
SupportX25519MLKEM768 bool
|
||||
}
|
||||
|
||||
func GetRealityConn(ctx context.Context, conn net.Conn, fingerprint UClientHelloID, tlsConfig *tls.Config, realityConfig *RealityConfig) (net.Conn, error) {
|
||||
@@ -48,38 +50,36 @@ func GetRealityConn(ctx context.Context, conn net.Conn, fingerprint UClientHello
|
||||
SessionTicketsDisabled: true,
|
||||
VerifyPeerCertificate: verifier.VerifyPeerCertificate,
|
||||
}
|
||||
clientID := utls.ClientHelloID{
|
||||
Client: fingerprint.Client,
|
||||
Version: fingerprint.Version,
|
||||
Seed: fingerprint.Seed,
|
||||
}
|
||||
uConn := utls.UClient(conn, uConfig, clientID)
|
||||
|
||||
uConn := utls.UClient(conn, uConfig, fingerprint)
|
||||
verifier.UConn = uConn
|
||||
err := uConn.BuildHandshakeState()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// ------for X25519MLKEM768 does not work properly with reality-------
|
||||
// Iterate over extensions and check
|
||||
for _, extension := range uConn.Extensions {
|
||||
if ce, ok := extension.(*utls.SupportedCurvesExtension); ok {
|
||||
ce.Curves = slices.DeleteFunc(ce.Curves, func(curveID utls.CurveID) bool {
|
||||
return curveID == utls.X25519MLKEM768
|
||||
})
|
||||
if !realityConfig.SupportX25519MLKEM768 {
|
||||
// ------for X25519MLKEM768 does not work properly with the old reality server-------
|
||||
// Iterate over extensions and check
|
||||
for _, extension := range uConn.Extensions {
|
||||
if ce, ok := extension.(*utls.SupportedCurvesExtension); ok {
|
||||
ce.Curves = slices.DeleteFunc(ce.Curves, func(curveID utls.CurveID) bool {
|
||||
return curveID == utls.X25519MLKEM768
|
||||
})
|
||||
}
|
||||
if ks, ok := extension.(*utls.KeyShareExtension); ok {
|
||||
ks.KeyShares = slices.DeleteFunc(ks.KeyShares, func(share utls.KeyShare) bool {
|
||||
return share.Group == utls.X25519MLKEM768
|
||||
})
|
||||
}
|
||||
}
|
||||
if ks, ok := extension.(*utls.KeyShareExtension); ok {
|
||||
ks.KeyShares = slices.DeleteFunc(ks.KeyShares, func(share utls.KeyShare) bool {
|
||||
return share.Group == utls.X25519MLKEM768
|
||||
})
|
||||
// Rebuild the client hello
|
||||
err = uConn.BuildHandshakeState()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// --------------------------------------------------------------------
|
||||
}
|
||||
// Rebuild the client hello
|
||||
err = uConn.BuildHandshakeState()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
hello := uConn.HandshakeState.Hello
|
||||
rawSessionID := hello.Raw[39 : 39+32] // the location of session ID
|
||||
@@ -144,7 +144,7 @@ func GetRealityConn(ctx context.Context, conn net.Conn, fingerprint UClientHello
|
||||
log.Debugln("REALITY Authentication: %v, AEAD: %T", verifier.verified, aeadCipher)
|
||||
|
||||
if !verifier.verified {
|
||||
go realityClientFallback(uConn, uConfig.ServerName, clientID)
|
||||
go realityClientFallback(uConn, uConfig.ServerName, fingerprint)
|
||||
return nil, errors.New("REALITY authentication failed")
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -36,7 +36,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-20250503140532-decbcfccbfdf
|
||||
github.com/metacubex/utls v1.7.0-alpha.3
|
||||
github.com/metacubex/utls v1.7.3
|
||||
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
|
||||
|
||||
+2
-2
@@ -138,8 +138,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-20250503140532-decbcfccbfdf h1:LwID1wz4tzypidd412dd4dC1H0m1TgRCQ/XvRvMJDFM=
|
||||
github.com/metacubex/tfo-go v0.0.0-20250503140532-decbcfccbfdf/go.mod h1:l9oLnLoEXyGZ5RVLsh7QCC5XsouTUyKk4F2nLm2DHLw=
|
||||
github.com/metacubex/utls v1.7.0-alpha.3 h1:cp1cEMUnoifiWrGHRzo+nCwPRveN9yPD8QaRFmfcYxA=
|
||||
github.com/metacubex/utls v1.7.0-alpha.3/go.mod h1:oknYT0qTOwE4hjPmZOEpzVdefnW7bAdGLvZcqmk4TLU=
|
||||
github.com/metacubex/utls v1.7.3 h1:yDcMEWojFh+t8rU9X0HPcZDPAoFze/rIIyssqivzj8A=
|
||||
github.com/metacubex/utls v1.7.3/go.mod h1:oknYT0qTOwE4hjPmZOEpzVdefnW7bAdGLvZcqmk4TLU=
|
||||
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=
|
||||
|
||||
+3
-3
@@ -31,7 +31,7 @@ func (l *LogLevel) UnmarshalYAML(unmarshal func(any) error) error {
|
||||
unmarshal(&tp)
|
||||
level, exist := LogLevelMapping[strings.ToLower(tp)]
|
||||
if !exist {
|
||||
return errors.New("invalid mode")
|
||||
return errors.New("invalid log-level")
|
||||
}
|
||||
*l = level
|
||||
return nil
|
||||
@@ -43,7 +43,7 @@ func (l *LogLevel) UnmarshalJSON(data []byte) error {
|
||||
json.Unmarshal(data, &tp)
|
||||
level, exist := LogLevelMapping[strings.ToLower(tp)]
|
||||
if !exist {
|
||||
return errors.New("invalid mode")
|
||||
return errors.New("invalid log-level")
|
||||
}
|
||||
*l = level
|
||||
return nil
|
||||
@@ -53,7 +53,7 @@ func (l *LogLevel) UnmarshalJSON(data []byte) error {
|
||||
func (l *LogLevel) UnmarshalText(data []byte) error {
|
||||
level, exist := LogLevelMapping[strings.ToLower(string(data))]
|
||||
if !exist {
|
||||
return errors.New("invalid mode")
|
||||
return errors.New("invalid log-level")
|
||||
}
|
||||
*l = level
|
||||
return nil
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-ddns-go
|
||||
PKG_VERSION:=1.5.2
|
||||
PKG_RELEASE:=20250514
|
||||
PKG_VERSION:=1.5.3
|
||||
PKG_RELEASE:=20250515
|
||||
|
||||
PKG_MAINTAINER:=sirpdboy <herboy2008@gmail.com>
|
||||
PKG_CONFIG_DEPENDS:=
|
||||
|
||||
+30
-13
@@ -7,17 +7,33 @@
|
||||
'require form';
|
||||
'require poll';
|
||||
|
||||
function checkProcess() {
|
||||
return fs.exec('/bin/pidof', ['ddns-go']).then(function(res) {
|
||||
return {
|
||||
running: res.code === 0,
|
||||
pid: res.code === 0 ? res.stdout.trim() : null
|
||||
};
|
||||
}).catch(function() {
|
||||
return { running: false, pid: null };
|
||||
});
|
||||
}
|
||||
|
||||
async function checkProcess() {
|
||||
// 先尝试用 pidof
|
||||
try {
|
||||
const pidofRes = await fs.exec('/bin/pidof', ['ddns-go']);
|
||||
if (pidofRes.code === 0) {
|
||||
return {
|
||||
running: true,
|
||||
pid: pidofRes.stdout.trim()
|
||||
};
|
||||
}
|
||||
} catch (err) {
|
||||
// pidof 失败,继续尝试 ps
|
||||
}
|
||||
|
||||
// 回退到 ps
|
||||
try {
|
||||
const psRes = await fs.exec('/bin/ps', ['-C', 'ddns-go', '-o', 'pid=']);
|
||||
const pid = psRes.stdout.trim();
|
||||
return {
|
||||
running: pid !== '',
|
||||
pid: pid || null
|
||||
};
|
||||
} catch (err) {
|
||||
return { running: false, pid: null };
|
||||
}
|
||||
}
|
||||
function renderStatus(isRunning, listen_port, noweb) {
|
||||
var statusText = isRunning ? _('RUNNING') : _('NOT RUNNING');
|
||||
var color = isRunning ? 'green' : 'red';
|
||||
@@ -52,8 +68,8 @@ return view.extend({
|
||||
|
||||
render: function(data) {
|
||||
var m, s, o;
|
||||
var listen_port = (uci.get(data[0], 'basic', 'port') || '[::]:9876').split(':').slice(-1)[0];
|
||||
var noweb = uci.get(data[0], 'basic', 'noweb') || '0';
|
||||
var listen_port = (uci.get('ddns-go', 'config', 'port') || '[::]:9876').split(':').slice(-1)[0];
|
||||
var noweb = uci.get('ddns-go', 'config', 'noweb') || '0';
|
||||
|
||||
m = new form.Map('ddns-go', _('DDNS-GO'),
|
||||
_('DDNS-GO automatically obtains your public IPv4 or IPv6 address and resolves it to the corresponding domain name service.'));
|
||||
@@ -63,7 +79,7 @@ return view.extend({
|
||||
s.anonymous = true;
|
||||
s.render = function() {
|
||||
var statusView = E('p', { id: 'control_status' },
|
||||
'<span class="spinning">⏳</span> ' + _('Checking status...'));
|
||||
'<span class="spinning"></span> ' + _('Checking status...'));
|
||||
|
||||
var pollInterval = poll.add(function() {
|
||||
return checkProcess()
|
||||
@@ -122,6 +138,7 @@ return view.extend({
|
||||
|
||||
o = s.option(form.Flag, 'noweb', _('Do not start web services'));
|
||||
o.default = '0';
|
||||
o.rmempty = false;
|
||||
|
||||
o = s.option(form.Value, 'delay', _('Delayed Start (seconds)'));
|
||||
o.default = '60';
|
||||
|
||||
+46
-33
@@ -9,58 +9,71 @@
|
||||
'require poll';
|
||||
|
||||
return view.extend({
|
||||
//handleSaveApply: null,
|
||||
//handleSave: null,
|
||||
//handleReset: null,
|
||||
load: function() {
|
||||
return uci.load('ddns-go');
|
||||
},
|
||||
|
||||
checkRunning: function() {
|
||||
return fs.exec('/bin/pidof', ['ddns-go']).then(function(pidRes) {
|
||||
if (pidRes.code === 0) return { isRunning: true };
|
||||
return fs.exec('/bin/ash', ['-c', 'ps | grep -q "[d]dns-go"']).then(function(grepRes) {
|
||||
return { isRunning: grepRes.code === 0 };
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return fs.exec('/bin/pidof', ['ddns-go']).then(function(res) {
|
||||
var isRunning = res.code === 0;
|
||||
var port = uci.get('ddns-go', 'basic', 'port') || '[::]:9876';
|
||||
var noweb = uci.get('ddns-go', 'basic', 'noweb') || '0';
|
||||
var self = this;
|
||||
|
||||
return this.checkRunning().then(function(checkResult) {
|
||||
var isRunning = checkResult.isRunning;
|
||||
var port = uci.get('ddns-go', 'config', 'port') || '[::]:9876';
|
||||
var noweb = uci.get('ddns-go', 'config', 'noweb') ;
|
||||
port = port.split(':').pop();
|
||||
|
||||
var container = E('div');
|
||||
|
||||
var status = E('div', { style: 'text-align: center; padding: 2em;' }, [
|
||||
E('img', {
|
||||
src: 'data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMjQiIGhlaWdodD0iMTAyNCIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCI+PHBhdGggZmlsbD0iI2RmMDAwMCIgZD0iTTk0Mi40MjEgMjM0LjYyNGw4MC44MTEtODAuODExLTE1My4wNDUtMTUzLjA0NS04MC44MTEgODAuODExYy03OS45NTctNTEuNjI3LTE3NS4xNDctODEuNTc5LTI3Ny4zNzYtODEuNTc5LTI4Mi43NTIgMC01MTIgMjI5LjI0OC01MTIgNTEyIDAgMTAyLjIyOSAyOS45NTIgMTk3LjQxOSA4MS41NzkgMjc3LjM3NmwtODAuODExIDgwLjgxMSAxNTMuMDQ1IDE1My4wNDUgODAuODExLTgwLjgxMWM3OS45NTcgNTEuNjI3IDE3NS4xNDcgODEuNTc5IDI3Ny4zNzYgODEuNTc5IDI4Mi43NTIgMCA1MTItMjI5LjI0OCA1MTItNTEyIDAtMTAyLjIyOS0yOS45NTItMTk3LjQxOS04MS41NzktMjc3LjM3NnpNMTk0Ljk0NCA1MTJjMC0xNzUuMTA0IDE0MS45NTItMzE3LjA1NiAzMTcuMDU2LTMxNy4wNTYgNDggMCA5My40ODMgMTAuNjY3IDEzNC4yMjkgMjkuNzgxbC00MjEuNTQ3IDQyMS41NDdjLTE5LjA3Mi00MC43ODktMjkuNzM5LTg2LjI3Mi0yOS43MzktMTM0LjI3MnpNNTEyIDgyOS4wNTZjLTQ4IDAtOTMuNDgzLTEwLjY2Ny0xMzQuMjI5LTI5Ljc4MWw0MjEuNTQ3LTQyMS41NDdjMTkuMDcyIDQwLjc4OSAyOS43ODEgODYuMjcyIDI5Ljc4MSAxMzQuMjI5LTAuMDQzIDE3NS4xNDctMTQxLjk5NSAzMTcuMDk5LTMxNy4wOTkgMzE3LjA5OXoiLz48L3N2Zz4=',
|
||||
style: 'width: 100px; height: 100px; margin-bottom: 1em;'
|
||||
}),
|
||||
E('h2', {}, _('DDNS-GO Service Not Running')),
|
||||
E('p', {}, _('Please enable the DDNS-GO service'))
|
||||
]);
|
||||
|
||||
|
||||
if (isRunning && noweb !== '1') {
|
||||
console.log('Debug: isRunning=' + isRunning + ', noweb=' + noweb + ', port=' + port);
|
||||
if (!isRunning || noweb === '1') {
|
||||
if (!isRunning) {
|
||||
var message = _('DDNS-GO Service Not Running');
|
||||
}
|
||||
if (noweb === '1') {
|
||||
var message = _('DDNS-GO Web Interface Disabled');
|
||||
}
|
||||
|
||||
container.appendChild(E('div', {
|
||||
style: 'text-align: center; padding: 2em;'
|
||||
}, [
|
||||
E('img', {
|
||||
src: 'data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMjQiIGhlaWdodD0iMTAyNCIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCI+PHBhdGggZmlsbD0iI2RmMDAwMCIgZD0iTTk0Mi40MjEgMjM0LjYyNGw4MC44MTEtODAuODExLTE1My4wNDUtMTUzLjA0NS04MC44MTEgODAuODExYy03OS45NTctNTEuNjI3LTE3NS4xNDctODEuNTc5LTI3Ny4zNzYtODEuNTc5LTI4Mi43NTIgMC01MTIgMjI5LjI0OC01MTIgNTEyIDAgMTAyLjIyOSAyOS45NTIgMTk3LjQxOSA4MS41NzkgMjc3LjM3NmwtODAuODExIDgwLjgxMSAxNTMuMDQ1IDE1My4wNDUgODAuODExLTgwLjgxMWM3OS45NTcgNTEuNjI3IDE3NS4xNDcgODEuNTc5IDI3Ny4zNzYgODEuNTc5IDI4Mi43NTIgMCA1MTItMjI5LjI0OCA1MTItNTEyIDAtMTAyLjIyOS0yOS45NTItMTk3LjQxOS04MS41NzktMjc3LjM3NnpNMTk0Ljk0NCA1MTJjMC0xNzUuMTA0IDE0MS45NTItMzE3LjA1NiAzMTcuMDU2LTMxNy4wNTYgNDggMCA5My40ODMgMTAuNjY3IDEzNC4yMjkgMjkuNzgxbC00MjEuNTQ3IDQyMS41NDdjLTE5LjA3Mi00MC43ODktMjkuNzM5LTg2LjI3Mi0yOS43MzktMTM0LjI3MnpNNTEyIDgyOS4wNTZjLTQ4IDAtOTMuNDgzLTEwLjY2Ny0xMzQuMjI5LTI5Ljc4MWw0MjEuNTQ3LTQyMS41NDdjMTkuMDcyIDQwLjc4OSAyOS43ODEgODYuMjcyIDI5Ljc4MSAxMzQuMjI5LTAuMDQzIDE3NS4xNDctMTQxLjk5NSAzMTcuMDk5LTMxNy4wOTkgMzE3LjA5OXoiLz48L3N2Zz4=',
|
||||
style: 'width: 100px; height: 100px; margin-bottom: 1em;'
|
||||
}),
|
||||
E('h2', {}, message)
|
||||
]));
|
||||
} else {
|
||||
var iframe = E('iframe', {
|
||||
src: window.location.origin + ':' + port,
|
||||
style: 'width: 100%; min-height: 100vh; border: none; border-radius: 3px;'
|
||||
src: window.location.protocol + '//' + window.location.hostname + ':' + port,
|
||||
style: 'width: 100%; min-height: 100vh; border: none;'
|
||||
});
|
||||
container.appendChild(iframe);
|
||||
} else
|
||||
{
|
||||
container.appendChild(status);
|
||||
}
|
||||
}
|
||||
|
||||
// Add polling to refresh status
|
||||
poll.add(function() {
|
||||
return fs.exec('/bin/pidof', ['ddns-go']).then(function(res) {
|
||||
var newIsRunning = res.code === 0;
|
||||
if (newIsRunning !== isRunning) {
|
||||
return self.checkRunning().then(function(checkResult) {
|
||||
var newStatus = checkResult.isRunning;
|
||||
if (newStatus !== isRunning) {
|
||||
window.location.reload();
|
||||
}
|
||||
});
|
||||
}, 5);
|
||||
|
||||
poll.start();
|
||||
|
||||
|
||||
return container;
|
||||
}).catch(function(err) {
|
||||
return E('div', { class: 'error' }, _('Error checking DDNS-Go status: ') + err.message);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
handleSaveApply: null,
|
||||
handleSave: null,
|
||||
handleReset: null
|
||||
});
|
||||
@@ -43,8 +43,8 @@ msgstr "运行中"
|
||||
msgid "DDNS-GO Service Not Running"
|
||||
msgstr "DDNS-GO服务未启用"
|
||||
|
||||
msgid "Please enable the DDNS-GO service"
|
||||
msgstr "请将DDNS-GO服务启用"
|
||||
msgid "DDNS-GO Web Interface Disabled"
|
||||
msgstr "DDNS-GO WEB服务禁用"
|
||||
|
||||
msgid "Open Web Interface"
|
||||
msgstr "打开Web界面"
|
||||
|
||||
@@ -11,13 +11,13 @@ LUCI_DEPENDS:=+curl +opkg +luci-base +tar +libuci-lua +mount-utils +luci-lib-tas
|
||||
LUCI_EXTRA_DEPENDS:=luci-lib-taskd (>=1.0.19)
|
||||
LUCI_PKGARCH:=all
|
||||
|
||||
PKG_VERSION:=0.1.27-4
|
||||
PKG_VERSION:=0.1.28-2
|
||||
# PKG_RELEASE MUST be empty for luci.mk
|
||||
PKG_RELEASE:=
|
||||
|
||||
ISTORE_UI_VERSION:=0.1.27
|
||||
ISTORE_UI_RELEASE:=2
|
||||
PKG_HASH:=7fb8e9983dd33b14c43de3caf6a6121df0727e0adac6c666354e0d8a0cffa0b8
|
||||
ISTORE_UI_VERSION:=0.1.28
|
||||
ISTORE_UI_RELEASE:=1
|
||||
PKG_HASH:=c45d7552a4c52fdd2f5a2a9bbc94d14a66c5af187ef8a117a3e08b6a9a4b7dbf
|
||||
|
||||
PKG_SOURCE_URL_FILE:=v$(ISTORE_UI_VERSION)-$(ISTORE_UI_RELEASE).tar.gz
|
||||
PKG_SOURCE:=istore-ui-$(PKG_SOURCE_URL_FILE)
|
||||
|
||||
@@ -2,6 +2,7 @@ module("luci.controller.store", package.seeall)
|
||||
|
||||
local myopkg = "is-opkg"
|
||||
local is_backup = "/usr/libexec/istore/backup"
|
||||
local is_overlay_backup = "/usr/libexec/istore/overlay-backup"
|
||||
local page_index = {"admin", "store", "pages"}
|
||||
|
||||
function index()
|
||||
@@ -44,16 +45,18 @@ function index()
|
||||
store_api(action, false)
|
||||
end
|
||||
|
||||
-- backup
|
||||
-- istore backup
|
||||
if nixio.fs.access("/usr/libexec/istore/backup") then
|
||||
entry({"admin", "store", "get_support_backup_features"}, call("get_support_backup_features"))
|
||||
entry({"admin", "store", "light_backup"}, post("light_backup"))
|
||||
entry({"admin", "store", "get_light_backup_file"}, call("get_light_backup_file"))
|
||||
entry({"admin", "store", "local_backup"}, post("local_backup"))
|
||||
entry({"admin", "store", "light_restore"}, post("light_restore"))
|
||||
entry({"admin", "store", "local_restore"}, post("local_restore"))
|
||||
entry({"admin", "store", "get_backup_app_list_file_path"}, call("get_backup_app_list_file_path"))
|
||||
entry({"admin", "store", "get_backup_app_list"}, call("get_backup_app_list"))
|
||||
end
|
||||
if nixio.fs.access("/usr/libexec/istore/backup") or nixio.fs.access("/usr/libexec/istore/overlay-backup") then
|
||||
entry({"admin", "store", "local_backup"}, post("local_backup"))
|
||||
entry({"admin", "store", "local_restore"}, post("local_restore"))
|
||||
entry({"admin", "store", "get_available_backup_file_list"}, call("get_available_backup_file_list"))
|
||||
entry({"admin", "store", "set_local_backup_dir_path"}, post("set_local_backup_dir_path"))
|
||||
entry({"admin", "store", "get_local_backup_dir_path"}, call("get_local_backup_dir_path"))
|
||||
@@ -160,6 +163,9 @@ function store_index()
|
||||
if fs.access("/usr/libexec/istore/backup") then
|
||||
features[#features+1] = "backup"
|
||||
end
|
||||
if luci.sys.call(is_overlay_backup .. " supports_overlay_backup >/dev/null 2>&1") == 0 then
|
||||
features[#features+1] = "overlay"
|
||||
end
|
||||
if luci.sys.call("which docker >/dev/null 2>&1") == 0 then
|
||||
features[#features+1] = "docker"
|
||||
end
|
||||
@@ -682,18 +688,27 @@ function local_backup()
|
||||
local code, out, err, ret
|
||||
local error_ret
|
||||
local path = luci.http.formvalue("path")
|
||||
local type = luci.http.formvalue("type") or "istore"
|
||||
if path ~= "" then
|
||||
-- judge path
|
||||
local fs = require "nixio.fs"
|
||||
fs.mkdirr(path)
|
||||
code,out,err = is_exec("findmnt -T " .. path .. " -o TARGET|sed -n 2p")
|
||||
if out:gsub("[\r\n]", "") == "/" or out:gsub("[\r\n]", "") == "/tmp" then
|
||||
local mp = out:gsub("[\r\n]", "")
|
||||
if mp == "/" or mp == "/tmp" then
|
||||
-- error
|
||||
error_ret = {code = 500, stderr = "Path Error,Can not be / or tmp."}
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(error_ret)
|
||||
luci.http.write_json(error_ret)
|
||||
elseif type == "overlay" and ( mp == "/overlay" or mp == "/ext_overlay" ) then
|
||||
-- error
|
||||
error_ret = {code = 500, stderr = "Path Error,Can not be /overlay or /ext_overlay."}
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(error_ret)
|
||||
else
|
||||
-- update local backup path
|
||||
update_local_backup_path(path)
|
||||
code,out,err = _action(is_backup, "backup", path)
|
||||
code,out,err = _action(type == "overlay" and is_overlay_backup or is_backup, "backup", path)
|
||||
ret = {
|
||||
code = code,
|
||||
stdout = out,
|
||||
@@ -761,9 +776,10 @@ end
|
||||
-- post local_restore
|
||||
function local_restore()
|
||||
local path = luci.http.formvalue("path")
|
||||
local type = luci.http.formvalue("type") or "istore"
|
||||
local code, out, err, ret
|
||||
if path ~= "" then
|
||||
code,out,err = _action(is_backup, "restore", path)
|
||||
code,out,err = _action(type == "overlay" and is_overlay_backup or is_backup, "restore", path)
|
||||
ret = {
|
||||
code = code,
|
||||
stdout = out,
|
||||
@@ -821,12 +837,13 @@ function get_available_backup_file_list()
|
||||
local error_ret = {code = 500, msg = "Unknown"}
|
||||
local success_ret = {code = 200,msg = "Unknown"}
|
||||
local path = luci.http.formvalue("path")
|
||||
local type = luci.http.formvalue("type") or "istore"
|
||||
local r,o,e
|
||||
|
||||
if path ~= "" then
|
||||
-- update local backup path
|
||||
update_local_backup_path(path)
|
||||
r,o,e = is_exec(is_backup .. " get_available_backup_file_list " .. luci.util.shellquote(path))
|
||||
r,o,e = is_exec((type == "overlay" and is_overlay_backup or is_backup) .. " get_available_backup_file_list " .. luci.util.shellquote(path))
|
||||
if r ~= 0 then
|
||||
error_ret.msg = e
|
||||
luci.http.prepare_content("application/json")
|
||||
|
||||
@@ -170,7 +170,7 @@ backup() {
|
||||
ipk_build ${pkg_name} $BACKUP_PATH/backup_istore_$date
|
||||
done
|
||||
|
||||
# 5. create tar.gz file,and remove fir
|
||||
# 5. create tar.gz file,and remove dir
|
||||
cd $BACKUP_PATH
|
||||
echo "write backup file to $BACKUP_PATH/backup_istore_$date.backup.tar.gz"
|
||||
tar -czf $BACKUP_PATH/backup_istore_$date.backup.tar.gz backup_istore_$date
|
||||
@@ -246,10 +246,10 @@ get_backup_app_list() {
|
||||
}
|
||||
|
||||
get_available_backup_file_list() {
|
||||
local backup_file
|
||||
if [ -n "$1" ]; then
|
||||
for backup_file in `ls $1/*.backup.tar.gz`; do
|
||||
filename=${backup_file##*/}
|
||||
echo "${filename}"
|
||||
for backup_file in `cd $1 && ls backup_istore_*.backup.tar.gz`; do
|
||||
echo "${backup_file}"
|
||||
done
|
||||
else
|
||||
echo "input backup path is null"
|
||||
|
||||
@@ -0,0 +1,177 @@
|
||||
#!/bin/sh
|
||||
|
||||
TMP_SELF_COPY=/var/run/cloned-overlay-backup
|
||||
|
||||
action=${1}
|
||||
shift
|
||||
|
||||
has_overlay() {
|
||||
[ -d "/overlay/upper" ] || return 1
|
||||
[ "overlay" = "$(/bin/mount | awk '($3 ~ /^\/$/) && ($5 !~ /rootfs/) { print $5 }')" ] || return 1
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
has_ext_overlay() {
|
||||
[ -d "/ext_overlay/upper" ] || return 1
|
||||
grep '^overlayfs:/overlay / ' /proc/mounts | grep -Fq 'upperdir=/ext_overlay/upper' || return 1
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
backup() {
|
||||
if ! has_overlay; then
|
||||
echo "only supports squashfs firmware"
|
||||
exit 1
|
||||
fi
|
||||
if [ -z "$1" ]; then
|
||||
echo "input backup path is null"
|
||||
exit 1
|
||||
fi
|
||||
local BACKUP_PATH="$1"
|
||||
|
||||
if echo "$BACKUP_PATH" | grep -q -e '^/overlay/upper' -e '^/ext_overlay/upper' ; then
|
||||
echo "can not backup to /overlay/upper, /ext_overlay/upper"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -d "${BACKUP_PATH}" ] && ! mkdir -p "${BACKUP_PATH}" ; then
|
||||
echo "backup path does not exist and can not be create"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
local realpath="$(cd "${BACKUP_PATH}"; pwd -P)"
|
||||
if [ -z "$realpath" ]; then
|
||||
echo "cannot get absolute path of ${BACKUP_PATH}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
local mountpoint=$(findmnt -T $realpath -o TARGET | sed -n 2p)
|
||||
# while read -r; do
|
||||
# if [[ "x$realpath" == "x$REPLY" || "x${realpath#$REPLY/}" != "x$realpath" ]]; then
|
||||
# mountpoint="$REPLY"
|
||||
# break
|
||||
# fi
|
||||
# done < <(
|
||||
# cat /proc/mounts | grep -v '^overlay ' | awk 'NR>1 {print $2}' | grep -v '^/$' | \
|
||||
# sort -u | \
|
||||
# while read -r; do printf "%b\n" "$REPLY" ; done | \
|
||||
# awk '{print length, $0}' | sort -nr | cut -d' ' -f2-
|
||||
# )
|
||||
|
||||
if [ "/" = "$mountpoint" ]; then
|
||||
echo "can not backup to /"
|
||||
exit 1
|
||||
else
|
||||
echo "found mount point $mountpoint"
|
||||
fi
|
||||
|
||||
local tar_extra_args=
|
||||
if has_ext_overlay; then
|
||||
tar_extra_args="$tar_extra_args ext_overlay/upper"
|
||||
fi
|
||||
|
||||
local hostname=$(cat /proc/sys/kernel/hostname)
|
||||
local fwver=$(. /etc/openwrt_release; echo $DISTRIB_ID-$DISTRIB_RELEASE)
|
||||
|
||||
local date=$(date +%Y-%m%d-%H%M)
|
||||
local backup_name="backup_overlay_${hostname}_${fwver}_${date}.overlay.tar.gz"
|
||||
local backup_full_path="$BACKUP_PATH/$backup_name"
|
||||
echo "writing backup to $backup_full_path"
|
||||
if tar -C / -cz overlay/upper $tar_extra_args > "$backup_full_path" ; then
|
||||
sync "$BACKUP_PATH"
|
||||
echo "backup success"
|
||||
return 0
|
||||
else
|
||||
rm -f "$backup_full_path"
|
||||
echo "backup failed"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
restore() {
|
||||
if ! has_overlay; then
|
||||
echo "only supports squashfs firmware"
|
||||
exit 1
|
||||
fi
|
||||
if [ -z "$1" ]; then
|
||||
echo "input backup path is null"
|
||||
exit 1
|
||||
fi
|
||||
local BACKUP_PATH_FILE="$1"
|
||||
|
||||
if [ ! -f "${BACKUP_PATH_FILE}" ]; then
|
||||
echo "invalid backup file, can not restore"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
local tar_extra_args=
|
||||
if has_ext_overlay; then
|
||||
tar_extra_args="$tar_extra_args ext_overlay/upper"
|
||||
fi
|
||||
|
||||
sync /
|
||||
echo "restoring from ${BACKUP_PATH_FILE}"
|
||||
if tar -C / -xz overlay/upper $tar_extra_args < "${BACKUP_PATH_FILE}" ; then
|
||||
sync /overlay /ext_overlay
|
||||
echo "restore success"
|
||||
echo "schedule to restart after 5 seconds!"
|
||||
/etc/init.d/tasks task_add reboot 'reboot -d 5'
|
||||
return 0
|
||||
else
|
||||
echo "restore failed"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
supports_overlay_backup() {
|
||||
has_overlay || return 1
|
||||
echo "overlay"
|
||||
has_ext_overlay && echo "ext_overlay"
|
||||
return 0
|
||||
}
|
||||
|
||||
get_backup_file_list() {
|
||||
local backup_file
|
||||
if [ -n "$1" ]; then
|
||||
for backup_file in `cd $1 && ls backup_overlay_*.overlay.tar.gz`; do
|
||||
echo "${backup_file}"
|
||||
done
|
||||
else
|
||||
echo "input backup path is null"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
usage() {
|
||||
echo "usage: overlay-backup sub-command [arguments...]"
|
||||
echo "where sub-command is one of:"
|
||||
echo " backup [dir] Backup all installed package(s) to [directory]"
|
||||
echo " restore [dir] Restore package(s) by [directory]"
|
||||
echo " supports_overlay_backup check system supports overlay backup"
|
||||
echo " get_backup_file_list [dir] get local available backup file list in [dir]"
|
||||
}
|
||||
|
||||
case $action in
|
||||
"supports_overlay_backup")
|
||||
supports_overlay_backup
|
||||
;;
|
||||
"backup")
|
||||
backup "$@"
|
||||
;;
|
||||
"restore")
|
||||
if [ "$0" = "$TMP_SELF_COPY" ]; then
|
||||
restore "$@"
|
||||
else
|
||||
echo "copy self $0 to $TMP_SELF_COPY when restore"
|
||||
cp -af "$0" "$TMP_SELF_COPY"
|
||||
exec "$TMP_SELF_COPY" restore "$@"
|
||||
fi
|
||||
;;
|
||||
"get_available_backup_file_list")
|
||||
get_backup_file_list "$@"
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
@@ -6,7 +6,7 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-passwall
|
||||
PKG_VERSION:=25.5.15
|
||||
PKG_VERSION:=25.5.16
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_CONFIG_DEPENDS:= \
|
||||
|
||||
@@ -459,6 +459,9 @@ function gen_outbound(flag, node, tag, proxy_table)
|
||||
if node.protocol == "anytls" then
|
||||
protocol_table = {
|
||||
password = (node.password and node.password ~= "") and node.password or "",
|
||||
idle_session_check_interval = "30s",
|
||||
idle_session_timeout = "30s",
|
||||
min_idle_session = 5,
|
||||
tls = tls
|
||||
}
|
||||
end
|
||||
@@ -1023,7 +1026,7 @@ function gen_config(var)
|
||||
end
|
||||
if is_new_ut_node then
|
||||
local ut_node = uci:get_all(appname, ut_node_id)
|
||||
local outbound = gen_outbound(flag, ut_node, ut_node_tag)
|
||||
local outbound = gen_outbound(flag, ut_node, ut_node_tag, { run_socks_instance = not no_run })
|
||||
if outbound then
|
||||
outbound.tag = outbound.tag .. ":" .. ut_node.remarks
|
||||
table.insert(outbounds, outbound)
|
||||
@@ -1439,7 +1442,7 @@ function gen_config(var)
|
||||
sys.call(string.format("mkdir -p %s && touch %s/%s", api.TMP_IFACE_PATH, api.TMP_IFACE_PATH, node.iface))
|
||||
end
|
||||
else
|
||||
local outbound = gen_outbound(flag, node)
|
||||
local outbound = gen_outbound(flag, node, nil, { run_socks_instance = not no_run })
|
||||
if outbound then
|
||||
outbound.tag = outbound.tag .. ":" .. node.remarks
|
||||
COMMON.default_outbound_tag, last_insert_outbound = set_outbound_detour(node, outbound, outbounds)
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-passwall
|
||||
PKG_VERSION:=25.5.8
|
||||
PKG_VERSION:=25.5.15
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_CONFIG_DEPENDS:= \
|
||||
|
||||
@@ -84,6 +84,7 @@ function gen_outbound(flag, node, tag, proxy_table)
|
||||
local run_socks_instance = true
|
||||
if proxy_table ~= nil and type(proxy_table) == "table" then
|
||||
proxy_tag = proxy_table.tag or nil
|
||||
run_socks_instance = proxy_table.run_socks_instance
|
||||
end
|
||||
|
||||
if node.type ~= "sing-box" then
|
||||
@@ -458,6 +459,9 @@ function gen_outbound(flag, node, tag, proxy_table)
|
||||
if node.protocol == "anytls" then
|
||||
protocol_table = {
|
||||
password = (node.password and node.password ~= "") and node.password or "",
|
||||
idle_session_check_interval = "30s",
|
||||
idle_session_timeout = "30s",
|
||||
min_idle_session = 5,
|
||||
tls = tls
|
||||
}
|
||||
end
|
||||
|
||||
@@ -62,6 +62,7 @@ function gen_outbound(flag, node, tag, proxy_table)
|
||||
proxy_tag = proxy_table.tag or nil
|
||||
fragment = proxy_table.fragment or nil
|
||||
noise = proxy_table.noise or nil
|
||||
run_socks_instance = proxy_table.run_socks_instance
|
||||
end
|
||||
|
||||
if node.type ~= "Xray" then
|
||||
@@ -735,7 +736,7 @@ function gen_config(var)
|
||||
end
|
||||
if is_new_blc_node then
|
||||
local blc_node = uci:get_all(appname, blc_node_id)
|
||||
local outbound = gen_outbound(flag, blc_node, blc_node_tag, { fragment = xray_settings.fragment == "1" or nil, noise = xray_settings.noise == "1" or nil })
|
||||
local outbound = gen_outbound(flag, blc_node, blc_node_tag, { fragment = xray_settings.fragment == "1" or nil, noise = xray_settings.noise == "1" or nil, run_socks_instance = not no_run })
|
||||
if outbound then
|
||||
outbound.tag = outbound.tag .. ":" .. blc_node.remarks
|
||||
table.insert(outbounds, outbound)
|
||||
@@ -761,7 +762,7 @@ function gen_config(var)
|
||||
if is_new_node then
|
||||
local fallback_node = uci:get_all(appname, fallback_node_id)
|
||||
if fallback_node.protocol ~= "_balancing" then
|
||||
local outbound = gen_outbound(flag, fallback_node, fallback_node_id, { fragment = xray_settings.fragment == "1" or nil, noise = xray_settings.noise == "1" or nil })
|
||||
local outbound = gen_outbound(flag, fallback_node, fallback_node_id, { fragment = xray_settings.fragment == "1" or nil, noise = xray_settings.noise == "1" or nil, run_socks_instance = not no_run })
|
||||
if outbound then
|
||||
outbound.tag = outbound.tag .. ":" .. fallback_node.remarks
|
||||
table.insert(outbounds, outbound)
|
||||
@@ -1140,7 +1141,7 @@ function gen_config(var)
|
||||
sys.call(string.format("mkdir -p %s && touch %s/%s", api.TMP_IFACE_PATH, api.TMP_IFACE_PATH, node.iface))
|
||||
end
|
||||
else
|
||||
local outbound = gen_outbound(flag, node, nil, { fragment = xray_settings.fragment == "1" or nil, noise = xray_settings.fragment == "1" or nil })
|
||||
local outbound = gen_outbound(flag, node, nil, { fragment = xray_settings.fragment == "1" or nil, noise = xray_settings.fragment == "1" or nil, run_socks_instance = not no_run })
|
||||
if outbound then
|
||||
outbound.tag = outbound.tag .. ":" .. node.remarks
|
||||
COMMON.default_outbound_tag, last_insert_outbound = set_outbound_detour(node, outbound, outbounds)
|
||||
|
||||
@@ -30,15 +30,21 @@ reload_dnsmasq_pids() {
|
||||
|
||||
while true; do
|
||||
|
||||
if [ -s "$LEASE_FILE" ]; then
|
||||
awk 'NF >= 4 {print $3" "$4}' "$LEASE_FILE" | sort > "$TMP_FILE"
|
||||
if [ -f "$TMP_FILE" ]; then
|
||||
if [ ! -f "$HOSTS_FILE" ] || [ "$(md5sum "$TMP_FILE" | awk '{print $1}')" != "$(md5sum "$HOSTS_FILE" | awk '{print $1}')" ]; then
|
||||
if [ -f "$LEASE_FILE" ]; then
|
||||
awk 'NF >= 4 && $4 != "*" {print $3" "$4}' "$LEASE_FILE" | sort > "$TMP_FILE"
|
||||
if [ -s "$TMP_FILE" ]; then
|
||||
if [ ! -f "$HOSTS_FILE" ] || ! cmp -s "$TMP_FILE" "$HOSTS_FILE"; then
|
||||
mv "$TMP_FILE" "$HOSTS_FILE"
|
||||
reload_dnsmasq_pids
|
||||
else
|
||||
rm -rf "$TMP_FILE"
|
||||
rm -f "$TMP_FILE"
|
||||
fi
|
||||
else
|
||||
if [ -s "$HOSTS_FILE" ]; then
|
||||
: > "$HOSTS_FILE"
|
||||
reload_dnsmasq_pids
|
||||
fi
|
||||
rm -f "$TMP_FILE"
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
@@ -95,40 +95,11 @@ url_test_node() {
|
||||
[ "${chn_list}" = "proxy" ] && probeUrl="www.baidu.com"
|
||||
result=$(${_curl} --max-time 5 -o /dev/null -I -skL -x ${curlx} ${curl_arg}${probeUrl})
|
||||
pgrep -af "url_test_${node_id}" | awk '! /test\.sh/{print $1}' | xargs kill -9 >/dev/null 2>&1
|
||||
rm -rf "/tmp/etc/${CONFIG}/url_test_${node_id}"*.json
|
||||
rm -rf /tmp/etc/${CONFIG}/*url_test_${node_id}*.json
|
||||
}
|
||||
echo $result
|
||||
}
|
||||
|
||||
test_node() {
|
||||
local node_id=$1
|
||||
local _type=$(echo $(config_n_get ${node_id} type) | tr 'A-Z' 'a-z')
|
||||
[ -n "${_type}" ] && {
|
||||
if [ "${_type}" == "socks" ]; then
|
||||
local _address=$(config_n_get ${node_id} address)
|
||||
local _port=$(config_n_get ${node_id} port)
|
||||
[ -n "${_address}" ] && [ -n "${_port}" ] && {
|
||||
local curlx="socks5h://${_address}:${_port}"
|
||||
local _username=$(config_n_get ${node_id} username)
|
||||
local _password=$(config_n_get ${node_id} password)
|
||||
[ -n "${_username}" ] && [ -n "${_password}" ] && curlx="socks5h://${_username}:${_password}@${_address}:${_port}"
|
||||
}
|
||||
else
|
||||
local _tmp_port=$(/usr/share/${CONFIG}/app.sh get_new_port 61080 tcp)
|
||||
/usr/share/${CONFIG}/app.sh run_socks flag="test_node_${node_id}" node=${node_id} bind=127.0.0.1 socks_port=${_tmp_port} config_file=test_node_${node_id}.json
|
||||
local curlx="socks5h://127.0.0.1:${_tmp_port}"
|
||||
fi
|
||||
sleep 1s
|
||||
_proxy_status=$(test_url "https://www.google.com/generate_204" ${retry_num} ${connect_timeout} "-x $curlx")
|
||||
pgrep -af "test_node_${node_id}" | awk '! /test\.sh/{print $1}' | xargs kill -9 >/dev/null 2>&1
|
||||
rm -rf "/tmp/etc/${CONFIG}/test_node_${node_id}.json"
|
||||
if [ "${_proxy_status}" -eq 200 ]; then
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
return 1
|
||||
}
|
||||
|
||||
arg1=$1
|
||||
shift
|
||||
case $arg1 in
|
||||
|
||||
@@ -1417,6 +1417,6 @@
|
||||
<value>صادر کردن سرور</value>
|
||||
</data>
|
||||
<data name="TbSettingsIPAPIUrl" xml:space="preserve">
|
||||
<value>Current connection info test URL</value>
|
||||
<value>URL آزمایش اطلاعات اتصال فعلی</value>
|
||||
</data>
|
||||
</root>
|
||||
</root>
|
||||
|
||||
@@ -9,10 +9,6 @@ A V2Ray client for Android, support [Xray core](https://github.com/XTLS/Xray-cor
|
||||
[](https://github.com/2dust/v2rayNG/releases)
|
||||
[](https://t.me/v2rayn)
|
||||
|
||||
<a href="https://play.google.com/store/apps/details?id=com.v2ray.ang">
|
||||
<img alt="Get it on Google Play" src="https://play.google.com/intl/en_us/badges/images/generic/en_badge_web_generic.png" width="165" height="64" />
|
||||
</a>
|
||||
|
||||
### Telegram Channel
|
||||
[github_2dust](https://t.me/github_2dust)
|
||||
|
||||
|
||||
@@ -96,7 +96,6 @@ type DefaultDispatcher struct {
|
||||
router routing.Router
|
||||
policy policy.Manager
|
||||
stats stats.Manager
|
||||
dns dns.Client
|
||||
fdns dns.FakeDNSEngine
|
||||
}
|
||||
|
||||
@@ -107,7 +106,7 @@ func init() {
|
||||
core.OptionalFeatures(ctx, func(fdns dns.FakeDNSEngine) {
|
||||
d.fdns = fdns
|
||||
})
|
||||
return d.Init(config.(*Config), om, router, pm, sm, dc)
|
||||
return d.Init(config.(*Config), om, router, pm, sm)
|
||||
}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -116,12 +115,11 @@ func init() {
|
||||
}
|
||||
|
||||
// Init initializes DefaultDispatcher.
|
||||
func (d *DefaultDispatcher) Init(config *Config, om outbound.Manager, router routing.Router, pm policy.Manager, sm stats.Manager, dns dns.Client) error {
|
||||
func (d *DefaultDispatcher) Init(config *Config, om outbound.Manager, router routing.Router, pm policy.Manager, sm stats.Manager) error {
|
||||
d.ohm = om
|
||||
d.router = router
|
||||
d.policy = pm
|
||||
d.stats = sm
|
||||
d.dns = dns
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -407,18 +405,6 @@ func sniffer(ctx context.Context, cReader *cachedReader, metadataOnly bool, netw
|
||||
func (d *DefaultDispatcher) routedDispatch(ctx context.Context, link *transport.Link, destination net.Destination) {
|
||||
outbounds := session.OutboundsFromContext(ctx)
|
||||
ob := outbounds[len(outbounds)-1]
|
||||
if hosts, ok := d.dns.(dns.HostsLookup); ok && destination.Address.Family().IsDomain() {
|
||||
proxied := hosts.LookupHosts(ob.Target.String())
|
||||
if proxied != nil {
|
||||
ro := ob.RouteTarget == destination
|
||||
destination.Address = *proxied
|
||||
if ro {
|
||||
ob.RouteTarget = destination
|
||||
} else {
|
||||
ob.Target = destination
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var handler outbound.Handler
|
||||
|
||||
|
||||
@@ -243,22 +243,6 @@ func (s *DNS) LookupIP(domain string, option dns.IPOption) ([]net.IP, uint32, er
|
||||
return nil, 0, dns.ErrEmptyResponse
|
||||
}
|
||||
|
||||
// LookupHosts implements dns.HostsLookup.
|
||||
func (s *DNS) LookupHosts(domain string) *net.Address {
|
||||
domain = strings.TrimSuffix(domain, ".")
|
||||
if domain == "" {
|
||||
return nil
|
||||
}
|
||||
// Normalize the FQDN form query
|
||||
addrs := s.hosts.Lookup(domain, *s.ipOption)
|
||||
if len(addrs) > 0 {
|
||||
errors.LogInfo(s.ctx, "domain replaced: ", domain, " -> ", addrs[0].String())
|
||||
return &addrs[0]
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *DNS) sortClients(domain string) []*Client {
|
||||
clients := make([]*Client, 0, len(s.clients))
|
||||
clientUsed := make([]bool, len(s.clients))
|
||||
|
||||
@@ -24,10 +24,6 @@ type Client interface {
|
||||
LookupIP(domain string, option IPOption) ([]net.IP, uint32, error)
|
||||
}
|
||||
|
||||
type HostsLookup interface {
|
||||
LookupHosts(domain string) *net.Address
|
||||
}
|
||||
|
||||
// ClientType returns the type of Client interface. Can be used for implementing common.HasType.
|
||||
//
|
||||
// xray:api:beta
|
||||
|
||||
+2
-2
@@ -13,7 +13,7 @@ require (
|
||||
github.com/pelletier/go-toml v1.9.5
|
||||
github.com/pires/go-proxyproto v0.8.1
|
||||
github.com/quic-go/quic-go v0.51.0
|
||||
github.com/refraction-networking/utls v1.7.2
|
||||
github.com/refraction-networking/utls v1.7.3
|
||||
github.com/sagernet/sing v0.5.1
|
||||
github.com/sagernet/sing-shadowsocks v0.2.7
|
||||
github.com/seiflotfy/cuckoofilter v0.0.0-20240715131351-a2f2c23f1771
|
||||
@@ -27,7 +27,7 @@ require (
|
||||
golang.org/x/sync v0.14.0
|
||||
golang.org/x/sys v0.33.0
|
||||
golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173
|
||||
google.golang.org/grpc v1.72.0
|
||||
google.golang.org/grpc v1.72.1
|
||||
google.golang.org/protobuf v1.36.6
|
||||
gvisor.dev/gvisor v0.0.0-20250428193742-2d800c3129d5
|
||||
h12.io/socks v1.0.3
|
||||
|
||||
+4
-4
@@ -56,8 +56,8 @@ github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI=
|
||||
github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg=
|
||||
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/refraction-networking/utls v1.7.2 h1:XOgYzit7lAKaa7kzAO5BJR9l4X/H200eVUD4s8SF8/s=
|
||||
github.com/refraction-networking/utls v1.7.2/go.mod h1:TUhh27RHMGtQvjQq+RyO11P6ZNQNBb3N0v7wsEjKAIQ=
|
||||
github.com/refraction-networking/utls v1.7.3 h1:L0WRhHY7Oq1T0zkdzVZMR6zWZv+sXbHB9zcuvsAEqCo=
|
||||
github.com/refraction-networking/utls v1.7.3/go.mod h1:TUhh27RHMGtQvjQq+RyO11P6ZNQNBb3N0v7wsEjKAIQ=
|
||||
github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 h1:f/FNXud6gA3MNr8meMVVGxhp+QBTqY91tM8HjEuMjGg=
|
||||
github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3/go.mod h1:HgjTstvQsPGkxUsCd2KWxErBblirPizecHcpD3ffK+s=
|
||||
github.com/sagernet/sing v0.5.1 h1:mhL/MZVq0TjuvHcpYcFtmSD1BFOxZ/+8ofbNZcg1k1Y=
|
||||
@@ -143,8 +143,8 @@ golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 h1:/jFs0duh4rdb8uI
|
||||
golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173/go.mod h1:tkCQ4FQXmpAgYVh++1cq16/dH4QJtmvpRv19DWGAHSA=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250218202821-56aae31c358a h1:51aaUVRocpvUOSQKM6Q7VuoaktNIaMCLuhZB6DKksq4=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250218202821-56aae31c358a/go.mod h1:uRxBH1mhmO8PGhU89cMcHaXKZqO+OfakD8QQO0oYwlQ=
|
||||
google.golang.org/grpc v1.72.0 h1:S7UkcVa60b5AAQTaO6ZKamFp1zMZSU0fGDK2WZLbBnM=
|
||||
google.golang.org/grpc v1.72.0/go.mod h1:wH5Aktxcg25y1I3w7H69nHfXdOG3UiadoBtjh3izSDM=
|
||||
google.golang.org/grpc v1.72.1 h1:HR03wO6eyZ7lknl75XlxABNVLLFc2PAb6mHlYh756mA=
|
||||
google.golang.org/grpc v1.72.1/go.mod h1:wH5Aktxcg25y1I3w7H69nHfXdOG3UiadoBtjh3izSDM=
|
||||
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/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
|
||||
Reference in New Issue
Block a user