2018-03-13 17:16:15 +00:00
|
|
|
package ipfscluster
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"encoding/hex"
|
|
|
|
|
2019-05-06 08:19:46 +00:00
|
|
|
"github.com/ipfs/ipfs-cluster/config"
|
2018-03-13 17:16:15 +00:00
|
|
|
libp2p "github.com/libp2p/go-libp2p"
|
2019-09-26 08:10:12 +00:00
|
|
|
relay "github.com/libp2p/go-libp2p-circuit"
|
2019-05-22 22:34:47 +00:00
|
|
|
connmgr "github.com/libp2p/go-libp2p-connmgr"
|
2019-09-26 08:10:12 +00:00
|
|
|
routing "github.com/libp2p/go-libp2p-core/routing"
|
2019-02-20 14:24:25 +00:00
|
|
|
crypto "github.com/libp2p/go-libp2p-crypto"
|
2018-03-13 17:16:15 +00:00
|
|
|
host "github.com/libp2p/go-libp2p-host"
|
|
|
|
ipnet "github.com/libp2p/go-libp2p-interface-pnet"
|
2019-02-20 14:24:25 +00:00
|
|
|
dht "github.com/libp2p/go-libp2p-kad-dht"
|
2018-03-13 17:16:15 +00:00
|
|
|
pnet "github.com/libp2p/go-libp2p-pnet"
|
2019-02-20 14:24:25 +00:00
|
|
|
pubsub "github.com/libp2p/go-libp2p-pubsub"
|
|
|
|
routedhost "github.com/libp2p/go-libp2p/p2p/host/routed"
|
2018-03-13 17:16:15 +00:00
|
|
|
)
|
|
|
|
|
2019-02-20 14:24:25 +00:00
|
|
|
// NewClusterHost creates a libp2p Host with the options from the provided
|
|
|
|
// cluster configuration. Using that host, it creates pubsub and a DHT
|
|
|
|
// instances, for shared use by all cluster components. The returned host uses
|
|
|
|
// the DHT for routing. The resulting DHT is not bootstrapped.
|
|
|
|
func NewClusterHost(
|
|
|
|
ctx context.Context,
|
2019-05-06 08:19:46 +00:00
|
|
|
ident *config.Identity,
|
2019-05-06 08:54:31 +00:00
|
|
|
cfg *Config,
|
2019-08-24 15:09:54 +00:00
|
|
|
) (host.Host, *pubsub.PubSub, *dht.IpfsDHT, error) {
|
2019-02-20 14:24:25 +00:00
|
|
|
|
2019-05-22 22:34:47 +00:00
|
|
|
connman := connmgr.NewConnManager(cfg.ConnMgr.LowWater, cfg.ConnMgr.HighWater, cfg.ConnMgr.GracePeriod)
|
|
|
|
|
2018-08-15 10:30:00 +00:00
|
|
|
h, err := newHost(
|
|
|
|
ctx,
|
|
|
|
cfg.Secret,
|
|
|
|
ident.PrivateKey,
|
|
|
|
libp2p.ListenAddrs(cfg.ListenAddr),
|
|
|
|
libp2p.NATPortMap(),
|
2019-05-22 22:34:47 +00:00
|
|
|
libp2p.ConnectionManager(connman),
|
2018-08-15 10:30:00 +00:00
|
|
|
)
|
2019-02-20 14:24:25 +00:00
|
|
|
if err != nil {
|
2019-08-24 15:09:54 +00:00
|
|
|
return nil, nil, nil, err
|
2019-02-20 14:24:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
psub, err := newPubSub(ctx, h)
|
|
|
|
if err != nil {
|
|
|
|
h.Close()
|
2019-08-24 15:09:54 +00:00
|
|
|
return nil, nil, nil, err
|
2019-02-20 14:24:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
idht, err := newDHT(ctx, h)
|
|
|
|
if err != nil {
|
|
|
|
h.Close()
|
2019-08-24 15:09:54 +00:00
|
|
|
return nil, nil, nil, err
|
2019-02-20 14:24:25 +00:00
|
|
|
}
|
|
|
|
|
2019-08-24 15:09:54 +00:00
|
|
|
return routedHost(h, idht), psub, idht, nil
|
2019-02-20 14:24:25 +00:00
|
|
|
}
|
|
|
|
|
2018-08-15 10:30:00 +00:00
|
|
|
func newHost(ctx context.Context, secret []byte, priv crypto.PrivKey, opts ...libp2p.Option) (host.Host, error) {
|
2018-03-13 17:16:15 +00:00
|
|
|
var prot ipnet.Protector
|
2018-03-15 15:41:06 +00:00
|
|
|
var err error
|
2018-03-13 17:16:15 +00:00
|
|
|
|
|
|
|
// Create protector if we have a secret.
|
2019-02-20 14:24:25 +00:00
|
|
|
if secret != nil && len(secret) > 0 {
|
2018-03-15 15:41:06 +00:00
|
|
|
var key [32]byte
|
2019-02-20 14:24:25 +00:00
|
|
|
copy(key[:], secret)
|
2018-03-15 15:41:06 +00:00
|
|
|
prot, err = pnet.NewV1ProtectorFromBytes(&key)
|
2018-03-13 17:16:15 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-08-15 10:30:00 +00:00
|
|
|
finalOpts := []libp2p.Option{
|
2019-02-20 14:24:25 +00:00
|
|
|
libp2p.Identity(priv),
|
2018-03-13 17:16:15 +00:00
|
|
|
libp2p.PrivateNetwork(prot),
|
2019-09-26 08:10:12 +00:00
|
|
|
libp2p.Routing(func(h host.Host) (routing.PeerRouting, error) {
|
|
|
|
return dht.New(ctx, h)
|
|
|
|
}),
|
|
|
|
libp2p.EnableRelay(relay.OptHop, relay.OptDiscovery),
|
|
|
|
libp2p.EnableAutoRelay(),
|
2018-08-15 10:30:00 +00:00
|
|
|
}
|
|
|
|
finalOpts = append(finalOpts, opts...)
|
|
|
|
|
|
|
|
return libp2p.New(
|
|
|
|
ctx,
|
|
|
|
finalOpts...,
|
2018-03-13 17:16:15 +00:00
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2019-02-20 14:24:25 +00:00
|
|
|
func newDHT(ctx context.Context, h host.Host) (*dht.IpfsDHT, error) {
|
|
|
|
return dht.New(ctx, h)
|
|
|
|
}
|
|
|
|
|
|
|
|
func newPubSub(ctx context.Context, h host.Host) (*pubsub.PubSub, error) {
|
|
|
|
return pubsub.NewGossipSub(
|
|
|
|
ctx,
|
|
|
|
h,
|
|
|
|
pubsub.WithMessageSigning(true),
|
|
|
|
pubsub.WithStrictSignatureVerification(true),
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
func routedHost(h host.Host, d *dht.IpfsDHT) host.Host {
|
|
|
|
return routedhost.Wrap(h, d)
|
|
|
|
}
|
|
|
|
|
2018-03-13 17:16:15 +00:00
|
|
|
// EncodeProtectorKey converts a byte slice to its hex string representation.
|
|
|
|
func EncodeProtectorKey(secretBytes []byte) string {
|
|
|
|
return hex.EncodeToString(secretBytes)
|
|
|
|
}
|