github.com/turingchain2020/turingchain@v1.1.21/system/p2p/dht/extension/relay.go (about)

     1  package extension
     2  
     3  import (
     4  	"context"
     5  	"time"
     6  
     7  	circuit "github.com/libp2p/go-libp2p-circuit"
     8  	coredis "github.com/libp2p/go-libp2p-core/discovery"
     9  	host "github.com/libp2p/go-libp2p-core/host"
    10  	"github.com/libp2p/go-libp2p-core/peer"
    11  	discovery "github.com/libp2p/go-libp2p-discovery"
    12  	swarm "github.com/libp2p/go-libp2p-swarm"
    13  	swarmt "github.com/libp2p/go-libp2p-swarm/testing"
    14  	relay "github.com/libp2p/go-libp2p/p2p/host/relay"
    15  )
    16  
    17  // Relay p2p relay
    18  type Relay struct {
    19  	advertise *discovery.RoutingDiscovery
    20  	crelay    *circuit.Relay
    21  }
    22  
    23  func newRelay(ctx context.Context, host host.Host, opts ...circuit.RelayOpt) (*circuit.Relay, error) {
    24  	r, err := circuit.NewRelay(ctx, host, swarmt.GenUpgrader(host.Network().(*swarm.Swarm)), opts...)
    25  	if err != nil {
    26  		return nil, err
    27  	}
    28  	return r, nil
    29  }
    30  
    31  // NewRelayDiscovery new relay discovery
    32  func NewRelayDiscovery(host host.Host, adv *discovery.RoutingDiscovery, opts ...circuit.RelayOpt) *Relay {
    33  	r := new(Relay)
    34  	r.advertise = adv
    35  	var err error
    36  	r.crelay, err = newRelay(context.Background(), host, opts...)
    37  	if err != nil {
    38  		return nil
    39  	}
    40  	return r
    41  }
    42  
    43  // Advertise 如果自己支持relay模式,愿意充当relay中继器,则需要调用此函数
    44  func (r *Relay) Advertise(ctx context.Context) {
    45  	discovery.Advertise(ctx, r.advertise, relay.RelayRendezvous)
    46  }
    47  
    48  // FindOpPeers 如果需要用到中继相关功能,则需要先调用FindOpPeers查找到relay中继节点
    49  func (r *Relay) FindOpPeers() ([]peer.AddrInfo, error) {
    50  	dctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
    51  	defer cancel()
    52  	return discovery.FindPeers(dctx, r.advertise, relay.RelayRendezvous, coredis.Limit(100))
    53  }
    54  
    55  // DialDestPeer 通过hop中继节点连接dst节点
    56  func (r *Relay) DialDestPeer(hop, dst peer.AddrInfo) (*circuit.Conn, error) {
    57  
    58  	rctx, rcancel := context.WithTimeout(context.Background(), time.Second)
    59  	defer rcancel()
    60  
    61  	conn, err := r.crelay.DialPeer(rctx, hop, dst)
    62  	return conn, err
    63  
    64  }
    65  
    66  // CheckHOp 检查请求的节点是否支持relay中继
    67  func (r *Relay) CheckHOp(isop peer.ID) (bool, error) {
    68  
    69  	rctx, rcancel := context.WithTimeout(context.Background(), time.Second)
    70  	defer rcancel()
    71  	canhop, err := r.crelay.CanHop(rctx, isop)
    72  	if err != nil {
    73  		return false, err
    74  	}
    75  
    76  	if !canhop {
    77  		return false, nil
    78  	}
    79  	return true, nil
    80  }