bootstrap addrs: moved parsing around
this commit: * moves parsing of bootstrap peers into config * moves location of bootstrap addrs into core/commands * refactor `*BootstrapPeer -> BootstrapPeer
Juan Batiz-Benet committed
Jan 6, 2015 at 00:23 UTC
517d3e99b8df2e7514538cd6e2d0ff0529c1c311
4 files changed
+108
-98
cmd/ipfs/init.go
+9
-32
@@ -12,6 +12,7 @@ import (
12
cmds "github.com/jbenet/go-ipfs/commands"
13
config "github.com/jbenet/go-ipfs/config"
14
core "github.com/jbenet/go-ipfs/core"
15
+ corecmds "github.com/jbenet/go-ipfs/core/commands"
16
imp "github.com/jbenet/go-ipfs/importer"
17
chunk "github.com/jbenet/go-ipfs/importer/chunk"
18
ci "github.com/jbenet/go-ipfs/p2p/crypto"
@@ -179,6 +180,11 @@ func initConfig(configFilename string, dspathOverride string, nBitsForKeypair in
180
return nil, err
181
}
182
183
+ bootstrapPeers, err := corecmds.DefaultBootstrapPeers()
184
+ if err != nil {
185
+ return nil, err
186
+ }
187
+
188
conf := &config.Config{
189
190
// setup the node's default addresses.
@@ -191,39 +197,10 @@ func initConfig(configFilename string, dspathOverride string, nBitsForKeypair in
197
API: "/ip4/127.0.0.1/tcp/5001",
198
},
199
194
- Bootstrap: []*config.BootstrapPeer{
195
- &config.BootstrapPeer{ // Use these hardcoded bootstrap peers for now.
196
- // mars.i.ipfs.io
197
- PeerID: "QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ",
198
- Address: "/ip4/104.131.131.82/tcp/4001",
199
- },
200
- &config.BootstrapPeer{
201
- // Neptune
202
- PeerID: "QmSoLnSGccFuZQJzRadHn95W2CrSFmZuTdDWP8HXaHca9z",
203
- Address: "/ip4/104.236.176.52/tcp/4001",
204
- },
205
- &config.BootstrapPeer{
206
- // Pluto
207
- PeerID: "QmSoLpPVmHKQ4XTPdz8tjDFgdeRFkpV8JgYq8JVJ69RrZm",
208
- Address: "/ip4/104.236.179.241/tcp/4001",
209
- },
210
- &config.BootstrapPeer{
211
- // Uranus
212
- PeerID: "QmSoLueR4xBeUbY9WZ9xGUUxunbKWcrNFTDAadQJmocnWm",
213
- Address: "/ip4/162.243.248.213/tcp/4001",
214
- },
215
- &config.BootstrapPeer{
216
- // Saturn
217
- PeerID: "QmSoLSafTMBsPKadTEgaXctDQVcqN88CNLHXMkTNwMKPnu",
218
- Address: "/ip4/128.199.219.111/tcp/4001",
219
- },
220
- },
221
-
200
+ Bootstrap: bootstrapPeers,
201
Datastore: ds,
223
-
224
- Logs: logConfig,
225
-
226
- Identity: identity,
202
+ Logs: logConfig,
203
+ Identity: identity,
204
205
// setup the node mount points.
206
Mounts: config.Mounts{
config/config.go
+56
-8
@@ -3,8 +3,13 @@ package config
3
4
import (
5
"encoding/base64"
6
+ "errors"
7
"os"
8
"path/filepath"
9
+ "strings"
10
+
11
+ ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
12
+ mh "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multihash"
13
14
ic "github.com/jbenet/go-ipfs/p2p/crypto"
15
u "github.com/jbenet/go-ipfs/util"
@@ -55,6 +60,49 @@ func (bp *BootstrapPeer) String() string {
60
return bp.Address + "/" + bp.PeerID
61
}
62
63
+func ParseBootstrapPeer(addr string) (BootstrapPeer, error) {
64
+ // to be replaced with just multiaddr parsing, once ptp is a multiaddr protocol
65
+ idx := strings.LastIndex(addr, "/")
66
+ if idx == -1 {
67
+ return BootstrapPeer{}, errors.New("invalid address")
68
+ }
69
+ addrS := addr[:idx]
70
+ peeridS := addr[idx+1:]
71
+
72
+ // make sure addrS parses as a multiaddr.
73
+ if len(addrS) > 0 {
74
+ maddr, err := ma.NewMultiaddr(addrS)
75
+ if err != nil {
76
+ return BootstrapPeer{}, err
77
+ }
78
+
79
+ addrS = maddr.String()
80
+ }
81
+
82
+ // make sure idS parses as a peer.ID
83
+ _, err := mh.FromB58String(peeridS)
84
+ if err != nil {
85
+ return BootstrapPeer{}, err
86
+ }
87
+
88
+ return BootstrapPeer{
89
+ Address: addrS,
90
+ PeerID: peeridS,
91
+ }, nil
92
+}
93
+
94
+func ParseBootstrapPeers(addrs []string) ([]BootstrapPeer, error) {
95
+ peers := make([]BootstrapPeer, len(addrs))
96
+ var err error
97
+ for i, addr := range addrs {
98
+ peers[i], err = ParseBootstrapPeer(addr)
99
+ if err != nil {
100
+ return nil, err
101
+ }
102
+ }
103
+ return peers, nil
104
+}
105
+
106
// Tour stores the ipfs tour read-list and resume point
107
type Tour struct {
108
Last string // last tour topic read
@@ -63,14 +111,14 @@ type Tour struct {
111
112
// Config is used to load IPFS config files.
113
type Config struct {
66
- Identity Identity // local node's peer identity
67
- Datastore Datastore // local node's storage
68
- Addresses Addresses // local node's addresses
69
- Mounts Mounts // local node's mount points
70
- Version Version // local node's version management
71
- Bootstrap []*BootstrapPeer // local nodes's bootstrap peers
72
- Tour Tour // local node's tour position
73
- Logs Logs // local node's event log configuration
114
+ Identity Identity // local node's peer identity
115
+ Datastore Datastore // local node's storage
116
+ Addresses Addresses // local node's addresses
117
+ Mounts Mounts // local node's mount points
118
+ Version Version // local node's version management
119
+ Bootstrap []BootstrapPeer // local nodes's bootstrap peers
120
+ Tour Tour // local node's tour position
121
+ Logs Logs // local node's event log configuration
122
}
123
124
// DefaultPathRoot is the path to the default config dir location.
core/bootstrap.go
+3
-3
@@ -29,7 +29,7 @@ func superviseConnections(parent context.Context,
29
h host.Host,
30
route *dht.IpfsDHT, // TODO depend on abstract interface for testing purposes
31
store peer.Peerstore,
32
- peers []*config.BootstrapPeer) error {
32
+ peers []config.BootstrapPeer) error {
33
34
for {
35
ctx, _ := context.WithTimeout(parent, connectiontimeout)
@@ -51,7 +51,7 @@ func bootstrap(ctx context.Context,
51
h host.Host,
52
r *dht.IpfsDHT,
53
ps peer.Peerstore,
54
- boots []*config.BootstrapPeer) error {
54
+ boots []config.BootstrapPeer) error {
55
56
connectedPeers := h.Network().Peers()
57
if len(connectedPeers) >= recoveryThreshold {
@@ -137,7 +137,7 @@ func connect(ctx context.Context, ps peer.Peerstore, r *dht.IpfsDHT, peers []pee
137
return nil
138
}
139
140
-func toPeer(bootstrap *config.BootstrapPeer) (p peer.PeerInfo, err error) {
140
+func toPeer(bootstrap config.BootstrapPeer) (p peer.PeerInfo, err error) {
141
id, err := peer.IDB58Decode(bootstrap.PeerID)
142
if err != nil {
143
return
core/commands/bootstrap.go
+40
-55
@@ -3,18 +3,29 @@ package commands
3
import (
4
"bytes"
5
"io"
6
- "strings"
7
-
8
- ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
9
- mh "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multihash"
6
7
cmds "github.com/jbenet/go-ipfs/commands"
8
config "github.com/jbenet/go-ipfs/config"
9
u "github.com/jbenet/go-ipfs/util"
10
+ errors "github.com/jbenet/go-ipfs/util/debugerror"
11
)
12
13
+// DefaultBootstrapAddresses are the hardcoded bootstrap addresses
14
+// for ipfs. they are nodes run by the ipfs team. docs on these later.
15
+// As with all p2p networks, bootstrap is an important security concern.
16
+//
17
+// Note: this is here -- and not inside cmd/ipfs/init.go -- because of an
18
+// import dependency issue. TODO: move this into a config/default/ package.
19
+var DefaultBootstrapAddresses = []string{
20
+ "/ip4/104.131.131.82/tcp/4001/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ", // mars.i.ipfs.io
21
+ "/ip4/104.236.176.52/tcp/4001/QmSoLnSGccFuZQJzRadHn95W2CrSFmZuTdDWP8HXaHca9z", // neptune (to be neptune.i.ipfs.io)
22
+ "/ip4/104.236.179.241/tcp/4001/QmSoLpPVmHKQ4XTPdz8tjDFgdeRFkpV8JgYq8JVJ69RrZm", // pluto (to be pluto.i.ipfs.io)
23
+ "/ip4/162.243.248.213/tcp/4001/QmSoLueR4xBeUbY9WZ9xGUUxunbKWcrNFTDAadQJmocnWm", // uranus (to be uranus.i.ipfs.io)
24
+ "/ip4/128.199.219.111/tcp/4001/QmSoLSafTMBsPKadTEgaXctDQVcqN88CNLHXMkTNwMKPnu", // saturn (to be saturn.i.ipfs.io)
25
+}
26
+
27
type BootstrapOutput struct {
17
- Peers []*config.BootstrapPeer
28
+ Peers []config.BootstrapPeer
29
}
30
31
var peerOptionDesc = "A peer to add to the bootstrap list (in the format '<multiaddr>/<peerID>')"
@@ -55,7 +66,7 @@ in the bootstrap list).
66
cmds.StringArg("peer", true, true, peerOptionDesc),
67
},
68
Run: func(req cmds.Request) (interface{}, error) {
58
- input, err := bootstrapInputToPeers(req.Arguments())
69
+ inputPeers, err := config.ParseBootstrapPeers(req.Arguments())
70
if err != nil {
71
return nil, err
72
}
@@ -70,7 +81,7 @@ in the bootstrap list).
81
return nil, err
82
}
83
73
- added, err := bootstrapAdd(filename, cfg, input)
84
+ added, err := bootstrapAdd(filename, cfg, inputPeers)
85
if err != nil {
86
return nil, err
87
}
@@ -106,7 +117,7 @@ var bootstrapRemoveCmd = &cmds.Command{
117
cmds.BoolOption("all", "Remove all bootstrap peers."),
118
},
119
Run: func(req cmds.Request) (interface{}, error) {
109
- input, err := bootstrapInputToPeers(req.Arguments())
120
+ input, err := config.ParseBootstrapPeers(req.Arguments())
121
if err != nil {
122
return nil, err
123
}
@@ -126,7 +137,7 @@ var bootstrapRemoveCmd = &cmds.Command{
137
return nil, err
138
}
139
129
- var removed []*config.BootstrapPeer
140
+ var removed []config.BootstrapPeer
141
if all {
142
removed, err = bootstrapRemoveAll(filename, cfg)
143
} else {
@@ -185,7 +196,7 @@ func bootstrapMarshaler(res cmds.Response) ([]byte, error) {
196
return buf.Bytes(), err
197
}
198
188
-func bootstrapWritePeers(w io.Writer, prefix string, peers []*config.BootstrapPeer) error {
199
+func bootstrapWritePeers(w io.Writer, prefix string, peers []config.BootstrapPeer) error {
200
201
for _, peer := range peers {
202
s := prefix + peer.Address + "/" + peer.PeerID + "\n"
@@ -197,46 +208,8 @@ func bootstrapWritePeers(w io.Writer, prefix string, peers []*config.BootstrapPe
208
return nil
209
}
210
200
-func bootstrapInputToPeers(input []string) ([]*config.BootstrapPeer, error) {
201
- split := func(addr string) (string, string) {
202
- idx := strings.LastIndex(addr, "/")
203
- if idx == -1 {
204
- return "", addr
205
- }
206
- return addr[:idx], addr[idx+1:]
207
- }
208
-
209
- peers := []*config.BootstrapPeer{}
210
- for _, addr := range input {
211
- addrS, peeridS := split(addr)
212
-
213
- // make sure addrS parses as a multiaddr.
214
- if len(addrS) > 0 {
215
- maddr, err := ma.NewMultiaddr(addrS)
216
- if err != nil {
217
- return nil, err
218
- }
219
-
220
- addrS = maddr.String()
221
- }
222
-
223
- // make sure idS parses as a peer.ID
224
- _, err := mh.FromB58String(peeridS)
225
- if err != nil {
226
- return nil, err
227
- }
228
-
229
- // construct config entry
230
- peers = append(peers, &config.BootstrapPeer{
231
- Address: addrS,
232
- PeerID: peeridS,
233
- })
234
- }
235
- return peers, nil
236
-}
237
-
238
-func bootstrapAdd(filename string, cfg *config.Config, peers []*config.BootstrapPeer) ([]*config.BootstrapPeer, error) {
239
- added := make([]*config.BootstrapPeer, 0, len(peers))
211
+func bootstrapAdd(filename string, cfg *config.Config, peers []config.BootstrapPeer) ([]config.BootstrapPeer, error) {
212
+ added := make([]config.BootstrapPeer, 0, len(peers))
213
214
for _, peer := range peers {
215
duplicate := false
@@ -261,9 +234,9 @@ func bootstrapAdd(filename string, cfg *config.Config, peers []*config.Bootstrap
234
return added, nil
235
}
236
264
-func bootstrapRemove(filename string, cfg *config.Config, toRemove []*config.BootstrapPeer) ([]*config.BootstrapPeer, error) {
265
- removed := make([]*config.BootstrapPeer, 0, len(toRemove))
266
- keep := make([]*config.BootstrapPeer, 0, len(cfg.Bootstrap))
237
+func bootstrapRemove(filename string, cfg *config.Config, toRemove []config.BootstrapPeer) ([]config.BootstrapPeer, error) {
238
+ removed := make([]config.BootstrapPeer, 0, len(toRemove))
239
+ keep := make([]config.BootstrapPeer, 0, len(cfg.Bootstrap))
240
241
for _, peer := range cfg.Bootstrap {
242
found := false
@@ -289,8 +262,8 @@ func bootstrapRemove(filename string, cfg *config.Config, toRemove []*config.Boo
262
return removed, nil
263
}
264
292
-func bootstrapRemoveAll(filename string, cfg *config.Config) ([]*config.BootstrapPeer, error) {
293
- removed := make([]*config.BootstrapPeer, len(cfg.Bootstrap))
265
+func bootstrapRemoveAll(filename string, cfg *config.Config) ([]config.BootstrapPeer, error) {
266
+ removed := make([]config.BootstrapPeer, len(cfg.Bootstrap))
267
copy(removed, cfg.Bootstrap)
268
269
cfg.Bootstrap = nil
@@ -302,6 +275,18 @@ func bootstrapRemoveAll(filename string, cfg *config.Config) ([]*config.Bootstra
275
return removed, nil
276
}
277
278
+// DefaultBootstrapPeers returns the (parsed) set of default bootstrap peers.
279
+// if it fails, it returns a meaningful error for the user.
280
+// This is here (and not inside cmd/ipfs/init) because of module dependency problems.
281
+func DefaultBootstrapPeers() ([]config.BootstrapPeer, error) {
282
+ ps, err := config.ParseBootstrapPeers(DefaultBootstrapAddresses)
283
+ if err != nil {
284
+ return nil, errors.Errorf(`failed to parse hardcoded bootstrap peers: %s
285
+This is a problem with the ipfs codebase. Please report it to the dev team.`, err)
286
+ }
287
+ return ps, nil
288
+}
289
+
290
const bootstrapSecurityWarning = `
291
SECURITY WARNING:
292