mirror of
https://github.com/Sagit-chu/flvx.git
synced 2026-10-14 04:56:38 +08:00
merge: resolve conflicts with main branch
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -0,0 +1,11 @@
|
||||
探索转发创建时入口IP的生成流程:
|
||||
|
||||
1. 查找 `buildTunnelInIP` 函数的完整实现
|
||||
2. 查找 `resolveForwardIngress` 函数的完整实现
|
||||
3. 理解 `forward_port` 表如何与节点IP关联
|
||||
4. 查找转发创建API(createForward)如何处理入口端口分配
|
||||
|
||||
返回:
|
||||
- 关键代码片段和行号
|
||||
- 入口IP是如何从节点信息中提取的
|
||||
- 修改入口IP需要改动的关键位置
|
||||
@@ -0,0 +1,185 @@
|
||||
现在我已经找到了完整的入口IP生成流程。让我整理并返回关键信息:
|
||||
|
||||
---
|
||||
|
||||
## 入口IP生成流程分析
|
||||
|
||||
### 1. `buildTunnelInIP` 函数 (创建/更新隧道时)
|
||||
|
||||
**位置**: `go-backend/internal/http/handler/mutations.go:2112-2152`
|
||||
|
||||
```go
|
||||
func buildTunnelInIP(inNodes []tunnelRuntimeNode, nodes map[int64]*nodeRecord, ipPreference string) string {
|
||||
set := make(map[string]struct{})
|
||||
ordered := make([]string, 0)
|
||||
preferV6 := strings.TrimSpace(ipPreference) == "v6"
|
||||
for _, inNode := range inNodes {
|
||||
node := nodes[inNode.NodeID]
|
||||
if node == nil {
|
||||
continue
|
||||
}
|
||||
v4 := strings.TrimSpace(node.ServerIPv4) // 从节点获取 IPv4
|
||||
v6 := strings.TrimSpace(node.ServerIPv6) // 从节点获取 IPv6
|
||||
var addrs []string
|
||||
if preferV6 {
|
||||
if v6 != "" { addrs = append(addrs, v6) }
|
||||
if v4 != "" { addrs = append(addrs, v4) }
|
||||
} else {
|
||||
if v4 != "" { addrs = append(addrs, v4) }
|
||||
if v6 != "" { addrs = append(addrs, v6) }
|
||||
}
|
||||
if len(addrs) == 0 {
|
||||
if v := strings.TrimSpace(node.ServerIP); v != "" { // fallback 到 ServerIP
|
||||
addrs = append(addrs, v)
|
||||
}
|
||||
}
|
||||
// ... 去重后拼接
|
||||
}
|
||||
return strings.Join(ordered, ",")
|
||||
}
|
||||
```
|
||||
|
||||
**调用位置**:
|
||||
- 隧道创建: `mutations.go:496`
|
||||
- 隧道更新: `mutations.go:693`
|
||||
|
||||
---
|
||||
|
||||
### 2. `resolveForwardIngress` 函数 (查询转发时)
|
||||
|
||||
**位置**: `go-backend/internal/store/repo/repository.go:2727-2796`
|
||||
|
||||
```go
|
||||
func resolveForwardIngress(db *gorm.DB, forwardID int64, tunnelID int64) (string, sql.NullInt64, error) {
|
||||
// 1. 首先从 tunnel 表获取 in_ip (由 buildTunnelInIP 生成)
|
||||
var tunnelInIP sql.NullString
|
||||
db.Model(&model.Tunnel{}).Select("in_ip").Where("id = ?", tunnelID).Limit(1).Scan(&tunnelInIP)
|
||||
|
||||
// 2. 从 forward_port + node 表获取端口和节点IP
|
||||
type fpRow struct {
|
||||
Port sql.NullInt64
|
||||
ServerIP sql.NullString
|
||||
}
|
||||
var fpRows []fpRow
|
||||
err := db.Model(&model.ForwardPort{}).
|
||||
Select("forward_port.port, node.server_ip").
|
||||
Joins("LEFT JOIN node ON node.id = forward_port.node_id").
|
||||
Where("forward_port.forward_id = ?", forwardID).
|
||||
Order("forward_port.id ASC").
|
||||
Find(&fpRows).Error
|
||||
|
||||
// 3. 组装入口地址
|
||||
// - 如果 tunnel.in_ip 存在: "ip1:port,ip2:port..."
|
||||
// - 否则使用 forward_port 关联的 node.server_ip: "ip:port"
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
**调用位置**:
|
||||
- `repository.go:495` - 用户转发列表
|
||||
- `repository.go:730` - 管理员转发列表
|
||||
|
||||
---
|
||||
|
||||
### 3. `forward_port` 表与节点IP关联
|
||||
|
||||
**模型定义**: `go-backend/internal/store/model/model.go:50-57`
|
||||
|
||||
```go
|
||||
type ForwardPort struct {
|
||||
ID int64 `gorm:"primaryKey;autoIncrement"`
|
||||
ForwardID int64 `gorm:"column:forward_id;not null"`
|
||||
NodeID int64 `gorm:"column:node_id;not null"` // 关联到 node.id
|
||||
Port int `gorm:"not null"`
|
||||
}
|
||||
```
|
||||
|
||||
**关联查询** (在 `resolveForwardIngress` 中):
|
||||
```sql
|
||||
SELECT forward_port.port, node.server_ip
|
||||
FROM forward_port
|
||||
LEFT JOIN node ON node.id = forward_port.node_id
|
||||
WHERE forward_port.forward_id = ?
|
||||
ORDER BY forward_port.id ASC
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4. 转发创建API入口分配流程
|
||||
|
||||
**入口函数**: `go-backend/internal/http/handler/mutations.go:1108-1194`
|
||||
|
||||
```go
|
||||
func (h *Handler) forwardCreate(w http.ResponseWriter, r *http.Request) {
|
||||
// 1. 获取隧道入口节点IDs
|
||||
entryNodes, _ := h.tunnelEntryNodeIDs(tunnelID) // line 1162
|
||||
|
||||
// 2. 获取或选择入口端口
|
||||
port := asInt(req["inPort"], 0)
|
||||
if port <= 0 {
|
||||
port = h.pickTunnelPort(tunnelID) // 自动分配端口 (line 1157)
|
||||
}
|
||||
|
||||
// 3. 创建转发记录 + forward_port 记录
|
||||
forwardID, err := h.repo.CreateForwardTx(..., entryNodes, port, ...) // line 1179
|
||||
}
|
||||
```
|
||||
|
||||
**`CreateForwardTx`**: `go-backend/internal/store/repo/repository_mutations.go:1171-1209`
|
||||
```go
|
||||
func (r *Repository) CreateForwardTx(..., entryNodeIDs []int64, port int, ...) (int64, error) {
|
||||
// 创建 forward 记录
|
||||
// 为每个入口节点创建 forward_port 记录
|
||||
for _, nodeID := range entryNodeIDs {
|
||||
fp := model.ForwardPort{
|
||||
ForwardID: forwardID,
|
||||
NodeID: nodeID, // 入口节点ID
|
||||
Port: port, // 入口端口
|
||||
}
|
||||
tx.Create(&fp)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**入口节点获取**: `repository_mutations.go:535-548`
|
||||
```go
|
||||
func (r *Repository) TunnelEntryNodeIDs(tunnelID int64) ([]int64, error) {
|
||||
// 从 chain_tunnel 表查询 chain_type = 1 (入口) 的节点
|
||||
r.db.Model(&model.ChainTunnel{}).
|
||||
Where("tunnel_id = ? AND chain_type = ?", tunnelID, "1").
|
||||
Order("inx ASC, id ASC").
|
||||
Pluck("node_id", &ids)
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 关键修改位置
|
||||
|
||||
| 需求 | 修改文件 | 行号 | 说明 |
|
||||
|------|----------|------|------|
|
||||
| **修改隧道入口IP生成逻辑** | `mutations.go` | 2112-2152 | `buildTunnelInIP` 函数,控制IPv4/IPv6优先级和组合 |
|
||||
| **修改转发入口IP解析** | `repository.go` | 2727-2796 | `resolveForwardIngress`,控制入口地址格式 |
|
||||
| **修改端口自动分配** | `mutations.go` | 2901-2964 | `pickTunnelPort`,控制端口范围选择 |
|
||||
| **修改入口节点关联** | `repository_mutations.go` | 1196-1205 | `CreateForwardTx` 中的 forward_port 创建 |
|
||||
| **节点IP来源** | `model.go` | 516-531 | `NodeRecord` 结构体 |
|
||||
| **节点IP存储** | `model.go` | 59-65 | `Node` 模型: `ServerIP`, `ServerIPV4`, `ServerIPV6` |
|
||||
|
||||
---
|
||||
|
||||
## 入口IP数据流
|
||||
|
||||
```
|
||||
1. 节点注册 → Node表存储 server_ip, server_ip_v4, server_ip_v6
|
||||
|
||||
2. 创建隧道:
|
||||
chain_tunnel (入口节点) → buildTunnelInIP() → tunnel.in_ip 字段
|
||||
|
||||
3. 创建转发:
|
||||
隧道入口节点IDs → forward_port(forward_id, node_id, port)
|
||||
|
||||
4. 查询转发入口:
|
||||
forward_port JOIN node → resolveForwardIngress()
|
||||
├─ 优先使用 tunnel.in_ip (多IP组合)
|
||||
└─ 否则用 forward_port 关联的 node.server_ip
|
||||
```
|
||||
Reference in New Issue
Block a user