feat: 国内流量直连分流(geoip-cn / geosite-cn)— #5
国内 IP/域名直连(不走隧道)→ 省流量 + 国内访问快;非国内走代理。
- clientconfig.go: BuildClientConfig 加 ClientConfigOpts{SplitCN,RulesBaseURL};
开启时 route 加 {rule_set:[geoip-cn,geosite-cn]→direct} + 定义 rule_set
(remote .srs,download_detour:direct 直连下载)
- rules.go: 控制面静态服务 /v1/rules/{name}.srs(白名单防穿越)——自托管避免
GitHub 在国内被墙的鸡生蛋;客户端反正连控制面,可达性有保证
- nodes.go ConnectNode: 读 ?split_cn → opts;NodeAPI 加 rulesBaseURL
(PANGOLIN_PUBLIC_URL);main.go 挂 /v1/rules 路由 + RulesHandler
- 客户端: connect_api splitCN→?split_cn=1;connection_provider 传 smartRoute 偏好
- deploy/single-node: 拉 geoip-cn/geosite-cn.srs 到 $DATA_DIR/rules +
设 PANGOLIN_PUBLIC_URL/PANGOLIN_RULES_DIR
验证:go test(splitCN 开/关渲染 + RulesHandler 白名单/404)+ flutter analyze +
shellcheck;不需要节点。订阅链接暂用默认 opts、DNS 分流为后续增强。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -27,11 +27,14 @@ type NodeAPI struct {
|
||||
store nodes.NodeStore
|
||||
hub *nodes.Hub
|
||||
deriveKey string
|
||||
// rulesBaseURL 是控制面对外公网基址(PANGOLIN_PUBLIC_URL),供国内分流的
|
||||
// rule_set .srs 下载用;空则分流不生效。
|
||||
rulesBaseURL string
|
||||
}
|
||||
|
||||
// NewNodeAPI creates a NodeAPI.
|
||||
func NewNodeAPI(store nodes.NodeStore, hub *nodes.Hub, deriveKey string) *NodeAPI {
|
||||
return &NodeAPI{store: store, hub: hub, deriveKey: deriveKey}
|
||||
func NewNodeAPI(store nodes.NodeStore, hub *nodes.Hub, deriveKey, rulesBaseURL string) *NodeAPI {
|
||||
return &NodeAPI{store: store, hub: hub, deriveKey: deriveKey, rulesBaseURL: rulesBaseURL}
|
||||
}
|
||||
|
||||
// ─── GET /v1/nodes ───────────────────────────────────────────────────────────
|
||||
@@ -175,7 +178,10 @@ func (a *NodeAPI) ConnectNode(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
// 7. Render and return the full sing-box CLIENT config JSON.
|
||||
cfgJSON, renderErr := BuildClientConfig(node, ent.DpUUID, a.deriveKey)
|
||||
// split_cn=1/true → 国内 IP/域名直连(#5);客户端按 smartRoute 偏好传。
|
||||
splitCN := r.URL.Query().Get("split_cn") == "1" || r.URL.Query().Get("split_cn") == "true"
|
||||
cfgJSON, renderErr := BuildClientConfig(node, ent.DpUUID, a.deriveKey,
|
||||
ClientConfigOpts{SplitCN: splitCN, RulesBaseURL: a.rulesBaseURL})
|
||||
if renderErr != nil {
|
||||
apierr.WriteJSON(w, http.StatusInternalServerError, apierr.ErrInternal)
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user