fix(tunnel): auto-update entry node IP on every tunnel update

This commit is contained in:
sagit
2026-02-13 01:24:48 +00:00
parent 69f62188cf
commit 9ed875b7ef
6 changed files with 56 additions and 41 deletions
@@ -700,21 +700,20 @@ func (h *Handler) federationTunnelCreate(w http.ResponseWriter, r *http.Request)
defer tx.Rollback()
now := time.Now().UnixMilli()
res, err := tx.Exec(`INSERT INTO tunnel (name, type, protocol, flow, created_time, updated_time, status, in_ip) VALUES (?, ?, ?, 0, ?, ?, 1, ?)`,
var tunnelID int64
err = tx.QueryRow(`INSERT INTO tunnel (name, type, protocol, flow, created_time, updated_time, status, in_ip) VALUES (?, ?, ?, 0, ?, ?, 1, ?) RETURNING id`,
fmt.Sprintf("Share-%d-Port-%d", share.ID, req.RemotePort),
tunnelType,
req.Protocol,
now,
now,
"",
)
).Scan(&tunnelID)
if err != nil {
response.WriteJSON(w, response.Err(-2, err.Error()))
return
}
tunnelID, _ := res.LastInsertId()
_, err = tx.Exec(`INSERT INTO chain_tunnel (tunnel_id, chain_type, node_id, port, strategy, inx, protocol) VALUES (?, 1, ?, ?, 'fifo', 0, ?)`,
tunnelID,
share.NodeID,
+20 -18
View File
@@ -559,13 +559,13 @@ func (h *Handler) tunnelCreate(w http.ResponseWriter, r *http.Request) {
}
}
res, err := tx.Exec(`INSERT INTO tunnel(name, traffic_ratio, type, protocol, flow, created_time, updated_time, status, in_ip, inx) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
name, trafficRatio, typeVal, "tls", flow, now, now, status, nullableText(inIP), inx)
var tunnelID int64
err = tx.QueryRow(`INSERT INTO tunnel(name, traffic_ratio, type, protocol, flow, created_time, updated_time, status, in_ip, inx) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING id`,
name, trafficRatio, typeVal, "tls", flow, now, now, status, nullableText(inIP), inx).Scan(&tunnelID)
if err != nil {
response.WriteJSON(w, response.Err(-2, err.Error()))
return
}
tunnelID, _ := res.LastInsertId()
runtimeState.TunnelID = tunnelID
var federationBindings []sqlite.FederationTunnelBinding
var federationReleaseRefs []federationRuntimeReleaseRef
@@ -688,6 +688,9 @@ func (h *Handler) tunnelUpdate(w http.ResponseWriter, r *http.Request) {
return
}
runtimeState.TunnelID = id
inIp := buildTunnelInIP(runtimeState.InNodes, runtimeState.Nodes)
var federationBindings []sqlite.FederationTunnelBinding
var federationReleaseRefs []federationRuntimeReleaseRef
if typeVal == 2 {
@@ -700,7 +703,7 @@ func (h *Handler) tunnelUpdate(w http.ResponseWriter, r *http.Request) {
applyTunnelPortsToRequest(req, runtimeState)
_, err = tx.Exec(`UPDATE tunnel SET name=?, type=?, flow=?, traffic_ratio=?, status=?, in_ip=?, updated_time=? WHERE id=?`,
asString(req["name"]), typeVal, asInt64(req["flow"], 1), asFloat(req["trafficRatio"], 1.0), asInt(req["status"], 1), nullableText(asString(req["inIp"])), now, id)
asString(req["name"]), typeVal, asInt64(req["flow"], 1), asFloat(req["trafficRatio"], 1.0), asInt(req["status"], 1), nullableText(inIp), now, id)
if err != nil {
response.WriteJSON(w, response.Err(-2, err.Error()))
return
@@ -1119,15 +1122,15 @@ func (h *Handler) forwardCreate(w http.ResponseWriter, r *http.Request) {
return
}
defer func() { _ = tx.Rollback() }()
res, err := tx.Exec(`
var forwardID int64
err = tx.QueryRow(`
INSERT INTO forward(user_id, user_name, name, tunnel_id, remote_addr, strategy, in_flow, out_flow, created_time, updated_time, status, inx)
VALUES(?, ?, ?, ?, ?, ?, 0, 0, ?, ?, 1, ?)
`, userID, userName, name, tunnelID, remoteAddr, defaultString(asString(req["strategy"]), "fifo"), now, now, inx)
VALUES(?, ?, ?, ?, ?, ?, 0, 0, ?, ?, 1, ?) RETURNING id
`, userID, userName, name, tunnelID, remoteAddr, defaultString(asString(req["strategy"]), "fifo"), now, now, inx).Scan(&forwardID)
if err != nil {
response.WriteJSON(w, response.Err(-2, err.Error()))
return
}
forwardID, _ := res.LastInsertId()
entryNodes, _ := h.tunnelEntryNodeIDs(tunnelID)
for _, nodeID := range entryNodes {
_, _ = tx.Exec(`INSERT INTO forward_port(forward_id, node_id, port) VALUES(?, ?, ?)`, forwardID, nodeID, port)
@@ -1587,13 +1590,13 @@ func (h *Handler) speedLimitCreate(w http.ResponseWriter, r *http.Request) {
}
now := time.Now().UnixMilli()
speed := asInt(req["speed"], 100)
res, err := h.repo.DB().Exec(`INSERT INTO speed_limit(name, speed, tunnel_id, tunnel_name, created_time, updated_time, status) VALUES(?, ?, ?, ?, ?, ?, ?)`,
name, speed, tunnelID, tunnelName, now, now, asInt(req["status"], 1))
var id int64
err := h.repo.DB().QueryRow(`INSERT INTO speed_limit(name, speed, tunnel_id, tunnel_name, created_time, updated_time, status) VALUES(?, ?, ?, ?, ?, ?, ?) RETURNING id`,
name, speed, tunnelID, tunnelName, now, now, asInt(req["status"], 1)).Scan(&id)
if err != nil {
response.WriteJSON(w, response.Err(-2, err.Error()))
return
}
id, _ := res.LastInsertId()
_ = h.sendLimiterConfig(id, speed, tunnelID)
response.WriteJSON(w, response.OKEmpty())
}
@@ -1687,7 +1690,7 @@ func (h *Handler) groupTunnelAssign(w http.ResponseWriter, r *http.Request) {
defer func() { _ = tx.Rollback() }()
_, _ = tx.Exec(`DELETE FROM tunnel_group_tunnel WHERE tunnel_group_id = ?`, req.GroupID)
for _, tid := range req.TunnelIDs {
_, _ = tx.Exec(`INSERT OR IGNORE INTO tunnel_group_tunnel(tunnel_group_id, tunnel_id, created_time) VALUES(?, ?, ?)`, req.GroupID, tid, time.Now().UnixMilli())
_, _ = tx.Exec(`INSERT INTO tunnel_group_tunnel(tunnel_group_id, tunnel_id, created_time) VALUES(?, ?, ?) ON CONFLICT(tunnel_group_id, tunnel_id) DO NOTHING`, req.GroupID, tid, time.Now().UnixMilli())
}
if err := tx.Commit(); err != nil {
response.WriteJSON(w, response.Err(-2, err.Error()))
@@ -1714,7 +1717,7 @@ func (h *Handler) groupUserAssign(w http.ResponseWriter, r *http.Request) {
defer func() { _ = tx.Rollback() }()
_, _ = tx.Exec(`DELETE FROM user_group_user WHERE user_group_id = ?`, req.GroupID)
for _, uid := range req.UserIDs {
_, _ = tx.Exec(`INSERT OR IGNORE INTO user_group_user(user_group_id, user_id, created_time) VALUES(?, ?, ?)`, req.GroupID, uid, time.Now().UnixMilli())
_, _ = tx.Exec(`INSERT INTO user_group_user(user_group_id, user_id, created_time) VALUES(?, ?, ?) ON CONFLICT(user_group_id, user_id) DO NOTHING`, req.GroupID, uid, time.Now().UnixMilli())
}
if err := tx.Commit(); err != nil {
response.WriteJSON(w, response.Err(-2, err.Error()))
@@ -1733,7 +1736,7 @@ func (h *Handler) groupPermissionAssign(w http.ResponseWriter, r *http.Request)
response.WriteJSON(w, response.ErrDefault("请求参数错误"))
return
}
_, err := h.repo.DB().Exec(`INSERT OR IGNORE INTO group_permission(user_group_id, tunnel_group_id, created_time) VALUES(?, ?, ?)`, req.UserGroupID, req.TunnelGroupID, time.Now().UnixMilli())
_, err := h.repo.DB().Exec(`INSERT INTO group_permission(user_group_id, tunnel_group_id, created_time) VALUES(?, ?, ?) ON CONFLICT(user_group_id, tunnel_group_id) DO NOTHING`, req.UserGroupID, req.TunnelGroupID, time.Now().UnixMilli())
if err != nil {
response.WriteJSON(w, response.Err(-2, err.Error()))
return
@@ -1835,7 +1838,7 @@ func (h *Handler) applyGroupPermission(userGroupID, tunnelGroupID int64) error {
if created {
createdByGroup = 1
}
_, _ = db.Exec(`INSERT OR IGNORE INTO group_permission_grant(user_group_id, tunnel_group_id, user_tunnel_id, created_by_group, created_time) VALUES(?, ?, ?, ?, ?)`,
_, _ = db.Exec(`INSERT INTO group_permission_grant(user_group_id, tunnel_group_id, user_tunnel_id, created_by_group, created_time) VALUES(?, ?, ?, ?, ?) ON CONFLICT(user_group_id, tunnel_group_id, user_tunnel_id) DO NOTHING`,
userGroupID, tunnelGroupID, utID, createdByGroup, time.Now().UnixMilli())
}
}
@@ -1882,12 +1885,11 @@ func ensureUserTunnelGrant(db *sql.DB, userID, tunnelID int64) (int64, bool, err
if err := db.QueryRow(`SELECT flow, num, exp_time, flow_reset_time FROM user WHERE id = ?`, userID).Scan(&flow, &num, &expTime, &flowReset); err != nil {
return 0, false, err
}
res, err := db.Exec(`INSERT INTO user_tunnel(user_id, tunnel_id, speed_id, num, flow, in_flow, out_flow, flow_reset_time, exp_time, status) VALUES(?, ?, NULL, ?, ?, 0, 0, ?, ?, 1)`,
userID, tunnelID, num, flow, flowReset, expTime)
err = db.QueryRow(`INSERT INTO user_tunnel(user_id, tunnel_id, speed_id, num, flow, in_flow, out_flow, flow_reset_time, exp_time, status) VALUES(?, ?, NULL, ?, ?, 0, 0, ?, ?, 1) RETURNING id`,
userID, tunnelID, num, flow, flowReset, expTime).Scan(&id)
if err != nil {
return 0, false, err
}
id, _ = res.LastInsertId()
return id, true, nil
}