fix(fptn): add fptn action to sing-box route target and outbound generation

- Add fptn to route.target() to prevent exit(2) crash on config generation
- Add add_fptn_outbound() using direct outbound with routing_mark=0x00300000
  (routes traffic through tun-fptn via kernel ip rule → table 4249)
- Add fptn to reserve_section_outbound_tags
- Add fptn to generator_routes outbound dispatch

Fixes torrents and all traffic breaking when an FPTN section is configured.
This commit is contained in:
Dushnilin
2026-09-16 06:33:23 +03:00
parent c59e90f4e1
commit 971d958331
3 changed files with 16 additions and 3 deletions
@@ -1844,6 +1844,16 @@ function add_olcrtc_outbound(config, section, sections) {
});
}
// FPTN routes traffic through its TUN interface (tun-fptn) via kernel routing.
// fwmark 0x00300000 (3145728) → ip rule → routing table 4249 → dev tun-fptn.
function add_fptn_outbound(config, section, sections) {
push(config.outbounds, {
type: "direct",
tag: outbound_tag(section[".name"]),
routing_mark: 3145728
});
}
return {
init,
reserved_runtime_tag_set,
@@ -1880,5 +1890,6 @@ return {
add_zapret2_outbound,
add_byedpi_outbound,
add_wdtt_outbound,
add_olcrtc_outbound
add_olcrtc_outbound,
add_fptn_outbound
};
@@ -1824,6 +1824,8 @@ function add_outbound_for_section(config, section, taken, sections) {
ctx.outbounds.add_wdtt_outbound(config, section, sections);
else if (action == "olcrtc")
ctx.outbounds.add_olcrtc_outbound(config, section, sections);
else if (action == "fptn")
ctx.outbounds.add_fptn_outbound(config, section, sections);
else if (action == "bypass") {
/* route-only action */
}
@@ -1849,7 +1851,7 @@ function reserve_section_outbound_tags(sections, taken) {
let action = option(section, "action", "");
if (connections.is_connections_action(action) ||
action == "awg" || action == "warp" || action == "byedpi" || action == "zapret" || action == "zapret2" ||
action == "wdtt" || action == "olcrtc" ||
action == "wdtt" || action == "olcrtc" || action == "fptn" ||
action == "anytls" || action == "snell" || action == "mieru" || action == "sudoku" ||
action == "masque" || action == "openvpn")
taken[outbound_tag(section[".name"])] = true;
+1 -1
View File
@@ -126,7 +126,7 @@ function target(section, outbound_tag_name) {
action == "anytls" || action == "snell" || action == "mieru" || action == "sudoku" ||
action == "masque" || action == "openvpn" ||
action == "byedpi" || action == "zapret" || action == "zapret2" ||
action == "wdtt" || action == "olcrtc")
action == "wdtt" || action == "olcrtc" || action == "fptn")
return { action: "route", outbound: outbound_tag_name };
if (action == "bypass")
return { action: "route", outbound: runtime_constants.BYPASS_OUTBOUND_TAG };