默认入站:显示可选出站,并给一条转成命名入站的路

上一版把默认入站的整个出站块都藏了,结果策略组也看不见。改成只藏 RULE/DIRECT/GLOBAL
那三张卡(它固定是 RULE),策略组和线路照常列出来当上下文,只是不可点。

顺带修一个显示错误:老式顶层端口没有 listen 字段,实际地址是内核从 allow-lan 和
bind-address 推出来的(listener/listener.go:709-718)——allow-lan 关着时绑的是
127.0.0.1,而界面一律显示 0.0.0.0,会让人以为局域网连得上。

转换时会把老式端口字段删掉并把推导出的地址显式写进 listen:不删会导致同一个端口被声明
两次内核起不来,不写 listen 则以后改 allow-lan 会连带影响这个端口。
This commit is contained in:
im0o
2026-08-10 12:37:33 +08:00
parent cf24755375
commit f97981b146
4 changed files with 126 additions and 14 deletions
+22
View File
@@ -39,6 +39,28 @@ describe('合并两套写法的入站', () => {
})
})
describe('老式端口实际绑在哪', () => {
// 内核源码 listener/listener.go:709-718。界面上一律显示 0.0.0.0 会骗人。
it('allow-lan 没开时只绑本机', () => {
expect(collectInbounds({ 'mixed-port': 7777 })[0]!.listen).toBe('127.0.0.1')
expect(collectInbounds({ 'mixed-port': 7777, 'allow-lan': false })[0]!.listen).toBe('127.0.0.1')
})
it('allow-lan 开了但没指定地址时绑所有网卡', () => {
expect(collectInbounds({ 'mixed-port': 7777, 'allow-lan': true })[0]!.listen).toBe('0.0.0.0')
expect(
collectInbounds({ 'mixed-port': 7777, 'allow-lan': true, 'bind-address': '*' })[0]!.listen,
).toBe('0.0.0.0')
})
it('指定了地址就用那个地址', () => {
expect(
collectInbounds({ 'mixed-port': 7777, 'allow-lan': true, 'bind-address': '192.168.1.5' })[0]!
.listen,
).toBe('192.168.1.5')
})
})
describe('出站去向的四种形态', () => {
const of = (proxy?: string) => {
// 用扩展而不是直接写 proxy: undefined —— 配置里「没有这个键」和「这个键是空」
+18 -1
View File
@@ -74,8 +74,25 @@ export function outboundToProxyField(mode: OutboundMode): string | undefined {
return mode.name
}
/**
* 老式顶层端口实际绑在哪个地址上。
*
* 它没有自己的 listen 字段,地址是内核从两个全局开关推出来的
* (内核源码 `listener/listener.go:709-718`):
* allow-lan 关 → 127.0.0.1,只有本机连得上
* allow-lan 开 → bind-address 指定的地址,写 * 或没写就是所有网卡
* 界面上不能一律显示 0.0.0.0,那会让人以为局域网连得上而实际连不上。
*/
export function legacyListenAddress(data: ConfigObject): string {
if (data['allow-lan'] !== true) return '127.0.0.1'
const bind = data['bind-address']
if (typeof bind !== 'string' || bind === '' || bind === '*') return '0.0.0.0'
return bind
}
export function collectInbounds(data: ConfigObject): Inbound[] {
const result: Inbound[] = []
const legacyListen = legacyListenAddress(data)
for (const { key, type } of LEGACY_PORTS) {
const raw = data[key]
@@ -89,7 +106,7 @@ export function collectInbounds(data: ConfigObject): Inbound[] {
name: key,
type,
port: String(port),
listen: null,
listen: legacyListen,
outbound: { kind: 'rules' },
ruleSet: null,
isDefault: true,