00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "Qt.h"
00024 #include "LocalPeer.h"
00025 #include "Http/Header.h"
00026 #include "Gnutella/Bootstrapping/ConnectionKeeper.h"
00027 #include "Gnutella/Bootstrapping/NodeCache.h"
00028 #include "Gnutella/Bootstrapping/PingHandler.h"
00029 #include "Gnutella/Bootstrapping/PongHandler.h"
00030 #include "Gnutella/Bootstrapping/UdpHostCache.h"
00031 #include "Protocols/Transports/TcpConnection.h"
00032 #include "Protocols/Transports/UdpConnection.h"
00033 #include "Protocols/Transports/UdpSwitch.h"
00034 #include "Gnutella/Handshaking/Handshaker.h"
00035 #include "Gnutella/Handshaking/SlotAllocator.h"
00036 #include "Gnutella/PacketProcessing/PacketProcessor.h"
00037 #include "Gnutella/PacketProcessing/PongCache.h"
00038 #include "Gnutella/Packets/Extensions/Ggeps/DailyUptime.h"
00039 #include "Gnutella/Packets/Query.h"
00040 #include "Gnutella/Searching/LocalSearch.h"
00041 #include "Gnutella/Searching/Searcher.h"
00042 #include "UIs/NodeModel.h"
00043 #include "PacketModel.h"
00044 #include "UIs/Searching/SearchModel.h"
00045
00046 using Gnutella::LocalPeer;
00047 using Gnutella::LocalPeerPrivate;
00048 using Gnutella::NodeInfo;
00049 using Gnutella::Bootstrapping::ConnectionKeeper;
00050 using Gnutella::Bootstrapping::NodeCache;
00051 using Gnutella::Bootstrapping::PingHandler;
00052 using Gnutella::Bootstrapping::PongHandler;
00053 using Gnutella::Bootstrapping::UdpHostCache;
00054 using Protocols::Transports::Connection;
00055 using Protocols::Transports::TcpConnection;
00056 using Protocols::Transports::UdpConnection;
00057 using Protocols::Transports::UdpSwitch;
00058 using Gnutella::Handshaking::HandshakeError;
00059 using Gnutella::Handshaking::Handshaker;
00060 using Gnutella::Handshaking::SlotAllocator;
00061 using Gnutella::PacketProcessing::PacketProcessor;
00062 using Gnutella::Searching::LocalSearch;
00063 using Gnutella::Searching::Searcher;
00064 using UIs::Searching::SearchModel;
00065
00066
00067
00068
00069 class Gnutella::Workaround {
00070 public:
00071 Workaround (LocalPeer *lp, LocalPeerPrivate *p)
00072 { lp->p = p; }
00073 };
00074
00075 class LocalPeerPrivate
00076 {
00077 public:
00078 Workaround workaround;
00079 NodeCache nodeCache;
00080 UdpHostCache udpHostCache;
00081 Handshaker handshaker;
00082 ConnectionKeeper connectionKeeper;
00083 SlotAllocator slotAllocator;
00084 LocalSearch localSearch;
00085 Searcher searcher;
00086 PacketProcessor packetProcessor;
00087 PingHandler pingHandler;
00088 PongHandler pongHandler;
00089
00090 NodeInfo nodeInfo;
00091 bool serverIsFirewalled;
00092
00093 QTcpServer server;
00094 UdpSwitch udpSwitch;
00095
00096 NodeModel nodeModel;
00097 PacketModel packetModel;
00098
00099 LocalPeerPrivate (LocalPeer *localPeer)
00100 : workaround (localPeer, this),
00101 nodeCache(),
00102 udpHostCache (&udpSwitch, &pingHandler),
00103 handshaker (localPeer, &nodeCache, &slotAllocator),
00104 connectionKeeper (localPeer),
00105 slotAllocator (localPeer),
00106 localSearch (localPeer, &packetProcessor),
00107 searcher (localPeer),
00108 packetProcessor (localPeer),
00109 pingHandler (localPeer),
00110 pongHandler (localPeer),
00111 nodeInfo(),
00112 serverIsFirewalled (false),
00113 server(),
00114 udpSwitch(),
00115 nodeModel(),
00116 packetModel()
00117 {
00118 nodeInfo.type = Gnutella::TypeUltrapeer;
00119
00120
00121 qRegisterMetaType <qint64> ("qint64");
00122 }
00123 };
00124
00125 LocalPeer::LocalPeer()
00126 : p (new LocalPeerPrivate (this))
00127 {
00128 connect (&p->slotAllocator, SIGNAL (handshakingSlotFreed()),
00129 &p->connectionKeeper, SLOT (keepConnection()));
00130 connect (&p->slotAllocator, SIGNAL (ultrapeerSlotFreed()),
00131 &p->connectionKeeper, SLOT (keepConnection()));
00132 connect (&p->slotAllocator, SIGNAL (peerSlotFreed()),
00133 &p->connectionKeeper, SLOT (keepConnection()));
00134 connect (&p->packetProcessor, SIGNAL (receivedPong (const Pong &)),
00135 &p->pongHandler, SLOT (processPong (const Pong &)));
00136 connect (&p->packetProcessor, SIGNAL (receivedQueryHits (const QueryHits &)),
00137 &p->searcher, SLOT (processQueryHits (const QueryHits &)));
00138 connect (&p->packetProcessor, SIGNAL (processQueryStatusRequest (const QueryStatusRequest &)),
00139 &p->searcher, SLOT (processQueryStatusRequest (const QueryStatusRequest &)));
00140 connect (&p->udpHostCache, SIGNAL (receivedPong (const Pong &)),
00141 &p->pongHandler, SLOT (processPong (const Pong &)));
00142 connect (&p->udpSwitch, SIGNAL (connectionAccepted (UdpConnection *)),
00143 &p->udpHostCache, SLOT (connectionAcceptedSlot (UdpConnection *)));
00144 connect (&p->handshaker, SIGNAL (handshakingStarted (Connection *)),
00145 &p->nodeModel, SLOT (setHandshaking (Connection *)));
00146 connect (&p->handshaker, SIGNAL (handshakingCompleted (Connection *, NodeInfo)),
00147 &p->nodeModel, SLOT (setConnected (Connection *, NodeInfo)));
00148 connect (&p->handshaker, SIGNAL (handshakingCompleted (Connection *, NodeInfo)),
00149 &p->packetProcessor, SLOT (addConnection (Connection *, NodeInfo)));
00150 }
00151
00152 LocalPeer::~LocalPeer()
00153 {
00154 disconnectFromNetwork();
00155 delete p;
00156 }
00157
00158 bool LocalPeer::isUltrapeer() const
00159 { return p->nodeInfo.type == TypeUltrapeer; }
00160
00161 QHostAddress LocalPeer::serverIpAddress() const
00162 { return p->nodeInfo.address.hostAddress(); }
00163
00164 quint16 LocalPeer::serverPort() const
00165 { return p->nodeInfo.address.hostPort(); }
00166
00167 const NodeInfo & LocalPeer::nodeInfo() const
00168 { return p->nodeInfo; }
00169
00170 UdpHostCache * LocalPeer::udpHostCache()
00171 { return &p->udpHostCache; }
00172
00173 SlotAllocator * LocalPeer::slotAllocator()
00174 { return &p->slotAllocator; }
00175
00176 NodeCache * LocalPeer::nodeCache()
00177 { return &p->nodeCache; }
00178
00179 PacketProcessor * LocalPeer::packetProcessor()
00180 { return &p->packetProcessor; }
00181
00182 Searcher* LocalPeer::searcher()
00183 { return &p->searcher; }
00184
00185 QAbstractItemModel * LocalPeer::nodeModel()
00186 { return &p->nodeModel; }
00187
00188 QAbstractItemModel * LocalPeer::packetModel()
00189 { return &p->packetModel; }
00190
00191 bool LocalPeer::connectToNetwork()
00192 {
00193
00194 if (p->nodeInfo.address.hostPort() == 0)
00195 return false;
00196
00197 connect (&p->server, SIGNAL(newConnection()), this, SLOT(newConnection()));
00198 if (!p->server.listen (QHostAddress::Any, p->nodeInfo.address.hostPort()))
00199 return false;
00200
00201 setServerIpAddress (p->server.serverAddress());
00202
00203
00204
00205 p->udpSwitch.start (NodeAddress (QHostAddress::Any, p->nodeInfo.address.hostPort()), true);
00206
00207 p->nodeCache.loadNodes (tr ("hosts.dat"));
00208
00209 p->connectionKeeper.bootstrap();
00210 return true;
00211 }
00212
00213 void LocalPeer::setServerIpAddress (const QHostAddress &ipAddress)
00214 {
00215
00216
00217 p->nodeInfo.address.setHostAddress (ipAddress);
00218
00219
00220
00221
00222
00223 }
00224
00225 void LocalPeer::setServerPort (quint16 port)
00226 {
00227
00228 p->nodeInfo.address.setHostPort (port);
00229
00230
00231
00232
00233
00234 }
00235
00236 bool LocalPeer::disconnectFromNetwork()
00237 {
00238 p->nodeCache.storeNodes (tr ("hosts.dat"));
00239
00240 return true;
00241 }
00242
00243 void LocalPeer::connectToPeer (const QString &hostName, quint16 port)
00244 {
00245 qDebug() << "Connecting to " << hostName << ":" << port;
00246
00247 TcpConnection *connection = new TcpConnection;
00248 NodeAddress nodeAddress = NodeAddress (hostName, port);
00249 p->nodeModel.nodeConnecting (connection, nodeAddress);
00250 p->handshaker.requestConnection (connection, nodeAddress);
00251 }
00252
00253 void LocalPeer::disconnectFromPeer (Connection *connection)
00254 {
00255 connection->disconnectFromNode();
00256 }
00257
00258 void LocalPeer::newConnection()
00259 {
00260 QTcpSocket *socket = p->server.nextPendingConnection();
00261 qDebug() << "Accepting connection from " << socket->peerAddress().toString() << ":" << socket->peerPort();
00262
00263 acceptHandshakeConnection (socket);
00264 }
00265
00266 void LocalPeer::acceptHandshakeConnection (QTcpSocket *socket)
00267 {
00268 Connection *connection = new TcpConnection (socket);
00269
00270 NodeAddress nodeAddress = connection->remoteNodeAddress();
00271
00272 p->nodeModel.nodeConnecting (connection, nodeAddress);
00273 p->handshaker.acceptConnection (connection);
00274 }
00275
00276
00277 void LocalPeer::startSearch (SearchModel *searchModel, QString &query)
00278 {
00279 searcher()->startSearch (searchModel, query);
00280 }
00281
00285 void LocalPeer::stopSearch (SearchModel *searchModel)
00286 {
00287 searcher()->stopSearch (searchModel);
00288 }