mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-10-12 02:06:37 +08:00
migrate
This commit is contained in:
@@ -0,0 +1,117 @@
|
||||
// Copyright 2026 Arctel.net
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package relay
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/Rain-kl/Wavelet/internal/db"
|
||||
"github.com/Rain-kl/Wavelet/internal/model"
|
||||
)
|
||||
|
||||
const nodeStatusOnline = "online"
|
||||
|
||||
// HeartbeatPayload is sent by OpenFlareRelay on each heartbeat.
|
||||
type HeartbeatPayload struct {
|
||||
Version string `json:"version"`
|
||||
ExtVersion string `json:"frp_version"`
|
||||
RelayStatus string `json:"relay_status"`
|
||||
Name string `json:"name"`
|
||||
IP string `json:"ip"`
|
||||
}
|
||||
|
||||
// Config is the frps configuration sent to the relay.
|
||||
type Config struct {
|
||||
BindPort int `json:"bind_port"`
|
||||
VhostHTTPPort int `json:"vhost_http_port"`
|
||||
AuthToken string `json:"auth_token"`
|
||||
LogLevel string `json:"log_level"`
|
||||
WebServerEnabled bool `json:"web_server_enabled"`
|
||||
}
|
||||
|
||||
// Settings contains runtime settings for relay and flared clients.
|
||||
type Settings struct {
|
||||
HeartbeatInterval int `json:"heartbeat_interval"`
|
||||
WebsocketUpgradeEnabled bool `json:"websocket_upgrade_enabled"`
|
||||
AutoUpdate bool `json:"auto_update"`
|
||||
UpdateRepo string `json:"update_repo"`
|
||||
UpdateNow bool `json:"update_now"`
|
||||
UpdateChannel string `json:"update_channel"`
|
||||
UpdateTag string `json:"update_tag"`
|
||||
}
|
||||
|
||||
// HeartbeatResponse is returned from a relay heartbeat.
|
||||
type HeartbeatResponse struct {
|
||||
RelayConfig *Config `json:"relay_config"`
|
||||
RelaySettings *Settings `json:"relay_settings"`
|
||||
}
|
||||
|
||||
// Heartbeat processes a relay heartbeat, updates node status, and returns config.
|
||||
func Heartbeat(ctx context.Context, node *model.OpenFlareNode, payload HeartbeatPayload) (*HeartbeatResponse, error) {
|
||||
if node == nil {
|
||||
return nil, fmt.Errorf("relay node is nil")
|
||||
}
|
||||
|
||||
payload.Version = strings.TrimSpace(payload.Version)
|
||||
payload.ExtVersion = strings.TrimSpace(payload.ExtVersion)
|
||||
payload.RelayStatus = normalizeRelayStatus(payload.RelayStatus)
|
||||
payload.Name = strings.TrimSpace(payload.Name)
|
||||
payload.IP = strings.TrimSpace(payload.IP)
|
||||
|
||||
previous := *node
|
||||
updateNow := node.UpdateRequested
|
||||
updateChannel := normalizeReleaseChannel(node.UpdateChannel)
|
||||
updateTag := strings.TrimSpace(node.UpdateTag)
|
||||
|
||||
now := time.Now().UTC()
|
||||
changes := map[string]any{
|
||||
"version": payload.Version,
|
||||
"ext_version": payload.ExtVersion,
|
||||
"relay_status": payload.RelayStatus,
|
||||
"last_seen_at": now,
|
||||
"status": nodeStatusOnline,
|
||||
"update_requested": false,
|
||||
"update_channel": "stable",
|
||||
"update_tag": "",
|
||||
}
|
||||
if payload.Name != "" && strings.TrimSpace(node.Name) == "" {
|
||||
changes["name"] = payload.Name
|
||||
node.Name = payload.Name
|
||||
}
|
||||
if payload.IP != "" && !node.IPManualOverride {
|
||||
changes["ip"] = payload.IP
|
||||
node.IP = payload.IP
|
||||
}
|
||||
if !previous.UpdateRequested {
|
||||
delete(changes, "update_requested")
|
||||
}
|
||||
if previous.UpdateChannel == "stable" {
|
||||
delete(changes, "update_channel")
|
||||
}
|
||||
if previous.UpdateTag == "" {
|
||||
delete(changes, "update_tag")
|
||||
}
|
||||
|
||||
node.Version = payload.Version
|
||||
node.ExtVersion = payload.ExtVersion
|
||||
node.RelayStatus = payload.RelayStatus
|
||||
node.UpdateRequested = false
|
||||
node.UpdateChannel = "stable"
|
||||
node.UpdateTag = ""
|
||||
lastSeen := now
|
||||
node.LastSeenAt = &lastSeen
|
||||
node.Status = nodeStatusOnline
|
||||
|
||||
if err := db.DB(ctx).Model(node).Updates(changes).Error; err != nil {
|
||||
return nil, fmt.Errorf("update relay heartbeat: %w", err)
|
||||
}
|
||||
|
||||
return &HeartbeatResponse{
|
||||
RelayConfig: buildRelayConfig(node),
|
||||
RelaySettings: BuildSettings(node, updateNow, updateChannel, updateTag),
|
||||
}, nil
|
||||
}
|
||||
Reference in New Issue
Block a user