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