schollz / peerdiscovery

Pure-Go library for cross-platform local peer discovery using UDP multicast :woman: :repeat: :woman:
MIT License
638 stars 55 forks source link

Port doesn't get closed upon discovery complete #26

Closed maddie closed 2 years ago

maddie commented 3 years ago

I've wrapped the Discover function like this:

func Discover() {
    info := make(map[string]string)
    info["name"] = "device"
    info["id"] = "1"
    info["address"] = ip

    b, _ := json.Marshal(&info)

    for {
        _, err := peerdiscovery.Discover(peerdiscovery.Settings{
            Limit:   -1,
            Payload: b,
            Notify: func(d peerdiscovery.Discovered) {
                // save the discovered nodes into memory
            },
        })
        if err != nil {
            log.Errorf("Error trying to discover peers: %s", err)
        }
        time.Sleep(5 * time.Second)
    }
}

If I'm understanding the Settings correctly, this should discover for 10 secs (default) for unlimited nodes, exits, and restart in 5 secs.

But what I'm seeing here is that after the discovery completes, there's a lot of listeners on port 9999 (default):

$ sudo lsof -i:9999 -n -P | wc -l
1041

Is there a way to close these listeners after the function is finished?

EDIT: The reason I'm running this in a loop is that if I set the time limit to -1, it works for some time; if the network changes, it will just stop discovering/being discovered altogether. So I figured maybe I'll just let it run periodically for 10 secs.

maddie commented 3 years ago

I think I've found the problem:

https://github.com/maddie/peerdiscovery/blob/8e53523cb7128edc0a2e286fe20642872dd0a125/peerdiscovery.go#L305-L384

I've set the limit to -1, so the break statement will never reach; and somehow p2.ReadFrom never returned error, so the return statement never reached either, and there goes the dangling listener.

Was this done by purpose, or is it just a case not tested/handled?

EDIT: Tested on both Linux (Ubuntu 20.04 x64) and macOS Big Sur, both are having the same problem.