add pub/priv key code to identify, not complete yet
Jeromy committed
Sep 1, 2014 at 16:09 UTC
45fc43c9cf72a17ccf01b4d82933520a748cf47e
5 files changed
+181
-27
config/config.go
+9
-2
@@ -1,13 +1,15 @@
1
package config
2
3
import (
4
- u "github.com/jbenet/go-ipfs/util"
4
"os"
5
+
6
+ u "github.com/jbenet/go-ipfs/util"
7
)
8
9
// Identity tracks the configuration of the local node's identity.
10
type Identity struct {
10
- PeerID string
11
+ PeerID string
12
+ Address string
13
}
14
15
// Datastore tracks the configuration of the datastore.
@@ -16,10 +18,15 @@ type Datastore struct {
18
Path string
19
}
20
21
+type SavedPeer struct {
22
+ Address string
23
+}
24
+
25
// Config is used to load IPFS config files.
26
type Config struct {
27
Identity *Identity
28
Datastore *Datastore
29
+ Peers []*SavedPeer
30
}
31
32
var defaultConfigFilePath = "~/.go-ipfs/config"
core/core.go
+45
-25
@@ -67,34 +67,10 @@ func NewIpfsNode(cfg *config.Config, online bool) (*IpfsNode, error) {
67
68
var swap *bitswap.BitSwap
69
if online {
70
- maddr, err := ma.NewMultiaddr("/ip4/127.0.0.1/tcp/4001")
70
+ swap, err = loadBitswap(cfg, d)
71
if err != nil {
72
return nil, err
73
}
74
-
75
- local := &peer.Peer{
76
- ID: peer.ID(cfg.Identity.PeerID),
77
- Addresses: []*ma.Multiaddr{maddr},
78
- }
79
-
80
- if len(local.ID) == 0 {
81
- mh, err := u.Hash([]byte("blah blah blah ID"))
82
- if err != nil {
83
- return nil, err
84
- }
85
- local.ID = peer.ID(mh)
86
- }
87
-
88
- net := swarm.NewSwarm(local)
89
- err = net.Listen()
90
- if err != nil {
91
- return nil, err
92
- }
93
-
94
- route := dht.NewDHT(local, net, d)
95
- route.Start()
96
-
97
- swap = bitswap.NewBitSwap(local, net, d, route)
74
}
75
76
bs, err := bserv.NewBlockService(d, swap)
@@ -115,3 +91,47 @@ func NewIpfsNode(cfg *config.Config, online bool) (*IpfsNode, error) {
91
92
return n, nil
93
}
94
+
95
+func loadBitswap(cfg *config.Config, d ds.Datastore) (*bitswap.BitSwap, error) {
96
+ maddr, err := ma.NewMultiaddr("/ip4/127.0.0.1/tcp/4001")
97
+ if err != nil {
98
+ return nil, err
99
+ }
100
+
101
+ local := &peer.Peer{
102
+ ID: peer.ID(cfg.Identity.PeerID),
103
+ Addresses: []*ma.Multiaddr{maddr},
104
+ }
105
+
106
+ if len(local.ID) == 0 {
107
+ mh, err := u.Hash([]byte("blah blah blah ID"))
108
+ if err != nil {
109
+ return nil, err
110
+ }
111
+ local.ID = peer.ID(mh)
112
+ }
113
+
114
+ net := swarm.NewSwarm(local)
115
+ err = net.Listen()
116
+ if err != nil {
117
+ return nil, err
118
+ }
119
+
120
+ route := dht.NewDHT(local, net, d)
121
+ route.Start()
122
+
123
+ for _, p := range cfg.Peers {
124
+ maddr, err := ma.NewMultiaddr(p.Address)
125
+ if err != nil {
126
+ u.PErr("error: %v\n", err)
127
+ continue
128
+ }
129
+
130
+ _, err = route.Connect(maddr)
131
+ if err != nil {
132
+ u.PErr("Bootstrapping error: %v\n", err)
133
+ }
134
+ }
135
+
136
+ return bitswap.NewBitSwap(local, net, d, route), nil
137
+}
identify/identify.go
+69
@@ -3,6 +3,13 @@
3
package identify
4
5
import (
6
+ "crypto"
7
+ "crypto/rand"
8
+ "crypto/rsa"
9
+ "crypto/x509"
10
+ "errors"
11
+ "io/ioutil"
12
+
13
peer "github.com/jbenet/go-ipfs/peer"
14
u "github.com/jbenet/go-ipfs/util"
15
)
@@ -18,3 +25,65 @@ func Handshake(self, remote *peer.Peer, in, out chan []byte) error {
25
26
return nil
27
}
28
+
29
+type KeyPair struct {
30
+ Pub crypto.PublicKey
31
+ Priv crypto.PrivateKey
32
+}
33
+
34
+func GenKeypair() (*KeyPair, error) {
35
+ priv, err := rsa.GenerateKey(rand.Reader, 4096)
36
+ if err != nil {
37
+ return nil, err
38
+ }
39
+
40
+ return &KeyPair{
41
+ Priv: priv,
42
+ Pub: priv.PublicKey,
43
+ }, nil
44
+}
45
+
46
+func LoadKeypair(dir string) (*KeyPair, error) {
47
+ var kp KeyPair
48
+ pk_b, err := ioutil.ReadFile(dir + "/priv.key")
49
+ if err != nil {
50
+ return nil, err
51
+ }
52
+
53
+ priv, err := x509.ParsePKCS1PrivateKey(pk_b)
54
+ if err != nil {
55
+ return nil, err
56
+ }
57
+
58
+ kp.Priv = priv
59
+ kp.Pub = priv.PublicKey
60
+
61
+ return &kp, nil
62
+}
63
+
64
+func (pk *KeyPair) ID() (peer.ID, error) {
65
+ pub_b, err := x509.MarshalPKIXPublicKey(pk.Pub)
66
+ if err != nil {
67
+ return nil, err
68
+ }
69
+ hash, err := u.Hash(pub_b)
70
+ if err != nil {
71
+ return nil, err
72
+ }
73
+ return peer.ID(hash), nil
74
+}
75
+
76
+func (kp *KeyPair) Save(dir string) error {
77
+ switch k := kp.Priv.(type) {
78
+ case *rsa.PrivateKey:
79
+ err := k.Validate()
80
+ if err != nil {
81
+ return err
82
+ }
83
+ pk_b := x509.MarshalPKCS1PrivateKey(k)
84
+ err = ioutil.WriteFile(dir+"/priv.key", pk_b, 0600)
85
+ return err
86
+ default:
87
+ return errors.New("invalid private key type.")
88
+ }
89
+}
routing/dht/dht.go
+8
@@ -2,6 +2,7 @@ package dht
2
3
import (
4
"bytes"
5
+ "crypto/rand"
6
"fmt"
7
"sync"
8
"time"
@@ -637,3 +638,10 @@ func (dht *IpfsDHT) peerFromInfo(pbp *PBDHTMessage_PBPeer) (*peer.Peer, error) {
638
639
return dht.network.GetConnection(peer.ID(pbp.GetId()), maddr)
640
}
641
+
642
+// Builds up list of peers by requesting random peer IDs
643
+func (dht *IpfsDHT) Bootstrap() {
644
+ id := make([]byte, 16)
645
+ rand.Read(id)
646
+ dht.FindPeer(peer.ID(id), time.Second*10)
647
+}
routing/dht/routing.go
+50
@@ -340,6 +340,56 @@ func (dht *IpfsDHT) FindPeer(id peer.ID, timeout time.Duration) (*peer.Peer, err
340
return nil, u.ErrNotFound
341
}
342
343
+func (dht *IpfsDHT) findPeerMultiple(id peer.ID, timeout time.Duration) (*peer.Peer, error) {
344
+ // Check if were already connected to them
345
+ p, _ := dht.Find(id)
346
+ if p != nil {
347
+ return p, nil
348
+ }
349
+
350
+ routeLevel := 0
351
+ peers := dht.routingTables[routeLevel].NearestPeers(kb.ConvertPeerID(id), AlphaValue)
352
+ if len(peers) == 0 {
353
+ return nil, kb.ErrLookupFailure
354
+ }
355
+
356
+ found := make(chan *peer.Peer)
357
+ after := time.After(timeout)
358
+
359
+ for _, p := range peers {
360
+ go func(p *peer.Peer) {
361
+ pmes, err := dht.findPeerSingle(p, id, timeout, routeLevel)
362
+ if err != nil {
363
+ u.DErr("getPeer error: %v\n", err)
364
+ return
365
+ }
366
+ plist := pmes.GetPeers()
367
+ if len(plist) == 0 {
368
+ routeLevel++
369
+ }
370
+ for _, fp := range plist {
371
+ nxtp, err := dht.peerFromInfo(fp)
372
+ if err != nil {
373
+ u.DErr("findPeer error: %v\n", err)
374
+ continue
375
+ }
376
+
377
+ if nxtp.ID.Equal(dht.self.ID) {
378
+ found <- nxtp
379
+ return
380
+ }
381
+ }
382
+ }(p)
383
+ }
384
+
385
+ select {
386
+ case p := <-found:
387
+ return p, nil
388
+ case <-after:
389
+ return nil, u.ErrTimeout
390
+ }
391
+}
392
+
393
// Ping a peer, log the time it took
394
func (dht *IpfsDHT) Ping(p *peer.Peer, timeout time.Duration) error {
395
// Thoughts: maybe this should accept an ID and do a peer lookup?