mirror of
https://github.com/bolucat/Archive.git
synced 2026-04-22 16:07:49 +08:00
Update On Sat Mar 23 19:27:34 CET 2024
This commit is contained in:
@@ -595,3 +595,4 @@ Update On Wed Mar 20 14:51:04 CET 2024
|
||||
Update On Wed Mar 20 15:20:33 CET 2024
|
||||
Update On Fri Mar 22 14:55:10 CET 2024
|
||||
Update On Fri Mar 22 19:26:11 CET 2024
|
||||
Update On Sat Mar 23 19:27:23 CET 2024
|
||||
|
||||
@@ -78,7 +78,9 @@ func (c *client) ExchangeContext(ctx context.Context, m *D.Msg) (*D.Msg, error)
|
||||
options = append(options, dialer.WithInterface(c.iface))
|
||||
}
|
||||
|
||||
conn, err := getDialHandler(c.r, c.proxyAdapter, c.proxyName, options...)(ctx, network, net.JoinHostPort(ip.String(), c.port))
|
||||
dialHandler := getDialHandler(c.r, c.proxyAdapter, c.proxyName, options...)
|
||||
addr := net.JoinHostPort(ip.String(), c.port)
|
||||
conn, err := dialHandler(ctx, network, addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -111,7 +113,16 @@ func (c *client) ExchangeContext(ctx context.Context, m *D.Msg) (*D.Msg, error)
|
||||
if msg != nil && msg.Truncated && c.Client.Net == "" {
|
||||
tcpClient := *c.Client // copy a client
|
||||
tcpClient.Net = "tcp"
|
||||
network = "tcp"
|
||||
log.Debugln("[DNS] Truncated reply from %s:%s for %s over UDP, retrying over TCP", c.host, c.port, m.Question[0].String())
|
||||
dConn.Conn, err = dialHandler(ctx, network, addr)
|
||||
if err != nil {
|
||||
ch <- result{msg, err}
|
||||
return
|
||||
}
|
||||
defer func() {
|
||||
_ = conn.Close()
|
||||
}()
|
||||
msg, _, err = tcpClient.ExchangeWithConn(m, dConn)
|
||||
}
|
||||
|
||||
|
||||
Generated
+22
-17
@@ -781,7 +781,7 @@ dependencies = [
|
||||
"glob",
|
||||
"gunzip",
|
||||
"image 0.25.0",
|
||||
"indexmap 2.2.5",
|
||||
"indexmap 2.2.6",
|
||||
"log",
|
||||
"nanoid",
|
||||
"once_cell",
|
||||
@@ -819,7 +819,7 @@ dependencies = [
|
||||
"uuid",
|
||||
"warp",
|
||||
"webview2-com",
|
||||
"which 6.0.0",
|
||||
"which 6.0.1",
|
||||
"window-shadows",
|
||||
"window-vibrancy",
|
||||
"windows 0.39.0",
|
||||
@@ -2173,7 +2173,7 @@ dependencies = [
|
||||
"futures-sink",
|
||||
"futures-util",
|
||||
"http",
|
||||
"indexmap 2.2.5",
|
||||
"indexmap 2.2.6",
|
||||
"slab",
|
||||
"tokio",
|
||||
"tokio-util",
|
||||
@@ -2536,9 +2536,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.2.5"
|
||||
version = "2.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7b0b929d511467233429c45a44ac1dcaa21ba0f5ba11e4879e6ed28ddb4f9df4"
|
||||
checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown 0.14.3",
|
||||
@@ -2921,7 +2921,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0c2a198fb6b0eada2a8df47933734e6d35d350665a33a3593d7164fa52c75c19"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"windows-targets 0.52.4",
|
||||
"windows-targets 0.48.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3871,7 +3871,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9"
|
||||
dependencies = [
|
||||
"fixedbitset",
|
||||
"indexmap 2.2.5",
|
||||
"indexmap 2.2.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4074,7 +4074,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5699cc8a63d1aa2b1ee8e12b9ad70ac790d65788cd36101fa37f87ea46c4cef"
|
||||
dependencies = [
|
||||
"base64 0.21.7",
|
||||
"indexmap 2.2.5",
|
||||
"indexmap 2.2.6",
|
||||
"line-wrap",
|
||||
"quick-xml 0.31.0",
|
||||
"serde",
|
||||
@@ -4962,7 +4962,7 @@ version = "1.0.114"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0"
|
||||
dependencies = [
|
||||
"indexmap 2.2.5",
|
||||
"indexmap 2.2.6",
|
||||
"itoa 1.0.10",
|
||||
"ryu",
|
||||
"serde",
|
||||
@@ -5010,7 +5010,7 @@ dependencies = [
|
||||
"chrono",
|
||||
"hex",
|
||||
"indexmap 1.9.3",
|
||||
"indexmap 2.2.5",
|
||||
"indexmap 2.2.6",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
@@ -5048,7 +5048,7 @@ version = "0.9.33"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a0623d197252096520c6f2a5e1171ee436e5af99a5d7caa2891e55e61950e6d9"
|
||||
dependencies = [
|
||||
"indexmap 2.2.5",
|
||||
"indexmap 2.2.6",
|
||||
"itoa 1.0.10",
|
||||
"ryu",
|
||||
"serde",
|
||||
@@ -6143,7 +6143,7 @@ version = "0.19.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421"
|
||||
dependencies = [
|
||||
"indexmap 2.2.5",
|
||||
"indexmap 2.2.6",
|
||||
"serde",
|
||||
"serde_spanned",
|
||||
"toml_datetime",
|
||||
@@ -6156,7 +6156,7 @@ version = "0.22.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "18769cd1cec395d70860ceb4d932812a0b4d06b1a4bb336745a4d21b9496e992"
|
||||
dependencies = [
|
||||
"indexmap 2.2.5",
|
||||
"indexmap 2.2.6",
|
||||
"serde",
|
||||
"serde_spanned",
|
||||
"toml_datetime",
|
||||
@@ -6872,15 +6872,14 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "which"
|
||||
version = "6.0.0"
|
||||
version = "6.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7fa5e0c10bf77f44aac573e498d1a82d5fbd5e91f6fc0a99e7be4b38e85e101c"
|
||||
checksum = "8211e4f58a2b2805adfbefbc07bab82958fc91e3836339b1ab7ae32465dce0d7"
|
||||
dependencies = [
|
||||
"either",
|
||||
"home",
|
||||
"once_cell",
|
||||
"rustix 0.38.31",
|
||||
"windows-sys 0.52.0",
|
||||
"winsafe",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -7415,6 +7414,12 @@ dependencies = [
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winsafe"
|
||||
version = "0.0.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d135d17ab770252ad95e9a872d365cf3090e3be864a34ab46f48555993efc904"
|
||||
|
||||
[[package]]
|
||||
name = "wry"
|
||||
version = "0.24.7"
|
||||
|
||||
@@ -103,7 +103,7 @@
|
||||
"@types/js-cookie": "3.0.6",
|
||||
"@types/lodash-es": "4.17.12",
|
||||
"@types/node": "20.11.30",
|
||||
"@types/react": "18.2.67",
|
||||
"@types/react": "18.2.69",
|
||||
"@types/react-dom": "18.2.22",
|
||||
"@types/react-transition-group": "4.4.10",
|
||||
"@typescript-eslint/eslint-plugin": "7.3.1",
|
||||
@@ -151,7 +151,7 @@
|
||||
"telegraf": "4.16.3",
|
||||
"tsx": "4.7.1",
|
||||
"typescript": "5.4.3",
|
||||
"vite": "5.2.3",
|
||||
"vite": "5.2.4",
|
||||
"vite-plugin-monaco-editor": "1.1.0",
|
||||
"vite-plugin-svgr": "4.2.0"
|
||||
}
|
||||
|
||||
Generated
+80
-80
@@ -19,25 +19,25 @@ dependencies:
|
||||
version: 3.2.2(react@18.2.0)
|
||||
'@emotion/react':
|
||||
specifier: 11.11.4
|
||||
version: 11.11.4(@types/react@18.2.67)(react@18.2.0)
|
||||
version: 11.11.4(@types/react@18.2.69)(react@18.2.0)
|
||||
'@emotion/styled':
|
||||
specifier: 11.11.0
|
||||
version: 11.11.0(@emotion/react@11.11.4)(@types/react@18.2.67)(react@18.2.0)
|
||||
version: 11.11.0(@emotion/react@11.11.4)(@types/react@18.2.69)(react@18.2.0)
|
||||
'@juggle/resize-observer':
|
||||
specifier: 3.4.0
|
||||
version: 3.4.0
|
||||
'@mui/icons-material':
|
||||
specifier: 5.15.14
|
||||
version: 5.15.14(@mui/material@5.15.14)(@types/react@18.2.67)(react@18.2.0)
|
||||
version: 5.15.14(@mui/material@5.15.14)(@types/react@18.2.69)(react@18.2.0)
|
||||
'@mui/lab':
|
||||
specifier: 5.0.0-alpha.169
|
||||
version: 5.0.0-alpha.169(@emotion/react@11.11.4)(@emotion/styled@11.11.0)(@mui/material@5.15.14)(@types/react@18.2.67)(react-dom@18.2.0)(react@18.2.0)
|
||||
version: 5.0.0-alpha.169(@emotion/react@11.11.4)(@emotion/styled@11.11.0)(@mui/material@5.15.14)(@types/react@18.2.69)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@mui/material':
|
||||
specifier: 5.15.14
|
||||
version: 5.15.14(@emotion/react@11.11.4)(@emotion/styled@11.11.0)(@types/react@18.2.67)(react-dom@18.2.0)(react@18.2.0)
|
||||
version: 5.15.14(@emotion/react@11.11.4)(@emotion/styled@11.11.0)(@types/react@18.2.69)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@mui/x-data-grid':
|
||||
specifier: 7.0.0
|
||||
version: 7.0.0(@emotion/react@11.11.4)(@emotion/styled@11.11.0)(@mui/material@5.15.14)(@types/react@18.2.67)(react-dom@18.2.0)(react@18.2.0)
|
||||
version: 7.0.0(@emotion/react@11.11.4)(@emotion/styled@11.11.0)(@mui/material@5.15.14)(@types/react@18.2.69)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@tauri-apps/api':
|
||||
specifier: 1.5.3
|
||||
version: 1.5.3
|
||||
@@ -64,7 +64,7 @@ dependencies:
|
||||
version: 0.47.0
|
||||
mui-color-input:
|
||||
specifier: 2.0.3
|
||||
version: 2.0.3(@emotion/react@11.11.4)(@emotion/styled@11.11.0)(@mui/material@5.15.14)(@types/react@18.2.67)(react-dom@18.2.0)(react@18.2.0)
|
||||
version: 2.0.3(@emotion/react@11.11.4)(@emotion/styled@11.11.0)(@mui/material@5.15.14)(@types/react@18.2.69)(react-dom@18.2.0)(react@18.2.0)
|
||||
react:
|
||||
specifier: 18.2.0
|
||||
version: 18.2.0
|
||||
@@ -82,7 +82,7 @@ dependencies:
|
||||
version: 14.1.0(i18next@23.10.1)(react-dom@18.2.0)(react@18.2.0)
|
||||
react-markdown:
|
||||
specifier: 9.0.1
|
||||
version: 9.0.1(@types/react@18.2.67)(react@18.2.0)
|
||||
version: 9.0.1(@types/react@18.2.69)(react@18.2.0)
|
||||
react-router-dom:
|
||||
specifier: 6.22.3
|
||||
version: 6.22.3(react-dom@18.2.0)(react@18.2.0)
|
||||
@@ -125,8 +125,8 @@ devDependencies:
|
||||
specifier: 20.11.30
|
||||
version: 20.11.30
|
||||
'@types/react':
|
||||
specifier: 18.2.67
|
||||
version: 18.2.67
|
||||
specifier: 18.2.69
|
||||
version: 18.2.69
|
||||
'@types/react-dom':
|
||||
specifier: 18.2.22
|
||||
version: 18.2.22
|
||||
@@ -141,7 +141,7 @@ devDependencies:
|
||||
version: 7.3.1(eslint@8.57.0)(typescript@5.4.3)
|
||||
'@vitejs/plugin-react':
|
||||
specifier: 4.2.1
|
||||
version: 4.2.1(vite@5.2.3)
|
||||
version: 4.2.1(vite@5.2.4)
|
||||
adm-zip:
|
||||
specifier: 0.5.12
|
||||
version: 0.5.12
|
||||
@@ -269,14 +269,14 @@ devDependencies:
|
||||
specifier: 5.4.3
|
||||
version: 5.4.3
|
||||
vite:
|
||||
specifier: 5.2.3
|
||||
version: 5.2.3(@types/node@20.11.30)(sass@1.72.0)
|
||||
specifier: 5.2.4
|
||||
version: 5.2.4(@types/node@20.11.30)(sass@1.72.0)
|
||||
vite-plugin-monaco-editor:
|
||||
specifier: npm:vite-plugin-monaco-editor-new@1.1.3
|
||||
version: /vite-plugin-monaco-editor-new@1.1.3(monaco-editor@0.47.0)
|
||||
vite-plugin-svgr:
|
||||
specifier: 4.2.0
|
||||
version: 4.2.0(typescript@5.4.3)(vite@5.2.3)
|
||||
version: 4.2.0(typescript@5.4.3)(vite@5.2.4)
|
||||
|
||||
packages:
|
||||
|
||||
@@ -825,7 +825,7 @@ packages:
|
||||
resolution: {integrity: sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==}
|
||||
dev: false
|
||||
|
||||
/@emotion/react@11.11.4(@types/react@18.2.67)(react@18.2.0):
|
||||
/@emotion/react@11.11.4(@types/react@18.2.69)(react@18.2.0):
|
||||
resolution: {integrity: sha512-t8AjMlF0gHpvvxk5mAtCqR4vmxiGHCeJBaQO6gncUSdklELOgtwjerNY2yuJNfwnc6vi16U/+uMF+afIawJ9iw==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
@@ -841,7 +841,7 @@ packages:
|
||||
'@emotion/use-insertion-effect-with-fallbacks': 1.0.1(react@18.2.0)
|
||||
'@emotion/utils': 1.2.1
|
||||
'@emotion/weak-memoize': 0.3.1
|
||||
'@types/react': 18.2.67
|
||||
'@types/react': 18.2.69
|
||||
hoist-non-react-statics: 3.3.2
|
||||
react: 18.2.0
|
||||
dev: false
|
||||
@@ -860,7 +860,7 @@ packages:
|
||||
resolution: {integrity: sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA==}
|
||||
dev: false
|
||||
|
||||
/@emotion/styled@11.11.0(@emotion/react@11.11.4)(@types/react@18.2.67)(react@18.2.0):
|
||||
/@emotion/styled@11.11.0(@emotion/react@11.11.4)(@types/react@18.2.69)(react@18.2.0):
|
||||
resolution: {integrity: sha512-hM5Nnvu9P3midq5aaXj4I+lnSfNi7Pmd4EWk1fOZ3pxookaQTNew6bp4JaCBYM4HVFZF9g7UjJmsUmC2JlxOng==}
|
||||
peerDependencies:
|
||||
'@emotion/react': ^11.0.0-rc.0
|
||||
@@ -873,11 +873,11 @@ packages:
|
||||
'@babel/runtime': 7.23.8
|
||||
'@emotion/babel-plugin': 11.11.0
|
||||
'@emotion/is-prop-valid': 1.2.1
|
||||
'@emotion/react': 11.11.4(@types/react@18.2.67)(react@18.2.0)
|
||||
'@emotion/react': 11.11.4(@types/react@18.2.69)(react@18.2.0)
|
||||
'@emotion/serialize': 1.1.3
|
||||
'@emotion/use-insertion-effect-with-fallbacks': 1.0.1(react@18.2.0)
|
||||
'@emotion/utils': 1.2.1
|
||||
'@types/react': 18.2.67
|
||||
'@types/react': 18.2.69
|
||||
react: 18.2.0
|
||||
dev: false
|
||||
|
||||
@@ -1451,7 +1451,7 @@ packages:
|
||||
resolution: {integrity: sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA==}
|
||||
dev: false
|
||||
|
||||
/@mui/base@5.0.0-beta.40(@types/react@18.2.67)(react-dom@18.2.0)(react@18.2.0):
|
||||
/@mui/base@5.0.0-beta.40(@types/react@18.2.69)(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-I/lGHztkCzvwlXpjD2+SNmvNQvB4227xBXhISPjEaJUXGImOQ9f3D2Yj/T3KasSI/h0MLWy74X0J6clhPmsRbQ==}
|
||||
engines: {node: '>=12.0.0'}
|
||||
peerDependencies:
|
||||
@@ -1464,10 +1464,10 @@ packages:
|
||||
dependencies:
|
||||
'@babel/runtime': 7.23.9
|
||||
'@floating-ui/react-dom': 2.0.8(react-dom@18.2.0)(react@18.2.0)
|
||||
'@mui/types': 7.2.14(@types/react@18.2.67)
|
||||
'@mui/utils': 5.15.14(@types/react@18.2.67)(react@18.2.0)
|
||||
'@mui/types': 7.2.14(@types/react@18.2.69)
|
||||
'@mui/utils': 5.15.14(@types/react@18.2.69)(react@18.2.0)
|
||||
'@popperjs/core': 2.11.8
|
||||
'@types/react': 18.2.67
|
||||
'@types/react': 18.2.69
|
||||
clsx: 2.1.0
|
||||
prop-types: 15.8.1
|
||||
react: 18.2.0
|
||||
@@ -1478,7 +1478,7 @@ packages:
|
||||
resolution: {integrity: sha512-on75VMd0XqZfaQW+9pGjSNiqW+ghc5E2ZSLRBXwcXl/C4YzjfyjrLPhrEpKnR9Uym9KXBvxrhoHfPcczYHweyA==}
|
||||
dev: false
|
||||
|
||||
/@mui/icons-material@5.15.14(@mui/material@5.15.14)(@types/react@18.2.67)(react@18.2.0):
|
||||
/@mui/icons-material@5.15.14(@mui/material@5.15.14)(@types/react@18.2.69)(react@18.2.0):
|
||||
resolution: {integrity: sha512-vj/51k7MdFmt+XVw94sl30SCvGx6+wJLsNYjZRgxhS6y3UtnWnypMOsm3Kmg8TN+P0dqwsjy4/fX7B1HufJIhw==}
|
||||
engines: {node: '>=12.0.0'}
|
||||
peerDependencies:
|
||||
@@ -1490,12 +1490,12 @@ packages:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@babel/runtime': 7.23.9
|
||||
'@mui/material': 5.15.14(@emotion/react@11.11.4)(@emotion/styled@11.11.0)(@types/react@18.2.67)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@types/react': 18.2.67
|
||||
'@mui/material': 5.15.14(@emotion/react@11.11.4)(@emotion/styled@11.11.0)(@types/react@18.2.69)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@types/react': 18.2.69
|
||||
react: 18.2.0
|
||||
dev: false
|
||||
|
||||
/@mui/lab@5.0.0-alpha.169(@emotion/react@11.11.4)(@emotion/styled@11.11.0)(@mui/material@5.15.14)(@types/react@18.2.67)(react-dom@18.2.0)(react@18.2.0):
|
||||
/@mui/lab@5.0.0-alpha.169(@emotion/react@11.11.4)(@emotion/styled@11.11.0)(@mui/material@5.15.14)(@types/react@18.2.69)(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-h6xe1K6ISKUbyxTDgdvql4qoDP6+q8ad5fg9nXQxGLUrIeT2jVrBuT/jRECSTufbnhzP+V5kulvYxaMfM8rEdA==}
|
||||
engines: {node: '>=12.0.0'}
|
||||
peerDependencies:
|
||||
@@ -1514,21 +1514,21 @@ packages:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@babel/runtime': 7.23.9
|
||||
'@emotion/react': 11.11.4(@types/react@18.2.67)(react@18.2.0)
|
||||
'@emotion/styled': 11.11.0(@emotion/react@11.11.4)(@types/react@18.2.67)(react@18.2.0)
|
||||
'@mui/base': 5.0.0-beta.40(@types/react@18.2.67)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@mui/material': 5.15.14(@emotion/react@11.11.4)(@emotion/styled@11.11.0)(@types/react@18.2.67)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@mui/system': 5.15.14(@emotion/react@11.11.4)(@emotion/styled@11.11.0)(@types/react@18.2.67)(react@18.2.0)
|
||||
'@mui/types': 7.2.14(@types/react@18.2.67)
|
||||
'@mui/utils': 5.15.14(@types/react@18.2.67)(react@18.2.0)
|
||||
'@types/react': 18.2.67
|
||||
'@emotion/react': 11.11.4(@types/react@18.2.69)(react@18.2.0)
|
||||
'@emotion/styled': 11.11.0(@emotion/react@11.11.4)(@types/react@18.2.69)(react@18.2.0)
|
||||
'@mui/base': 5.0.0-beta.40(@types/react@18.2.69)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@mui/material': 5.15.14(@emotion/react@11.11.4)(@emotion/styled@11.11.0)(@types/react@18.2.69)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@mui/system': 5.15.14(@emotion/react@11.11.4)(@emotion/styled@11.11.0)(@types/react@18.2.69)(react@18.2.0)
|
||||
'@mui/types': 7.2.14(@types/react@18.2.69)
|
||||
'@mui/utils': 5.15.14(@types/react@18.2.69)(react@18.2.0)
|
||||
'@types/react': 18.2.69
|
||||
clsx: 2.1.0
|
||||
prop-types: 15.8.1
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0(react@18.2.0)
|
||||
dev: false
|
||||
|
||||
/@mui/material@5.15.14(@emotion/react@11.11.4)(@emotion/styled@11.11.0)(@types/react@18.2.67)(react-dom@18.2.0)(react@18.2.0):
|
||||
/@mui/material@5.15.14(@emotion/react@11.11.4)(@emotion/styled@11.11.0)(@types/react@18.2.69)(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-kEbRw6fASdQ1SQ7LVdWR5OlWV3y7Y54ZxkLzd6LV5tmz+NpO3MJKZXSfgR0LHMP7meKsPiMm4AuzV0pXDpk/BQ==}
|
||||
engines: {node: '>=12.0.0'}
|
||||
peerDependencies:
|
||||
@@ -1546,14 +1546,14 @@ packages:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@babel/runtime': 7.23.9
|
||||
'@emotion/react': 11.11.4(@types/react@18.2.67)(react@18.2.0)
|
||||
'@emotion/styled': 11.11.0(@emotion/react@11.11.4)(@types/react@18.2.67)(react@18.2.0)
|
||||
'@mui/base': 5.0.0-beta.40(@types/react@18.2.67)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@emotion/react': 11.11.4(@types/react@18.2.69)(react@18.2.0)
|
||||
'@emotion/styled': 11.11.0(@emotion/react@11.11.4)(@types/react@18.2.69)(react@18.2.0)
|
||||
'@mui/base': 5.0.0-beta.40(@types/react@18.2.69)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@mui/core-downloads-tracker': 5.15.14
|
||||
'@mui/system': 5.15.14(@emotion/react@11.11.4)(@emotion/styled@11.11.0)(@types/react@18.2.67)(react@18.2.0)
|
||||
'@mui/types': 7.2.14(@types/react@18.2.67)
|
||||
'@mui/utils': 5.15.14(@types/react@18.2.67)(react@18.2.0)
|
||||
'@types/react': 18.2.67
|
||||
'@mui/system': 5.15.14(@emotion/react@11.11.4)(@emotion/styled@11.11.0)(@types/react@18.2.69)(react@18.2.0)
|
||||
'@mui/types': 7.2.14(@types/react@18.2.69)
|
||||
'@mui/utils': 5.15.14(@types/react@18.2.69)(react@18.2.0)
|
||||
'@types/react': 18.2.69
|
||||
'@types/react-transition-group': 4.4.10
|
||||
clsx: 2.1.0
|
||||
csstype: 3.1.3
|
||||
@@ -1564,7 +1564,7 @@ packages:
|
||||
react-transition-group: 4.4.5(react-dom@18.2.0)(react@18.2.0)
|
||||
dev: false
|
||||
|
||||
/@mui/private-theming@5.15.14(@types/react@18.2.67)(react@18.2.0):
|
||||
/@mui/private-theming@5.15.14(@types/react@18.2.69)(react@18.2.0):
|
||||
resolution: {integrity: sha512-UH0EiZckOWcxiXLX3Jbb0K7rC8mxTr9L9l6QhOZxYc4r8FHUkefltV9VDGLrzCaWh30SQiJvAEd7djX3XXY6Xw==}
|
||||
engines: {node: '>=12.0.0'}
|
||||
peerDependencies:
|
||||
@@ -1575,8 +1575,8 @@ packages:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@babel/runtime': 7.24.1
|
||||
'@mui/utils': 5.15.14(@types/react@18.2.67)(react@18.2.0)
|
||||
'@types/react': 18.2.67
|
||||
'@mui/utils': 5.15.14(@types/react@18.2.69)(react@18.2.0)
|
||||
'@types/react': 18.2.69
|
||||
prop-types: 15.8.1
|
||||
react: 18.2.0
|
||||
dev: false
|
||||
@@ -1596,14 +1596,14 @@ packages:
|
||||
dependencies:
|
||||
'@babel/runtime': 7.24.1
|
||||
'@emotion/cache': 11.11.0
|
||||
'@emotion/react': 11.11.4(@types/react@18.2.67)(react@18.2.0)
|
||||
'@emotion/styled': 11.11.0(@emotion/react@11.11.4)(@types/react@18.2.67)(react@18.2.0)
|
||||
'@emotion/react': 11.11.4(@types/react@18.2.69)(react@18.2.0)
|
||||
'@emotion/styled': 11.11.0(@emotion/react@11.11.4)(@types/react@18.2.69)(react@18.2.0)
|
||||
csstype: 3.1.3
|
||||
prop-types: 15.8.1
|
||||
react: 18.2.0
|
||||
dev: false
|
||||
|
||||
/@mui/system@5.15.14(@emotion/react@11.11.4)(@emotion/styled@11.11.0)(@types/react@18.2.67)(react@18.2.0):
|
||||
/@mui/system@5.15.14(@emotion/react@11.11.4)(@emotion/styled@11.11.0)(@types/react@18.2.69)(react@18.2.0):
|
||||
resolution: {integrity: sha512-auXLXzUaCSSOLqJXmsAaq7P96VPRXg2Rrz6OHNV7lr+kB8lobUF+/N84Vd9C4G/wvCXYPs5TYuuGBRhcGbiBGg==}
|
||||
engines: {node: '>=12.0.0'}
|
||||
peerDependencies:
|
||||
@@ -1620,20 +1620,20 @@ packages:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@babel/runtime': 7.24.1
|
||||
'@emotion/react': 11.11.4(@types/react@18.2.67)(react@18.2.0)
|
||||
'@emotion/styled': 11.11.0(@emotion/react@11.11.4)(@types/react@18.2.67)(react@18.2.0)
|
||||
'@mui/private-theming': 5.15.14(@types/react@18.2.67)(react@18.2.0)
|
||||
'@emotion/react': 11.11.4(@types/react@18.2.69)(react@18.2.0)
|
||||
'@emotion/styled': 11.11.0(@emotion/react@11.11.4)(@types/react@18.2.69)(react@18.2.0)
|
||||
'@mui/private-theming': 5.15.14(@types/react@18.2.69)(react@18.2.0)
|
||||
'@mui/styled-engine': 5.15.14(@emotion/react@11.11.4)(@emotion/styled@11.11.0)(react@18.2.0)
|
||||
'@mui/types': 7.2.14(@types/react@18.2.67)
|
||||
'@mui/utils': 5.15.14(@types/react@18.2.67)(react@18.2.0)
|
||||
'@types/react': 18.2.67
|
||||
'@mui/types': 7.2.14(@types/react@18.2.69)
|
||||
'@mui/utils': 5.15.14(@types/react@18.2.69)(react@18.2.0)
|
||||
'@types/react': 18.2.69
|
||||
clsx: 2.1.0
|
||||
csstype: 3.1.3
|
||||
prop-types: 15.8.1
|
||||
react: 18.2.0
|
||||
dev: false
|
||||
|
||||
/@mui/types@7.2.14(@types/react@18.2.67):
|
||||
/@mui/types@7.2.14(@types/react@18.2.69):
|
||||
resolution: {integrity: sha512-MZsBZ4q4HfzBsywtXgM1Ksj6HDThtiwmOKUXH1pKYISI9gAVXCNHNpo7TlGoGrBaYWZTdNoirIN7JsQcQUjmQQ==}
|
||||
peerDependencies:
|
||||
'@types/react': ^17.0.0 || ^18.0.0
|
||||
@@ -1641,10 +1641,10 @@ packages:
|
||||
'@types/react':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@types/react': 18.2.67
|
||||
'@types/react': 18.2.69
|
||||
dev: false
|
||||
|
||||
/@mui/utils@5.15.14(@types/react@18.2.67)(react@18.2.0):
|
||||
/@mui/utils@5.15.14(@types/react@18.2.69)(react@18.2.0):
|
||||
resolution: {integrity: sha512-0lF/7Hh/ezDv5X7Pry6enMsbYyGKjADzvHyo3Qrc/SSlTsQ1VkbDMbH0m2t3OR5iIVLwMoxwM7yGd+6FCMtTFA==}
|
||||
engines: {node: '>=12.0.0'}
|
||||
peerDependencies:
|
||||
@@ -1656,13 +1656,13 @@ packages:
|
||||
dependencies:
|
||||
'@babel/runtime': 7.24.1
|
||||
'@types/prop-types': 15.7.11
|
||||
'@types/react': 18.2.67
|
||||
'@types/react': 18.2.69
|
||||
prop-types: 15.8.1
|
||||
react: 18.2.0
|
||||
react-is: 18.2.0
|
||||
dev: false
|
||||
|
||||
/@mui/x-data-grid@7.0.0(@emotion/react@11.11.4)(@emotion/styled@11.11.0)(@mui/material@5.15.14)(@types/react@18.2.67)(react-dom@18.2.0)(react@18.2.0):
|
||||
/@mui/x-data-grid@7.0.0(@emotion/react@11.11.4)(@emotion/styled@11.11.0)(@mui/material@5.15.14)(@types/react@18.2.69)(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-Nwwfr+ot/di0oH/pVwIxKV2QD7QyUY/MKkTWRSKzQoJw2aiFQf1Usmvq9Fu1qsCsvMmqIFaToY7972p0cczRjw==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
peerDependencies:
|
||||
@@ -1671,9 +1671,9 @@ packages:
|
||||
react-dom: ^17.0.0 || ^18.0.0
|
||||
dependencies:
|
||||
'@babel/runtime': 7.24.1
|
||||
'@mui/material': 5.15.14(@emotion/react@11.11.4)(@emotion/styled@11.11.0)(@types/react@18.2.67)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@mui/system': 5.15.14(@emotion/react@11.11.4)(@emotion/styled@11.11.0)(@types/react@18.2.67)(react@18.2.0)
|
||||
'@mui/utils': 5.15.14(@types/react@18.2.67)(react@18.2.0)
|
||||
'@mui/material': 5.15.14(@emotion/react@11.11.4)(@emotion/styled@11.11.0)(@types/react@18.2.69)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@mui/system': 5.15.14(@emotion/react@11.11.4)(@emotion/styled@11.11.0)(@types/react@18.2.69)(react@18.2.0)
|
||||
'@mui/utils': 5.15.14(@types/react@18.2.69)(react@18.2.0)
|
||||
clsx: 2.1.0
|
||||
prop-types: 15.8.1
|
||||
react: 18.2.0
|
||||
@@ -2309,16 +2309,16 @@ packages:
|
||||
/@types/react-dom@18.2.22:
|
||||
resolution: {integrity: sha512-fHkBXPeNtfvri6gdsMYyW+dW7RXFo6Ad09nLFK0VQWR7yGLai/Cyvyj696gbwYvBnhGtevUG9cET0pmUbMtoPQ==}
|
||||
dependencies:
|
||||
'@types/react': 18.2.67
|
||||
'@types/react': 18.2.69
|
||||
dev: true
|
||||
|
||||
/@types/react-transition-group@4.4.10:
|
||||
resolution: {integrity: sha512-hT/+s0VQs2ojCX823m60m5f0sL5idt9SO6Tj6Dg+rdphGPIeJbJ6CxvBYkgkGKrYeDjvIpKTR38UzmtHJOGW3Q==}
|
||||
dependencies:
|
||||
'@types/react': 18.2.67
|
||||
'@types/react': 18.2.69
|
||||
|
||||
/@types/react@18.2.67:
|
||||
resolution: {integrity: sha512-vkIE2vTIMHQ/xL0rgmuoECBCkZFZeHr49HeWSc24AptMbNRo7pwSBvj73rlJJs9fGKj0koS+V7kQB1jHS0uCgw==}
|
||||
/@types/react@18.2.69:
|
||||
resolution: {integrity: sha512-W1HOMUWY/1Yyw0ba5TkCV+oqynRjG7BnteBB+B7JmAK7iw3l2SW+VGOxL+akPweix6jk2NNJtyJKpn4TkpfK3Q==}
|
||||
dependencies:
|
||||
'@types/prop-types': 15.7.11
|
||||
'@types/scheduler': 0.16.2
|
||||
@@ -2474,7 +2474,7 @@ packages:
|
||||
/@ungap/structured-clone@1.2.0:
|
||||
resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==}
|
||||
|
||||
/@vitejs/plugin-react@4.2.1(vite@5.2.3):
|
||||
/@vitejs/plugin-react@4.2.1(vite@5.2.4):
|
||||
resolution: {integrity: sha512-oojO9IDc4nCUUi8qIR11KoQm0XFFLIwsRBwHRR4d/88IWghn1y6ckz/bJ8GHDCsYEJee8mDzqtJxh15/cisJNQ==}
|
||||
engines: {node: ^14.18.0 || >=16.0.0}
|
||||
peerDependencies:
|
||||
@@ -2485,7 +2485,7 @@ packages:
|
||||
'@babel/plugin-transform-react-jsx-source': 7.23.3(@babel/core@7.23.6)
|
||||
'@types/babel__core': 7.20.5
|
||||
react-refresh: 0.14.0
|
||||
vite: 5.2.3(@types/node@20.11.30)(sass@1.72.0)
|
||||
vite: 5.2.4(@types/node@20.11.30)(sass@1.72.0)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: true
|
||||
@@ -5625,7 +5625,7 @@ packages:
|
||||
/ms@2.1.2:
|
||||
resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==}
|
||||
|
||||
/mui-color-input@2.0.3(@emotion/react@11.11.4)(@emotion/styled@11.11.0)(@mui/material@5.15.14)(@types/react@18.2.67)(react-dom@18.2.0)(react@18.2.0):
|
||||
/mui-color-input@2.0.3(@emotion/react@11.11.4)(@emotion/styled@11.11.0)(@mui/material@5.15.14)(@types/react@18.2.69)(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-rAd040qQ0Y+8dk4gE8kkCiJ/vCgA0j4vv1quJ43BfORTFE3uHarHj0xY1Vo9CPbojtx1f5vW+CjckYPRIZPIRg==}
|
||||
peerDependencies:
|
||||
'@emotion/react': ^11.5.0
|
||||
@@ -5639,10 +5639,10 @@ packages:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@ctrl/tinycolor': 4.0.3
|
||||
'@emotion/react': 11.11.4(@types/react@18.2.67)(react@18.2.0)
|
||||
'@emotion/styled': 11.11.0(@emotion/react@11.11.4)(@types/react@18.2.67)(react@18.2.0)
|
||||
'@mui/material': 5.15.14(@emotion/react@11.11.4)(@emotion/styled@11.11.0)(@types/react@18.2.67)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@types/react': 18.2.67
|
||||
'@emotion/react': 11.11.4(@types/react@18.2.69)(react@18.2.0)
|
||||
'@emotion/styled': 11.11.0(@emotion/react@11.11.4)(@types/react@18.2.69)(react@18.2.0)
|
||||
'@mui/material': 5.15.14(@emotion/react@11.11.4)(@emotion/styled@11.11.0)(@types/react@18.2.69)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@types/react': 18.2.69
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0(react@18.2.0)
|
||||
dev: false
|
||||
@@ -6164,14 +6164,14 @@ packages:
|
||||
resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==}
|
||||
dev: false
|
||||
|
||||
/react-markdown@9.0.1(@types/react@18.2.67)(react@18.2.0):
|
||||
/react-markdown@9.0.1(@types/react@18.2.69)(react@18.2.0):
|
||||
resolution: {integrity: sha512-186Gw/vF1uRkydbsOIkcGXw7aHq0sZOCRFFjGrr7b9+nVZg4UfA4enXCaxm4fUzecU38sWfrNDitGhshuU7rdg==}
|
||||
peerDependencies:
|
||||
'@types/react': '>=18'
|
||||
react: '>=18'
|
||||
dependencies:
|
||||
'@types/hast': 3.0.4
|
||||
'@types/react': 18.2.67
|
||||
'@types/react': 18.2.69
|
||||
devlop: 1.1.0
|
||||
hast-util-to-jsx-runtime: 2.3.0
|
||||
html-url-attributes: 3.0.0
|
||||
@@ -7334,7 +7334,7 @@ packages:
|
||||
monaco-editor: 0.47.0
|
||||
dev: true
|
||||
|
||||
/vite-plugin-svgr@4.2.0(typescript@5.4.3)(vite@5.2.3):
|
||||
/vite-plugin-svgr@4.2.0(typescript@5.4.3)(vite@5.2.4):
|
||||
resolution: {integrity: sha512-SC7+FfVtNQk7So0XMjrrtLAbEC8qjFPifyD7+fs/E6aaNdVde6umlVVh0QuwDLdOMu7vp5RiGFsB70nj5yo0XA==}
|
||||
peerDependencies:
|
||||
vite: ^2.6.0 || 3 || 4 || 5
|
||||
@@ -7342,15 +7342,15 @@ packages:
|
||||
'@rollup/pluginutils': 5.0.5
|
||||
'@svgr/core': 8.1.0(typescript@5.4.3)
|
||||
'@svgr/plugin-jsx': 8.1.0(@svgr/core@8.1.0)
|
||||
vite: 5.2.3(@types/node@20.11.30)(sass@1.72.0)
|
||||
vite: 5.2.4(@types/node@20.11.30)(sass@1.72.0)
|
||||
transitivePeerDependencies:
|
||||
- rollup
|
||||
- supports-color
|
||||
- typescript
|
||||
dev: true
|
||||
|
||||
/vite@5.2.3(@types/node@20.11.30)(sass@1.72.0):
|
||||
resolution: {integrity: sha512-+i1oagbvkVIhEy9TnEV+fgXsng13nZM90JQbrcPrf6DvW2mXARlz+DK7DLiDP+qeKoD1FCVx/1SpFL1CLq9Mhw==}
|
||||
/vite@5.2.4(@types/node@20.11.30)(sass@1.72.0):
|
||||
resolution: {integrity: sha512-vjFghvHWidBTinu5TCymJk/lRHlR5ljqB83yugr0HA1xspUPdOZHqbqDLnZ8f9/jINrtFHTCYYyIUi+o+Q5iyg==}
|
||||
engines: {node: ^18.0.0 || >=20.0.0}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
|
||||
+149
-9
@@ -5,8 +5,12 @@ import (
|
||||
"crypto/x509"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/netip"
|
||||
"os"
|
||||
"runtime"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -20,6 +24,7 @@ import (
|
||||
"github.com/apernet/hysteria/app/internal/redirect"
|
||||
"github.com/apernet/hysteria/app/internal/socks5"
|
||||
"github.com/apernet/hysteria/app/internal/tproxy"
|
||||
"github.com/apernet/hysteria/app/internal/tun"
|
||||
"github.com/apernet/hysteria/app/internal/url"
|
||||
"github.com/apernet/hysteria/app/internal/utils"
|
||||
"github.com/apernet/hysteria/core/client"
|
||||
@@ -65,6 +70,7 @@ type clientConfig struct {
|
||||
TCPTProxy *tcpTProxyConfig `mapstructure:"tcpTProxy"`
|
||||
UDPTProxy *udpTProxyConfig `mapstructure:"udpTProxy"`
|
||||
TCPRedirect *tcpRedirectConfig `mapstructure:"tcpRedirect"`
|
||||
TUN *tunConfig `mapstructure:"tun"`
|
||||
}
|
||||
|
||||
type clientConfigTransportUDP struct {
|
||||
@@ -145,6 +151,23 @@ type tcpRedirectConfig struct {
|
||||
Listen string `mapstructure:"listen"`
|
||||
}
|
||||
|
||||
type tunConfig struct {
|
||||
Name string `mapstructure:"name"`
|
||||
MTU uint32 `mapstructure:"mtu"`
|
||||
Timeout time.Duration `mapstructure:"timeout"`
|
||||
Address struct {
|
||||
IPv4 string `mapstructure:"ipv4"`
|
||||
IPv6 string `mapstructure:"ipv6"`
|
||||
} `mapstructure:"address"`
|
||||
Route *struct {
|
||||
Strict bool `mapstructure:"strict"`
|
||||
IPv4 []string `mapstructure:"ipv4"`
|
||||
IPv6 []string `mapstructure:"ipv6"`
|
||||
IPv4Exclude []string `mapstructure:"ipv4Exclude"`
|
||||
IPv6Exclude []string `mapstructure:"ipv6Exclude"`
|
||||
} `mapstructure:"route"`
|
||||
}
|
||||
|
||||
func (c *clientConfig) fillServerAddr(hyConfig *client.Config) error {
|
||||
if c.Server == "" {
|
||||
return configError{Field: "server", Err: errors.New("server address is empty")}
|
||||
@@ -459,6 +482,11 @@ func runClient(cmd *cobra.Command, args []string) {
|
||||
return clientTCPRedirect(*config.TCPRedirect, c)
|
||||
})
|
||||
}
|
||||
if config.TUN != nil {
|
||||
runner.Add("TUN", func() error {
|
||||
return clientTUN(*config.TUN, c)
|
||||
})
|
||||
}
|
||||
|
||||
runner.Run()
|
||||
}
|
||||
@@ -656,6 +684,92 @@ func clientTCPRedirect(config tcpRedirectConfig, c client.Client) error {
|
||||
return p.ListenAndServe(laddr)
|
||||
}
|
||||
|
||||
func clientTUN(config tunConfig, c client.Client) error {
|
||||
supportedPlatforms := []string{"linux", "darwin", "windows", "android"}
|
||||
if !slices.Contains(supportedPlatforms, runtime.GOOS) {
|
||||
logger.Error("TUN is not supported on this platform", zap.String("platform", runtime.GOOS))
|
||||
}
|
||||
if config.Name == "" {
|
||||
return configError{Field: "name", Err: errors.New("name is empty")}
|
||||
}
|
||||
if config.MTU == 0 {
|
||||
config.MTU = 1500
|
||||
}
|
||||
timeout := int64(config.Timeout.Seconds())
|
||||
if timeout == 0 {
|
||||
timeout = 300
|
||||
}
|
||||
if config.Address.IPv4 == "" {
|
||||
config.Address.IPv4 = "100.100.100.101/30"
|
||||
}
|
||||
prefix4, err := netip.ParsePrefix(config.Address.IPv4)
|
||||
if err != nil {
|
||||
return configError{Field: "address.ipv4", Err: err}
|
||||
}
|
||||
if config.Address.IPv6 == "" {
|
||||
config.Address.IPv6 = "2001::ffff:ffff:ffff:fff1/126"
|
||||
}
|
||||
prefix6, err := netip.ParsePrefix(config.Address.IPv6)
|
||||
if err != nil {
|
||||
return configError{Field: "address.ipv6", Err: err}
|
||||
}
|
||||
server := &tun.Server{
|
||||
HyClient: c,
|
||||
EventLogger: &tunLogger{},
|
||||
Logger: logger,
|
||||
IfName: config.Name,
|
||||
MTU: config.MTU,
|
||||
Timeout: timeout,
|
||||
Inet4Address: []netip.Prefix{prefix4},
|
||||
Inet6Address: []netip.Prefix{prefix6},
|
||||
}
|
||||
if config.Route != nil {
|
||||
server.AutoRoute = true
|
||||
server.StructRoute = config.Route.Strict
|
||||
|
||||
parsePrefixes := func(field string, ss []string) ([]netip.Prefix, error) {
|
||||
var prefixes []netip.Prefix
|
||||
for i, s := range ss {
|
||||
var p netip.Prefix
|
||||
if strings.Contains(s, "/") {
|
||||
var err error
|
||||
p, err = netip.ParsePrefix(s)
|
||||
if err != nil {
|
||||
return nil, configError{Field: fmt.Sprintf("%s[%d]", field, i), Err: err}
|
||||
}
|
||||
} else {
|
||||
pa, err := netip.ParseAddr(s)
|
||||
if err != nil {
|
||||
return nil, configError{Field: fmt.Sprintf("%s[%d]", field, i), Err: err}
|
||||
}
|
||||
p = netip.PrefixFrom(pa, pa.BitLen())
|
||||
}
|
||||
prefixes = append(prefixes, p)
|
||||
}
|
||||
return prefixes, nil
|
||||
}
|
||||
|
||||
server.Inet4RouteAddress, err = parsePrefixes("route.ipv4", config.Route.IPv4)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
server.Inet6RouteAddress, err = parsePrefixes("route.ipv6", config.Route.IPv6)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
server.Inet4RouteExcludeAddress, err = parsePrefixes("route.ipv4Exclude", config.Route.IPv4Exclude)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
server.Inet6RouteExcludeAddress, err = parsePrefixes("route.ipv6Exclude", config.Route.IPv6Exclude)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
logger.Info("TUN listening", zap.String("interface", config.Name))
|
||||
return server.Serve()
|
||||
}
|
||||
|
||||
// parseServerAddrString parses server address string.
|
||||
// Server address can be in either "host:port" or "host" format (in which case we assume port 443).
|
||||
func parseServerAddrString(addrStr string) (host, port, hostPort string) {
|
||||
@@ -715,7 +829,7 @@ func (l *socks5Logger) TCPError(addr net.Addr, reqAddr string, err error) {
|
||||
if err == nil {
|
||||
logger.Debug("SOCKS5 TCP closed", zap.String("addr", addr.String()), zap.String("reqAddr", reqAddr))
|
||||
} else {
|
||||
logger.Error("SOCKS5 TCP error", zap.String("addr", addr.String()), zap.String("reqAddr", reqAddr), zap.Error(err))
|
||||
logger.Warn("SOCKS5 TCP error", zap.String("addr", addr.String()), zap.String("reqAddr", reqAddr), zap.Error(err))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -727,7 +841,7 @@ func (l *socks5Logger) UDPError(addr net.Addr, err error) {
|
||||
if err == nil {
|
||||
logger.Debug("SOCKS5 UDP closed", zap.String("addr", addr.String()))
|
||||
} else {
|
||||
logger.Error("SOCKS5 UDP error", zap.String("addr", addr.String()), zap.Error(err))
|
||||
logger.Warn("SOCKS5 UDP error", zap.String("addr", addr.String()), zap.Error(err))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -741,7 +855,7 @@ func (l *httpLogger) ConnectError(addr net.Addr, reqAddr string, err error) {
|
||||
if err == nil {
|
||||
logger.Debug("HTTP CONNECT closed", zap.String("addr", addr.String()), zap.String("reqAddr", reqAddr))
|
||||
} else {
|
||||
logger.Error("HTTP CONNECT error", zap.String("addr", addr.String()), zap.String("reqAddr", reqAddr), zap.Error(err))
|
||||
logger.Warn("HTTP CONNECT error", zap.String("addr", addr.String()), zap.String("reqAddr", reqAddr), zap.Error(err))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -753,7 +867,7 @@ func (l *httpLogger) HTTPError(addr net.Addr, reqURL string, err error) {
|
||||
if err == nil {
|
||||
logger.Debug("HTTP closed", zap.String("addr", addr.String()), zap.String("reqURL", reqURL))
|
||||
} else {
|
||||
logger.Error("HTTP error", zap.String("addr", addr.String()), zap.String("reqURL", reqURL), zap.Error(err))
|
||||
logger.Warn("HTTP error", zap.String("addr", addr.String()), zap.String("reqURL", reqURL), zap.Error(err))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -767,7 +881,7 @@ func (l *tcpLogger) Error(addr net.Addr, err error) {
|
||||
if err == nil {
|
||||
logger.Debug("TCP forwarding closed", zap.String("addr", addr.String()))
|
||||
} else {
|
||||
logger.Error("TCP forwarding error", zap.String("addr", addr.String()), zap.Error(err))
|
||||
logger.Warn("TCP forwarding error", zap.String("addr", addr.String()), zap.Error(err))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -781,7 +895,7 @@ func (l *udpLogger) Error(addr net.Addr, err error) {
|
||||
if err == nil {
|
||||
logger.Debug("UDP forwarding closed", zap.String("addr", addr.String()))
|
||||
} else {
|
||||
logger.Error("UDP forwarding error", zap.String("addr", addr.String()), zap.Error(err))
|
||||
logger.Warn("UDP forwarding error", zap.String("addr", addr.String()), zap.Error(err))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -795,7 +909,7 @@ func (l *tcpTProxyLogger) Error(addr, reqAddr net.Addr, err error) {
|
||||
if err == nil {
|
||||
logger.Debug("TCP transparent proxy closed", zap.String("addr", addr.String()), zap.String("reqAddr", reqAddr.String()))
|
||||
} else {
|
||||
logger.Error("TCP transparent proxy error", zap.String("addr", addr.String()), zap.String("reqAddr", reqAddr.String()), zap.Error(err))
|
||||
logger.Warn("TCP transparent proxy error", zap.String("addr", addr.String()), zap.String("reqAddr", reqAddr.String()), zap.Error(err))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -809,7 +923,7 @@ func (l *udpTProxyLogger) Error(addr, reqAddr net.Addr, err error) {
|
||||
if err == nil {
|
||||
logger.Debug("UDP transparent proxy closed", zap.String("addr", addr.String()), zap.String("reqAddr", reqAddr.String()))
|
||||
} else {
|
||||
logger.Error("UDP transparent proxy error", zap.String("addr", addr.String()), zap.String("reqAddr", reqAddr.String()), zap.Error(err))
|
||||
logger.Warn("UDP transparent proxy error", zap.String("addr", addr.String()), zap.String("reqAddr", reqAddr.String()), zap.Error(err))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -823,6 +937,32 @@ func (l *tcpRedirectLogger) Error(addr, reqAddr net.Addr, err error) {
|
||||
if err == nil {
|
||||
logger.Debug("TCP redirect closed", zap.String("addr", addr.String()), zap.String("reqAddr", reqAddr.String()))
|
||||
} else {
|
||||
logger.Error("TCP redirect error", zap.String("addr", addr.String()), zap.String("reqAddr", reqAddr.String()), zap.Error(err))
|
||||
logger.Warn("TCP redirect error", zap.String("addr", addr.String()), zap.String("reqAddr", reqAddr.String()), zap.Error(err))
|
||||
}
|
||||
}
|
||||
|
||||
type tunLogger struct{}
|
||||
|
||||
func (l *tunLogger) TCPRequest(addr, reqAddr string) {
|
||||
logger.Debug("TUN TCP request", zap.String("addr", addr), zap.String("reqAddr", reqAddr))
|
||||
}
|
||||
|
||||
func (l *tunLogger) TCPError(addr, reqAddr string, err error) {
|
||||
if err == nil {
|
||||
logger.Debug("TUN TCP closed", zap.String("addr", addr), zap.String("reqAddr", reqAddr))
|
||||
} else {
|
||||
logger.Warn("TUN TCP error", zap.String("addr", addr), zap.String("reqAddr", reqAddr), zap.Error(err))
|
||||
}
|
||||
}
|
||||
|
||||
func (l *tunLogger) UDPRequest(addr string) {
|
||||
logger.Debug("TUN UDP request", zap.String("addr", addr))
|
||||
}
|
||||
|
||||
func (l *tunLogger) UDPError(addr string, err error) {
|
||||
if err == nil {
|
||||
logger.Debug("TUN UDP closed", zap.String("addr", addr))
|
||||
} else {
|
||||
logger.Warn("TUN UDP error", zap.String("addr", addr), zap.Error(err))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,6 +88,28 @@ func TestClientConfig(t *testing.T) {
|
||||
TCPRedirect: &tcpRedirectConfig{
|
||||
Listen: "127.0.0.1:3500",
|
||||
},
|
||||
TUN: &tunConfig{
|
||||
Name: "hytun",
|
||||
MTU: 1500,
|
||||
Timeout: 60 * time.Second,
|
||||
Address: struct {
|
||||
IPv4 string `mapstructure:"ipv4"`
|
||||
IPv6 string `mapstructure:"ipv6"`
|
||||
}{IPv4: "100.100.100.101/30", IPv6: "2001::ffff:ffff:ffff:fff1/126"},
|
||||
Route: &struct {
|
||||
Strict bool `mapstructure:"strict"`
|
||||
IPv4 []string `mapstructure:"ipv4"`
|
||||
IPv6 []string `mapstructure:"ipv6"`
|
||||
IPv4Exclude []string `mapstructure:"ipv4Exclude"`
|
||||
IPv6Exclude []string `mapstructure:"ipv6Exclude"`
|
||||
}{
|
||||
Strict: true,
|
||||
IPv4: []string{"0.0.0.0/0"},
|
||||
IPv6: []string{"2000::/3"},
|
||||
IPv4Exclude: []string{"192.0.2.1/32"},
|
||||
IPv6Exclude: []string{"2001:db8::1/128"},
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -65,3 +65,17 @@ udpTProxy:
|
||||
|
||||
tcpRedirect:
|
||||
listen: 127.0.0.1:3500
|
||||
|
||||
tun:
|
||||
name: "hytun"
|
||||
mtu: 1500
|
||||
timeout: 1m
|
||||
address:
|
||||
ipv4: 100.100.100.101/30
|
||||
ipv6: 2001::ffff:ffff:ffff:fff1/126
|
||||
route:
|
||||
strict: true
|
||||
ipv4: [0.0.0.0/0]
|
||||
ipv6: ["2000::/3"]
|
||||
ipv4Exclude: [192.0.2.1/32]
|
||||
ipv6Exclude: ["2001:db8::1/128"]
|
||||
|
||||
@@ -815,7 +815,7 @@ func (l *serverLogger) TCPError(addr net.Addr, id, reqAddr string, err error) {
|
||||
if err == nil {
|
||||
logger.Debug("TCP closed", zap.String("addr", addr.String()), zap.String("id", id), zap.String("reqAddr", reqAddr))
|
||||
} else {
|
||||
logger.Error("TCP error", zap.String("addr", addr.String()), zap.String("id", id), zap.String("reqAddr", reqAddr), zap.Error(err))
|
||||
logger.Warn("TCP error", zap.String("addr", addr.String()), zap.String("id", id), zap.String("reqAddr", reqAddr), zap.Error(err))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -827,7 +827,7 @@ func (l *serverLogger) UDPError(addr net.Addr, id string, sessionID uint32, err
|
||||
if err == nil {
|
||||
logger.Debug("UDP closed", zap.String("addr", addr.String()), zap.String("id", id), zap.Uint32("sessionID", sessionID))
|
||||
} else {
|
||||
logger.Error("UDP error", zap.String("addr", addr.String()), zap.String("id", id), zap.Uint32("sessionID", sessionID), zap.Error(err))
|
||||
logger.Warn("UDP error", zap.String("addr", addr.String()), zap.String("id", id), zap.Uint32("sessionID", sessionID), zap.Error(err))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+11
-4
@@ -6,9 +6,11 @@ require (
|
||||
github.com/apernet/go-tproxy v0.0.0-20230809025308-8f4723fd742f
|
||||
github.com/apernet/hysteria/core v0.0.0-00010101000000-000000000000
|
||||
github.com/apernet/hysteria/extras v0.0.0-00010101000000-000000000000
|
||||
github.com/apernet/sing-tun v0.2.6-0.20240323130332-b9f6511036ad
|
||||
github.com/caddyserver/certmagic v0.17.2
|
||||
github.com/mdp/qrterminal/v3 v3.1.1
|
||||
github.com/mholt/acmez v1.0.4
|
||||
github.com/sagernet/sing v0.3.2
|
||||
github.com/spf13/cobra v1.7.0
|
||||
github.com/spf13/viper v1.15.0
|
||||
github.com/stretchr/testify v1.8.4
|
||||
@@ -20,7 +22,8 @@ require (
|
||||
github.com/apernet/quic-go v0.41.1-0.20240301003057-e18162de481d // indirect
|
||||
github.com/babolivier/go-doh-client v0.0.0-20201028162107-a76cff4cb8b6 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/fsnotify/fsnotify v1.6.0 // indirect
|
||||
github.com/fsnotify/fsnotify v1.7.0 // indirect
|
||||
github.com/go-ole/go-ole v1.3.0 // indirect
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
|
||||
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 // indirect
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.5 // indirect
|
||||
@@ -36,6 +39,8 @@ require (
|
||||
github.com/pelletier/go-toml/v2 v2.0.6 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/quic-go/qpack v0.4.0 // indirect
|
||||
github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97 // indirect
|
||||
github.com/scjalliance/comshim v0.0.0-20230315213746-5e51f40bd3b9 // indirect
|
||||
github.com/spf13/afero v1.9.3 // indirect
|
||||
github.com/spf13/cast v1.5.0 // indirect
|
||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||
@@ -43,14 +48,16 @@ require (
|
||||
github.com/stretchr/objx v0.5.0 // indirect
|
||||
github.com/subosito/gotenv v1.4.2 // indirect
|
||||
github.com/txthinking/runnergroup v0.0.0-20210608031112-152c7c4432bf // indirect
|
||||
github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 // indirect
|
||||
go.uber.org/atomic v1.11.0 // indirect
|
||||
go.uber.org/mock v0.3.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
golang.org/x/crypto v0.17.0 // indirect
|
||||
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba // indirect
|
||||
golang.org/x/crypto v0.19.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20221205204356-47842c84f3db // indirect
|
||||
golang.org/x/mod v0.12.0 // indirect
|
||||
golang.org/x/net v0.17.0 // indirect
|
||||
golang.org/x/sys v0.15.0 // indirect
|
||||
golang.org/x/net v0.21.0 // indirect
|
||||
golang.org/x/sys v0.17.0 // indirect
|
||||
golang.org/x/text v0.14.0 // indirect
|
||||
golang.org/x/tools v0.11.1 // indirect
|
||||
google.golang.org/protobuf v1.33.0 // indirect
|
||||
|
||||
+24
-9
@@ -42,6 +42,8 @@ github.com/apernet/go-tproxy v0.0.0-20230809025308-8f4723fd742f h1:uVh0qpEslrWjg
|
||||
github.com/apernet/go-tproxy v0.0.0-20230809025308-8f4723fd742f/go.mod h1:xkkq9D4ygcldQQhKS/w9CadiCKwCngU7K9E3DaKahpM=
|
||||
github.com/apernet/quic-go v0.41.1-0.20240301003057-e18162de481d h1:K1DMSNtPcaZ/lihYmOHnjThNfUX7cD6SNuVRFnVLVmI=
|
||||
github.com/apernet/quic-go v0.41.1-0.20240301003057-e18162de481d/go.mod h1:4GInxO6ypy63J2NaO5rQx1wRp6K8YHI6zqLG+VswU6I=
|
||||
github.com/apernet/sing-tun v0.2.6-0.20240323130332-b9f6511036ad h1:QzQ2sKpc9o42HNRR8ukM5uMC/RzR2HgZd/Nvaqol2C0=
|
||||
github.com/apernet/sing-tun v0.2.6-0.20240323130332-b9f6511036ad/go.mod h1:S5IydyLSN/QAfvY+r2GoomPJ6hidtXWm/Ad18sJVssk=
|
||||
github.com/babolivier/go-doh-client v0.0.0-20201028162107-a76cff4cb8b6 h1:4NNbNM2Iq/k57qEu7WfL67UrbPq1uFWxW4qODCohi+0=
|
||||
github.com/babolivier/go-doh-client v0.0.0-20201028162107-a76cff4cb8b6/go.mod h1:J29hk+f9lJrblVIfiJOtTFk+OblBawmib4uz/VdKzlg=
|
||||
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
|
||||
@@ -68,13 +70,15 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.m
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE=
|
||||
github.com/frankban/quicktest v1.14.3/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps=
|
||||
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
|
||||
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
|
||||
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
|
||||
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
|
||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
|
||||
github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
|
||||
github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
@@ -196,6 +200,12 @@ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR
|
||||
github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k=
|
||||
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97 h1:iL5gZI3uFp0X6EslacyapiRz7LLSJyr4RajF/BhMVyE=
|
||||
github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97/go.mod h1:xLnfdiJbSp8rNqYEdIW/6eDO4mVoogml14Bh2hSiFpM=
|
||||
github.com/sagernet/sing v0.3.2 h1:CwWcxUBPkMvwgfe2/zUgY5oHG9qOL8Aob/evIFYK9jo=
|
||||
github.com/sagernet/sing v0.3.2/go.mod h1:qHySJ7u8po9DABtMYEkNBcOumx7ZZJf/fbv2sfTkNHE=
|
||||
github.com/scjalliance/comshim v0.0.0-20230315213746-5e51f40bd3b9 h1:rc/CcqLH3lh8n+csdOuDfP+NuykE0U6AeYSJJHKDgSg=
|
||||
github.com/scjalliance/comshim v0.0.0-20230315213746-5e51f40bd3b9/go.mod h1:a/83NAfUXvEuLpmxDssAXxgUgrEy12MId3Wd7OTs76s=
|
||||
github.com/spf13/afero v1.9.3 h1:41FoI0fD7OR7mGcKE/aOiLkGreyf8ifIOQmJANWogMk=
|
||||
github.com/spf13/afero v1.9.3/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y=
|
||||
github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w=
|
||||
@@ -229,6 +239,8 @@ github.com/txthinking/runnergroup v0.0.0-20210608031112-152c7c4432bf h1:7PflaKRt
|
||||
github.com/txthinking/runnergroup v0.0.0-20210608031112-152c7c4432bf/go.mod h1:CLUSJbazqETbaR+i0YAhXBICV9TrKH93pziccMhmhpM=
|
||||
github.com/txthinking/socks5 v0.0.0-20230325130024-4230056ae301 h1:d/Wr/Vl/wiJHc3AHYbYs5I3PucJvRuw3SvbmlIRf+oM=
|
||||
github.com/txthinking/socks5 v0.0.0-20230325130024-4230056ae301/go.mod h1:ntmMHL/xPq1WLeKiw8p/eRATaae6PiVRNipHFJxI8PM=
|
||||
github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 h1:gga7acRE695APm9hlsSMoOoE65U4/TcqNj90mc69Rlg=
|
||||
github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0=
|
||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
@@ -255,6 +267,8 @@ go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN8
|
||||
go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw=
|
||||
go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60=
|
||||
go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg=
|
||||
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba h1:0b9z3AuHCjxk0x/opv64kcgZLBseWJUpBw5I82+2U4M=
|
||||
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba/go.mod h1:PLyyIXexvUFg3Owu6p/WfdlivPbZJsZdgWZlrGope/Y=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
@@ -263,8 +277,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh
|
||||
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
|
||||
golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
|
||||
golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo=
|
||||
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
@@ -340,8 +354,8 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b
|
||||
golang.org/x/net v0.0.0-20220630215102-69896b714898/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
|
||||
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
|
||||
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
|
||||
golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=
|
||||
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
@@ -382,6 +396,7 @@ golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -405,10 +420,10 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
|
||||
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y=
|
||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
package tun
|
||||
|
||||
import (
|
||||
"github.com/sagernet/sing/common/logger"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
var _ logger.Logger = (*singLogger)(nil)
|
||||
|
||||
type singLogger struct {
|
||||
tag string
|
||||
zapLogger *zap.Logger
|
||||
}
|
||||
|
||||
func extractSingExceptions(args []any) {
|
||||
for i, arg := range args {
|
||||
if err, ok := arg.(error); ok {
|
||||
args[i] = err.Error()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (l *singLogger) Trace(args ...any) {
|
||||
if l.zapLogger == nil {
|
||||
return
|
||||
}
|
||||
extractSingExceptions(args)
|
||||
l.zapLogger.Debug(l.tag, zap.Any("args", args))
|
||||
}
|
||||
|
||||
func (l *singLogger) Debug(args ...any) {
|
||||
if l.zapLogger == nil {
|
||||
return
|
||||
}
|
||||
extractSingExceptions(args)
|
||||
l.zapLogger.Debug(l.tag, zap.Any("args", args))
|
||||
}
|
||||
|
||||
func (l *singLogger) Info(args ...any) {
|
||||
if l.zapLogger == nil {
|
||||
return
|
||||
}
|
||||
extractSingExceptions(args)
|
||||
l.zapLogger.Info(l.tag, zap.Any("args", args))
|
||||
}
|
||||
|
||||
func (l *singLogger) Warn(args ...any) {
|
||||
if l.zapLogger == nil {
|
||||
return
|
||||
}
|
||||
extractSingExceptions(args)
|
||||
l.zapLogger.Warn(l.tag, zap.Any("args", args))
|
||||
}
|
||||
|
||||
func (l *singLogger) Error(args ...any) {
|
||||
if l.zapLogger == nil {
|
||||
return
|
||||
}
|
||||
extractSingExceptions(args)
|
||||
l.zapLogger.Error(l.tag, zap.Any("args", args))
|
||||
}
|
||||
|
||||
func (l *singLogger) Fatal(args ...any) {
|
||||
if l.zapLogger == nil {
|
||||
return
|
||||
}
|
||||
extractSingExceptions(args)
|
||||
l.zapLogger.Fatal(l.tag, zap.Any("args", args))
|
||||
}
|
||||
|
||||
func (l *singLogger) Panic(args ...any) {
|
||||
if l.zapLogger == nil {
|
||||
return
|
||||
}
|
||||
extractSingExceptions(args)
|
||||
l.zapLogger.Panic(l.tag, zap.Any("args", args))
|
||||
}
|
||||
@@ -0,0 +1,230 @@
|
||||
package tun
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"net/netip"
|
||||
|
||||
tun "github.com/apernet/sing-tun"
|
||||
"github.com/sagernet/sing/common/buf"
|
||||
"github.com/sagernet/sing/common/control"
|
||||
"github.com/sagernet/sing/common/metadata"
|
||||
"github.com/sagernet/sing/common/network"
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/apernet/hysteria/core/client"
|
||||
)
|
||||
|
||||
type Server struct {
|
||||
HyClient client.Client
|
||||
EventLogger EventLogger
|
||||
|
||||
// for debugging
|
||||
Logger *zap.Logger
|
||||
|
||||
IfName string
|
||||
MTU uint32
|
||||
Timeout int64 // in seconds, also applied to TCP in system stack
|
||||
|
||||
// required by system stack
|
||||
Inet4Address []netip.Prefix
|
||||
Inet6Address []netip.Prefix
|
||||
|
||||
// auto route
|
||||
AutoRoute bool
|
||||
StructRoute bool
|
||||
Inet4RouteAddress []netip.Prefix
|
||||
Inet6RouteAddress []netip.Prefix
|
||||
Inet4RouteExcludeAddress []netip.Prefix
|
||||
Inet6RouteExcludeAddress []netip.Prefix
|
||||
}
|
||||
|
||||
type EventLogger interface {
|
||||
TCPRequest(addr, reqAddr string)
|
||||
TCPError(addr, reqAddr string, err error)
|
||||
UDPRequest(addr string)
|
||||
UDPError(addr string, err error)
|
||||
}
|
||||
|
||||
func (s *Server) Serve() error {
|
||||
tunOpts := tun.Options{
|
||||
Name: s.IfName,
|
||||
Inet4Address: s.Inet4Address,
|
||||
Inet6Address: s.Inet6Address,
|
||||
MTU: s.MTU,
|
||||
GSO: true,
|
||||
AutoRoute: s.AutoRoute,
|
||||
StrictRoute: s.StructRoute,
|
||||
Inet4RouteAddress: s.Inet4RouteAddress,
|
||||
Inet6RouteAddress: s.Inet6RouteAddress,
|
||||
Inet4RouteExcludeAddress: s.Inet4RouteExcludeAddress,
|
||||
Inet6RouteExcludeAddress: s.Inet6RouteExcludeAddress,
|
||||
Logger: &singLogger{
|
||||
tag: "tun",
|
||||
zapLogger: s.Logger,
|
||||
},
|
||||
}
|
||||
tunIf, err := tun.New(tunOpts)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create tun interface: %w", err)
|
||||
}
|
||||
defer tunIf.Close()
|
||||
|
||||
tunStack, err := tun.NewSystem(tun.StackOptions{
|
||||
Context: context.Background(),
|
||||
Tun: tunIf,
|
||||
TunOptions: tunOpts,
|
||||
UDPTimeout: s.Timeout,
|
||||
Handler: &tunHandler{s},
|
||||
Logger: &singLogger{
|
||||
tag: "tun-stack",
|
||||
zapLogger: s.Logger,
|
||||
},
|
||||
ForwarderBindInterface: true,
|
||||
InterfaceFinder: &interfaceFinder{},
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create tun stack: %w", err)
|
||||
}
|
||||
defer tunStack.Close()
|
||||
return tunStack.(tun.StackRunner).Run()
|
||||
}
|
||||
|
||||
type tunHandler struct {
|
||||
*Server
|
||||
}
|
||||
|
||||
var _ tun.Handler = (*tunHandler)(nil)
|
||||
|
||||
func (t *tunHandler) NewConnection(ctx context.Context, conn net.Conn, m metadata.Metadata) error {
|
||||
addr := m.Source.String()
|
||||
reqAddr := m.Destination.String()
|
||||
if t.EventLogger != nil {
|
||||
t.EventLogger.TCPRequest(addr, reqAddr)
|
||||
}
|
||||
var closeErr error
|
||||
defer func() {
|
||||
if t.EventLogger != nil {
|
||||
t.EventLogger.TCPError(addr, reqAddr, closeErr)
|
||||
}
|
||||
}()
|
||||
rc, err := t.HyClient.TCP(reqAddr)
|
||||
if err != nil {
|
||||
closeErr = err
|
||||
// the returned err is ignored by caller
|
||||
return nil
|
||||
}
|
||||
defer rc.Close()
|
||||
|
||||
// start forwarding
|
||||
copyErrChan := make(chan error, 3)
|
||||
go func() {
|
||||
<-ctx.Done()
|
||||
copyErrChan <- ctx.Err()
|
||||
}()
|
||||
go func() {
|
||||
_, copyErr := io.Copy(rc, conn)
|
||||
copyErrChan <- copyErr
|
||||
}()
|
||||
go func() {
|
||||
_, copyErr := io.Copy(conn, rc)
|
||||
copyErrChan <- copyErr
|
||||
}()
|
||||
closeErr = <-copyErrChan
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *tunHandler) NewPacketConnection(ctx context.Context, conn network.PacketConn, m metadata.Metadata) error {
|
||||
addr := m.Source.String()
|
||||
if t.EventLogger != nil {
|
||||
t.EventLogger.UDPRequest(addr)
|
||||
}
|
||||
var closeErr error
|
||||
defer func() {
|
||||
if t.EventLogger != nil {
|
||||
t.EventLogger.UDPError(addr, closeErr)
|
||||
}
|
||||
}()
|
||||
rc, err := t.HyClient.UDP()
|
||||
if err != nil {
|
||||
closeErr = err
|
||||
// the returned err is simply called into NewError again
|
||||
return nil
|
||||
}
|
||||
defer rc.Close()
|
||||
|
||||
// start forwarding
|
||||
copyErrChan := make(chan error, 3)
|
||||
go func() {
|
||||
<-ctx.Done()
|
||||
copyErrChan <- ctx.Err()
|
||||
}()
|
||||
// local <- remote
|
||||
go func() {
|
||||
for {
|
||||
bs, from, err := rc.Receive()
|
||||
if err != nil {
|
||||
copyErrChan <- err
|
||||
return
|
||||
}
|
||||
var fromAddr metadata.Socksaddr
|
||||
if ap, perr := netip.ParseAddrPort(from); perr == nil {
|
||||
fromAddr = metadata.SocksaddrFromNetIP(ap)
|
||||
} else {
|
||||
fromAddr.Fqdn = from
|
||||
}
|
||||
err = conn.WritePacket(buf.As(bs), fromAddr)
|
||||
if err != nil {
|
||||
copyErrChan <- err
|
||||
return
|
||||
}
|
||||
}
|
||||
}()
|
||||
// local -> remote
|
||||
go func() {
|
||||
buffer := buf.NewPacket()
|
||||
defer buffer.Release()
|
||||
|
||||
for {
|
||||
buffer.Reset()
|
||||
addr, err := conn.ReadPacket(buffer)
|
||||
if err != nil {
|
||||
copyErrChan <- err
|
||||
return
|
||||
}
|
||||
err = rc.Send(buffer.Bytes(), addr.String())
|
||||
if err != nil {
|
||||
copyErrChan <- err
|
||||
return
|
||||
}
|
||||
}
|
||||
}()
|
||||
closeErr = <-copyErrChan
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *tunHandler) NewError(ctx context.Context, err error) {
|
||||
// unused
|
||||
}
|
||||
|
||||
type interfaceFinder struct{}
|
||||
|
||||
var _ control.InterfaceFinder = (*interfaceFinder)(nil)
|
||||
|
||||
func (f *interfaceFinder) InterfaceIndexByName(name string) (int, error) {
|
||||
ifce, err := net.InterfaceByName(name)
|
||||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
return ifce.Index, nil
|
||||
}
|
||||
|
||||
func (f *interfaceFinder) InterfaceNameByIndex(index int) (string, error) {
|
||||
ifce, err := net.InterfaceByIndex(index)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return ifce.Name, nil
|
||||
}
|
||||
@@ -21,10 +21,10 @@ require (
|
||||
github.com/quic-go/qpack v0.4.0 // indirect
|
||||
github.com/stretchr/objx v0.5.0 // indirect
|
||||
go.uber.org/mock v0.3.0 // indirect
|
||||
golang.org/x/crypto v0.17.0 // indirect
|
||||
golang.org/x/crypto v0.19.0 // indirect
|
||||
golang.org/x/mod v0.12.0 // indirect
|
||||
golang.org/x/net v0.17.0 // indirect
|
||||
golang.org/x/sys v0.15.0 // indirect
|
||||
golang.org/x/net v0.21.0 // indirect
|
||||
golang.org/x/sys v0.17.0 // indirect
|
||||
golang.org/x/text v0.14.0 // indirect
|
||||
golang.org/x/tools v0.11.1 // indirect
|
||||
google.golang.org/protobuf v1.33.0 // indirect
|
||||
|
||||
@@ -45,17 +45,17 @@ go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A=
|
||||
go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4=
|
||||
go.uber.org/mock v0.3.0 h1:3mUxI1No2/60yUYax92Pt8eNOEecx2D3lcXZh2NEZJo=
|
||||
go.uber.org/mock v0.3.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc=
|
||||
golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
|
||||
golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
|
||||
golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo=
|
||||
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||
golang.org/x/exp v0.0.0-20221205204356-47842c84f3db h1:D/cFflL63o2KSLJIwjlcIt8PR064j/xsmdEJL/YvY/o=
|
||||
golang.org/x/exp v0.0.0-20221205204356-47842c84f3db/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
|
||||
golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
|
||||
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
|
||||
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
|
||||
golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=
|
||||
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
|
||||
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y=
|
||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/time v0.4.0 h1:Z81tqI5ddIoXDPvVQ7/7CC9TnLM7ubaFG2qXYd5BbYY=
|
||||
|
||||
@@ -9,8 +9,8 @@ require (
|
||||
github.com/miekg/dns v1.1.55
|
||||
github.com/stretchr/testify v1.8.4
|
||||
github.com/txthinking/socks5 v0.0.0-20230325130024-4230056ae301
|
||||
golang.org/x/crypto v0.17.0
|
||||
golang.org/x/net v0.17.0
|
||||
golang.org/x/crypto v0.19.0
|
||||
golang.org/x/net v0.21.0
|
||||
google.golang.org/protobuf v1.33.0
|
||||
)
|
||||
|
||||
@@ -28,7 +28,7 @@ require (
|
||||
go.uber.org/mock v0.3.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20221205204356-47842c84f3db // indirect
|
||||
golang.org/x/mod v0.12.0 // indirect
|
||||
golang.org/x/sys v0.15.0 // indirect
|
||||
golang.org/x/sys v0.17.0 // indirect
|
||||
golang.org/x/text v0.14.0 // indirect
|
||||
golang.org/x/tools v0.11.1 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
|
||||
@@ -58,8 +58,8 @@ go.uber.org/mock v0.3.0 h1:3mUxI1No2/60yUYax92Pt8eNOEecx2D3lcXZh2NEZJo=
|
||||
go.uber.org/mock v0.3.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
|
||||
golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
|
||||
golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo=
|
||||
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||
golang.org/x/exp v0.0.0-20221205204356-47842c84f3db h1:D/cFflL63o2KSLJIwjlcIt8PR064j/xsmdEJL/YvY/o=
|
||||
golang.org/x/exp v0.0.0-20221205204356-47842c84f3db/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
@@ -70,8 +70,8 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
|
||||
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
|
||||
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
|
||||
golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=
|
||||
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
@@ -84,8 +84,8 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
|
||||
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y=
|
||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
|
||||
|
||||
+10
-7
@@ -26,6 +26,8 @@ dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D
|
||||
git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999 h1:OR8VhtwhcAI3U48/rzBsVOuHi0zDPzYI1xASVcdSgR8=
|
||||
git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg=
|
||||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||
github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak=
|
||||
github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802 h1:1BDTz0u9nC3//pOCMdNH+CiXJVYJh5UQNCOBG7jbELc=
|
||||
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA=
|
||||
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
|
||||
@@ -53,6 +55,8 @@ github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHH
|
||||
github.com/creack/pty v1.1.9 h1:uDmaGzcdjhF4i/plgjmEsriH11Y0o7RKapEf/LDaM3w=
|
||||
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
|
||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/dvyukov/go-fuzz v0.0.0-20210103155950-6a8e9d1f2415 h1:q1oJaUPdmpDm/VyXosjgPgr6wS7c5iV2p0PwJD73bUI=
|
||||
github.com/dvyukov/go-fuzz v0.0.0-20210103155950-6a8e9d1f2415/go.mod h1:11Gm+ccJnvAhCNLlf5+cS9KjtbaD5I5zaZpFMsTHWTw=
|
||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad h1:EmNYJhPYy0pOFjCx2PrgtaBXmee0iUX9hLlxE1xHOJE=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0 h1:EQciDnbrYxy13PgWoY8AqoxGiPrpgBZ1R8UNe3ddc+A=
|
||||
github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
|
||||
@@ -237,8 +241,8 @@ golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACk
|
||||
golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
|
||||
golang.org/x/crypto v0.4.0/go.mod h1:3quD/ATkf6oY+rnes5c3ExXTbLc8mueNue5/DoinL80=
|
||||
golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
|
||||
golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
|
||||
golang.org/x/exp/typeparams v0.0.0-20221208152030-732eee02a75a h1:Jw5wfR+h9mnIYH+OtGT2im5wV1YGGDora5vTv/aa5bE=
|
||||
golang.org/x/exp/typeparams v0.0.0-20221208152030-732eee02a75a/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b h1:+qEpEAPhDZ1o0x3tHzZTQDArnOixOzGD9HUJfcg0mb4=
|
||||
golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5 h1:2M3HP5CCK1Si9FQhwnzYhXdG6DXeebvUHFpre8QvbyI=
|
||||
@@ -264,14 +268,11 @@ golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
|
||||
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols=
|
||||
@@ -281,9 +282,9 @@ golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek=
|
||||
golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
|
||||
golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4=
|
||||
golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0=
|
||||
golang.org/x/term v0.17.0 h1:mkTF7LCd6WGJNL3K1Ad7kwxNfYAW6a8a8QqtMblp/4U=
|
||||
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.1.0 h1:xYY+Bajn2a7VBmTM5GikTmnK8ZuX8YgnQCqZpbBNtmA=
|
||||
golang.org/x/time v0.1.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
@@ -324,6 +325,8 @@ grpc.go4.org v0.0.0-20170609214715-11d0a25b4919 h1:tmXTu+dfa+d9Evp8NpJdgOy6+rt8/
|
||||
grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o=
|
||||
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.1-2020.1.4 h1:UoveltGrhghAA7ePc+e+QYDHXrBps2PqFZiHkGR/xK8=
|
||||
honnef.co/go/tools v0.4.5 h1:YGD4H+SuIOOqsyoLOpZDWcieM28W47/zRO7f+9V3nvo=
|
||||
honnef.co/go/tools v0.4.5/go.mod h1:GUV+uIBCLpdf0/v6UhHHG/yzI/z6qPskBeQCjcNB96k=
|
||||
rsc.io/binaryregexp v0.2.0 h1:HfqmD5MEmC0zvwBuF187nq9mdnXjXsSivRiXN7SmRkE=
|
||||
rsc.io/quote/v3 v3.1.0 h1:9JKUTTIUgS6kzR9mK1YuGKv6Nl+DijDNIc0ghT58FaY=
|
||||
rsc.io/sampler v1.3.0 h1:7uVkIFmeBqHfdjD+gZwtXXI+RODJ2Wc4O7MPEh/QiW4=
|
||||
|
||||
Vendored
-2
@@ -15,8 +15,6 @@ jobs:
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version-file: go.mod
|
||||
- name: Run go vet
|
||||
run: make vet
|
||||
- name: Build binaries
|
||||
run: make build
|
||||
- name: Upload artifacts
|
||||
|
||||
+1
-1
@@ -27,7 +27,7 @@ For an explanation of the mieru protocol, see [mieru Proxy Protocol](./docs/prot
|
||||
6. mieru supports multiple users sharing a single proxy server.
|
||||
7. mieru supports IPv4 and IPv6.
|
||||
8. mieru provides socks5, HTTP and HTTPS proxy.
|
||||
9. The client software supports Windows, Mac OS and Linux.
|
||||
9. The client software supports Windows, Mac OS, Linux and Android. For Android users, please use [NekoBox](https://github.com/MatsuriDayo/NekoBoxForAndroid) version 1.3.1 or above, and install [mieru plugin](https://github.com/enfein/NekoBoxPlugins).
|
||||
10. The server software supports socks5 outbound (proxy chain).
|
||||
11. If you need advanced features like global proxy or customized routing rules, you can use mieru as the backend of a proxy platform such as clash.
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ mieru 的翻墙原理与 shadowsocks / v2ray 等软件类似,在客户端和
|
||||
6. mieru 支持多个用户共享代理服务器。
|
||||
7. mieru 支持 IPv4 和 IPv6。
|
||||
8. mieru 提供 socks5, HTTP 和 HTTPS 代理。
|
||||
9. 客户端软件支持 Windows, Mac OS 和 Linux 系统。
|
||||
9. 客户端软件支持 Windows, Mac OS, Linux 和 Android 系统。Android 用户请使用 [NekoBox](https://github.com/MatsuriDayo/NekoBoxForAndroid) 1.3.1 及以上版本,并安装 [mieru 插件](https://github.com/enfein/NekoBoxPlugins)。
|
||||
10. 服务器软件支持 socks5 出站(链式代理)。
|
||||
11. 如果需要全局代理或自定义路由规则等高级功能,可以将 mieru 作为 clash 等代理平台的后端。
|
||||
|
||||
|
||||
@@ -20,8 +20,6 @@ curl -LSO https://github.com/enfein/mieru/releases/download/v2.7.0/mita-2.7.0-1.
|
||||
curl -LSO https://github.com/enfein/mieru/releases/download/v2.7.0/mita-2.7.0-1.aarch64.rpm
|
||||
```
|
||||
|
||||
If the above link is blocked, please use your browser to download and install from the GitHub Releases page.
|
||||
|
||||
## Install mita package
|
||||
|
||||
```sh
|
||||
@@ -38,6 +36,8 @@ sudo rpm -Uvh --force mita-2.7.0-1.x86_64.rpm
|
||||
sudo rpm -Uvh --force mita-2.7.0-1.aarch64.rpm
|
||||
```
|
||||
|
||||
Those instructions can also be used to upgrade the version of mita software package.
|
||||
|
||||
## Grant permissions, logout and login again to make the change effective
|
||||
|
||||
```sh
|
||||
|
||||
@@ -20,8 +20,6 @@ curl -LSO https://github.com/enfein/mieru/releases/download/v2.7.0/mita-2.7.0-1.
|
||||
curl -LSO https://github.com/enfein/mieru/releases/download/v2.7.0/mita-2.7.0-1.aarch64.rpm
|
||||
```
|
||||
|
||||
如果上述链接被墙,请翻墙后使用浏览器从 GitHub Releases 页面下载安装。
|
||||
|
||||
## 安装 mita 软件包
|
||||
|
||||
```sh
|
||||
@@ -38,6 +36,8 @@ sudo rpm -Uvh --force mita-2.7.0-1.x86_64.rpm
|
||||
sudo rpm -Uvh --force mita-2.7.0-1.aarch64.rpm
|
||||
```
|
||||
|
||||
上述指令也可以用来升级 mita 软件包的版本。
|
||||
|
||||
## 赋予当前用户操作 mita 的权限,重新登录使此设置生效
|
||||
|
||||
```sh
|
||||
|
||||
+12
-1
@@ -78,7 +78,9 @@ func (c *client) ExchangeContext(ctx context.Context, m *D.Msg) (*D.Msg, error)
|
||||
options = append(options, dialer.WithInterface(c.iface))
|
||||
}
|
||||
|
||||
conn, err := getDialHandler(c.r, c.proxyAdapter, c.proxyName, options...)(ctx, network, net.JoinHostPort(ip.String(), c.port))
|
||||
dialHandler := getDialHandler(c.r, c.proxyAdapter, c.proxyName, options...)
|
||||
addr := net.JoinHostPort(ip.String(), c.port)
|
||||
conn, err := dialHandler(ctx, network, addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -111,7 +113,16 @@ func (c *client) ExchangeContext(ctx context.Context, m *D.Msg) (*D.Msg, error)
|
||||
if msg != nil && msg.Truncated && c.Client.Net == "" {
|
||||
tcpClient := *c.Client // copy a client
|
||||
tcpClient.Net = "tcp"
|
||||
network = "tcp"
|
||||
log.Debugln("[DNS] Truncated reply from %s:%s for %s over UDP, retrying over TCP", c.host, c.port, m.Question[0].String())
|
||||
dConn.Conn, err = dialHandler(ctx, network, addr)
|
||||
if err != nil {
|
||||
ch <- result{msg, err}
|
||||
return
|
||||
}
|
||||
defer func() {
|
||||
_ = conn.Close()
|
||||
}()
|
||||
msg, _, err = tcpClient.ExchangeWithConn(m, dConn)
|
||||
}
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ define Package/$(PKG_NAME)
|
||||
CATEGORY:=Network
|
||||
SUBMENU:=Web Servers/Proxies
|
||||
TITLE:=A file list program that supports multiple storage
|
||||
URL:=https://alist-doc.nn.ci/
|
||||
URL:=https://alist.nn.ci/
|
||||
DEPENDS:=$(GO_ARCH_DEPENDS) +ca-bundle
|
||||
endef
|
||||
|
||||
|
||||
@@ -103,7 +103,7 @@ start_service() {
|
||||
"force_https": false,
|
||||
"cert_file": "$ssl_cert",
|
||||
"key_file": "$ssl_key",
|
||||
"unix_file": "/var/alist.sock"
|
||||
"unix_file": "/var/run/alist.sock"
|
||||
},
|
||||
"temp_dir": "$temp_dir",
|
||||
"bleve_dir": "$data_dir/bleve",
|
||||
@@ -121,13 +121,15 @@ start_service() {
|
||||
}
|
||||
EOF
|
||||
|
||||
procd_open_instance alist
|
||||
procd_open_instance
|
||||
procd_set_param command $PROG
|
||||
procd_append_param command server --data $data_dir
|
||||
procd_set_param stdout 0
|
||||
procd_set_param stderr 0
|
||||
procd_set_param respawn
|
||||
procd_close_instance alist
|
||||
procd_set_param limits core="unlimited"
|
||||
procd_set_param limits nofile="200000 200000"
|
||||
procd_close_instance
|
||||
}
|
||||
|
||||
service_triggers() {
|
||||
|
||||
@@ -5,8 +5,8 @@ buildscript {
|
||||
}
|
||||
|
||||
plugins {
|
||||
id 'com.android.application' version '8.3.0' apply false
|
||||
id 'com.android.library' version '8.3.0' apply false
|
||||
id 'com.android.application' version '8.3.1' apply false
|
||||
id 'com.android.library' version '8.3.1' apply false
|
||||
id 'org.jetbrains.kotlin.android' version '1.9.0' apply false
|
||||
id 'com.google.devtools.ksp' version '1.9.0-1.0.12' apply false
|
||||
id 'com.github.triplet.play' version '3.8.4' apply false
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
VERSION_CODE=305
|
||||
VERSION_CODE=307
|
||||
VERSION_NAME=1.8.10
|
||||
GO_VERSION=go1.22.1
|
||||
|
||||
+1
-1
@@ -33,7 +33,7 @@ require (
|
||||
github.com/sagernet/sing-shadowsocks v0.2.6
|
||||
github.com/sagernet/sing-shadowsocks2 v0.2.0
|
||||
github.com/sagernet/sing-shadowtls v0.1.4
|
||||
github.com/sagernet/sing-tun v0.2.5-beta.2
|
||||
github.com/sagernet/sing-tun v0.2.6-beta.1
|
||||
github.com/sagernet/sing-vmess v0.1.8
|
||||
github.com/sagernet/smux v0.0.0-20231208180855-7041f6ea79e7
|
||||
github.com/sagernet/tfo-go v0.0.0-20231209031829-7b5343ac1dc6
|
||||
|
||||
+2
-2
@@ -123,8 +123,8 @@ github.com/sagernet/sing-shadowsocks2 v0.2.0 h1:wpZNs6wKnR7mh1wV9OHwOyUr21VkS3wK
|
||||
github.com/sagernet/sing-shadowsocks2 v0.2.0/go.mod h1:RnXS0lExcDAovvDeniJ4IKa2IuChrdipolPYWBv9hWQ=
|
||||
github.com/sagernet/sing-shadowtls v0.1.4 h1:aTgBSJEgnumzFenPvc+kbD9/W0PywzWevnVpEx6Tw3k=
|
||||
github.com/sagernet/sing-shadowtls v0.1.4/go.mod h1:F8NBgsY5YN2beQavdgdm1DPlhaKQlaL6lpDdcBglGK4=
|
||||
github.com/sagernet/sing-tun v0.2.5-beta.2 h1:mOWW80jYEup8LIFG3VuWASWgiRzyusuX5kH+Lbl+V7s=
|
||||
github.com/sagernet/sing-tun v0.2.5-beta.2/go.mod h1:E+KwQKzYkdGEhfIxjmoaB1ZkADaxeXUNzx6GRDRKOfE=
|
||||
github.com/sagernet/sing-tun v0.2.6-beta.1 h1:6yfOJQaa706/VAKb7SVa8ziXppTxVOg/p9p63qk2N/o=
|
||||
github.com/sagernet/sing-tun v0.2.6-beta.1/go.mod h1:E+KwQKzYkdGEhfIxjmoaB1ZkADaxeXUNzx6GRDRKOfE=
|
||||
github.com/sagernet/sing-vmess v0.1.8 h1:XVWad1RpTy9b5tPxdm5MCU8cGfrTGdR8qCq6HV2aCNc=
|
||||
github.com/sagernet/sing-vmess v0.1.8/go.mod h1:vhx32UNzTDUkNwOyIjcZQohre1CaytquC5mPplId8uA=
|
||||
github.com/sagernet/smux v0.0.0-20231208180855-7041f6ea79e7 h1:DImB4lELfQhplLTxeq2z31Fpv8CQqqrUwTbrIRumZqQ=
|
||||
|
||||
+3
-3
@@ -9,9 +9,9 @@ PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_URL:=https://gn.googlesource.com/gn.git
|
||||
PKG_SOURCE_DATE:=2024-03-08
|
||||
PKG_SOURCE_VERSION:=59c4bb920542ee903ee1df39097ae024e2e8226f
|
||||
PKG_MIRROR_HASH:=604096e2804bd49b9d2ed6c6aaea1101db0d475a20ebfd2693dc4082e88cbdf6
|
||||
PKG_SOURCE_DATE:=2024-03-21
|
||||
PKG_SOURCE_VERSION:=06cdcc8e1fa8e56f70efb4357d473345b7d1c083
|
||||
PKG_MIRROR_HASH:=98a72b8a4e4a7d50da27821a5ee42417f19f3a8ab4382297362168676002ec06
|
||||
|
||||
PKG_LICENSE:=BSD 3-Clause
|
||||
PKG_LICENSE_FILES:=LICENSE
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#ifndef OUT_LAST_COMMIT_POSITION_H_
|
||||
#define OUT_LAST_COMMIT_POSITION_H_
|
||||
|
||||
#define LAST_COMMIT_POSITION_NUM 2157
|
||||
#define LAST_COMMIT_POSITION "2157 (59c4bb920542)"
|
||||
#define LAST_COMMIT_POSITION_NUM 2159
|
||||
#define LAST_COMMIT_POSITION "2159 (06cdcc8e1fa8)"
|
||||
|
||||
#endif // OUT_LAST_COMMIT_POSITION_H_
|
||||
|
||||
@@ -6,12 +6,12 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=sing-box
|
||||
PKG_VERSION:=1.8.9
|
||||
PKG_VERSION:=1.8.10
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=https://codeload.github.com/SagerNet/sing-box/tar.gz/v$(PKG_VERSION)?
|
||||
PKG_HASH:=764c51bdf43af86e67b2657baf87bf67a2e1d8e42b0d39ee9ef7a9a414c658fc
|
||||
PKG_HASH:=a959f9a40148ed4166b8161072672f3ce1532957adef7717132c7277bb96dcf6
|
||||
|
||||
PKG_LICENSE:=GPL-3.0-or-later
|
||||
PKG_LICENSE_FILES:=LICENSE
|
||||
|
||||
@@ -1,33 +1,37 @@
|
||||
# SPDX-FileCopyrightText: 2021 yuzu Emulator Project
|
||||
# SPDX-FileCopyrightText: 2024 suyu Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
name: yuzu-ci
|
||||
# Actions Documentation: https://forgejo.org/docs/next/user/actions/#list-of-tasks-in-a-repository
|
||||
|
||||
name: suyu-ci
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
branches: [ "dev" ]
|
||||
tags: [ "*" ]
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
branches: [ "dev" ]
|
||||
|
||||
jobs:
|
||||
transifex:
|
||||
runs-on: ubuntu-latest
|
||||
container: yuzuemu/build-environments:linux-transifex
|
||||
if: ${{ github.repository == 'yuzu-emu/yuzu' && !github.head_ref }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: recursive
|
||||
fetch-depth: 0
|
||||
- name: Update Translation
|
||||
run: ./.ci/scripts/transifex/docker.sh
|
||||
env:
|
||||
TX_TOKEN: ${{ secrets.TRANSIFEX_API_TOKEN }}
|
||||
# transifex:
|
||||
# runs-on: ubuntu-latest
|
||||
# container: fijxu/build-environments:linux-transifex
|
||||
# if: ${{ GITHUB_REPOSITORY == 'suyu/suyu' && !GITHUB_HEAD_REF }}
|
||||
# steps:
|
||||
# - uses: https://code.forgejo.org/actions/checkout@v3
|
||||
# with:
|
||||
# submodules: recursive
|
||||
# fetch-depth: 0
|
||||
# - name: Update Translation
|
||||
# run: ./.ci/scripts/transifex/docker.sh
|
||||
# env:
|
||||
# TX_TOKEN: ${{ secrets.TRANSIFEX_API_TOKEN }}
|
||||
|
||||
reuse:
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.repository == 'yuzu-emu/yuzu' }}
|
||||
if: ${{ github.repository == 'suyu/suyu' }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: fsfe/reuse-action@v1
|
||||
- uses: https://code.forgejo.org/actions/checkout@v3
|
||||
- uses: https://github.com/fsfe/reuse-action@v1
|
||||
|
||||
|
||||
@@ -9,7 +9,13 @@
|
||||
# Actions Documentation: https://forgejo.org/docs/next/user/actions/#list-of-tasks-in-a-repository
|
||||
|
||||
name: codespell
|
||||
on: pull_request
|
||||
on:
|
||||
push:
|
||||
branches: [ "*" ]
|
||||
tags: [ "*" ]
|
||||
pull_request:
|
||||
branches: [ "*" ]
|
||||
|
||||
permissions: {}
|
||||
jobs:
|
||||
codespell:
|
||||
@@ -20,3 +26,4 @@ jobs:
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: https://github.com/codespell-project/actions-codespell@master
|
||||
|
||||
|
||||
@@ -1,30 +1,39 @@
|
||||
# SPDX-FileCopyrightText: 2022 yuzu Emulator Project
|
||||
# SPDX-FileCopyrightText: 2024 suyu Emulator Project
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
name: 'yuzu verify'
|
||||
# Actions Documentation: https://forgejo.org/docs/next/user/actions/#list-of-tasks-in-a-repository
|
||||
|
||||
name: 'suyu verify'
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
branches: [ "dev" ]
|
||||
push:
|
||||
branches: [ "dev" ]
|
||||
env:
|
||||
PR_NUMBER: pr${{ github.event.number }}
|
||||
CCACHE_DIR: '.ccache'
|
||||
|
||||
|
||||
jobs:
|
||||
format:
|
||||
name: 'verify format'
|
||||
name: 'Verify Format'
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: fijxu/build-environments:linux-clang-format
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: https://code.forgejo.org/actions/checkout@v3
|
||||
with:
|
||||
submodules: false
|
||||
- name: set up JDK 17
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
java-version: '17'
|
||||
distribution: 'temurin'
|
||||
# - name: set up JDK 17
|
||||
# uses: https://github.com/actions/setup-java@v3
|
||||
# with:
|
||||
# java-version: '17'
|
||||
# distribution: 'temurin'
|
||||
- name: 'Verify Formatting'
|
||||
run: bash -ex ./.ci/scripts/format/script.sh
|
||||
build:
|
||||
build-linux:
|
||||
name: 'test build'
|
||||
needs: format
|
||||
runs-on: ubuntu-latest
|
||||
@@ -39,24 +48,24 @@ jobs:
|
||||
- type: windows
|
||||
image: linux-mingw
|
||||
container:
|
||||
image: yuzuemu/build-environments:${{ matrix.image }}
|
||||
image: fijxu/build-environments:${{ matrix.image }}
|
||||
options: -u 1001
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: https://code.forgejo.org/actions/checkout@v3
|
||||
with:
|
||||
submodules: recursive
|
||||
fetch-depth: 0
|
||||
- name: Set up cache
|
||||
uses: actions/cache@v3
|
||||
uses: https://code.forgejo.org/actions/cache@v3
|
||||
id: ccache-restore
|
||||
with:
|
||||
path: ~/.ccache
|
||||
path: .ccache
|
||||
key: ${{ runner.os }}-${{ matrix.type }}-${{ github.sha }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-${{ matrix.type }}-
|
||||
- name: Create ccache directory
|
||||
if: steps.ccache-restore.outputs.cache-hit != 'true'
|
||||
run: mkdir -p ~/.ccache
|
||||
run: mkdir -p .ccache
|
||||
- name: Build
|
||||
run: ./.ci/scripts/${{ matrix.type }}/docker.sh
|
||||
env:
|
||||
@@ -66,112 +75,112 @@ jobs:
|
||||
env:
|
||||
NO_SOURCE_PACK: "YES"
|
||||
- name: Upload
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: https://code.forgejo.org/actions/upload-artifact@v3
|
||||
with:
|
||||
name: ${{ matrix.type }}
|
||||
path: artifacts/
|
||||
build-mac:
|
||||
name: 'test build (macos)'
|
||||
needs: format
|
||||
runs-on: macos-14
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: recursive
|
||||
fetch-depth: 0
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
brew install autoconf automake boost ccache ffmpeg fmt glslang hidapi libtool libusb lz4 ninja nlohmann-json openssl pkg-config qt@5 sdl2 speexdsp zlib zlib zstd
|
||||
- name: Build
|
||||
run: |
|
||||
mkdir build
|
||||
cd build
|
||||
export Qt5_DIR="$(brew --prefix qt@5)/lib/cmake"
|
||||
cmake .. -GNinja -DCMAKE_BUILD_TYPE=RelWithDebInfo -DSUYU_USE_BUNDLED_VCPKG=OFF -DSUYU_TESTS=OFF -DENABLE_WEB_SERVICE=OFF -DENABLE_LIBUSB=OFF
|
||||
ninja
|
||||
build-msvc:
|
||||
name: 'test build (windows, msvc)'
|
||||
needs: format
|
||||
runs-on: windows-2022
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: recursive
|
||||
fetch-depth: 0
|
||||
- name: Set up cache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/.buildcache
|
||||
key: ${{ runner.os }}-msvc-${{ github.sha }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-msvc-
|
||||
- name: Install dependencies
|
||||
shell: pwsh
|
||||
run: |
|
||||
$ErrorActionPreference = "Stop"
|
||||
$BuildCacheVer = "v0.28.4"
|
||||
$File = "buildcache-windows.zip"
|
||||
$Uri = "https://github.com/mbitsnbites/buildcache/releases/download/$BuildCacheVer/$File"
|
||||
$WebClient = New-Object System.Net.WebClient
|
||||
$WebClient.DownloadFile($Uri, $File)
|
||||
7z x $File
|
||||
$CurrentDir = Convert-Path .
|
||||
echo "$CurrentDir/buildcache/bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
|
||||
- name: Install Vulkan SDK
|
||||
shell: pwsh
|
||||
run: .\.ci\scripts\windows\install-vulkan-sdk.ps1
|
||||
- name: Set up MSVC
|
||||
uses: ilammy/msvc-dev-cmd@v1
|
||||
- name: Configure
|
||||
env:
|
||||
CC: cl.exe
|
||||
CXX: cl.exe
|
||||
run: |
|
||||
glslangValidator --version
|
||||
mkdir build
|
||||
cmake . -B build -GNinja -DCMAKE_TOOLCHAIN_FILE="CMakeModules/MSVCCache.cmake" -DUSE_CCACHE=ON -DSUYU_USE_BUNDLED_QT=1 -DSUYU_USE_BUNDLED_SDL2=1 -DSUYU_USE_QT_WEB_ENGINE=ON -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DSUYU_ENABLE_COMPATIBILITY_REPORTING=ON -DUSE_DISCORD_PRESENCE=ON -DENABLE_QT_TRANSLATION=ON -DCMAKE_BUILD_TYPE=Release -DGIT_BRANCH=pr-verify -DSUYU_CRASH_DUMPS=ON
|
||||
- name: Build
|
||||
run: cmake --build build
|
||||
- name: Cache Summary
|
||||
run: buildcache -s
|
||||
- name: Pack
|
||||
shell: pwsh
|
||||
run: .\.ci\scripts\windows\upload.ps1
|
||||
- name: Upload
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: msvc
|
||||
path: artifacts/
|
||||
- name: Upload EXE
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: ${{ env.INDIVIDUAL_EXE }}
|
||||
path: ${{ env.INDIVIDUAL_EXE }}
|
||||
# build-mac:
|
||||
# name: 'test build (macos)'
|
||||
# needs: format
|
||||
# runs-on: macos-14
|
||||
# steps:
|
||||
# - uses: https://code.forgejo.org/actions/checkout@v3
|
||||
# with:
|
||||
# submodules: recursive
|
||||
# fetch-depth: 0
|
||||
# - name: Install dependencies
|
||||
# run: |
|
||||
# brew install autoconf automake boost ccache ffmpeg fmt glslang hidapi libtool libusb lz4 ninja nlohmann-json openssl pkg-config qt@5 sdl2 speexdsp zlib zlib zstd
|
||||
# - name: Build
|
||||
# run: |
|
||||
# mkdir build
|
||||
# cd build
|
||||
# export Qt5_DIR="$(brew --prefix qt@5)/lib/cmake"
|
||||
# cmake .. -GNinja -DCMAKE_BUILD_TYPE=RelWithDebInfo -DSUYU_USE_BUNDLED_VCPKG=OFF -DSUYU_TESTS=OFF -DENABLE_WEB_SERVICE=OFF -DENABLE_LIBUSB=OFF
|
||||
# ninja
|
||||
# build-msvc:
|
||||
# name: 'test build (windows, msvc)'
|
||||
# needs: format
|
||||
# runs-on: windows-2022
|
||||
# steps:
|
||||
# - uses: https://code.forgejo.org/actions/checkout@v3
|
||||
# with:
|
||||
# submodules: recursive
|
||||
# fetch-depth: 0
|
||||
# - name: Set up cache
|
||||
# uses: https://code.forgejo.org/actions/cache@v3
|
||||
# with:
|
||||
# path: ~/.buildcache
|
||||
# key: ${{ runner.os }}-msvc-${{ github.sha }}
|
||||
# restore-keys: |
|
||||
# ${{ runner.os }}-msvc-
|
||||
# - name: Install dependencies
|
||||
# shell: pwsh
|
||||
# run: |
|
||||
# $ErrorActionPreference = "Stop"
|
||||
# $BuildCacheVer = "v0.28.4"
|
||||
# $File = "buildcache-windows.zip"
|
||||
# $Uri = "https://github.com/mbitsnbites/buildcache/releases/download/$BuildCacheVer/$File"
|
||||
# $WebClient = New-Object System.Net.WebClient
|
||||
# $WebClient.DownloadFile($Uri, $File)
|
||||
# 7z x $File
|
||||
# $CurrentDir = Convert-Path .
|
||||
# echo "$CurrentDir/buildcache/bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
|
||||
# - name: Install Vulkan SDK
|
||||
# shell: pwsh
|
||||
# run: .\.ci\scripts\windows\install-vulkan-sdk.ps1
|
||||
# - name: Set up MSVC
|
||||
# uses: https://github.com/ilammy/msvc-dev-cmd@v1
|
||||
# - name: Configure
|
||||
# env:
|
||||
# CC: cl.exe
|
||||
# CXX: cl.exe
|
||||
# run: |
|
||||
# glslangValidator --version
|
||||
# mkdir build
|
||||
# cmake . -B build -GNinja -DCMAKE_TOOLCHAIN_FILE="CMakeModules/MSVCCache.cmake" -DUSE_CCACHE=ON -DSUYU_USE_BUNDLED_QT=1 -DSUYU_USE_BUNDLED_SDL2=1 -DSUYU_USE_QT_WEB_ENGINE=ON -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DSUYU_ENABLE_COMPATIBILITY_REPORTING=ON -DUSE_DISCORD_PRESENCE=ON -DENABLE_QT_TRANSLATION=ON -DCMAKE_BUILD_TYPE=Release -DGIT_BRANCH=pr-verify -DSUYU_CRASH_DUMPS=ON
|
||||
# - name: Build
|
||||
# run: cmake --build build
|
||||
# - name: Cache Summary
|
||||
# run: buildcache -s
|
||||
# - name: Pack
|
||||
# shell: pwsh
|
||||
# run: .\.ci\scripts\windows\upload.ps1
|
||||
# - name: Upload
|
||||
# uses: https://code.forgejo.org/actions/upload-artifact@v3
|
||||
# with:
|
||||
# name: msvc
|
||||
# path: artifacts/
|
||||
# - name: Upload EXE
|
||||
# uses: https://code.forgejo.org/actions/upload-artifact@v3
|
||||
# with:
|
||||
# name: ${{ env.INDIVIDUAL_EXE }}
|
||||
# path: ${{ env.INDIVIDUAL_EXE }}
|
||||
android:
|
||||
runs-on: ubuntu-latest
|
||||
needs: format
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: https://code.forgejo.org/actions/checkout@v3
|
||||
with:
|
||||
submodules: recursive
|
||||
fetch-depth: 0
|
||||
- name: set up JDK 17
|
||||
uses: actions/setup-java@v3
|
||||
uses: https://github.com/actions/setup-java@v3
|
||||
with:
|
||||
java-version: '17'
|
||||
distribution: 'temurin'
|
||||
- name: Set up cache
|
||||
uses: actions/cache@v3
|
||||
uses: https://code.forgejo.org/actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
~/.gradle/caches
|
||||
~/.gradle/wrapper
|
||||
~/.ccache
|
||||
.ccache
|
||||
key: ${{ runner.os }}-android-${{ github.sha }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-android-
|
||||
- name: Query tag name
|
||||
uses: olegtarasov/get-tag@v2.1.2
|
||||
uses: https://github.com/olegtarasov/get-tag@v2.1.2
|
||||
id: tagName
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
@@ -186,7 +195,8 @@ jobs:
|
||||
ANDROID_KEYSTORE_PASS: ${{ secrets.ANDROID_KEYSTORE_PASS }}
|
||||
run: ./.ci/scripts/android/upload.sh
|
||||
- name: Upload
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: https://code.forgejo.org/actions/upload-artifact@v3
|
||||
with:
|
||||
name: android
|
||||
path: artifacts/
|
||||
|
||||
|
||||
+5
-5
@@ -9,22 +9,22 @@
|
||||
url = https://github.com/mozilla/cubeb.git
|
||||
[submodule "dynarmic"]
|
||||
path = externals/dynarmic
|
||||
url = https://gitlab.com/suyu-emu/dynarmic.git
|
||||
url = https://git.suyu.dev/suyu/dynarmic.git
|
||||
[submodule "libusb"]
|
||||
path = externals/libusb/libusb
|
||||
url = https://github.com/libusb/libusb.git
|
||||
[submodule "discord-rpc"]
|
||||
path = externals/discord-rpc
|
||||
url = https://gitlab.com/suyu-emu/discord-rpc.git
|
||||
url = https://git.suyu.dev/suyu/discord-rpc.git
|
||||
[submodule "Vulkan-Headers"]
|
||||
path = externals/Vulkan-Headers
|
||||
url = https://github.com/KhronosGroup/Vulkan-Headers.git
|
||||
[submodule "sirit"]
|
||||
path = externals/sirit
|
||||
url = https://gitlab.com/suyu-emu/sirit.git
|
||||
url = https://git.suyu.dev/suyu/sirit.git
|
||||
[submodule "mbedtls"]
|
||||
path = externals/mbedtls
|
||||
url = https://gitlab.com/suyu-emu/mbedtls.git
|
||||
url = https://git.suyu.dev/suyu/mbedtls.git
|
||||
[submodule "xbyak"]
|
||||
path = externals/xbyak
|
||||
url = https://github.com/herumi/xbyak.git
|
||||
@@ -57,7 +57,7 @@
|
||||
url = https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator.git
|
||||
[submodule "breakpad"]
|
||||
path = externals/breakpad
|
||||
url = https://gitlab.com/suyu-emu/breakpad.git
|
||||
url = https://git.suyu.dev/suyu/breakpad.git
|
||||
[submodule "simpleini"]
|
||||
path = externals/simpleini
|
||||
url = https://github.com/brofield/simpleini.git
|
||||
|
||||
+6
-4
@@ -1,6 +1,6 @@
|
||||
<!--
|
||||
SPDX-FileCopyrightText: 2024 suyu emulator project
|
||||
SPDX-License-Identifier: GPL v3
|
||||
SPDX-License-Identifier: GPL-3.0-or-later
|
||||
-->
|
||||
|
||||
**Note**: We do not support or condone piracy in any form. In order to use suyu, you'll need keys from your real Switch system, and games which you have legally obtained and paid for. We do not intend to make money or profit from this project.
|
||||
@@ -60,8 +60,10 @@ We have official builds [here.](https://git.suyu.dev/suyu/suyu/releases) If any
|
||||
|
||||
## Building
|
||||
|
||||
* __Windows__: [Wiki page](https://git.suyu.dev/suyu/suyu/wiki/Building-for-Windows)
|
||||
* __Linux__: [Wiki page](https://git.suyu.dev/suyu/suyu/wiki/Building-for-Linux)
|
||||
* __Windows__: [Windows Build](https://git.suyu.dev/suyu/suyu/wiki/Building-For-Windows)
|
||||
* __Linux__: [Linux Build](https://git.suyu.dev/suyu/suyu/wiki/Building-For-Linux)
|
||||
* __Android__: [Android Build](https://git.suyu.dev/suyu/suyu/wiki/Building-For-Android)
|
||||
* __MacOS__: [MacOS Build](https://git.suyu.dev/suyu/suyu/wiki/Building-for-macOS)
|
||||
|
||||
|
||||
|
||||
@@ -72,4 +74,4 @@ If you have any questions, don't hesitate to ask us on [Discord](https://discord
|
||||
|
||||
## License
|
||||
|
||||
suyu is licensed under the free and open-source GPL v3 license.
|
||||
suyu is licensed under the free and open-source GPL-3.0-or-later license.
|
||||
|
||||
+17
-13
@@ -12,6 +12,7 @@
|
||||
#include <thread>
|
||||
#include "core/hle/service/am/applet_manager.h"
|
||||
#include "core/loader/nca.h"
|
||||
#include "core/loader/nro.h"
|
||||
#include "core/tools/renderdoc.h"
|
||||
|
||||
#ifdef __APPLE__
|
||||
@@ -1747,18 +1748,21 @@ void GMainWindow::AllowOSSleep() {
|
||||
}
|
||||
|
||||
bool GMainWindow::LoadROM(const QString& filename, Service::AM::FrontendAppletParameters params) {
|
||||
if (!CheckFirmwarePresence()) {
|
||||
QMessageBox::critical(this, tr("Component Missing"), tr("Missing Firmware."));
|
||||
return false;
|
||||
}
|
||||
if (Loader::AppLoader_NRO::IdentifyType(Core::GetGameFileFromPath(vfs, filename.toStdString())) !=
|
||||
Loader::FileType::NRO) {
|
||||
if (!CheckFirmwarePresence()) {
|
||||
QMessageBox::critical(this, tr("Component Missing"), tr("Missing Firmware."));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ContentManager::AreKeysPresent()) {
|
||||
QMessageBox::warning(this, tr("Derivation Components Missing"),
|
||||
tr("Encryption keys are missing. "
|
||||
"In order to use this emulator"
|
||||
"you need to provide your own encryption keys"
|
||||
"in order to play them."));
|
||||
return false;
|
||||
if (!ContentManager::AreKeysPresent()) {
|
||||
QMessageBox::warning(this, tr("Derivation Components Missing"),
|
||||
tr("Encryption keys are missing. "
|
||||
"In order to use this emulator, "
|
||||
"you need to provide your own encryption keys "
|
||||
"in order to play them."));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Shutdown previous session if the emu thread is still active...
|
||||
@@ -4630,8 +4634,8 @@ void GMainWindow::OnCheckFirmwareDecryption() {
|
||||
if (!ContentManager::AreKeysPresent()) {
|
||||
QMessageBox::warning(this, tr("Derivation Components Missing"),
|
||||
tr("Encryption keys are missing. "
|
||||
"In order to use this emulator"
|
||||
"you need to provide your own encryption keys"
|
||||
"In order to use this emulator, "
|
||||
"you need to provide your own encryption keys "
|
||||
"in order to play them."));
|
||||
}
|
||||
|
||||
|
||||
@@ -702,7 +702,7 @@ public:
|
||||
return properties.driver.driverID == VK_DRIVER_ID_NVIDIA_PROPRIETARY;
|
||||
}
|
||||
|
||||
/// Checks if we are runing MolvenVK.
|
||||
/// Checks if we are running MolvenVK.
|
||||
bool IsMoltenVK() const noexcept {
|
||||
return properties.driver.driverID == VK_DRIVER_ID_MOLTENVK;
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace v2rayN
|
||||
|
||||
public async Task<string?> DownloadStringAsync(IWebProxy? webProxy, string url, string? userAgent, int timeout)
|
||||
{
|
||||
if (string.IsNullOrEmpty(url))
|
||||
if (Utile.IsNullOrEmpty(url))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
@@ -57,7 +57,7 @@ namespace v2rayN
|
||||
|
||||
public async Task DownloadDataAsync4Speed(IWebProxy webProxy, string url, IProgress<string> progress, int timeout)
|
||||
{
|
||||
if (string.IsNullOrEmpty(url))
|
||||
if (Utile.IsNullOrEmpty(url))
|
||||
{
|
||||
throw new ArgumentNullException(nameof(url));
|
||||
}
|
||||
@@ -120,11 +120,11 @@ namespace v2rayN
|
||||
|
||||
public async Task DownloadFileAsync(IWebProxy? webProxy, string url, string fileName, IProgress<double> progress, int timeout)
|
||||
{
|
||||
if (string.IsNullOrEmpty(url))
|
||||
if (Utile.IsNullOrEmpty(url))
|
||||
{
|
||||
throw new ArgumentNullException(nameof(url));
|
||||
}
|
||||
if (string.IsNullOrEmpty(fileName))
|
||||
if (Utile.IsNullOrEmpty(fileName))
|
||||
{
|
||||
throw new ArgumentNullException(nameof(fileName));
|
||||
}
|
||||
|
||||
@@ -23,13 +23,13 @@ namespace v2rayN
|
||||
|
||||
public async Task<string?> GetAsync(string url)
|
||||
{
|
||||
if (string.IsNullOrEmpty(url)) return null;
|
||||
if (Utile.IsNullOrEmpty(url)) return null;
|
||||
return await httpClient.GetStringAsync(url);
|
||||
}
|
||||
|
||||
public async Task<string?> GetAsync(HttpClient client, string url, CancellationToken token = default)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(url)) return null;
|
||||
if (Utile.IsNullOrEmpty(url)) return null;
|
||||
return await client.GetStringAsync(url, token);
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@ namespace v2rayN
|
||||
|
||||
public async Task DownloadDataAsync4Speed(HttpClient client, string url, IProgress<string> progress, CancellationToken token = default)
|
||||
{
|
||||
if (string.IsNullOrEmpty(url))
|
||||
if (Utile.IsNullOrEmpty(url))
|
||||
{
|
||||
throw new ArgumentNullException(nameof(url));
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace v2rayN
|
||||
{
|
||||
try
|
||||
{
|
||||
if (string.IsNullOrEmpty(strJson))
|
||||
if (string.IsNullOrWhiteSpace(strJson))
|
||||
{
|
||||
return default;
|
||||
}
|
||||
@@ -49,7 +49,7 @@ namespace v2rayN
|
||||
{
|
||||
try
|
||||
{
|
||||
if (string.IsNullOrEmpty(strJson))
|
||||
if (string.IsNullOrWhiteSpace(strJson))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -361,7 +361,7 @@ namespace v2rayN
|
||||
/// <returns></returns>
|
||||
public static string GetPunycode(string url)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(url))
|
||||
if (Utile.IsNullOrEmpty(url))
|
||||
{
|
||||
return url;
|
||||
}
|
||||
@@ -391,7 +391,7 @@ namespace v2rayN
|
||||
|
||||
public static string Convert2Comma(string text)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(text))
|
||||
if (Utile.IsNullOrEmpty(text))
|
||||
{
|
||||
return text;
|
||||
}
|
||||
@@ -428,7 +428,7 @@ namespace v2rayN
|
||||
/// <returns></returns>
|
||||
public static bool IsNullOrEmpty(string? text)
|
||||
{
|
||||
if (string.IsNullOrEmpty(text))
|
||||
if (string.IsNullOrWhiteSpace(text))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -840,7 +840,7 @@ namespace v2rayN
|
||||
{
|
||||
Directory.CreateDirectory(_tempPath);
|
||||
}
|
||||
if (string.IsNullOrEmpty(filename))
|
||||
if (Utile.IsNullOrEmpty(filename))
|
||||
{
|
||||
return _tempPath;
|
||||
}
|
||||
@@ -876,7 +876,7 @@ namespace v2rayN
|
||||
{
|
||||
Directory.CreateDirectory(_tempPath);
|
||||
}
|
||||
if (string.IsNullOrEmpty(filename))
|
||||
if (Utile.IsNullOrEmpty(filename))
|
||||
{
|
||||
return _tempPath;
|
||||
}
|
||||
@@ -901,7 +901,7 @@ namespace v2rayN
|
||||
Directory.CreateDirectory(_tempPath);
|
||||
}
|
||||
}
|
||||
if (string.IsNullOrEmpty(filename))
|
||||
if (Utile.IsNullOrEmpty(filename))
|
||||
{
|
||||
return _tempPath;
|
||||
}
|
||||
@@ -918,7 +918,7 @@ namespace v2rayN
|
||||
{
|
||||
Directory.CreateDirectory(_tempPath);
|
||||
}
|
||||
if (string.IsNullOrEmpty(filename))
|
||||
if (Utile.IsNullOrEmpty(filename))
|
||||
{
|
||||
return _tempPath;
|
||||
}
|
||||
@@ -935,7 +935,7 @@ namespace v2rayN
|
||||
{
|
||||
Directory.CreateDirectory(_tempPath);
|
||||
}
|
||||
if (string.IsNullOrEmpty(filename))
|
||||
if (Utile.IsNullOrEmpty(filename))
|
||||
{
|
||||
return _tempPath;
|
||||
}
|
||||
@@ -1107,7 +1107,7 @@ namespace v2rayN
|
||||
/// <exception cref="ArgumentNullException"></exception>
|
||||
public static void AutoStart(string taskName, string fileName, string description)
|
||||
{
|
||||
if (string.IsNullOrEmpty(taskName))
|
||||
if (Utile.IsNullOrEmpty(taskName))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -1122,7 +1122,7 @@ namespace v2rayN
|
||||
{
|
||||
taskService.RootFolder.DeleteTask(t.Name);
|
||||
}
|
||||
if (string.IsNullOrEmpty(fileName))
|
||||
if (Utile.IsNullOrEmpty(fileName))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace v2rayN.Converters
|
||||
try
|
||||
{
|
||||
var fontFamily = LazyConfig.Instance.GetConfig().uiItem.currentFontFamily;
|
||||
if (!string.IsNullOrEmpty(fontFamily))
|
||||
if (!Utile.IsNullOrEmpty(fontFamily))
|
||||
{
|
||||
var fontPath = Utile.GetFontsPath();
|
||||
MyFont = new FontFamily(new Uri(@$"file:///{fontPath}\"), $"./#{fontFamily}");
|
||||
|
||||
@@ -1177,6 +1177,46 @@ namespace v2rayN.Handler
|
||||
return false;
|
||||
}
|
||||
|
||||
//Is v2ray array configuration
|
||||
var configObjects = JsonUtile.Deserialize<Object[]>(clipboardData);
|
||||
if (configObjects != null && configObjects.Length > 0)
|
||||
{
|
||||
if (isSub && !Utile.IsNullOrEmpty(subid))
|
||||
{
|
||||
RemoveServerViaSubid(config, subid, isSub);
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
foreach (var configObject in configObjects)
|
||||
{
|
||||
var objectString = JsonUtile.Serialize(configObject);
|
||||
var v2rayCon = JsonUtile.Deserialize<V2rayConfig>(objectString);
|
||||
if (v2rayCon?.inbounds?.Count > 0 && v2rayCon.outbounds?.Count > 0)
|
||||
{
|
||||
var fileName = Utile.GetTempPath($"{Utile.GetGUID(false)}.json");
|
||||
File.WriteAllText(fileName, objectString);
|
||||
|
||||
var profileIt = new ProfileItem
|
||||
{
|
||||
coreType = ECoreType.Xray,
|
||||
address = fileName,
|
||||
remarks = v2rayCon.remarks ?? "v2ray_custom",
|
||||
subid = subid,
|
||||
isSub = isSub
|
||||
};
|
||||
|
||||
if (AddCustomServer(config, profileIt, true) == 0)
|
||||
{
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (count > 0)
|
||||
{
|
||||
return count;
|
||||
}
|
||||
}
|
||||
|
||||
ProfileItem profileItem = new();
|
||||
//Is v2ray configuration
|
||||
var v2rayConfig = JsonUtile.Deserialize<V2rayConfig>(clipboardData);
|
||||
@@ -1188,7 +1228,7 @@ namespace v2rayN.Handler
|
||||
|
||||
profileItem.coreType = ECoreType.Xray;
|
||||
profileItem.address = fileName;
|
||||
profileItem.remarks = "v2ray_custom";
|
||||
profileItem.remarks = v2rayConfig.remarks ?? "v2ray_custom";
|
||||
}
|
||||
//Is Clash configuration
|
||||
else if (Contains(clipboardData, "port", "socks-port", "proxies"))
|
||||
|
||||
@@ -354,11 +354,11 @@ namespace v2rayN.Handler
|
||||
if (node.streamSecurity == Global.StreamSecurityReality || node.streamSecurity == Global.StreamSecurity)
|
||||
{
|
||||
var server_name = string.Empty;
|
||||
if (!string.IsNullOrWhiteSpace(node.sni))
|
||||
if (!Utile.IsNullOrEmpty(node.sni))
|
||||
{
|
||||
server_name = node.sni;
|
||||
}
|
||||
else if (!string.IsNullOrWhiteSpace(node.requestHost))
|
||||
else if (!Utile.IsNullOrEmpty(node.requestHost))
|
||||
{
|
||||
server_name = Utile.String2List(node.requestHost)[0];
|
||||
}
|
||||
@@ -761,7 +761,7 @@ namespace v2rayN.Handler
|
||||
{
|
||||
var item = LazyConfig.Instance.GetDNSItem(ECoreType.sing_box);
|
||||
var tunDNS = item?.tunDNS;
|
||||
if (string.IsNullOrWhiteSpace(tunDNS))
|
||||
if (Utile.IsNullOrEmpty(tunDNS))
|
||||
{
|
||||
tunDNS = Utile.GetEmbedText(Global.TunSingboxDNSFileName);
|
||||
}
|
||||
@@ -771,7 +771,7 @@ namespace v2rayN.Handler
|
||||
{
|
||||
var item = LazyConfig.Instance.GetDNSItem(ECoreType.sing_box);
|
||||
var normalDNS = item?.normalDNS;
|
||||
if (string.IsNullOrWhiteSpace(normalDNS))
|
||||
if (Utile.IsNullOrEmpty(normalDNS))
|
||||
{
|
||||
normalDNS = "{\"servers\":[{\"address\":\"tcp://8.8.8.8\"}]}";
|
||||
}
|
||||
@@ -972,6 +972,13 @@ namespace v2rayN.Handler
|
||||
singboxConfig.route.rules.Add(rule);
|
||||
}
|
||||
|
||||
GenDns(new(), singboxConfig);
|
||||
var dnsServer = singboxConfig.dns?.servers.FirstOrDefault();
|
||||
if (dnsServer != null)
|
||||
{
|
||||
dnsServer.detour = singboxConfig.route.rules.LastOrDefault()?.outbound;
|
||||
}
|
||||
|
||||
//msg = string.Format(ResUI.SuccessfulConfiguration"), node.getSummary());
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -533,11 +533,11 @@ namespace v2rayN.Handler
|
||||
alpn = node.GetAlpn(),
|
||||
fingerprint = node.fingerprint.IsNullOrEmpty() ? _config.coreBasicItem.defFingerprint : node.fingerprint
|
||||
};
|
||||
if (!string.IsNullOrWhiteSpace(sni))
|
||||
if (!Utile.IsNullOrEmpty(sni))
|
||||
{
|
||||
tlsSettings.serverName = sni;
|
||||
}
|
||||
else if (!string.IsNullOrWhiteSpace(host))
|
||||
else if (!Utile.IsNullOrEmpty(host))
|
||||
{
|
||||
tlsSettings.serverName = Utile.String2List(host)[0];
|
||||
}
|
||||
@@ -592,15 +592,15 @@ namespace v2rayN.Handler
|
||||
WsSettings4Ray wsSettings = new();
|
||||
wsSettings.headers = new Headers4Ray();
|
||||
string path = node.path;
|
||||
if (!string.IsNullOrWhiteSpace(host))
|
||||
if (!Utile.IsNullOrEmpty(host))
|
||||
{
|
||||
wsSettings.headers.Host = host;
|
||||
}
|
||||
if (!string.IsNullOrWhiteSpace(path))
|
||||
if (!Utile.IsNullOrEmpty(path))
|
||||
{
|
||||
wsSettings.path = path;
|
||||
}
|
||||
if (!string.IsNullOrWhiteSpace(useragent))
|
||||
if (!Utile.IsNullOrEmpty(useragent))
|
||||
{
|
||||
wsSettings.headers.UserAgent = useragent;
|
||||
}
|
||||
@@ -611,11 +611,11 @@ namespace v2rayN.Handler
|
||||
case nameof(ETransport.httpupgrade):
|
||||
HttpupgradeSettings4Ray httpupgradeSettings = new();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(node.path))
|
||||
if (!Utile.IsNullOrEmpty(node.path))
|
||||
{
|
||||
httpupgradeSettings.path = node.path;
|
||||
}
|
||||
if (!string.IsNullOrWhiteSpace(host))
|
||||
if (!Utile.IsNullOrEmpty(host))
|
||||
{
|
||||
httpupgradeSettings.host = host;
|
||||
}
|
||||
@@ -626,7 +626,7 @@ namespace v2rayN.Handler
|
||||
case nameof(ETransport.h2):
|
||||
HttpSettings4Ray httpSettings = new();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(host))
|
||||
if (!Utile.IsNullOrEmpty(host))
|
||||
{
|
||||
httpSettings.host = Utile.String2List(host);
|
||||
}
|
||||
@@ -649,7 +649,7 @@ namespace v2rayN.Handler
|
||||
streamSettings.quicSettings = quicsettings;
|
||||
if (node.streamSecurity == Global.StreamSecurity)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(sni))
|
||||
if (!Utile.IsNullOrEmpty(sni))
|
||||
{
|
||||
streamSettings.tlsSettings.serverName = sni;
|
||||
}
|
||||
@@ -663,6 +663,7 @@ namespace v2rayN.Handler
|
||||
case nameof(ETransport.grpc):
|
||||
GrpcSettings4Ray grpcSettings = new()
|
||||
{
|
||||
authority = Utile.IsNullOrEmpty(host) ? null : host,
|
||||
serviceName = node.path,
|
||||
multiMode = (node.headerType == Global.GrpcMultiMode),
|
||||
idle_timeout = _config.grpcItem.idle_timeout,
|
||||
@@ -721,13 +722,13 @@ namespace v2rayN.Handler
|
||||
var item = LazyConfig.Instance.GetDNSItem(ECoreType.Xray);
|
||||
var normalDNS = item?.normalDNS;
|
||||
var domainStrategy4Freedom = item?.domainStrategy4Freedom;
|
||||
if (string.IsNullOrWhiteSpace(normalDNS))
|
||||
if (Utile.IsNullOrEmpty(normalDNS))
|
||||
{
|
||||
normalDNS = "1.1.1.1,8.8.8.8";
|
||||
}
|
||||
|
||||
//Outbound Freedom domainStrategy
|
||||
if (!string.IsNullOrWhiteSpace(domainStrategy4Freedom))
|
||||
if (!Utile.IsNullOrEmpty(domainStrategy4Freedom))
|
||||
{
|
||||
var outbound = v2rayConfig.outbounds[1];
|
||||
outbound.settings.domainStrategy = domainStrategy4Freedom;
|
||||
|
||||
@@ -292,7 +292,7 @@ namespace v2rayN.Handler
|
||||
{
|
||||
proc.OutputDataReceived += (sender, e) =>
|
||||
{
|
||||
if (!string.IsNullOrEmpty(e.Data))
|
||||
if (!Utile.IsNullOrEmpty(e.Data))
|
||||
{
|
||||
string msg = e.Data + Environment.NewLine;
|
||||
ShowMsg(false, msg);
|
||||
@@ -300,7 +300,7 @@ namespace v2rayN.Handler
|
||||
};
|
||||
proc.ErrorDataReceived += (sender, e) =>
|
||||
{
|
||||
if (!string.IsNullOrEmpty(e.Data))
|
||||
if (!Utile.IsNullOrEmpty(e.Data))
|
||||
{
|
||||
string msg = e.Data + Environment.NewLine;
|
||||
ShowMsg(false, msg);
|
||||
|
||||
@@ -364,6 +364,7 @@ namespace v2rayN.Handler
|
||||
case nameof(ETransport.grpc):
|
||||
if (!Utile.IsNullOrEmpty(item.path))
|
||||
{
|
||||
dicQuery.Add("authority", Utile.UrlEncode(item.requestHost));
|
||||
dicQuery.Add("serviceName", Utile.UrlEncode(item.path));
|
||||
if (item.headerType is Global.GrpcGunMode or Global.GrpcMultiMode)
|
||||
{
|
||||
@@ -592,7 +593,7 @@ namespace v2rayN.Handler
|
||||
break;
|
||||
|
||||
default:
|
||||
if (!string.IsNullOrWhiteSpace(i.streamSecurity))
|
||||
if (!Utile.IsNullOrEmpty(i.streamSecurity))
|
||||
return null;
|
||||
break;
|
||||
}
|
||||
@@ -981,6 +982,7 @@ namespace v2rayN.Handler
|
||||
break;
|
||||
|
||||
case nameof(ETransport.grpc):
|
||||
item.requestHost = Utile.UrlDecode(query["authority"] ?? "");
|
||||
item.path = Utile.UrlDecode(query["serviceName"] ?? "");
|
||||
item.headerType = Utile.UrlDecode(query["mode"] ?? Global.GrpcGunMode);
|
||||
break;
|
||||
|
||||
@@ -84,7 +84,7 @@ namespace v2rayN.Handler
|
||||
while (!res.CloseStatus.HasValue)
|
||||
{
|
||||
var result = Encoding.UTF8.GetString(buffer, 0, res.Count);
|
||||
if (!string.IsNullOrEmpty(result))
|
||||
if (!Utile.IsNullOrEmpty(result))
|
||||
{
|
||||
ParseOutput(result, out ulong up, out ulong down);
|
||||
|
||||
|
||||
@@ -207,7 +207,7 @@ namespace v2rayN.Handler
|
||||
//convert
|
||||
if (!Utile.IsNullOrEmpty(item.convertTarget))
|
||||
{
|
||||
var subConvertUrl = string.IsNullOrEmpty(config.constItem.subConvertUrl) ? Global.SubConvertUrls.FirstOrDefault() : config.constItem.subConvertUrl;
|
||||
var subConvertUrl = Utile.IsNullOrEmpty(config.constItem.subConvertUrl) ? Global.SubConvertUrls.FirstOrDefault() : config.constItem.subConvertUrl;
|
||||
url = string.Format(subConvertUrl!, Utile.UrlEncode(url));
|
||||
if (!url.Contains("target="))
|
||||
{
|
||||
|
||||
@@ -7,6 +7,11 @@ namespace v2rayN.Model
|
||||
/// </summary>
|
||||
public class V2rayConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// Properties that do not belong to Ray
|
||||
/// </summary>
|
||||
public string? remarks { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 日志配置
|
||||
/// </summary>
|
||||
@@ -634,7 +639,8 @@ namespace v2rayN.Model
|
||||
|
||||
public class GrpcSettings4Ray
|
||||
{
|
||||
public string serviceName { get; set; }
|
||||
public string? authority { get; set; }
|
||||
public string? serviceName { get; set; }
|
||||
public bool multiMode { get; set; }
|
||||
public int idle_timeout { get; set; }
|
||||
public int health_check_timeout { get; set; }
|
||||
|
||||
+9
@@ -3283,6 +3283,15 @@ namespace v2rayN.Resx {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 *grpc Authority 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string TransportRequestHostTip5 {
|
||||
get {
|
||||
return ResourceManager.GetString("TransportRequestHostTip5", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Ungrouped 的本地化字符串。
|
||||
/// </summary>
|
||||
|
||||
@@ -1195,4 +1195,7 @@
|
||||
<data name="SpeedtestingStop" xml:space="preserve">
|
||||
<value>Test terminating...</value>
|
||||
</data>
|
||||
<data name="TransportRequestHostTip5" xml:space="preserve">
|
||||
<value>*grpc Authority</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -1192,4 +1192,7 @@
|
||||
<data name="SpeedtestingStop" xml:space="preserve">
|
||||
<value>测试终止中...</value>
|
||||
</data>
|
||||
<data name="TransportRequestHostTip5" xml:space="preserve">
|
||||
<value>*grpc Authority</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -1165,4 +1165,7 @@
|
||||
<data name="SpeedtestingStop" xml:space="preserve">
|
||||
<value>測試終止中...</value>
|
||||
</data>
|
||||
<data name="TransportRequestHostTip5" xml:space="preserve">
|
||||
<value>*grpc Authority</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -46,7 +46,7 @@ namespace v2rayN.ViewModels
|
||||
private void SaveSub()
|
||||
{
|
||||
string remarks = SelectedSource.remarks;
|
||||
if (string.IsNullOrEmpty(remarks))
|
||||
if (Utile.IsNullOrEmpty(remarks))
|
||||
{
|
||||
_noticeHandler?.Enqueue(ResUI.PleaseFillRemarks);
|
||||
return;
|
||||
|
||||
@@ -346,6 +346,7 @@ namespace v2rayN.Views
|
||||
break;
|
||||
|
||||
case nameof(ETransport.grpc):
|
||||
tipRequestHost.Text = ResUI.TransportRequestHostTip5;
|
||||
tipPath.Text = ResUI.TransportPathTip4;
|
||||
tipHeaderType.Text = ResUI.TransportHeaderTypeTip4;
|
||||
labHeaderType.Visibility = Visibility.Hidden;
|
||||
|
||||
@@ -48,7 +48,7 @@ namespace v2rayN.Views
|
||||
|
||||
var MsgFilter = cmbMsgFilter.Text.TrimEx();
|
||||
if (MsgFilter != lastMsgFilter) lastMsgFilterNotAvailable = false;
|
||||
if (!string.IsNullOrEmpty(MsgFilter) && !lastMsgFilterNotAvailable)
|
||||
if (!Utile.IsNullOrEmpty(MsgFilter) && !lastMsgFilterNotAvailable)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.33.0
|
||||
// protoc v4.23.1
|
||||
// protoc v5.26.0
|
||||
// source: app/proxyman/config.proto
|
||||
|
||||
package proxyman
|
||||
@@ -524,6 +524,7 @@ type SenderConfig struct {
|
||||
StreamSettings *internet.StreamConfig `protobuf:"bytes,2,opt,name=stream_settings,json=streamSettings,proto3" json:"stream_settings,omitempty"`
|
||||
ProxySettings *internet.ProxyConfig `protobuf:"bytes,3,opt,name=proxy_settings,json=proxySettings,proto3" json:"proxy_settings,omitempty"`
|
||||
MultiplexSettings *MultiplexingConfig `protobuf:"bytes,4,opt,name=multiplex_settings,json=multiplexSettings,proto3" json:"multiplex_settings,omitempty"`
|
||||
ViaCidr string `protobuf:"bytes,5,opt,name=via_cidr,json=viaCidr,proto3" json:"via_cidr,omitempty"`
|
||||
}
|
||||
|
||||
func (x *SenderConfig) Reset() {
|
||||
@@ -586,6 +587,13 @@ func (x *SenderConfig) GetMultiplexSettings() *MultiplexingConfig {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *SenderConfig) GetViaCidr() string {
|
||||
if x != nil {
|
||||
return x.ViaCidr
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type MultiplexingConfig struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
@@ -855,7 +863,7 @@ var file_app_proxyman_config_proto_rawDesc = []byte{
|
||||
0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x2e, 0x54, 0x79, 0x70, 0x65,
|
||||
0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x0d, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x53,
|
||||
0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x22, 0x10, 0x0a, 0x0e, 0x4f, 0x75, 0x74, 0x62, 0x6f,
|
||||
0x75, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0xb0, 0x02, 0x0a, 0x0c, 0x53, 0x65,
|
||||
0x75, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0xcb, 0x02, 0x0a, 0x0c, 0x53, 0x65,
|
||||
0x6e, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x2d, 0x0a, 0x03, 0x76, 0x69,
|
||||
0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63,
|
||||
0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x49, 0x50, 0x4f, 0x72, 0x44, 0x6f,
|
||||
@@ -874,26 +882,28 @@ var file_app_proxyman_config_proto_rawDesc = []byte{
|
||||
0x28, 0x0b, 0x32, 0x25, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x70, 0x72,
|
||||
0x6f, 0x78, 0x79, 0x6d, 0x61, 0x6e, 0x2e, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x78,
|
||||
0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x11, 0x6d, 0x75, 0x6c, 0x74, 0x69,
|
||||
0x70, 0x6c, 0x65, 0x78, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x22, 0xa4, 0x01, 0x0a,
|
||||
0x12, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x78, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e,
|
||||
0x66, 0x69, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01,
|
||||
0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x20, 0x0a,
|
||||
0x0b, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x02, 0x20, 0x01,
|
||||
0x28, 0x05, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x12,
|
||||
0x28, 0x0a, 0x0f, 0x78, 0x75, 0x64, 0x70, 0x43, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e,
|
||||
0x63, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0f, 0x78, 0x75, 0x64, 0x70, 0x43, 0x6f,
|
||||
0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x28, 0x0a, 0x0f, 0x78, 0x75, 0x64,
|
||||
0x70, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x55, 0x44, 0x50, 0x34, 0x34, 0x33, 0x18, 0x04, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x0f, 0x78, 0x75, 0x64, 0x70, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x55, 0x44, 0x50,
|
||||
0x34, 0x34, 0x33, 0x2a, 0x23, 0x0a, 0x0e, 0x4b, 0x6e, 0x6f, 0x77, 0x6e, 0x50, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x12, 0x08, 0x0a, 0x04, 0x48, 0x54, 0x54, 0x50, 0x10, 0x00, 0x12,
|
||||
0x07, 0x0a, 0x03, 0x54, 0x4c, 0x53, 0x10, 0x01, 0x42, 0x55, 0x0a, 0x15, 0x63, 0x6f, 0x6d, 0x2e,
|
||||
0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x6d, 0x61,
|
||||
0x6e, 0x50, 0x01, 0x5a, 0x26, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
|
||||
0x78, 0x74, 0x6c, 0x73, 0x2f, 0x78, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x61,
|
||||
0x70, 0x70, 0x2f, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x6d, 0x61, 0x6e, 0xaa, 0x02, 0x11, 0x58, 0x72,
|
||||
0x61, 0x79, 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x6d, 0x61, 0x6e, 0x62,
|
||||
0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x70, 0x6c, 0x65, 0x78, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x19, 0x0a, 0x08,
|
||||
0x76, 0x69, 0x61, 0x5f, 0x63, 0x69, 0x64, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07,
|
||||
0x76, 0x69, 0x61, 0x43, 0x69, 0x64, 0x72, 0x22, 0xa4, 0x01, 0x0a, 0x12, 0x4d, 0x75, 0x6c, 0x74,
|
||||
0x69, 0x70, 0x6c, 0x65, 0x78, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x18,
|
||||
0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52,
|
||||
0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x63,
|
||||
0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x63,
|
||||
0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x28, 0x0a, 0x0f, 0x78, 0x75,
|
||||
0x64, 0x70, 0x43, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x03, 0x20,
|
||||
0x01, 0x28, 0x05, 0x52, 0x0f, 0x78, 0x75, 0x64, 0x70, 0x43, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72,
|
||||
0x65, 0x6e, 0x63, 0x79, 0x12, 0x28, 0x0a, 0x0f, 0x78, 0x75, 0x64, 0x70, 0x50, 0x72, 0x6f, 0x78,
|
||||
0x79, 0x55, 0x44, 0x50, 0x34, 0x34, 0x33, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x78,
|
||||
0x75, 0x64, 0x70, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x55, 0x44, 0x50, 0x34, 0x34, 0x33, 0x2a, 0x23,
|
||||
0x0a, 0x0e, 0x4b, 0x6e, 0x6f, 0x77, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73,
|
||||
0x12, 0x08, 0x0a, 0x04, 0x48, 0x54, 0x54, 0x50, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x54, 0x4c,
|
||||
0x53, 0x10, 0x01, 0x42, 0x55, 0x0a, 0x15, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e,
|
||||
0x61, 0x70, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x6d, 0x61, 0x6e, 0x50, 0x01, 0x5a, 0x26,
|
||||
0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x74, 0x6c, 0x73, 0x2f,
|
||||
0x78, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x70, 0x72,
|
||||
0x6f, 0x78, 0x79, 0x6d, 0x61, 0x6e, 0xaa, 0x02, 0x11, 0x58, 0x72, 0x61, 0x79, 0x2e, 0x41, 0x70,
|
||||
0x70, 0x2e, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x6d, 0x61, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
|
||||
@@ -91,6 +91,7 @@ message SenderConfig {
|
||||
xray.transport.internet.StreamConfig stream_settings = 2;
|
||||
xray.transport.internet.ProxyConfig proxy_settings = 3;
|
||||
MultiplexingConfig multiplex_settings = 4;
|
||||
string via_cidr = 5;
|
||||
}
|
||||
|
||||
message MultiplexingConfig {
|
||||
|
||||
@@ -4,6 +4,8 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"io"
|
||||
"math/rand"
|
||||
gonet "net"
|
||||
"os"
|
||||
|
||||
"github.com/xtls/xray-core/app/proxyman"
|
||||
@@ -269,7 +271,11 @@ func (h *Handler) Dial(ctx context.Context, dest net.Destination) (stat.Connecti
|
||||
outbound = new(session.Outbound)
|
||||
ctx = session.ContextWithOutbound(ctx, outbound)
|
||||
}
|
||||
outbound.Gateway = h.senderSettings.Via.AsAddress()
|
||||
if h.senderSettings.ViaCidr == "" {
|
||||
outbound.Gateway = h.senderSettings.Via.AsAddress()
|
||||
} else { //Get a random address.
|
||||
outbound.Gateway = ParseRandomIPv6(h.senderSettings.Via.AsAddress(), h.senderSettings.ViaCidr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -312,3 +318,17 @@ func (h *Handler) Close() error {
|
||||
common.Close(h.mux)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Return random IPv6 in a CIDR block
|
||||
func ParseRandomIPv6(address net.Address, prefix string) net.Address {
|
||||
addr := address.IP().String()
|
||||
_, network, _ := gonet.ParseCIDR(addr + "/" + prefix)
|
||||
|
||||
ipv6 := network.IP.To16()
|
||||
prefixLen, _ := network.Mask.Size()
|
||||
for i := prefixLen / 8; i < 16; i++ {
|
||||
ipv6[i] = byte(rand.Intn(256))
|
||||
}
|
||||
|
||||
return net.ParseAddress(gonet.IP(ipv6).String())
|
||||
}
|
||||
|
||||
@@ -183,6 +183,7 @@ func (c *WebSocketConfig) Build() (proto.Message, error) {
|
||||
type HttpUpgradeConfig struct {
|
||||
Path string `json:"path"`
|
||||
Host string `json:"host"`
|
||||
Headers map[string]string `json:"headers"`
|
||||
AcceptProxyProtocol bool `json:"acceptProxyProtocol"`
|
||||
}
|
||||
|
||||
@@ -202,6 +203,7 @@ func (c *HttpUpgradeConfig) Build() (proto.Message, error) {
|
||||
config := &httpupgrade.Config{
|
||||
Path: path,
|
||||
Host: c.Host,
|
||||
Header: c.Headers,
|
||||
AcceptProxyProtocol: c.AcceptProxyProtocol,
|
||||
Ed: ed,
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"github.com/xtls/xray-core/app/dispatcher"
|
||||
"github.com/xtls/xray-core/app/proxyman"
|
||||
"github.com/xtls/xray-core/app/stats"
|
||||
"github.com/xtls/xray-core/common/net"
|
||||
"github.com/xtls/xray-core/common/serial"
|
||||
core "github.com/xtls/xray-core/core"
|
||||
"github.com/xtls/xray-core/transport/internet"
|
||||
@@ -279,7 +280,7 @@ func (c *InboundDetourConfig) Build() (*core.InboundHandlerConfig, error) {
|
||||
|
||||
type OutboundDetourConfig struct {
|
||||
Protocol string `json:"protocol"`
|
||||
SendThrough *Address `json:"sendThrough"`
|
||||
SendThrough *string `json:"sendThrough"`
|
||||
Tag string `json:"tag"`
|
||||
Settings *json.RawMessage `json:"settings"`
|
||||
StreamSetting *StreamConfig `json:"streamSettings"`
|
||||
@@ -305,9 +306,14 @@ func (c *OutboundDetourConfig) Build() (*core.OutboundHandlerConfig, error) {
|
||||
}
|
||||
|
||||
if c.SendThrough != nil {
|
||||
address := c.SendThrough
|
||||
if address.Family().IsDomain() {
|
||||
return nil, newError("unable to send through: " + address.String())
|
||||
address := ParseSendThough(c.SendThrough)
|
||||
//Check if CIDR exists
|
||||
if strings.Contains(*c.SendThrough, "/") {
|
||||
senderSettings.ViaCidr = strings.Split(*c.SendThrough, "/")[1]
|
||||
} else {
|
||||
if address.Family().IsDomain() {
|
||||
return nil, newError("unable to send through: " + address.String())
|
||||
}
|
||||
}
|
||||
senderSettings.Via = address.Build()
|
||||
}
|
||||
@@ -397,19 +403,19 @@ type Config struct {
|
||||
// and should not be used.
|
||||
OutboundDetours []OutboundDetourConfig `json:"outboundDetour"`
|
||||
|
||||
LogConfig *LogConfig `json:"log"`
|
||||
RouterConfig *RouterConfig `json:"routing"`
|
||||
DNSConfig *DNSConfig `json:"dns"`
|
||||
InboundConfigs []InboundDetourConfig `json:"inbounds"`
|
||||
OutboundConfigs []OutboundDetourConfig `json:"outbounds"`
|
||||
Transport *TransportConfig `json:"transport"`
|
||||
Policy *PolicyConfig `json:"policy"`
|
||||
API *APIConfig `json:"api"`
|
||||
Metrics *MetricsConfig `json:"metrics"`
|
||||
Stats *StatsConfig `json:"stats"`
|
||||
Reverse *ReverseConfig `json:"reverse"`
|
||||
FakeDNS *FakeDNSConfig `json:"fakeDns"`
|
||||
Observatory *ObservatoryConfig `json:"observatory"`
|
||||
LogConfig *LogConfig `json:"log"`
|
||||
RouterConfig *RouterConfig `json:"routing"`
|
||||
DNSConfig *DNSConfig `json:"dns"`
|
||||
InboundConfigs []InboundDetourConfig `json:"inbounds"`
|
||||
OutboundConfigs []OutboundDetourConfig `json:"outbounds"`
|
||||
Transport *TransportConfig `json:"transport"`
|
||||
Policy *PolicyConfig `json:"policy"`
|
||||
API *APIConfig `json:"api"`
|
||||
Metrics *MetricsConfig `json:"metrics"`
|
||||
Stats *StatsConfig `json:"stats"`
|
||||
Reverse *ReverseConfig `json:"reverse"`
|
||||
FakeDNS *FakeDNSConfig `json:"fakeDns"`
|
||||
Observatory *ObservatoryConfig `json:"observatory"`
|
||||
BurstObservatory *BurstObservatoryConfig `json:"burstObservatory"`
|
||||
}
|
||||
|
||||
@@ -717,3 +723,10 @@ func (c *Config) Build() (*core.Config, error) {
|
||||
|
||||
return config, nil
|
||||
}
|
||||
|
||||
// Convert string to Address.
|
||||
func ParseSendThough(Addr *string) *Address {
|
||||
var addr Address
|
||||
addr.Address = net.ParseAddress(strings.Split(*Addr, "/")[0])
|
||||
return &addr
|
||||
}
|
||||
|
||||
@@ -43,12 +43,16 @@ Example:
|
||||
func executeBalancerInfo(cmd *base.Command, args []string) {
|
||||
setSharedFlags(cmd)
|
||||
cmd.Flag.Parse(args)
|
||||
unnamedArgs := cmd.Flag.Args()
|
||||
if len(unnamedArgs) == 0 {
|
||||
fmt.Println("set balancer tag")
|
||||
unnamedArgs = []string{""}
|
||||
}
|
||||
|
||||
conn, ctx, close := dialAPIServer()
|
||||
defer close()
|
||||
|
||||
client := routerService.NewRoutingServiceClient(conn)
|
||||
r := &routerService.GetBalancerInfoRequest{Tag: args[0]}
|
||||
r := &routerService.GetBalancerInfoRequest{Tag: unnamedArgs[0]}
|
||||
resp, err := client.GetBalancerInfo(ctx, r)
|
||||
if err != nil {
|
||||
base.Fatalf("failed to get health information: %s", err)
|
||||
@@ -75,9 +79,10 @@ func showBalancerInfo(b *routerService.BalancerMsg) {
|
||||
}
|
||||
// Selects
|
||||
sb.WriteString(" - Selects:\n")
|
||||
|
||||
for i, o := range b.PrincipleTarget.Tag {
|
||||
writeRow(sb, tableIndent, i+1, []string{o}, nil)
|
||||
if b.PrincipleTarget != nil {
|
||||
for i, o := range b.PrincipleTarget.Tag {
|
||||
writeRow(sb, tableIndent, i+1, []string{o}, nil)
|
||||
}
|
||||
}
|
||||
os.Stdout.WriteString(sb.String())
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.33.0
|
||||
// protoc v4.23.1
|
||||
// protoc v5.26.0
|
||||
// source: transport/internet/httpupgrade/config.proto
|
||||
|
||||
package httpupgrade
|
||||
@@ -25,10 +25,11 @@ type Config struct {
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Path string `protobuf:"bytes,2,opt,name=path,proto3" json:"path,omitempty"`
|
||||
Host string `protobuf:"bytes,3,opt,name=host,proto3" json:"host,omitempty"`
|
||||
AcceptProxyProtocol bool `protobuf:"varint,4,opt,name=accept_proxy_protocol,json=acceptProxyProtocol,proto3" json:"accept_proxy_protocol,omitempty"`
|
||||
Ed uint32 `protobuf:"varint,5,opt,name=ed,proto3" json:"ed,omitempty"`
|
||||
Path string `protobuf:"bytes,2,opt,name=path,proto3" json:"path,omitempty"`
|
||||
Host string `protobuf:"bytes,3,opt,name=host,proto3" json:"host,omitempty"`
|
||||
AcceptProxyProtocol bool `protobuf:"varint,4,opt,name=accept_proxy_protocol,json=acceptProxyProtocol,proto3" json:"accept_proxy_protocol,omitempty"`
|
||||
Ed uint32 `protobuf:"varint,5,opt,name=ed,proto3" json:"ed,omitempty"`
|
||||
Header map[string]string `protobuf:"bytes,6,rep,name=header,proto3" json:"header,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
|
||||
}
|
||||
|
||||
func (x *Config) Reset() {
|
||||
@@ -91,6 +92,13 @@ func (x *Config) GetEd() uint32 {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *Config) GetHeader() map[string]string {
|
||||
if x != nil {
|
||||
return x.Header
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var File_transport_internet_httpupgrade_config_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_transport_internet_httpupgrade_config_proto_rawDesc = []byte{
|
||||
@@ -99,24 +107,33 @@ var file_transport_internet_httpupgrade_config_proto_rawDesc = []byte{
|
||||
0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x23, 0x78,
|
||||
0x72, 0x61, 0x79, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e,
|
||||
0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x68, 0x74, 0x74, 0x70, 0x75, 0x70, 0x67, 0x72, 0x61,
|
||||
0x64, 0x65, 0x22, 0x7a, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x12, 0x0a, 0x04,
|
||||
0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68,
|
||||
0x12, 0x12, 0x0a, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
|
||||
0x68, 0x6f, 0x73, 0x74, 0x12, 0x32, 0x0a, 0x15, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x5f, 0x70,
|
||||
0x72, 0x6f, 0x78, 0x79, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x04, 0x20,
|
||||
0x01, 0x28, 0x08, 0x52, 0x13, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x50, 0x72, 0x6f, 0x78, 0x79,
|
||||
0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x0e, 0x0a, 0x02, 0x65, 0x64, 0x18, 0x05,
|
||||
0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, 0x65, 0x64, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x42, 0x8b,
|
||||
0x01, 0x0a, 0x27, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x74, 0x72, 0x61, 0x6e,
|
||||
0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x68,
|
||||
0x74, 0x74, 0x70, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x50, 0x01, 0x5a, 0x38, 0x67, 0x69,
|
||||
0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x74, 0x6c, 0x73, 0x2f, 0x78, 0x72,
|
||||
0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72,
|
||||
0x74, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2f, 0x68, 0x74, 0x74, 0x70, 0x75,
|
||||
0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0xaa, 0x02, 0x23, 0x58, 0x72, 0x61, 0x79, 0x2e, 0x54, 0x72,
|
||||
0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74,
|
||||
0x2e, 0x48, 0x74, 0x74, 0x70, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x62, 0x06, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x33,
|
||||
0x64, 0x65, 0x22, 0x86, 0x02, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x12, 0x0a,
|
||||
0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74,
|
||||
0x68, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x04, 0x68, 0x6f, 0x73, 0x74, 0x12, 0x32, 0x0a, 0x15, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x5f,
|
||||
0x70, 0x72, 0x6f, 0x78, 0x79, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x04,
|
||||
0x20, 0x01, 0x28, 0x08, 0x52, 0x13, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x50, 0x72, 0x6f, 0x78,
|
||||
0x79, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x0e, 0x0a, 0x02, 0x65, 0x64, 0x18,
|
||||
0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, 0x65, 0x64, 0x12, 0x4f, 0x0a, 0x06, 0x68, 0x65, 0x61,
|
||||
0x64, 0x65, 0x72, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x37, 0x2e, 0x78, 0x72, 0x61, 0x79,
|
||||
0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72,
|
||||
0x6e, 0x65, 0x74, 0x2e, 0x68, 0x74, 0x74, 0x70, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x2e,
|
||||
0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x45, 0x6e, 0x74,
|
||||
0x72, 0x79, 0x52, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x1a, 0x39, 0x0a, 0x0b, 0x48, 0x65,
|
||||
0x61, 0x64, 0x65, 0x72, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79,
|
||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76,
|
||||
0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75,
|
||||
0x65, 0x3a, 0x02, 0x38, 0x01, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x42, 0x8b, 0x01, 0x0a, 0x27,
|
||||
0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f,
|
||||
0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x68, 0x74, 0x74, 0x70,
|
||||
0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x50, 0x01, 0x5a, 0x38, 0x67, 0x69, 0x74, 0x68, 0x75,
|
||||
0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x74, 0x6c, 0x73, 0x2f, 0x78, 0x72, 0x61, 0x79, 0x2d,
|
||||
0x63, 0x6f, 0x72, 0x65, 0x2f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x69,
|
||||
0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2f, 0x68, 0x74, 0x74, 0x70, 0x75, 0x70, 0x67, 0x72,
|
||||
0x61, 0x64, 0x65, 0xaa, 0x02, 0x23, 0x58, 0x72, 0x61, 0x79, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73,
|
||||
0x70, 0x6f, 0x72, 0x74, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x48, 0x74,
|
||||
0x74, 0x70, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -131,16 +148,18 @@ func file_transport_internet_httpupgrade_config_proto_rawDescGZIP() []byte {
|
||||
return file_transport_internet_httpupgrade_config_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_transport_internet_httpupgrade_config_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
|
||||
var file_transport_internet_httpupgrade_config_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
|
||||
var file_transport_internet_httpupgrade_config_proto_goTypes = []interface{}{
|
||||
(*Config)(nil), // 0: xray.transport.internet.httpupgrade.Config
|
||||
nil, // 1: xray.transport.internet.httpupgrade.Config.HeaderEntry
|
||||
}
|
||||
var file_transport_internet_httpupgrade_config_proto_depIdxs = []int32{
|
||||
0, // [0:0] is the sub-list for method output_type
|
||||
0, // [0:0] is the sub-list for method input_type
|
||||
0, // [0:0] is the sub-list for extension type_name
|
||||
0, // [0:0] is the sub-list for extension extendee
|
||||
0, // [0:0] is the sub-list for field type_name
|
||||
1, // 0: xray.transport.internet.httpupgrade.Config.header:type_name -> xray.transport.internet.httpupgrade.Config.HeaderEntry
|
||||
1, // [1:1] is the sub-list for method output_type
|
||||
1, // [1:1] is the sub-list for method input_type
|
||||
1, // [1:1] is the sub-list for extension type_name
|
||||
1, // [1:1] is the sub-list for extension extendee
|
||||
0, // [0:1] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_transport_internet_httpupgrade_config_proto_init() }
|
||||
@@ -168,7 +187,7 @@ func file_transport_internet_httpupgrade_config_proto_init() {
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_transport_internet_httpupgrade_config_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 1,
|
||||
NumMessages: 2,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
|
||||
@@ -15,4 +15,5 @@ message Config {
|
||||
bool accept_proxy_protocol = 4;
|
||||
|
||||
uint32 ed = 5;
|
||||
map<string, string> header = 6;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
package httpupgrade
|
||||
|
||||
import "net"
|
||||
|
||||
type connnection struct {
|
||||
net.Conn
|
||||
remoteAddr net.Addr
|
||||
}
|
||||
|
||||
func newConnection(conn net.Conn, remoteAddr net.Addr) *connnection {
|
||||
return &connnection{
|
||||
Conn: conn,
|
||||
remoteAddr: remoteAddr,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *connnection) RemoteAddr() net.Addr {
|
||||
return c.remoteAddr
|
||||
}
|
||||
@@ -73,6 +73,9 @@ func dialhttpUpgrade(ctx context.Context, dest net.Destination, streamSettings *
|
||||
Host: transportConfiguration.Host,
|
||||
Header: make(http.Header),
|
||||
}
|
||||
for key, value := range transportConfiguration.Header {
|
||||
req.Header.Add(key, value)
|
||||
}
|
||||
req.Header.Set("Connection", "upgrade")
|
||||
req.Header.Set("Upgrade", "websocket")
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
|
||||
"github.com/xtls/xray-core/common"
|
||||
"github.com/xtls/xray-core/common/net"
|
||||
http_proto "github.com/xtls/xray-core/common/protocol/http"
|
||||
"github.com/xtls/xray-core/common/session"
|
||||
"github.com/xtls/xray-core/transport/internet"
|
||||
"github.com/xtls/xray-core/transport/internet/stat"
|
||||
@@ -68,6 +69,20 @@ func (s *server) Handle(conn net.Conn) (stat.Connection, error) {
|
||||
_ = conn.Close()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
forwardedAddrs := http_proto.ParseXForwardedFor(req.Header)
|
||||
remoteAddr := conn.RemoteAddr()
|
||||
if len(forwardedAddrs) > 0 && forwardedAddrs[0].Family().IsIP() {
|
||||
remoteAddr = &net.TCPAddr{
|
||||
IP: forwardedAddrs[0].IP(),
|
||||
Port: int(0),
|
||||
}
|
||||
}
|
||||
if remoteAddr == nil {
|
||||
return nil, newError("remoteAddr is nil")
|
||||
}
|
||||
|
||||
conn = newConnection(conn, remoteAddr)
|
||||
return stat.Connection(conn), nil
|
||||
}
|
||||
|
||||
|
||||
@@ -1647,10 +1647,10 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
|
||||
except JSInterpreter.Exception as e:
|
||||
self.report_warning(
|
||||
'%s (%s %s)' % (
|
||||
self.__ie_msg(
|
||||
'Unable to decode n-parameter: download likely to be throttled'),
|
||||
'Unable to decode n-parameter: download likely to be throttled',
|
||||
error_to_compat_str(e),
|
||||
traceback.format_exc()))
|
||||
traceback.format_exc()),
|
||||
video_id=video_id)
|
||||
return
|
||||
|
||||
self.write_debug('Decrypted nsig {0} => {1}'.format(n, ret))
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import contextlib
|
||||
import io
|
||||
import logging
|
||||
import ssl
|
||||
@@ -38,27 +39,40 @@ if websockets_version < (12, 0):
|
||||
import websockets.sync.client
|
||||
from websockets.uri import parse_uri
|
||||
|
||||
# In websockets Connection, recv_exc and recv_events_exc are defined
|
||||
# after the recv events handler thread is started [1].
|
||||
# On our CI using PyPy, in some cases a race condition may occur
|
||||
# where the recv events handler thread tries to use these attributes before they are defined [2].
|
||||
# 1: https://github.com/python-websockets/websockets/blame/de768cf65e7e2b1a3b67854fb9e08816a5ff7050/src/websockets/sync/connection.py#L93
|
||||
# 2: "AttributeError: 'ClientConnection' object has no attribute 'recv_events_exc'. Did you mean: 'recv_events'?"
|
||||
import websockets.sync.connection # isort: split
|
||||
with contextlib.suppress(Exception):
|
||||
# > 12.0
|
||||
websockets.sync.connection.Connection.recv_exc = None
|
||||
# 12.0
|
||||
websockets.sync.connection.Connection.recv_events_exc = None
|
||||
|
||||
|
||||
class WebsocketsResponseAdapter(WebSocketResponse):
|
||||
|
||||
def __init__(self, wsw: websockets.sync.client.ClientConnection, url):
|
||||
def __init__(self, ws: websockets.sync.client.ClientConnection, url):
|
||||
super().__init__(
|
||||
fp=io.BytesIO(wsw.response.body or b''),
|
||||
fp=io.BytesIO(ws.response.body or b''),
|
||||
url=url,
|
||||
headers=wsw.response.headers,
|
||||
status=wsw.response.status_code,
|
||||
reason=wsw.response.reason_phrase,
|
||||
headers=ws.response.headers,
|
||||
status=ws.response.status_code,
|
||||
reason=ws.response.reason_phrase,
|
||||
)
|
||||
self.wsw = wsw
|
||||
self._ws = ws
|
||||
|
||||
def close(self):
|
||||
self.wsw.close()
|
||||
self._ws.close()
|
||||
super().close()
|
||||
|
||||
def send(self, message):
|
||||
# https://websockets.readthedocs.io/en/stable/reference/sync/client.html#websockets.sync.client.ClientConnection.send
|
||||
try:
|
||||
return self.wsw.send(message)
|
||||
return self._ws.send(message)
|
||||
except (websockets.exceptions.WebSocketException, RuntimeError, TimeoutError) as e:
|
||||
raise TransportError(cause=e) from e
|
||||
except SocksProxyError as e:
|
||||
@@ -69,7 +83,7 @@ class WebsocketsResponseAdapter(WebSocketResponse):
|
||||
def recv(self):
|
||||
# https://websockets.readthedocs.io/en/stable/reference/sync/client.html#websockets.sync.client.ClientConnection.recv
|
||||
try:
|
||||
return self.wsw.recv()
|
||||
return self._ws.recv()
|
||||
except SocksProxyError as e:
|
||||
raise ProxyError(cause=e) from e
|
||||
except (websockets.exceptions.WebSocketException, RuntimeError, TimeoutError) as e:
|
||||
|
||||
Reference in New Issue
Block a user