summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLoyalsoldier <[email protected]>2022-08-29 22:34:33 +0800
committerLoyalsoldier <[email protected]>2022-08-29 23:41:01 +0800
commitcd65e109bac7533ff7328688b45e8cd05e6fcc86 (patch)
tree56ffb4dfbc329e38d7b649b4ec07b67ad2a50ae8
parent703045963b6f293cc725d8a65de58661c55ee02c (diff)
Fix: add option overwriteList
Due to MaxMind mmdb file format constraint, the IPs and/or CIDRs of the latter written list will overwrite those of the former one when duplicated data is found. To make sure that the lists you added include all their own IPs and/or CIDRs, you must place the name of the most important list at last in option wantedList and option overwriteList of type maxmindMMDB in config file. The option overwriteList of type maxmindMMDB is used when the IPs and/or CIDRs of some lists in generated mmdb file overlap. For example, if you change the CIDRs of the list "cn", and generate the full version of Country.mmdb file which is with all countries(lists), the option overwriteList must include "cn", so that the "cn" list will be written at last, which ensures it includes all the CIDRs you specify. If the option wantedList of type maxmindMMDB is specified, no need for option overwriteList.
-rw-r--r--README.md6
-rw-r--r--config-example.json8
-rw-r--r--config.json14
-rw-r--r--plugin/maxmind/mmdb.go85
4 files changed, 85 insertions, 28 deletions
diff --git a/README.md b/README.md
index 795cde93..0b54cc06 100644
--- a/README.md
+++ b/README.md
@@ -167,6 +167,12 @@ These two concepts are notable: `input` and `output`. The `input` is the data so
- **clashRuleSet**:[ipcidr 类型的 Clash RuleSet](https://github.com/Dreamacro/clash/wiki/premium-core-features#ipcidr)
- **surgeRuleSet**:[Surge RuleSet](https://manual.nssurge.com/rule/ruleset.html)
+### 注意事项
+
+由于 MaxMind mmdb 文件格式的限制,当不同列表的 IP 或 CIDR 数据有交集或重复项时,后写入的列表的 IP 或 CIDR 数据会覆盖(overwrite)之前已写入的列表的数据。譬如,IP `1.1.1.1` 同属于列表 `AU` 和列表 `Cloudflare`。如果 `Cloudflare` 在 `AU` 之后写入,则 IP `1.1.1.1` 归属于列表 `Cloudflare`。
+
+为了确保某些指定的列表、被修改的列表一定囊括属于它的所有 IP 或 CIDR 数据,可在 `output` 输出格式为 `maxmindMMDB` 的配置中增加选项 `overwriteList`,该选项中指定的列表会在最后逐一写入,列表中最后一项优先级最高。若已设置选项 `wantedList`,则无需设置 `overwriteList`。`wantedList` 中指定的列表会在最后逐一写入,列表中最后一项优先级最高。
+
## CLI 功能展示
可通过 `go install -v github.com/Loyalsoldier/geoip@latest` 直接安装 CLI。
diff --git a/config-example.json b/config-example.json
index f2a1363b..0396feae 100644
--- a/config-example.json
+++ b/config-example.json
@@ -113,6 +113,14 @@
"type": "maxmindMMDB",
"action": "output",
"args": {
+ "outputName": "Country.mmdb",
+ "overwriteList": ["cn", "private"]
+ }
+ },
+ {
+ "type": "maxmindMMDB",
+ "action": "output",
+ "args": {
"outputName": "country-only-cn-private.mmdb",
"wantedList": ["cn", "private"]
}
diff --git a/config.json b/config.json
index 860a80c8..68bff450 100644
--- a/config.json
+++ b/config.json
@@ -83,7 +83,19 @@
"type": "maxmindMMDB",
"action": "output",
"args": {
- "outputName": "Country.mmdb"
+ "outputName": "Country.mmdb",
+ "overwriteList": [
+ "cn",
+ "private",
+ "cloudflare",
+ "cloudfront",
+ "facebook",
+ "fastly",
+ "google",
+ "netflix",
+ "telegram",
+ "twitter"
+ ]
}
},
{
diff --git a/plugin/maxmind/mmdb.go b/plugin/maxmind/mmdb.go
index 4e0ec242..26440101 100644
--- a/plugin/maxmind/mmdb.go
+++ b/plugin/maxmind/mmdb.go
@@ -38,6 +38,7 @@ func newMMDB(action lib.Action, data json.RawMessage) (lib.OutputConverter, erro
OutputName string `json:"outputName"`
OutputDir string `json:"outputDir"`
Want []string `json:"wantedList"`
+ Overwrite []string `json:"overwriteList"`
OnlyIPType lib.IPType `json:"onlyIPType"`
}
@@ -62,6 +63,7 @@ func newMMDB(action lib.Action, data json.RawMessage) (lib.OutputConverter, erro
OutputName: tmp.OutputName,
OutputDir: tmp.OutputDir,
Want: tmp.Want,
+ Overwrite: tmp.Overwrite,
OnlyIPType: tmp.OnlyIPType,
}, nil
}
@@ -73,6 +75,7 @@ type mmdb struct {
OutputName string
OutputDir string
Want []string
+ Overwrite []string
OnlyIPType lib.IPType
}
@@ -89,14 +92,6 @@ func (m *mmdb) GetDescription() string {
}
func (m *mmdb) Output(container lib.Container) error {
- // Filter want list
- wantList := make(map[string]bool)
- for _, want := range m.Want {
- if want = strings.ToUpper(strings.TrimSpace(want)); want != "" {
- wantList[want] = true
- }
- }
-
writer, err := mmdbwriter.New(
mmdbwriter.Options{
DatabaseType: "GeoLite2-Country",
@@ -110,27 +105,16 @@ func (m *mmdb) Output(container lib.Container) error {
}
updated := false
- switch len(wantList) {
- case 0:
- for entry := range container.Loop() {
- if err := m.marshalData(writer, entry); err != nil {
- return err
- }
- updated = true
+ for _, name := range m.getEntryNameListInOrder(container) {
+ entry, found := container.GetEntry(name)
+ if !found {
+ log.Printf("❌ entry %s not found", name)
+ continue
}
-
- default:
- for name := range wantList {
- entry, found := container.GetEntry(name)
- if !found {
- log.Printf("❌ entry %s not found", name)
- continue
- }
- if err := m.marshalData(writer, entry); err != nil {
- return err
- }
- updated = true
+ if err := m.marshalData(writer, entry); err != nil {
+ return err
}
+ updated = true
}
if updated {
@@ -144,6 +128,53 @@ func (m *mmdb) Output(container lib.Container) error {
return nil
}
+func (m *mmdb) getEntryNameListInOrder(container lib.Container) []string {
+ /*
+ Note: The IPs and/or CIDRs of the latter list will overwrite those of the former one
+ when duplicated data found due to MaxMind mmdb file format constraint.
+
+ Be sure to place the name of the most important list at last
+ when writing wantedList and overwriteList in config file.
+
+ The order of names in wantedList has a higher priority than which of the overwriteList.
+ */
+
+ wantList := make([]string, 0, 200)
+ for _, want := range m.Want {
+ if want = strings.ToUpper(strings.TrimSpace(want)); want != "" {
+ wantList = append(wantList, want)
+ }
+ }
+
+ if len(wantList) > 0 {
+ return wantList
+ }
+
+ overwriteList := make([]string, 0, 200)
+ overwriteMap := make(map[string]bool)
+ for _, overwrite := range m.Overwrite {
+ if overwrite = strings.ToUpper(strings.TrimSpace(overwrite)); overwrite != "" {
+ overwriteList = append(overwriteList, overwrite)
+ overwriteMap[overwrite] = true
+ }
+ }
+
+ list := make([]string, 0, 200)
+ for entry := range container.Loop() {
+ name := entry.GetName()
+ _, found := overwriteMap[name]
+ if found {
+ continue
+ }
+ list = append(list, name)
+ }
+
+ // Make sure the names in overwriteList are written at last
+ list = append(list, overwriteList...)
+
+ return list
+}
+
func (m *mmdb) marshalData(writer *mmdbwriter.Tree, entry *lib.Entry) error {
var entryCidr []string
var err error