From 79cc9a4baeddeb6142023732ab132cf6f3852c3b Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Mon, 7 Jun 2021 18:35:39 +0200 Subject: [PATCH 1/3] Fix race in adding connections to connsByPeer Side A could already be running Identify with side B before B had the connection in the connsByPeer, this lead to Connectedness returning NotConnected and Identify failing. Signed-off-by: Jakub Sztandera --- p2p/net/mock/mock_peernet.go | 47 +++++++++++++++++++++++------------- 1 file changed, 30 insertions(+), 17 deletions(-) diff --git a/p2p/net/mock/mock_peernet.go b/p2p/net/mock/mock_peernet.go index 426c28fdc1..67409e7dbd 100644 --- a/p2p/net/mock/mock_peernet.go +++ b/p2p/net/mock/mock_peernet.go @@ -160,11 +160,41 @@ func (pn *peernet) connect(p peer.ID) (*conn, error) { func (pn *peernet) openConn(r peer.ID, l *link) *conn { lc, rc := l.newConnPair(pn) log.Debugf("%s opening connection to %s", pn.LocalPeer(), lc.RemotePeer()) + addConnPair(pn, rc.net, lc, rc) + go rc.net.remoteOpenedConn(rc) pn.addConn(lc) return lc } +// addConnPair adds connection to both peernets at the same time +// must be followerd by pn1.addConn(c1) and pn2.addConn(c2) +func addConnPair(pn1, pn2 *peernet, c1, c2 *conn) { + pn1.Lock() + pn2.Lock() + + add := func(pn *peernet, c *conn) { + _, found := pn.connsByPeer[c.RemotePeer()] + if !found { + pn.connsByPeer[c.RemotePeer()] = map[*conn]struct{}{} + } + pn.connsByPeer[c.RemotePeer()][c] = struct{}{} + + _, found = pn.connsByLink[c.link] + if !found { + pn.connsByLink[c.link] = map[*conn]struct{}{} + } + pn.connsByLink[c.link][c] = struct{}{} + } + add(pn1, c1) + add(pn2, c2) + + c1.notifLk.Lock() + c2.notifLk.Lock() + pn2.Unlock() + pn1.Unlock() +} + func (pn *peernet) remoteOpenedConn(c *conn) { log.Debugf("%s accepting connection from %s", pn.LocalPeer(), c.RemotePeer()) pn.addConn(c) @@ -174,24 +204,7 @@ func (pn *peernet) remoteOpenedConn(c *conn) { // addConn constructs and adds a connection // to given remote peer over given link func (pn *peernet) addConn(c *conn) { - pn.Lock() - - _, found := pn.connsByPeer[c.RemotePeer()] - if !found { - pn.connsByPeer[c.RemotePeer()] = map[*conn]struct{}{} - } - pn.connsByPeer[c.RemotePeer()][c] = struct{}{} - - _, found = pn.connsByLink[c.link] - if !found { - pn.connsByLink[c.link] = map[*conn]struct{}{} - } - pn.connsByLink[c.link][c] = struct{}{} - - c.notifLk.Lock() defer c.notifLk.Unlock() - pn.Unlock() - // Call this after unlocking as it might cause us to immediately close // the connection and remove it from the swarm. c.setup() From 8c975722a18f52ad2a9f6ff29eb067ea2c2d3647 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Mon, 7 Jun 2021 18:51:08 +0200 Subject: [PATCH 2/3] Update go-libp2p in examples to fix CI Signed-off-by: Jakub Sztandera --- examples/go.mod | 2 +- examples/go.sum | 8 ++++---- examples/ipfs-camp-2019/go.mod | 2 +- examples/ipfs-camp-2019/go.sum | 8 ++++---- examples/pubsub/chat/go.mod | 2 +- examples/pubsub/chat/go.sum | 8 ++++---- 6 files changed, 15 insertions(+), 15 deletions(-) diff --git a/examples/go.mod b/examples/go.mod index a8e1aa2a26..63c311a77f 100644 --- a/examples/go.mod +++ b/examples/go.mod @@ -7,7 +7,7 @@ require ( github.com/google/uuid v1.2.0 github.com/ipfs/go-datastore v0.4.5 github.com/ipfs/go-log/v2 v2.1.3 - github.com/libp2p/go-libp2p v0.13.0 + github.com/libp2p/go-libp2p v0.14.1 github.com/libp2p/go-libp2p-circuit v0.4.0 github.com/libp2p/go-libp2p-connmgr v0.2.4 github.com/libp2p/go-libp2p-core v0.8.5 diff --git a/examples/go.sum b/examples/go.sum index 2e0e141cad..69c99a5270 100644 --- a/examples/go.sum +++ b/examples/go.sum @@ -323,8 +323,8 @@ github.com/libp2p/go-libp2p-transport-upgrader v0.4.2/go.mod h1:NR8ne1VwfreD5VIW github.com/libp2p/go-libp2p-yamux v0.2.8/go.mod h1:/t6tDqeuZf0INZMTgd0WxIRbtK2EzI2h7HbFm9eAKI4= github.com/libp2p/go-libp2p-yamux v0.4.0/go.mod h1:+DWDjtFMzoAwYLVkNZftoucn7PelNoy5nm3tZ3/Zw30= github.com/libp2p/go-libp2p-yamux v0.5.0/go.mod h1:AyR8k5EzyM2QN9Bbdg6X1SkVVuqLwTGf0L4DFq9g6po= -github.com/libp2p/go-libp2p-yamux v0.5.3 h1:x2bK2BWktdMdTrciiDmgTMIxYNBdkxewQFEjHDl7VgU= -github.com/libp2p/go-libp2p-yamux v0.5.3/go.mod h1:Vy3TMonBAfTMXHWopsMc8iX/XGRYrRlpUaMzaeuHV/s= +github.com/libp2p/go-libp2p-yamux v0.5.4 h1:/UOPtT/6DHPtr3TtKXBHa6g0Le0szYuI33Xc/Xpd7fQ= +github.com/libp2p/go-libp2p-yamux v0.5.4/go.mod h1:tfrXbyaTqqSU654GTvK3ocnSZL3BuHoeTSqhcel1wsE= github.com/libp2p/go-maddr-filter v0.0.5/go.mod h1:Jk+36PMfIqCJhAnaASRH83bdAvfDRp/w6ENFaC9bG+M= github.com/libp2p/go-maddr-filter v0.1.0 h1:4ACqZKw8AqiuJfwFGq1CYDFugfXTOos+qQ3DETkhtCE= github.com/libp2p/go-maddr-filter v0.1.0/go.mod h1:VzZhTXkMucEGGEOSKddrwGiOv0tUhgnKqNEmIAz/bPU= @@ -367,8 +367,8 @@ github.com/libp2p/go-yamux v1.3.7/go.mod h1:fr7aVgmdNGJK+N1g+b6DW6VxzbRCjCOejR/h github.com/libp2p/go-yamux v1.4.0/go.mod h1:fr7aVgmdNGJK+N1g+b6DW6VxzbRCjCOejR/hkmpooHE= github.com/libp2p/go-yamux v1.4.1 h1:P1Fe9vF4th5JOxxgQvfbOHkrGqIZniTLf+ddhZp8YTI= github.com/libp2p/go-yamux v1.4.1/go.mod h1:fr7aVgmdNGJK+N1g+b6DW6VxzbRCjCOejR/hkmpooHE= -github.com/libp2p/go-yamux/v2 v2.1.1 h1:3RkXAnDmaXJPckF/QbDnNbA6lZXMgycNTVMMTQ2YlAI= -github.com/libp2p/go-yamux/v2 v2.1.1/go.mod h1:3So6P6TV6r75R9jiBpiIKgU/66lOarCZjqROGxzPpPQ= +github.com/libp2p/go-yamux/v2 v2.2.0 h1:RwtpYZ2/wVviZ5+3pjC8qdQ4TKnrak0/E01N1UWoAFU= +github.com/libp2p/go-yamux/v2 v2.2.0/go.mod h1:3So6P6TV6r75R9jiBpiIKgU/66lOarCZjqROGxzPpPQ= github.com/lucas-clemente/quic-go v0.19.3 h1:eCDQqvGBB+kCTkA0XrAFtNe81FMa0/fn4QSoeAbmiF4= github.com/lucas-clemente/quic-go v0.19.3/go.mod h1:ADXpNbTQjq1hIzCpB+y/k5iz4n4z4IwqoLb94Kh5Hu8= github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= diff --git a/examples/ipfs-camp-2019/go.mod b/examples/ipfs-camp-2019/go.mod index daf4f82d14..79ccc94c0f 100644 --- a/examples/ipfs-camp-2019/go.mod +++ b/examples/ipfs-camp-2019/go.mod @@ -11,7 +11,7 @@ require ( github.com/libp2p/go-libp2p-mplex v0.4.1 github.com/libp2p/go-libp2p-pubsub v0.4.1 github.com/libp2p/go-libp2p-secio v0.2.2 - github.com/libp2p/go-libp2p-yamux v0.5.3 + github.com/libp2p/go-libp2p-yamux v0.5.4 github.com/libp2p/go-tcp-transport v0.2.1 github.com/libp2p/go-ws-transport v0.4.0 github.com/multiformats/go-multiaddr v0.3.1 diff --git a/examples/ipfs-camp-2019/go.sum b/examples/ipfs-camp-2019/go.sum index c1ddf60187..dbfaa02260 100644 --- a/examples/ipfs-camp-2019/go.sum +++ b/examples/ipfs-camp-2019/go.sum @@ -325,8 +325,8 @@ github.com/libp2p/go-libp2p-transport-upgrader v0.4.2/go.mod h1:NR8ne1VwfreD5VIW github.com/libp2p/go-libp2p-yamux v0.2.8/go.mod h1:/t6tDqeuZf0INZMTgd0WxIRbtK2EzI2h7HbFm9eAKI4= github.com/libp2p/go-libp2p-yamux v0.4.0/go.mod h1:+DWDjtFMzoAwYLVkNZftoucn7PelNoy5nm3tZ3/Zw30= github.com/libp2p/go-libp2p-yamux v0.5.0/go.mod h1:AyR8k5EzyM2QN9Bbdg6X1SkVVuqLwTGf0L4DFq9g6po= -github.com/libp2p/go-libp2p-yamux v0.5.3 h1:x2bK2BWktdMdTrciiDmgTMIxYNBdkxewQFEjHDl7VgU= -github.com/libp2p/go-libp2p-yamux v0.5.3/go.mod h1:Vy3TMonBAfTMXHWopsMc8iX/XGRYrRlpUaMzaeuHV/s= +github.com/libp2p/go-libp2p-yamux v0.5.4 h1:/UOPtT/6DHPtr3TtKXBHa6g0Le0szYuI33Xc/Xpd7fQ= +github.com/libp2p/go-libp2p-yamux v0.5.4/go.mod h1:tfrXbyaTqqSU654GTvK3ocnSZL3BuHoeTSqhcel1wsE= github.com/libp2p/go-maddr-filter v0.0.5/go.mod h1:Jk+36PMfIqCJhAnaASRH83bdAvfDRp/w6ENFaC9bG+M= github.com/libp2p/go-maddr-filter v0.1.0 h1:4ACqZKw8AqiuJfwFGq1CYDFugfXTOos+qQ3DETkhtCE= github.com/libp2p/go-maddr-filter v0.1.0/go.mod h1:VzZhTXkMucEGGEOSKddrwGiOv0tUhgnKqNEmIAz/bPU= @@ -369,8 +369,8 @@ github.com/libp2p/go-yamux v1.3.7/go.mod h1:fr7aVgmdNGJK+N1g+b6DW6VxzbRCjCOejR/h github.com/libp2p/go-yamux v1.4.0/go.mod h1:fr7aVgmdNGJK+N1g+b6DW6VxzbRCjCOejR/hkmpooHE= github.com/libp2p/go-yamux v1.4.1 h1:P1Fe9vF4th5JOxxgQvfbOHkrGqIZniTLf+ddhZp8YTI= github.com/libp2p/go-yamux v1.4.1/go.mod h1:fr7aVgmdNGJK+N1g+b6DW6VxzbRCjCOejR/hkmpooHE= -github.com/libp2p/go-yamux/v2 v2.1.1 h1:3RkXAnDmaXJPckF/QbDnNbA6lZXMgycNTVMMTQ2YlAI= -github.com/libp2p/go-yamux/v2 v2.1.1/go.mod h1:3So6P6TV6r75R9jiBpiIKgU/66lOarCZjqROGxzPpPQ= +github.com/libp2p/go-yamux/v2 v2.2.0 h1:RwtpYZ2/wVviZ5+3pjC8qdQ4TKnrak0/E01N1UWoAFU= +github.com/libp2p/go-yamux/v2 v2.2.0/go.mod h1:3So6P6TV6r75R9jiBpiIKgU/66lOarCZjqROGxzPpPQ= github.com/lucas-clemente/quic-go v0.19.3 h1:eCDQqvGBB+kCTkA0XrAFtNe81FMa0/fn4QSoeAbmiF4= github.com/lucas-clemente/quic-go v0.19.3/go.mod h1:ADXpNbTQjq1hIzCpB+y/k5iz4n4z4IwqoLb94Kh5Hu8= github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= diff --git a/examples/pubsub/chat/go.mod b/examples/pubsub/chat/go.mod index 26f7ac88cb..e9d261981b 100644 --- a/examples/pubsub/chat/go.mod +++ b/examples/pubsub/chat/go.mod @@ -4,7 +4,7 @@ go 1.14 require ( github.com/gdamore/tcell/v2 v2.1.0 - github.com/libp2p/go-libp2p v0.13.0 + github.com/libp2p/go-libp2p v0.14.1 github.com/libp2p/go-libp2p-core v0.8.5 github.com/libp2p/go-libp2p-pubsub v0.4.1 github.com/rivo/tview v0.0.0-20210125085121-dbc1f32bb1d0 diff --git a/examples/pubsub/chat/go.sum b/examples/pubsub/chat/go.sum index 063ec302fd..757cc263e2 100644 --- a/examples/pubsub/chat/go.sum +++ b/examples/pubsub/chat/go.sum @@ -293,8 +293,8 @@ github.com/libp2p/go-libp2p-transport-upgrader v0.4.2/go.mod h1:NR8ne1VwfreD5VIW github.com/libp2p/go-libp2p-yamux v0.2.8/go.mod h1:/t6tDqeuZf0INZMTgd0WxIRbtK2EzI2h7HbFm9eAKI4= github.com/libp2p/go-libp2p-yamux v0.4.0/go.mod h1:+DWDjtFMzoAwYLVkNZftoucn7PelNoy5nm3tZ3/Zw30= github.com/libp2p/go-libp2p-yamux v0.5.0/go.mod h1:AyR8k5EzyM2QN9Bbdg6X1SkVVuqLwTGf0L4DFq9g6po= -github.com/libp2p/go-libp2p-yamux v0.5.3 h1:x2bK2BWktdMdTrciiDmgTMIxYNBdkxewQFEjHDl7VgU= -github.com/libp2p/go-libp2p-yamux v0.5.3/go.mod h1:Vy3TMonBAfTMXHWopsMc8iX/XGRYrRlpUaMzaeuHV/s= +github.com/libp2p/go-libp2p-yamux v0.5.4 h1:/UOPtT/6DHPtr3TtKXBHa6g0Le0szYuI33Xc/Xpd7fQ= +github.com/libp2p/go-libp2p-yamux v0.5.4/go.mod h1:tfrXbyaTqqSU654GTvK3ocnSZL3BuHoeTSqhcel1wsE= github.com/libp2p/go-maddr-filter v0.0.5/go.mod h1:Jk+36PMfIqCJhAnaASRH83bdAvfDRp/w6ENFaC9bG+M= github.com/libp2p/go-maddr-filter v0.1.0 h1:4ACqZKw8AqiuJfwFGq1CYDFugfXTOos+qQ3DETkhtCE= github.com/libp2p/go-maddr-filter v0.1.0/go.mod h1:VzZhTXkMucEGGEOSKddrwGiOv0tUhgnKqNEmIAz/bPU= @@ -336,8 +336,8 @@ github.com/libp2p/go-yamux v1.3.7/go.mod h1:fr7aVgmdNGJK+N1g+b6DW6VxzbRCjCOejR/h github.com/libp2p/go-yamux v1.4.0/go.mod h1:fr7aVgmdNGJK+N1g+b6DW6VxzbRCjCOejR/hkmpooHE= github.com/libp2p/go-yamux v1.4.1 h1:P1Fe9vF4th5JOxxgQvfbOHkrGqIZniTLf+ddhZp8YTI= github.com/libp2p/go-yamux v1.4.1/go.mod h1:fr7aVgmdNGJK+N1g+b6DW6VxzbRCjCOejR/hkmpooHE= -github.com/libp2p/go-yamux/v2 v2.1.1 h1:3RkXAnDmaXJPckF/QbDnNbA6lZXMgycNTVMMTQ2YlAI= -github.com/libp2p/go-yamux/v2 v2.1.1/go.mod h1:3So6P6TV6r75R9jiBpiIKgU/66lOarCZjqROGxzPpPQ= +github.com/libp2p/go-yamux/v2 v2.2.0 h1:RwtpYZ2/wVviZ5+3pjC8qdQ4TKnrak0/E01N1UWoAFU= +github.com/libp2p/go-yamux/v2 v2.2.0/go.mod h1:3So6P6TV6r75R9jiBpiIKgU/66lOarCZjqROGxzPpPQ= github.com/lucas-clemente/quic-go v0.19.3 h1:eCDQqvGBB+kCTkA0XrAFtNe81FMa0/fn4QSoeAbmiF4= github.com/lucas-clemente/quic-go v0.19.3/go.mod h1:ADXpNbTQjq1hIzCpB+y/k5iz4n4z4IwqoLb94Kh5Hu8= github.com/lucasb-eyer/go-colorful v1.0.3 h1:QIbQXiugsb+q10B+MI+7DI1oQLdmnep86tWFlaaUAac= From d82385ef7054c722aa15b6b47f7054b949d13c7f Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Mon, 7 Jun 2021 20:45:07 +0200 Subject: [PATCH 3/3] Deterministic lock order Signed-off-by: Jakub Sztandera --- p2p/net/mock/mock_peernet.go | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/p2p/net/mock/mock_peernet.go b/p2p/net/mock/mock_peernet.go index 67409e7dbd..d28610a893 100644 --- a/p2p/net/mock/mock_peernet.go +++ b/p2p/net/mock/mock_peernet.go @@ -1,6 +1,7 @@ package mocknet import ( + "bytes" "context" "fmt" "math/rand" @@ -170,8 +171,14 @@ func (pn *peernet) openConn(r peer.ID, l *link) *conn { // addConnPair adds connection to both peernets at the same time // must be followerd by pn1.addConn(c1) and pn2.addConn(c2) func addConnPair(pn1, pn2 *peernet, c1, c2 *conn) { - pn1.Lock() - pn2.Lock() + var l1, l2 = pn1, pn2 // peernets in lock order + // bytes compare as string compare is lexicographical + if bytes.Compare([]byte(l1.LocalPeer()), []byte(l2.LocalPeer())) > 0 { + l1, l2 = l2, l1 + } + + l1.Lock() + l2.Lock() add := func(pn *peernet, c *conn) { _, found := pn.connsByPeer[c.RemotePeer()] @@ -191,8 +198,8 @@ func addConnPair(pn1, pn2 *peernet, c1, c2 *conn) { c1.notifLk.Lock() c2.notifLk.Lock() - pn2.Unlock() - pn1.Unlock() + l2.Unlock() + l1.Unlock() } func (pn *peernet) remoteOpenedConn(c *conn) {