Skip to content

Commit 1d6f99d

Browse files
committed
update: Optimize the logic for the main control to extract the host
update: When synchronizing the master control, update the master control information update: Optimized the partial layout of the instance detail page update: Remove the experimental functional judgment on the main control detail page
1 parent 811eff1 commit 1d6f99d

File tree

13 files changed

+268
-226
lines changed

13 files changed

+268
-226
lines changed

internal/api/data.go

Lines changed: 11 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import (
1010
"NodePassDash/internal/tunnel"
1111
"encoding/json"
1212
"fmt"
13-
"net"
1413
"net/http"
1514
"net/url"
1615
"strings"
@@ -37,7 +36,7 @@ func NewDataHandler(db *gorm.DB, mgr *sse.Manager, endpointService *endpoint.Ser
3736
}
3837
}
3938

40-
// extractIPFromURL 从URL中提取IP地址(IPv4或IPv6
39+
// extractIPFromURL 从URL中提取hostname(可以是IP地址或域名
4140
func extractIPFromURL(urlStr string) string {
4241
// 尝试解析URL
4342
parsedURL, err := url.Parse(urlStr)
@@ -52,16 +51,11 @@ func extractIPFromURL(urlStr string) string {
5251
return ""
5352
}
5453

55-
// 检查是否为有效的IP地址
56-
if ip := net.ParseIP(host); ip != nil {
57-
return ip.String()
58-
}
59-
60-
// 如果不是IP地址,返回空字符串
61-
return ""
54+
// 返回hostname(可以是IP或域名)
55+
return host
6256
}
6357

