@cryptotaxi247 / kubo / commits / ee1450bf9

routed host stash

Juan Batiz-Benet committed Feb 13, 2015 at 22:26 UTC ee1450bf9e310a1e6f0eb168b6a05c2dfcc6f730
1 file changed +108
p2p/host/routed/routed.go new
+108
@@ -0,0 +1,108 @@
1 +package routedhost
2 +
3 +import (
4 + "fmt"
5 + "time"
6 +
7 + context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
8 + ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
9 +
10 + eventlog "github.com/jbenet/go-ipfs/thirdparty/eventlog"
11 + lgbl "github.com/jbenet/go-ipfs/util/eventlog/loggables"
12 +
13 + host "github.com/jbenet/go-ipfs/p2p/host"
14 + inet "github.com/jbenet/go-ipfs/p2p/net"
15 + peer "github.com/jbenet/go-ipfs/p2p/peer"
16 + protocol "github.com/jbenet/go-ipfs/p2p/protocol"
17 + routing "github.com/jbenet/go-ipfs/routing"
18 +)
19 +
20 +var log = eventlog.Logger("p2p/host/routed")
21 +
22 +// AddressTTL is the expiry time for our addresses.
23 +// We expire them quickly.
24 +const AddressTTL = time.Second * 10
25 +
26 +// RoutedHost is a p2p Host that includes a routing system.
27 +// This allows the Host to find the addresses for peers when
28 +// it does not have them.
29 +type RoutedHost struct {
30 + host host.Host // embedded other host.
31 + route routing.IpfsRouting
32 +}
33 +
34 +func Wrap(h host.Host, r routing.IpfsRouting) *RoutedHost {
35 + return &RoutedHost{h, r}
36 +}
37 +
38 +// Connect ensures there is a connection between this host and the peer with
39 +// given peer.ID. See (host.Host).Connect for more information.
40 +//
41 +// RoutedHost's Connect differs in that if the host has no addresses for a
42 +// given peer, it will use its routing system to try to find some.
43 +func (rh *RoutedHost) Connect(ctx context.Context, pi peer.PeerInfo) error {
44 + // first, check if we're already connected.
45 + if len(rh.Network().ConnsToPeer(pi.ID)) > 0 {
46 + return nil
47 + }
48 +
49 + // if we were given some addresses, keep + use them.
50 + if len(pi.Addrs) > 0 {
51 + rh.Peerstore().AddAddrs(pi.ID, pi.Addrs, peer.TempAddrTTL)
52 + }
53 +
54 + // Check if we have some addresses in our recent memory.
55 + addrs := rh.Peerstore().Addrs(pi.ID)
56 + if len(addrs) < 1 {
57 +
58 + // no addrs? find some with the routing system.
59 + pi2, err := rh.route.FindPeer(ctx, pi.ID)
60 + if err != nil {
61 + return err // couldnt find any :(
62 + }
63 + if pi2.ID != pi.ID {
64 + err = fmt.Errorf("routing failure: provided addrs for different peer")
65 + logRoutingErrDifferentPeers(ctx, pi.ID, pi2.ID, err)
66 + return err
67 + }
68 + addrs = pi2.Addrs
69 + }
70 +
71 + // if we're here, we got some addrs. let's use our wrapped host to connect.
72 + pi.Addrs = addrs
73 + return rh.host.Connect(ctx, pi)
74 +}
75 +
76 +func logRoutingErrDifferentPeers(ctx context.Context, wanted, got peer.ID, err error) {
77 + lm := make(lgbl.DeferredMap)
78 + lm["error"] = err
79 + lm["wantedPeer"] = func() interface{} { return wanted.Pretty() }
80 + lm["gotPeer"] = func() interface{} { return got.Pretty() }
81 + log.Event(ctx, "routingError", lm)
82 +}
83 +
84 +func (rh *RoutedHost) ID() peer.ID {
85 + return rh.host.ID()
86 +}
87 +func (rh *RoutedHost) Peerstore() peer.Peerstore {
88 + return rh.host.Peerstore()
89 +}
90 +func (rh *RoutedHost) Addrs() []ma.Multiaddr {
91 + return rh.host.Addrs()
92 +}
93 +func (rh *RoutedHost) Network() inet.Network {
94 + return rh.host.Network()
95 +}
96 +func (rh *RoutedHost) Mux() *protocol.Mux {
97 + return rh.host.Mux()
98 +}
99 +func (rh *RoutedHost) SetStreamHandler(pid protocol.ID, handler inet.StreamHandler) {
100 + rh.host.SetStreamHandler(pid, handler)
101 +}
102 +func (rh *RoutedHost) NewStream(pid protocol.ID, p peer.ID) (inet.Stream, error) {
103 + return rh.host.NewStream(pid, p)
104 +}
105 +func (rh *RoutedHost) Close() error {
106 + // no need to close IpfsRouting. we dont own it.
107 + return rh.host.Close()
108 +}