diff --git a/p2p/discovery/mdns/mdns.go b/p2p/discovery/mdns/mdns.go index 54e6989a7f..646b7f1f0b 100644 --- a/p2p/discovery/mdns/mdns.go +++ b/p2p/discovery/mdns/mdns.go @@ -93,13 +93,18 @@ func (s *mdnsService) Start() error { case evt := <-ipEvt.Out(): if _, ok := evt.(event.EvtLocalAddressesUpdated); ok { s.mu.Lock() + s.ctxCancel() if s.server != nil { s.server.Shutdown() s.server = nil } + s.resolverWG.Wait() + s.ctx, s.ctxCancel = context.WithCancel(context.Background()) + s.startResolver(s.ctx) if err = s.startServer(); err != nil { log.Errorf("failed to restart mdns server: %s", err) } + s.mu.Unlock() } } diff --git a/p2p/discovery/mdns/mdns_test.go b/p2p/discovery/mdns/mdns_test.go index a2462790d3..270788dd64 100644 --- a/p2p/discovery/mdns/mdns_test.go +++ b/p2p/discovery/mdns/mdns_test.go @@ -1,6 +1,8 @@ package mdns import ( + "github.com/libp2p/go-libp2p/core/event" + "github.com/libp2p/go-libp2p/core/host" "sync" "testing" "time" @@ -96,3 +98,38 @@ func TestOtherDiscovery(t *testing.T) { "expected peers to find each other", ) } + +func setupHost(t *testing.T) (host.Host, *notif) { + t.Helper() + + h, err := libp2p.New(libp2p.ListenAddrStrings("/ip4/127.0.0.1/tcp/0")) + require.NoError(t, err) + + notif := ¬if{} + + s := NewMdnsService(h, "", notif) + require.NoError(t, s.Start()) + + return h, notif +} + +func TestMdnsServiceIpChange(t *testing.T) { + + host1, notif1 := setupHost(t) + defer host1.Close() + + ipEvt, err := host1.EventBus().Emitter(new(event.EvtLocalAddressesUpdated)) + require.NoError(t, err) + + err = ipEvt.Emit(event.EvtLocalAddressesUpdated{}) + require.NoError(t, err) + + time.Sleep(2 * time.Second) // wait for host1 to restart mdns server + + host2, notif2 := setupHost(t) + defer host2.Close() + + assert.Eventually(t, func() bool { + return len(notif1.GetPeers()) == 1 && len(notif2.GetPeers()) == 1 + }, 5*time.Second, 5*time.Millisecond) +}