64-
// extractIPFromString 从字符串中手动提取IP地址(备用方法)
58+
// extractIPFromString 从字符串中手动提取host部分(备用方法)
6559
func extractIPFromString(input string) string {
6660
// 去除协议部分
6761
if idx := strings.Index(input, "://"); idx != -1 {
@@ -78,30 +72,17 @@ func extractIPFromString(input string) string {
7872
input = input[:slashIdx]
7973
}
8074

81-
// 处理IPv6地址(方括号包围的地址)
82-
if strings.HasPrefix(input, "[") {
83-
if end := strings.Index(input, "]"); end != -1 {
84-
// 提取方括号内的IPv6地址
85-
ipv6Addr := input[1:end]
86-
// 检查是否为有效的IPv6地址
87-
if ip := net.ParseIP(ipv6Addr); ip != nil {
88-
return ip.String()
89-
}
90-
}
91-
return ""
75+
// 去除查询参数
76+
if queryIdx := strings.Index(input, "?"); queryIdx != -1 {
77+
input = input[:queryIdx]
9278
}
9379

94-
// 去除端口部分(IPv4)
80+
// 去除端口部分
9581
if colonIdx := strings.Index(input, ":"); colonIdx != -1 {
9682
input = input[:colonIdx]
9783
}
9884

99-
// 检查是否为有效的IP地址
100-
if ip := net.ParseIP(input); ip != nil {
101-
return ip.String()
102-
}
103-
104-
return ""
85+
return input
10586
}
10687

10788
func SetupDataRoutes(rg *gin.RouterGroup, db *gorm.DB, sseManager *sse.Manager, endpointService *endpoint.Service, tunnelService *tunnel.Service) {
@@ -171,11 +152,6 @@ func (h *DataHandler) HandleExport(c *gin.Context) {
171152
APIKey: ep.APIKey,
172153
}
173154

174-
// 设置颜色(如果有)
175-
if ep.Color != nil {
176-
exportEp.Color = *ep.Color
177-
}
178-
179155
exportEndpoints = append(exportEndpoints, exportEp)
180156
}
181157

@@ -281,7 +257,7 @@ func (h *DataHandler) handleImportV1(c *gin.Context, baseData struct {
281257
newEndpoint := models.Endpoint{
282258
Name: ep.Name,
283259
URL: ep.URL,
284-
IP: extractedIP, // 填充提取的IP地址
260+
Hostname: extractedIP, // 填充提取的IP地址
285261
APIPath: ep.APIPath,
286262
APIKey: ep.APIKey,
287263
Status: status,
@@ -487,7 +463,7 @@ func (h *DataHandler) handleImportV2(c *gin.Context, baseData struct {
487463
newEndpoint := models.Endpoint{
488464
Name: ep.Name,
489465
URL: ep.URL,
490-
IP: extractedIP, // 填充提取的IP地址
466+
Hostname: extractedIP, // 填充提取的IP地址
491467
APIPath: ep.APIPath,
492468
APIKey: ep.APIKey,
493469
Status: models.EndpointStatusOffline,
@@ -496,10 +472,6 @@ func (h *DataHandler) handleImportV2(c *gin.Context, baseData struct {
496472
UpdatedAt: time.Now(),
497473
}
498474

499-
if ep.Color != "" {
500-
newEndpoint.Color = &ep.Color
501-
}
502-
503475
if err := tx.Create(&newEndpoint).Error; err != nil {
504476
log.Errorf("插入端点失败: %v", err)
505477
continue

internal/api/endpoint.go

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1185,11 +1185,16 @@ func (h *EndpointHandler) refreshTunnels(endpointID int64) error {
11851185
return nil
11861186
})
11871187

1188-
// 如果事务成功,异步更新隧道计数
1188+
// 如果事务成功,异步更新隧道计数和主控信息
11891189
if err == nil {
11901190
go func(id int64) {
11911191
time.Sleep(50 * time.Millisecond)
1192+
1193+
// 更新隧道计数
11921194
updateEndpointTunnelCount(id)
1195+
1196+
// 获取并更新主控信息
1197+
h.fetchAndUpdateEndpointInfo(id)
11931198
}(endpointID)
11941199
}
11951200

@@ -1652,6 +1657,49 @@ func updateEndpointTunnelCount(endpointID int64) {
16521657
}
16531658
}
16541659

1660+
// fetchAndUpdateEndpointInfo 获取并更新端点系统信息和hostname
1661+
func (h *EndpointHandler) fetchAndUpdateEndpointInfo(endpointID int64) {
1662+
// 首先获取端点信息以获取URL用于提取hostname
1663+
var endpoint models.Endpoint
1664+
if err := h.endpointService.DB().First(&endpoint, endpointID).Error; err != nil {
1665+
log.Warnf("[Master-%d] 获取端点信息失败: %v", endpointID, err)
1666+
return
1667+
}
1668+
1669+
// 从URL中提取hostname并更新
1670+
hostname := extractIPFromURL(endpoint.URL)
1671+
if hostname != "" {
1672+
updates := map[string]interface{}{
1673+
"hostname": hostname,
1674+
"updated_at": time.Now(),
1675+
}
1676+
if err := h.endpointService.DB().Model(&models.Endpoint{}).Where("id = ?", endpointID).Updates(updates).Error; err != nil {
1677+
log.Errorf("[Master-%d] 更新hostname失败: %v", endpointID, err)
1678+
} else {
1679+
log.Debugf("[Master-%d] Hostname已更新: %s", endpointID, hostname)
1680+
}
1681+
}
1682+
1683+
// 尝试获取系统信息 (处理低版本API不存在的情况)
1684+
info, err := nodepass.GetInfo(endpointID)
1685+
if err != nil {
1686+
log.Warnf("[Master-%d] 获取系统信息失败: %v", endpointID, err)
1687+
// 不返回错误,继续处理
1688+
return
1689+
}
1690+
1691+
// 如果成功获取到信息,更新数据库
1692+
if info != nil {
1693+
if updateErr := h.endpointService.UpdateEndpointInfo(endpointID, *info); updateErr != nil {
1694+
log.Errorf("[Master-%d] 更新系统信息失败: %v", endpointID, updateErr)
1695+
} else {
1696+
// 在日志中显示uptime信息
1697+
uptimeMsg := fmt.Sprintf("%d秒", info.Uptime)
1698+
log.Infof("[Master-%d] 系统信息已更新: OS=%s, Arch=%s, Ver=%s, Uptime=%s", endpointID, info.OS, info.Arch, info.Ver, uptimeMsg)
1699+
}
1700+
}
1701+
}
1702+
16551703
// HandleGetAvailableLogDates 获取指定端点和实例的可用日志日期列表
16561704
func (h *EndpointHandler) HandleGetAvailableLogDates(c *gin.Context) {
16571705
// Method validation removed - handled by Gin router

internal/api/tunnel.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -866,6 +866,9 @@ func (h *TunnelHandler) HandleGetTunnelDetails(c *gin.Context) {
866866
"slot": parsedConfig.Slot,
867867
"proxy": parsedConfig.Proxy,
868868
"quic": parsedConfig.Quic,
869+
"dns": parsedConfig.Dns,
870+
"dial": parsedConfig.Dial,
871+
"listenType": parsedConfig.ListenType,
869872
},
870873

871874
// tags - GORM 自动反序列化为 *map[string]string

internal/endpoint/service.go

Lines changed: 13 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import (
55
"NodePassDash/internal/nodepass"
66
"errors"
77
"fmt"
8-
"net"
98
"net/url"
109
"strings"
1110
"time"
@@ -65,15 +64,15 @@ func extractIPFromURL(urlStr string) string {
6564
}
6665

6766
// 检查是否为有效的IP地址
68-
if ip := net.ParseIP(host); ip != nil {
69-
return ip.String()
70-
}
67+
//if ip := net.ParseIP(host); ip != nil {
68+
// return ip.String()
69+
//}
7170

7271
// 如果不是IP地址,返回空字符串
73-
return ""
72+
return host
7473
}
7574

76-
// extractIPFromString 从字符串中手动提取IP地址(备用方法)
75+
// extractIPFromString 从字符串中手动提取host部分(备用方法)
7776
func extractIPFromString(input string) string {
7877
// 去除协议部分
7978
if idx := strings.Index(input, "://"); idx != -1 {
@@ -90,39 +89,17 @@ func extractIPFromString(input string) string {
9089
input = input[:slashIdx]
9190
}
9291

93-
// 处理IPv6地址(方括号包围的地址)
94-
if strings.HasPrefix(input, "[") {
95-
if end := strings.Index(input, "]"); end != -1 {
96-
// 提取方括号内的IPv6地址
97-
ipv6Addr := input[1:end]
98-
// 检查是否为有效的IPv6地址
99-
if ip := net.ParseIP(ipv6Addr); ip != nil {
100-
return ip.String()
101-
}
102-
// 如果不是有效IPv6,返回方括号内的内容
103-
return ipv6Addr
104-
}
105-
return ""
92+
// 去除查询参数
93+
if queryIdx := strings.Index(input, "?"); queryIdx != -1 {
94+
input = input[:queryIdx]
10695
}
10796

108-
// 处理IPv4地址或带端口的地址
97+
// 去除端口部分
10998
if colonIdx := strings.Index(input, ":"); colonIdx != -1 {
110-
// 提取冒号前的部分
111-
hostPart := input[:colonIdx]
112-
// 检查是否为有效的IP地址
113-
if ip := net.ParseIP(hostPart); ip != nil {
114-
return ip.String()
115-
}
116-
// 如果不是有效IP,返回端口前的信息
117-
return hostPart
118-
} else {
119-
// 没有冒号,整个字符串可能是IP地址
120-
if ip := net.ParseIP(input); ip != nil {
121-
return ip.String()
122-
}
123-
// 如果不是有效IP,返回整个字符串
124-
return input
99+
input = input[:colonIdx]
125100
}
101+
102+
return input
126103
}
127104

128105
// CreateEndpoint 创建新端点
@@ -151,11 +128,10 @@ func (s *Service) CreateEndpoint(req CreateEndpointRequest) (*Endpoint, error) {
151128
endpoint := &models.Endpoint{
152129
Name: req.Name,
153130
URL: req.URL,
154-
IP: extractedIP, // 填充提取的IP地址
131+
Hostname: extractedIP, // 填充提取的IP地址
155132
APIPath: req.APIPath,
156133
APIKey: req.APIKey,
157134
Status: StatusOffline,
158-
Color: &req.Color,
159135
LastCheck: time.Now(),
160136
}
161137

internal/endpoint/service_test.go

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -98,21 +98,6 @@ func TestExtractIPFromString(t *testing.T) {
9898
input: "192.168.1.100:8080",
9999
expected: "192.168.1.100",
100100
},
101-
{
102-
name: "IPv6地址",
103-
input: "[2001:db8::1]",
104-
expected: "2001:db8::1",
105-
},
106-
{
107-
name: "IPv6地址带端口",
108-
input: "[2a0f:85c1:861:2180::1]:41231",
109-
expected: "2a0f:85c1:861:2180::1",
110-
},
111-
{
112-
name: "IPv6地址带端口",
113-
input: "[::1]:8080",
114-
expected: "::1",
115-
},
116101
{
117102
name: "带协议的IPv4",
118103
input: "http://192.168.1.100",
@@ -154,9 +139,9 @@ func TestExtractIPFromString(t *testing.T) {
154139
expected: "adasdasd",
155140
},
156141
{
157-
name: "无效IPv6格式但带端口",
158-
input: "[invalid-ipv6]:8080",
159-
expected: "invalid-ipv6",
142+
name: "域名带端口",
143+
input: "xx.xx:8080",
144+
expected: "xx.xx",
160145
},
161146
}
162147

internal/models/models.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,10 @@ type Endpoint struct {
99
ID int64 `json:"id" gorm:"primaryKey;autoIncrement;column:id"`
1010
Name string `json:"name" gorm:"type:text;uniqueIndex;not null;column:name"`
1111
URL string `json:"url" gorm:"type:text;uniqueIndex;not null;column:url"`
12-
IP string `json:"ip" gorm:"type:text;column:ip"`
12+
Hostname string `json:"hostname" gorm:"type:text;column:hostname"`
1313
APIPath string `json:"apiPath" gorm:"type:text;not null;column:api_path"`
1414
APIKey string `json:"apiKey" gorm:"type:text;not null;column:api_key"`
1515
Status EndpointStatus `json:"status" gorm:"type:text;default:'OFFLINE';column:status"`
16-
Color *string `json:"color,omitempty" gorm:"type:text;default:'default';column:color"`
1716
OS *string `json:"os,omitempty" gorm:"type:text;column:os"`
1817
Arch *string `json:"arch,omitempty" gorm:"type:text;column:arch"`
1918
Ver *string `json:"ver,omitempty" gorm:"type:text;column:ver"`

internal/services/service.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -530,7 +530,7 @@ func (s *ServiceImpl) syncServiceFromTunnel(sid, serviceType, instanceID string,
530530
if err := s.db.First(&endpoint, endpointID).Error; err == nil {
531531
service.TunnelEndpointName = &endpoint.Name
532532
if service.EntranceHost == nil || *service.EntranceHost == "" {
533-
service.EntranceHost = &endpoint.IP
533+
service.EntranceHost = &endpoint.Hostname
534534
}
535535
}
536536

@@ -578,7 +578,7 @@ func (s *ServiceImpl) syncServiceFromTunnel(sid, serviceType, instanceID string,
578578
if err := s.db.First(&endpoint, endpointID).Error; err == nil {
579579
service.TunnelEndpointName = &endpoint.Name
580580
if service.EntranceHost == nil || *service.EntranceHost == "" {
581-
service.EntranceHost = &endpoint.IP
581+
service.EntranceHost = &endpoint.Hostname
582582
}
583583
}
584584

internal/sse/service.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -633,7 +633,7 @@ func (s *Service) upsertService(instanceID string, tunnel *models.Tunnel) {
633633
if err := s.db.First(&endpoint, tunnel.EndpointID).Error; err == nil {
634634
service.TunnelEndpointName = &endpoint.Name
635635
if service.EntranceHost == nil || *service.EntranceHost == "" {
636-
service.EntranceHost = &endpoint.IP
636+
service.EntranceHost = &endpoint.Hostname
637637
}
638638
}
639639
}
@@ -655,7 +655,7 @@ func (s *Service) upsertService(instanceID string, tunnel *models.Tunnel) {
655655
if err := s.db.First(&endpoint, tunnel.EndpointID).Error; err == nil {
656656
service.TunnelEndpointName = &endpoint.Name
657657
if service.EntranceHost == nil || *service.EntranceHost == "" {
658-
service.EntranceHost = &endpoint.IP
658+
service.EntranceHost = &endpoint.Hostname
659659
}
660660
}
661661

@@ -701,7 +701,7 @@ func (s *Service) upsertService(instanceID string, tunnel *models.Tunnel) {
701701
if err := s.db.First(&endpoint, tunnel.EndpointID).Error; err == nil {
702702
service.TunnelEndpointName = &endpoint.Name
703703
if service.EntranceHost == nil || *service.EntranceHost == "" {
704-
service.EntranceHost = &endpoint.IP
704+
service.EntranceHost = &endpoint.Hostname
705705
}
706706
}
707707

web/src/components/tunnels/network-quality-card.tsx

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,11 @@ export const NetworkQualityCard = ({
2727

2828
// 计算连接池质量等级 (适中最好)
2929
const getPoolQuality = (poolCount: number) => {
30-
if (poolCount === 0) return { level: "空闲", percentage: 50 };
31-
if (poolCount <= 10) return { level: "轻负载", percentage: 80 };
30+
if (poolCount === 0) return { level: "无空闲", percentage: 50 };
31+
if (poolCount <= 10) return { level: "重负载", percentage: 80 };
3232
if (poolCount <= 50) return { level: "中负载", percentage: 90 };
33-
if (poolCount <= 100) return { level: "重负载", percentage: 70 };
34-
35-
return { level: "超负载", percentage: 40 };
33+
if (poolCount <= 100) return { level: "轻负载", percentage: 70 };
34+
return { level: "空负载", percentage: 40 };
3635
};
3736

3837
const latencyQuality = getLatencyQuality(ping);

0 commit comments

Comments
 (0)