1 /* 2 * Copyright (C) 2009-2010 Big Muscle, http://strongdc.sf.net 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 17 */ 18 19 #pragma once 20 21 #include "BootstrapManager.h" 22 #include "Constants.h" 23 #include "KBucket.h" 24 #include "UDPSocket.h" 25 #include "stdafx.h" 26 #include "dcpp/AdcCommand.h" 27 #include "dcpp/CID.h" 28 #include "dcpp/MerkleTree.h" 29 #include "dcpp/Singleton.h" 30 #include "dcpp/TimerManager.h" 31 32 namespace dht 33 { 34 35 class DHT : 36 public Singleton<DHT>, public Speaker<ClientListener>, public ClientBase 37 { 38 public: 39 DHT(void); 40 ~DHT(void) throw(); 41 42 enum InfType { NONE = 0, PING = 1, MAKE_ONLINE = 2 }; 43 44 /** ClientBase derived functions */ getHubUrl()45 const string& getHubUrl() const { return NetworkName; } getHubName()46 string getHubName() const { return NetworkName; } isOp()47 bool isOp() const { return false; } 48 49 /** Starts DHT. */ 50 void start(); 51 void stop(bool exiting = false); 52 getPort()53 uint16_t getPort() const { return BOOLSETTING(USE_DHT) ? socket.getPort() : 0; } 54 55 /** Process incoming command */ 56 void dispatch(const string& aLine, const string& ip, uint16_t port, bool isUdpKeyValid); 57 58 /** Sends command to ip and port */ 59 void send(AdcCommand& cmd, const string& ip, uint16_t port, const CID& targetCID, const CID& udpKey); 60 61 /** Creates new (or update existing) node which is NOT added to our routing table */ 62 Node::Ptr createNode(const CID& cid, const string& ip, uint16_t port, bool update, bool isUdpKeyValid); 63 64 /** Adds node to routing table */ 65 bool addNode(const Node::Ptr& node, bool makeOnline); 66 67 /** Returns counts of nodes available in k-buckets */ getNodesCount()68 size_t getNodesCount() { Lock l(cs); return bucket->getNodes().size(); } 69 70 /** Removes dead nodes */ 71 void checkExpiration(uint64_t aTick); 72 73 /** Finds the file in the network */ 74 void findFile(const string& tth, const string& token = Util::toString(Util::rand())); 75 76 /** Sends our info to specified ip:port */ 77 void info(const string& ip, uint16_t port, uint32_t type, const CID& targetCID, const CID& udpKey); 78 79 /** Sends Connect To Me request to online node */ 80 void connect(const OnlineUser& ou, const string& token); 81 82 /** Sends private message to online node */ 83 void privateMessage(const OnlineUser& ou, const string& aMessage, bool thirdPerson); 84 85 /** Is DHT connected? */ isConnected()86 bool isConnected() const { return lastPacket && (GET_TICK() - lastPacket < CONNECTED_TIMEOUT); } 87 88 /** Mark that network data should be saved */ setDirty()89 void setDirty() { dirty = true; } 90 91 /** Saves network information to XML file */ 92 void saveData(); 93 94 /** Returns if our UDP port is open */ isFirewalled()95 bool isFirewalled() const { return firewalled; } 96 97 /** Returns our IP got from the last firewall check */ getLastExternalIP()98 string getLastExternalIP() const { return lastExternalIP; } 99 setRequestFWCheck()100 void setRequestFWCheck() { Lock l(cs); requestFWCheck = true; firewalledWanted.clear(); firewalledChecks.clear(); } 101 102 private: 103 /** Classes that can access to my private members */ 104 friend class Singleton<DHT>; 105 friend class SearchManager; 106 107 void handle(AdcCommand::INF, const Node::Ptr& node, AdcCommand& c) throw(); // user's info 108 void handle(AdcCommand::SCH, const Node::Ptr& node, AdcCommand& c) throw(); // incoming search request 109 void handle(AdcCommand::RES, const Node::Ptr& node, AdcCommand& c) throw(); // incoming search result 110 void handle(AdcCommand::PUB, const Node::Ptr& node, AdcCommand& c) throw(); // incoming publish request 111 void handle(AdcCommand::CTM, const Node::Ptr& node, AdcCommand& c) throw(); // connection request 112 void handle(AdcCommand::RCM, const Node::Ptr& node, AdcCommand& c) throw(); // reverse connection request 113 void handle(AdcCommand::STA, const Node::Ptr& node, AdcCommand& c) throw(); // status message 114 void handle(AdcCommand::PSR, const Node::Ptr& node, AdcCommand& c) throw(); // partial file request 115 void handle(AdcCommand::MSG, const Node::Ptr& node, AdcCommand& c) throw(); // private message 116 void handle(AdcCommand::GET, const Node::Ptr& node, AdcCommand& c) throw(); 117 void handle(AdcCommand::SND, const Node::Ptr& node, AdcCommand& c) throw(); 118 119 /** Unsupported command */ handle(T,const Node::Ptr & user,AdcCommand &)120 template<typename T> void handle(T, const Node::Ptr&user, AdcCommand&) { } 121 122 /** UDP socket */ 123 UDPSocket socket; 124 125 /** Routing table */ 126 KBucket* bucket; 127 128 /** Lock to routing table */ 129 CriticalSection cs; 130 CriticalSection fwCheckCs; 131 132 /** Our external IP got from last firewalled check */ 133 string lastExternalIP; 134 135 /** Time when last packet was received */ 136 uint64_t lastPacket; 137 138 /** IPs who we received firewalled status from */ 139 std::unordered_set<string> firewalledWanted; 140 std::unordered_map< string, std::pair< string, uint16_t > > firewalledChecks; 141 bool firewalled; 142 bool requestFWCheck; 143 144 /** Should the network data be saved? */ 145 bool dirty; 146 147 /** Finds "max" closest nodes and stores them to the list */ 148 void getClosestNodes(const CID& cid, std::map<CID, Node::Ptr>& closest, unsigned int max, uint8_t maxType); 149 150 /** Loads network information from XML file */ 151 void loadData(); 152 }; 153 154 } 155