added header to syncOnConnect
[anytun.git] / src / buffer.cpp
blob23228eb96d477a4bf78122b92530915bf93acd7d
1 /*
2 * anytun
4 * The secure anycast tunneling protocol (satp) defines a protocol used
5 * for communication between any combination of unicast and anycast
6 * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel
7 * mode and allows tunneling of every ETHER TYPE protocol (e.g.
8 * ethernet, ip, arp ...). satp directly includes cryptography and
9 * message authentication based on the methodes used by SRTP. It is
10 * intended to deliver a generic, scaleable and secure solution for
11 * tunneling and relaying of packets of any protocol.
14 * Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl,
15 * Christian Pointner <satp@wirdorange.org>
17 * This file is part of Anytun.
19 * Anytun is free software: you can redistribute it and/or modify
20 * it under the terms of the GNU General Public License version 3 as
21 * published by the Free Software Foundation.
23 * Anytun is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
28 * You should have received a copy of the GNU General Public License
29 * along with anytun. If not, see <http://www.gnu.org/licenses/>.
32 #include <cstring>
33 #include <stdexcept>
34 #include <string>
35 #include <sstream>
36 #include <iostream>
37 #include <boost/archive/text_oarchive.hpp>
38 #include <boost/archive/text_iarchive.hpp>
39 #include "datatypes.h"
40 #include "buffer.h"
42 Buffer::Buffer(bool allow_realloc) : buf_(0), length_(0), real_length_(0), allow_realloc_(allow_realloc)
46 Buffer::Buffer(u_int32_t length, bool allow_realloc) : length_(length), real_length_(length_ + Buffer::OVER_SIZE_),
47 allow_realloc_(allow_realloc)
49 buf_ = new u_int8_t[real_length_];
50 if(!buf_) {
51 length_ = 0;
52 real_length_ = 0;
53 throw std::bad_alloc();
55 std::memset(buf_, 0, real_length_);
58 Buffer::Buffer(u_int8_t* data, u_int32_t length, bool allow_realloc) : length_(length), real_length_(length + Buffer::OVER_SIZE_),
59 allow_realloc_(allow_realloc)
61 if(!data) {
62 length_ = 0;
63 real_length_ = 0;
64 return;
67 buf_ = new u_int8_t[real_length_];
68 if(!buf_) {
69 length_ = 0;
70 real_length_ = 0;
71 throw std::bad_alloc();
73 std::memcpy(buf_, data, length_);
76 Buffer::Buffer(std::string hex_data, bool allow_realloc) : length_(hex_data.size()/2),
77 real_length_(length_ + Buffer::OVER_SIZE_),
78 allow_realloc_(allow_realloc)
80 buf_ = new u_int8_t[real_length_];
81 if(!buf_) {
82 length_ = 0;
83 real_length_ = 0;
84 throw std::bad_alloc();
87 for(u_int32_t i=0; i<length_; ++i)
89 u_int32_t tmp;
90 std::istringstream ss(std::string(hex_data.c_str(), i*2, 2));
91 if(!(ss >> std::hex >> tmp)) tmp = 0;
92 buf_[i] = tmp;
96 Buffer::~Buffer()
98 if(buf_)
99 delete[] buf_;
102 Buffer::Buffer(const Buffer &src) : length_(src.length_), real_length_(src.real_length_), allow_realloc_(src.allow_realloc_)
104 buf_ = new u_int8_t[real_length_];
105 if(!buf_) {
106 length_ = 0;
107 real_length_ = 0;
108 throw std::bad_alloc();
110 std::memcpy(buf_, src.buf_, length_);
113 void Buffer::operator=(const Buffer &src)
115 if(buf_)
116 delete[] buf_;
118 length_ = src.length_;
119 real_length_ = src.real_length_;
120 allow_realloc_ = src.allow_realloc_;
122 buf_ = new u_int8_t[real_length_];
123 if(!buf_) {
124 length_ = 0;
125 real_length_ = 0;
126 throw std::bad_alloc();
128 std::memcpy(buf_, src.buf_, length_);
133 bool Buffer::operator==(const Buffer &cmp) const
135 if(length_ != cmp.length_)
136 return false;
138 if(!std::memcmp(buf_, cmp.buf_, length_))
139 return true;
141 return false;
144 Buffer Buffer::operator^(const Buffer &xor_by) const
146 u_int32_t res_length = (xor_by.length_ > length_) ? xor_by.length_ : length_;
147 u_int32_t min_length = (xor_by.length_ < length_) ? xor_by.length_ : length_;
148 Buffer res(res_length);
150 for( u_int32_t index = 0; index < min_length; index++ )
151 res[index] = buf_[index] ^ xor_by[index];
153 return res;
156 u_int32_t Buffer::getLength() const
158 return length_;
161 void Buffer::setLength(u_int32_t new_length)
163 if(new_length == length_)
164 return;
166 if(new_length > real_length_)
168 if(!allow_realloc_)
169 throw std::out_of_range("buffer::setLength() - reallocation not allowed for this Buffer");
171 u_int8_t* old_buf = buf_;
172 u_int32_t old_length = length_;
174 length_ = new_length;
175 real_length_ = length_ + Buffer::OVER_SIZE_;
177 buf_ = new u_int8_t[real_length_];
178 if(!buf_) {
179 length_ = 0;
180 real_length_ = 0;
181 if(old_buf)
182 delete[] old_buf;
184 throw std::bad_alloc();
186 std::memcpy(buf_, old_buf, old_length);
188 if(old_buf)
189 delete[] old_buf;
191 old_buf = &buf_[old_length];
192 std::memset(old_buf, 0, real_length_ - old_length);
194 else
195 length_ = new_length;
197 reinit();
201 u_int8_t* Buffer::getBuf()
203 return buf_;
206 u_int8_t& Buffer::operator[](u_int32_t index)
208 if(index >= length_)
209 throw std::out_of_range("buffer::operator[]");
211 return buf_[index];
214 u_int8_t Buffer::operator[](u_int32_t index) const
216 if(index >= length_)
217 throw std::out_of_range("buffer::operator[] const");
219 return buf_[index];
222 Buffer::operator u_int8_t*()
224 return buf_;
227 std::string Buffer::getHexDump() const
229 std::stringstream ss;
230 ss << "Length=" << length_ << std::endl << std::hex << std::uppercase;
231 for( u_int32_t index = 0; index < length_; index++ )
233 ss << std::setw(2) << std::setfill('0') << u_int32_t(buf_[index]) << " ";
234 if(!((index+1) % 16)) {
235 ss << std::endl;
236 continue;
238 if(!((index+1) % 8))
239 ss << " ";
241 return ss.str();
244 std::string Buffer::getHexDumpOneLine() const
246 std::stringstream ss;
247 ss << length_ << " Bytes,'" << std::hex << std::uppercase;
248 for( u_int32_t index = 0; index < length_; index++ )
250 ss << std::setw(2) << std::setfill('0') << u_int32_t(buf_[index]);
252 ss << "'";
253 return ss.str();
256 bool Buffer::isReallocAllowed() const
258 return allow_realloc_;