Advanced Configurations for InputConverter and OutputConverter in the geoip Tool

The geoip tool supports advanced configuration options including wantedList filtering, onlyIPType IP version restriction, inputDir batch processing, jsonPath extraction, overwriteList conflict resolution, and sourceMMDBURI metadata enrichment.

The loyalsoldier/geoip repository implements a plugin-based architecture that separates data ingestion from export formatting. By leveraging advanced InputConverter and OutputConverter configurations, you can control exactly how IP ranges are parsed, filtered, and written to final artifacts. These options enable precise management of overlapping CIDR ranges and support complex CI/CD workflows.

Architectural Overview

The core engine in lib/converter.go defines two fundamental interfaces that drive the entire data flow:

  • InputConverter – Parses raw data sources (JSON, plain-text, MaxMind CSV) and inserts extracted IP/CIDR entries into an internal container
  • OutputConverter – Traverses the container and writes stored entries to target formats (Clash rules, MMDB databases, text files)

Each plugin self-registers via RegisterInputConverter or RegisterOutputConverter functions during initialization. The configuration processor in lib/config.go unmarshals JSON settings into ConfigItem structures, then dispatches to the appropriate factory functions based on the type field.

Advanced InputConverter Options

Input converters support granular control over data ingestion through the args map in your configuration JSON.

Filtering by Category and IP Version

The wantedList array restricts processing to specific category names, while onlyIPType (ipv4 or ipv6) filters entries by IP protocol version.

{
  "type": "text",
  "action": "add",
  "args": {
    "uri": "https://example.com/ips.txt",
    "wantedList": ["cn", "us"],
    "onlyIPType": "ipv4"
  }
}

Batch Directory Processing

When inputDir is specified instead of uri, the converter scans the directory non-recursively and treats each filename as a category name. Combined with wantedList, this enables batch processing of entire rule-set folders without individual configuration entries.

In plugin/plaintext/text_in.go, this logic processes each file in the directory:

{
  "type": "text",
  "action": "add",
  "args": {
    "inputDir": "./rulesets",
    "wantedList": ["cn", "us", "private"]
  }
}

Data Extraction and Transformation

For complex JSON payloads, the jsonPath array specifies GJSON paths to IP lists. The plain-text converter supports removePrefixesInLine and removeSuffixesInLine arrays to strip formatting artifacts (like IP-CIDR, or ,no-resolve) before CIDR detection.

{
  "type": "json",
  "action": "add",
  "args": {
    "uri": "https://api.fastly.com/public-ip-list",
    "jsonPath": ["addresses", "ipv6_addresses"],
    "onlyIPType": "ipv4"
  }
}
{
  "type": "text",
  "action": "add",
  "args": {
    "inputDir": "./clash-rules",
    "removePrefixesInLine": ["IP-CIDR,", "HOST,"],
    "removeSuffixesInLine": [",no-resolve"]
  }
}

Advanced OutputConverter Options

Output converters provide deterministic control over file generation and conflict resolution.

Output Control and Naming

Standard options include outputDir for destination folders, outputExtension for custom suffixes (e.g., .yaml), and outputName to override auto-generated filenames. These are implemented across all output plugins including plugin/plaintext/text_out.go and the MaxMind generators.

{
  "type": "text",
  "action": "output",
  "args": {
    "outputDir": "./output",
    "outputExtension": ".txt"
  }
}

Selective Exporting

wantedList limits export to specific categories, while excludedList blacklists categories regardless of other filters. When both are present, excludedList takes precedence. onlyIPType restricts the output to a single IP family.

{
  "type": "maxmindMMDB",
  "action": "output",
  "args": {
    "wantedList": ["cn", "google"],
    "excludedList": ["private"],
    "onlyIPType": "ipv6"
  }
}

Conflict Resolution with overwriteList

In MMDB format, overlapping CIDR ranges retain only the last written entry. The overwriteList array guarantees specified categories are written last, giving them precedence. This logic resides in plugin/maxmind/common_out.go.

{
  "type": "maxmindMMDB",
  "action": "output",
  "args": {
    "overwriteList": ["cn", "google"],
    "outputName": "Country.mmdb"
  }
}

Metadata Enrichment via sourceMMDBURI

For MMDB outputs, sourceMMDBURI points to an official database (DB-IP, IPInfo, or MaxMind) to supplement missing metadata. Without this option, the generated MMDB contains only country.iso_code. With it, the tool copies richer fields like country names and continent codes into your custom categories while preserving your classification logic.

