---
url: /development/lua/reference/module-geodata.md
---
# xray.geodata

提供域名和 IP 的规则匹配功能。

```lua
local geodata = require("xray.geodata")
```

## API 索引

| 分类 | 成员                                                             | 说明                     |
| ---- | ---------------------------------------------------------------- | ------------------------ |
| 函数 | [`geodata.BuildDomainMatcher(...)`](#geodata-builddomainmatcher) | 创建 `DomainMatcher`     |
| 函数 | [`geodata.BuildIPMatcher(...)`](#geodata-buildipmatcher)         | 创建 `IPMatcher`         |
| 对象 | [`DomainMatcher`](#domainmatcher)                                | 域名匹配器               |
| 方法 | [`domainMatcherObj:MatchAny(domain)`](#matchany)                 | 判断域名是否命中任意规则 |
| 方法 | [`domainMatcherObj:Match(domain)`](#match)                       | 取得命中的域名规则编号   |
| 对象 | [`IPMatcher`](#ipmatcher)                                        | IP 匹配器                |
| 方法 | [`ipMatcherObj:Match(ip)`](#match-1)                             | 匹配单个 IP              |
| 方法 | [`ipMatcherObj:AnyMatch(ips)`](#anymatch)                        | 判断是否有 IP 命中       |
| 方法 | [`ipMatcherObj:Matches(ips)`](#matches)                          | 判断整个 IP 列表是否命中 |
| 方法 | [`ipMatcherObj:FilterIPs(ips)`](#filterips)                      | 分离命中和未命中的 IP    |
| 方法 | [`ipMatcherObj:SetReverse(reverse)`](#setreverse)                | 设置反选标记             |
| 方法 | [`ipMatcherObj:ToggleReverse()`](#togglereverse)                 | 切换反选标记             |

## 函数

### geodata.BuildDomainMatcher

```lua
local domainMatcherObj = geodata.BuildDomainMatcher(rule1, rule2, ...)
```

根据域名规则创建 [`DomainMatcher`](#domainmatcher)。

**参数**

| 参数                | 类型     | 说明 / 要求                      |
| ------------------- | -------- | -------------------------------- |
| `rule1, rule2, ...` | `string` | 必填，至少一条域名规则，逐个传入 |

**返回值**

| 返回值             | 类型                              | 说明           |
| ------------------ | --------------------------------- | -------------- |
| `domainMatcherObj` | [`DomainMatcher`](#domainmatcher) | 域名匹配器实例 |

**行为约定**

未传入规则、参数类型错误，或规则解析、资源加载、构建失败时，抛出 Lua 异常。

支持 `domain:`、`full:`、`keyword:`、`regexp:`、`dotless:`、`geosite:`、`ext:`（亦可写为 `ext-domain:` / `ext-site:`），格式见[路由域名规则](../../../config/routing.md#ruleobject)。GeoSite 文件从[资源目录](../../../config/env.md#资源文件路径)加载。

无前缀字符串默认使用 `domain:` 规则。

除正则表达式外，规则在构建时转为小写。

**示例**

```lua
local sitesObj = geodata.BuildDomainMatcher(
    "example.com", "full:other.example"
)
```

### geodata.BuildIPMatcher

```lua
local ipMatcherObj = geodata.BuildIPMatcher(rule1, rule2, ...)
```

根据 IP 规则创建 [`IPMatcher`](#ipmatcher)。

**参数**

| 参数                | 类型     | 说明 / 要求                      |
| ------------------- | -------- | -------------------------------- |
| `rule1, rule2, ...` | `string` | 必填，至少一条 IP 规则，逐个传入 |

**返回值**

| 返回值         | 类型                      | 说明          |
| -------------- | ------------------------- | ------------- |
| `ipMatcherObj` | [`IPMatcher`](#ipmatcher) | IP 匹配器实例 |

**行为约定**

未传入规则、参数类型错误、规则为空字符串，或规则解析、资源加载、构建失败时，抛出 Lua 异常。

支持 IP、CIDR、`geoip:`、`ext:`（亦可写为 `ext-ip:`）及 `!` 反选规则，组合方式见[路由 IP 规则](../../../config/routing.md#ruleobject)。GeoIP 文件从[资源目录](../../../config/env.md#资源文件路径)加载。

**示例**

```lua
local privateIPsObj = geodata.BuildIPMatcher(
    "10.0.0.0/8", "192.168.0.0/16", "fc00::/7"
)
```

## 对象

### DomainMatcher

| 属性        | 说明                                                                      |
| ----------- | ------------------------------------------------------------------------- |
| Go 底层类型 | `geodata.DomainMatcher` 接口的实现                                        |
| Lua 表现    | `userdata`                                                                |
| 取得方式    | [`geodata.BuildDomainMatcher(...)`](#geodata-builddomainmatcher) 的返回值 |

**通用约定**

匹配方法接收一个域名字符串。`nil`、省略参数、类型或参数数量错误会抛出 Lua 异常。

输入域名不会自动转为小写，需由脚本按需处理。

#### MatchAny

```lua
local matched = domainMatcherObj:MatchAny(domain)
```

判断域名是否命中至少一条规则。

**参数**

| 参数     | 类型     | 说明 / 要求      |
| -------- | -------- | ---------------- |
| `domain` | `string` | 必填，待匹配域名 |

**返回值**

| 返回值    | 类型      | 说明                            |
| --------- | --------- | ------------------------------- |
| `matched` | `boolean` | 命中时为 `true`，否则为 `false` |

**示例**

```lua
local matched = sitesObj:MatchAny("www.example.com")
```

#### Match

```lua
local indices = domainMatcherObj:Match(domain)
```

取得域名命中的规则编号。

**参数**

| 参数     | 类型     | 说明 / 要求      |
| -------- | -------- | ---------------- |
| `domain` | `string` | 必填，待匹配域名 |

**返回值**

| 返回值    | 类型                                          | 说明                                                 |
| --------- | --------------------------------------------- | ---------------------------------------------------- |
| `indices` | [`[]uint32`](./data-types.md#uint32) 或 `nil` | 命中的规则编号；未命中时为 `nil` 或长度为 0 的 slice |

**行为约定**

规则编号从 **0** 开始，对应构建时传入的规则顺序。结果顺序不保证，可能包含重复编号；GeoSite 展开的条目沿用其所属规则的编号。

若将同一组规则保存在 Lua 数组中，可用 `rules[ruleNumber + 1]` 取得原规则。slice 的访问方式见[数据类型](./data-types.md#slice)。

**示例**

```lua
local indices = sitesObj:Match("www.example.com")
if indices ~= nil then
    for i = 1, #indices do
        local ruleNumber = indices[i]
    end
end
```

### IPMatcher

| 属性        | 说明                                                              |
| ----------- | ----------------------------------------------------------------- |
| Go 底层类型 | `geodata.IPMatcher` 接口的实现                                    |
| Lua 表现    | `userdata`                                                        |
| 取得方式    | [`geodata.BuildIPMatcher(...)`](#geodata-buildipmatcher) 的返回值 |

**通用约定**

匹配单个 IP 时使用 [`net.IP`](./data-types.md#net-ip)；匹配或筛选列表时，输入形式见 [IP 列表输入](./data-types.md#ip-列表输入)。IP 地址字符串不会自动解析为 `net.IP`。

匹配和筛选方法均接受显式的 `nil`。省略参数、类型或参数数量错误会抛出 Lua 异常。

#### Match

```lua
local matched = ipMatcherObj:Match(ip)
```

判断单个 IP 是否命中规则。

**参数**

| 参数 | 类型                                        | 说明 / 要求      |
| ---- | ------------------------------------------- | ---------------- |
| `ip` | [`net.IP`](./data-types.md#net-ip) 或 `nil` | 必填，须显式传入 |

**返回值**

| 返回值    | 类型      | 说明                                                |
| --------- | --------- | --------------------------------------------------- |
| `matched` | `boolean` | 有效 IP 命中时为 `true`；`nil` 或无效 IP 为 `false` |

**行为约定**

传入 `""` 或空 table `{}` 时，会被视为空 IP 并返回 `false`；字符串不会按 IP 地址文本解析。

#### AnyMatch

```lua
local matched = ipMatcherObj:AnyMatch(ips)
```

判断是否至少有一个有效 IP 命中规则。

**参数**

| 参数  | 类型                                       | 说明 / 要求                  |
| ----- | ------------------------------------------ | ---------------------------- |
| `ips` | [IP 列表输入](./data-types.md#ip-列表输入) | 必填，须显式传入，允许 `nil` |

**返回值**

| 返回值    | 类型      | 说明                                                               |
| --------- | --------- | ------------------------------------------------------------------ |
| `matched` | `boolean` | 至少一个有效 IP 命中时为 `true`；`nil`、空列表或未命中时为 `false` |

#### Matches

```lua
local matched = ipMatcherObj:Matches(ips)
```

判断整个 IP 列表是否命中规则。

**参数**

| 参数  | 类型                                       | 说明 / 要求                  |
| ----- | ------------------------------------------ | ---------------------------- |
| `ips` | [IP 列表输入](./data-types.md#ip-列表输入) | 必填，须显式传入，允许 `nil` |

**返回值**

| 返回值    | 类型      | 说明                                                                   |
| --------- | --------- | ---------------------------------------------------------------------- |
| `matched` | `boolean` | 整个列表满足匹配要求时为 `true`；`nil`、空列表或含无效 IP 时为 `false` |

**行为约定**

组合规则可能包含多个内部匹配器，必须有一个内部匹配器命中整个列表。

例如，用 `geodata.BuildIPMatcher("192.168.1.0/24", "geoip:us")` 构建匹配器，输入列表同时包含 `192.168.1.1` 和 `8.8.8.8` 时，`Matches` 返回 `false`：前者命中 custom CIDR，后者命中 `geoip:us`，但两类规则属于不同的内部匹配器，没有一个能命中整个列表。

只需判断是否有地址命中时，使用 [`AnyMatch`](#anymatch)。

#### FilterIPs

```lua
local matched, unmatched = ipMatcherObj:FilterIPs(ips)
```

将有效 IP 分为命中和未命中两组。

**参数**

| 参数  | 类型                                       | 说明 / 要求                  |
| ----- | ------------------------------------------ | ---------------------------- |
| `ips` | [IP 列表输入](./data-types.md#ip-列表输入) | 必填，须显式传入，允许 `nil` |

**返回值**

| 返回值      | 类型                                   | 说明                      |
| ----------- | -------------------------------------- | ------------------------- |
| `matched`   | [`[]net.IP`](./data-types.md#net-ip-1) | 命中的 IP，始终非 `nil`   |
| `unmatched` | [`[]net.IP`](./data-types.md#net-ip-1) | 未命中的 IP，始终非 `nil` |

**行为约定**

没有结果的一组为空 slice；传入 `nil`、空列表或全部无效 IP 时，两组均为空 slice。

无效 IP 会被丢弃，结果顺序不保证与输入相同。

#### SetReverse

```lua
ipMatcherObj:SetReverse(reverse)
```

设置各内部匹配器的反选标记。

**参数**

| 参数      | 类型      | 说明 / 要求                             |
| --------- | --------- | --------------------------------------- |
| `reverse` | `boolean` | 必填，`true` 开启反选，`false` 关闭反选 |

**返回值**

无返回值。

**行为约定**

`nil`、省略参数或类型错误会抛出 Lua 异常。此操作覆盖各内部匹配器原有的反选标记，包括规则中 `!` 指定的标记。反选只作用于原规则包含的地址族，且不会匹配无效 IP。

设置后的反选状态保存在当前匹配器对象中。如果后续 Hook 调用复用该对象，修改后的状态也会继续生效，见[池化实例内状态](../guide/lifecycle.md#池化实例内状态)。

**示例**

对 `10.0.0.0/8` 反选后，匹配该范围以外的有效 IPv4 地址：

```lua
local ipMatcherObj = geodata.BuildIPMatcher("10.0.0.0/8")
ipMatcherObj:SetReverse(true)
```

#### ToggleReverse

```lua
ipMatcherObj:ToggleReverse()
```

切换各内部匹配器的反选标记。

**参数**

无额外参数。

**返回值**

无返回值。

**行为约定**

组合规则中的各内部匹配器分别切换反选标记，结果不等同于对整个组合结果取逻辑反。
切换后的反选状态保存在当前匹配器对象中。如果后续 Hook 调用复用该对象，修改后的状态也会继续生效，见[池化实例内状态](../guide/lifecycle.md#池化实例内状态)。
