Packet.h
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
00033 #ifndef PACKET_H
00034 #define PACKET_H
00035
00036 #include "Extensions/Extension.h"
00037
00038
00039 namespace Gnutella {
00040 namespace Packets {
00042
00043 FORWARD_DECLARE (Testing, class ByeConcretePacket)
00044 FORWARD_DECLARE (Testing, class TestPacket)
00045
00046
00051 enum PayloadDescriptor
00052 {
00053 PingDescriptor = 0x00,
00054 PongDescriptor = 0x01,
00055 QueryDescriptor = 0x80,
00056 QueryHitsDescriptor = 0x81,
00057 PushDescriptor = 0x40,
00058
00059 ByeDescriptor = 0x02,
00060 IbmcDescriptor = 0x10,
00061 QueryRoutingDescriptor = 0x30,
00062 OpenVendorDescriptor = 0x31,
00063 StandardVendorDescriptor = 0x32
00064 };
00065
00067
00071 enum PacketConstants
00072 {
00073 DefaultHops = 0,
00074 DefaultTtl = 5,
00075 MaximalTtl = 7,
00076 HeaderLength = 23,
00077 MaximalPayloadLength = 0x00010000 - HeaderLength,
00078 MaximalQueryPayloadLength = 0x00001000 - HeaderLength,
00079 MaximalPacketLength = HeaderLength + MaximalPayloadLength
00080 };
00081
00083
00137 class Packet
00138 {
00139 public:
00140 virtual ~Packet();
00141 static Packet * fromRawData (const QByteArray &rawHeader, const QByteArray &rawPayload);
00142
00143 virtual QString name() const = 0;
00144
00145 inline const QUuid & descriptorId() const;
00146 inline PayloadDescriptor payloadDescriptor() const;
00147 inline uchar ttl() const;
00148 inline uchar hops() const;
00149 inline quint32 payloadLength() const;
00150 inline quint32 packetLength() const;
00151
00152 inline bool isValid() const;
00153 inline void doHop();
00154
00155 inline void setDescriptorId (const QUuid &descriptorId);
00156 inline void setTtl (uchar ttl);
00157 inline void setHops (uchar hops);
00158
00159 QByteArray rawHeader() const;
00160 QByteArray rawPayload() const;
00161
00162 virtual Packet* copy() const = 0;
00163
00164 protected:
00165 Packet (PayloadDescriptor payloadDescriptor);
00166 Packet (const QByteArray &rawHeader, const QByteArray &rawPayload);
00167 inline Packet (const Packet &other);
00168 Packet & operator= (const Packet &other);
00169
00170 inline void setIsValid (bool isValid);
00171 void invalidateHeader();
00172 virtual void invalidatePayload();
00173
00174 void parse();
00175 virtual bool prepareReadPayload (const QByteArray &rawPayload) = 0;
00176 virtual void readPayload (QDataStream &stream) = 0;
00177 virtual int prepareWritePayload() const = 0;
00178 virtual void writePayload (QDataStream &stream) const = 0;
00179
00180 private:
00181 bool prepareReadHeader (const QByteArray &rawHeader) const;
00182 void readHeader (QDataStream &stream);
00183 void writeHeader (QDataStream &stream) const;
00184
00186 struct Data
00187 {
00188 QBasicAtomic ref;
00189
00190 QUuid descriptorId;
00191 PayloadDescriptor payloadDescriptor;
00192 uchar ttl;
00193 uchar hops;
00194 mutable quint32 payloadLength;
00195
00196 bool isValid;
00197 mutable QByteArray rawHeader;
00198 mutable QByteArray rawPayload;
00199 mutable bool rewriteHeader;
00200 mutable bool rewritePayload;
00201 };
00202
00203 Data *d;
00204
00205 friend class Testing::ByeConcretePacket;
00206 friend class Testing::TestPacket;
00207 };
00208
00209 QDataStream & operator>> (QDataStream &in, PayloadDescriptor &pd);
00210 QDataStream & operator<< (QDataStream &out, const PayloadDescriptor &pd);
00211 QDataStream & operator>> (QDataStream &in, QHostAddress &ha);
00212 QDataStream & operator<< (QDataStream &out, const QHostAddress &ha);
00213 QDataStream & operator>> (QDataStream &in, Extensions::Extension &extension);
00214 QDataStream & operator<< (QDataStream &out, const Extensions::Extension &extension);
00215
00216
00218
00220
00221 inline Packet::Packet (const Packet &other)
00222 : d (other.d)
00223 { d->ref.ref(); }
00224
00225 inline const QUuid & Packet::descriptorId() const
00226 { return d->descriptorId; }
00227
00228 inline PayloadDescriptor Packet::payloadDescriptor() const
00229 { return d->payloadDescriptor; }
00230
00231 inline uchar Packet::ttl() const
00232 { return d->ttl; }
00233
00234 inline uchar Packet::hops() const
00235 { return d->hops; }
00236
00237 inline quint32 Packet::payloadLength() const
00238 {
00239
00240
00241 rawPayload();
00242 return d->payloadLength;
00243 }
00244
00245 inline quint32 Packet::packetLength() const
00246 { return HeaderLength + payloadLength(); }
00247
00248 inline bool Packet::isValid() const
00249 { return d->isValid; }
00250
00251 inline void Packet::doHop()
00252 { invalidateHeader(); d->ttl--; d->hops++; }
00253
00254 inline void Packet::setDescriptorId (const QUuid &descriptorId)
00255 { invalidateHeader(); d->descriptorId = descriptorId; }
00256
00257 inline void Packet::setTtl (uchar ttl)
00258 { invalidateHeader(); d->ttl = ttl; }
00259
00260 inline void Packet::setHops (uchar hops)
00261 { invalidateHeader(); d->hops = hops; }
00262
00263 inline void Packet::setIsValid (bool isValid)
00264 { d->isValid = isValid; }
00265
00266
00267 }
00268 }
00270
00271 #endif // PACKET_H