-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathpacket.go
145 lines (125 loc) · 2.66 KB
/
packet.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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
package authConn
import (
"encoding/binary"
"errors"
"io"
)
const (
PACKET_TYPE_AUTH = 0x1001
PACKET_TYPE_AUTH_RSP = 0x1002
)
var (
ErrPacketTypeInvalid = errors.New("invalid packet type")
)
type Packet interface {
Packet() []byte
Reset(src io.Reader) error
}
func ReadPacket(reader io.Reader) (res Packet, err error) {
packetType, err := decodeUint64(reader)
if err != nil {
return nil, err
}
switch packetType {
case PACKET_TYPE_AUTH:
res = &AuthPacket{data: map[string]string{}}
err = res.(*AuthPacket).reset(reader)
case PACKET_TYPE_AUTH_RSP:
res = &AuthRspPacket{}
err = res.(*AuthRspPacket).reset(reader)
default:
err = ErrPacketTypeInvalid
}
return
}
func decodeByte(b io.Reader) (byte, error) {
num := make([]byte, 1)
_, err := io.ReadFull(b, num)
if err != nil {
return 0, err
}
return num[0], nil
}
func decodeUint16(b io.Reader) (uint16, error) {
num := make([]byte, 2)
_, err := io.ReadFull(b, num)
if err != nil {
return 0, err
}
return binary.BigEndian.Uint16(num), nil
}
func decodeUint64(b io.Reader) (uint64, error) {
num := make([]byte, 8)
_, err := io.ReadFull(b, num)
if err != nil {
return 0, err
}
return binary.BigEndian.Uint64(num), nil
}
func encodeUint16(num uint16) []byte {
bytesResult := make([]byte, 2)
binary.BigEndian.PutUint16(bytesResult, num)
return bytesResult
}
func encodeUint64(num uint64) []byte {
bytesResult := make([]byte, 8)
binary.BigEndian.PutUint64(bytesResult, num)
return bytesResult
}
func encodeString(field string) []byte {
return encodeBytes([]byte(field))
}
func decodeString(b io.Reader) (string, error) {
buf, err := decodeBytes(b)
return string(buf), err
}
func decodeBytes(b io.Reader) ([]byte, error) {
fieldLength, err := decodeUint16(b)
if err != nil {
return nil, err
}
field := make([]byte, fieldLength)
_, err = io.ReadFull(b, field)
if err != nil {
return nil, err
}
return field, nil
}
func encodeBytes(field []byte) []byte {
fieldLength := make([]byte, 2)
binary.BigEndian.PutUint16(fieldLength, uint16(len(field)))
return append(fieldLength, field...)
}
func encodeLength(length int) []byte {
var encLength []byte
for {
digit := byte(length % 128)
length /= 128
if length > 0 {
digit |= 0x80
}
encLength = append(encLength, digit)
if length == 0 {
break
}
}
return encLength
}
func decodeLength(r io.Reader) (int, error) {
var rLength uint32
var multiplier uint32
b := make([]byte, 1)
for multiplier < 27 {
_, err := io.ReadFull(r, b)
if err != nil {
return 0, err
}
digit := b[0]
rLength |= uint32(digit&127) << multiplier
if (digit & 128) == 0 {
break
}
multiplier += 7
}
return int(rLength), nil
}