Enhancements

Rework generation of sing-box rules.
Add a dns outbound to sing-box configs.
This commit is contained in:
Tindy X
2023-11-11 18:24:14 +08:00
parent d08426a53e
commit 4e94a986b4
5 changed files with 67 additions and 8 deletions

View File

@@ -7,7 +7,7 @@ INCLUDE_DIRECTORIES("${CMAKE_SOURCE_DIR}/include/")
IF(NOT CMAKE_BUILD_TYPE)
SET(CMAKE_BUILD_TYPE Release)
ENDIF()
SET(CMAKE_CXX_STANDARD 17)
SET(CMAKE_CXX_STANDARD 20)
IF(NOT MSVC)
ADD_COMPILE_OPTIONS(-Wall -Wextra -Wno-unused-parameter -Wno-unused-result)

View File

@@ -481,6 +481,22 @@ static rapidjson::Value transformRuleToSingBox(const std::string& rule, const st
return rule_obj;
}
static void appendSingBoxRule(rapidjson::Value &rules, const std::string& rule, rapidjson::MemoryPoolAllocator<>& allocator)
{
using namespace rapidjson_ext;
auto args = split(rule, ",");
if (args.size() < 2) return;
auto type = toLower(std::string(args[0]));
auto value = toLower(args[1]);
// std::string_view option;
// if (args.size() >= 3) option = args[2];
type = replaceAllDistinct(type, "-", "_");
type = replaceAllDistinct(type, "ip_cidr6", "ip_cidr");
rules | AppendToArray(type.c_str(), rapidjson::Value(value.c_str(), allocator), allocator);
}
void rulesetToSingBox(rapidjson::Document &base_rule, std::vector<RulesetContent> &ruleset_content_array, bool overwrite_original_rules)
{
using namespace rapidjson_ext;
@@ -504,6 +520,9 @@ void rulesetToSingBox(rapidjson::Document &base_rule, std::vector<RulesetContent
rules.PushBack(direct_object, allocator);
}
auto dns_object = buildObject(allocator, "protocol", "dns", "outbound", "dns-out");
rules.PushBack(dns_object, allocator);
for(RulesetContent &x : ruleset_content_array)
{
if(global.maxAllowedRules && total_rules > global.maxAllowedRules)
@@ -532,7 +551,10 @@ void rulesetToSingBox(rapidjson::Document &base_rule, std::vector<RulesetContent
strStrm.clear();
strStrm<<retrieved_rules;
std::string::size_type lineSize;
rapidjson::Value rule(rapidjson::kObjectType);
while(getline(strStrm, strLine, delimiter))
{
if(global.maxAllowedRules && total_rules > global.maxAllowedRules)
@@ -548,8 +570,11 @@ void rulesetToSingBox(rapidjson::Document &base_rule, std::vector<RulesetContent
strLine.erase(strLine.find("//"));
strLine = trimWhitespace(strLine);
}
rules.PushBack(transformRuleToSingBox(strLine, rule_group, allocator), allocator);
appendSingBoxRule(rule, strLine, allocator);
}
if (rule.ObjectEmpty()) continue;
rule.AddMember("outbound", rapidjson::Value(rule_group.c_str(), allocator), allocator);
rules.PushBack(rule, allocator);
}
if (!base_rule.HasMember("route"))

View File

@@ -2097,6 +2097,8 @@ void proxyToSingBox(std::vector<Proxy> &nodes, rapidjson::Document &json, std::v
outbounds.PushBack(direct, allocator);
auto reject = buildObject(allocator, "type", "block", "tag", "REJECT");
outbounds.PushBack(reject, allocator);
auto dns = buildObject(allocator, "type", "dns", "tag", "dns-out");
outbounds.PushBack(dns, allocator);
for (Proxy &x : nodes)
{

View File

@@ -447,7 +447,6 @@ int script_context_init(qjs::Context &context)
.fun<&qjs_fetch_Headers::parse_from_string>("parse");
module.class_<qjs_fetch_Request>("Request")
.constructor<>()
.constructor<const std::string&>("Request")
.fun<&qjs_fetch_Request::method>("method")
.fun<&qjs_fetch_Request::url>("url")
.fun<&qjs_fetch_Request::proxy>("proxy")

View File

@@ -96,20 +96,53 @@ namespace rapidjson_ext {
};
struct AddMemberOrReplace : public ExtensionFunction<rapidjson::Value &> {
rapidjson::Value &member;
rapidjson::Value &value;
const rapidjson::Value::Ch *name;
rapidjson::MemoryPoolAllocator<> &allocator;
AddMemberOrReplace(const rapidjson::Value::Ch *name, rapidjson::Value &value,
rapidjson::MemoryPoolAllocator<> &allocator) : member(value), name(name), allocator(allocator) {}
rapidjson::MemoryPoolAllocator<> &allocator) : value(value), name(name), allocator(allocator) {}
AddMemberOrReplace(const rapidjson::Value::Ch *name, rapidjson::Value &&value,
rapidjson::MemoryPoolAllocator<> &allocator) : member(value), name(name), allocator(allocator) {}
rapidjson::MemoryPoolAllocator<> &allocator) : value(value), name(name), allocator(allocator) {}
inline rapidjson::Value & operator() (rapidjson::Value &root) const override
{
if (root.HasMember(name))
root[name] = member;
root[name] = value;
else
root.AddMember(rapidjson::StringRef(name), member, allocator);
root.AddMember(rapidjson::Value(name, allocator), value, allocator);
return root;
}
};
struct AppendToArray : public ExtensionFunction<rapidjson::Value &>
{
rapidjson::Value &value;
const rapidjson::Value::Ch *name;
rapidjson::MemoryPoolAllocator<> &allocator;
AppendToArray(const rapidjson::Value::Ch *name, rapidjson::Value &value,
rapidjson::MemoryPoolAllocator<> &allocator): value(value), name(name), allocator(allocator) {}
AppendToArray(const rapidjson::Value::Ch *name, rapidjson::Value &&value,
rapidjson::MemoryPoolAllocator<> &allocator): value(value), name(name), allocator(allocator) {}
inline rapidjson::Value &operator()(rapidjson::Value &root) const override
{
if (root.HasMember(name))
{
if (root[name].IsArray())
{
root[name].PushBack(value, allocator);
}
else
{
root[name] = rapidjson::Value(rapidjson::kArrayType).PushBack(value, allocator);
}
}
else
{
root.AddMember(rapidjson::Value(name, allocator), rapidjson::Value(rapidjson::kArrayType).PushBack(value, allocator), allocator);
}
return root;
}
};