# Advanced Configurations for InputConverter and OutputConverter in the geoip Tool

> Explore advanced geoip tool configurations for InputConverter and OutputConverter. Learn about wantedList filtering, onlyIPType, inputDir, jsonPath, overwriteList, and sourceMMDBURI for enhanced processing.

- Repository: [Loyalsoldier/geoip](https://github.com/loyalsoldier/geoip)
- Tags: deep-dive
- Published: 2026-03-06

---

**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`](https://github.com/loyalsoldier/geoip/blob/main/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`](https://github.com/loyalsoldier/geoip/blob/main/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.

```json
{
  "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`](https://github.com/loyalsoldier/geoip/blob/main/plugin/plaintext/text_in.go), this logic processes each file in the directory:

```json
{
  "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.

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

```

```json
{
  "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`](https://github.com/loyalsoldier/geoip/blob/main/plugin/plaintext/text_out.go) and the MaxMind generators.

```json
{
  "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.

```json
{
  "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`](https://github.com/loyalsoldier/geoip/blob/main/plugin/maxmind/common_out.go).

```json
{
  "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.

```json
{
  "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`](https://github.com/loyalsoldier/geoip/blob/main/plugin/plaintext/json_in.go) to extract IPs from nested JSON structures:

```json
{
  "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:

```json
{
  "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:

```json
{
  "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:

```json
[
  {
    "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`](https://github.com/loyalsoldier/geoip/blob/main/lib/converter.go) maintains two global maps: `inputConverterMap` and `outputConverterMap`. Each plugin registers itself in its `init()` function:

```go
// 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`](https://github.com/loyalsoldier/geoip/blob/main/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`](https://github.com/loyalsoldier/geoip/blob/main/lib/converter.go) and configured through JSON `ConfigItem` structures processed by [`lib/config.go`](https://github.com/loyalsoldier/geoip/blob/main/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`](https://github.com/loyalsoldier/geoip/blob/main/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`](https://github.com/loyalsoldier/geoip/blob/main/plugin/plaintext/text_in.go) and [`plugin/plaintext/json_in.go`](https://github.com/loyalsoldier/geoip/blob/main/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.