{
  "type": "ipinfoCountryMMDB",
  "action": "output",
  "args": {
    "sourceMMDBURI": "https://example.com/GeoLite2-Country.mmdb",
    "outputDir": "./mmdb"
  }
}

Complete Configuration Examples

JSON Input with Deep Extraction

This configuration uses plugin/plaintext/json_in.go to extract IPs from nested JSON structures:

{
  "type": "json",
  "action": "add",
  "args": {
    "name": "fastly",
    "uri": "https://api.fastly.com/public-ip-list",
    "onlyIPType": "ipv4",
    "jsonPath": [
      "addresses",
      "ipv6_addresses"
    ],
    "wantedList": ["fastly"]
  }
}

Batch Text Processing with Cleanup

Processing a directory of Clash rules while stripping prefixes and suffixes:

{
  "type": "text",
  "action": "add",
  "args": {
    "inputDir": "./ruleset",
    "wantedList": ["cn", "us"],
    "removePrefixesInLine": ["IP-CIDR,", "HOST,"],
    "removeSuffixesInLine": [",no-resolve"]
  }
}

MMDB Output with Enrichment and Conflict Control

Generating a MaxMind-compatible database with metadata copying and deterministic overlap handling:

{
  "type": "maxmindMMDB",
  "action": "output",
  "args": {
    "outputDir": "./output",
    "outputName": "Country.mmdb",
    "overwriteList": ["cn", "google"],
    "excludedList": ["private"],
    "sourceMMDBURI": "https://example.com/GeoLite2-Country.mmdb"
  }
}

Full Input-to-Output Workflow

Combining remote ingestion with selective MMDB generation:

[
  {
    "type": "text",
    "action": "add",
    "args": {
      "uri": "https://raw.githubusercontent.com/Loyalsoldier/v2ray-rules-dat/master/geosite.dat",
      "onlyIPType": "ipv4"
    }
  },
  {
    "type": "maxmindMMDB",
    "action": "output",
    "args": {
      "outputDir": "./mmdb",
      "outputName": "GeoIP.mmdb",
      "wantedList": ["cn", "private"],
      "sourceMMDBURI": "./maxmind/GeoLite2-Country.mmdb"
    }
  }
]

Implementation and Registration Details

The registration system in lib/converter.go maintains two global maps: inputConverterMap and outputConverterMap. Each plugin registers itself in its init() function:

// Example from plugin/plaintext/text_in.go
func init() {
    lib.RegisterInputConverter("text", &TextIn{})
}

Factory functions read the args map from ConfigItem structures defined in lib/config.go. Input converters execute in configuration file order, filling a shared Container. Output converters execute after all inputs complete, with MMDB outputs specifically resolving filters in this sequence: wantedList → excludedList → overwriteList.

Summary

  • InputConverter options include wantedList for category whitelisting, onlyIPType for IP version filtering, inputDir for batch directory processing, and jsonPath for deep JSON extraction
  • OutputConverter options include wantedList/excludedList for selective exporting, overwriteList for deterministic conflict resolution in MMDB files, and sourceMMDBURI for metadata enrichment
  • The architecture uses interface-based plugins registered via lib/converter.go and configured through JSON ConfigItem structures processed by lib/config.go
  • Execution order matters: inputs run sequentially as listed, while MMDB outputs apply filters in a specific priority sequence to handle overlapping CIDR ranges

Frequently Asked Questions

How do I handle overlapping IP ranges between different categories?

Use the overwriteList option in MMDB output configurations. Categories listed in overwriteList are written last to the database, ensuring their entries take precedence when CIDR ranges overlap. This is implemented in plugin/maxmind/common_out.go.

Can I process multiple input files without listing each one in the configuration?

Yes. Use the inputDir argument instead of uri. The converter scans the specified directory non-recursively and treats each filename as a category name. Combine with wantedList to filter which files to process, as supported in plugin/plaintext/text_in.go and plugin/plaintext/json_in.go.

What is the purpose of the sourceMMDBURI option in output converters?

The sourceMMDBURI option points to an official MMDB file (MaxMind, DB-IP, or IPInfo) from which the tool copies metadata fields like country names and continent codes into your generated database. Without this option, MMDB outputs contain only the country.iso_code field and your custom categories.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →