core: make announced swarm addresses configurable
License: MIT Signed-off-by: Lars Gierth <larsg@systemli.org>
Lars Gierth committed
May 31, 2017 at 02:49 UTC
952f658ada36f2b2c9fb737a8134a2968bfe37f6
7 files changed
+140
-8
cmd/ipfs/daemon.go
+16
-2
@@ -497,15 +497,29 @@ func printSwarmAddrs(node *core.IpfsNode) {
497
fmt.Println("Swarm not listening, running in offline mode.")
498
return
499
}
500
+
501
+ var lisAddrs []string
502
+ ifaceAddrs, err := node.PeerHost.Network().InterfaceListenAddresses()
503
+ if err != nil {
504
+ log.Errorf("failed to read listening addresses: %s", err)
505
+ }
506
+ for _, addr := range ifaceAddrs {
507
+ lisAddrs = append(lisAddrs, addr.String())
508
+ }
509
+ sort.Sort(sort.StringSlice(lisAddrs))
510
+ for _, addr := range lisAddrs {
511
+ fmt.Printf("Swarm listening on %s\n", addr)
512
+ }
513
+
514
var addrs []string
515
for _, addr := range node.PeerHost.Addrs() {
516
addrs = append(addrs, addr.String())
517
}
518
sort.Sort(sort.StringSlice(addrs))
505
-
519
for _, addr := range addrs {
507
- fmt.Printf("Swarm listening on %s\n", addr)
520
+ fmt.Printf("Swarm announcing %s\n", addr)
521
}
522
+
523
}
524
525
// serveHTTPGateway collects options, creates listener, prints status message and starts serving requests
core/core.go
+61
-1
@@ -45,6 +45,7 @@ import (
45
pnet "gx/ipfs/QmNMCAuxnQFHLGWcvay3DmVFrKuY6Y2nsc9vzsf4gVouJV/go-libp2p-pnet"
46
pstore "gx/ipfs/QmPgDWmTmuzvP7QE5zwo1TmjbJme9pmZHNujB2453jkCTr/go-libp2p-peerstore"
47
routing "gx/ipfs/QmPjTrrSfE6TzLv6ya6VWhGcCgPrUAdcgrDcQyRDX2VyW1/go-libp2p-routing"
48
+ mafilter "gx/ipfs/QmQBB2dQLmQHJgs2gqZ3iqL2XiuCtUCvXzWt5kMXDf5Zcr/go-maddr-filter"
49
ipnet "gx/ipfs/QmQq9YzmdFdWNTDdArueGyD7L5yyiRQigrRHJnTGkxcEjT/go-libp2p-interface-pnet"
50
dht "gx/ipfs/QmRKEzkaiwud2LnwJ9CgBrKw122ddKPTMtLizV3DNimVRD/go-libp2p-kad-dht"
51
p2phost "gx/ipfs/QmRNyPNJGNCaZyYonJj7owciWTsMd9gRfEKmZY3o6xwN3h/go-libp2p-host"
@@ -212,8 +213,17 @@ func (n *IpfsNode) startOnlineServices(ctx context.Context, routingOption Routin
213
}()
214
}
215
216
+ addrsFactory, err := makeAddrsFactory(cfg.Addresses)
217
+ if err != nil {
218
+ return err
219
+ }
220
+
221
+ hostopts := &ConstructPeerHostOpts{
222
+ AddrsFactory: addrsFactory,
223
+ DisableNatPortMap: cfg.Swarm.DisableNatPortMap,
224
+ }
225
peerhost, err := hostOption(ctx, n.Identity, n.Peerstore, n.Reporter,
216
- addrfilter, tpt, protec, &ConstructPeerHostOpts{DisableNatPortMap: cfg.Swarm.DisableNatPortMap})
226
+ addrfilter, tpt, protec, hostopts)
227
if err != nil {
228
return err
229
}
@@ -263,6 +273,52 @@ func (n *IpfsNode) startOnlineServices(ctx context.Context, routingOption Routin
273
return n.Bootstrap(DefaultBootstrapConfig)
274
}
275
276
+func makeAddrsFactory(cfg config.Addresses) (p2pbhost.AddrsFactory, error) {
277
+ var annAddrs []ma.Multiaddr
278
+ for _, addr := range cfg.Announce {
279
+ maddr, err := ma.NewMultiaddr(addr)
280
+ if err != nil {
281
+ return nil, err
282
+ }
283
+ annAddrs = append(annAddrs, maddr)
284
+ }
285
+
286
+ filters := mafilter.NewFilters()
287
+ noAnnAddrs := map[string]bool{}
288
+ for _, addr := range cfg.NoAnnounce {
289
+ f, err := mamask.NewMask(addr)
290
+ if err == nil {
291
+ filters.AddDialFilter(f)
292
+ continue
293
+ }
294
+ maddr, err := ma.NewMultiaddr(addr)
295
+ if err != nil {
296
+ return nil, err
297
+ }
298
+ noAnnAddrs[maddr.String()] = true
299
+ }
300
+
301
+ return func(allAddrs []ma.Multiaddr) []ma.Multiaddr {
302
+ var addrs []ma.Multiaddr
303
+ if len(annAddrs) > 0 {
304
+ addrs = annAddrs
305
+ } else {
306
+ addrs = allAddrs
307
+ }
308
+
309
+ var out []ma.Multiaddr
310
+ for _, maddr := range addrs {
311
+ // check for exact matches
312
+ ok, _ := noAnnAddrs[maddr.String()]
313
+ // check for /ipcidr matches
314
+ if !ok && !filters.AddrBlocked(maddr) {
315
+ out = append(out, maddr)
316
+ }
317
+ }
318
+ return out
319
+ }, nil
320
+}
321
+
322
func makeSmuxTransport(mplexExp bool) smux.Transport {
323
mstpt := mssmux.NewBlankTransport()
324
@@ -705,6 +761,7 @@ func listenAddresses(cfg *config.Config) ([]ma.Multiaddr, error) {
761
762
type ConstructPeerHostOpts struct {
763
DisableNatPortMap bool
764
+ AddrsFactory p2pbhost.AddrsFactory
765
}
766
767
type HostOption func(ctx context.Context, id peer.ID, ps pstore.Peerstore, bwr metrics.Reporter, fs []*net.IPNet, tpt smux.Transport, protc ipnet.Protector, opts *ConstructPeerHostOpts) (p2phost.Host, error)
@@ -730,6 +787,9 @@ func constructPeerHost(ctx context.Context, id peer.ID, ps pstore.Peerstore, bwr
787
if !opts.DisableNatPortMap {
788
hostOpts = append(hostOpts, p2pbhost.NATPortMap)
789
}
790
+ if opts.AddrsFactory != nil {
791
+ hostOpts = append(hostOpts, opts.AddrsFactory)
792
+ }
793
794
host := p2pbhost.New(network, hostOpts...)
795
package.json
+5
@@ -446,6 +446,11 @@
446
"hash": "Qma7Kuwun7w8SZphjEPDVxvGfetBkqdNGmigDA13sJdLex",
447
"name": "go-ipld-git",
448
"version": "0.1.3"
449
+ },
450
+ {
451
+ "hash": "QmQBB2dQLmQHJgs2gqZ3iqL2XiuCtUCvXzWt5kMXDf5Zcr",
452
+ "name": "go-maddr-filter",
453
+ "version": "1.1.4"
454
}
455
],
456
"gxVersion": "0.10.0",
repo/config/addresses.go
+5
-3
@@ -2,7 +2,9 @@ package config
2
3
// Addresses stores the (string) multiaddr addresses for the node.
4
type Addresses struct {
5
- Swarm []string // addresses for the swarm network
6
- API string // address for the local API (RPC)
7
- Gateway string // address to listen on for IPFS HTTP object gateway
5
+ Swarm []string // addresses for the swarm to listen on
6
+ Announce []string // swarm addresses to announce to the network
7
+ NoAnnounce []string // swarm addresses not to announce to the network
8
+ API string // address for the local API (RPC)
9
+ Gateway string // address to listen on for IPFS HTTP object gateway
10
}
repo/config/init.go
+4
-2
@@ -36,8 +36,10 @@ func Init(out io.Writer, nBitsForKeypair int) (*Config, error) {
36
// "/ip4/0.0.0.0/udp/4002/utp", // disabled for now.
37
"/ip6/::/tcp/4001",
38
},
39
- API: "/ip4/127.0.0.1/tcp/5001",
40
- Gateway: "/ip4/127.0.0.1/tcp/8080",
39
+ Announce: []string{},
40
+ NoAnnounce: []string{},
41
+ API: "/ip4/127.0.0.1/tcp/5001",
42
+ Gateway: "/ip4/127.0.0.1/tcp/8080",
43
},
44
45
Datastore: datastore,
test/sharness/t0060-daemon.sh
+1
@@ -39,6 +39,7 @@ test_expect_success "ipfs daemon output looks good" '
39
STARTFILE="ipfs cat /ipfs/$HASH_WELCOME_DOCS/readme" &&
40
echo "Initializing daemon..." >expected_daemon &&
41
sed "s/^/Swarm listening on /" local_addrs >>expected_daemon &&
42
+ sed "s/^/Swarm announcing /" local_addrs >>expected_daemon &&
43
echo "API server listening on '$API_MADDR'" >>expected_daemon &&
44
echo "Gateway (readonly) server listening on '$GWAY_MADDR'" >>expected_daemon &&
45
echo "Daemon is ready" >>expected_daemon &&
test/sharness/t0140-swarm.sh
+48
@@ -49,4 +49,52 @@ test_expect_success "cant trigger a dial backoff with swarm connect" '
49
50
test_kill_ipfs_daemon
51
52
+announceCfg='["/ip4/127.0.0.1/tcp/4001", "/ip4/1.2.3.4/tcp/1234"]'
53
+test_expect_success "test_config_set succeeds" "
54
+ ipfs config --json Addresses.Announce '$announceCfg'
55
+"
56
+
57
+test_launch_ipfs_daemon
58
+
59
+test_expect_success 'Addresses.Announce affects addresses' '
60
+ ipfs swarm addrs local >actual &&
61
+ grep "/ip4/1.2.3.4/tcp/1234" actual &&
62
+ ipfs id -f"<addrs>" | xargs -n1 echo >actual &&
63
+ grep "/ip4/1.2.3.4/tcp/1234" actual
64
+'
65
+
66
+test_kill_ipfs_daemon
67
+
68
+noAnnounceCfg='["/ip4/1.2.3.4/tcp/1234"]'
69
+test_expect_success "test_config_set succeeds" "
70
+ ipfs config --json Addresses.NoAnnounce '$noAnnounceCfg'
71
+"
72
+
73
+test_launch_ipfs_daemon
74
+
75
+test_expect_success "Addresses.NoAnnounce affects addresses" '
76
+ ipfs swarm addrs local >actual &&
77
+ grep -v "/ip4/1.2.3.4/tcp/1234" actual &&
78
+ ipfs id -f"<addrs>" | xargs -n1 echo >actual &&
79
+ grep -v "/ip4/1.2.3.4/tcp/1234" actual
80
+'
81
+
82
+test_kill_ipfs_daemon
83
+
84
+noAnnounceCfg='["/ip4/1.2.3.4/ipcidr/16"]'
85
+test_expect_success "test_config_set succeeds" "
86
+ ipfs config --json Addresses.NoAnnounce '$noAnnounceCfg'
87
+"
88
+
89
+test_launch_ipfs_daemon
90
+
91
+test_expect_success "Addresses.NoAnnounce with /ipcidr affects addresses" '
92
+ ipfs swarm addrs local >actual &&
93
+ grep -v "/ip4/1.2.3.4/tcp/1234" actual &&
94
+ ipfs id -f"<addrs>" | xargs -n1 echo >actual &&
95
+ grep -v "/ip4/1.2.3.4/tcp/1234" actual
96
+'
97
+
98
+test_kill_ipfs_daemon
99
+
100
test_done