From 63631d6cdfa89f55f00e4e25609d5be42f07acbb Mon Sep 17 00:00:00 2001 From: ZacharyZcR Date: Sat, 13 Jun 2026 21:42:49 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E6=89=80=E6=9C=89UDP=E6=8F=92=E4=BB=B6?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0ReadDeadline=E9=98=B2=E6=AD=A2=E6=97=A0?= =?UTF-8?q?=E9=99=90=E9=98=BB=E5=A1=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SNMP/BACnet/DNS/IPMI/TFTP 的 conn.Read() 在目标不响应时 无限阻塞(goroutine 泄漏),导致整个扫描无法结束。 在 Write 前设置 ReadDeadline 确保超时后返回。 --- plugins/services/bacnet.go | 4 ++++ plugins/services/dns.go | 4 ++++ plugins/services/ipmi.go | 4 ++++ plugins/services/snmp.go | 4 ++++ plugins/services/tftp.go | 4 ++++ 5 files changed, 20 insertions(+) diff --git a/plugins/services/bacnet.go b/plugins/services/bacnet.go index 949cba8..f3a4fa2 100644 --- a/plugins/services/bacnet.go +++ b/plugins/services/bacnet.go @@ -34,6 +34,10 @@ func (p *BACnetPlugin) Scan(ctx context.Context, info *common.HostInfo, session } defer conn.Close() + if dl, ok := conn.(interface{ SetReadDeadline(time.Time) error }); ok { + _ = dl.SetReadDeadline(time.Now().Add(timeout)) + } + if _, err := conn.Write(bacnetWhoIs); err != nil { return &ScanResult{Success: false, Service: "bacnet"} } diff --git a/plugins/services/dns.go b/plugins/services/dns.go index a247d0d..a02285d 100644 --- a/plugins/services/dns.go +++ b/plugins/services/dns.go @@ -34,6 +34,10 @@ func (p *DNSPlugin) Scan(ctx context.Context, info *common.HostInfo, session *co } defer conn.Close() + if dl, ok := conn.(interface{ SetReadDeadline(time.Time) error }); ok { + _ = dl.SetReadDeadline(time.Now().Add(timeout)) + } + if _, err := conn.Write(query); err != nil { return &ScanResult{Success: false, Service: "dns"} } diff --git a/plugins/services/ipmi.go b/plugins/services/ipmi.go index fe32eaf..e027489 100644 --- a/plugins/services/ipmi.go +++ b/plugins/services/ipmi.go @@ -53,6 +53,10 @@ func (p *IPMIPlugin) rmcpPing(ctx context.Context, target string, timeout time.D 0x00, // data length = 0 } + if dl, ok := conn.(interface{ SetReadDeadline(time.Time) error }); ok { + _ = dl.SetReadDeadline(time.Now().Add(timeout)) + } + if _, err := conn.Write(ping); err != nil { return nil } diff --git a/plugins/services/snmp.go b/plugins/services/snmp.go index 0686575..b75f09c 100644 --- a/plugins/services/snmp.go +++ b/plugins/services/snmp.go @@ -75,6 +75,10 @@ func (p *SNMPPlugin) probe(ctx context.Context, target, community string, timeou } defer conn.Close() + if dl, ok := conn.(interface{ SetReadDeadline(time.Time) error }); ok { + _ = dl.SetReadDeadline(time.Now().Add(timeout)) + } + pkt := buildSNMPGetRequest(community, []int{1, 3, 6, 1, 2, 1, 1, 1, 0}) if _, err := conn.Write(pkt); err != nil { return nil diff --git a/plugins/services/tftp.go b/plugins/services/tftp.go index 000b211..f3cf0ed 100644 --- a/plugins/services/tftp.go +++ b/plugins/services/tftp.go @@ -33,6 +33,10 @@ func (p *TFTPPlugin) Scan(ctx context.Context, info *common.HostInfo, session *c } defer conn.Close() + if dl, ok := conn.(interface{ SetReadDeadline(time.Time) error }); ok { + _ = dl.SetReadDeadline(time.Now().Add(timeout)) + } + if _, err := conn.Write(buildTFTPReadRequest("probe")); err != nil { return &ScanResult{Success: false, Service: "tftp"} }