You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

122 lines
2.1 KiB

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