Packet.h

Go to the documentation of this file.
00001 /*
00002 
00003 Copyright (C) 2005-2007 by Peter Dimov.
00004 
00005 This file is part of Calitko (http://www.calitko.org).
00006 
00007 Calitko is free software; you can redistribute it and/or modify
00008 it under the terms of the GNU General Public License as published by
00009 the Free Software Foundation; either version 2 of the License, or
00010 (at your option) any later version.
00011 
00012 Calitko is distributed in the hope that it will be useful,
00013 but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 GNU General Public License for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with Calitko; if not, write to the Free Software
00019 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00020 
00021 */
00022 
00033 #ifndef PACKET_H
00034 #define PACKET_H
00035 
00036 #include "Extensions/Extension.h"
00037 
00038 // Open containing namespaces:
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     // Extension Decriptiors:
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); // \todo Move to Extension.h
00215 
00216 
00218 // inline functions
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     // Force payloadLength to be recalculated if required!
00240     // Necessary for filters!
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 // Close containing namespaces:
00267 } // namespace Packets
00268 } // namespace Gnutella
00270 
00271 #endif // PACKET_H