mirror of
https://github.com/Qv2ray/Qv2ray.git
synced 2025-05-20 19:00:22 +08:00
[merge] merged branch patch-keep-extra-outbounds #25
Signed-off-by: Leroy.H.Y <lhy20010403@hotmail.com>
This commit is contained in:
commit
b0581f037a
@ -18,6 +18,14 @@
|
|||||||
#define QV2RAY_VCORE_ACCESS_LOG_FILENAME "access.log"
|
#define QV2RAY_VCORE_ACCESS_LOG_FILENAME "access.log"
|
||||||
#define QV2RAY_VCORE_ERROR_LOG_FILENAME "error.log"
|
#define QV2RAY_VCORE_ERROR_LOG_FILENAME "error.log"
|
||||||
|
|
||||||
|
// These is for early-2.0 version, final 2.0 will move these content into global config.
|
||||||
|
#define QV2RAY_CONFIG_TYPE_FILE "File"
|
||||||
|
#define QV2RAY_CONFIG_TYPE_MANUAL "Manual"
|
||||||
|
#define QV2RAY_CONFIG_TYPE_CONNECTIONSTRING "ConnectionString"
|
||||||
|
#define QV2RAY_CONFIG_TYPE_SUBSCRIPTION "Subscription"
|
||||||
|
#define QV2RAY_CONFIG_TYPE_JSON_KEY "_qv2ray.configSource"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// GUI TOOLS
|
// GUI TOOLS
|
||||||
#define RED(obj) \
|
#define RED(obj) \
|
||||||
|
@ -66,6 +66,7 @@ namespace Qv2ray
|
|||||||
outbounds.append(outbound);
|
outbounds.append(outbound);
|
||||||
root.insert("outbounds", outbounds);
|
root.insert("outbounds", outbounds);
|
||||||
root.insert("QV2RAY_ALIAS", QString::fromStdString(vmessConf.ps));
|
root.insert("QV2RAY_ALIAS", QString::fromStdString(vmessConf.ps));
|
||||||
|
root.insert(QV2RAY_CONFIG_TYPE_JSON_KEY, QV2RAY_CONFIG_TYPE_CONNECTIONSTRING);
|
||||||
RROOT
|
RROOT
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,30 +78,11 @@ namespace Qv2ray
|
|||||||
JSON_ROOT_TRY_REMOVE("inbounds")
|
JSON_ROOT_TRY_REMOVE("inbounds")
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
JSON_ROOT_TRY_REMOVE("log")
|
JSON_ROOT_TRY_REMOVE("log")
|
||||||
JSON_ROOT_TRY_REMOVE("api")
|
JSON_ROOT_TRY_REMOVE("api")
|
||||||
JSON_ROOT_TRY_REMOVE("stats")
|
JSON_ROOT_TRY_REMOVE("stats")
|
||||||
JSON_ROOT_TRY_REMOVE("policy")
|
|
||||||
JSON_ROOT_TRY_REMOVE("dns")
|
JSON_ROOT_TRY_REMOVE("dns")
|
||||||
JSON_ROOT_TRY_REMOVE("routing")
|
root.insert(QV2RAY_CONFIG_TYPE_JSON_KEY, QV2RAY_CONFIG_TYPE_FILE);
|
||||||
QJsonArray outbounds;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Currently, we only support VMess (And ShadowSocks now). So remove all other types of outbounds.
|
|
||||||
for (int i = root["outbounds"].toArray().count(); i >= 0 ; i--) {
|
|
||||||
auto isVMess = root["outbounds"].toArray()[i].toObject()["protocol"].toString() == "vmess";
|
|
||||||
auto isSS = root["outbounds"].toArray()[i].toObject()["protocol"].toString() == "shadowsocks";
|
|
||||||
|
|
||||||
if (isVMess || isSS) {
|
|
||||||
auto conn = root["outbounds"].toArray()[i].toObject();
|
|
||||||
conn.insert("tag", OUTBOUND_TAG_PROXY);
|
|
||||||
outbounds.append(conn);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
JSON_ROOT_TRY_REMOVE("outbounds")
|
|
||||||
root.insert("outbounds", outbounds);
|
|
||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,9 +166,16 @@ namespace Qv2ray
|
|||||||
|
|
||||||
auto dnsObject = GenerateDNS(gConf.withLocalDNS, dnsList);
|
auto dnsObject = GenerateDNS(gConf.withLocalDNS, dnsList);
|
||||||
root.insert("dns", dnsObject);
|
root.insert("dns", dnsObject);
|
||||||
|
|
||||||
//
|
//
|
||||||
|
// This is for imported config files as there are routing entries already.
|
||||||
|
// We don't add extra routings.
|
||||||
|
// We don't use QV2RAY_CONFIG_TYPE_FILE checking scheme because not all connections have this part.
|
||||||
|
if (!root.contains("routing")) {
|
||||||
auto routeObject = GenerateRoutes(gConf.proxyDefault, gConf.proxyCN);
|
auto routeObject = GenerateRoutes(gConf.proxyDefault, gConf.proxyCN);
|
||||||
root.insert("routing", routeObject);
|
root.insert("routing", routeObject);
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
root.insert("stats", QJsonObject());
|
root.insert("stats", QJsonObject());
|
||||||
@ -178,20 +185,16 @@ namespace Qv2ray
|
|||||||
root.insert("inbounds", QJsonArray());
|
root.insert("inbounds", QJsonArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// This is configured as a global option...
|
|
||||||
auto conf = GetGlobalConfig();
|
|
||||||
|
|
||||||
// HTTP InBound
|
// HTTP InBound
|
||||||
if (conf.inBoundSettings.http_port != 0) {
|
if (gConf.inBoundSettings.http_port != 0) {
|
||||||
QJsonObject httpInBoundObject;
|
QJsonObject httpInBoundObject;
|
||||||
httpInBoundObject.insert("listen", QString::fromStdString(conf.inBoundSettings.listenip));
|
httpInBoundObject.insert("listen", QString::fromStdString(gConf.inBoundSettings.listenip));
|
||||||
httpInBoundObject.insert("port", conf.inBoundSettings.http_port);
|
httpInBoundObject.insert("port", gConf.inBoundSettings.http_port);
|
||||||
httpInBoundObject.insert("protocol", "http");
|
httpInBoundObject.insert("protocol", "http");
|
||||||
httpInBoundObject.insert("tag", "http_IN");
|
httpInBoundObject.insert("tag", "http_IN");
|
||||||
|
|
||||||
if (conf.inBoundSettings.http_useAuth) {
|
if (gConf.inBoundSettings.http_useAuth) {
|
||||||
auto httpInSettings = GenerateHTTPIN(QList<AccountObject>() << conf.inBoundSettings.httpAccount);
|
auto httpInSettings = GenerateHTTPIN(QList<AccountObject>() << gConf.inBoundSettings.httpAccount);
|
||||||
httpInBoundObject.insert("settings", httpInSettings);
|
httpInBoundObject.insert("settings", httpInSettings);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,24 +202,32 @@ namespace Qv2ray
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SOCKS InBound
|
// SOCKS InBound
|
||||||
if (conf.inBoundSettings.socks_port != 0) {
|
if (gConf.inBoundSettings.socks_port != 0) {
|
||||||
QJsonObject socksInBoundObject;
|
QJsonObject socksInBoundObject;
|
||||||
socksInBoundObject.insert("listen", QString::fromStdString(conf.inBoundSettings.listenip));
|
socksInBoundObject.insert("listen", QString::fromStdString(gConf.inBoundSettings.listenip));
|
||||||
socksInBoundObject.insert("port", conf.inBoundSettings.socks_port);
|
socksInBoundObject.insert("port", gConf.inBoundSettings.socks_port);
|
||||||
socksInBoundObject.insert("protocol", "socks");
|
socksInBoundObject.insert("protocol", "socks");
|
||||||
socksInBoundObject.insert("tag", "socks_IN");
|
socksInBoundObject.insert("tag", "socks_IN");
|
||||||
auto socksInSettings = GenerateSocksIN(conf.inBoundSettings.socks_useAuth ? "password" : "noauth", QList<AccountObject>() << conf.inBoundSettings.socksAccount);
|
auto socksInSettings = GenerateSocksIN(gConf.inBoundSettings.socks_useAuth ? "password" : "noauth", QList<AccountObject>() << gConf.inBoundSettings.socksAccount);
|
||||||
socksInBoundObject.insert("settings", socksInSettings);
|
socksInBoundObject.insert("settings", socksInSettings);
|
||||||
root["inbounds"].toArray().append(socksInBoundObject);
|
root["inbounds"].toArray().append(socksInBoundObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: MultiOutbound Settings
|
||||||
|
if (root.contains(QV2RAY_CONFIG_TYPE_JSON_KEY) && root[QV2RAY_CONFIG_TYPE_JSON_KEY] == QV2RAY_CONFIG_TYPE_FILE) {
|
||||||
|
LOG(MODULE_CONFIG, "Found an imported config file, skipping adding 'freedom' outbound.")
|
||||||
|
// Do nothing because it's an imported connection.
|
||||||
|
} else {
|
||||||
QJsonArray outbounds = root["outbounds"].toArray();
|
QJsonArray outbounds = root["outbounds"].toArray();
|
||||||
|
// It's not imported so we add new stuff.
|
||||||
// For DIRECT
|
// For DIRECT
|
||||||
outbounds.append(GenerateOutboundEntry("freedom", GenerateFreedomOUT("AsIs", ":0", 0), QJsonObject(), QJsonObject(), "0.0.0.0", OUTBOUND_TAG_DIRECT));
|
outbounds.append(GenerateOutboundEntry("freedom", GenerateFreedomOUT("AsIs", ":0", 0), QJsonObject(), QJsonObject(), "0.0.0.0", OUTBOUND_TAG_DIRECT));
|
||||||
QJsonObject first = outbounds.first().toObject();
|
QJsonObject first = outbounds.first().toObject();
|
||||||
first.insert("mux", GetRootObject(gConf.mux));
|
first.insert("mux", GetRootObject(gConf.mux));
|
||||||
outbounds[0] = first;
|
outbounds[0] = first;
|
||||||
root["outbounds"] = outbounds;
|
root["outbounds"] = outbounds;
|
||||||
|
}
|
||||||
|
|
||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,7 @@ ConnectionEditWindow::ConnectionEditWindow(QWidget *parent)
|
|||||||
vmess = VMessServerObject();
|
vmess = VMessServerObject();
|
||||||
vmess.users.push_back(VMessServerObject::UserObject());
|
vmess.users.push_back(VMessServerObject::UserObject());
|
||||||
stream = StreamSettingsObject();
|
stream = StreamSettingsObject();
|
||||||
|
OutboundType = "vmess";
|
||||||
ReLoad_GUI_JSON_ModelContent();
|
ReLoad_GUI_JSON_ModelContent();
|
||||||
GEN_JSON
|
GEN_JSON
|
||||||
}
|
}
|
||||||
@ -142,8 +143,8 @@ void ConnectionEditWindow::ReLoad_GUI_JSON_ModelContent()
|
|||||||
|
|
||||||
void ConnectionEditWindow::on_buttonBox_accepted()
|
void ConnectionEditWindow::on_buttonBox_accepted()
|
||||||
{
|
{
|
||||||
bool new_config = _alias == "";
|
bool is_new_config = _alias == "";
|
||||||
auto alias = new_config ? (ui->ipLineEdit->text() + "_" + ui->portLineEdit->text()) : _alias;
|
auto alias = is_new_config ? (ui->ipLineEdit->text() + "_" + ui->portLineEdit->text()) : _alias;
|
||||||
//
|
//
|
||||||
auto outbound = GenerateConnectionJson();
|
auto outbound = GenerateConnectionJson();
|
||||||
QJsonArray outbounds;
|
QJsonArray outbounds;
|
||||||
@ -155,16 +156,17 @@ void ConnectionEditWindow::on_buttonBox_accepted()
|
|||||||
}
|
}
|
||||||
|
|
||||||
originalRoot.insert("outbounds", outbounds);
|
originalRoot.insert("outbounds", outbounds);
|
||||||
|
originalRoot.insert(QV2RAY_CONFIG_TYPE_JSON_KEY, QV2RAY_CONFIG_TYPE_MANUAL);
|
||||||
SaveConnectionConfig(originalRoot, &alias);
|
SaveConnectionConfig(originalRoot, &alias);
|
||||||
auto globalConf = GetGlobalConfig();
|
auto globalConf = GetGlobalConfig();
|
||||||
|
|
||||||
if (new_config) {
|
if (is_new_config) {
|
||||||
// New config...
|
// New config...
|
||||||
globalConf.configs.push_back(alias.toStdString());
|
globalConf.configs.push_back(alias.toStdString());
|
||||||
}
|
}
|
||||||
|
|
||||||
SetGlobalConfig(globalConf);
|
SetGlobalConfig(globalConf);
|
||||||
emit s_reload_config(!new_config);
|
emit s_reload_config(!is_new_config);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConnectionEditWindow::on_ipLineEdit_textEdited(const QString &arg1)
|
void ConnectionEditWindow::on_ipLineEdit_textEdited(const QString &arg1)
|
||||||
|
@ -59,6 +59,7 @@ void ImportConfigWindow::on_buttonBox_accepted()
|
|||||||
int result = VerifyVMessProtocolString(vmess);
|
int result = VerifyVMessProtocolString(vmess);
|
||||||
|
|
||||||
if (result == 0) {
|
if (result == 0) {
|
||||||
|
// This result code passes the validation check.
|
||||||
//QvMessageBox(this, tr("#VMessCheck"), tr("#AbleToImportConfig"));
|
//QvMessageBox(this, tr("#VMessCheck"), tr("#AbleToImportConfig"));
|
||||||
} else if (result == -1) {
|
} else if (result == -1) {
|
||||||
QvMessageBox(this, tr("#VMessCheck"), tr("#NotValidVMessProtocolString"));
|
QvMessageBox(this, tr("#VMessCheck"), tr("#NotValidVMessProtocolString"));
|
||||||
|
185
test.conf.json
185
test.conf.json
@ -1,185 +0,0 @@
|
|||||||
{
|
|
||||||
"dns": {
|
|
||||||
"servers": [
|
|
||||||
"8.8.8.8",
|
|
||||||
"8.8.4.4",
|
|
||||||
"localhost"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"inbounds": [
|
|
||||||
{
|
|
||||||
"listen": "0.0.0.0",
|
|
||||||
"port": 60080,
|
|
||||||
"protocol": "dokodemo-door",
|
|
||||||
"settings": {
|
|
||||||
"followRedirect": true,
|
|
||||||
"network": "tcp,udp"
|
|
||||||
},
|
|
||||||
"streamSettings": {
|
|
||||||
"sockopt": {
|
|
||||||
"tproxy": "tproxy"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"listen": "127.0.0.1",
|
|
||||||
"port": 1081,
|
|
||||||
"protocol": "socks",
|
|
||||||
"settings": {
|
|
||||||
"auth": "noauth",
|
|
||||||
"ip": "127.0.0.1",
|
|
||||||
"udp": true
|
|
||||||
},
|
|
||||||
"tag": "socks-in"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"listen": "127.0.0.1",
|
|
||||||
"port": 6666,
|
|
||||||
"protocol": "http",
|
|
||||||
"settings": {
|
|
||||||
"auth": "noauth",
|
|
||||||
"ip": "127.0.0.1",
|
|
||||||
"udp": true
|
|
||||||
},
|
|
||||||
"tag": "http-in"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"log": {
|
|
||||||
"error": "",
|
|
||||||
"loglevel": ""
|
|
||||||
},
|
|
||||||
"outbounds": [
|
|
||||||
{
|
|
||||||
"mux": {
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
"protocol": "vmess",
|
|
||||||
"settings": {
|
|
||||||
"vnext": [
|
|
||||||
{
|
|
||||||
"address": "addreess1.com",
|
|
||||||
"port": 443,
|
|
||||||
"users": [
|
|
||||||
{
|
|
||||||
"alterId": 233,
|
|
||||||
"id": "askdsakldlskdmsadml",
|
|
||||||
"security": "auto"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"streamSettings": {
|
|
||||||
"headers": null,
|
|
||||||
"network": "ws",
|
|
||||||
"security": "tls",
|
|
||||||
"tlsSettings": {
|
|
||||||
"allowInsecure": true,
|
|
||||||
"serverName": null
|
|
||||||
},
|
|
||||||
"wsSettings": {
|
|
||||||
"path": "/admin"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"tag": "route1"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"protocol": "freedom",
|
|
||||||
"settings": {},
|
|
||||||
"tag": "direct"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"mux": {
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
"protocol": "vmess",
|
|
||||||
"settings": {
|
|
||||||
"vnext": [
|
|
||||||
{
|
|
||||||
"address": "addreess2.com",
|
|
||||||
"port": 443,
|
|
||||||
"users": [
|
|
||||||
{
|
|
||||||
"alterId": 233,
|
|
||||||
"id": "asdsadasdsadadsa",
|
|
||||||
"security": "auto"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"streamSettings": {
|
|
||||||
"headers": null,
|
|
||||||
"network": "ws",
|
|
||||||
"security": "tls",
|
|
||||||
"tlsSettings": {
|
|
||||||
"allowInsecure": true,
|
|
||||||
"serverName": null
|
|
||||||
},
|
|
||||||
"wsSettings": {
|
|
||||||
"path": "/admin"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"tag": "route2"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"mux": {
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
"protocol": "vmess",
|
|
||||||
"settings": {
|
|
||||||
"vnext": [
|
|
||||||
{
|
|
||||||
"address": "addreess3.com",
|
|
||||||
"port": 33333,
|
|
||||||
"users": [
|
|
||||||
{
|
|
||||||
"alterId": 2,
|
|
||||||
"id": "asddadadadasd",
|
|
||||||
"security": "chacha20-poly1305"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"tag": "route3"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"protocol": "socks",
|
|
||||||
"settings": {
|
|
||||||
"servers": [
|
|
||||||
{
|
|
||||||
"address": "127.0.0.1",
|
|
||||||
"port": 1082
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"tag": "sock"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"routing": {
|
|
||||||
"domainStrategy": "IPOnDemand",
|
|
||||||
"rules": [
|
|
||||||
{
|
|
||||||
"domain": [
|
|
||||||
"youtube.com",
|
|
||||||
"googlevideo.com",
|
|
||||||
"googleusercontent.com",
|
|
||||||
"gstatic.com",
|
|
||||||
"download.ok.is"
|
|
||||||
],
|
|
||||||
"network": "tcp,udp",
|
|
||||||
"outboundTag": "route1",
|
|
||||||
"type": "field"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ip": [
|
|
||||||
"172.65.128.0/24"
|
|
||||||
],
|
|
||||||
"network": "tcp,udp",
|
|
||||||
"outboundTag": "route2",
|
|
||||||
"type": "field"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user