routing.go 2.25 KB
Newer Older
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
1 2 3
package dht

import (
4 5 6
	"math/rand"
	"time"

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
7 8 9
	peer "github.com/jbenet/go-ipfs/peer"
	swarm "github.com/jbenet/go-ipfs/swarm"
	u "github.com/jbenet/go-ipfs/util"
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
10 11
)

12 13
// TODO: determine a way of creating and managing message IDs
func GenerateMessageID() uint64 {
14
	return uint64(rand.Uint32()) << 32 & uint64(rand.Uint32())
15 16
}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
17 18 19 20 21
// This file implements the Routing interface for the IpfsDHT struct.

// Basic Put/Get

// PutValue adds value corresponding to given Key.
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
22
func (s *IpfsDHT) PutValue(key u.Key, value []byte) error {
23
	var p *peer.Peer
24
	p = s.routes.NearestPeer(convertKey(key))
25

26 27 28 29 30 31 32
	pmes_type := DHTMessage_PUT_VALUE
	str_key := string(key)
	mes_id := GenerateMessageID()

	pmes := new(DHTMessage)
	pmes.Type = &pmes_type
	pmes.Key = &str_key
33
	pmes.Value = value
34
	pmes.Id = &mes_id
35 36 37 38 39 40 41

	mes := new(swarm.Message)
	mes.Data = []byte(pmes.String())
	mes.Peer = p

	s.network.Chan.Outgoing <- mes
	return nil
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
42 43 44 45
}

// GetValue searches for the value corresponding to given Key.
func (s *IpfsDHT) GetValue(key u.Key, timeout time.Duration) ([]byte, error) {
46
	var p *peer.Peer
47
	p = s.routes.NearestPeer(convertKey(key))
48

49 50 51
	str_key := string(key)
	mes_type := DHTMessage_GET_VALUE
	mes_id := GenerateMessageID()
52
	// protobuf structure
53 54 55 56
	pmes := new(DHTMessage)
	pmes.Type = &mes_type
	pmes.Key = &str_key
	pmes.Id = &mes_id
57 58 59 60 61

	mes := new(swarm.Message)
	mes.Data = []byte(pmes.String())
	mes.Peer = p

62
	response_chan := s.ListenFor(*pmes.Id)
63

64
	// Wait for either the response or a timeout
65 66
	timeup := time.After(timeout)
	select {
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
67 68
	case <-timeup:
		// TODO: unregister listener
69
		return nil, u.ErrTimeout
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
70 71
	case resp := <-response_chan:
		return resp.Data, nil
72
	}
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
73 74 75 76 77 78
}

// Value provider layer of indirection.
// This is what DSHTs (Coral and MainlineDHT) do to store large values in a DHT.

// Announce that this node can provide value for given key
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
79 80
func (s *IpfsDHT) Provide(key u.Key) error {
	return u.ErrNotImplemented
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
81 82 83 84
}

// FindProviders searches for peers who can provide the value for given key.
func (s *IpfsDHT) FindProviders(key u.Key, timeout time.Duration) (*peer.Peer, error) {
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
85
	return nil, u.ErrNotImplemented
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
86 87 88 89 90 91
}

// Find specific Peer

// FindPeer searches for a peer with given ID.
func (s *IpfsDHT) FindPeer(id peer.ID, timeout time.Duration) (*peer.Peer, error) {
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
92
	return nil, u.ErrNotImplemented
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
93
}