mirror of
				https://github.com/TeaOSLab/EdgeNode.git
				synced 2025-11-04 16:00:25 +08:00 
			
		
		
		
	
		
			
	
	
		
			125 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
		
		
			
		
	
	
			125 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| 
								 | 
							
								package iplibrary
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								import (
							 | 
						|||
| 
								 | 
							
									"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
							 | 
						|||
| 
								 | 
							
									"github.com/TeaOSLab/EdgeNode/internal/events"
							 | 
						|||
| 
								 | 
							
									"github.com/TeaOSLab/EdgeNode/internal/logs"
							 | 
						|||
| 
								 | 
							
									"github.com/TeaOSLab/EdgeNode/internal/rpc"
							 | 
						|||
| 
								 | 
							
									"github.com/iwind/TeaGo/Tea"
							 | 
						|||
| 
								 | 
							
									"sync"
							 | 
						|||
| 
								 | 
							
									"time"
							 | 
						|||
| 
								 | 
							
								)
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								var SharedIPListManager = NewIPListManager()
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								func init() {
							 | 
						|||
| 
								 | 
							
									events.On(events.EventStart, func() {
							 | 
						|||
| 
								 | 
							
										go SharedIPListManager.Start()
							 | 
						|||
| 
								 | 
							
									})
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								// IP名单管理
							 | 
						|||
| 
								 | 
							
								type IPListManager struct {
							 | 
						|||
| 
								 | 
							
									// 缓存文件
							 | 
						|||
| 
								 | 
							
									// 每行一个数据:id|from|to|expiredAt
							 | 
						|||
| 
								 | 
							
									cacheFile string
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									version  int64
							 | 
						|||
| 
								 | 
							
									pageSize int64
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									listMap map[int64]*IPList
							 | 
						|||
| 
								 | 
							
									locker  sync.Mutex
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								func NewIPListManager() *IPListManager {
							 | 
						|||
| 
								 | 
							
									return &IPListManager{
							 | 
						|||
| 
								 | 
							
										cacheFile: Tea.Root + "/configs/ip_list.cache",
							 | 
						|||
| 
								 | 
							
										pageSize:  1000,
							 | 
						|||
| 
								 | 
							
										listMap:   map[int64]*IPList{},
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								func (this *IPListManager) Start() {
							 | 
						|||
| 
								 | 
							
									// TODO 从缓存当中读取数据
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									// 第一次读取
							 | 
						|||
| 
								 | 
							
									err := this.loop()
							 | 
						|||
| 
								 | 
							
									if err != nil {
							 | 
						|||
| 
								 | 
							
										logs.Println("IP_LIST_MANAGER", err.Error())
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									ticker := time.NewTicker(60 * time.Second) // TODO 未来改成可以手动触发IP变更事件
							 | 
						|||
| 
								 | 
							
									events.On(events.EventQuit, func() {
							 | 
						|||
| 
								 | 
							
										ticker.Stop()
							 | 
						|||
| 
								 | 
							
									})
							 | 
						|||
| 
								 | 
							
									for range ticker.C {
							 | 
						|||
| 
								 | 
							
										err := this.loop()
							 | 
						|||
| 
								 | 
							
										if err != nil {
							 | 
						|||
| 
								 | 
							
											logs.Println("IP_LIST_MANAGER", err.Error())
							 | 
						|||
| 
								 | 
							
										}
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								func (this *IPListManager) loop() error {
							 | 
						|||
| 
								 | 
							
									for {
							 | 
						|||
| 
								 | 
							
										hasNext, err := this.fetch()
							 | 
						|||
| 
								 | 
							
										if err != nil {
							 | 
						|||
| 
								 | 
							
											return err
							 | 
						|||
| 
								 | 
							
										}
							 | 
						|||
| 
								 | 
							
										if !hasNext {
							 | 
						|||
| 
								 | 
							
											break
							 | 
						|||
| 
								 | 
							
										}
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									// TODO 写入到缓存当中
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									return nil
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								func (this *IPListManager) fetch() (hasNext bool, err error) {
							 | 
						|||
| 
								 | 
							
									rpcClient, err := rpc.SharedRPC()
							 | 
						|||
| 
								 | 
							
									if err != nil {
							 | 
						|||
| 
								 | 
							
										return false, err
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
									itemsResp, err := rpcClient.IPItemRPC().ListIPItemsAfterVersion(rpcClient.Context(), &pb.ListIPItemsAfterVersionRequest{
							 | 
						|||
| 
								 | 
							
										Version: this.version,
							 | 
						|||
| 
								 | 
							
										Size:    this.pageSize,
							 | 
						|||
| 
								 | 
							
									})
							 | 
						|||
| 
								 | 
							
									if err != nil {
							 | 
						|||
| 
								 | 
							
										return false, err
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
									items := itemsResp.IpItems
							 | 
						|||
| 
								 | 
							
									if len(items) == 0 {
							 | 
						|||
| 
								 | 
							
										return false, nil
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
									this.locker.Lock()
							 | 
						|||
| 
								 | 
							
									for _, item := range items {
							 | 
						|||
| 
								 | 
							
										list, ok := this.listMap[item.ListId]
							 | 
						|||
| 
								 | 
							
										if !ok {
							 | 
						|||
| 
								 | 
							
											list = NewIPList()
							 | 
						|||
| 
								 | 
							
											this.listMap[item.ListId] = list
							 | 
						|||
| 
								 | 
							
										}
							 | 
						|||
| 
								 | 
							
										if item.IsDeleted {
							 | 
						|||
| 
								 | 
							
											list.Delete(item.Id)
							 | 
						|||
| 
								 | 
							
											continue
							 | 
						|||
| 
								 | 
							
										}
							 | 
						|||
| 
								 | 
							
										list.Add(&IPItem{
							 | 
						|||
| 
								 | 
							
											Id:        item.Id,
							 | 
						|||
| 
								 | 
							
											IPFrom:    IP2Long(item.IpFrom),
							 | 
						|||
| 
								 | 
							
											IPTo:      IP2Long(item.IpTo),
							 | 
						|||
| 
								 | 
							
											ExpiredAt: item.ExpiredAt,
							 | 
						|||
| 
								 | 
							
										})
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
									this.locker.Unlock()
							 | 
						|||
| 
								 | 
							
									this.version = items[len(items)-1].Version
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									return true, nil
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								func (this *IPListManager) FindList(listId int64) *IPList {
							 | 
						|||
| 
								 | 
							
									this.locker.Lock()
							 | 
						|||
| 
								 | 
							
									list, _ := this.listMap[listId]
							 | 
						|||
| 
								 | 
							
									this.locker.Unlock()
							 | 
						|||
| 
								 | 
							
									return list
							 | 
						|||
| 
								 | 
							
								}
							 |