This repository has been archived by the owner on Sep 15, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 143
/
bs.go
133 lines (114 loc) · 2.93 KB
/
bs.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// Copyright (C) 2013-2018, The MetaCurrency Project (Eric Harris-Braun, Arthur Brock, et. al.)
// Use of this source code is governed by GPLv3 found in the LICENSE file
//----------------------------------------------------------------------------------------
// implements bootstrap server access
package holochain
import (
"bytes"
"encoding/json"
"errors"
"fmt"
peer "github.com/libp2p/go-libp2p-peer"
pstore "github.com/libp2p/go-libp2p-peerstore"
ma "github.com/multiformats/go-multiaddr"
"io/ioutil"
"net/http"
"strings"
"time"
)
const (
BootstrapTTL = time.Minute * 5
)
type BSReq struct {
Version int
NodeID string
NodeAddr string
}
type BSResp struct {
Req BSReq
Remote string
LastSeen time.Time
}
func (h *Holochain) BSpost() (err error) {
if h.node == nil {
return errors.New("Node hasn't been initialized yet.")
}
nodeID := h.nodeIDStr
req := BSReq{Version: 1, NodeID: nodeID, NodeAddr: h.node.ExternalAddr().String()}
host := h.Config.BootstrapServer
id := h.DNAHash()
url := fmt.Sprintf("http://%s/%s/%s", host, id.String(), nodeID)
var b []byte
b, err = json.Marshal(req)
//var resp *http.Response
if err == nil {
var resp *http.Response
resp, err = http.Post(url, "application/json", bytes.NewBuffer(b))
if err == nil {
resp.Body.Close()
}
}
return
}
func (h *Holochain) checkBSResponses(nodes []BSResp) (err error) {
myNodeID := h.nodeIDStr
for _, r := range nodes {
h.dht.dlog.Logf("checking returned node: %v", r)
var id peer.ID
var addr ma.Multiaddr
id, err = peer.IDB58Decode(r.Req.NodeID)
if err == nil {
//@TODO figure when to use Remote or r.NodeAddr
x := strings.Split(r.Remote, ":")
y := strings.Split(r.Req.NodeAddr, "/")
port := y[len(y)-1]
// assume the multi-address is the ip address as the bootstrap server saw it
// with port number advertised by the node in it's multi-address
addr, err = ma.NewMultiaddr("/ip4/" + x[0] + "/tcp/" + port)
if err == nil {
// don't "discover" ourselves
if r.Req.NodeID != myNodeID {
h.dht.dlog.Logf("discovered peer via bs: %s (%v)", r.Req.NodeID, addr)
go func() {
err = h.AddPeer(pstore.PeerInfo{ID: id, Addrs: []ma.Multiaddr{addr}})
}()
}
}
}
}
return
}
func (h *Holochain) BSget() (err error) {
if h.node == nil {
return errors.New("Node hasn't been initialized yet.")
}
host := h.Config.BootstrapServer
if host == "" {
return
}
id := h.DNAHash()
url := fmt.Sprintf("http://%s/%s", host, id.String())
var req *http.Request
req, err = http.NewRequest("GET", url, nil)
if err != nil {
return
}
req.Close = true
client := http.DefaultClient
var resp *http.Response
resp, err = client.Do(req)
// resp, err = http.Get(url)
if err == nil {
var b []byte
b, err = ioutil.ReadAll(resp.Body)
if err == nil {
var nodes []BSResp
err = json.Unmarshal(b, &nodes)
if err == nil {
err = h.checkBSResponses(nodes)
}
}
resp.Body.Close()
}
return
}