1 // distribution boxbackup-0.11_trunk_2979 (svn version: 2979) 2 // Box Backup, http://www.boxbackup.org/ 3 // 4 // Copyright (c) 2003-2010, Ben Summers and contributors. 5 // All rights reserved. 6 // 7 // Note that this project uses mixed licensing. Any file with this license 8 // attached, or where the code LICENSE-DUAL appears on the first line, falls 9 // under this license. See the file COPYING.txt for more information. 10 // 11 // This file is dual licensed. You may use and distribute it providing that you 12 // comply EITHER with the terms of the BSD license, OR the GPL license. It is 13 // not necessary to comply with both licenses, only one. 14 // 15 // The BSD license option follows: 16 // 17 // Redistribution and use in source and binary forms, with or without 18 // modification, are permitted provided that the following conditions are met: 19 // 20 // 1. Redistributions of source code must retain the above copyright 21 // notice, this list of conditions and the following disclaimer. 22 // 23 // 2. Redistributions in binary form must reproduce the above copyright 24 // notice, this list of conditions and the following disclaimer in the 25 // documentation and/or other materials provided with the distribution. 26 // 27 // 3. Neither the name of the Box Backup nor the names of its contributors may 28 // be used to endorse or promote products derived from this software without 29 // specific prior written permission. 30 // 31 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 32 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 33 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 34 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY 35 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 36 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 37 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 38 // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 39 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 40 // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 41 // 42 // [http://en.wikipedia.org/wiki/BSD_licenses#3-clause_license_.28.22New_BSD_License.22.29] 43 // 44 // The GPL license option follows: 45 // 46 // This program is free software; you can redistribute it and/or 47 // modify it under the terms of the GNU General Public License 48 // as published by the Free Software Foundation; either version 2 49 // of the License, or (at your option) any later version. 50 // 51 // This program is distributed in the hope that it will be useful, 52 // but WITHOUT ANY WARRANTY; without even the implied warranty of 53 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 54 // GNU General Public License for more details. 55 // 56 // You should have received a copy of the GNU General Public License 57 // along with this program; if not, write to the Free Software 58 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 59 // 60 // [http://www.gnu.org/licenses/old-licenses/gpl-2.0.html#SEC4] 61 // -------------------------------------------------------------------------- 62 // 63 // File 64 // Name: Protocol.h 65 // Purpose: Generic protocol support 66 // Created: 2003/08/19 67 // 68 // -------------------------------------------------------------------------- 69 70 #ifndef PROTOCOL__H 71 #define PROTOCOL__H 72 73 #include <sys/types.h> 74 75 class IOStream; 76 #include "ProtocolObject.h" 77 #include <memory> 78 #include <vector> 79 #include <string> 80 81 // default timeout is 15 minutes 82 #define PROTOCOL_DEFAULT_TIMEOUT (15*60*1000) 83 // 16 default maximum object size -- should be enough 84 #define PROTOCOL_DEFAULT_MAXOBJSIZE (16*1024) 85 86 // -------------------------------------------------------------------------- 87 // 88 // Class 89 // Name: Protocol 90 // Purpose: Generic command / response protocol support 91 // Created: 2003/08/19 92 // 93 // -------------------------------------------------------------------------- 94 class Protocol 95 { 96 public: 97 Protocol(IOStream &rStream); 98 virtual ~Protocol(); 99 100 private: 101 Protocol(const Protocol &rToCopy); 102 103 public: 104 void Handshake(); 105 std::auto_ptr<ProtocolObject> Receive(); 106 void Send(const ProtocolObject &rObject); 107 108 std::auto_ptr<IOStream> ReceiveStream(); 109 void SendStream(IOStream &rStream); 110 111 enum 112 { 113 NoError = -1, 114 UnknownError = 0 115 }; 116 117 bool GetLastError(int &rTypeOut, int &rSubTypeOut); 118 119 // -------------------------------------------------------------------------- 120 // 121 // Function 122 // Name: Protocol::SetTimeout(int) 123 // Purpose: Sets the timeout for sending and reciving 124 // Created: 2003/08/19 125 // 126 // -------------------------------------------------------------------------- SetTimeout(int NewTimeout)127 void SetTimeout(int NewTimeout) {mTimeout = NewTimeout;} 128 129 130 // -------------------------------------------------------------------------- 131 // 132 // Function 133 // Name: Protocol::GetTimeout() 134 // Purpose: Get current timeout for sending and receiving 135 // Created: 2003/09/06 136 // 137 // -------------------------------------------------------------------------- GetTimeout()138 int GetTimeout() {return mTimeout;} 139 140 // -------------------------------------------------------------------------- 141 // 142 // Function 143 // Name: Protocol::SetMaxObjectSize(int) 144 // Purpose: Sets the maximum size of an object which will be accepted 145 // Created: 2003/08/19 146 // 147 // -------------------------------------------------------------------------- SetMaxObjectSize(unsigned int NewMaxObjSize)148 void SetMaxObjectSize(unsigned int NewMaxObjSize) {mMaxObjectSize = NewMaxObjSize;} 149 150 // For ProtocolObject derived classes 151 void Read(void *Buffer, int Size); 152 void Read(std::string &rOut, int Size); 153 void Read(int64_t &rOut); 154 void Read(int32_t &rOut); 155 void Read(int16_t &rOut); 156 void Read(int8_t &rOut); Read(bool & rOut)157 void Read(bool &rOut) {int8_t read; Read(read); rOut = (read == true);} 158 void Read(std::string &rOut); 159 template<typename type> Read(type & rOut)160 void Read(type &rOut) 161 { 162 rOut.ReadFromProtocol(*this); 163 } 164 // -------------------------------------------------------------------------- 165 // 166 // Function 167 // Name: Protocol::ReadVector(std::vector<> &) 168 // Purpose: Reads a vector/list of items from the stream 169 // Created: 2003/08/19 170 // 171 // -------------------------------------------------------------------------- 172 template<typename type> ReadVector(std::vector<type> & rOut)173 void ReadVector(std::vector<type> &rOut) 174 { 175 rOut.clear(); 176 int16_t num = 0; 177 Read(num); 178 for(int16_t n = 0; n < num; ++n) 179 { 180 type v; 181 Read(v); 182 rOut.push_back(v); 183 } 184 } 185 186 void Write(const void *Buffer, int Size); 187 void Write(int64_t Value); 188 void Write(int32_t Value); 189 void Write(int16_t Value); 190 void Write(int8_t Value); Write(bool Value)191 void Write(bool Value) {int8_t write = Value; Write(write);} 192 void Write(const std::string &rValue); 193 template<typename type> Write(const type & rValue)194 void Write(const type &rValue) 195 { 196 rValue.WriteToProtocol(*this); 197 } 198 template<typename type> 199 // -------------------------------------------------------------------------- 200 // 201 // Function 202 // Name: Protocol::WriteVector(const std::vector<> &) 203 // Purpose: Writes a vector/list of items from the stream 204 // Created: 2003/08/19 205 // 206 // -------------------------------------------------------------------------- WriteVector(const std::vector<type> & rValue)207 void WriteVector(const std::vector<type> &rValue) 208 { 209 int16_t num = rValue.size(); 210 Write(num); 211 for(int16_t n = 0; n < num; ++n) 212 { 213 Write(rValue[n]); 214 } 215 } 216 217 public: 218 static const uint16_t sProtocolStreamHeaderLengths[256]; 219 enum 220 { 221 ProtocolStreamHeader_EndOfStream = 0, 222 ProtocolStreamHeader_MaxEncodedSizeValue = 252, 223 ProtocolStreamHeader_SizeIs64k = 253, 224 ProtocolStreamHeader_Reserved1 = 254, 225 ProtocolStreamHeader_Reserved2 = 255 226 }; 227 enum 228 { 229 ProtocolStream_SizeUncertain = 0xffffffff 230 }; 231 232 protected: 233 virtual std::auto_ptr<ProtocolObject> MakeProtocolObject(int ObjType) = 0; 234 virtual const char *GetIdentString() = 0; SetError(int Type,int SubType)235 void SetError(int Type, int SubType) {mLastErrorType = Type; mLastErrorSubType = SubType;} 236 void CheckAndReadHdr(void *hdr); // don't use type here to avoid dependency 237 238 // Will be used for logging 239 virtual void InformStreamReceiving(u_int32_t Size); 240 virtual void InformStreamSending(u_int32_t Size); 241 242 private: 243 void EnsureBufferAllocated(int Size); 244 int SendStreamSendBlock(uint8_t *Block, int BytesInBlock); 245 246 private: 247 IOStream &mrStream; 248 bool mHandshakeDone; 249 unsigned int mMaxObjectSize; 250 int mTimeout; 251 char *mpBuffer; 252 int mBufferSize; 253 int mReadOffset; 254 int mWriteOffset; 255 int mValidDataSize; 256 int mLastErrorType; 257 int mLastErrorSubType; 258 }; 259 260 #endif // PROTOCOL__H 261 262