1 (* Copyright 2001, 2002 b8_bavard, b8_fee_carabine, INRIA *)
3 This file is part of mldonkey.
5 mldonkey is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 mldonkey is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with mldonkey; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 open CommonDownloads.Basic
22 open CommonInteractive
23 open SlskComplexOptions
26 open TcpBufferedSocket
33 open CommonComplexOptions
52 let disconnect_peer c reason
=
53 match c
.client_peer_sock
with
55 | ConnectionWaiting token
->
57 c
.client_peer_sock
<- NoConnection
59 lprintf
"DISCONNECTED FROM PEER"; lprint_newline
();
61 c
.client_peer_sock
<- NoConnection
;
62 c
.client_requests
<- []
64 let disconnect_result c sock
=
65 lprintf
"DISCONNECTED FROM RESULT"; lprint_newline
();
66 close sock Closed_by_user
;
67 c
.client_result_socks
<- List2.removeq sock c
.client_result_socks
69 module Download
= CommonDownloads.Basic.Make
(struct
74 let file file = as_file
file.file_file
75 let client client = as_client
client.client_client
77 let client_disconnected d
=
78 lprintf
"DISCONNECTED FROM SOURCE"; lprint_newline
();
79 let c = d
.download_client
in
80 c.client_downloads
<- List2.removeq d
c.client_downloads
83 let download_finished d
=
84 let file = d
.download_file
in
85 if List.memq
file !current_files
then begin
86 current_files
:= List2.removeq
file !current_files
;
87 old_files
=:= (file_best_name
(as_file
file.file_file
),
88 file_size
file) :: !!old_files
;
90 c.client_files
<- List.remove_assoc
file c.client_files
96 let connect_download c file req
=
98 match c.client_addr
with
101 let token = add_pending_connection connection_manager
(fun token ->
102 connection_try
c.client_connection_control
;
103 let sock = connect
token "client download"
104 (Ip.to_inet_addr ip
) port
107 let d = Download.new_download
sock c file 1 in
108 set_reader
sock (Download.download_reader
d);
109 set_client_state
c (Connected_downloading
(file_num
file));
110 init_download_connection
sock file (local_login
()) req
117 lprintf
"Exception %s while connecting to client"
118 (Printexc2.to_string e
);
121 let client_to_client c t
sock =
122 if !verbose_msg_clients
then begin
123 lprintf
"MESSAGE FROM PEER"; lprint_newline
();
129 | C2C.FileSearchResultReq t
->
131 let module SR
= C2C.FileSearchResult
in
132 let u = new_user t
.SR.user
in
134 let q = List.assoc t
.SR.id
!SlskGlobals.searches
in
135 List.iter
(fun file ->
137 let basename = Filename2.basename file.C2C.file_name
in
138 let r = new_result
basename file.C2C.file_size
in
139 add_result_source
r u file.C2C.file_name
;
140 search_add_result
true q r
142 lprintf
"Exception %s for file %s"
143 (Printexc2.to_string e
) file.C2C.file_name
;
148 lprintf
"******* NO SEARCH ASSOCIATED WITH %d ******"
149 t
.SR.id
; lprint_newline
();
152 | C2C.TransferRequestReq
(false, req_id
, file_name
, size
) ->
153 (* Someone wants to upload to us !! *)
156 let file = Hashtbl.find files_by_key
(String.lowercase file_name
) in
158 lprintf
"File Found"; lprint_newline
();
159 if size
<> file_size
file then begin
160 lprintf
"Bad file size"; lprint_newline
();
163 if file_state
file = FileDownloading
then begin
164 client_send
sock (C2C.TransferOKReplyReq
(req_id
,
166 connect_download c file req_id
170 client_send
sock (C2C.TransferFailedReplyReq
(!requests,
171 "Not needed anymore"))
175 lprintf
"Exception %s for TransferRequestReq Upload %s:%Ld"
176 (Printexc2.to_string e
) file_name size
; lprint_newline
();
179 | C2C.SharedFileListReq files
->
180 List.iter
(fun (dir
, files
) ->
182 let r = new_result f
.C2C.file_name f
.C2C.file_size
in
183 add_result_source
r c.client_user
(Filename.concat dir f
.C2C.file_name
);
184 client_new_file
(as_client
c.client_client
) dir
r
188 | C2C.TransferOKReplyReq
(req
, filesize
) ->
191 let file = List.assoc req
c.client_requests
in
192 c.client_requests
<- List.remove_assoc req
c.client_requests
;
193 connect_download c file req
196 lprintf
"req %d not found !" req
; lprint_newline
();
199 | C2C.TransferFailedReplyReq
(req
, reason
) ->
202 let file = List.assoc req
c.client_requests
in
203 c.client_requests
<- List.remove_assoc req
c.client_requests
;
204 let reason = String.lowercase
reason in
205 if reason = "queued" then
206 set_client_state
c (Connected
0)
208 update_file_state
(file.file_file
) (FileAborted
reason)
211 lprintf
"req %d not found !" req
; lprint_newline
();
215 lprintf
"Unused message from client:"; lprint_newline
();
216 SlskProtocol.C2C.print t
;
219 let connect_peer c token msgs
=
220 if !verbose_msg_clients
then begin
221 lprintf
"CONNECT PEER"; lprint_newline
();
223 match c.client_peer_sock
with
225 List.iter
(fun t
-> client_send
sock t
) msgs
226 | ConnectionWaiting _
-> ()
228 match c.client_addr
with
230 if !verbose_msg_clients
then begin
231 lprintf
"NO ADDRESS FOR CLIENT"; lprint_newline
();
234 do_if_connected s
.server_sock
(fun sock ->
235 if !verbose_msg_servers
then begin
236 lprintf
"ASKING FOR CLIENT IP: %s" c.client_name
;
239 server_send
sock (C2S.GetPeerAddressReq
c.client_name
);
245 add_pending_connection connection_manager
(fun ctoken
->
246 c.client_peer_sock
<- NoConnection
;
248 if !verbose_msg_clients
then begin
249 lprintf
"CONNECTING"; lprint_newline
();
251 connection_try
c.client_connection_control
;
252 let sock = connect ctoken
"peer connect"
253 (Ip.to_inet_addr ip
) port
256 set_closer
sock (fun _
r -> disconnect_peer c r);
257 TcpBufferedSocket.set_read_controler
sock download_control
;
258 TcpBufferedSocket.set_write_controler
sock upload_control
;
259 set_rtimeout
sock 30.;
260 TcpBufferedSocket.set_reader
sock (
261 soulseek_handler
C2C.parse
(client_to_client c));
262 c.client_peer_sock
<- Connection
sock;
263 init_peer_connection
sock (local_login
()) token;
264 List.iter
(fun t
-> client_send
sock t
) msgs
266 lprintf
"Exception %s while connecting to client\n"
267 (Printexc2.to_string e
);
268 disconnect_peer c (Closed_for_exception e
)
270 c.client_peer_sock
<- ConnectionWaiting
token
272 let connect_result c token =
273 match c.client_addr
with
276 let ctoken = add_pending_connection connection_manager
(fun ctoken ->
278 if !verbose_msg_clients
then begin
279 lprintf
"CONNECTING"; lprint_newline
();
281 connection_try
c.client_connection_control
;
282 let sock = connect
ctoken "peer connect"
283 (Ip.to_inet_addr ip
) port
286 set_closer
sock (fun _ _
-> disconnect_result c sock);
287 TcpBufferedSocket.set_read_controler
sock download_control
;
288 TcpBufferedSocket.set_write_controler
sock upload_control
;
289 set_rtimeout
sock 30.;
290 TcpBufferedSocket.set_reader
sock (
291 soulseek_handler
C2C.parse
(client_to_client c));
292 c.client_result_socks
<- sock :: c.client_result_socks
;
293 init_result_connection
sock token
295 lprintf
"Exception %s while connecting to client"
296 (Printexc2.to_string e
);