google / gopacket

Provides packet processing capabilities for Go
BSD 3-Clause "New" or "Revised" License
6.35k stars 1.14k forks source link

PacketSource ReClose Error #1189

Open tongchengbin opened 1 month ago

tongchengbin commented 1 month ago

I want to create a temporary source and close it after use. The handle needs to be used for a longer period of time, but after I finally close the handle, it results in the source channel being closed multiple times.

func TestSourceClose(t *testing.T) {
    h, err := pcap.OpenLive("\\Device\\NPF_Loopback", 65536, false, time.Second*3)
    assert.Equal(t, nil, err)
    source := gopacket.NewPacketSource(h, nil)
    go func() {
        for _ = range source.Packets() {
            continue
        }
        println("done")

    }()
    close(source.Packets())
    source2 := gopacket.NewPacketSource(h, nil)
    go func() {
        for _ = range source2.Packets() {
            continue
        }
        println("done2")
    }()
    time.Sleep(1 * time.Second)
    h.Close()

}
panic: send on closed channel

goroutine 18 [running]:
github.com/google/gopacket.(*PacketSource).packetsToChannel(0xc0000215c0)
    D:/code/github.com/gopacket/packet.go:820 +0xb3
created by github.com/google/gopacket.(*PacketSource).Packets in goroutine 7
    D:/code/github.com/gopacket/packet.go:861 +0x98
panic: send on closed channel
    panic: close of closed channel

goroutine 8 [running]:
github.com/google/gopacket.(*PacketSource).packetsToChannel(0xc0000215c0)
    D:/code/github.com/gopacket/packet.go:820 +0xb3
created by github.com/google/gopacket.(*PacketSource).Packets in goroutine 6
    D:/code/github.com/gopacket/packet.go:861 +0x98
Surya-7890 commented 3 weeks ago

I see that you are closing the channel here "close(source.Packets())", like this.

You are closing the channel right after the go routine. Try using defer in your code.

defer close(source.Packets()) 

This way the channel will only be closed, when the function completes its execution (function returns).