forked from prettymuchbryce/kademlia
-
Notifications
You must be signed in to change notification settings - Fork 1
/
netmsg.go
111 lines (90 loc) · 1.93 KB
/
netmsg.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
package kademlia
import (
"bytes"
"encoding/binary"
"encoding/gob"
"io"
)
const (
messageTypePing = iota
messageTypeStore
messageTypeFindNode
messageTypeFindValue
)
type message struct {
Sender *NetworkNode
Receiver *NetworkNode
ID int64
Error error
Type int
IsResponse bool
Data interface{}
}
type queryDataFindNode struct {
Target []byte
}
type queryDataFindValue struct {
Target []byte
}
type queryDataStore struct {
Data []byte
Publishing bool // Whether or not we are the original publisher
}
type responseDataFindNode struct {
Closest []*NetworkNode
}
type responseDataFindValue struct {
Closest []*NetworkNode
Value []byte
}
type responseDataStore struct {
Success bool
}
func netMsgInit() {
gob.Register(&queryDataFindNode{})
gob.Register(&queryDataFindValue{})
gob.Register(&queryDataStore{})
gob.Register(&responseDataFindNode{})
gob.Register(&responseDataFindValue{})
gob.Register(&responseDataStore{})
}
func serializeMessage(q *message) ([]byte, error) {
var msgBuffer bytes.Buffer
enc := gob.NewEncoder(&msgBuffer)
err := enc.Encode(q)
if err != nil {
return nil, err
}
length := msgBuffer.Len()
var lengthBytes [8]byte
binary.PutUvarint(lengthBytes[:], uint64(length))
var result []byte
result = append(result, lengthBytes[:]...)
result = append(result, msgBuffer.Bytes()...)
return result, nil
}
func deserializeMessage(conn io.Reader) (*message, error) {
lengthBytes := make([]byte, 8)
_, err := conn.Read(lengthBytes)
if err != nil {
return nil, err
}
lengthReader := bytes.NewBuffer(lengthBytes)
length, err := binary.ReadUvarint(lengthReader)
if err != nil {
return nil, err
}
msgBytes := make([]byte, length)
_, err = conn.Read(msgBytes)
if err != nil {
return nil, err
}
reader := bytes.NewBuffer(msgBytes)
msg := &message{}
dec := gob.NewDecoder(reader)
err = dec.Decode(msg)
if err != nil {
return nil, err
}
return msg, nil
}