From 9e5b35c8671cc8b92b6524d6945d17bb1058d356 Mon Sep 17 00:00:00 2001
From: sitieqiang <42805344+sitieqiang@users.noreply.github.com>
Date: Wed, 20 Feb 2019 17:44:24 +0800
Subject: [PATCH] Add reverse config for V2Ray Pro
* add reverse
add reverse
use io write ,fix sequence(cjson.encode's sequence , reverse can't work )
* fix v2ray rule bug
---
.../luasrc/model/cbi/v2raypro.lua | 109 ++++++
.../luci-app-v2ray-pro/po/zh-cn/v2raypro.po | 6 +
.../root/etc/config/v2raypro | 25 +-
.../root/etc/v2ray/gen_config.lua | 337 ++++++++++++------
4 files changed, 360 insertions(+), 117 deletions(-)
mode change 100644 => 100755 package/lean/luci-app-v2ray-pro/luasrc/model/cbi/v2raypro.lua
mode change 100644 => 100755 package/lean/luci-app-v2ray-pro/po/zh-cn/v2raypro.po
mode change 100644 => 100755 package/lean/luci-app-v2ray-pro/root/etc/config/v2raypro
mode change 100644 => 100755 package/lean/luci-app-v2ray-pro/root/etc/v2ray/gen_config.lua
diff --git a/package/lean/luci-app-v2ray-pro/luasrc/model/cbi/v2raypro.lua b/package/lean/luci-app-v2ray-pro/luasrc/model/cbi/v2raypro.lua
old mode 100644
new mode 100755
index 28137d207..824246edf
--- a/package/lean/luci-app-v2ray-pro/luasrc/model/cbi/v2raypro.lua
+++ b/package/lean/luci-app-v2ray-pro/luasrc/model/cbi/v2raypro.lua
@@ -174,7 +174,116 @@ tls.rmempty = false
mux = s:taboption("main",Flag, "mux", translate("Mux"))
mux.rmempty = false
+------------------------------------------------
+s:tab("reverse", translate("Severse Setting"))
+risen = s:taboption("reverse",Flag, "risen", translate("Enable"))
+risen.rmempty = false
+rserver = s:taboption("reverse",Value, "raddress", translate("Server Address"))
+rserver.datatype = "host"
+rserver.rmempty = ture
+
+rserver_domain = s:taboption("reverse",Value, "rserver_domain", translate("Server domain"))
+rserver_domain.datatype = "host"
+rserver_domain.rmempty = ture
+
+rserver_port = s:taboption("reverse",Value, "rport", translate("Server Port"))
+rserver_port.datatype = "range(0,65535)"
+rserver_port.rmempty = ture
+
+rid = s:taboption("reverse",Value, "rid", translate("ID"))
+rid.password = true
+
+ralterId = s:taboption("reverse",Value, "ralterId", translate("Alter ID"))
+ralterId.datatype = "range(1,65535)"
+ralterId.rmempty = ture
+
+rsecurity = s:taboption("reverse",ListValue, "rsecurity", translate("Security"))
+rsecurity:value("none")
+rsecurity:value("auto")
+rsecurity:value("aes-128-cfb")
+rsecurity:value("aes-128-gcm")
+rsecurity:value("chacha20-poly1305")
+
+rnetwork_type = s:taboption("reverse",ListValue, "rnetwork_type", translate("Network Type"))
+rnetwork_type:value("tcp")
+rnetwork_type:value("kcp")
+rnetwork_type:value("ws")
+rnetwork_type:value("h2")
+
+-- tcp settings
+rtcp_obfs = s:taboption("reverse",ListValue, "rtcp_obfs", translate("TCP Obfs"))
+rtcp_obfs:value("none")
+rtcp_obfs:value("http")
+rtcp_obfs:depends("rnetwork_type", "tcp")
+
+rtcp_path = s:taboption("reverse",DynamicList, "rtcp_path", translate("TCP Obfs Path"))
+rtcp_path:depends("rtcp_obfs", "http")
+
+rtcp_host = s:taboption("reverse",DynamicList, "rtcp_host", translate("TCP Obfs Header"))
+rtcp_host:depends("rtcp_obfs", "http")
+rtcp_host.datatype = "host"
+
+-- kcp settings
+rkcp_obfs = s:taboption("reverse",ListValue, "rkcp_obfs", translate("KCP Obfs"))
+rkcp_obfs:value("none")
+rkcp_obfs:value("srtp")
+rkcp_obfs:value("utp")
+rkcp_obfs:value("wechat-video")
+rkcp_obfs:value("dtls")
+rkcp_obfs:value("wireguard")
+rkcp_obfs:depends("rnetwork_type", "kcp")
+
+rkcp_mtu = s:taboption("reverse",Value, "rkcp_mtu", translate("KCP MTU"))
+rkcp_mtu.datatype = "range(576,1460)"
+rkcp_mtu:depends("rnetwork_type", "kcp")
+
+rkcp_tti = s:taboption("reverse",Value, "rkcp_tti", translate("KCP TTI"))
+rkcp_tti.datatype = "range(10,100)"
+rkcp_tti:depends("rnetwork_type", "kcp")
+
+rkcp_uplink = s:taboption("reverse",Value, "rkcp_uplink", translate("KCP uplinkCapacity"))
+rkcp_uplink.datatype = "range(0,1000)"
+rkcp_uplink:depends("rnetwork_type", "kcp")
+
+rkcp_downlink = s:taboption("reverse",Value, "rkcp_downlink", translate("KCP downlinkCapacity"))
+rkcp_downlink.datatype = "range(0,1000)"
+rkcp_downlink:depends("rnetwork_type", "kcp")
+
+rkcp_readbuf = s:taboption("reverse",Value, "rkcp_readbuf", translate("KCP readBufferSize"))
+rkcp_readbuf.datatype = "range(0,100)"
+rkcp_readbuf:depends("rnetwork_type", "kcp")
+
+rkcp_writebuf = s:taboption("reverse",Value, "rkcp_writebuf", translate("KCP writeBufferSize"))
+rkcp_writebuf.datatype = "range(0,100)"
+rkcp_writebuf:depends("rnetwork_type", "kcp")
+
+rkcp_congestion = s:taboption("reverse",Flag, "rkcp_congestion", translate("KCP Congestion"))
+rkcp_congestion:depends("rnetwork_type", "kcp")
+
+-- websocket settings
+rws_path = s:taboption("reverse",Value, "rws_path", translate("WebSocket Path"))
+rws_path:depends("rnetwork_type", "ws")
+
+rws_headers = s:taboption("reverse",Value, "rws_headers", translate("WebSocket Header"))
+rws_headers:depends("rnetwork_type", "ws")
+rws_headers.datatype = "host"
+
+-- http/2 settings
+rh2_path = s:taboption("reverse",Value, "rh2_path", translate("HTTP Path"))
+rh2_path:depends("rnetwork_type", "h2")
+
+rh2_domain = s:taboption("reverse",Value, "rh2_domain", translate("HTTP Domain"))
+rh2_domain:depends("rnetwork_type", "h2")
+rh2_domain.datatype = "host"
+
+-- others
+rtls = s:taboption("reverse",Flag, "rtls", translate("TLS"))
+rtls.rmempty = false
+
+rmux = s:taboption("reverse",Flag, "rmux", translate("Mux"))
+rmux.rmempty = false
+--------------------------------------------------
s:tab("list", translate("User-defined GFW-List"))
gfwlist = s:taboption("list", TextValue, "conf")
gfwlist.description = translate("
(!)Note: When the domain name is entered and will automatically merge with the online GFW-List. Please manually update the GFW-List list after applying.")
diff --git a/package/lean/luci-app-v2ray-pro/po/zh-cn/v2raypro.po b/package/lean/luci-app-v2ray-pro/po/zh-cn/v2raypro.po
old mode 100644
new mode 100755
index ee3ffb44f..12dd2dd39
--- a/package/lean/luci-app-v2ray-pro/po/zh-cn/v2raypro.po
+++ b/package/lean/luci-app-v2ray-pro/po/zh-cn/v2raypro.po
@@ -114,3 +114,9 @@ msgstr "文件已保存到"
msgid "No specify upload file."
msgstr "未指定上传文件"
+
+msgid "Severse Setting"
+msgstr "反向代理设置"
+
+msgid "Server domain"
+msgstr "反向代理域名"
diff --git a/package/lean/luci-app-v2ray-pro/root/etc/config/v2raypro b/package/lean/luci-app-v2ray-pro/root/etc/config/v2raypro
old mode 100644
new mode 100755
index 18dff0474..ab8c2468d
--- a/package/lean/luci-app-v2ray-pro/root/etc/config/v2raypro
+++ b/package/lean/luci-app-v2ray-pro/root/etc/config/v2raypro
@@ -9,10 +9,23 @@ config v2raypro 'v2raypro'
option id '00755892-0921-4433-bd92-04242abd92af'
option alterId '64'
option security 'aes-128-gcm'
- option network_type 'ws'
- option tls '1'
- option mux '1'
- option ws_path '/v2ray'
- option ws_headers 'www.baidu.com'
- option enabled '0'
+ option network_type 'tcp'
+ option tcp_obfs 'none'
+ option tls '0'
+ option mux '0'
+ option raddress '4.4.4.4'
+ option rport '455'
+ option ralterId '64'
+ option rsecurity 'none'
+ option rnetwork_type 'tcp'
+ option rtcp_obfs 'none'
+ option rtls '0'
+ option rmux '0'
+ option rid '00755892-0921-4433-bd92-04242abd92af'
+ option enabled '1'
+ option renable '1'
+ option rdomain 'abcd.com'
+ option renabled '0'
+ option risen '0'
+ option rserver_domain 'abc.com'
diff --git a/package/lean/luci-app-v2ray-pro/root/etc/v2ray/gen_config.lua b/package/lean/luci-app-v2ray-pro/root/etc/v2ray/gen_config.lua
old mode 100644
new mode 100755
index 409ed480f..ae65b30f6
--- a/package/lean/luci-app-v2ray-pro/root/etc/v2ray/gen_config.lua
+++ b/package/lean/luci-app-v2ray-pro/root/etc/v2ray/gen_config.lua
@@ -1,6 +1,10 @@
--[[
Auto generate config for Project V
Author: @libc0607
+ add reverse
+ use io write ,fix sequence(cjson.encode's sequence , reverse can't work )
+ @tqsi
+
]]--
local conf_path, json_path = ...
@@ -8,13 +12,14 @@ conf_path = conf_path or "v2raypro"
json_path = json_path or "/tmp/config.json"
local local_listen_port = 7070
-
local cjson = require "cjson.safe"
local ucursor = require "luci.model.uci".cursor()
local lip = require "luci.ip"
+
local v2ray_stream_mode = ucursor:get(conf_path, "v2raypro", "network_type") -- tcp/kcp/ws
+local v2ray_enReverse = ucursor:get(conf_path, "v2raypro", "risen")=="1" and true or false
function v2ray_get_conf_list(op)
local t = {}
for k, v in pairs(ucursor:get_list(conf_path, 'v2ray', op)) do
@@ -47,122 +52,232 @@ function get_ip_list_by_domain(domain)
return domain_list
end
-local v2ray = {
- log = {
- access = "",
- error = "",
- loglevel = "none"
- },
- inbound = {
- protocol = "dokodemo-door",
- port = local_listen_port,
- domainOverride = {"tls", "http"},
- address = "",
- settings = {
- network = "tcp,udp",
- timeout = 30,
- followRedirect = true
- },
- },
- outbound = {
- protocol = "vmess",
- settings = {
- vnext = {
- [1] = {
- address = ucursor:get(conf_path, "v2raypro", "address"),
- port = tonumber(ucursor:get(conf_path, "v2raypro", "port")),
- users = {
- [1] = {
- id = ucursor:get(conf_path, "v2raypro", "id"),
- alterId = tonumber(ucursor:get(conf_path, "v2raypro", "alterId")),
- security = ucursor:get(conf_path, "v2raypro", "security")
- },
- },
- },
- },
- },
- streamSettings = {
- network = ucursor:get(conf_path, "v2raypro", "network_type"),
- security = (ucursor:get(conf_path, "v2raypro", "tls") == '1') and "tls" or "none",
- tcpSettings = (v2ray_stream_mode == "tcp" and ucursor:get(conf_path, "v2raypro", "tcp_obfs") == "http") and {
- connectionReuse = true,
- header = {
- type = ucursor:get(conf_path, "v2raypro", "tcp_obfs"),
- request = {
- version = "1.1",
- method = "GET",
- path = v2ray_get_conf_list('tcp_path'),
- headers = {
- Host = v2ray_get_conf_list('tcp_host'),
- User_Agent = {
- "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.75 Safari/537.36",
- "Mozilla/5.0 (iPhone; CPU iPhone OS 10_0_2 like Mac OS X) AppleWebKit/601.1 (KHTML, like Gecko) CriOS/53.0.2785.109 Mobile/14A456 Safari/601.1.46"
- },
- Accept_Encoding = {"gzip, deflate"},
- Connection = {"keep-alive"},
- Pragma = "no-cache"
- },
- },
- response = {
- version = "1.1",
- status = "200",
- reason = "OK",
- headers = {
- Content_Type = {"application/octet-stream","video/mpeg"},
- Transfer_Encoding = {"chunked"},
- Connection= {"keep-alive"},
- Pragma = "no-cache"
- },
- },
- }
- } or nil,
-
- kcpSettings = (v2ray_stream_mode == "kcp") and {
- mtu = tonumber(ucursor:get(conf_path, "v2raypro", "kcp_mtu")),
- tti = tonumber(ucursor:get(conf_path, "v2raypro", "kcp_tti")),
- uplinkCapacity = tonumber(ucursor:get(conf_path, "v2raypro", "kcp_uplink")),
- downlinkCapacity = tonumber(ucursor:get(conf_path, "v2raypro", "kcp_downlink")),
- congestion = (ucursor:get(conf_path, "v2raypro", "kcp_congestion") == "1") and true or false,
- readBufferSize = tonumber(ucursor:get(conf_path, "v2raypro", "kcp_readbuf")),
- writeBufferSize = tonumber(ucursor:get(conf_path, "v2raypro", "kcp_writebuf")),
- header = {
- type = ucursor:get(conf_path, "v2raypro", "kcp_obfs")
- }
- } or nil,
-
- wsSettings = (v2ray_stream_mode == "ws") and {
- connectionReuse = true,
- path = ucursor:get(conf_path, "v2raypro", "ws_path"),
- headers = (ucursor:get(conf_path, "v2raypro", "ws_headers") ~= nil) and {
- Host = ucursor:get(conf_path, "v2raypro", "ws_headers")
- } or nil,
- } or nil,
-
- httpSettings = (v2ray_stream_mode == "h2") and {
- path = ucursor:get(conf_path, "v2raypro", "h2_path"),
- host = (ucursor:get(conf_path, "v2raypro", "h2_domain") ~= nil) and {
- ucursor:get(conf_path, "v2raypro", "h2_domain")
- } or nil,
- } or nil,
- },
- mux = {
- enabled = (ucursor:get(conf_path, "v2raypro", "mux") == "1") and true or false
- },
- },
- dns = {
- servers = {
- "localhost"
- },
- },
-}
-- Generate config json to
-local json_raw = cjson.encode(v2ray)
+
+
local json_file = io.open(json_path, "w+")
io.output(json_file)
-io.write(json_raw)
+io.write("{\"log\":{\"loglevel\":\"warning\",\"access\":\"\",\"error\":\"\"},\"dns\": {\"servers\": [\"localhost\"]},\"inbounds\":[{\"port\":7070,\"tag\": \"listen\",\"protocol\":\"dokodemo-door\",\"address\":\"\",\"settings\":{\"followRedirect\":true,\"network\":\"tcp,udp\",\"timeout\":50},\"domainOverride\":[\"tls\",\"http\"]}],")
+if v2ray_enReverse then --reverse set
+ io.write("\"reverse\": {\"bridges\": [{\"tag\": \"bridge\",\"domain\": \"")
+ io.write(ucursor:get(conf_path, "v2raypro", "rserver_domain"))
+ io.write("\"}]},")
+end
+
+--outbound
+v2ray_proxy={
+ tag = "proxy",
+ protocol = "vmess",
+ settings = {
+ vnext = {
+ [1] = {
+ address = ucursor:get(conf_path, "v2raypro", "address"),
+ port = tonumber(ucursor:get(conf_path, "v2raypro", "port")),
+ users = {
+ [1] = {
+ id = ucursor:get(conf_path, "v2raypro", "id"),
+ alterId = tonumber(ucursor:get(conf_path, "v2raypro", "alterId")),
+ security = ucursor:get(conf_path, "v2raypro", "security")
+ },
+ },
+ },
+ },
+ },
+ streamSettings = {
+ network = ucursor:get(conf_path, "v2raypro", "network_type"),
+ security = (ucursor:get(conf_path, "v2raypro", "tls") == '1') and "tls" or "none",
+ tcpSettings = (v2ray_stream_mode == "tcp" and ucursor:get(conf_path, "v2raypro", "tcp_obfs") == "http") and {
+ connectionReuse = true,
+ header = {
+ type = ucursor:get(conf_path, "v2raypro", "tcp_obfs"),
+ request = {
+ version = "1.1",
+ method = "GET",
+ path = v2ray_get_conf_list('tcp_path'),
+ headers = {
+ Host = v2ray_get_conf_list('tcp_host'),
+ User_Agent = {
+ "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.75 Safari/537.36",
+ "Mozilla/5.0 (iPhone; CPU iPhone OS 10_0_2 like Mac OS X) AppleWebKit/601.1 (KHTML, like Gecko) CriOS/53.0.2785.109 Mobile/14A456 Safari/601.1.46"
+ },
+ Accept_Encoding = {"gzip, deflate"},
+ Connection = {"keep-alive"},
+ Pragma = "no-cache"
+ },
+ },
+ response = {
+ version = "1.1",
+ status = "200",
+ reason = "OK",
+ headers = {
+ Content_Type = {"application/octet-stream","video/mpeg"},
+ Transfer_Encoding = {"chunked"},
+ Connection= {"keep-alive"},
+ Pragma = "no-cache"
+ },
+ },
+ }
+ } or nil,
+
+ kcpSettings = (v2ray_stream_mode == "kcp") and {
+ mtu = tonumber(ucursor:get(conf_path, "v2raypro", "kcp_mtu")),
+ tti = tonumber(ucursor:get(conf_path, "v2raypro", "kcp_tti")),
+ uplinkCapacity = tonumber(ucursor:get(conf_path, "v2raypro", "kcp_uplink")),
+ downlinkCapacity = tonumber(ucursor:get(conf_path, "v2raypro", "kcp_downlink")),
+ congestion = (ucursor:get(conf_path, "v2raypro", "kcp_congestion") == "1") and true or false,
+ readBufferSize = tonumber(ucursor:get(conf_path, "v2raypro", "kcp_readbuf")),
+ writeBufferSize = tonumber(ucursor:get(conf_path, "v2raypro", "kcp_writebuf")),
+ header = {
+ type = ucursor:get(conf_path, "v2raypro", "kcp_obfs")
+ }
+ } or nil,
+
+ wsSettings = (v2ray_stream_mode == "ws") and {
+ connectionReuse = true,
+ path = ucursor:get(conf_path, "v2raypro", "ws_path"),
+ headers = (ucursor:get(conf_path, "v2raypro", "ws_headers") ~= nil) and {
+ Host = ucursor:get(conf_path, "v2raypro", "ws_headers")
+ } or nil,
+ } or nil,
+
+ httpSettings = (v2ray_stream_mode == "h2") and {
+ path = ucursor:get(conf_path, "v2raypro", "h2_path"),
+ host = (ucursor:get(conf_path, "v2raypro", "h2_domain") ~= nil) and {
+ ucursor:get(conf_path, "v2raypro", "h2_domain")
+ } or nil,
+ } or nil,
+ },
+ mux = (v2ray_enReverse==false) and{
+ enabled = (ucursor:get(conf_path, "v2raypro", "mux") == "1") and true or false
+ } or nil,
+}
+
+
+
+
+io.write("\"outbounds\": [")
+
+
+
+if v2ray_enReverse then
+ local v2ray_stream_tunnel_mode = ucursor:get(conf_path, "v2raypro", "rnetwork_type") -- tcp/kcp/ws
+ local v2ray_tunnel= {
+ tag = "tunnel",
+ protocol = "vmess",
+ settings = {
+ vnext = {
+ [1] = {
+ address = ucursor:get(conf_path, "v2raypro", "raddress"),
+ port = tonumber(ucursor:get(conf_path, "v2raypro", "rport")),
+ users = {
+ [1] = {
+ id = ucursor:get(conf_path, "v2raypro", "rid"),
+ alterId = tonumber(ucursor:get(conf_path, "v2raypro", "ralterId")),
+ security = ucursor:get(conf_path, "v2raypro", "rsecurity")
+ },
+ },
+ },
+ },
+ },
+ streamSettings = {
+ network = ucursor:get(conf_path, "v2raypro", "rnetwork_type"),
+ security = (ucursor:get(conf_path, "v2raypro", "rtls") == '1') and "tls" or "none",
+ tcpSettings = (v2ray_stream_tunnel_mode == "tcp" and ucursor:get(conf_path, "v2raypro", "rtcp_obfs") == "http") and {
+ connectionReuse = true,
+ header = {
+ type = ucursor:get(conf_path, "v2raypro", "rtcp_obfs"),
+ request = {
+ version = "1.1",
+ method = "GET",
+ path = v2ray_get_conf_list('tcp_path'),
+ headers = {
+ Host = v2ray_get_conf_list('tcp_host'),
+ User_Agent = {
+ "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.75 Safari/537.36",
+ "Mozilla/5.0 (iPhone; CPU iPhone OS 10_0_2 like Mac OS X) AppleWebKit/601.1 (KHTML, like Gecko) CriOS/53.0.2785.109 Mobile/14A456 Safari/601.1.46"
+ },
+ Accept_Encoding = {"gzip, deflate"},
+ Connection = {"keep-alive"},
+ Pragma = "no-cache"
+ },
+ },
+ response = {
+ version = "1.1",
+ status = "200",
+ reason = "OK",
+ headers = {
+ Content_Type = {"application/octet-stream","video/mpeg"},
+ Transfer_Encoding = {"chunked"},
+ Connection= {"keep-alive"},
+ Pragma = "no-cache"
+ },
+ },
+ }
+ } or nil,
+
+ kcpSettings = (v2ray_stream_tunnel_mode == "kcp") and {
+ mtu = tonumber(ucursor:get(conf_path, "v2raypro", "rkcp_mtu")),
+ tti = tonumber(ucursor:get(conf_path, "v2raypro", "rkcp_tti")),
+ uplinkCapacity = tonumber(ucursor:get(conf_path, "v2raypro", "rkcp_uplink")),
+ downlinkCapacity = tonumber(ucursor:get(conf_path, "v2raypro", "rkcp_downlink")),
+ congestion = (ucursor:get(conf_path, "v2raypro", "rkcp_congestion") == "1") and true or false,
+ readBufferSize = tonumber(ucursor:get(conf_path, "v2raypro", "rkcp_readbuf")),
+ writeBufferSize = tonumber(ucursor:get(conf_path, "v2raypro", "rkcp_writebuf")),
+ header = {
+ type = ucursor:get(conf_path, "v2raypro", "rkcp_obfs")
+ }
+ } or nil,
+
+ wsSettings = (v2ray_stream_tunnel_mode == "ws") and {
+ connectionReuse = true,
+ path = ucursor:get(conf_path, "v2raypro", "rws_path"),
+ headers = (ucursor:get(conf_path, "v2raypro", "rws_headers") ~= nil) and {
+ Host = ucursor:get(conf_path, "v2raypro", "rws_headers")
+ } or nil,
+ } or nil,
+
+ httpSettings = (v2ray_stream_tunnel_mode == "h2") and {
+ path = ucursor:get(conf_path, "v2raypro", "rh2_path"),
+ host = (ucursor:get(conf_path, "v2raypro", "rh2_domain") ~= nil) and {
+ ucursor:get(conf_path, "v2raypro", "rh2_domain")
+ } or nil,
+ } or nil,
+ },
+ mux = (v2ray_enReverse==false) and{
+ enabled = (ucursor:get(conf_path, "v2raypro", "mux") == "1") and true or false
+ } or nil,
+ }
+
+ json_raw_t = cjson.encode(v2ray_tunnel)
+ io.write(json_raw_t..",")
+ io.write("{\"protocol\": \"freedom\",\"settings\": {},\"tag\": \"out\"},")
+
+end
+
+
+local json_raw = cjson.encode(v2ray_proxy)
+io.write(json_raw.."],")
+--io.write("]")
+
+
+io.write("\"routing\": {\"strategy\": \"rules\",\"settings\": {\"rules\": [")--routing set
+if v2ray_enReverse then
+ io.write("{\"type\": \"field\",\"inboundTag\": [\"bridge\"],\"domain\": [\"full:")
+ io.write(ucursor:get(conf_path, "v2raypro", "rserver_domain"))
+ io.write("\"],\"outboundTag\": \"tunnel\"},{\"type\": \"field\",\"inboundTag\": [\"bridge\"],\"outboundTag\": \"out\"},")
+end
+
+io.write("{\"domainStrategy\": \"IPIfNonMatch\",\"type\": \"field\",\"outboundTag\": \"proxy\",\"inboundTag\": [\"listen\"]}]}}")
+
+
+
+
+io.write("}")--end
io.close(json_file)
+
+
-- change '_' to '-'
local keys_including_minus = {"User_Agent", "Content_Type", "Accept_Encoding", "Transfer_Encoding"}
local keys_corrected = {"User-Agent", "Content-Type", "Accept-Encoding", "Transfer-Encoding"}