Browse Source

update to the current master of go-libp2p (#23)

pull/1737/head
Marten Seemann 2 years ago
committed by GitHub
parent
commit
97e739f0a8
  1. 4
      p2p/transport/webtransport/conn.go
  2. 75
      p2p/transport/webtransport/listener.go
  3. 8
      p2p/transport/webtransport/mock_connection_gater_test.go
  4. 34
      p2p/transport/webtransport/noise_early_data.go
  5. 2
      p2p/transport/webtransport/stream.go
  6. 48
      p2p/transport/webtransport/transport.go
  7. 10
      p2p/transport/webtransport/transport_test.go

4
p2p/transport/webtransport/conn.go

@ -3,8 +3,8 @@ package libp2pwebtransport
import (
"context"
"github.com/libp2p/go-libp2p-core/network"
tpt "github.com/libp2p/go-libp2p-core/transport"
"github.com/libp2p/go-libp2p/core/network"
tpt "github.com/libp2p/go-libp2p/core/transport"
"github.com/marten-seemann/webtransport-go"
ma "github.com/multiformats/go-multiaddr"

75
p2p/transport/webtransport/listener.go

@ -5,15 +5,16 @@ import (
"crypto/tls"
"errors"
"fmt"
pb "github.com/marten-seemann/go-libp2p-webtransport/pb"
"github.com/multiformats/go-multihash"
"net"
"net/http"
"time"
"github.com/libp2p/go-libp2p-core/connmgr"
"github.com/libp2p/go-libp2p-core/network"
tpt "github.com/libp2p/go-libp2p-core/transport"
noise "github.com/libp2p/go-libp2p-noise"
"github.com/libp2p/go-libp2p/core/connmgr"
"github.com/libp2p/go-libp2p/core/network"
tpt "github.com/libp2p/go-libp2p/core/transport"
"github.com/libp2p/go-libp2p/p2p/security/noise"
"github.com/lucas-clemente/quic-go/http3"
"github.com/marten-seemann/webtransport-go"
@ -27,10 +28,11 @@ const queueLen = 16
const handshakeTimeout = 10 * time.Second
type listener struct {
transport tpt.Transport
noise *noise.Transport
certManager *certManager
staticTLSConf *tls.Config
transport tpt.Transport
noise *noise.Transport
certManager *certManager
tlsConf *tls.Config
isStaticTLSConf bool
rcmgr network.ResourceManager
gater connmgr.ConnectionGater
@ -67,23 +69,25 @@ func newListener(laddr ma.Multiaddr, transport tpt.Transport, noise *noise.Trans
if err != nil {
return nil, err
}
isStaticTLSConf := tlsConf != nil
if tlsConf == nil {
tlsConf = &tls.Config{GetConfigForClient: func(*tls.ClientHelloInfo) (*tls.Config, error) {
return certManager.GetConfig(), nil
}}
}
ln := &listener{
transport: transport,
noise: noise,
certManager: certManager,
staticTLSConf: tlsConf,
rcmgr: rcmgr,
gater: gater,
queue: make(chan tpt.CapableConn, queueLen),
serverClosed: make(chan struct{}),
addr: udpConn.LocalAddr(),
multiaddr: localMultiaddr,
server: webtransport.Server{H3: http3.Server{TLSConfig: tlsConf}},
transport: transport,
noise: noise,
certManager: certManager,
tlsConf: tlsConf,
isStaticTLSConf: isStaticTLSConf,
rcmgr: rcmgr,
gater: gater,
queue: make(chan tpt.CapableConn, queueLen),
serverClosed: make(chan struct{}),
addr: udpConn.LocalAddr(),
multiaddr: localMultiaddr,
server: webtransport.Server{H3: http3.Server{TLSConfig: tlsConf}},
}
ln.ctx, ln.ctxCancel = context.WithCancel(context.Background())
mux := http.NewServeMux()
@ -184,7 +188,11 @@ func (l *listener) handshake(ctx context.Context, sess *webtransport.Session) (c
if err != nil {
return nil, err
}
c, err := l.noise.SecureInbound(ctx, &webtransportStream{Stream: str, wsess: sess}, "")
n, err := l.noise.WithSessionOptions(noise.EarlyData(newEarlyDataReceiver(l.checkEarlyData)))
if err != nil {
return nil, fmt.Errorf("failed to initialize Noise session: %w", err)
}
c, err := n.SecureInbound(ctx, &webtransportStream{Stream: str, wsess: sess}, "")
if err != nil {
return nil, err
}
@ -195,6 +203,31 @@ func (l *listener) handshake(ctx context.Context, sess *webtransport.Session) (c
}, nil
}
func (l *listener) checkEarlyData(b []byte) error {
var msg pb.WebTransport
if err := msg.Unmarshal(b); err != nil {
fmt.Println(1)
return fmt.Errorf("failed to unmarshal early data protobuf: %w", err)
}
if l.isStaticTLSConf {
if len(msg.CertHashes) > 0 {
return errors.New("using static TLS config, didn't expect any certificate hashes")
}
return nil
}
hashes := make([]multihash.DecodedMultihash, 0, len(msg.CertHashes))
for _, h := range msg.CertHashes {
dh, err := multihash.Decode(h)
if err != nil {
return fmt.Errorf("failed to decode hash: %w", err)
}
hashes = append(hashes, *dh)
}
return l.certManager.Verify(hashes)
}
func (l *listener) Addr() net.Addr {
return l.addr
}

8
p2p/transport/webtransport/mock_connection_gater_test.go

@ -1,5 +1,5 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: github.com/libp2p/go-libp2p-core/connmgr (interfaces: ConnectionGater)
// Source: github.com/libp2p/go-libp2p/core/connmgr (interfaces: ConnectionGater)
// Package libp2pwebtransport_test is a generated GoMock package.
package libp2pwebtransport_test
@ -8,9 +8,9 @@ import (
reflect "reflect"
gomock "github.com/golang/mock/gomock"
control "github.com/libp2p/go-libp2p-core/control"
network "github.com/libp2p/go-libp2p-core/network"
peer "github.com/libp2p/go-libp2p-core/peer"
control "github.com/libp2p/go-libp2p/core/control"
network "github.com/libp2p/go-libp2p/core/network"
peer "github.com/libp2p/go-libp2p/core/peer"
multiaddr "github.com/multiformats/go-multiaddr"
)

34
p2p/transport/webtransport/noise_early_data.go

@ -0,0 +1,34 @@
package libp2pwebtransport
import (
"context"
"github.com/libp2p/go-libp2p/core/peer"
"github.com/libp2p/go-libp2p/p2p/security/noise"
"net"
)
type earlyDataHandler struct {
earlyData []byte
receive func([]byte) error
}
var _ noise.EarlyDataHandler = &earlyDataHandler{}
func newEarlyDataSender(earlyData []byte) noise.EarlyDataHandler {
return &earlyDataHandler{earlyData: earlyData}
}
func newEarlyDataReceiver(receive func([]byte) error) noise.EarlyDataHandler {
return &earlyDataHandler{receive: receive}
}
func (e *earlyDataHandler) Send(context.Context, net.Conn, peer.ID) []byte {
return e.earlyData
}
func (e *earlyDataHandler) Received(_ context.Context, _ net.Conn, b []byte) error {
if e.receive == nil {
return nil
}
return e.receive(b)
}

2
p2p/transport/webtransport/stream.go

@ -6,7 +6,7 @@ import (
"github.com/marten-seemann/webtransport-go"
"github.com/libp2p/go-libp2p-core/network"
"github.com/libp2p/go-libp2p/core/network"
)
const (

48
p2p/transport/webtransport/transport.go

@ -4,7 +4,6 @@ import (
"context"
"crypto/tls"
"crypto/x509"
"errors"
"fmt"
"io"
"sync"
@ -12,13 +11,12 @@ import (
pb "github.com/marten-seemann/go-libp2p-webtransport/pb"
"github.com/libp2p/go-libp2p-core/connmgr"
ic "github.com/libp2p/go-libp2p-core/crypto"
"github.com/libp2p/go-libp2p-core/network"
"github.com/libp2p/go-libp2p-core/peer"
tpt "github.com/libp2p/go-libp2p-core/transport"
noise "github.com/libp2p/go-libp2p-noise"
"github.com/libp2p/go-libp2p/core/connmgr"
ic "github.com/libp2p/go-libp2p/core/crypto"
"github.com/libp2p/go-libp2p/core/network"
"github.com/libp2p/go-libp2p/core/peer"
tpt "github.com/libp2p/go-libp2p/core/transport"
"github.com/libp2p/go-libp2p/p2p/security/noise"
"github.com/benbjohnson/clock"
logging "github.com/ipfs/go-log/v2"
@ -102,11 +100,11 @@ func New(key ic.PrivKey, gater connmgr.ConnectionGater, rcmgr network.ResourceMa
return nil, err
}
}
noise, err := noise.New(key, noise.WithEarlyDataHandler(t.checkEarlyData))
n, err := noise.New(key)
if err != nil {
return nil, err
}
t.noise = noise
t.noise = n
return t, nil
}
@ -207,7 +205,11 @@ func (t *transport) upgrade(ctx context.Context, sess *webtransport.Session, p p
if err != nil {
return nil, fmt.Errorf("failed to marshal WebTransport protobuf: %w", err)
}
c, err := t.noise.SecureOutboundWithEarlyData(ctx, &webtransportStream{Stream: str, wsess: sess}, p, msgBytes)
n, err := t.noise.WithSessionOptions(noise.EarlyData(newEarlyDataSender(msgBytes)))
if err != nil {
return nil, fmt.Errorf("failed to create Noise transport: %w", err)
}
c, err := n.SecureOutbound(ctx, &webtransportStream{Stream: str, wsess: sess}, p)
if err != nil {
return nil, err
}
@ -217,30 +219,6 @@ func (t *transport) upgrade(ctx context.Context, sess *webtransport.Session, p p
}, nil
}
func (t *transport) checkEarlyData(b []byte) error {
var msg pb.WebTransport
if err := msg.Unmarshal(b); err != nil {
return fmt.Errorf("failed to unmarshal early data protobuf: %w", err)
}
hashes := make([]multihash.DecodedMultihash, 0, len(msg.CertHashes))
if t.staticTLSConf != nil {
if len(hashes) > 0 {
return errors.New("using static TLS config, didn't expect any certificate hashes")
}
return nil
}
for _, h := range msg.CertHashes {
dh, err := multihash.Decode(h)
if err != nil {
return fmt.Errorf("failed to decode hash: %w", err)
}
hashes = append(hashes, *dh)
}
return t.certManager.Verify(hashes)
}
func (t *transport) CanDial(addr ma.Multiaddr) bool {
var numHashes int
ma.ForEach(addr, func(c ma.Component) bool {

10
p2p/transport/webtransport/transport_test.go

@ -20,12 +20,12 @@ import (
libp2pwebtransport "github.com/marten-seemann/go-libp2p-webtransport"
ic "github.com/libp2p/go-libp2p-core/crypto"
"github.com/libp2p/go-libp2p-core/network"
"github.com/libp2p/go-libp2p-core/peer"
ic "github.com/libp2p/go-libp2p/core/crypto"
"github.com/libp2p/go-libp2p/core/network"
mocknetwork "github.com/libp2p/go-libp2p/core/network/mocks"
"github.com/libp2p/go-libp2p/core/peer"
"github.com/golang/mock/gomock"
mocknetwork "github.com/libp2p/go-libp2p-testing/mocks/network"
ma "github.com/multiformats/go-multiaddr"
manet "github.com/multiformats/go-multiaddr/net"
"github.com/multiformats/go-multibase"
@ -338,7 +338,7 @@ func TestResourceManagerListening(t *testing.T) {
}
// TODO: unify somehow. We do the same in libp2pquic.
//go:generate sh -c "mockgen -package libp2pwebtransport_test -destination mock_connection_gater_test.go github.com/libp2p/go-libp2p-core/connmgr ConnectionGater && goimports -w mock_connection_gater_test.go"
//go:generate sh -c "mockgen -package libp2pwebtransport_test -destination mock_connection_gater_test.go github.com/libp2p/go-libp2p/core/connmgr ConnectionGater && goimports -w mock_connection_gater_test.go"
func TestConnectionGaterDialing(t *testing.T) {
ctrl := gomock.NewController(t)

Loading…
Cancel
Save