Skip to content
This repository has been archived by the owner on May 26, 2022. It is now read-only.

Commit

Permalink
fix listen addrs race
Browse files Browse the repository at this point in the history
Copy the listen address list before returning it.

If you're wondering about the syntax:
https://github.com/go101/go101/wiki/How-to-perfectly-clone-a-slice%3F
  • Loading branch information
Stebalien committed Aug 21, 2019
1 parent 4a42085 commit 682bcc8
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 3 deletions.
6 changes: 3 additions & 3 deletions swarm_addr.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ func (s *Swarm) InterfaceListenAddresses() ([]ma.Multiaddr, error) {
s.listeners.RUnlock() // RLock end

if ifaceListenAddres != nil && !isEOL {
// Cache is valid
return ifaceListenAddres, nil
// Cache is valid, clone the slice
return append(ifaceListenAddres[:0:0], ifaceListenAddres...), nil
}

// Cache is not valid
Expand Down Expand Up @@ -64,5 +64,5 @@ func (s *Swarm) InterfaceListenAddresses() ([]ma.Multiaddr, error) {

s.listeners.Unlock() // Lock end

return ifaceListenAddres, nil
return append(ifaceListenAddres[:0:0], ifaceListenAddres...), nil
}
18 changes: 18 additions & 0 deletions swarm_addr_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,21 @@ func TestDialBadAddrs(t *testing.T) {
test(m("/ip6/fe80::100")) // link local
test(m("/ip4/127.0.0.1/udp/1234/utp")) // utp
}

func TestAddrRace(t *testing.T) {
ctx := context.Background()
s := makeSwarms(ctx, t, 1)[0]

a1, err := s.InterfaceListenAddresses()
if err != nil {
t.Fatal(err)
}
a2, err := s.InterfaceListenAddresses()
if err != nil {
t.Fatal(err)
}

if len(a1) > 0 && len(a2) > 0 && &a1[0] == &a2[0] {
t.Fatal("got the exact same address set twice; this could lead to data races")
}
}

0 comments on commit 682bcc8

Please sign in to comment.