1 /** 2 * @file mega/transfer.h 3 * @brief pending/active up/download ordered by file fingerprint 4 * 5 * (c) 2013-2014 by Mega Limited, Auckland, New Zealand 6 * 7 * This file is part of the MEGA SDK - Client Access Engine. 8 * 9 * Applications using the MEGA API must present a valid application key 10 * and comply with the the rules set forth in the Terms of Service. 11 * 12 * The MEGA SDK is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 15 * 16 * @copyright Simplified (2-clause) BSD License. 17 * 18 * You should have received a copy of the license along with this 19 * program. 20 */ 21 22 #ifndef MEGA_TRANSFER_H 23 #define MEGA_TRANSFER_H 1 24 25 #include "filefingerprint.h" 26 #include "backofftimer.h" 27 #include "http.h" 28 #include "command.h" 29 #include "raid.h" 30 31 namespace mega { 32 33 // helper class for categorizing transfers for upload/download queues 34 struct TransferCategory 35 { 36 direction_t direction = NONE; 37 filesizetype_t sizetype = LARGEFILE; 38 39 TransferCategory(direction_t d, filesizetype_t s); 40 TransferCategory(Transfer*); 41 unsigned index(); 42 unsigned directionIndex(); 43 }; 44 45 class DBTableTransactionCommitter; 46 47 // pending/active up/download ordered by file fingerprint (size - mtime - sparse CRC) 48 struct MEGA_API Transfer : public FileFingerprint 49 { 50 // PUT or GET 51 direction_t type; 52 53 // transfer slot this transfer is active in (can be NULL if still queued) 54 TransferSlot* slot; 55 56 // files belonging to this transfer - transfer terminates upon its last 57 // file is removed 58 file_list files; 59 60 // failures/backoff 61 unsigned failcount; 62 BackoffTimerTracked bt; 63 64 // representative local filename for this transfer 65 LocalPath localfilename; 66 67 // progress completed 68 m_off_t progresscompleted; 69 70 m_off_t pos; 71 72 byte filekey[FILENODEKEYLENGTH]; 73 74 // CTR mode IV 75 int64_t ctriv; 76 77 // meta MAC 78 int64_t metamac; 79 80 // file crypto key and shared cipher 81 std::array<byte, SymmCipher::KEYLENGTH> transferkey; 82 SymmCipher *transfercipher(); 83 84 chunkmac_map chunkmacs; 85 86 // upload handle for file attribute attachment (only set if file attribute queued) 87 handle uploadhandle; 88 89 // minimum number of file attributes that need to be posted before a PUT transfer can complete 90 int minfa; 91 92 // position in transfers[type] 93 transfer_map::iterator transfers_it; 94 95 // position in faputcompletion[uploadhandle] 96 handletransfer_map::iterator faputcompletion_it; 97 98 // upload result 99 byte *ultoken; 100 101 // backlink to base 102 MegaClient* client; 103 int tag; 104 105 // signal failure. Either the transfer's slot or the transfer itself (including slot) will be deleted. 106 void failed(const Error&, DBTableTransactionCommitter&, dstime = 0); 107 108 // signal completion 109 void complete(DBTableTransactionCommitter&); 110 111 // execute completion 112 void completefiles(); 113 114 // remove file from transfer including in cache 115 void removeTransferFile(error, File* f, DBTableTransactionCommitter* committer); 116 117 // previous wrong fingerprint 118 FileFingerprint badfp; 119 120 // flag to know if prevmetamac is valid 121 bool hasprevmetamac; 122 123 // previous wrong metamac 124 int64_t prevmetamac; 125 126 // flag to know if currentmetamac is valid 127 bool hascurrentmetamac; 128 129 // current wrong metamac 130 int64_t currentmetamac; 131 132 // transfer state 133 bool finished; 134 135 // temp URLs for upload/download data. They can be cached. For uploads, a new url means any previously uploaded data is abandoned. 136 // downloads can have 6 for raid, 1 for non-raid. Uploads always have 1 137 std::vector<string> tempurls; 138 139 // context of the async fopen operation 140 AsyncIOContext* asyncopencontext; 141 142 // timestamp of the start of the transfer 143 m_time_t lastaccesstime; 144 145 // priority of the transfer 146 uint64_t priority; 147 148 // state of the transfer 149 transferstate_t state; 150 151 bool skipserialization; 152 153 Transfer(MegaClient*, direction_t); 154 virtual ~Transfer(); 155 156 // serialize the Transfer object 157 bool serialize(string*) override; 158 159 // unserialize a Transfer and add it to the transfer map 160 static Transfer* unserialize(MegaClient *, string*, transfer_map *); 161 162 // examine a file on disk for video/audio attributes to attach to the file, on upload/download 163 void addAnyMissingMediaFileAttributes(Node* node, LocalPath& localpath); 164 165 // whether the Transfer needs to remove itself from the list it's in (for quick shutdown we can skip) 166 bool mOptimizedDelete = false; 167 }; 168 169 170 struct LazyEraseTransferPtr 171 { 172 // This class enables us to relatively quickly and efficiently delete many items from the middle of std::deque 173 // By being the class actualy stored in a mega::deque_with_lazy_bulk_erase. 174 // Such builk deletion is done by marking the ones to delete, and finally performing those as a single remove_if. 175 Transfer* transfer; 176 uint64_t preErasurePriority = 0; 177 bool erased = false; 178 LazyEraseTransferPtrLazyEraseTransferPtr179 explicit LazyEraseTransferPtr(Transfer* t) : transfer(t) {} 180 operator Transfer*&() { return transfer; } eraseLazyEraseTransferPtr181 void erase() { preErasurePriority = transfer->priority; transfer = nullptr; erased = true; } isErasedLazyEraseTransferPtr182 bool isErased() const { return erased; } 183 bool operator==(const LazyEraseTransferPtr& e) { return transfer && transfer == e.transfer; } 184 }; 185 186 class MEGA_API TransferList 187 { 188 public: 189 static const uint64_t PRIORITY_START = 0x0000800000000000ull; 190 static const uint64_t PRIORITY_STEP = 0x0000000000010000ull; 191 192 typedef deque_with_lazy_bulk_erase<Transfer*, LazyEraseTransferPtr> transfer_list; 193 194 TransferList(); 195 void addtransfer(Transfer* transfer, DBTableTransactionCommitter&, bool startFirst = false); 196 void removetransfer(Transfer *transfer); 197 void movetransfer(Transfer *transfer, Transfer *prevTransfer, DBTableTransactionCommitter& committer); 198 void movetransfer(Transfer *transfer, unsigned int position, DBTableTransactionCommitter& committer); 199 void movetransfer(Transfer *transfer, transfer_list::iterator dstit, DBTableTransactionCommitter&); 200 void movetransfer(transfer_list::iterator it, transfer_list::iterator dstit, DBTableTransactionCommitter&); 201 void movetofirst(Transfer *transfer, DBTableTransactionCommitter& committer); 202 void movetofirst(transfer_list::iterator it, DBTableTransactionCommitter& committer); 203 void movetolast(Transfer *transfer, DBTableTransactionCommitter& committer); 204 void movetolast(transfer_list::iterator it, DBTableTransactionCommitter& committer); 205 void moveup(Transfer *transfer, DBTableTransactionCommitter& committer); 206 void moveup(transfer_list::iterator it, DBTableTransactionCommitter& committer); 207 void movedown(Transfer *transfer, DBTableTransactionCommitter& committer); 208 void movedown(transfer_list::iterator it, DBTableTransactionCommitter& committer); 209 error pause(Transfer *transfer, bool enable, DBTableTransactionCommitter& committer); 210 transfer_list::iterator begin(direction_t direction); 211 transfer_list::iterator end(direction_t direction); 212 bool getIterator(Transfer *transfer, transfer_list::iterator&, bool canHandleErasedElements = false); 213 std::array<vector<Transfer*>, 6> nexttransfers(std::function<bool(Transfer*)>& continuefunction); 214 Transfer *transferat(direction_t direction, unsigned int position); 215 216 std::array<transfer_list, 2> transfers; 217 MegaClient *client; 218 uint64_t currentpriority; 219 220 private: 221 void prepareIncreasePriority(Transfer *transfer, transfer_list::iterator srcit, transfer_list::iterator dstit, DBTableTransactionCommitter& committer); 222 void prepareDecreasePriority(Transfer *transfer, transfer_list::iterator it, transfer_list::iterator dstit); 223 bool isReady(Transfer *transfer); 224 }; 225 226 struct MEGA_API DirectReadSlot 227 { 228 m_off_t pos; 229 230 // values to calculate the transfer speed 231 static const int MEAN_SPEED_INTERVAL_DS = 100; 232 static const int MIN_BYTES_PER_SECOND = 1024 * 15; 233 static const int TIMEOUT_DS = 100; 234 static const int TEMPURL_TIMEOUT_DS = 3000; 235 236 DirectRead* dr; 237 std::vector<HttpReq*> reqs; 238 239 drs_list::iterator drs_it; 240 SpeedController speedController; 241 m_off_t speed; 242 m_off_t meanSpeed; 243 244 bool doio(); 245 246 DirectReadSlot(DirectRead*); 247 ~DirectReadSlot(); 248 249 private: 250 std::string adjustURLPort(std::string url); 251 bool processAnyOutputPieces(); 252 }; 253 254 struct MEGA_API DirectRead 255 { 256 m_off_t count; 257 m_off_t offset; 258 m_off_t progress; 259 m_off_t nextrequestpos; 260 261 DirectReadBufferManager drbuf; 262 263 DirectReadNode* drn; 264 DirectReadSlot* drs; 265 266 dr_list::iterator reads_it; 267 dr_list::iterator drq_it; 268 269 void* appdata; 270 271 int reqtag; 272 273 void abort(); 274 275 DirectRead(DirectReadNode*, m_off_t, m_off_t, int, void*); 276 ~DirectRead(); 277 }; 278 279 struct MEGA_API DirectReadNode 280 { 281 handle h; 282 bool p; 283 string publicauth; 284 string privateauth; 285 string chatauth; 286 m_off_t partiallen; 287 dstime partialstarttime; 288 289 std::vector<std::string> tempurls; 290 291 m_off_t size; 292 293 class CommandDirectRead* pendingcmd; 294 295 int retries; 296 297 int64_t ctriv; 298 SymmCipher symmcipher; 299 300 dr_list reads; 301 302 MegaClient* client; 303 304 handledrn_map::iterator hdrn_it; 305 dsdrn_map::iterator dsdrn_it; 306 307 // API command result 308 void cmdresult(const Error&, dstime = 0); 309 310 // enqueue new read 311 void enqueue(m_off_t, m_off_t, int, void*); 312 313 // dispatch all reads 314 void dispatch(); 315 316 // schedule next event 317 void schedule(dstime); 318 319 // report failure to app and abort or retry all reads 320 void retry(const Error &, dstime = 0); 321 322 DirectReadNode(MegaClient*, handle, bool, SymmCipher*, int64_t, const char*, const char*, const char*); 323 ~DirectReadNode(); 324 }; 325 } // namespace 326 327 #endif 328