mirror of
https://github.com/XTLS/Xray-docs-next.git
synced 2026-10-12 09:18:19 +03:00
182 lines
8.5 KiB
Markdown
182 lines
8.5 KiB
Markdown
# 路由 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
|
||
```
|