Verification Steps
Description
[Feature] Loopback proxy for re-running rules with a new IN-NAME / sub-rules
Problem
In mihomo, a proxy-group is currently effectively the point where the final outbound is selected. If a rules entry selects a group, and the user then selects a specific proxy inside that group, there is no way to run rules again after that selection.
This makes the following use case difficult:
- incoming traffic goes into one common proxy-group, for example
GLOBAL;
- inside
GLOBAL, the user selects a special outbound with one button;
- this outbound should not perform a real network dial, but should send the connection back to the rule matcher;
- after that,
rules should decide again where to route the traffic, for example YouTube to one group, AI/ChatGPT to another group, and everything else to DIRECT.
Proposal
Add a new proxy type:
proxies:
- name: LB
type: loopback
target-in-name: LB_TEST
target-sub-rules: loopback-test
max-hops: 2
loopback is not a real network outbound. Instead, it triggers another rule matching pass.
Fields
target-in-name
Sets a new metadata.InName value before the second rule matching pass. After that, normal rules can match it:
rules:
- AND,((IN-NAME,LB_TEST),(RULE-SET,geosite_youtube)),LINK_YOUTUBE
- AND,((IN-NAME,LB_TEST),(RULE-SET,geosite_ai)),LINK_AI
- IN-NAME,mixed-in,GLOBAL
- MATCH,DIRECT
target-sub-rules
Optionally selects a sub-rules set for the second rule matching pass. If the target set does not exist, mihomo could log a warning and fall back to the default rules.
Example:
sub-rules:
loopback-test:
- RULE-SET,geosite_youtube,LINK_YOUTUBE
- RULE-SET,geosite_ai,LINK_AI
- MATCH,DIRECT
max-hops
Limits the number of loopback jumps for one connection. This is a guard against invalid configs and routing loops.
Example scenario
proxy-groups:
- name: GLOBAL
type: select
proxies:
- LB
- DIRECT
- SomeProxy
proxies:
- name: LB
type: loopback
target-in-name: LB_TEST
max-hops: 2
rules:
- AND,((IN-NAME,LB_TEST),(RULE-SET,geosite_youtube)),LINK_YOUTUBE
- AND,((IN-NAME,LB_TEST),(RULE-SET,geosite_ai)),LINK_AI
- IN-NAME,mixed-in,GLOBAL
- MATCH,DIRECT
Flow:
- A client connects through
mixed-in.
- The rule
IN-NAME,mixed-in,GLOBAL sends traffic to GLOBAL.
- The user selects
LB inside GLOBAL.
LB triggers another rule matching pass and sets IN-NAME=LB_TEST.
- The second rule matching pass routes YouTube, AI/ChatGPT, and everything else using normal rules.
Loop protection
There should be protection against accidental infinite loopback routing.
Suggested behavior:
- if the same loopback transition is detected again, drop the connection;
- if
max-hops is exceeded, drop the connection;
- both cases should be logged as warnings;
- a missing
target-sub-rules should not drop the connection, a warning plus fallback to default rules should be enough.
url-test / health-check behavior
Because loopback can be selected inside a proxy-group, it would be useful if url-test did not fail immediately on the loopback proxy itself. Instead, it should run the same second rule matching pass and test the final selected outbound.
For example, if the health-check URL https://www.gstatic.com/generate_204 is routed to DIRECT after the second rule matching pass, the test should go through DIRECT.
Connections display
For debugging, it would be useful if chains showed that the connection passed through loopback, for example:
LINK_YOUTUBE -> LB -> GLOBAL -> FinalProxy
Otherwise, the web panel only shows the final rule and final group, but not the intermediate loopback step.
Prototype
I made an experimental prototype based on v1.19.24:
https://github.com/Medium1992/mihomo-loopback/commit/d8b73e2283657eead03589e15eddd3c09facf5b2
I tested the prototype locally in an Alpine container on RouterOS:
- re-running
rules works;
IN-NAME after loopback works;
RULE-SET after loopback works;
- fallback for missing
target-sub-rules works;
url-test behavior for loopback is included in the prototype;
go test ./... passes.
The prototype was made with the help of Codex: I described the desired behavior and tested the result, because I am not very strong in Go programming myself.
I do not insist on this exact implementation. I would be very happy if the idea of such a loopback proxy could be considered and integrated into mihomo in a form that fits the project. In my opinion, this proxy could add a lot of flexibility: the user can select one item in a proxy-group, and then normal rules can handle the rest of the routing, instead of creating many separate groups for different resources.
Verification Steps
Description
[Feature] Loopback proxy for re-running rules with a new IN-NAME / sub-rules
Problem
In mihomo, a proxy-group is currently effectively the point where the final outbound is selected. If a
rulesentry selects a group, and the user then selects a specific proxy inside that group, there is no way to runrulesagain after that selection.This makes the following use case difficult:
GLOBAL;GLOBAL, the user selects a special outbound with one button;rulesshould decide again where to route the traffic, for example YouTube to one group, AI/ChatGPT to another group, and everything else to DIRECT.Proposal
Add a new proxy type:
loopbackis not a real network outbound. Instead, it triggers another rule matching pass.Fields
target-in-nameSets a new
metadata.InNamevalue before the second rule matching pass. After that, normal rules can match it:target-sub-rulesOptionally selects a
sub-rulesset for the second rule matching pass. If the target set does not exist, mihomo could log a warning and fall back to the defaultrules.Example:
max-hopsLimits the number of loopback jumps for one connection. This is a guard against invalid configs and routing loops.
Example scenario
Flow:
mixed-in.IN-NAME,mixed-in,GLOBALsends traffic toGLOBAL.LBinsideGLOBAL.LBtriggers another rule matching pass and setsIN-NAME=LB_TEST.Loop protection
There should be protection against accidental infinite loopback routing.
Suggested behavior:
max-hopsis exceeded, drop the connection;target-sub-rulesshould not drop the connection, a warning plus fallback to defaultrulesshould be enough.url-test / health-check behavior
Because
loopbackcan be selected inside a proxy-group, it would be useful ifurl-testdid not fail immediately on theloopbackproxy itself. Instead, it should run the same second rule matching pass and test the final selected outbound.For example, if the health-check URL
https://www.gstatic.com/generate_204is routed toDIRECTafter the second rule matching pass, the test should go throughDIRECT.Connections display
For debugging, it would be useful if
chainsshowed that the connection passed through loopback, for example:Otherwise, the web panel only shows the final rule and final group, but not the intermediate loopback step.
Prototype
I made an experimental prototype based on
v1.19.24:https://github.com/Medium1992/mihomo-loopback/commit/d8b73e2283657eead03589e15eddd3c09facf5b2
I tested the prototype locally in an Alpine container on RouterOS:
rulesworks;IN-NAMEafter loopback works;RULE-SETafter loopback works;target-sub-rulesworks;url-testbehavior for loopback is included in the prototype;go test ./...passes.The prototype was made with the help of Codex: I described the desired behavior and tested the result, because I am not very strong in Go programming myself.
I do not insist on this exact implementation. I would be very happy if the idea of such a
loopbackproxy could be considered and integrated into mihomo in a form that fits the project. In my opinion, this proxy could add a lot of flexibility: the user can select one item in a proxy-group, and then normalrulescan handle the rest of the routing, instead of creating many separate groups for different resources.