31 std::string
expected{
"0400000021000000160000000b00000001\n"};
32 std::ostringstream actual;
50 ack.prepend(buf,
false);
54 std::string expected2{
"080000002100000100000000990000008800000077000000660000005500000044\n"};
56 std::ostringstream actual2;
60 ack.prepend(buf2,
true);
62 EXPECT_EQ(actual2.str(), expected2);
67 std::ostringstream actual;
75 std::string
expected{
"0400000004000000030000000200000001\n"};
79 ack.prepend(buf,
false);
82 EXPECT_EQ(ack.resend_size(), 4u);
88 std::string expected2{
"0400000002000000040000000600000003\n"};
93 ack.prepend(buf2,
false);
95 EXPECT_EQ(actual.str(), expected2);
97 EXPECT_EQ(ack.resend_size(), 5u);
102 ack.prepend(buf3,
false);
106 std::string expected3{
"0400000002000000040000000300000006\n"};
107 EXPECT_EQ(actual.str(), expected3);
112 std::ostringstream actual;
120 ack.prepend(buf,
false);
140 operator bool()
const
165 std::stringstream &case_detail)
167 case_detail << t.raw() <<
' ' << title
168 <<
'[' <<
id <<
"] " << (
char *)buf->data()
175 const Time::Duration end,
176 const Time::Duration step,
177 const Time::Duration end_sends,
179 const size_t wiresize,
180 const unsigned int reorder_prob,
181 const unsigned int drop_prob,
182 std::stringstream &case_detail)
187 std::deque<Message> wire;
199 for (t = Time::Duration(); t < end; t += step)
202 const Time now = base + t;
205 while (!acklist.empty())
212 case_detail << t.
raw() <<
" ACK [" <<
id <<
"]" << std::endl;
217 case_detail << t.raw() <<
" Simulate dropped ACK [" <<
id <<
"]" << std::endl;
226 ReliableSend::Message &m = send.
ref_by_id(i);
227 if (m.ready_retransmit(now))
235 m.reset_retransmit(now, Time::Duration());
245 if (send.
ready() && t < end_sends)
248 std::ostringstream
os;
249 os <<
"Test packet #" << count;
250 const std::string s =
os.str();
252 ReliableSend::Message &m = send.
send(now, Time::Duration());
253 m.packet.buf = buffer;
256 send_id =
msg.id = m.id();
264 if (!rand.
randrange(reorder_prob) && wire.size() >= 2)
266 const size_t i1 = rand.
randrange(wire.size());
267 const size_t i2 = rand.
randrange(wire.size());
270 case_detail << t.raw()
271 <<
" Simulate packet reordering "
272 << i1 <<
" <-> " << i2 << std::endl;
273 std::swap(wire[i1], wire[i2]);
279 while (wire.size() >= wiresize || (!wire.empty() && !rand.
randrange(8)))
284 case_detail << t.raw() <<
" Received packet [" <<
msg.
id <<
"]" << std::endl;
292 acklist.push_back(
msg.id);
296 case_detail << t.raw()
297 <<
" Simulate dropped packet [" <<
msg.id <<
"]" << std::endl;
305 print_msg(t,
"RECV", m.packet.buf, m.id(), case_detail);
306 if (m.id() != rec_id)
307 throw receive_sequence();
314 case_detail <<
"Case Summary:\nrelsize=" << relsize
315 <<
" wiresize=" << wiresize
316 <<
" reorder=" << reorder_prob
317 <<
" drop=" << drop_prob
318 <<
" final_t=" << t.raw()
319 <<
" iterations=" << iterations
320 <<
" count=" << count
321 <<
" [" << send_id <<
'/' << (rec_id ? rec_id - 1 : 0) <<
']'
323 if (send_id != (rec_id ? rec_id - 1 : 0))
324 throw receive_sequence();
339 std::vector<test_params> sim_cases = {
345 const Time::Duration end = Time::Duration::seconds(1000);
346 const Time::Duration step = Time::Duration::binary_ms(100);
347 const Time::Duration end_sends = end - Time::Duration::seconds(5);
348 for (
auto &sim_case : sim_cases)
351 std::stringstream case_detail;
354 case_detail <<
"Test case " << sim_case.test_case << std::endl;
362 sim_case.reorder_prob,
366 catch (
const std::exception &e)
368 ASSERT_TRUE(
false) <<
"Exception: " << e.what() <<
"\nDetail:\n"
369 << case_detail.rdbuf();
void init_headroom(const size_t headroom)
Initializes the headroom (offset) of the buffer.
void reset() noexcept
Points this RCPtr<T> to nullptr safely.
T randrange(const T end)
Return a uniformly distributed random number in the range [0, end)
static Ptr Create(ArgsT &&...args)
Creates a new instance of RcEnable with the given arguments.
void push_back(id_t value)
Message & next_sequenced()
unsigned int receive(const PACKET &packet, const id_t id)
Message & ref_by_id(const id_t id)
Message & send(const Time &now, const Time::Duration &tls_timeout)
Time::Duration until_retransmit(const Time &now)
static TimeType infinite()
#define OPENVPN_SIMPLE_EXCEPTION(C)
openvpn::reliable::id_t id_t
constexpr BufferFlags NO_FLAGS(0u)
no flags set
std::string render_hex_generic(const V &data, const bool caps=false)
openvpn::PacketIDControl::id_t id
Packet(const BufferPtr &buf_arg)
unsigned int reorder_prob
openvpn::PacketIDControl::id_t relsize
ReliableRecvTemplate< Packet > ReliableRecv
ReliableSendTemplate< Packet > ReliableSend
void print_msg(const Time::Duration t, const char *title, BufferPtr &buf, const openvpn::PacketIDControl::id_t id, std::stringstream &case_detail)