Skip to content

Commit 0f540bb

Browse files
authored
Release v0.39.1 (#3185)
1 parent f38ab36 commit 0f540bb

File tree

7 files changed

+122
-23
lines changed

7 files changed

+122
-23
lines changed

p2p/test/transport/gating_test.go

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,26 @@ import (
2222

2323
//go:generate go run go.uber.org/mock/mockgen -package transport_integration -destination mock_connection_gater_test.go github.com/libp2p/go-libp2p/core/connmgr ConnectionGater
2424

25-
func stripCertHash(addr ma.Multiaddr) ma.Multiaddr {
25+
// normalize removes the certhash and replaces /wss with /tls/ws
26+
func normalize(addr ma.Multiaddr) ma.Multiaddr {
2627
for {
2728
if _, err := addr.ValueForProtocol(ma.P_CERTHASH); err != nil {
2829
break
2930
}
3031
addr, _ = ma.SplitLast(addr)
3132
}
32-
return addr
33+
34+
// replace /wss with /tls/ws
35+
components := []ma.Multiaddr{}
36+
ma.ForEach(addr, func(c ma.Component) bool {
37+
if c.Protocol().Code == ma.P_WSS {
38+
components = append(components, ma.StringCast("/tls/ws"))
39+
} else {
40+
components = append(components, &c)
41+
}
42+
return true
43+
})
44+
return ma.Join(components...)
3345
}
3446

3547
func addrPort(addr ma.Multiaddr) netip.AddrPort {
@@ -119,8 +131,7 @@ func TestInterceptSecuredOutgoing(t *testing.T) {
119131
connGater.EXPECT().InterceptPeerDial(h2.ID()).Return(true),
120132
connGater.EXPECT().InterceptAddrDial(h2.ID(), gomock.Any()).Return(true),
121133
connGater.EXPECT().InterceptSecured(network.DirOutbound, h2.ID(), gomock.Any()).Do(func(_ network.Direction, _ peer.ID, addrs network.ConnMultiaddrs) {
122-
// remove the certhash component from WebTransport and WebRTC addresses
123-
require.Equal(t, stripCertHash(h2.Addrs()[0]).String(), addrs.RemoteMultiaddr().String())
134+
require.Equal(t, normalize(h2.Addrs()[0]), normalize(addrs.RemoteMultiaddr()))
124135
}),
125136
)
126137
err := h1.Connect(ctx, peer.AddrInfo{ID: h2.ID(), Addrs: h2.Addrs()})
@@ -154,8 +165,7 @@ func TestInterceptUpgradedOutgoing(t *testing.T) {
154165
connGater.EXPECT().InterceptAddrDial(h2.ID(), gomock.Any()).Return(true),
155166
connGater.EXPECT().InterceptSecured(network.DirOutbound, h2.ID(), gomock.Any()).Return(true),
156167
connGater.EXPECT().InterceptUpgraded(gomock.Any()).Do(func(c network.Conn) {
157-
// remove the certhash component from WebTransport addresses
158-
require.Equal(t, stripCertHash(h2.Addrs()[0]), c.RemoteMultiaddr())
168+
require.Equal(t, normalize(h2.Addrs()[0]), normalize(c.RemoteMultiaddr()))
159169
require.Equal(t, h1.ID(), c.LocalPeer())
160170
require.Equal(t, h2.ID(), c.RemotePeer())
161171
}))
@@ -189,17 +199,15 @@ func TestInterceptAccept(t *testing.T) {
189199
// In WebRTC, retransmissions of the STUN packet might cause us to create multiple connections,
190200
// if the first connection attempt is rejected.
191201
connGater.EXPECT().InterceptAccept(gomock.Any()).Do(func(addrs network.ConnMultiaddrs) {
192-
// remove the certhash component from WebTransport addresses
193-
require.Equal(t, stripCertHash(h2.Addrs()[0]), addrs.LocalMultiaddr())
202+
require.Equal(t, normalize(h2.Addrs()[0]), normalize(addrs.LocalMultiaddr()))
194203
}).AnyTimes()
195-
} else if strings.Contains(tc.Name, "WebSocket-Shared") {
204+
} else if strings.Contains(tc.Name, "WebSocket-Shared") || strings.Contains(tc.Name, "WebSocket-Secured-Shared") {
196205
connGater.EXPECT().InterceptAccept(gomock.Any()).Do(func(addrs network.ConnMultiaddrs) {
197206
require.Equal(t, addrPort(h2.Addrs()[0]), addrPort(addrs.LocalMultiaddr()))
198207
})
199208
} else {
200209
connGater.EXPECT().InterceptAccept(gomock.Any()).Do(func(addrs network.ConnMultiaddrs) {
201-
// remove the certhash component from WebTransport addresses
202-
require.Equal(t, stripCertHash(h2.Addrs()[0]), addrs.LocalMultiaddr(), "%s\n%s", h2.Addrs()[0], addrs.LocalMultiaddr())
210+
require.Equal(t, normalize(h2.Addrs()[0]), normalize(addrs.LocalMultiaddr()))
203211
})
204212
}
205213

@@ -236,8 +244,7 @@ func TestInterceptSecuredIncoming(t *testing.T) {
236244
gomock.InOrder(
237245
connGater.EXPECT().InterceptAccept(gomock.Any()).Return(true),
238246
connGater.EXPECT().InterceptSecured(network.DirInbound, h1.ID(), gomock.Any()).Do(func(_ network.Direction, _ peer.ID, addrs network.ConnMultiaddrs) {
239-
// remove the certhash component from WebTransport addresses
240-
require.Equal(t, stripCertHash(h2.Addrs()[0]), addrs.LocalMultiaddr())
247+
require.Equal(t, normalize(h2.Addrs()[0]), normalize(addrs.LocalMultiaddr()))
241248
}),
242249
)
243250
h1.Peerstore().AddAddrs(h2.ID(), h2.Addrs(), time.Hour)
@@ -270,8 +277,7 @@ func TestInterceptUpgradedIncoming(t *testing.T) {
270277
connGater.EXPECT().InterceptAccept(gomock.Any()).Return(true),
271278
connGater.EXPECT().InterceptSecured(network.DirInbound, h1.ID(), gomock.Any()).Return(true),
272279
connGater.EXPECT().InterceptUpgraded(gomock.Any()).Do(func(c network.Conn) {
273-
// remove the certhash component from WebTransport addresses
274-
require.Equal(t, stripCertHash(h2.Addrs()[0]), c.LocalMultiaddr())
280+
require.Equal(t, normalize(h2.Addrs()[0]), normalize(c.LocalMultiaddr()))
275281
require.Equal(t, h1.ID(), c.RemotePeer())
276282
require.Equal(t, h2.ID(), c.LocalPeer())
277283
}),

p2p/test/transport/transport_test.go

Lines changed: 84 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,16 @@ package transport_integration
33
import (
44
"bytes"
55
"context"
6+
"crypto/ecdsa"
7+
"crypto/elliptic"
68
"crypto/rand"
9+
"crypto/tls"
10+
"crypto/x509"
11+
"crypto/x509/pkix"
712
"errors"
813
"fmt"
914
"io"
15+
"math/big"
1016
"net"
1117
"runtime"
1218
"strings"
@@ -15,6 +21,8 @@ import (
1521
"testing"
1622
"time"
1723

24+
libp2ptls "github.com/libp2p/go-libp2p/p2p/security/tls"
25+
1826
"github.com/libp2p/go-libp2p"
1927
"github.com/libp2p/go-libp2p/config"
2028
"github.com/libp2p/go-libp2p/core/connmgr"
@@ -30,9 +38,9 @@ import (
3038
"github.com/libp2p/go-libp2p/p2p/net/swarm"
3139
"github.com/libp2p/go-libp2p/p2p/protocol/ping"
3240
"github.com/libp2p/go-libp2p/p2p/security/noise"
33-
tls "github.com/libp2p/go-libp2p/p2p/security/tls"
3441
"github.com/libp2p/go-libp2p/p2p/transport/tcp"
3542
libp2pwebrtc "github.com/libp2p/go-libp2p/p2p/transport/webrtc"
43+
"github.com/libp2p/go-libp2p/p2p/transport/websocket"
3644
"go.uber.org/mock/gomock"
3745

3846
ma "github.com/multiformats/go-multiaddr"
@@ -67,6 +75,44 @@ func transformOpts(opts TransportTestCaseOpts) []config.Option {
6775
return libp2pOpts
6876
}
6977

78+
func selfSignedTLSConfig(t *testing.T) *tls.Config {
79+
t.Helper()
80+
priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
81+
require.NoError(t, err)
82+
83+
notBefore := time.Now()
84+
notAfter := notBefore.Add(365 * 24 * time.Hour)
85+
86+
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
87+
serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
88+
require.NoError(t, err)
89+
90+
certTemplate := x509.Certificate{
91+
SerialNumber: serialNumber,
92+
Subject: pkix.Name{
93+
Organization: []string{"Test"},
94+
},
95+
NotBefore: notBefore,
96+
NotAfter: notAfter,
97+
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
98+
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
99+
BasicConstraintsValid: true,
100+
}
101+
102+
derBytes, err := x509.CreateCertificate(rand.Reader, &certTemplate, &certTemplate, &priv.PublicKey, priv)
103+
require.NoError(t, err)
104+
105+
cert := tls.Certificate{
106+
Certificate: [][]byte{derBytes},
107+
PrivateKey: priv,
108+
}
109+
110+
tlsConfig := &tls.Config{
111+
Certificates: []tls.Certificate{cert},
112+
}
113+
return tlsConfig
114+
}
115+
70116
var transportsToTest = []TransportTestCase{
71117
{
72118
Name: "TCP / Noise / Yamux",
@@ -88,7 +134,7 @@ var transportsToTest = []TransportTestCase{
88134
Name: "TCP / TLS / Yamux",
89135
HostGenerator: func(t *testing.T, opts TransportTestCaseOpts) host.Host {
90136
libp2pOpts := transformOpts(opts)
91-
libp2pOpts = append(libp2pOpts, libp2p.Security(tls.ID, tls.New))
137+
libp2pOpts = append(libp2pOpts, libp2p.Security(libp2ptls.ID, libp2ptls.New))
92138
libp2pOpts = append(libp2pOpts, libp2p.Muxer(yamux.ID, yamux.DefaultTransport))
93139
if opts.NoListen {
94140
libp2pOpts = append(libp2pOpts, libp2p.NoListenAddrs)
@@ -105,7 +151,7 @@ var transportsToTest = []TransportTestCase{
105151
HostGenerator: func(t *testing.T, opts TransportTestCaseOpts) host.Host {
106152
libp2pOpts := transformOpts(opts)
107153
libp2pOpts = append(libp2pOpts, libp2p.ShareTCPListener())
108-
libp2pOpts = append(libp2pOpts, libp2p.Security(tls.ID, tls.New))
154+
libp2pOpts = append(libp2pOpts, libp2p.Security(libp2ptls.ID, libp2ptls.New))
109155
libp2pOpts = append(libp2pOpts, libp2p.Muxer(yamux.ID, yamux.DefaultTransport))
110156
if opts.NoListen {
111157
libp2pOpts = append(libp2pOpts, libp2p.NoListenAddrs)
@@ -122,7 +168,7 @@ var transportsToTest = []TransportTestCase{
122168
HostGenerator: func(t *testing.T, opts TransportTestCaseOpts) host.Host {
123169
libp2pOpts := transformOpts(opts)
124170
libp2pOpts = append(libp2pOpts, libp2p.ShareTCPListener())
125-
libp2pOpts = append(libp2pOpts, libp2p.Security(tls.ID, tls.New))
171+
libp2pOpts = append(libp2pOpts, libp2p.Security(libp2ptls.ID, libp2ptls.New))
126172
libp2pOpts = append(libp2pOpts, libp2p.Muxer(yamux.ID, yamux.DefaultTransport))
127173
libp2pOpts = append(libp2pOpts, libp2p.Transport(tcp.NewTCPTransport, tcp.WithMetrics()))
128174
if opts.NoListen {
@@ -139,7 +185,7 @@ var transportsToTest = []TransportTestCase{
139185
Name: "TCP-WithMetrics / TLS / Yamux",
140186
HostGenerator: func(t *testing.T, opts TransportTestCaseOpts) host.Host {
141187
libp2pOpts := transformOpts(opts)
142-
libp2pOpts = append(libp2pOpts, libp2p.Security(tls.ID, tls.New))
188+
libp2pOpts = append(libp2pOpts, libp2p.Security(libp2ptls.ID, libp2ptls.New))
143189
libp2pOpts = append(libp2pOpts, libp2p.Muxer(yamux.ID, yamux.DefaultTransport))
144190
libp2pOpts = append(libp2pOpts, libp2p.Transport(tcp.NewTCPTransport, tcp.WithMetrics()))
145191
if opts.NoListen {
@@ -167,6 +213,23 @@ var transportsToTest = []TransportTestCase{
167213
return h
168214
},
169215
},
216+
{
217+
Name: "WebSocket-Secured-Shared",
218+
HostGenerator: func(t *testing.T, opts TransportTestCaseOpts) host.Host {
219+
libp2pOpts := transformOpts(opts)
220+
libp2pOpts = append(libp2pOpts, libp2p.ShareTCPListener())
221+
if opts.NoListen {
222+
config := tls.Config{InsecureSkipVerify: true}
223+
libp2pOpts = append(libp2pOpts, libp2p.NoListenAddrs, libp2p.Transport(websocket.New, websocket.WithTLSClientConfig(&config)))
224+
} else {
225+
config := selfSignedTLSConfig(t)
226+
libp2pOpts = append(libp2pOpts, libp2p.ListenAddrStrings("/ip4/127.0.0.1/tcp/0/sni/localhost/tls/ws"), libp2p.Transport(websocket.New, websocket.WithTLSConfig(config)))
227+
}
228+
h, err := libp2p.New(libp2pOpts...)
229+
require.NoError(t, err)
230+
return h
231+
},
232+
},
170233
{
171234
Name: "WebSocket",
172235
HostGenerator: func(t *testing.T, opts TransportTestCaseOpts) host.Host {
@@ -181,6 +244,22 @@ var transportsToTest = []TransportTestCase{
181244
return h
182245
},
183246
},
247+
{
248+
Name: "WebSocket-Secured",
249+
HostGenerator: func(t *testing.T, opts TransportTestCaseOpts) host.Host {
250+
libp2pOpts := transformOpts(opts)
251+
if opts.NoListen {
252+
config := tls.Config{InsecureSkipVerify: true}
253+
libp2pOpts = append(libp2pOpts, libp2p.NoListenAddrs, libp2p.Transport(websocket.New, websocket.WithTLSClientConfig(&config)))
254+
} else {
255+
config := selfSignedTLSConfig(t)
256+
libp2pOpts = append(libp2pOpts, libp2p.ListenAddrStrings("/ip4/127.0.0.1/tcp/0/sni/localhost/tls/ws"), libp2p.Transport(websocket.New, websocket.WithTLSConfig(config)))
257+
}
258+
h, err := libp2p.New(libp2pOpts...)
259+
require.NoError(t, err)
260+
return h
261+
},
262+
},
184263
{
185264
Name: "QUIC",
186265
HostGenerator: func(t *testing.T, opts TransportTestCaseOpts) host.Host {

p2p/transport/tcpreuse/connwithscope.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@ func (c connWithScope) Scope() network.ConnManagementScope {
1717
return c.scope
1818
}
1919

20+
func (c *connWithScope) Close() error {
21+
c.scope.Done()
22+
return c.ManetTCPConnInterface.Close()
23+
}
24+
2025
func manetConnWithScope(c manet.Conn, scope network.ConnManagementScope) (manet.Conn, error) {
2126
if tcpconn, ok := c.(sampledconn.ManetTCPConnInterface); ok {
2227
return &connWithScope{tcpconn, scope}, nil

p2p/transport/tcpreuse/listener.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,7 @@ func (m *multiplexedListener) run() error {
260260
select {
261261
case demux.buffer <- connWithScope:
262262
case <-ctx.Done():
263+
log.Debug("accept timeout; dropping connection from: %v", connWithScope.RemoteMultiaddr())
263264
connWithScope.Close()
264265
}
265266
}()

p2p/transport/websocket/conn.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package websocket
22

33
import (
4+
"crypto/tls"
45
"errors"
56
"io"
67
"net"
@@ -142,6 +143,13 @@ func (c *Conn) Scope() network.ConnManagementScope {
142143
}); ok {
143144
return sc.Scope()
144145
}
146+
if nc, ok := nc.(*tls.Conn); ok {
147+
if sc, ok := nc.NetConn().(interface {
148+
Scope() network.ConnManagementScope
149+
}); ok {
150+
return sc.Scope()
151+
}
152+
}
145153
return nil
146154
}
147155

p2p/transport/websocket/listener.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,9 +137,9 @@ func (l *listener) ServeHTTP(w http.ResponseWriter, r *http.Request) {
137137
return
138138
}
139139
select {
140-
case l.incoming <- NewConn(c, l.isWss):
140+
case l.incoming <- nc:
141141
case <-l.closed:
142-
c.Close()
142+
nc.Close()
143143
}
144144
// The connection has been hijacked, it's safe to return.
145145
}

version.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
{
2-
"version": "v0.39.0"
2+
"version": "v0.39.1"
33
}

0 commit comments

Comments
 (0)