11 open TcpBufferedSocket
17 http://www.bittorrent.org/beps/bep_0015.html *)
21 let of_bits = string_of_bitstring
22 let bits = bitstring_of_string
25 Choose a random transaction ID.
26 Fill the connect request structure.
29 let connect_request txn =
30 of_bits ( BITSTRING { 0x41727101980L : 64 ; 0l : 32 ; txn : 32 } )
32 exception Error of string
34 let fail fmt = Printf.ksprintf (fun s -> raise (Error s)) fmt
38 Check whether the packet is at least 16 bytes.
39 Check whether the transaction ID is equal to the one you chose.
40 Check whether the action is connect.
41 Store the connection ID for future use.
43 let connect_response s exp_txn =
45 | { 0l : 32 ; txn : 32 ; conn_id : 64 } ->
46 if txn = exp_txn then conn_id else fail "error connect_response txn %ld expected %ld" txn exp_txn
47 | { 3l : 32 ; txn : 32 ; msg : -1 : string } -> fail "error connect_response txn %ld : %s" txn msg
48 | { _ } -> fail "error connect_response"
51 Choose a random transaction ID.
52 Fill the announce request structure.
55 let announce_request conn txn ~info_hash ~peer_id (downloaded,left,uploaded) event ?(key=0l) ~numwant port =
60 info_hash : 20 * 8 : string;
61 peer_id : 20 * 8 : string;
68 numwant : 32 ; (* key *)
73 Check whether the packet is at least 20 bytes.
74 Check whether the transaction ID is equal to the one you chose.
75 Check whether the action is announce.
76 Do not announce again until interval seconds have passed or an event has occurred.
78 let announce_response s exp_txn =
79 let rec clients rest l =
81 | { ip : 32 ; port : 16 ; rest : -1 : bitstring } -> clients rest ((ip,port)::l)
85 | { 1l : 32 ; txn : 32 ; interval : 32 ; leechers : 32 ; seeders : 32 ;
86 rest : -1 : bitstring } ->
88 (interval,clients rest [])
90 fail "error announce_response txn %ld expected %ld" txn exp_txn
91 | { 3l : 32 ; txn : 32 ; msg : -1 : string } -> fail "error announce_response txn %ld : %s" txn msg
92 | { _ } -> fail "error announce_response"
95 If the tracker encounters an error, it might send an error packet.
97 Check whether the packet is at least 8 bytes.
98 Check whether the transaction ID is equal to the one you chose.
100 let error_response s =
102 | { 3l : 32 ; txn : 32 ; msg : -1 : string } -> Some (txn, msg)