PacketRouter.cpp
Go to the documentation of this file.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 "PacketRouter.h"
00025 #include "Gnutella/Packets/Packet.h"
00026 #include "Gnutella/Packets/Query.h"
00027 #include "Gnutella/Packets/QueryHits.h"
00028 #include "Gnutella/Packets/Push.h"
00029
00030
00031
00032 using Gnutella::PacketProcessing::PacketRouter;
00033 using Gnutella::PacketProcessing::PacketSession;
00034 using Gnutella::Packets::Packet;
00035 using Gnutella::Packets::QueryDescriptor;
00036 using Gnutella::Packets::QueryHitsDescriptor;
00037 using Gnutella::Packets::PushDescriptor;
00038 using Gnutella::Packets::Query;
00039 using Gnutella::Packets::QueryHits;
00040 using Gnutella::Packets::Push;
00041
00042 enum RouterConstants
00043 {
00044 DefaultQueryExpiration = 60 * 10,
00045 DefaultQueryHitsExpiration = 60 * 30,
00046 ExpirationTimerInterval = 1000 * 60
00047 };
00048
00049 PacketRouter::PacketRouter()
00050 : queryPaths(), queryHitsPaths(), queryStatusRequestPaths(),
00051 queryExpirations(), queryHitsExpirations(),
00052 queryStatusRequestExpirations(), expirationTimer()
00053 {
00054 QObject::connect (&expirationTimer, SIGNAL (timeout ()), this, SLOT (clearExpiredPaths ()));
00055 expirationTimer.setInterval (ExpirationTimerInterval);
00056 expirationTimer.start();
00057 }
00058
00062 PacketRouter::~PacketRouter()
00063 {
00064 }
00065
00066 bool PacketRouter::isDuplicate (const Packet &packet)
00067 {
00068 using namespace Gnutella::Packets;
00069 switch (packet.payloadDescriptor())
00070 {
00071 case QueryDescriptor:
00072 {
00073 PacketPaths::iterator it = queryPaths.find (packet.descriptorId());
00074 if (it != queryPaths.end())
00075 return true;
00076 return false;
00077 }
00078 case QueryHitsDescriptor:
00079 case PushDescriptor:
00080
00081
00082 case PingDescriptor:
00083 case PongDescriptor:
00084 case ByeDescriptor:
00085 case IbmcDescriptor:
00086 case QueryRoutingDescriptor:
00087 case OpenVendorDescriptor:
00088 case StandardVendorDescriptor:
00089 default:
00090 return false;
00091 }
00092 }
00093
00094 void PacketRouter::addQueryPath (const Query &query, PacketSession *session)
00095 {
00096 const QUuid &descriptorId = query.descriptorId();
00097 PacketPaths::iterator it = queryPaths.find (descriptorId);
00098
00099 if (it == queryPaths.end()) {
00100 it = queryPaths.insert (descriptorId, new PathSet);
00101 QTime expirationTime = QTime::currentTime().addSecs (DefaultQueryExpiration);
00102 queryExpirations.push_back (new Expiration (descriptorId, expirationTime));
00103 }
00104 (*it)->insert (session);
00105 }
00106
00107 void PacketRouter::addQueryHitsPath (const QueryHits &queryHits, PacketSession *session)
00108 {
00109 const QUuid &serventId = queryHits.serventId();
00110 PacketPaths::iterator it = queryHitsPaths.find (serventId);
00111
00112 if (it == queryHitsPaths.end()) {
00113 it = queryHitsPaths.insert (serventId, new PathSet);
00114 QTime expirationTime = QTime::currentTime().addSecs (DefaultQueryHitsExpiration);
00115 queryExpirations.push_back (new Expiration (serventId, expirationTime));
00116 }
00117 (*it)->insert (session);
00118 }
00119
00120 void PacketRouter::addQueryStatusRequestPath (const Packet &packet, PacketSession *session)
00121 {
00122 const QUuid &serventId = packet.descriptorId();
00123 PacketPaths::iterator it = queryStatusRequestPaths.find (serventId);
00124
00125 if (it == queryStatusRequestPaths.end()) {
00126 it = queryStatusRequestPaths.insert (serventId, new PathSet);
00127 QTime expirationTime = QTime::currentTime().addSecs (DefaultQueryHitsExpiration);
00128 queryExpirations.push_back (new Expiration (serventId, expirationTime));
00129 }
00130 (*it)->insert (session);
00131 }
00132
00133 PacketRouter::Paths PacketRouter::queryHitsRoutePaths (const Packet &packet)
00134 {
00135 const QUuid &descriptorId = packet.descriptorId();
00136 PacketPaths::iterator it = queryPaths.find (descriptorId);
00137 if (it != queryPaths.end())
00138 return (*it)->values().toSet();
00139 else
00140 return Paths();
00141 }
00142
00143 PacketRouter::Paths PacketRouter::pushRoutePaths (const Push &push)
00144 {
00145 const QUuid &serventId = push.serventId();
00146 PacketPaths::iterator it = queryHitsPaths.find (serventId);
00147 if (it != queryHitsPaths.end())
00148 return (*it)->values().toSet();
00149 else
00150 return Paths();
00151 }
00152
00153 PacketRouter::Paths PacketRouter::queryStatusResponsePaths (const Packet &packet)
00154 {
00155 const QUuid &serventId = packet.descriptorId();
00156 PacketPaths::iterator it = queryStatusRequestPaths.find (serventId);
00157 if (it != queryStatusRequestPaths.end())
00158 return (*it)->values().toSet();
00159 else
00160 return Paths();
00161 }
00162
00163 void PacketRouter::clearExpiredPaths()
00164 {
00165 QTime currentTime = QTime::currentTime();
00166
00167 Expiration *expiration = 0;
00168 while (!queryExpirations.isEmpty()) {
00169 expiration = queryExpirations.front();
00170 if (expiration->second > currentTime)
00171 break;
00172
00173 queryExpirations.pop_front();
00174 PacketPaths::iterator it = queryPaths.find (expiration->first);
00175 if (it != queryPaths.end()) {
00176 delete (*it);
00177 queryPaths.remove (expiration->first);
00178 }
00179 delete expiration;
00180 }
00181
00182 while (!queryHitsExpirations.isEmpty()) {
00183 expiration = queryHitsExpirations.front();
00184 if (expiration->second > currentTime)
00185 break;
00186
00187 queryHitsExpirations.pop_front();
00188 PacketPaths::iterator it = queryHitsPaths.find (expiration->first);
00189 if (it != queryHitsPaths.end()) {
00190 delete (*it);
00191 queryHitsPaths.remove (expiration->first);
00192 }
00193 delete expiration;
00194 }
00195
00196 while (!queryStatusRequestExpirations.isEmpty()) {
00197 expiration = queryStatusRequestExpirations.front();
00198 if (expiration->second > currentTime)
00199 break;
00200
00201 queryStatusRequestExpirations.pop_front();
00202 PacketPaths::iterator it = queryStatusRequestPaths.find (expiration->first);
00203 if (it != queryStatusRequestPaths.end()) {
00204 delete (*it);
00205 queryStatusRequestPaths.remove (expiration->first);
00206 }
00207 delete expiration;
00208 }
00209 }