diff --git a/cmd/ipfs/daemon.go b/cmd/ipfs/daemon.go index 09a63d293..cf6c22c01 100644 --- a/cmd/ipfs/daemon.go +++ b/cmd/ipfs/daemon.go @@ -347,6 +347,11 @@ func daemonFunc(req cmds.Request, res cmds.Response) { } node.SetLocal(false) + if node.PNetFingerpint != nil { + fmt.Println("Swarm is limited to private network of peers with the swarm key") + fmt.Printf("Swarm key fingerprint: %x\n", node.PNetFingerpint) + } + printSwarmAddrs(node) defer func() { diff --git a/core/core.go b/core/core.go index aa660c0fe..9136c4f28 100644 --- a/core/core.go +++ b/core/core.go @@ -10,6 +10,7 @@ interfaces and how core/... fits into the bigger IPFS picture, see: package core import ( + "bytes" "context" "errors" "fmt" @@ -44,6 +45,7 @@ import ( ic "gx/ipfs/QmNiCwBNA8MWDADTFVq1BonUEJbS2SvjAoNkZZrhEwcuUi/go-libp2p-crypto" addrutil "gx/ipfs/QmPB5aAzt2wo5Xk8SoZi6y2oFN7shQMvYWgduMATojkdpj/go-addr-util" metrics "gx/ipfs/QmPj6rmE2sWJ65h6b8F4fcN5kySDhYqL2Ty8DWWF3WEUNS/go-libp2p-metrics" + pnet "gx/ipfs/QmQ2sk2irQYkeMMVKpLjq1bSiNPn9B5wZB53Nx8dd4dhnQ/go-libp2p-pnet" mplex "gx/ipfs/QmQ3UABWTgK78utKeiVXaH9BrjC7Ydn1pRuwqnWHT3p4zh/go-smux-multiplex" floodsub "gx/ipfs/QmQDb7jmfC33qzGUGpWrfgRootQnmQvN7DMktfuekShsiF/floodsub" pstore "gx/ipfs/QmQMQ2RUjnaEEX8ybmrhuFFGhAwPjyL1Eo6ZoJGD7aAccM/go-libp2p-peerstore" @@ -67,6 +69,7 @@ import ( u "gx/ipfs/QmZuY8aV7zbNXVy6DyN9SmnuH3o9nG852F4aTiSBpts8d1/go-ipfs-util" yamux "gx/ipfs/Qmbn7RYyWzBVXiUp9jZ1dA4VADHy9DtS7iZLwfhEUQvm3U/go-smux-yamux" p2phost "gx/ipfs/QmbzbRyd22gcW92U1rA2yKagB3myMYhk45XBknJ49F9XWJ/go-libp2p-host" + ipnet "gx/ipfs/QmcT6bMjz32yoMdyvZsMvqFnbbsDxhTYw6FG1yMqKV8Rbh/go-libp2p-interface-pnet" smux "gx/ipfs/QmeZBgYBHvxMukGK5ojg28BCNLB9SeXqT7XXg6o7r2GbJy/go-stream-muxer" ) @@ -100,9 +103,10 @@ type IpfsNode struct { Repo repo.Repo // Local node - Pinning pin.Pinner // the pinning manager - Mounts Mounts // current mount state, if any. - PrivateKey ic.PrivKey // the local node's private Key + Pinning pin.Pinner // the pinning manager + Mounts Mounts // current mount state, if any. + PrivateKey ic.PrivKey // the local node's private Key + PNetFingerpint []byte // fingerprint of private network // Services Peerstore pstore.Peerstore // storage for other Peer instances @@ -174,7 +178,22 @@ func (n *IpfsNode) startOnlineServices(ctx context.Context, routingOption Routin tpt := makeSmuxTransport(mplex) - peerhost, err := hostOption(ctx, n.Identity, n.Peerstore, n.Reporter, addrfilter, tpt) + swarmkey, err := n.Repo.SwarmKey() + if err != nil { + return err + } + + var protec ipnet.Protector + if swarmkey != nil { + protec, err = pnet.NewProtector(bytes.NewReader(swarmkey)) + if err != nil { + return err + } + n.PNetFingerpint = protec.Fingerprint() + } + + peerhost, err := hostOption(ctx, n.Identity, n.Peerstore, n.Reporter, + addrfilter, tpt, protec) if err != nil { return err } @@ -671,15 +690,15 @@ func listenAddresses(cfg *config.Config) ([]ma.Multiaddr, error) { return listen, nil } -type HostOption func(ctx context.Context, id peer.ID, ps pstore.Peerstore, bwr metrics.Reporter, fs []*net.IPNet, tpt smux.Transport) (p2phost.Host, error) +type HostOption func(ctx context.Context, id peer.ID, ps pstore.Peerstore, bwr metrics.Reporter, fs []*net.IPNet, tpt smux.Transport, protc ipnet.Protector) (p2phost.Host, error) var DefaultHostOption HostOption = constructPeerHost // isolates the complex initialization steps -func constructPeerHost(ctx context.Context, id peer.ID, ps pstore.Peerstore, bwr metrics.Reporter, fs []*net.IPNet, tpt smux.Transport) (p2phost.Host, error) { +func constructPeerHost(ctx context.Context, id peer.ID, ps pstore.Peerstore, bwr metrics.Reporter, fs []*net.IPNet, tpt smux.Transport, protec ipnet.Protector) (p2phost.Host, error) { // no addresses to begin with. we'll start later. - swrm, err := swarm.NewSwarmWithProtector(ctx, nil, id, ps, nil, tpt, bwr) + swrm, err := swarm.NewSwarmWithProtector(ctx, nil, id, ps, protec, tpt, bwr) if err != nil { return nil, err } diff --git a/core/mock/mock.go b/core/mock/mock.go index 110ae3c47..a021b031d 100644 --- a/core/mock/mock.go +++ b/core/mock/mock.go @@ -18,6 +18,7 @@ import ( mocknet "gx/ipfs/QmU3g3psEDiC4tQh1Qu2NYg5aYVQqxC3m74ZavLwPfJEtu/go-libp2p/p2p/net/mock" peer "gx/ipfs/QmZcUPvPhD1Xvk6mwijYF8AfR3mG31S1YsEfHG4khrFPRr/go-libp2p-peer" host "gx/ipfs/QmbzbRyd22gcW92U1rA2yKagB3myMYhk45XBknJ49F9XWJ/go-libp2p-host" + ipnet "gx/ipfs/QmcT6bMjz32yoMdyvZsMvqFnbbsDxhTYw6FG1yMqKV8Rbh/go-libp2p-interface-pnet" smux "gx/ipfs/QmeZBgYBHvxMukGK5ojg28BCNLB9SeXqT7XXg6o7r2GbJy/go-stream-muxer" ) @@ -33,7 +34,7 @@ func NewMockNode() (*core.IpfsNode, error) { } func MockHostOption(mn mocknet.Mocknet) core.HostOption { - return func(ctx context.Context, id peer.ID, ps pstore.Peerstore, bwr metrics.Reporter, fs []*net.IPNet, _ smux.Transport) (host.Host, error) { + return func(ctx context.Context, id peer.ID, ps pstore.Peerstore, bwr metrics.Reporter, fs []*net.IPNet, _ smux.Transport, _ ipnet.Protector) (host.Host, error) { return mn.AddPeerWithPeerstore(id, ps) } } diff --git a/package.json b/package.json index 73ad3b630..d90d27eca 100644 --- a/package.json +++ b/package.json @@ -294,6 +294,12 @@ "hash": "QmU1N5xVAUXgo3XRTt6GhJ2SuJEbxj2zRgMS7FpjSR2U83", "name": "semver", "version": "3.3.0" + }, + { + "author": "libp2p", + "hash": "QmQ2sk2irQYkeMMVKpLjq1bSiNPn9B5wZB53Nx8dd4dhnQ", + "name": "go-libp2p-pnet", + "version": "2.2.1" } ], "gxVersion": "0.10.0", diff --git a/repo/fsrepo/fsrepo.go b/repo/fsrepo/fsrepo.go index 4ea8d31d2..1abbe62a1 100644 --- a/repo/fsrepo/fsrepo.go +++ b/repo/fsrepo/fsrepo.go @@ -4,6 +4,7 @@ import ( "errors" "fmt" "io" + "io/ioutil" "os" "path/filepath" "strconv" @@ -62,6 +63,7 @@ func (err NoRepoError) Error() string { } const apiFile = "api" +const swarmKeyFile = "swarm.key" var ( @@ -592,6 +594,26 @@ func (r *FSRepo) GetStorageUsage() (uint64, error) { return du, err } +func (r *FSRepo) SwarmKey() ([]byte, error) { + repoPath := filepath.Clean(r.path) + spath := filepath.Join(repoPath, swarmKeyFile) + + f, err := os.Open(spath) + if err != nil { + if os.IsNotExist(err) { + return nil, nil + } else { + return nil, err + } + } + defer f.Close() + if err != nil { + return nil, err + } + + return ioutil.ReadAll(f) +} + var _ io.Closer = &FSRepo{} var _ repo.Repo = &FSRepo{} diff --git a/repo/mock.go b/repo/mock.go index 3aae13bf7..07151fca9 100644 --- a/repo/mock.go +++ b/repo/mock.go @@ -44,3 +44,7 @@ func (m *Mock) Close() error { return errTODO } func (m *Mock) SetAPIAddr(addr ma.Multiaddr) error { return errTODO } func (m *Mock) Keystore() keystore.Keystore { return nil } + +func (m *Mock) SwarmKey() ([]byte, error) { + return nil, nil +} diff --git a/repo/repo.go b/repo/repo.go index 5e8824d80..493d06e08 100644 --- a/repo/repo.go +++ b/repo/repo.go @@ -30,6 +30,8 @@ type Repo interface { // SetAPIAddr sets the API address in the repo. SetAPIAddr(addr ma.Multiaddr) error + SwarmKey() ([]byte, error) + io.Closer }