1 /* <!-- copyright */ 2 /* 3 * aria2 - The high speed download utility 4 * 5 * Copyright (C) 2006 Tatsuhiro Tsujikawa 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program 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. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 * 21 * In addition, as a special exception, the copyright holders give 22 * permission to link the code of portions of this program with the 23 * OpenSSL library under certain conditions as described in each 24 * individual source file, and distribute linked combinations 25 * including the two. 26 * You must obey the GNU General Public License in all respects 27 * for all of the code used other than OpenSSL. If you modify 28 * file(s) with this exception, you may extend this exception to your 29 * version of the file(s), but you are not obligated to do so. If you 30 * do not wish to do so, delete this exception statement from your 31 * version. If you delete this exception statement from all source 32 * files in the program, then also delete it here. 33 */ 34 /* copyright --> */ 35 #ifndef D_DOWNLOAD_ENGINE_H 36 #define D_DOWNLOAD_ENGINE_H 37 38 #include "common.h" 39 40 #include <string> 41 #include <deque> 42 #include <map> 43 #include <vector> 44 #include <memory> 45 46 #include "a2netcompat.h" 47 #include "TimerA2.h" 48 #include "a2io.h" 49 #include "CUIDCounter.h" 50 #include "FileAllocationMan.h" 51 #include "CheckIntegrityMan.h" 52 #include "DNSCache.h" 53 #ifdef ENABLE_ASYNC_DNS 54 # include "AsyncNameResolver.h" 55 #endif // ENABLE_ASYNC_DNS 56 57 namespace aria2 { 58 59 class Option; 60 class RequestGroupMan; 61 class StatCalc; 62 class SocketCore; 63 class CookieStorage; 64 class AuthConfigFactory; 65 class Request; 66 class EventPoll; 67 class Command; 68 #ifdef ENABLE_BITTORRENT 69 class BtRegistry; 70 #endif // ENABLE_BITTORRENT 71 #ifdef ENABLE_WEBSOCKET 72 namespace rpc { 73 class WebSocketSessionMan; 74 } // namespace rpc 75 #endif // ENABLE_WEBSOCKET 76 77 namespace util { 78 namespace security { 79 class HMAC; 80 class HMACResult; 81 } // namespace security 82 } // namespace util 83 84 class DownloadEngine { 85 private: 86 void waitData(); 87 88 std::string sessionId_; 89 90 std::unique_ptr<EventPoll> eventPoll_; 91 92 std::unique_ptr<StatCalc> statCalc_; 93 94 int haltRequested_; 95 96 class SocketPoolEntry { 97 private: 98 std::shared_ptr<SocketCore> socket_; 99 // protocol specific option string 100 std::string options_; 101 102 std::chrono::seconds timeout_; 103 104 Timer registeredTime_; 105 106 public: 107 SocketPoolEntry(const std::shared_ptr<SocketCore>& socket, 108 const std::string& option, std::chrono::seconds timeout); 109 110 SocketPoolEntry(const std::shared_ptr<SocketCore>& socket, 111 std::chrono::seconds timeout); 112 113 ~SocketPoolEntry(); 114 115 bool isTimeout() const; 116 getSocket()117 const std::shared_ptr<SocketCore>& getSocket() const { return socket_; } 118 getOptions()119 const std::string& getOptions() const { return options_; } 120 }; 121 122 // key = IP address:port, value = SocketPoolEntry 123 std::multimap<std::string, SocketPoolEntry> socketPool_; 124 125 Timer lastSocketPoolScan_; 126 127 bool noWait_; 128 129 std::chrono::milliseconds refreshInterval_; 130 Timer lastRefresh_; 131 132 std::unique_ptr<CookieStorage> cookieStorage_; 133 134 #ifdef ENABLE_BITTORRENT 135 std::unique_ptr<BtRegistry> btRegistry_; 136 #endif // ENABLE_BITTORRENT 137 138 CUIDCounter cuidCounter_; 139 140 #ifdef HAVE_ARES_ADDR_NODE 141 ares_addr_node* asyncDNSServers_; 142 #endif // HAVE_ARES_ADDR_NODE 143 144 std::unique_ptr<DNSCache> dnsCache_; 145 146 std::unique_ptr<AuthConfigFactory> authConfigFactory_; 147 148 #ifdef ENABLE_WEBSOCKET 149 std::unique_ptr<rpc::WebSocketSessionMan> webSocketSessionMan_; 150 #endif // ENABLE_WEBSOCKET 151 152 /** 153 * Delegates to StatCalc 154 */ 155 void calculateStatistics(); 156 157 void onEndOfRun(); 158 159 void afterEachIteration(); 160 161 void poolSocket(const std::string& key, const SocketPoolEntry& entry); 162 163 std::multimap<std::string, SocketPoolEntry>::iterator 164 findSocketPoolEntry(const std::string& key); 165 166 std::unique_ptr<RequestGroupMan> requestGroupMan_; 167 std::unique_ptr<FileAllocationMan> fileAllocationMan_; 168 std::unique_ptr<CheckIntegrityMan> checkIntegrityMan_; 169 Option* option_; 170 // Ensure that Commands are cleaned up before requestGroupMan_ is 171 // deleted. 172 std::deque<std::unique_ptr<Command>> routineCommands_; 173 std::deque<std::unique_ptr<Command>> commands_; 174 175 std::unique_ptr<util::security::HMAC> tokenHMAC_; 176 std::unique_ptr<util::security::HMACResult> tokenExpected_; 177 178 public: 179 DownloadEngine(std::unique_ptr<EventPoll> eventPoll); 180 181 ~DownloadEngine(); 182 183 // If oneshot is true, this function returns after one event polling 184 // and performing action for them. This function returns 1 when 185 // oneshot is true and there are still downloads to be 186 // processed. Otherwise, returns 0. 187 int run(bool oneshot = false); 188 189 bool addSocketForReadCheck(const std::shared_ptr<SocketCore>& socket, 190 Command* command); 191 bool deleteSocketForReadCheck(const std::shared_ptr<SocketCore>& socket, 192 Command* command); 193 bool addSocketForWriteCheck(const std::shared_ptr<SocketCore>& socket, 194 Command* command); 195 bool deleteSocketForWriteCheck(const std::shared_ptr<SocketCore>& socket, 196 Command* command); 197 198 #ifdef ENABLE_ASYNC_DNS 199 200 bool addNameResolverCheck(const std::shared_ptr<AsyncNameResolver>& resolver, 201 Command* command); 202 bool 203 deleteNameResolverCheck(const std::shared_ptr<AsyncNameResolver>& resolver, 204 Command* command); 205 #endif // ENABLE_ASYNC_DNS 206 207 void addCommand(std::vector<std::unique_ptr<Command>> commands); 208 209 void addCommand(std::unique_ptr<Command> command); 210 getRequestGroupMan()211 const std::unique_ptr<RequestGroupMan>& getRequestGroupMan() const 212 { 213 return requestGroupMan_; 214 } 215 216 void setRequestGroupMan(std::unique_ptr<RequestGroupMan> rgman); 217 getFileAllocationMan()218 const std::unique_ptr<FileAllocationMan>& getFileAllocationMan() const 219 { 220 return fileAllocationMan_; 221 } 222 223 void setFileAllocationMan(std::unique_ptr<FileAllocationMan> faman); 224 getCheckIntegrityMan()225 const std::unique_ptr<CheckIntegrityMan>& getCheckIntegrityMan() const 226 { 227 return checkIntegrityMan_; 228 } 229 230 void setCheckIntegrityMan(std::unique_ptr<CheckIntegrityMan> ciman); 231 getOption()232 Option* getOption() const { return option_; } 233 setOption(Option * op)234 void setOption(Option* op) { option_ = op; } 235 236 void setStatCalc(std::unique_ptr<StatCalc> statCalc); 237 isHaltRequested()238 bool isHaltRequested() const { return haltRequested_; } 239 isForceHaltRequested()240 bool isForceHaltRequested() const { return haltRequested_ >= 2; } 241 242 void requestHalt(); 243 244 void requestForceHalt(); 245 246 void setNoWait(bool b); 247 248 void addRoutineCommand(std::unique_ptr<Command> command); 249 250 void poolSocket(const std::string& ipaddr, uint16_t port, 251 const std::string& username, const std::string& proxyhost, 252 uint16_t proxyport, const std::shared_ptr<SocketCore>& sock, 253 const std::string& options, 254 std::chrono::seconds timeout = 15_s); 255 256 void poolSocket(const std::shared_ptr<Request>& request, 257 const std::string& username, 258 const std::shared_ptr<Request>& proxyRequest, 259 const std::shared_ptr<SocketCore>& socket, 260 const std::string& options, 261 std::chrono::seconds timeout = 15_s); 262 263 void poolSocket(const std::string& ipaddr, uint16_t port, 264 const std::string& proxyhost, uint16_t proxyport, 265 const std::shared_ptr<SocketCore>& sock, 266 std::chrono::seconds timeout = 15_s); 267 268 void poolSocket(const std::shared_ptr<Request>& request, 269 const std::shared_ptr<Request>& proxyRequest, 270 const std::shared_ptr<SocketCore>& socket, 271 std::chrono::seconds timeout = 15_s); 272 273 std::shared_ptr<SocketCore> popPooledSocket(const std::string& ipaddr, 274 uint16_t port, 275 const std::string& proxyhost, 276 uint16_t proxyport); 277 278 std::shared_ptr<SocketCore> 279 popPooledSocket(std::string& options, const std::string& ipaddr, 280 uint16_t port, const std::string& username, 281 const std::string& proxyhost, uint16_t proxyport); 282 283 std::shared_ptr<SocketCore> 284 popPooledSocket(const std::vector<std::string>& ipaddrs, uint16_t port); 285 286 std::shared_ptr<SocketCore> 287 popPooledSocket(std::string& options, const std::vector<std::string>& ipaddrs, 288 uint16_t port, const std::string& username); 289 290 void evictSocketPool(); 291 292 const std::unique_ptr<CookieStorage>& getCookieStorage() const; 293 294 #ifdef ENABLE_BITTORRENT getBtRegistry()295 const std::unique_ptr<BtRegistry>& getBtRegistry() const 296 { 297 return btRegistry_; 298 } 299 #endif // ENABLE_BITTORRENT 300 301 cuid_t newCUID(); 302 303 const std::string& findCachedIPAddress(const std::string& hostname, 304 uint16_t port) const; 305 306 template <typename OutputIterator> findAllCachedIPAddresses(OutputIterator out,const std::string & hostname,uint16_t port)307 void findAllCachedIPAddresses(OutputIterator out, const std::string& hostname, 308 uint16_t port) const 309 { 310 dnsCache_->findAll(out, hostname, port); 311 } 312 313 void cacheIPAddress(const std::string& hostname, const std::string& ipaddr, 314 uint16_t port); 315 316 void markBadIPAddress(const std::string& hostname, const std::string& ipaddr, 317 uint16_t port); 318 319 void removeCachedIPAddress(const std::string& hostname, uint16_t port); 320 321 void setAuthConfigFactory(std::unique_ptr<AuthConfigFactory> factory); 322 323 const std::unique_ptr<AuthConfigFactory>& getAuthConfigFactory() const; 324 325 void setRefreshInterval(std::chrono::milliseconds interval); 326 getSessionId()327 const std::string getSessionId() const { return sessionId_; } 328 329 #ifdef HAVE_ARES_ADDR_NODE 330 void setAsyncDNSServers(ares_addr_node* asyncDNSServers); 331 getAsyncDNSServers()332 ares_addr_node* getAsyncDNSServers() const { return asyncDNSServers_; } 333 #endif // HAVE_ARES_ADDR_NODE 334 335 #ifdef ENABLE_WEBSOCKET 336 void setWebSocketSessionMan(std::unique_ptr<rpc::WebSocketSessionMan> wsman); 337 const std::unique_ptr<rpc::WebSocketSessionMan>& getWebSocketSessionMan()338 getWebSocketSessionMan() const 339 { 340 return webSocketSessionMan_; 341 } 342 #endif // ENABLE_WEBSOCKET 343 344 bool validateToken(const std::string& token); 345 }; 346 347 } // namespace aria2 348 349 #endif // D_DOWNLOAD_ENGINE_H 350