Skip to content

Commit d7ba372

Browse files
authored
swarm: add ListenClose (#1586)
* feat(swarm): add ListenClose * fix(swarm): fix ListenClose behavior * refactor(swarm): move the listener's closing log
1 parent e6379f5 commit d7ba372

File tree

2 files changed

+60
-7
lines changed

2 files changed

+60
-7
lines changed

p2p/net/swarm/swarm_listen.go

+41-7
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"time"
66

77
"github.com/libp2p/go-libp2p-core/network"
8+
"github.com/libp2p/go-libp2p-core/transport"
89

910
ma "github.com/multiformats/go-multiaddr"
1011
)
@@ -35,6 +36,27 @@ func (s *Swarm) Listen(addrs ...ma.Multiaddr) error {
3536
return nil
3637
}
3738

39+
// ListenClose stop and delete listeners for all of the given addresses.
40+
func (s *Swarm) ListenClose(addrs ...ma.Multiaddr) {
41+
var listenersToClose []transport.Listener
42+
43+
s.listeners.Lock()
44+
for l := range s.listeners.m {
45+
if !containsMultiaddr(addrs, l.Multiaddr()) {
46+
continue
47+
}
48+
49+
delete(s.listeners.m, l)
50+
listenersToClose = append(listenersToClose, l)
51+
}
52+
s.listeners.cacheEOL = time.Time{}
53+
s.listeners.Unlock()
54+
55+
for _, l := range listenersToClose {
56+
l.Close()
57+
}
58+
}
59+
3860
// AddListenAddr tells the swarm to listen on a single address. Unlike Listen,
3961
// this method does not attempt to filter out bad addresses.
4062
func (s *Swarm) AddListenAddr(a ma.Multiaddr) error {
@@ -78,12 +100,19 @@ func (s *Swarm) AddListenAddr(a ma.Multiaddr) error {
78100

79101
go func() {
80102
defer func() {
81-
list.Close()
82103
s.listeners.Lock()
83-
delete(s.listeners.m, list)
84-
s.listeners.cacheEOL = time.Time{}
104+
_, ok := s.listeners.m[list]
105+
if ok {
106+
delete(s.listeners.m, list)
107+
s.listeners.cacheEOL = time.Time{}
108+
}
85109
s.listeners.Unlock()
86110

111+
if ok {
112+
list.Close()
113+
log.Errorf("swarm listener unintentionally closed")
114+
}
115+
87116
// signal to our notifiees on listen close.
88117
s.notifyAll(func(n network.Notifiee) {
89118
n.ListenClose(s, maddr)
@@ -93,10 +122,6 @@ func (s *Swarm) AddListenAddr(a ma.Multiaddr) error {
93122
for {
94123
c, err := list.Accept()
95124
if err != nil {
96-
if s.ctx.Err() == nil {
97-
// only log if the swarm is still running.
98-
log.Errorf("swarm listener accept error: %s", err)
99-
}
100125
return
101126
}
102127

@@ -119,3 +144,12 @@ func (s *Swarm) AddListenAddr(a ma.Multiaddr) error {
119144
}()
120145
return nil
121146
}
147+
148+
func containsMultiaddr(addrs []ma.Multiaddr, addr ma.Multiaddr) bool {
149+
for _, a := range addrs {
150+
if addr == a {
151+
return true
152+
}
153+
}
154+
return false
155+
}

p2p/net/swarm/swarm_test.go

+19
Original file line numberDiff line numberDiff line change
@@ -542,3 +542,22 @@ func TestResourceManagerAcceptStream(t *testing.T) {
542542
}
543543
require.EqualError(t, err, "stream reset")
544544
}
545+
546+
func TestListenCloseCount(t *testing.T) {
547+
s := GenSwarm(t, OptDialOnly)
548+
addrsToListen := []ma.Multiaddr{
549+
ma.StringCast("/ip4/0.0.0.0/tcp/0"),
550+
ma.StringCast("/ip4/0.0.0.0/udp/0/quic"),
551+
}
552+
553+
if err := s.Listen(addrsToListen...); err != nil {
554+
t.Fatal(err)
555+
}
556+
listenedAddrs := s.ListenAddresses()
557+
require.Equal(t, 2, len(listenedAddrs))
558+
559+
s.ListenClose(listenedAddrs...)
560+
561+
remainingAddrs := s.ListenAddresses()
562+
require.Equal(t, 0, len(remainingAddrs))
563+
}

0 commit comments

Comments
 (0)