arnaucube
arnaucube/go-dhtPublic Self-hosted repository
go-dht/node/node.go
node/node.goRaw
  1package node
  2
  3import (
  4	"fmt"
  5	"go-dht/config"
  6	"go-dht/kademlia"
  7	"net"
  8	"net/http"
  9	"net/rpc"
 10	"time"
 11
 12	log "github.com/sirupsen/logrus"
 13)
 14
 15type Node struct {
 16	port     string
 17	kademlia *kademlia.Kademlia
 18}
 19
 20func NewNode() (Node, error) {
 21	id, err := kademlia.NewID()
 22	if err != nil {
 23		return Node{}, err
 24	}
 25
 26	var n Node
 27	n.kademlia = kademlia.NewKademliaTable(id, config.C.Addr, config.C.Port)
 28	return n, nil
 29}
 30
 31func LoadNode(idStr string) (Node, error) {
 32	id, err := kademlia.IDFromString(idStr)
 33	if err != nil {
 34		return Node{}, err
 35	}
 36	var n Node
 37	n.kademlia = kademlia.NewKademliaTable(id, config.C.Addr, config.C.Port)
 38	return n, nil
 39}
 40
 41func (n Node) ID() kademlia.ID {
 42	return n.kademlia.N.ID
 43}
 44
 45func (n *Node) Start() error {
 46	// rpc server
 47	err := rpc.Register(n)
 48	if err != nil {
 49		return err
 50	}
 51	rpc.HandleHTTP()
 52	listener, err := net.Listen("tcp", ":"+config.C.Port)
 53	if err != nil {
 54		return err
 55	}
 56
 57	go func() {
 58		// TMP in order to print the KBuckets of the node
 59		for {
 60			fmt.Println(n.kademlia)
 61			time.Sleep(5 * time.Second)
 62		}
 63	}()
 64
 65	go n.pingKnownNodes(config.C.KnownNodes)
 66
 67	err = http.Serve(listener, nil)
 68	if err != nil {
 69		return err
 70	}
 71	return nil
 72}
 73
 74func (n *Node) pingKnownNodes(lns []kademlia.ListedNode) error {
 75	for _, ln := range lns {
 76		err := n.kademlia.CallPing(ln)
 77		if err != nil {
 78			log.Warning("[pingKnownNodes]", err)
 79		}
 80	}
 81	return nil
 82}
 83
 84// Exposed RPC calls: Ping, Store, FindNode, FindValue
 85
 86func (n *Node) Ping(ln kademlia.ListedNode, thisLn *kademlia.ListedNode) error {
 87	log.Info("[rpc] PING from ", ln.ID)
 88	n.kademlia.Update(ln)
 89	*thisLn = kademlia.ListedNode{
 90		ID:   n.ID(),
 91		Addr: config.C.Addr,
 92		Port: config.C.Port,
 93	}
 94	// perform PONG call to the requester (maybe ping&pong can be unified)
 95	err := n.kademlia.CallPong(ln)
 96	if err != nil {
 97		log.Warning("[PONG]", err)
 98	}
 99	return nil
100}
101
102func (n *Node) Pong(ln kademlia.ListedNode, ack *bool) error {
103	log.Info("[rpc] PONG")
104	n.kademlia.Update(ln)
105	return nil
106}
107
108func (n *Node) Store(data []byte, ack *bool) error {
109	log.Info("[rpc] STORE")
110
111	return nil
112}
113
114func (n *Node) FindNode() {
115	log.Info("[rpc] FIND_NODE")
116
117}
118
119func (n *Node) FindValue() {
120	log.Info("[rpc] FIND_VALUE")
121
122}