Files
XTLS_Xray-docs-next/docs/development/lua/reference/hook-routing.md
T

182 lines
8.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 路由 Hook
核心在选择出站时调用 `routing.script` 中的全局函数 `HandleRoute`。配置接入和完整示例见[路由脚本指南](../guide/routing.md)。
## API 索引
| 分类 | 成员 | 说明 |
| ---- | --------------------------------------- | -------------------- |
| Hook | [`HandleRoute(...)`](#handleroute) | 为请求选择出站 |
| 对象 | [`routing.Context`](#routing-context) | 当前请求的路由上下文 |
| 方法 | [`ctx:GetSourceIPs()`](#getsourceips) | 取得来源 IP |
| 方法 | [`ctx:GetTargetIPs()`](#gettargetips) | 取得目标 IP |
| 方法 | [`ctx:GetLocalIPs()`](#getlocalips) | 取得本地 IP |
| 方法 | [`ctx:GetAttributes()`](#getattributes) | 取得请求属性 |
## Hook 接口
### HandleRoute(...)
```lua
function HandleRoute(ctx, inboundTag, sourcePort, targetPort,
localPort, targetDomain, network, protocol, user,
vlessRoute, skipDNSResolve)
return outboundTag, ruleTag, err
end
```
为当前请求选择出站,并可返回规则名称或错误。
#### 参数
核心始终按上述顺序传入全部 11 个参数,均非 `nil`。函数定义可省略不使用的末尾形参,这不会改变核心传入的值。
| 参数 | 类型 | 说明 | 空值与缺省值 |
| ---------------- | ------------------------------------- | ---------------------------------------------------------------------- | ------------------------------------------------------ |
| `ctx` | [`routing.Context`](#routing-context) | 当前请求上下文 | 始终是有效的 `userdata` |
| `inboundTag` | `string` | 入站标识 | 入站未设置 tag 或没有入站信息时为 `""` |
| `sourcePort` | `number` | 来源端口,`0 .. 65535` | 没有有效来源地址时为 `0` |
| `targetPort` | `number` | 目标端口,`0 .. 65535` | 没有有效目标地址时为 `0` |
| `localPort` | `number` | 入站连接的本地端口,`0 .. 65535` | 没有有效本地地址时为 `0` |
| `targetDomain` | `string` | 优先取生效的嗅探域名,否则取连接目标中的域名,统一转为小写 | 目标为 IP 且无生效的嗅探域名,或缺少目标信息时为 `""` |
| `network` | `number` | 网络类型,与 [`router.NetworkTCP`](./module-router.md#常量) 等常量比较 | 没有出站信息或网络类型未知时为 `NetworkUnknown`(`0`) |
| `protocol` | `string` | 嗅探得到的协议 | 没有嗅探协议信息时为 `""` |
| `user` | `string` | 用户 email | 没有入站、用户信息或未设置 email 时为 `""` |
| `vlessRoute` | `number` | VLESS UUID 第 7、8 字节组成的路由值,`0 .. 65535` | 没有该信息时为 `0`,值本身也可能为 0 |
| `skipDNSResolve` | `boolean` | 为 `true` 时必须跳过 DNS 查询,避免回环 | 没有该标记或附加请求信息时为 `false` |
#### 返回值
| 返回值 | 类型 | 说明 |
| ------------- | --------------------------------------------------- | --------------------------------------------- |
| `outboundTag` | `string` 或 `nil` | 出站标识;`nil` 或 `""` 表示未选中 |
| `ruleTag` | `string` 或 `nil` | 可选的规则名称;`nil`、省略或 `""` 表示无名称 |
| `err` | [`error`](./data-types.md#error)、`string` 或 `nil` | 仅 `nil` 表示无错误 |
#### 行为约定
核心依次校验 `err`、`outboundTag`、`ruleTag`,遇到错误即停止;`err` 非 `nil` 时忽略前两项,未选中出站时忽略 `ruleTag`。
成功时可省略末尾的 `ruleTag` 和 `err`,例如 `return "direct"`。错误必须放在第三个位置,例如 `return nil, nil, "路由失败"`;`return nil, "路由失败"` 不会报告错误。
| 脚本结果 | 核心处理 |
| ---------------------------------- | ---------------------------------- |
| 校验通过且 `outboundTag` 非空 | 使用对应出站,标识不存在则关闭连接 |
| 未选中出站 | 使用默认出站 |
| 返回错误、返回值类型错误或执行异常 | 记录错误并尝试默认出站 |
默认出站是配置中的第一个出站;没有可用默认出站时关闭连接。若要阻断流量应显式返回已配置的 [`blackhole`](../../../config/outbounds/blackhole.md) 出站 tag 而不是利用此特性返回不存在的标识。
## 关联对象
### routing.Context
`routing.Context` 表示当前请求的路由上下文,在 `HandleRoute` 中通过参数 `ctx` 访问。
| 属性 | 说明 |
| ----------- | ---------------------------------------------- |
| Go 底层类型 | `features/routing` 中的 `routing.Context` 接口 |
| Lua 表现 | `userdata` |
| 取得方式 | 核心传入的 `HandleRoute` 第一个参数 |
下列方法均无额外参数。IP 及 slice 操作统一见[数据类型](./data-types.md)。
#### GetSourceIPs
```lua
local ips = ctx:GetSourceIPs()
```
取得请求的来源 IP。
**参数**
无额外参数。
**返回值**
| 返回值 | 类型 | 说明 |
| ------ | ----------------------------------------------- | ------------------ |
| `ips` | [`[]net.IP`](./data-types.md#net-ip-1) 或 `nil` | 对应地址的 IP 列表 |
**行为约定**
没有入站、来源地址无效或来源地址不是 IP 时返回 `nil`。
#### GetTargetIPs
```lua
local ips = ctx:GetTargetIPs()
```
取得请求的目标 IP。
**参数**
无额外参数。
**返回值**
| 返回值 | 类型 | 说明 |
| ------ | ----------------------------------------------- | ------------------ |
| `ips` | [`[]net.IP`](./data-types.md#net-ip-1) 或 `nil` | 对应地址的 IP 列表 |
**行为约定**
没有出站、目标地址无效或目标地址是域名时返回 `nil`。
#### GetLocalIPs
```lua
local ips = ctx:GetLocalIPs()
```
取得入站连接的本地 IP。
**参数**
无额外参数。
**返回值**
| 返回值 | 类型 | 说明 |
| ------ | ----------------------------------------------- | ------------------ |
| `ips` | [`[]net.IP`](./data-types.md#net-ip-1) 或 `nil` | 对应地址的 IP 列表 |
**行为约定**
没有入站、本地地址无效或本地地址不是 IP 时返回 `nil`。
#### GetAttributes
```lua
local attributes = ctx:GetAttributes()
```
取得当前请求的属性。
**参数**
无额外参数。
**返回值**
| 返回值 | 类型 | 说明 |
| ------------ | ------------------- | ------------------------------- |
| `attributes` | `map[string]string` | 始终返回 `userdata`,不为 `nil` |
**行为约定**
使用 `attributes[key]` 读取属性,`key` 必须为字符串。已存在的键返回字符串(可能为 `""`),不存在的键返回 `nil`。
属性的含义和用途见路由配置中的 [`attrs`](../../../config/routing.md#ruleobject) 字段。
**示例**
```lua
local attributes = ctx:GetAttributes()
if attributes[":method"] == "GET" then
return "direct", "lua-get"
end
```