完善节点筛选机制
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
## TODO
|
## TODO
|
||||||
|
|
||||||
- 日志记录
|
- edge.area_id 可为空,代表节点无固定地区
|
||||||
- 后台展示 mac, ip:port,实际地区
|
- 后台展示 mac, ip:port,实际地区
|
||||||
|
|
||||||
上传文件平铺到 uploads,不分子文件夹
|
上传文件平铺到 uploads,不分子文件夹
|
||||||
|
|||||||
@@ -669,7 +669,7 @@ create table edge (
|
|||||||
ip inet not null,
|
ip inet not null,
|
||||||
port int,
|
port int,
|
||||||
isp int not null,
|
isp int not null,
|
||||||
area_id int not null,
|
area_id int,
|
||||||
status int not null default 0,
|
status int not null default 0,
|
||||||
rtt int default 0,
|
rtt int default 0,
|
||||||
loss int default 0,
|
loss int default 0,
|
||||||
|
|||||||
@@ -230,23 +230,6 @@ type CreateChannelReqV3 struct {
|
|||||||
Isp *int `json:"isp"`
|
Isp *int `json:"isp"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func buildCreateChannelResp(result []*m.Channel, protocol int, authType s.ChannelAuthType) []*CreateChannelRespItem {
|
|
||||||
resp := make([]*CreateChannelRespItem, len(result))
|
|
||||||
for i, channel := range result {
|
|
||||||
resp[i] = &CreateChannelRespItem{
|
|
||||||
Proto: protocol,
|
|
||||||
Host: channel.Host,
|
|
||||||
IP: channel.Proxy.IP.String(),
|
|
||||||
Port: channel.Port,
|
|
||||||
}
|
|
||||||
if authType == s.ChannelAuthTypePass {
|
|
||||||
resp[i].Username = channel.Username
|
|
||||||
resp[i].Password = channel.Password
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return resp
|
|
||||||
}
|
|
||||||
|
|
||||||
type CreateChannelRespItem struct {
|
type CreateChannelRespItem struct {
|
||||||
Proto int `json:"-"`
|
Proto int `json:"-"`
|
||||||
Host string `json:"host"`
|
Host string `json:"host"`
|
||||||
@@ -474,3 +457,20 @@ type SyncChannelClearExpiredByAdminReq struct {
|
|||||||
type SyncChannelClearExpiredByAdminResp struct {
|
type SyncChannelClearExpiredByAdminResp struct {
|
||||||
Count int `json:"count"`
|
Count int `json:"count"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func buildCreateChannelResp(result []*m.Channel, protocol int, authType s.ChannelAuthType) []*CreateChannelRespItem {
|
||||||
|
resp := make([]*CreateChannelRespItem, len(result))
|
||||||
|
for i, channel := range result {
|
||||||
|
resp[i] = &CreateChannelRespItem{
|
||||||
|
Proto: protocol,
|
||||||
|
Host: channel.Host,
|
||||||
|
IP: channel.Proxy.IP.String(),
|
||||||
|
Port: channel.Port,
|
||||||
|
}
|
||||||
|
if authType == s.ChannelAuthTypePass {
|
||||||
|
resp[i].Username = channel.Username
|
||||||
|
resp[i].Password = channel.Password
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return resp
|
||||||
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ type Edge struct {
|
|||||||
IP orm.Inet `json:"ip" gorm:"column:ip;not null"` // 节点地址或 GOST chain addr 的 IP
|
IP orm.Inet `json:"ip" gorm:"column:ip;not null"` // 节点地址或 GOST chain addr 的 IP
|
||||||
Port *uint16 `json:"port,omitempty" gorm:"column:port"` // GOST chain addr 的端口
|
Port *uint16 `json:"port,omitempty" gorm:"column:port"` // GOST chain addr 的端口
|
||||||
ISP EdgeISP `json:"isp" gorm:"column:isp"` // 运营商:0-未知,1-电信,2-联通,3-移动
|
ISP EdgeISP `json:"isp" gorm:"column:isp"` // 运营商:0-未知,1-电信,2-联通,3-移动
|
||||||
AreaID int32 `json:"area_id" gorm:"column:area_id"` // 城市地区ID
|
AreaID *int32 `json:"area_id,omitempty" gorm:"column:area_id"` // 城市地区ID
|
||||||
Status EdgeStatus `json:"status" gorm:"column:status"` // 节点状态:0-离线,1-正常
|
Status EdgeStatus `json:"status" gorm:"column:status"` // 节点状态:0-离线,1-正常
|
||||||
RTT int32 `json:"rtt" gorm:"column:rtt"` // 最近平均延迟
|
RTT int32 `json:"rtt" gorm:"column:rtt"` // 最近平均延迟
|
||||||
Loss int32 `json:"loss" gorm:"column:loss"` // 最近丢包率
|
Loss int32 `json:"loss" gorm:"column:loss"` // 最近丢包率
|
||||||
@@ -41,6 +41,7 @@ const (
|
|||||||
type EdgeISP int
|
type EdgeISP int
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
EdgeISPUnknown EdgeISP = 0 // 未知/任意
|
||||||
EdgeISPTelecom EdgeISP = 1 // 电信
|
EdgeISPTelecom EdgeISP = 1 // 电信
|
||||||
EdgeISPUnicom EdgeISP = 2 // 联通
|
EdgeISPUnicom EdgeISP = 2 // 联通
|
||||||
EdgeISPMobile EdgeISP = 3 // 移动
|
EdgeISPMobile EdgeISP = 3 // 移动
|
||||||
|
|||||||
@@ -1,13 +1,11 @@
|
|||||||
package web
|
package web
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"platform/pkg/env"
|
"platform/pkg/env"
|
||||||
auth2 "platform/web/auth"
|
auth2 "platform/web/auth"
|
||||||
"platform/web/core"
|
"platform/web/core"
|
||||||
"platform/web/globals"
|
"platform/web/globals"
|
||||||
"platform/web/handlers"
|
"platform/web/handlers"
|
||||||
"strings"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
q "platform/web/queries"
|
q "platform/web/queries"
|
||||||
@@ -51,46 +49,6 @@ func ApplyRouters(app *fiber.App) {
|
|||||||
}
|
}
|
||||||
return ctx.JSON(resp)
|
return ctx.JSON(resp)
|
||||||
})
|
})
|
||||||
debug.Get("/gen-edge", func(ctx *fiber.Ctx) error {
|
|
||||||
areas, err := q.Area.Where(q.Area.Level.Eq(2)).Find()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
sb := strings.Builder{}
|
|
||||||
sb.WriteString("INSERT INTO edge (type, version, mac, ip, port, isp, area_id, status) VALUES\n")
|
|
||||||
|
|
||||||
for i, area := range areas {
|
|
||||||
// jh edges
|
|
||||||
for j := range 20 {
|
|
||||||
fmt.Fprintf(&sb, "(2, 1, 'jh-%d-%d-%d', '192.168.50.%d', %d, 0, %d, 1)", area.ID, j+1, i+44001, j+2, i+44001, area.ID)
|
|
||||||
sb.WriteString(",\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
// jg edges
|
|
||||||
for j := range 10 {
|
|
||||||
var ip string
|
|
||||||
var n int
|
|
||||||
if i < 100 {
|
|
||||||
ip = "192.168.0.232"
|
|
||||||
n = 1
|
|
||||||
} else if i < 200 {
|
|
||||||
ip = "192.168.59.236"
|
|
||||||
n = 2
|
|
||||||
} else {
|
|
||||||
ip = "192.168.59.237"
|
|
||||||
n = 3
|
|
||||||
}
|
|
||||||
fmt.Fprintf(&sb, "(2, 1, 'jg-%d-%d-%d', '%s', %d, 0, %d, 1)", area.ID, n, i*10+j+20001, ip, i*10+j+20001, area.ID)
|
|
||||||
if i < len(areas)-1 || j < 9 {
|
|
||||||
sb.WriteString(",\n")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sb.WriteString(";\n")
|
|
||||||
return ctx.SendString(sb.String())
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,6 +40,10 @@ type channelServer struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *channelServer) CreateChannels(source netip.Addr, resourceNo string, authWhitelist bool, authPassword bool, count int, edgeFilter *EdgeFilter) ([]*m.Channel, error) {
|
func (s *channelServer) CreateChannels(source netip.Addr, resourceNo string, authWhitelist bool, authPassword bool, count int, edgeFilter *EdgeFilter) ([]*m.Channel, error) {
|
||||||
|
if edgeFilter == nil {
|
||||||
|
edgeFilter = &EdgeFilter{}
|
||||||
|
}
|
||||||
|
|
||||||
var area *m.Area
|
var area *m.Area
|
||||||
if edgeFilter.AreaID != nil {
|
if edgeFilter.AreaID != nil {
|
||||||
var err error
|
var err error
|
||||||
@@ -265,8 +269,8 @@ func persistChannelCreate(ctx *channelCreateContext, channels []*m.Channel) erro
|
|||||||
BatchNo: ctx.BatchNo,
|
BatchNo: ctx.BatchNo,
|
||||||
Count: int32(ctx.Count),
|
Count: int32(ctx.Count),
|
||||||
ISP: u.X(ctx.Filter.Isp.String()),
|
ISP: u.X(ctx.Filter.Isp.String()),
|
||||||
Prov: prov,
|
Prov: u.Ternary(ctx.Filter.AreaID != nil, prov, nil),
|
||||||
City: city,
|
City: u.Ternary(ctx.Filter.AreaID != nil, city, nil),
|
||||||
IP: orm.Inet{Addr: ctx.Source},
|
IP: orm.Inet{Addr: ctx.Source},
|
||||||
Time: ctx.Now,
|
Time: ctx.Now,
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import (
|
|||||||
q "platform/web/queries"
|
q "platform/web/queries"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"gorm.io/gen"
|
"gorm.io/gen/field"
|
||||||
)
|
)
|
||||||
|
|
||||||
type channelGostProvider struct{}
|
type channelGostProvider struct{}
|
||||||
@@ -37,7 +37,7 @@ func (s *channelGostProvider) prepareCreate(ctx *channelCreateContext) (*channel
|
|||||||
serviceName := gostServiceName(ctx.BatchNo, port)
|
serviceName := gostServiceName(ctx.BatchNo, port)
|
||||||
channel := newBaseChannel(ctx, port)
|
channel := newBaseChannel(ctx, port)
|
||||||
channel.EdgeID = u.P(edge.ID)
|
channel.EdgeID = u.P(edge.ID)
|
||||||
channel.EdgeRef = u.P(serviceName)
|
channel.EdgeRef = u.P(edge.Mac)
|
||||||
channel.IP = u.P(edge.IP)
|
channel.IP = u.P(edge.IP)
|
||||||
|
|
||||||
service := &g.GostServiceConfig{
|
service := &g.GostServiceConfig{
|
||||||
@@ -141,40 +141,34 @@ func (s *channelGostProvider) selectEdge(filter *EdgeFilter, area *m.Area, count
|
|||||||
filter = &EdgeFilter{}
|
filter = &EdgeFilter{}
|
||||||
}
|
}
|
||||||
|
|
||||||
conds := []gen.Condition{
|
do := q.Edge.Where(
|
||||||
q.Edge.Type.Eq(int(m.EdgeTypeGostChain)),
|
q.Edge.Type.Eq(int(m.EdgeTypeGostChain)),
|
||||||
q.Edge.Status.Eq(int(m.EdgeStatusNormal)),
|
q.Edge.Status.Eq(int(m.EdgeStatusNormal)),
|
||||||
|
)
|
||||||
|
if filter.Isp != nil {
|
||||||
|
do = do.Where(q.Edge.ISP.In(int(m.EdgeISPUnknown), int(*filter.Isp)))
|
||||||
}
|
}
|
||||||
if isp := u.X(filter.Isp.String()); isp != nil {
|
|
||||||
conds = append(conds, q.Edge.ISP.Eq(int(*filter.Isp)))
|
|
||||||
}
|
|
||||||
|
|
||||||
query := q.Edge.Where(conds...)
|
|
||||||
if area != nil {
|
if area != nil {
|
||||||
switch area.Level {
|
switch area.Level {
|
||||||
case m.AreaLevelProvince:
|
case m.AreaLevelProvince:
|
||||||
edgeArea := q.Area.As("EdgeArea")
|
edgeArea := q.Area.As("EdgeArea")
|
||||||
query = query.
|
do = do.
|
||||||
Join(edgeArea, edgeArea.ID.EqCol(q.Edge.AreaID)).
|
Where(edgeArea.ParentID.Eq(area.ID)).
|
||||||
Where(edgeArea.ParentID.Eq(area.ID))
|
Join(edgeArea, edgeArea.ID.EqCol(q.Edge.AreaID))
|
||||||
case m.AreaLevelCity:
|
case m.AreaLevelCity:
|
||||||
query = query.Where(q.Edge.AreaID.Eq(area.ID))
|
do = do.Where(q.Edge.AreaID.Eq(area.ID))
|
||||||
default:
|
default:
|
||||||
return nil, core.NewBizErr("地区层级不支持")
|
return nil, core.NewBizErr("地区层级不支持")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
edges, err := query.
|
edges, err := do.
|
||||||
Order(q.Edge.ID).
|
Order(field.NewUnsafeFieldRaw("random()")).
|
||||||
Limit(count).
|
Limit(count).
|
||||||
Find()
|
Find()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, core.NewBizErr("查询可用节点失败", err)
|
return nil, core.NewBizErr("查询可用节点失败", err)
|
||||||
}
|
}
|
||||||
return expandGostEdges(edges, count)
|
|
||||||
}
|
|
||||||
|
|
||||||
func expandGostEdges(edges []*m.Edge, count int) ([]*m.Edge, error) {
|
|
||||||
if len(edges) == 0 {
|
if len(edges) == 0 {
|
||||||
return nil, core.NewBizErr("地区可用节点数量不足")
|
return nil, core.NewBizErr("地区可用节点数量不足")
|
||||||
}
|
}
|
||||||
@@ -183,6 +177,7 @@ func expandGostEdges(edges []*m.Edge, count int) ([]*m.Edge, error) {
|
|||||||
for i := range count {
|
for i := range count {
|
||||||
result[i] = edges[i%len(edges)]
|
result[i] = edges[i%len(edges)]
|
||||||
}
|
}
|
||||||
|
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user