mirror of
https://source.quilibrium.com/quilibrium/ceremonyclient.git
synced 2024-12-30 18:35:18 +00:00
207 lines
7.4 KiB
Go
207 lines
7.4 KiB
Go
|
package quic_test
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"testing"
|
||
|
"time"
|
||
|
|
||
|
"github.com/libp2p/go-libp2p"
|
||
|
"github.com/libp2p/go-libp2p/core/network"
|
||
|
"github.com/libp2p/go-libp2p/core/peer"
|
||
|
libp2pquic "github.com/libp2p/go-libp2p/p2p/transport/quic"
|
||
|
"github.com/libp2p/go-libp2p/p2p/transport/quicreuse"
|
||
|
webtransport "github.com/libp2p/go-libp2p/p2p/transport/webtransport"
|
||
|
|
||
|
ma "github.com/multiformats/go-multiaddr"
|
||
|
"github.com/stretchr/testify/require"
|
||
|
)
|
||
|
|
||
|
func getQUICMultiaddrCode(addr ma.Multiaddr) int {
|
||
|
if _, err := addr.ValueForProtocol(ma.P_QUIC); err == nil {
|
||
|
return ma.P_QUIC
|
||
|
}
|
||
|
if _, err := addr.ValueForProtocol(ma.P_QUIC_V1); err == nil {
|
||
|
return ma.P_QUIC_V1
|
||
|
}
|
||
|
return 0
|
||
|
}
|
||
|
|
||
|
func TestQUICVersions(t *testing.T) {
|
||
|
h1, err := libp2p.New(
|
||
|
libp2p.Transport(libp2pquic.NewTransport),
|
||
|
libp2p.Transport(webtransport.New),
|
||
|
libp2p.ListenAddrStrings(
|
||
|
"/ip4/127.0.0.1/udp/12345/quic", // QUIC draft-29
|
||
|
"/ip4/127.0.0.1/udp/12345/quic-v1", // QUIC v1
|
||
|
),
|
||
|
)
|
||
|
require.NoError(t, err)
|
||
|
defer h1.Close()
|
||
|
|
||
|
addrs := h1.Addrs()
|
||
|
require.Len(t, addrs, 2)
|
||
|
var quicDraft29Addr, quicV1Addr ma.Multiaddr
|
||
|
for _, addr := range addrs {
|
||
|
switch getQUICMultiaddrCode(addr) {
|
||
|
case ma.P_QUIC:
|
||
|
quicDraft29Addr = addr
|
||
|
case ma.P_QUIC_V1:
|
||
|
quicV1Addr = addr
|
||
|
}
|
||
|
}
|
||
|
require.NotNil(t, quicDraft29Addr, "expected to be listening on a QUIC draft-29 address")
|
||
|
require.NotNil(t, quicV1Addr, "expected to be listening on a QUIC v1 address")
|
||
|
|
||
|
ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
|
||
|
defer cancel()
|
||
|
// connect using QUIC draft-29
|
||
|
h2, err := libp2p.New(
|
||
|
libp2p.Transport(libp2pquic.NewTransport),
|
||
|
)
|
||
|
require.NoError(t, err)
|
||
|
require.NoError(t, h2.Connect(ctx, peer.AddrInfo{ID: h1.ID(), Addrs: []ma.Multiaddr{quicDraft29Addr}}))
|
||
|
conns := h2.Network().ConnsToPeer(h1.ID())
|
||
|
require.Len(t, conns, 1)
|
||
|
require.Equal(t, ma.P_QUIC, getQUICMultiaddrCode(conns[0].LocalMultiaddr()))
|
||
|
require.Equal(t, ma.P_QUIC, getQUICMultiaddrCode(conns[0].RemoteMultiaddr()))
|
||
|
h2.Close()
|
||
|
|
||
|
// connect using QUIC v1
|
||
|
h3, err := libp2p.New(
|
||
|
libp2p.Transport(libp2pquic.NewTransport),
|
||
|
)
|
||
|
require.NoError(t, err)
|
||
|
require.NoError(t, h3.Connect(ctx, peer.AddrInfo{ID: h1.ID(), Addrs: []ma.Multiaddr{quicV1Addr}}))
|
||
|
conns = h3.Network().ConnsToPeer(h1.ID())
|
||
|
require.Len(t, conns, 1)
|
||
|
require.Equal(t, ma.P_QUIC_V1, getQUICMultiaddrCode(conns[0].LocalMultiaddr()))
|
||
|
require.Equal(t, ma.P_QUIC_V1, getQUICMultiaddrCode(conns[0].RemoteMultiaddr()))
|
||
|
h3.Close()
|
||
|
}
|
||
|
|
||
|
func TestDisableQUICDraft29(t *testing.T) {
|
||
|
h1, err := libp2p.New(
|
||
|
libp2p.QUICReuse(quicreuse.NewConnManager, quicreuse.DisableDraft29()),
|
||
|
libp2p.Transport(libp2pquic.NewTransport),
|
||
|
libp2p.Transport(webtransport.New),
|
||
|
libp2p.ListenAddrStrings(
|
||
|
"/ip4/127.0.0.1/udp/12346/quic", // QUIC draft-29
|
||
|
"/ip4/127.0.0.1/udp/12346/quic-v1", // QUIC v1
|
||
|
),
|
||
|
)
|
||
|
require.NoError(t, err)
|
||
|
defer h1.Close()
|
||
|
|
||
|
addrs := h1.Addrs()
|
||
|
require.Len(t, addrs, 1)
|
||
|
require.Equal(t, ma.P_QUIC_V1, getQUICMultiaddrCode(addrs[0]))
|
||
|
|
||
|
// connect using QUIC draft-29
|
||
|
h2, err := libp2p.New(
|
||
|
libp2p.Transport(libp2pquic.NewTransport),
|
||
|
)
|
||
|
require.NoError(t, err)
|
||
|
defer h2.Close()
|
||
|
// We disabled QUIC Version Negotiation, so we will _not_ receive a Version Negotiation packet.
|
||
|
// Instead, the connection will run into the context timeout.
|
||
|
ctx, cancel := context.WithTimeout(context.Background(), 300*time.Microsecond)
|
||
|
defer cancel()
|
||
|
require.ErrorIs(t,
|
||
|
h2.Connect(ctx, peer.AddrInfo{ID: h1.ID(), Addrs: []ma.Multiaddr{ma.StringCast("/ip4/127.0.0.1/udp/12346/quic")}}),
|
||
|
context.DeadlineExceeded,
|
||
|
)
|
||
|
// make sure that dialing QUIC v1 works
|
||
|
ctx, cancel = context.WithTimeout(context.Background(), 10*time.Second)
|
||
|
defer cancel()
|
||
|
require.NoError(t, h2.Connect(ctx, peer.AddrInfo{ID: h1.ID(), Addrs: []ma.Multiaddr{addrs[0]}}))
|
||
|
}
|
||
|
|
||
|
func TestQUICAndWebTransport(t *testing.T) {
|
||
|
h1, err := libp2p.New(
|
||
|
libp2p.QUICReuse(quicreuse.NewConnManager),
|
||
|
libp2p.Transport(libp2pquic.NewTransport),
|
||
|
libp2p.Transport(webtransport.New),
|
||
|
libp2p.ListenAddrStrings(
|
||
|
"/ip4/127.0.0.1/udp/12347/quic/",
|
||
|
"/ip4/127.0.0.1/udp/12347/quic-v1",
|
||
|
"/ip4/127.0.0.1/udp/12347/quic-v1/webtransport",
|
||
|
),
|
||
|
)
|
||
|
require.NoError(t, err)
|
||
|
defer h1.Close()
|
||
|
|
||
|
addrs := h1.Addrs()
|
||
|
require.Len(t, addrs, 3)
|
||
|
var quicDraft29Addr, quicV1Addr, webtransportAddr ma.Multiaddr
|
||
|
for _, addr := range addrs {
|
||
|
if _, err := addr.ValueForProtocol(ma.P_WEBTRANSPORT); err == nil {
|
||
|
webtransportAddr = addr
|
||
|
} else if _, err := addr.ValueForProtocol(ma.P_QUIC_V1); err == nil {
|
||
|
quicV1Addr = addr
|
||
|
} else {
|
||
|
quicDraft29Addr = addr
|
||
|
}
|
||
|
}
|
||
|
require.NotNil(t, webtransportAddr, "expected to have a WebTransport address")
|
||
|
require.NotNil(t, quicDraft29Addr, "expected to have a QUIC draft-29 address")
|
||
|
require.NotNil(t, quicV1Addr, "expected to have a QUIC v1 address")
|
||
|
|
||
|
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
||
|
defer cancel()
|
||
|
// first test that we can dial a QUIC v1
|
||
|
h2, err := libp2p.New(
|
||
|
libp2p.Transport(libp2pquic.NewTransport),
|
||
|
libp2p.NoListenAddrs,
|
||
|
)
|
||
|
require.NoError(t, err)
|
||
|
require.NoError(t, h2.Connect(ctx, peer.AddrInfo{ID: h1.ID(), Addrs: h1.Addrs()}))
|
||
|
for _, conns := range [][]network.Conn{h2.Network().ConnsToPeer(h1.ID()), h1.Network().ConnsToPeer(h2.ID())} {
|
||
|
require.Len(t, conns, 1)
|
||
|
if _, err := conns[0].LocalMultiaddr().ValueForProtocol(ma.P_WEBTRANSPORT); err == nil {
|
||
|
t.Fatalf("expected a QUIC connection, got a WebTransport connection (%s <-> %s)", conns[0].LocalMultiaddr(), conns[0].RemoteMultiaddr())
|
||
|
}
|
||
|
require.Equal(t, ma.P_QUIC_V1, getQUICMultiaddrCode(conns[0].LocalMultiaddr()))
|
||
|
require.Equal(t, ma.P_QUIC_V1, getQUICMultiaddrCode(conns[0].RemoteMultiaddr()))
|
||
|
}
|
||
|
h2.Close()
|
||
|
|
||
|
// then test that we can dial a QUIC draft-29
|
||
|
h3, err := libp2p.New(
|
||
|
libp2p.Transport(libp2pquic.NewTransport),
|
||
|
libp2p.NoListenAddrs,
|
||
|
)
|
||
|
require.NoError(t, err)
|
||
|
require.NoError(t, h3.Connect(ctx, peer.AddrInfo{
|
||
|
ID: h1.ID(),
|
||
|
// a libp2p host will prefer dialing v1 if it supports both versions,
|
||
|
// so we need to filter the addresses so it thinks that h1 only supports draft-29
|
||
|
Addrs: ma.FilterAddrs(h1.Addrs(), func(addr ma.Multiaddr) bool { _, err := addr.ValueForProtocol(ma.P_QUIC); return err == nil }),
|
||
|
}))
|
||
|
for _, conns := range [][]network.Conn{h3.Network().ConnsToPeer(h1.ID()), h1.Network().ConnsToPeer(h3.ID())} {
|
||
|
require.Len(t, conns, 1)
|
||
|
if _, err := conns[0].LocalMultiaddr().ValueForProtocol(ma.P_WEBTRANSPORT); err == nil {
|
||
|
t.Fatalf("expected a QUIC connection, got a WebTransport connection (%s <-> %s)", conns[0].LocalMultiaddr(), conns[0].RemoteMultiaddr())
|
||
|
}
|
||
|
require.Equal(t, ma.P_QUIC, getQUICMultiaddrCode(conns[0].LocalMultiaddr()))
|
||
|
require.Equal(t, ma.P_QUIC, getQUICMultiaddrCode(conns[0].RemoteMultiaddr()))
|
||
|
}
|
||
|
h3.Close()
|
||
|
|
||
|
// finally, test that we can dial a WebTransport connection
|
||
|
h4, err := libp2p.New(
|
||
|
libp2p.Transport(webtransport.New),
|
||
|
libp2p.NoListenAddrs,
|
||
|
)
|
||
|
require.NoError(t, err)
|
||
|
require.NoError(t, h4.Connect(ctx, peer.AddrInfo{ID: h1.ID(), Addrs: h1.Addrs()}))
|
||
|
for _, conns := range [][]network.Conn{h4.Network().ConnsToPeer(h1.ID()), h1.Network().ConnsToPeer(h4.ID())} {
|
||
|
require.Len(t, conns, 1)
|
||
|
if _, err := conns[0].LocalMultiaddr().ValueForProtocol(ma.P_WEBTRANSPORT); err != nil {
|
||
|
t.Fatalf("expected a WebTransport connection, got a QUIC connection (%s <-> %s)", conns[0].LocalMultiaddr(), conns[0].RemoteMultiaddr())
|
||
|
}
|
||
|
require.Equal(t, ma.P_QUIC_V1, getQUICMultiaddrCode(conns[0].LocalMultiaddr()))
|
||
|
require.Equal(t, ma.P_QUIC_V1, getQUICMultiaddrCode(conns[0].RemoteMultiaddr()))
|
||
|
}
|
||
|
h4.Close()
|
||
|
}
|