go-dht/kademlia.go
kademlia.goRaw
1package main
2
3import (
4 "math/bits"
5 "strconv"
6)
7
8const (
9 alpha = 3 // 'alpha', max parallalel calls
10 B = 20 // 'B', 160 bits, ID length
11 KBucketSize = 20 // 'K', bucket size
12)
13
14type ListedNode struct {
15 ID ID
16 Addr string
17}
18
19type Node struct {
20 ID ID
21 KBuckets [B * 8][]ListedNode
22}
23
24func (n Node) String() string {
25 r := "Node ID: " + n.ID.String() + ", KBuckets:\n"
26 for i, kb := range n.KBuckets {
27 if len(kb) > 0 {
28 r += " KBucket " + strconv.Itoa(i) + "\n"
29 for _, e := range kb {
30 r += " " + e.ID.String() + "\n"
31 }
32 }
33 }
34 return r
35}
36
37func NewNode() (Node, error) {
38 // TODO if node already has id, import it
39 id, err := NewID()
40 if err != nil {
41 return Node{}, err
42 }
43
44 var n Node
45 n.ID = id
46 return n, nil
47}
48
49func LoadNode(idStr string) (Node, error) {
50 id, err := IDFromString("0fd85ddddf15aeec2d5d8b01b013dbca030a18d7")
51 if err != nil {
52 return Node{}, err
53 }
54 var n Node
55 n.ID = id
56 return n, nil
57}
58
59func (n Node) KBucket(o ID) int {
60 d := n.ID.Distance(o)
61 return kBucketByDistance(d[:])
62
63}
64
65func kBucketByDistance(b []byte) int {
66 for i := 0; i < B; i++ {
67 for a := b[i] ^ 0; a != 0; a &= a - 1 {
68 return (B-1-i)*8 + (7 - bits.TrailingZeros8(bits.Reverse8(uint8(a))))
69 }
70 }
71 return (B*8 - 1) - (B*8 - 1)
72}
73
74func (n *Node) Update(o ListedNode) {
75 k := n.KBucket(o.ID)
76 kb := n.KBuckets[k]
77 if len(kb) >= KBucketSize {
78 // TODO ping the kb[0], and if no response, delete it, and add the current o (ID)
79 return
80 }
81 // check that is not already in the list
82 exist, _ := existsInListedNodes(n.KBuckets[k], o)
83 if exist {
84 // update position to the bottom
85 return
86 }
87 // not exists, add it to the kBucket
88 n.KBuckets[k] = append(n.KBuckets[k], o)
89 return
90}
91
92func existsInListedNodes(lns []ListedNode, ln ListedNode) (bool, int) {
93 for i, v := range lns {
94 if v.ID.Equal(ln.ID) {
95 return true, i
96 }
97 }
98 return false, 0
99}