Skip to content

Commit

Permalink
webrtcprivate: integrate connection gater
Browse files Browse the repository at this point in the history
  • Loading branch information
sukunrt committed Sep 22, 2023
1 parent d7cf85a commit 113988f
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 15 deletions.
58 changes: 47 additions & 11 deletions p2p/transport/webrtcprivate/listener.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@ import (
"time"

"github.com/libp2p/go-libp2p/core/network"
"github.com/libp2p/go-libp2p/core/peer"
tpt "github.com/libp2p/go-libp2p/core/transport"
libp2pwebrtc "github.com/libp2p/go-libp2p/p2p/transport/webrtc"
"github.com/libp2p/go-libp2p/p2p/transport/webrtcprivate/pb"
"github.com/libp2p/go-msgio/pbio"
ma "github.com/multiformats/go-multiaddr"
manet "github.com/multiformats/go-multiaddr/net"
"github.com/pion/webrtc/v3"
)

Expand Down Expand Up @@ -259,17 +261,13 @@ func (l *listener) handleIncoming(s network.Stream) {
log.Debugf("connection setup failed, got state: %s", state)
return
case webrtc.PeerConnectionStateConnected:
conn, _ := libp2pwebrtc.NewWebRTCConnection(
network.DirInbound,
pc,
l.transport,
scope,
l.transport.host.ID(),
ma.StringCast("/webrtc"),
s.Conn().RemotePeer(),
l.transport.host.Peerstore().PubKey(s.Conn().RemotePeer()),
ma.StringCast("/webrtc"),
)
conn, err := l.setupConnection(pc, scope, s.Conn().RemotePeer())
if err != nil {
pc.Close()
s.Reset()
log.Debug("connection setup with %s failed: %w", s.Conn().RemotePeer(), err)
return
}
// Close the stream before we wait for the connection to be accepted
s.Close()
select {
Expand All @@ -283,3 +281,41 @@ func (l *listener) handleIncoming(s network.Stream) {
}
}
}

func (l *listener) setupConnection(pc *webrtc.PeerConnection, scope network.ConnManagementScope, p peer.ID) (tpt.CapableConn, error) {
cp, err := getSelectedCandidate(pc)
if cp == nil || err != nil {
return nil, fmt.Errorf("failed to get selected candidate address, got: %s: %w", cp, err)
}
localAddr, err := manet.FromNetAddr(&net.UDPAddr{IP: net.ParseIP(cp.Local.Address), Port: int(cp.Local.Port)})
if err != nil {
return nil, fmt.Errorf("failed to infer local address from candidate %s: %w", cp, err)
}
localAddr = localAddr.Encapsulate(WebRTCAddr)

remoteAddr, err := manet.FromNetAddr(&net.UDPAddr{IP: net.ParseIP(cp.Remote.Address), Port: int(cp.Remote.Port)})
if err != nil {
return nil, fmt.Errorf("failed to infer remote address from candidate %s: %w", cp, err)
}
remoteAddr = remoteAddr.Encapsulate(WebRTCAddr)

conn, err := libp2pwebrtc.NewWebRTCConnection(
network.DirInbound,
pc,
l.transport,
scope,
l.transport.host.ID(),
localAddr,
p,
l.transport.host.Peerstore().PubKey(p), // we have the public key from the relayed connection
remoteAddr,
)
if err != nil {
return nil, fmt.Errorf("failed to create tranport.CapableConn: %w", err)
}
if l.transport.gater != nil && l.transport.gater.InterceptSecured(network.DirOutbound, p, conn) {
conn.Close()
return nil, fmt.Errorf("conn gater refused connection to addr: %s", conn.RemoteMultiaddr())
}
return conn, nil
}
53 changes: 49 additions & 4 deletions p2p/transport/webrtcprivate/transport.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@ import (
"errors"
"fmt"
"io"
"net"
"sync"
"time"

logging "github.com/ipfs/go-log/v2"
"github.com/libp2p/go-libp2p/core/connmgr"
"github.com/libp2p/go-libp2p/core/host"
"github.com/libp2p/go-libp2p/core/network"
pionlogger "github.com/pion/logging"
Expand All @@ -27,6 +29,7 @@ import (

ma "github.com/multiformats/go-multiaddr"
mafmt "github.com/multiformats/go-multiaddr-fmt"
manet "github.com/multiformats/go-multiaddr/net"
)

const (
Expand All @@ -48,6 +51,7 @@ type transport struct {
host host.Host
rcmgr network.ResourceManager
webrtcConfig webrtc.Configuration
gater connmgr.ConnectionGater
maxInFlightConnections int

mu sync.Mutex
Expand Down Expand Up @@ -175,17 +179,45 @@ func (t *transport) dialWithScope(ctx context.Context, p peer.ID, scope network.
s.Reset()
return nil, fmt.Errorf("error establishing webrtc.PeerConnection: %w", err)
}
return libp2pwebrtc.NewWebRTCConnection(

cp, err := getSelectedCandidate(pc)
if cp == nil || err != nil {
s.Reset()
return nil, fmt.Errorf("failed to get selected candidate address, got: %s: %w", cp, err)
}
localAddr, err := manet.FromNetAddr(&net.UDPAddr{IP: net.ParseIP(cp.Local.Address), Port: int(cp.Local.Port)})
if err != nil {
return nil, fmt.Errorf("failed to infer local address from candidate %s: %w", cp, err)
}
localAddr = localAddr.Encapsulate(WebRTCAddr)

remoteAddr, err := manet.FromNetAddr(&net.UDPAddr{IP: net.ParseIP(cp.Remote.Address), Port: int(cp.Remote.Port)})
if err != nil {
return nil, fmt.Errorf("failed to infer remote address from candidate %s: %w", cp, err)
}
remoteAddr = remoteAddr.Encapsulate(WebRTCAddr)

conn, err := libp2pwebrtc.NewWebRTCConnection(
network.DirOutbound,
pc,
t,
scope,
t.host.ID(),
ma.StringCast("/webrtc"),
localAddr,
p,
t.host.Network().Peerstore().PubKey(p),
ma.StringCast("/webrtc"),
t.host.Network().Peerstore().PubKey(p), // we have the pubkey from the relayed connection
remoteAddr,
)
if err != nil {
pc.Close()
return nil, fmt.Errorf("failed to create transport.CapableConn: %w", err)
}

if t.gater != nil && !t.gater.InterceptSecured(network.DirOutbound, p, conn) {
conn.Close()
return nil, fmt.Errorf("conn gater refused connection to addr: %s", conn.RemoteMultiaddr())
}
return conn, nil
}

func (t *transport) establishPeerConnection(ctx context.Context, s network.Stream) (*webrtc.PeerConnection, error) {
Expand Down Expand Up @@ -427,3 +459,16 @@ func getRelayAddr(addr ma.Multiaddr) ma.Multiaddr {
}
return first.Encapsulate(rest)
}

func getSelectedCandidate(pc *webrtc.PeerConnection) (*webrtc.ICECandidatePair, error) {
if pc.SCTP() == nil {
return nil, errors.New("no sctp transport")
}
if pc.SCTP().Transport() == nil {
return nil, errors.New("no dtls transport")
}
if pc.SCTP().Transport().ICETransport() == nil {
return nil, errors.New("no ice transport")
}
return pc.SCTP().Transport().ICETransport().GetSelectedCandidatePair()
}

0 comments on commit 113988f

Please sign in to comment.