1 package torrent
2
3 import (
4 "bytes"
5 "encoding/binary"
6
7
8
9 "github.com/concurrency-8/parser"
10 "github.com/concurrency-8/tracker"
11 )
12
13
14 type Payload map[string]interface{}
15
16
17
18
19
20
21
22
23
24 func BuildHandshake(report tracker.ClientStatusReport) (handshake *bytes.Buffer, err error) {
25 handshake = new(bytes.Buffer)
26
27
28 if err = binary.Write(handshake, binary.BigEndian, uint8(19)); err != nil {
29 return
30 }
31
32
33 if err = binary.Write(handshake, binary.BigEndian, []byte("BitTorrent protocol")); err != nil {
34 return
35 }
36
37
38 if err = binary.Write(handshake, binary.BigEndian, uint64(0)); err != nil {
39 return
40 }
41
42
43 var infohashFromFile [20]byte
44 copy(infohashFromFile[:], report.TorrentFile.InfoHash)
45 if err = binary.Write(handshake, binary.BigEndian, infohashFromFile); err != nil {
46 return
47 }
48
49
50 if err = binary.Write(handshake, binary.BigEndian, []byte(report.PeerID)); err != nil {
51 return
52 }
53
54 return
55 }
56
57
58 func BuildKeepAlive() (keepAlive *bytes.Buffer) {
59 keepAlive = bytes.NewBuffer(make([]byte, 4))
60
61 return
62 }
63
64
65
66
67
68 func BuildChoke() (choke *bytes.Buffer, err error) {
69 choke = new(bytes.Buffer)
70
71 if err = binary.Write(choke, binary.BigEndian, uint32(1)); err != nil {
72 return
73 }
74
75 if err = binary.Write(choke, binary.BigEndian, uint8(0)); err != nil {
76 return
77 }
78
79 return
80 }
81
82
83
84
85
86 func BuildUnchoke() (unchoke *bytes.Buffer, err error) {
87 unchoke = new(bytes.Buffer)
88
89 if err = binary.Write(unchoke, binary.BigEndian, uint32(1)); err != nil {
90 return
91 }
92
93 if err = binary.Write(unchoke, binary.BigEndian, uint8(1)); err != nil {
94 return
95 }
96
97 return
98 }
99
100
101
102
103
104 func BuildInterested() (interested *bytes.Buffer, err error) {
105 interested = new(bytes.Buffer)
106
107 if err = binary.Write(interested, binary.BigEndian, uint32(1)); err != nil {
108 return
109 }
110
111 if err = binary.Write(interested, binary.BigEndian, uint8(2)); err != nil {
112 return
113 }
114
115 return
116 }
117
118
119
120
121
122 func BuildUninterested() (uninterested *bytes.Buffer, err error) {
123 uninterested = new(bytes.Buffer)
124
125 if err = binary.Write(uninterested, binary.BigEndian, uint32(1)); err != nil {
126 return
127 }
128
129 if err = binary.Write(uninterested, binary.BigEndian, uint8(3)); err != nil {
130 return
131 }
132
133 return
134 }
135
136
137
138
139
140
141 func BuildHave(payload uint32) (have *bytes.Buffer, err error) {
142 have = new(bytes.Buffer)
143
144 if err = binary.Write(have, binary.BigEndian, uint32(5)); err != nil {
145 return
146 }
147
148 if err = binary.Write(have, binary.BigEndian, uint8(4)); err != nil {
149 return
150 }
151
152 if err = binary.Write(have, binary.BigEndian, uint32(payload)); err != nil {
153 return
154 }
155
156 return
157 }
158
159
160
161
162
163
164
165 func BuildRequest(payload parser.PieceBlock) (request *bytes.Buffer, err error) {
166 request = new(bytes.Buffer)
167
168
169 if err = binary.Write(request, binary.BigEndian, uint32(13)); err != nil {
170 return
171 }
172
173 if err = binary.Write(request, binary.BigEndian, uint8(6)); err != nil {
174 return
175 }
176
177 if err = binary.Write(request, binary.BigEndian, uint32(payload.Index)); err != nil {
178 return
179 }
180
181 if err = binary.Write(request, binary.BigEndian, uint32(payload.Begin)); err != nil {
182 return
183 }
184
185 if err = binary.Write(request, binary.BigEndian, uint32(payload.Length)); err != nil {
186 return
187 }
188
189 return
190 }
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235 func BuildCancel(payload parser.PieceBlock) (cancelBuf *bytes.Buffer, err error) {
236 cancelBuf = new(bytes.Buffer)
237
238
239 if err = binary.Write(cancelBuf, binary.BigEndian, uint32(13)); err != nil {
240 return
241 }
242
243
244 if err = binary.Write(cancelBuf, binary.BigEndian, uint8(8)); err != nil {
245 return
246 }
247
248
249 if err = binary.Write(cancelBuf, binary.BigEndian, payload.Index); err != nil {
250 return
251 }
252
253
254 if err = binary.Write(cancelBuf, binary.BigEndian, payload.Begin); err != nil {
255 return
256 }
257
258
259 if err = binary.Write(cancelBuf, binary.BigEndian, payload.Length); err != nil {
260 return
261 }
262
263 return
264 }
265
266
267
268
269
270 func BuildPort(port uint16) (portBuf *bytes.Buffer, err error) {
271 portBuf = new(bytes.Buffer)
272
273
274 if err = binary.Write(portBuf, binary.BigEndian, uint32(3)); err != nil {
275 return
276 }
277
278 if err = binary.Write(portBuf, binary.BigEndian, uint8(9)); err != nil {
279 return
280 }
281
282 if err = binary.Write(portBuf, binary.BigEndian, uint16(port)); err != nil {
283 return
284 }
285 return
286 }
287
288
289 func ParseMsg(msg *bytes.Buffer) (size uint32, id uint8, payload Payload) {
290 payload = make(Payload)
291 binary.Read(msg, binary.BigEndian, &size)
292
293 if size > 0 {
294 binary.Read(msg, binary.BigEndian, &id)
295 }
296 if size > 1 {
297
298 if id == 6 || id == 7 || id == 8 {
299 rest := bytes.NewBuffer(msg.Bytes()[8:])
300 var index, begin uint32
301 binary.Read(msg, binary.BigEndian, &index)
302 binary.Read(msg, binary.BigEndian, &begin)
303 payload["index"] = index
304 payload["begin"] = begin
305
306 if id == 7 {
307 payload["block"] = rest
308
309 } else {
310 payload["length"] = rest
311 }
312 } else {
313 payload["payload"] = msg
314 }
315 }
316
317 return
318
319 }
320
View as plain text