From 6d8a8c4e2f000d948276eb6b0be1763e48a17050 Mon Sep 17 00:00:00 2001 From: nite Date: Thu, 5 Feb 2026 15:24:16 +0800 Subject: [PATCH] fix: auto accept block ask process --- internal/discovery/service.go | 64 +++++++++++++++++++++++++++++++++++ internal/transfer/client.go | 27 ++++++++------- internal/transfer/model.go | 41 +++++++++++++++++++--- internal/transfer/server.go | 4 +-- 4 files changed, 118 insertions(+), 18 deletions(-) diff --git a/internal/discovery/service.go b/internal/discovery/service.go index 2b90045..557bb06 100644 --- a/internal/discovery/service.go +++ b/internal/discovery/service.go @@ -45,6 +45,70 @@ func NewService(config *config.Config, app *application.App, port int) *Service } } +func (s *Service) GetLocalIPs() ([]string, bool) { + interfaces, err := net.Interfaces() + if err != nil { + slog.Error("Failed to get network interfaces", "error", err, "component", "discovery") + return nil, false + } + var ips []string + for _, iface := range interfaces { + // 过滤掉 Down 的接口和 Loopback 接口 + if iface.Flags&net.FlagUp == 0 || iface.Flags&net.FlagLoopback != 0 { + continue + } + // 获取该接口的地址 + addrs, err := iface.Addrs() + if err != nil { + continue + } + for _, addr := range addrs { + ip, _, err := net.ParseCIDR(addr.String()) + if err != nil { + continue + } + if ip.To4() == nil { + continue + } + ips = append(ips, ip.String()) + } + } + return ips, true +} + +func (s *Service) GetLocalIPInSameSubnet(receiverIP string) (string, bool) { + interfaces, err := net.Interfaces() + if err != nil { + slog.Error("Failed to get network interfaces", "error", err, "component", "discovery") + return "", false + } + for _, iface := range interfaces { + // 过滤掉 Down 的接口和 Loopback 接口 + if iface.Flags&net.FlagUp == 0 || iface.Flags&net.FlagLoopback != 0 { + continue + } + // 获取该接口的地址 + addrs, err := iface.Addrs() + if err != nil { + continue + } + for _, addr := range addrs { + ip, ipNet, err := net.ParseCIDR(addr.String()) + if err != nil { + continue + } + if ip.To4() == nil { + continue + } + if ipNet.Contains(net.ParseIP(receiverIP)) { + return ip.String(), true + } + } + } + slog.Error("Failed to get local IP in same subnet", "receiverIP", receiverIP, "component", "discovery") + return "", false +} + func (s *Service) startBroadcasting() { ticker := time.NewTicker(HeartbeatRate) for range ticker.C { diff --git a/internal/transfer/client.go b/internal/transfer/client.go index b644d03..a29786c 100644 --- a/internal/transfer/client.go +++ b/internal/transfer/client.go @@ -44,10 +44,11 @@ func (s *Service) SendFile(target *discovery.Peer, targetIP string, filePath str task := NewTransfer( taskID, - Sender{ - ID: s.discoveryService.GetID(), - Name: s.config.GetHostName(), - }, + NewSender( + s.discoveryService.GetID(), + s.config.GetHostName(), + WithReceiverIP(targetIP, s.discoveryService), + ), WithFileName(filepath.Base(filePath)), WithFileSize(stat.Size()), WithType(TransferTypeSend), @@ -105,10 +106,11 @@ func (s *Service) SendFolder(target *discovery.Peer, targetIP string, folderPath task := NewTransfer( taskID, - Sender{ - ID: s.discoveryService.GetID(), - Name: s.config.GetHostName(), - }, + NewSender( + s.discoveryService.GetID(), + s.config.GetHostName(), + WithReceiverIP(targetIP, s.discoveryService), + ), WithFileName(filepath.Base(folderPath)), WithFileSize(size), WithType(TransferTypeSend), @@ -152,10 +154,11 @@ func (s *Service) SendText(target *discovery.Peer, targetIP string, text string) r := bytes.NewReader([]byte(text)) task := NewTransfer( taskID, - Sender{ - ID: s.discoveryService.GetID(), - Name: s.config.GetHostName(), - }, + NewSender( + s.discoveryService.GetID(), + s.config.GetHostName(), + WithReceiverIP(targetIP, s.discoveryService), + ), WithFileSize(int64(len(text))), WithType(TransferTypeSend), WithContentType(ContentTypeText), diff --git a/internal/transfer/model.go b/internal/transfer/model.go index a25bcb9..71a3be7 100644 --- a/internal/transfer/model.go +++ b/internal/transfer/model.go @@ -1,6 +1,8 @@ package transfer import ( + "log/slog" + "mesh-drop/internal/discovery" "time" ) @@ -53,10 +55,11 @@ type TransferOption func(*Transfer) func NewTransfer(id string, sender Sender, opts ...TransferOption) *Transfer { t := &Transfer{ - ID: id, - CreateTime: time.Now().UnixMilli(), - Sender: sender, - Status: TransferStatusPending, // Default status + ID: id, + CreateTime: time.Now().UnixMilli(), + Sender: sender, + Status: TransferStatusPending, // Default status + DecisionChan: make(chan Decision, 1), } for _, opt := range opts { @@ -123,6 +126,36 @@ func WithToken(token string) TransferOption { type Sender struct { ID string `json:"id" binding:"required"` // 发送者 ID Name string `json:"name" binding:"required"` // 发送者名称 + IP string `json:"ip" binding:"required"` // 发送者 IP +} + +type NewSenderOption func(*Sender) + +func NewSender(id string, name string, opts ...NewSenderOption) Sender { + s := &Sender{ + ID: id, + Name: name, + } + for _, opt := range opts { + opt(s) + } + return *s +} + +func WithIP(ip string) NewSenderOption { + return func(s *Sender) { + s.IP = ip + } +} + +func WithReceiverIP(ip string, discoveryService *discovery.Service) NewSenderOption { + return func(s *Sender) { + ip, ok := discoveryService.GetLocalIPInSameSubnet(ip) + if !ok { + slog.Error("Failed to get local IP in same subnet", "ip", ip, "component", "transfer-client") + } + s.IP = ip + } } // Progress 用户前端传输进度 diff --git a/internal/transfer/server.go b/internal/transfer/server.go index 5801b34..59d658a 100644 --- a/internal/transfer/server.go +++ b/internal/transfer/server.go @@ -40,7 +40,6 @@ func (s *Service) handleAsk(c *gin.Context) { // 存储请求 task.Type = TransferTypeReceive task.Status = TransferStatusPending - task.DecisionChan = make(chan Decision) s.StoreTransferToList(&task) if s.config.GetAutoAccept() { @@ -50,10 +49,11 @@ func (s *Service) handleAsk(c *gin.Context) { SavePath: s.config.GetSavePath(), } } else { + // 发送系统通知 _ = s.notifier.SendNotification(notifications.NotificationOptions{ ID: uuid.New().String(), Title: "File Transfer Request", - Body: fmt.Sprintf("%s wants to transfer %s", task.Sender, task.FileName), + Body: fmt.Sprintf("%s(%s) wants to transfer %s", task.Sender.Name, task.Sender.IP, task.FileName), }) }