/* Copyright (c) 2016-2019, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#define TOR_CHANNEL_INTERNAL_
#define MAINLOOP_PRIVATE
#define NETWORKSTATUS_PRIVATE
#define TOR_TIMERS_PRIVATE
#include "core/or/or.h"
#include "test/test.h"
#include "lib/testsupport/testsupport.h"
#include "core/mainloop/connection.h"
#include "core/or/connection_or.h"
#include "core/or/channel.h"
#include "core/or/channeltls.h"
#include "core/or/channelpadding.h"
#include "lib/evloop/compat_libevent.h"
#include "app/config/config.h"
#include "lib/time/compat_time.h"
#include "core/mainloop/mainloop.h"
#include "feature/nodelist/networkstatus.h"
#include "test/log_test_helpers.h"
#include "lib/tls/tortls.h"
#include "lib/evloop/timers.h"
#include "lib/container/buffers.h"
#include "core/or/cell_st.h"
#include "feature/nodelist/networkstatus_st.h"
#include "core/or/or_connection_st.h"
#include "feature/nodelist/routerstatus_st.h"
int channelpadding_get_netflow_inactive_timeout_ms(channel_t *chan);
int64_t channelpadding_compute_time_until_pad_for_netflow(channel_t *chan);
int channelpadding_send_disable_command(channel_t*);
int channelpadding_find_timerslot(channel_t *chan);
void test_channelpadding_timers(void *arg);
void test_channelpadding_consensus(void *arg);
void test_channelpadding_negotiation(void *arg);
void test_channelpadding_decide_to_pad_channel(void *arg);
void test_channelpadding_killonehop(void *arg);
void dummy_nop_timer(void);
#define NSEC_PER_MSEC (1000*1000)
/* Thing to cast to fake tor_tls_t * to appease assert_connection_ok() */
static int fake_tortls = 0; /* Bleh... */
static int dont_stop_libevent = 0;
// From test_channel.c
channel_t * new_fake_channel(void);
void free_fake_channel(channel_t*);
static int
mock_channel_has_queued_writes(channel_t *chan)
{
(void)chan;
return 0;
}
static int tried_to_write_cell = 0;
static channel_t *relay1_relay2;
static channel_t *relay2_relay1;
static channel_t *relay3_client;
static channel_t *client_relay3;
static int
mock_channel_write_cell_relay2(channel_t *chan, cell_t *cell)
{
(void)chan;
tried_to_write_cell++;
channel_tls_handle_cell(cell, ((channel_tls_t*)relay1_relay2)->conn);
tor_libevent_exit_loop_after_callback(tor_libevent_get_base());
return 0;
}
static int
mock_channel_write_cell_relay1(channel_t *chan, cell_t *cell)
{
(void)chan;
tried_to_write_cell++;
channel_tls_handle_cell(cell, ((channel_tls_t*)relay2_relay1)->conn);
tor_libevent_exit_loop_after_callback(tor_libevent_get_base());
return 0;
}
static int
mock_channel_write_cell_relay3(channel_t *chan, cell_t *cell)
{
(void)chan;
tried_to_write_cell++;
channel_tls_handle_cell(cell, ((channel_tls_t*)client_relay3)->conn);
tor_libevent_exit_loop_after_callback(tor_libevent_get_base());
return 0;
}
static int
mock_channel_write_cell_client(channel_t *chan, cell_t *cell)
{
(void)chan;
tried_to_write_cell++;
channel_tls_handle_cell(cell, ((channel_tls_t*)relay3_client)->conn);
tor_libevent_exit_loop_after_callback(tor_libevent_get_base());
return 0;
}
static int
mock_channel_write_cell(channel_t *chan, cell_t *cell)
{
tried_to_write_cell++;
channel_tls_handle_cell(cell, ((channel_tls_t*)chan)->conn);
if (!dont_stop_libevent)
tor_libevent_exit_loop_after_callback(tor_libevent_get_base());
return 0;
}
static void
setup_fake_connection_for_channel(channel_tls_t *chan)
{
or_connection_t *conn = (or_connection_t*)connection_new(CONN_TYPE_OR