diff --git a/src/core/options.go b/src/core/options.go index ffbdae73..581c033b 100644 --- a/src/core/options.go +++ b/src/core/options.go @@ -13,7 +13,15 @@ func (c *Core) _applyOption(opt SetupOption) (err error) { if err != nil { return fmt.Errorf("unable to parse peering URI: %w", err) } - return c.links.add(u, v.SourceInterface, linkTypePersistent) + err = c.links.add(u, v.SourceInterface, linkTypePersistent) + switch err { + case ErrLinkAlreadyConfigured: + // Don't return this error, otherwise we'll panic at startup + // if there are multiple of the same peer configured + return nil + default: + return err + } case ListenAddress: c.config._listeners[v] = struct{}{} case NodeInfo: diff --git a/src/core/options_test.go b/src/core/options_test.go new file mode 100644 index 00000000..bab22fb1 --- /dev/null +++ b/src/core/options_test.go @@ -0,0 +1,41 @@ +package core + +import ( + "net/url" + "testing" + + "github.com/yggdrasil-network/yggdrasil-go/src/config" +) + +// Tests that duplicate peers in the configuration file +// won't cause an error when the node starts. Otherwise +// we can panic unnecessarily. +func TestDuplicatePeerAtStartup(t *testing.T) { + cfg := config.GenerateConfig() + for i := 0; i < 5; i++ { + cfg.Peers = append(cfg.Peers, "tcp://1.2.3.4:4321") + } + if _, err := New(cfg.Certificate, nil); err != nil { + t.Fatal(err) + } +} + +// Tests that duplicate peers given to us through the +// API will still error as expected, even if they didn't +// at startup. We expect to notify the user through the +// admin socket if they try to add a peer that is already +// configured. +func TestDuplicatePeerFromAPI(t *testing.T) { + cfg := config.GenerateConfig() + c, err := New(cfg.Certificate, nil) + if err != nil { + t.Fatal(err) + } + u, _ := url.Parse("tcp://1.2.3.4:4321") + if err := c.AddPeer(u, ""); err != nil { + t.Fatalf("Adding peer failed on first attempt: %s", err) + } + if err := c.AddPeer(u, ""); err == nil { + t.Fatalf("Adding peer should have failed on second attempt") + } +}