1 /***************************************************************************
2 ctransfer.h - description
3 -------------------
4 begin : Fri Feb 22 2002
5 copyright : (C) 2002-2004 by Mathias Küster
6 email : mathen@users.berlios.de
7 ***************************************************************************/
8
9 /***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17
18 #ifndef CTRANSFER_H
19 #define CTRANSFER_H
20
21 /**
22 *@author Mathias Küster
23 *
24 * This class handles a file transfer, reading or writing to the file,
25 * possibly doing zlib compression or decompression.
26 *
27 * Perhaps the worst thing missing from this class, and dclib overall, is
28 * that there is no verification of the data received using the TTH leaf data.
29 *
30 * The TTH leaf data should basically be a list of TTHs, for sections of the
31 * file, you can check the leaf data matches the root (by hashing it), and
32 * then hash the data as it is received.
33 *
34 * This class is an awful mess mainly for all the obsolete protocol command
35 * support, but also due to compressed transfers (most things are not even
36 * compressible anyway).
37 */
38
39 #include <dclib/dcos.h>
40 #include <dclib/core/cstring.h>
41 #include <dclib/core/ccallback.h>
42 #include <dclib/core/cfile.h>
43 #include <dclib/core/czlib.h>
44 #include <dclib/cdcproto.h>
45 #include <dclib/dcobject.h>
46
47 #ifndef WIN32
48 #include <sys/time.h>
49 #endif
50
51 class CByteArray;
52
53 enum eTransferState {
54 etsNONE,
55 etsREADY,
56 etsIDLE
57 };
58
59 /*
60 * Warning: these are not in order the types of slot are allocated.
61 * Changes for 0.3.22:
62 * - total upload rate dependant extra normal slots added (O: in DC++ tag)
63 * - if a user is granted a slot, the user may still get a normal slot,
64 * and this still uses up the granted slot
65 * - operator slots were fixed, and now may actually be allocated after special slots
66 *
67 * Previously operator slots were broken (never given), which is lucky
68 * because they would have prevented operators getting small files when
69 * normal users could. Also slots granted to users caused that
70 * user to not use a normal slot. I think the idea of slots granted to
71 * users is to allow friends to get files when normal slots are used, not to
72 * allow normal users to get files while your friends are busy downloading.
73 *
74 * SETTINGS, RATE_EXTRA and USER are all normal slots allowing all uploads,
75 * but SPECIAL is limited and OPERATOR more limited. So 3 types of slot
76 * but 5 ways for some kind of slot to be given (3,1,1 for normal,mini,op).
77 */
78 enum eTransferType {
79 ettNONE, /* unknown */
80 ettSETTINGS, /* normal slot from settings slot limit */
81 ettOPERATOR, /* 1 of 4 slots for operators to get the filelist */
82 ettUSER, /* normal slot granted to a user */
83 ettSPECIAL, /* 1 of 4 slots for small files,filelist,leaves */
84 ettRATE_EXTRA /* normal slot allocated because total upload rate was below minimum */
85 };
86
87 typedef struct sAverageTransferRate {
88 struct timeval tv[10];
89 ulonglong transfered[10];
90 int index;
91 } sAverageTransferRate;
92
93 class CTransfer : public CDCProto {
94 public:
95 /** */
96 CTransfer( bool listener = false );
97 /** */
98 virtual ~CTransfer();
99
100 /** callback function */
DC_CallBack(CDCMessage *)101 virtual int DC_CallBack( CDCMessage * ) { return -1; };
102 /** */
103 virtual void DataAvailable( const char * buffer, int len );
104 /** */
105 virtual void DataSend();
106 /** */
107 virtual void DataTimeout();
108 /** */
109 virtual void ConnectionState( eConnectionState state );
110 /** */
111 virtual void Notify();
112
113 /** */
114 void SetCallBackFunction( _CCallback2<CTransfer, CDCMessage*> * callback );
115
116 /** */
117 int StartDownload( CString dstfile, ulonglong startposition, ulonglong endposition, ulonglong size, ulonglong chunksize, CString srcfile, CString adcTTH = CString() );
118 /** */
119 int StartUpload( CString dstfile, ulonglong length, ulonglong pos, ulonglong chunksize, CString srcfile, bool uget = false, bool adcget = false, CString adcTTH = CString(), bool compress = false );
120
121 /** */
122 int CallBack_SendObject( CDCMessage * DCMessage );
123 /** */
124 int CallBack_SendError( CString msg );
125
126 /** */
127 ulonglong GetTransferrate();
128 /** */
129 ulonglong GetBytesForTransferrate( ulonglong rate );
130 /** */
131 void AddTraffic( long n );
132 /** */
133 ulonglong GetTraffic();
134
135 /** */
136 int HandleMessage( char * c, int len );
137
138 /** */
CloseFile()139 void CloseFile() { m_File.Close(); };
140 /** */
141 ulonglong GetTransferID() const;
142 /** */
143 void SetTransferID( ulonglong transferid );
144 /** */
145 CString GetDstFilename() const;
146 /** */
147 void SetDstFilename( CString filename );
148 /** */
149 CString GetSrcFilename() const;
150 /** */
151 void SetSrcFilename( CString filename );
152 /** */
153 CString GetDstNick() const;
154 /** */
155 CString GetHubHost() const;
156 /** */
157 void SetHubHost( CString hubhost );
158 /** */
159 CString GetHubName() const;
160 /** */
161 void SetHubName( CString hubname );
162 /** */
163 eltMedium GetMedium() const;
164 /** */
165 void SetMedium( eltMedium medium );
166 /** */
167 long GetBuffer( CByteArray *ba );
168 /** */
169 bool SaveBufferToFile( const CString & filename );
170 /** */
171 void SetBuffer( CByteArray *ba );
172 /**
173 * This is to avoid creating an intermediate CByteArray for ADCGET list transfers.
174 */
175 void ClearAndAppendBuffer( const unsigned char * data, const unsigned long length );
176
177 /** */
178 eDirection GetSrcDirection() const;
179 /** */
180 void SetSrcDirection( eDirection direction );
181 /** */
182 eDirection GetDstDirection() const;
183 /** */
184 void SetDstDirection( eDirection direction );
185
186 /** */
187 int GetSrcLevel() const;
188 /** */
189 int GetDstLevel() const;
190 /** */
191 eConnectionState GetMode() const;
192 /** */
193 void SetMode( eConnectionState mode );
194 /** */
195 ulonglong GetStartPosition() const;
196 /** */
197 void SetStartPosition( ulonglong pos );
198 /** */
199 ulonglong GetEndPosition() const;
200 /** */
201 void SetEndPosition( ulonglong pos );
202 /** */
203 ulonglong GetLength() const;
204 /** */
205 void SetLength( ulonglong length );
206 /** */
207 ulonglong GetTransfered() const;
208 /** */
SetTransfered(ulonglong n)209 void SetTransfered( ulonglong n ) { m_nTransfered = n; };
210 /** */
GetChunkSize()211 ulonglong GetChunkSize() const { return m_nChunkSize; };
212 /** */
SetChunkSize(ulonglong n)213 void SetChunkSize( ulonglong n ) { m_nChunkSize = n; };
214 /** */
215 void InitTime();
216 /** */
217 void SetNick( CString nick );
218 /** */
219 CString GetNick();
220 /** */
221 void SetRate( ulonglong rate );
222 /** */
223 ulonglong GetRate() const;
224 /** */
225 bool IsIdle() const;
226
227 /** */
228 void SetDone( eTransferState e );
229 /** */
230 eTransferState GetDone() const;
231 /** */
232 time_t GetStartTime() const;
233 /** */
234 void SetStartTime( time_t t );
235
236 /** */
237 eTransferType GetTransferType() const;
238 /** */
239 void SetTransferType( eTransferType type );
240
241 /** */
GetSupport()242 CMessageSupports GetSupport() { return m_MessageSupports; }
243 /** */
244 bool GetEncrypted();
245 /** */
246 bool SupportsChunks() const;
247
248 /** */
249 CString GetTTH() const;
250 /** */
251 void SetTTH( const CString & newtth );
252
253 /** */
IsListener()254 bool IsListener() const { return m_bListener; };
255
256 private:
257 /** */
258 bool DoInitDownload();
259 /** */
260 void DoInitUpload();
261 /** */
262 int HandleFileTransfer( const char * buffer, int len );
263 /** */
264 int HandleBufferTransfer( const char * buffer, int len );
265 /** */
266 int HandleControlTransfer( const char * buffer, int len );
267 /** Send SSL messages to GUI */
268 void SendSSLInfo();
269
270 /** */
271 int m_nDataType;
272 /** */
273 ulonglong m_nTransferID;
274 /** */
275 CString sNick;
276 /** */
277 CString sBuffer;
278 /** remote filesize */
279 ulonglong m_nFileSize;
280 /** start transfer from this fileposition */
281 ulonglong m_nStartPosition;
282 /** */
283 ulonglong m_nEndPosition;
284 /** bytes transfered */
285 ulonglong m_nTransfered;
286 /** wanted bytes */
287 ulonglong m_nChunkSize;
288 /** */
289 bool m_bListener;
290 /** */
291 long m_nFileBufferPos;
292 /** */
293 long m_nFileBufferSize;
294 /** */
295 ulonglong m_nTransferRate;
296 /** */
297 eConnectionState eMode;
298 /** */
299 eltMedium eMedium;
300 /** */
301 bool m_bIdle;
302 /** */
303 CFile m_File;
304 /** */
305 CByteArray * pByteArray;
306 /** local filename */
307 CString sSrcFilename;
308 /** remote filename */
309 CString sDstFilename;
310 /** local direction */
311 eDirection eSrcDirection;
312 /** remote direction */
313 eDirection eDstDirection;
314 /** remote nick */
315 CString sDstNick;
316 /** local level */
317 int m_nSrcLevel;
318 /** local level */
319 int m_nDstLevel;
320 /** identifier hubname */
321 CString sHubName;
322 /** identifier hubhost:hubport */
323 CString sHubHost;
324 /** */
325 struct timeval starttime;
326 /** */
327 ulonglong m_nPendingSendBytes;
328 /** */
329 CMutex TransferMutex;
330 /** callback function */
331 _CCallback2<CTransfer, CDCMessage*> * pCallback;
332 /** */
333 eTransferState m_eTransferState;
334 /** */
335 eTransferType m_eTransferType;
336 /** */
337 CMessageSupports m_MessageSupports;
338 /** Disable XML filelists for DC++ >= 0.307 and <= 0.403 */
339 bool m_bDisableXML;
340 /** */
341 struct sAverageTransferRate m_AverageTransferRate;
342 /** */
343 CZLib m_ZLib;
344 /** used to compress uploads */
345 CDeflater m_Deflater;
346 /** size of read buffer */
347 long m_nReadFileBufferSize;
348 /** last return value from czlib/cdeflater */
349 int m_nZlibStatus;
350 /** file TTH */
351 CString m_sTTH;
352 };
353
354 /** */
GetDstFilename()355 inline CString CTransfer::GetDstFilename() const
356 { return sDstFilename; }
357 /** */
SetDstFilename(CString filename)358 inline void CTransfer::SetDstFilename( CString filename )
359 { TransferMutex.Lock(); sDstFilename=filename; TransferMutex.UnLock(); }
360 /** */
GetSrcFilename()361 inline CString CTransfer::GetSrcFilename() const
362 { return sSrcFilename; }
363 /** */
SetSrcFilename(CString filename)364 inline void CTransfer::SetSrcFilename( CString filename )
365 { TransferMutex.Lock(); sSrcFilename=filename; TransferMutex.UnLock(); }
366 /** */
GetDstNick()367 inline CString CTransfer::GetDstNick() const
368 { return sDstNick; }
369 /** */
GetHubHost()370 inline CString CTransfer::GetHubHost() const
371 { return sHubHost; }
372 /** */
SetHubHost(CString hubhost)373 inline void CTransfer::SetHubHost( CString hubhost )
374 { TransferMutex.Lock(); sHubHost=hubhost; TransferMutex.UnLock(); }
375 /** */
GetHubName()376 inline CString CTransfer::GetHubName() const
377 { return sHubName; }
378 /** */
SetHubName(CString hubname)379 inline void CTransfer::SetHubName( CString hubname )
380 { TransferMutex.Lock(); sHubName=hubname; TransferMutex.UnLock(); }
381 /** */
SetMedium(eltMedium medium)382 inline void CTransfer::SetMedium( eltMedium medium )
383 { TransferMutex.Lock(); eMedium=medium; TransferMutex.UnLock(); }
384 /** */
GetMedium()385 inline eltMedium CTransfer::GetMedium() const
386 { return eMedium; }
387 /** */
GetSrcDirection()388 inline eDirection CTransfer::GetSrcDirection() const
389 { return eSrcDirection; }
390 /** */
SetSrcDirection(eDirection direction)391 inline void CTransfer::SetSrcDirection( eDirection direction )
392 { TransferMutex.Lock(); eSrcDirection = direction; TransferMutex.UnLock(); }
393 /** */
GetDstDirection()394 inline eDirection CTransfer::GetDstDirection() const
395 { return eDstDirection; }
396 /** */
SetDstDirection(eDirection direction)397 inline void CTransfer::SetDstDirection( eDirection direction )
398 { TransferMutex.Lock(); eDstDirection = direction; TransferMutex.UnLock(); }
399 /** */
GetSrcLevel()400 inline int CTransfer::GetSrcLevel() const
401 { return m_nSrcLevel; }
402 /** */
GetDstLevel()403 inline int CTransfer::GetDstLevel() const
404 { return m_nDstLevel; }
405 /** */
GetMode()406 inline eConnectionState CTransfer::GetMode() const
407 { return eMode; }
408 /** */
SetMode(eConnectionState mode)409 inline void CTransfer::SetMode( eConnectionState mode )
410 { TransferMutex.Lock(); eMode = mode; TransferMutex.UnLock(); }
411 /** */
GetStartPosition()412 inline ulonglong CTransfer::GetStartPosition() const
413 { return m_nStartPosition; }
414 /** */
SetStartPosition(ulonglong pos)415 inline void CTransfer::SetStartPosition( ulonglong pos )
416 { TransferMutex.Lock(); m_nStartPosition=pos; TransferMutex.UnLock(); }
417 /** */
GetEndPosition()418 inline ulonglong CTransfer::GetEndPosition() const
419 { return m_nEndPosition; }
420 /** */
SetEndPosition(ulonglong pos)421 inline void CTransfer::SetEndPosition( ulonglong pos )
422 { TransferMutex.Lock(); m_nEndPosition=pos; TransferMutex.UnLock(); }
423 /** */
GetLength()424 inline ulonglong CTransfer::GetLength() const
425 { return m_nFileSize; }
426 /** */
SetLength(ulonglong length)427 inline void CTransfer::SetLength( ulonglong length )
428 { TransferMutex.Lock(); m_nFileSize = length; TransferMutex.UnLock(); }
429 /** */
GetTransfered()430 inline ulonglong CTransfer::GetTransfered() const
431 { return m_nTransfered; }
432 /** */
SetNick(CString nick)433 inline void CTransfer::SetNick(CString nick)
434 { TransferMutex.Lock(); sNick=nick; TransferMutex.UnLock(); }
435 /** */
GetNick()436 inline CString CTransfer::GetNick()
437 { return sNick; }
438 /** */
SetRate(ulonglong rate)439 inline void CTransfer::SetRate( ulonglong rate )
440 { TransferMutex.Lock(); m_nTransferRate=rate; TransferMutex.UnLock(); }
441 /** */
GetRate()442 inline ulonglong CTransfer::GetRate() const
443 { return m_nTransferRate; }
444 /** */
IsIdle()445 inline bool CTransfer::IsIdle() const
446 { return m_bIdle; }
447 /** */
SetCallBackFunction(_CCallback2<CTransfer,CDCMessage * > * callback)448 inline void CTransfer::SetCallBackFunction( _CCallback2<CTransfer, CDCMessage*> * callback )
449 { TransferMutex.Lock(); delete pCallback; pCallback = callback; TransferMutex.UnLock(); }
450 /** */
SetDone(eTransferState e)451 inline void CTransfer::SetDone( eTransferState e )
452 { TransferMutex.Lock(); m_eTransferState = e; TransferMutex.UnLock(); }
453 /** */
GetDone()454 inline eTransferState CTransfer::GetDone() const
455 { return m_eTransferState; }
456 /** */
GetStartTime()457 inline time_t CTransfer::GetStartTime() const
458 { return starttime.tv_sec; }
459 /** */
SetStartTime(time_t t)460 inline void CTransfer::SetStartTime( time_t t )
461 { TransferMutex.Lock(); starttime.tv_sec = t; TransferMutex.UnLock(); }
462 /** */
GetTransferID()463 inline ulonglong CTransfer::GetTransferID() const
464 { return m_nTransferID; }
465 /** */
SetTransferID(ulonglong transferid)466 inline void CTransfer::SetTransferID( ulonglong transferid )
467 { TransferMutex.Lock(); m_nTransferID = transferid; TransferMutex.UnLock(); }
468 /** */
GetTransferType()469 inline eTransferType CTransfer::GetTransferType() const
470 { return m_eTransferType; }
471 /** */
SetTransferType(eTransferType type)472 inline void CTransfer::SetTransferType( eTransferType type )
473 { TransferMutex.Lock(); m_eTransferType = type; TransferMutex.UnLock(); }
474 /** */
GetTTH()475 inline CString CTransfer::GetTTH() const
476 { return m_sTTH; }
477 /** */
SetTTH(const CString & newtth)478 inline void CTransfer::SetTTH( const CString & newtth )
479 { TransferMutex.Lock(); m_sTTH = newtth; TransferMutex.UnLock(); }
480
481 #endif
482