mirror of
https://github.com/OpenVPN/openvpn3.git
synced 2024-09-19 19:52:15 +02:00
Added reltest.cpp for testing ReliableRecv and ReliableSend
objects by simulating an unreliable packet stream. Modified packet_id code so that current time (now) is passed via function calls rather than accessed as a global. Added integer random number support via boost::random.
This commit is contained in:
parent
52c42fb5d2
commit
f09b9ae12a
27
openvpn/common/boostrand.hpp
Normal file
27
openvpn/common/boostrand.hpp
Normal file
@ -0,0 +1,27 @@
|
||||
#ifndef OPENVPN_COMMON_BOOSTRAND_H
|
||||
#define OPENVPN_COMMON_BOOSTRAND_H
|
||||
|
||||
#include <boost/random.hpp>
|
||||
|
||||
namespace openvpn {
|
||||
|
||||
class RandomIntBase
|
||||
{
|
||||
public:
|
||||
typedef unsigned int type;
|
||||
|
||||
RandomIntBase(type seed) : rng_(seed) {}
|
||||
RandomIntBase() {} // deterministic sequence
|
||||
|
||||
type randrange(const type end)
|
||||
{
|
||||
return rng_() % end;
|
||||
}
|
||||
|
||||
private:
|
||||
boost::mt19937 rng_;
|
||||
};
|
||||
|
||||
} // namespace openvpn
|
||||
|
||||
#endif // OPENVPN_COMMON_BOOSTRAND_H
|
@ -20,6 +20,9 @@ namespace openvpn {
|
||||
OPENVPN_SIMPLE_EXCEPTION(message_window_ref_by_id);
|
||||
OPENVPN_SIMPLE_EXCEPTION(message_window_rm_head);
|
||||
|
||||
MessageWindow()
|
||||
: head_id_(0), span_(0) {}
|
||||
|
||||
MessageWindow(const id_t starting_head_id, const id_t span)
|
||||
: head_id_(starting_head_id), span_(span) {}
|
||||
|
||||
@ -81,6 +84,9 @@ namespace openvpn {
|
||||
// would have (even if it isn't defined yet).
|
||||
id_t head_id() const { return head_id_; }
|
||||
|
||||
// Return the id of one past the end of the window
|
||||
id_t tail_id() const { return head_id_ + span_; }
|
||||
|
||||
// Return the window size
|
||||
id_t span() const { return span_; }
|
||||
|
||||
@ -111,7 +117,7 @@ namespace openvpn {
|
||||
// to an object in the queue
|
||||
void grow(const id_t id)
|
||||
{
|
||||
const size_t needed_index = head_id_ + id;
|
||||
const size_t needed_index = id - head_id_;
|
||||
while (q_.size() <= needed_index)
|
||||
q_.push_back(M());
|
||||
}
|
||||
@ -120,7 +126,7 @@ namespace openvpn {
|
||||
// the queue, advancing the head_id_
|
||||
void purge()
|
||||
{
|
||||
while (!q_.empty() && !q_.front().defined())
|
||||
while (!q_.empty() && q_.front().erased())
|
||||
{
|
||||
q_.pop_front();
|
||||
++head_id_;
|
||||
|
@ -21,7 +21,7 @@ namespace openvpn {
|
||||
OPENVPN_SIMPLE_EXCEPTION(decrypt_hmac_verify_failed);
|
||||
OPENVPN_SIMPLE_EXCEPTION(decrypt_packet_id_verify_failed);
|
||||
|
||||
void decrypt(BufferAllocated& buf)
|
||||
void decrypt(BufferAllocated& buf, const PacketID::time_t now)
|
||||
{
|
||||
// verify the HMAC
|
||||
if (hmac.defined())
|
||||
@ -54,7 +54,7 @@ namespace openvpn {
|
||||
const int cipher_mode = cipher.cipher_mode();
|
||||
if (cipher_mode == CipherContext::CIPH_CBC_MODE)
|
||||
{
|
||||
verify_packet_id(work);
|
||||
verify_packet_id(work, now);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -63,7 +63,7 @@ namespace openvpn {
|
||||
}
|
||||
else // no encryption
|
||||
{
|
||||
verify_packet_id(buf);
|
||||
verify_packet_id(buf, now);
|
||||
}
|
||||
|
||||
// return cleartext result in buf
|
||||
@ -76,14 +76,14 @@ namespace openvpn {
|
||||
PacketIDReceive pid_recv;
|
||||
|
||||
private:
|
||||
void verify_packet_id(BufferAllocated& buf)
|
||||
void verify_packet_id(BufferAllocated& buf, const PacketID::time_t now)
|
||||
{
|
||||
// ignore packet ID if pid_recv is not initialized
|
||||
if (pid_recv.initialized())
|
||||
{
|
||||
const PacketID pid = pid_recv.read_next(buf);
|
||||
if (pid_recv.test(pid)) // verify packet ID
|
||||
pid_recv.add(pid); // remember packet ID
|
||||
if (pid_recv.test(pid, now)) // verify packet ID
|
||||
pid_recv.add(pid, now); // remember packet ID
|
||||
else
|
||||
throw decrypt_packet_id_verify_failed();
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ namespace openvpn {
|
||||
public:
|
||||
OPENVPN_SIMPLE_EXCEPTION(unsupported_cipher_mode);
|
||||
|
||||
void encrypt(BufferAllocated& buf)
|
||||
void encrypt(BufferAllocated& buf, const PacketID::time_t now)
|
||||
{
|
||||
if (cipher.defined())
|
||||
{
|
||||
@ -34,7 +34,7 @@ namespace openvpn {
|
||||
prng.bytes(iv_buf, iv_size);
|
||||
|
||||
// generate fresh outgoing packet ID and prepend to cleartext buffer
|
||||
pid_send.write_next(buf, true);
|
||||
pid_send.write_next(buf, true, now);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -57,7 +57,7 @@ namespace openvpn {
|
||||
else // no encryption
|
||||
{
|
||||
// generate fresh outgoing packet ID and prepend to cleartext buffer
|
||||
pid_send.write_next(buf, true);
|
||||
pid_send.write_next(buf, true, now);
|
||||
|
||||
// HMAC the cleartext
|
||||
prepend_hmac(work);
|
||||
|
@ -11,7 +11,7 @@
|
||||
#include <openvpn/common/exception.hpp>
|
||||
#include <openvpn/common/log.hpp>
|
||||
#include <openvpn/common/circ_list.hpp>
|
||||
#include <openvpn/time/now.hpp>
|
||||
#include <openvpn/time/time.hpp>
|
||||
#include <openvpn/buffer/buffer.hpp>
|
||||
|
||||
namespace openvpn {
|
||||
@ -130,7 +130,7 @@ namespace openvpn {
|
||||
form_ = form;
|
||||
}
|
||||
|
||||
PacketID next()
|
||||
PacketID next(const PacketID::time_t now)
|
||||
{
|
||||
PacketID ret;
|
||||
if (!pid_.time)
|
||||
@ -147,9 +147,9 @@ namespace openvpn {
|
||||
return ret;
|
||||
}
|
||||
|
||||
void write_next(Buffer& buf, const bool prepend)
|
||||
void write_next(Buffer& buf, const bool prepend, const PacketID::time_t now)
|
||||
{
|
||||
const PacketID pid = next();
|
||||
const PacketID pid = next(now);
|
||||
pid.write(buf, form_, prepend);
|
||||
}
|
||||
|
||||
@ -292,7 +292,7 @@ namespace openvpn {
|
||||
* Return true if packet id is ok, or false if
|
||||
* it's a replay.
|
||||
*/
|
||||
bool test(const PacketID& pin)
|
||||
bool test(const PacketID& pin, const PacketID::time_t now)
|
||||
{
|
||||
// make sure we were initialized
|
||||
if (!initialized_)
|
||||
@ -300,12 +300,12 @@ namespace openvpn {
|
||||
|
||||
// see if we should do an expiration reap pass
|
||||
if (last_reap_ + SEQ_REAP_PERIOD <= now)
|
||||
reap();
|
||||
reap(now);
|
||||
|
||||
// packet ID==0 is invalid
|
||||
if (!pin.id)
|
||||
{
|
||||
debug_log (DEBUG_LOW, pin, "ID is 0", 0);
|
||||
debug_log (DEBUG_LOW, pin, "ID is 0", 0, now);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -330,12 +330,12 @@ namespace openvpn {
|
||||
if (diff > max_backtrack_stat_)
|
||||
{
|
||||
max_backtrack_stat_ = diff;
|
||||
debug_log (DEBUG_LOW, pin, "UDP replay-window backtrack occurred", max_backtrack_stat_);
|
||||
debug_log (DEBUG_LOW, pin, "UDP replay-window backtrack occurred", max_backtrack_stat_, now);
|
||||
}
|
||||
|
||||
if (diff >= seq_list_.size())
|
||||
{
|
||||
debug_log (DEBUG_LOW, pin, "UDP large diff", diff);
|
||||
debug_log (DEBUG_LOW, pin, "UDP large diff", diff, now);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -346,14 +346,14 @@ namespace openvpn {
|
||||
else
|
||||
{
|
||||
/* raised from DEBUG_LOW to reduce verbosity */
|
||||
debug_log (DEBUG_MEDIUM, pin, "UDP replay", diff);
|
||||
debug_log (DEBUG_MEDIUM, pin, "UDP replay", diff, now);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (pin.time < time_) /* if time goes back, reject */
|
||||
{
|
||||
debug_log (DEBUG_LOW, pin, "UDP time backtrack", 0);
|
||||
debug_log (DEBUG_LOW, pin, "UDP time backtrack", 0, now);
|
||||
return false;
|
||||
}
|
||||
else /* time moved forward */
|
||||
@ -373,13 +373,13 @@ namespace openvpn {
|
||||
return true;
|
||||
else
|
||||
{
|
||||
debug_log (DEBUG_MEDIUM, pin, "TCP packet ID out of sequence", 0);
|
||||
debug_log (DEBUG_MEDIUM, pin, "TCP packet ID out of sequence", 0, now);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (pin.time < time_) /* if time goes back, reject */
|
||||
{
|
||||
debug_log (DEBUG_LOW, pin, "TCP time backtrack", 0);
|
||||
debug_log (DEBUG_LOW, pin, "TCP time backtrack", 0, now);
|
||||
return false;
|
||||
}
|
||||
else /* time moved forward */
|
||||
@ -388,7 +388,7 @@ namespace openvpn {
|
||||
return true;
|
||||
else
|
||||
{
|
||||
debug_log (DEBUG_LOW, pin, "bad initial TCP packet ID", pin.id);
|
||||
debug_log (DEBUG_LOW, pin, "bad initial TCP packet ID", pin.id, now);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -396,7 +396,7 @@ namespace openvpn {
|
||||
}
|
||||
|
||||
void
|
||||
add(const PacketID& pin)
|
||||
add(const PacketID& pin, const PacketID::time_t now)
|
||||
{
|
||||
if (!initialized_)
|
||||
throw packet_id_not_initialized();
|
||||
@ -423,10 +423,9 @@ namespace openvpn {
|
||||
|
||||
// remember timestamp of packet ID
|
||||
{
|
||||
const PacketID::time_t local_now = now;
|
||||
const size_t diff = id_ - pin.id;
|
||||
if (diff < seq_list_.size() && local_now > PacketID::time_t(SEQ_EXPIRED))
|
||||
seq_list_[diff] = local_now;
|
||||
if (diff < seq_list_.size() && now > PacketID::time_t(SEQ_EXPIRED))
|
||||
seq_list_[diff] = now;
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -447,12 +446,11 @@ namespace openvpn {
|
||||
}
|
||||
|
||||
#ifdef PACKET_ID_EXTRA_LOG_INFO
|
||||
std::string str() const
|
||||
std::string str(const PacketID::time_t now) const
|
||||
{
|
||||
if (!initialized_)
|
||||
throw packet_id_not_initialized();
|
||||
std::ostringstream os;
|
||||
const PacketID::time_t local_now = now;
|
||||
os << name_ << "-" << unit_ << " [";
|
||||
for (size_t i = 0; i < seq_list_.size(); ++i)
|
||||
{
|
||||
@ -464,7 +462,7 @@ namespace openvpn {
|
||||
c = 'E';
|
||||
else
|
||||
{
|
||||
const int diff = int(local_now - v);
|
||||
const int diff = int(now - v);
|
||||
if (diff < 0)
|
||||
c = 'N';
|
||||
else if (diff < 10)
|
||||
@ -485,9 +483,8 @@ namespace openvpn {
|
||||
* be accepted because they would violate
|
||||
* time_backtrack.
|
||||
*/
|
||||
void reap()
|
||||
void reap(const PacketID::time_t now)
|
||||
{
|
||||
const PacketID::time_t local_now = now;
|
||||
if (time_backtrack_)
|
||||
{
|
||||
bool expire = false;
|
||||
@ -496,25 +493,25 @@ namespace openvpn {
|
||||
const PacketID::time_t t = seq_list_[i];
|
||||
if (t == PacketID::time_t(SEQ_EXPIRED)) // fast path -- once we see SEQ_EXPIRED from previous run, we can stop
|
||||
break;
|
||||
if (!expire && t && t + time_backtrack_ < local_now)
|
||||
if (!expire && t && t + time_backtrack_ < now)
|
||||
expire = true;
|
||||
if (expire)
|
||||
seq_list_[i] = PacketID::time_t(SEQ_EXPIRED);
|
||||
}
|
||||
}
|
||||
last_reap_ = local_now;
|
||||
last_reap_ = now;
|
||||
}
|
||||
|
||||
void debug_log (const int level, const PacketID& pin, const char *description, const PacketID::id_t info) const
|
||||
void debug_log (const int level, const PacketID& pin, const char *description, const PacketID::id_t info, const PacketID::time_t now) const
|
||||
{
|
||||
if (debug_level_ >= level)
|
||||
do_log(pin, description, info);
|
||||
do_log(pin, description, info, now);
|
||||
}
|
||||
|
||||
void do_log (const PacketID& pin, const char *description, const PacketID::id_t info) const
|
||||
void do_log (const PacketID& pin, const char *description, const PacketID::id_t info, const PacketID::time_t now) const
|
||||
{
|
||||
#ifdef PACKET_ID_EXTRA_LOG_INFO
|
||||
OPENVPN_LOG("PACKET_ID: '" << description << "' pin=[" << pin.id << "," << pin.time << "] info=" << info << " state=" << str());
|
||||
OPENVPN_LOG("PACKET_ID: '" << description << "' pin=[" << pin.id << "," << pin.time << "] info=" << info << " state=" << str(now));
|
||||
#else
|
||||
OPENVPN_LOG("PACKET_ID: '" << description << "' pin=[" << pin.id << "," << pin.time << "] info=" << info << " state=" << name_ << "-" << unit_);
|
||||
#endif
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include <openssl/rand.h>
|
||||
|
||||
#include <openvpn/common/exception.hpp>
|
||||
#include <openvpn/common/boostrand.hpp>
|
||||
|
||||
namespace openvpn {
|
||||
OPENVPN_SIMPLE_EXCEPTION(rand_error);
|
||||
@ -14,6 +15,20 @@ namespace openvpn {
|
||||
throw rand_error();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline T rand_type()
|
||||
{
|
||||
T ret;
|
||||
rand_bytes((unsigned char *)&ret, sizeof(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
class RandomInt : public RandomIntBase
|
||||
{
|
||||
public:
|
||||
RandomInt() : RandomIntBase(rand_type<unsigned int>()) {}
|
||||
};
|
||||
|
||||
} // namespace openvpn
|
||||
|
||||
#endif // OPENVPN_OPENSSL_RAND_H
|
||||
|
36
openvpn/reliable/relcommon.hpp
Normal file
36
openvpn/reliable/relcommon.hpp
Normal file
@ -0,0 +1,36 @@
|
||||
#ifndef OPENVPN_RELIABLE_RELCOMMON_H
|
||||
#define OPENVPN_RELIABLE_RELCOMMON_H
|
||||
|
||||
#include <openvpn/buffer/buffer.hpp>
|
||||
#include <openvpn/crypto/packet_id.hpp>
|
||||
|
||||
namespace openvpn {
|
||||
|
||||
class ReliableMessageBase
|
||||
{
|
||||
public:
|
||||
typedef PacketID::id_t id_t;
|
||||
|
||||
ReliableMessageBase() : id_(0), erased_(false) {}
|
||||
bool defined() const { return bool(buffer); }
|
||||
bool erased() const { return erased_; }
|
||||
|
||||
void erase()
|
||||
{
|
||||
id_ = id_t(0);
|
||||
buffer.reset();
|
||||
erased_ = true;
|
||||
}
|
||||
|
||||
id_t id() const { return id_; }
|
||||
|
||||
BufferPtr buffer;
|
||||
|
||||
protected:
|
||||
id_t id_;
|
||||
bool erased_;
|
||||
};
|
||||
|
||||
} // namespace openvpn
|
||||
|
||||
#endif // OPENVPN_RELIABLE_RELCOMMON_H
|
@ -5,62 +5,65 @@
|
||||
#include <openvpn/common/exception.hpp>
|
||||
#include <openvpn/common/msgwin.hpp>
|
||||
#include <openvpn/buffer/buffer.hpp>
|
||||
#include <openvpn/crypto/packet_id.hpp>
|
||||
#include <openvpn/reliable/relcommon.hpp>
|
||||
|
||||
namespace openvpn {
|
||||
|
||||
class ReliableRecv
|
||||
{
|
||||
public:
|
||||
typedef PacketID::id_t id_t;
|
||||
OPENVPN_SIMPLE_EXCEPTION(rel_next_sequenced_not_ready);
|
||||
|
||||
OPENVPN_SIMPLE_EXCEPTION(next_sequenced_not_ready);
|
||||
typedef ReliableMessageBase::id_t id_t;
|
||||
|
||||
struct Message
|
||||
class Message : public ReliableMessageBase
|
||||
{
|
||||
public:
|
||||
Message() : id(0) {}
|
||||
bool defined() const { return bool(buffer); }
|
||||
void erase() { buffer.reset(); }
|
||||
|
||||
id_t id;
|
||||
BufferPtr buffer;
|
||||
friend class ReliableRecv;
|
||||
};
|
||||
|
||||
ReliableRecv() {}
|
||||
ReliableRecv(const id_t span) { init(span); }
|
||||
|
||||
void init(const id_t span)
|
||||
{
|
||||
window_.init(1, span);
|
||||
}
|
||||
|
||||
// Call with unsequenced packet off of the wire.
|
||||
// Will return true if ACK for this packet ID
|
||||
// should be returned to sender.
|
||||
bool receive(BufferPtr& buffer, const id_t id)
|
||||
{
|
||||
if (window.in_window(id))
|
||||
if (window_.in_window(id))
|
||||
{
|
||||
Message& m = window.ref_by_id(id);
|
||||
m.id = id;
|
||||
Message& m = window_.ref_by_id(id);
|
||||
m.id_ = id;
|
||||
m.buffer = buffer;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return window.pre_window(id);
|
||||
return window_.pre_window(id);
|
||||
}
|
||||
|
||||
// Return true if next_sequenced() is ready to return next buffer
|
||||
bool ready() const { return window.head_defined(); }
|
||||
bool ready() const { return window_.head_defined(); }
|
||||
|
||||
// Return next buffer in sequence. Requires that ready() returns true.
|
||||
Message next_sequenced()
|
||||
// Return next buffer in sequence.
|
||||
// Requires that ready() returns true.
|
||||
Message& next_sequenced()
|
||||
{
|
||||
if (ready())
|
||||
{
|
||||
Message ret = window.ref_head();
|
||||
window.rm_head_nocheck();
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
throw next_sequenced_not_ready();
|
||||
return window_.ref_head();
|
||||
}
|
||||
|
||||
// Call after buffer returned by receive is ready to
|
||||
// be disposed of.
|
||||
void advance()
|
||||
{
|
||||
window_.rm_head_nocheck();
|
||||
}
|
||||
|
||||
private:
|
||||
MessageWindow<Message, id_t> window;
|
||||
MessageWindow<Message, id_t> window_;
|
||||
};
|
||||
|
||||
} // namespace openvpn
|
||||
|
116
openvpn/reliable/relsend.hpp
Normal file
116
openvpn/reliable/relsend.hpp
Normal file
@ -0,0 +1,116 @@
|
||||
#ifndef OPENVPN_RELIABLE_RELSEND_H
|
||||
#define OPENVPN_RELIABLE_RELSEND_H
|
||||
|
||||
#include <openvpn/common/types.hpp>
|
||||
#include <openvpn/common/exception.hpp>
|
||||
#include <openvpn/common/msgwin.hpp>
|
||||
#include <openvpn/time/time.hpp>
|
||||
#include <openvpn/buffer/buffer.hpp>
|
||||
#include <openvpn/reliable/relcommon.hpp>
|
||||
|
||||
namespace openvpn {
|
||||
|
||||
class ReliableSend
|
||||
{
|
||||
public:
|
||||
typedef ReliableMessageBase::id_t id_t;
|
||||
|
||||
enum {
|
||||
RETRANSMIT = 2 // retransmit in N seconds if ACK not received
|
||||
};
|
||||
|
||||
class Message : public ReliableMessageBase
|
||||
{
|
||||
friend class ReliableSend;
|
||||
|
||||
public:
|
||||
bool ready_retransmit(const Time now) const
|
||||
{
|
||||
return defined() && now >= retransmit_at_;
|
||||
}
|
||||
|
||||
Time::Duration until_retransmit(const Time now) const
|
||||
{
|
||||
Time::Duration ret;
|
||||
if (now < retransmit_at_)
|
||||
ret = retransmit_at_ - now;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void reset_retransmit(const Time now)
|
||||
{
|
||||
retransmit_at_ = now + Time::Duration::seconds(RETRANSMIT);
|
||||
}
|
||||
|
||||
private:
|
||||
Time retransmit_at_;
|
||||
};
|
||||
|
||||
ReliableSend() : next(0) {}
|
||||
ReliableSend(const id_t span) { init(span); }
|
||||
|
||||
void init(const id_t span)
|
||||
{
|
||||
next = 1;
|
||||
window_.init(next, span);
|
||||
}
|
||||
|
||||
// Return the id that the object at the head of the queue
|
||||
// would have (even if it isn't defined yet).
|
||||
id_t head_id() const { return window_.head_id(); }
|
||||
|
||||
// Return the ID of one past the end of the window
|
||||
id_t tail_id() const { return window_.tail_id(); }
|
||||
|
||||
// Return the window size
|
||||
id_t span() const { return window_.span(); }
|
||||
|
||||
// Return a reference to M object at id, throw exception
|
||||
// if id is not in current window
|
||||
Message& ref_by_id(const id_t id)
|
||||
{
|
||||
return window_.ref_by_id(id);
|
||||
}
|
||||
|
||||
// Return the shortest duration for any pending retransmissions
|
||||
Time::Duration until_retransmit(const Time now)
|
||||
{
|
||||
Time::Duration ret = Time::Duration::infinite();
|
||||
for (id_t i = head_id(); i < tail_id(); ++i)
|
||||
{
|
||||
Message& msg = ref_by_id(i);
|
||||
if (msg.defined())
|
||||
{
|
||||
Time::Duration ut = msg.until_retransmit(now);
|
||||
if (ut < ret)
|
||||
ret = ut;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Return a fresh Message object that can be used to
|
||||
// construct the next packet in the sequence. Don't call
|
||||
// unless ready() returns true.
|
||||
Message& send(const Time now)
|
||||
{
|
||||
Message& msg = window_.ref_by_id(next);
|
||||
msg.id_ = next++;
|
||||
msg.reset_retransmit(now);
|
||||
return msg;
|
||||
}
|
||||
|
||||
// Return true if output buffer is ready to receive another packet
|
||||
bool ready() const { return window_.in_window(next); }
|
||||
|
||||
// Remove a packet from send buffer that has been acknowledged
|
||||
void ack(const id_t id) { window_.rm_by_id(id); }
|
||||
|
||||
private:
|
||||
id_t next;
|
||||
MessageWindow<Message, id_t> window_;
|
||||
};
|
||||
|
||||
} // namespace openvpn
|
||||
|
||||
#endif // OPENVPN_RELIABLE_RELSEND_H
|
@ -4,9 +4,11 @@
|
||||
#include <openvpn/time/time.hpp>
|
||||
|
||||
namespace openvpn {
|
||||
namespace time {
|
||||
|
||||
volatile Time::base_type now = 0; /* GLOBAL */
|
||||
Time now; /* GLOBAL */ // fixme should be volatile
|
||||
|
||||
} // namespace time
|
||||
} // namespace openvpn
|
||||
|
||||
#endif // OPENVPN_COMMON_NOW_H
|
||||
|
@ -33,8 +33,8 @@ namespace openvpn {
|
||||
const Time local_now = Time::now();
|
||||
const Time::type fs = local_now.fractional_binary_ms();
|
||||
const Time::Duration next_second = Time::Duration::binary_ms(Time::prec - fs);
|
||||
now = local_now.seconds_since_epoch();
|
||||
//std::cout << now << std::endl;
|
||||
time::now = local_now;
|
||||
//std::cout << time::now.seconds_since_epoch() << std::endl;
|
||||
timer_.expires_at(local_now + next_second);
|
||||
timer_.async_wait(asio_dispatch_timer(&NowUpdater::timer_callback, this));
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
#ifndef OPENVPN_COMMON_TIME_H
|
||||
#define OPENVPN_COMMON_TIME_H
|
||||
|
||||
#include <limits>
|
||||
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <openvpn/common/exception.hpp>
|
||||
@ -23,11 +25,13 @@ namespace openvpn {
|
||||
public:
|
||||
static Duration seconds(const T v) { return Duration(v * prec); }
|
||||
static Duration binary_ms(const T v) { return Duration(v); }
|
||||
static Duration infinite() { return Duration(std::numeric_limits<T>::max()); }
|
||||
|
||||
Duration() : duration_(T(0)) {}
|
||||
|
||||
operator bool() const { return duration_ != 0; }
|
||||
bool operator!() const { return duration_ == 0; }
|
||||
bool defined() const { return duration_ != T(0); }
|
||||
bool operator!() const { return duration_ == T(0); }
|
||||
bool is_infinite() const { return duration_ == std::numeric_limits<T>::max(); }
|
||||
|
||||
Duration operator+(const Duration& d) const { return Duration(duration_ + d.duration_); }
|
||||
Duration operator-(const Duration& d) const { return Duration(duration_ - d.duration_); }
|
||||
@ -42,6 +46,8 @@ namespace openvpn {
|
||||
T to_binary_ms() const { return duration_; }
|
||||
T to_microseconds() const { return duration_ * 1000000 / prec; }
|
||||
|
||||
T raw() const { return duration_; }
|
||||
|
||||
# define OPENVPN_DURATION_REL(OP) bool operator OP(const Duration& d) const { return duration_ OP d.duration_; }
|
||||
OPENVPN_DURATION_REL(==)
|
||||
OPENVPN_DURATION_REL(!=)
|
||||
@ -59,7 +65,10 @@ namespace openvpn {
|
||||
|
||||
TimeType() : time_(T(0)) {}
|
||||
|
||||
operator bool() const { return time_ != 0; }
|
||||
static TimeType zero() { return TimeType(T(0)); }
|
||||
static TimeType infinite() { return TimeType(std::numeric_limits<T>::max()); }
|
||||
|
||||
bool defined() const { return time_ != 0; }
|
||||
bool operator!() const { return time_ == 0; }
|
||||
|
||||
base_type seconds_since_epoch() const { return base_ + time_ / prec; }
|
||||
@ -76,6 +85,8 @@ namespace openvpn {
|
||||
static void reset_base() { base_ = ::time(0); }
|
||||
|
||||
TimeType operator+(const Duration& d) const { return TimeType(time_ + d.duration_); }
|
||||
TimeType& operator+=(const Duration& d) { time_ += d.duration_; return *this; }
|
||||
|
||||
Duration operator-(const TimeType& t) const { return Duration(time_ - t.time_); }
|
||||
|
||||
# define OPENVPN_TIME_REL(OP) bool operator OP(const TimeType& t) const { return time_ OP t.time_; }
|
||||
@ -87,6 +98,8 @@ namespace openvpn {
|
||||
OPENVPN_TIME_REL(<=)
|
||||
# undef OPENVPN_TIME_REL
|
||||
|
||||
T raw() const { return time_; }
|
||||
|
||||
private:
|
||||
explicit TimeType(const T time) : time_(time) {}
|
||||
|
||||
@ -96,7 +109,7 @@ namespace openvpn {
|
||||
|
||||
template <typename T> typename TimeType<T>::base_type TimeType<T>::base_;
|
||||
|
||||
typedef TimeType<unsigned int> Time;
|
||||
typedef TimeType<unsigned long> Time;
|
||||
|
||||
} // namespace openvpn
|
||||
|
||||
|
@ -5,6 +5,7 @@ if [ -z "$1" ]; then
|
||||
echo " DEBUG=1 -- enable debug"
|
||||
echo " STRIP=1 -- strip binary"
|
||||
echo " LTO=1 -- build with LTO"
|
||||
echo " GPROF=1 -- build for gprof profiling"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@ -14,9 +15,11 @@ if [ "$DEBUG" ]; then
|
||||
else
|
||||
# release build
|
||||
FLAGS=""
|
||||
[ "$LTO" ] && FLAGS="-flto=4 -Wl,--no-as-needed "
|
||||
[ "$LTO" ] && FLAGS="$FLAGS -flto=4 -Wl,--no-as-needed"
|
||||
[ "$GPROF" ] && FLAGS="$FLAGS -pg"
|
||||
g++ -Wall -O3 -fwhole-program $FLAGS -pthread $GCC_EXTRA -I$BOOST -I$OVPN3 -L$BOOST/stage/lib $1.cpp -o $1 -lboost_system -lcrypto -lssl
|
||||
fi
|
||||
|
||||
# maybe strip
|
||||
[ "$STRIP" ] && strip $1
|
||||
exit 0
|
||||
|
Loading…
Reference in New Issue
Block a user