tor-commits
Threads by month
- ----- 2026 -----
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- 1 participants
- 216106 discussions
[stegotorus/master] More tiny bugfixes - test suite now reliable on OSX
by zwol@torproject.org 20 Jul '12
by zwol@torproject.org 20 Jul '12
20 Jul '12
commit 2021bfe0d20eab807bd3a8276ef0cccc9c106a73
Author: Zack Weinberg <zackw(a)cmu.edu>
Date: Thu Mar 29 09:06:27 2012 -0700
More tiny bugfixes - test suite now reliable on OSX
---
src/protocol/chop.cc | 12 +++++++-----
src/protocol/null.cc | 9 ++++++++-
2 files changed, 15 insertions(+), 6 deletions(-)
diff --git a/src/protocol/chop.cc b/src/protocol/chop.cc
index 44e79a3..cf64e6c 100644
--- a/src/protocol/chop.cc
+++ b/src/protocol/chop.cc
@@ -236,6 +236,8 @@ public:
{
reassembly_elt rv = { 0, op_DAT };
uint8_t front = next_to_process & 0xFF;
+ log_debug("next_to_process=%d data=%p op=%02x",
+ next_to_process, cbuf[front].data, cbuf[front].op);
if (cbuf[front].data) {
rv = cbuf[front];
cbuf[front].data = 0;
@@ -255,14 +257,14 @@ public:
insert(uint32_t seqno, opcode_t op, evbuffer *data, conn_t *conn)
{
if (seqno - window() > 255) {
- log_warn(conn, "block outside receive window");
+ log_info(conn, "block outside receive window");
evbuffer_free(data);
return false;
}
uint8_t front = next_to_process & 0xFF;
uint8_t pos = front + (seqno - window());
if (cbuf[pos].data) {
- log_warn(conn, "duplicate block");
+ log_info(conn, "duplicate block");
evbuffer_free(data);
return false;
}
@@ -1193,7 +1195,7 @@ chop_conn_t::recv()
block_header hdr(recv_pending, *upstream->recv_hdr_crypt);
if (!hdr.valid(upstream->recv_queue.window())) {
const uint8_t *c = hdr.cleartext();
- log_warn(this, "invalid block header: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
+ log_info(this, "invalid block header: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7],
c[8], c[9], c[10], c[11], c[12], c[13], c[14], c[15]);
return -1;
@@ -1214,11 +1216,11 @@ chop_conn_t::recv()
if (upstream->recv_crypt->decrypt(decodebuf,
decodebuf, hdr.total_len() - HEADER_LEN,
hdr.nonce(), HEADER_LEN)) {
- log_warn("MAC verification failure");
+ log_info("MAC verification failure");
return -1;
}
- log_debug(this, "receiving block %u <d=%lu p=%lu f=%u>",
+ log_debug(this, "receiving block %u <d=%lu p=%lu f=%02x>",
hdr.seqno(), (unsigned long)hdr.dlen(), (unsigned long)hdr.plen(),
(unsigned int)hdr.opcode());
diff --git a/src/protocol/null.cc b/src/protocol/null.cc
index 989ffd4..277eb59 100644
--- a/src/protocol/null.cc
+++ b/src/protocol/null.cc
@@ -137,7 +137,10 @@ null_circuit_t::~null_circuit_t()
/* break the circular reference before deallocating the
downstream connection */
downstream->upstream = NULL;
- delete downstream;
+ if (evbuffer_get_length(downstream->outbound()) > 0)
+ conn_do_flush(downstream);
+ else
+ delete downstream;
}
}
@@ -191,6 +194,9 @@ null_circuit_t::drop_downstream(conn_t *cn)
int
null_circuit_t::send()
{
+ log_debug(this, "sending %lu bytes",
+ evbuffer_get_length(bufferevent_get_input(this->up_buffer)));
+
return evbuffer_add_buffer(this->downstream->outbound(),
bufferevent_get_input(this->up_buffer));
}
@@ -261,6 +267,7 @@ int
null_conn_t::recv()
{
log_assert(this->upstream);
+ log_debug(this, "receiving %lu bytes", evbuffer_get_length(this->inbound()));
return evbuffer_add_buffer(bufferevent_get_output(this->upstream->up_buffer),
this->inbound());
}
1
0
[stegotorus/master] Split up steg_t into per-connection and per-listener state objects.
by zwol@torproject.org 20 Jul '12
by zwol@torproject.org 20 Jul '12
20 Jul '12
commit 0448e1cc8aaaa5b4d71277b9738cfa5b33268212
Author: Zack Weinberg <zackw(a)panix.com>
Date: Thu Mar 29 17:45:25 2012 -0700
Split up steg_t into per-connection and per-listener state objects.
This will facilitate the removal of the global variables in embed and http
so that they work in multi-listener mode, and the addition of configurable
parameters to steg modules (such as the location of the trace files).
---
src/protocol/chop.cc | 26 +++++-----
src/steg.cc | 13 +++--
src/steg.h | 126 +++++++++++++++++++++++++++++++-----------------
src/steg/embed.cc | 122 ++++++++++++++++++++++++++++++++++-------------
src/steg/http.cc | 83 ++++++++++++++++++++++++---------
src/steg/nosteg.cc | 50 +++++++++++++++----
src/steg/nosteg_rr.cc | 62 ++++++++++++++++++------
7 files changed, 339 insertions(+), 143 deletions(-)
diff --git a/src/protocol/chop.cc b/src/protocol/chop.cc
index cf64e6c..06346b7 100644
--- a/src/protocol/chop.cc
+++ b/src/protocol/chop.cc
@@ -371,7 +371,7 @@ struct chop_config_t : config_t
{
struct evutil_addrinfo *up_address;
vector<struct evutil_addrinfo *> down_addresses;
- vector<const char *> steg_targets;
+ vector<steg_config_t *> steg_targets;
chop_circuit_table circuits;
CONFIG_DECLARE_METHODS(chop);
@@ -392,7 +392,9 @@ chop_config_t::~chop_config_t()
i != down_addresses.end(); i++)
evutil_freeaddrinfo(*i);
- // The strings in steg_targets are not on the heap.
+ for (vector<steg_config_t *>::iterator i = steg_targets.begin();
+ i != steg_targets.end(); i++)
+ delete *i;
for (chop_circuit_table::iterator i = circuits.begin();
i != circuits.end(); i++)
@@ -454,7 +456,7 @@ chop_config_t::init(int n_options, const char *const *options)
log_warn("chop: steganographer '%s' not supported", options[i]);
goto usage;
}
- steg_targets.push_back(options[i]);
+ steg_targets.push_back(steg_new(options[i], this));
}
return true;
@@ -744,7 +746,7 @@ chop_circuit_t::send_targeted(chop_conn_t *conn)
avail = SECTION_LEN;
avail += MIN_BLOCK_SIZE;
- size_t room = conn->steg->transmit_room(conn);
+ size_t room = conn->steg->transmit_room();
if (room < MIN_BLOCK_SIZE) {
log_warn(conn, "send() called without enough transmit room "
"(have %lu, need %lu)", (unsigned long)room,
@@ -752,7 +754,7 @@ chop_circuit_t::send_targeted(chop_conn_t *conn)
return -1;
}
log_debug(conn, "offers %lu bytes (%s)", (unsigned long)room,
- conn->steg->name());
+ conn->steg->cfg()->name());
if (room < avail)
avail = room;
@@ -868,7 +870,7 @@ chop_circuit_t::pick_connection(size_t desired, size_t *blocksize)
if (conn->steg) {
// Find the connections whose transmit rooms are closest to the
// desired transmission length from both directions.
- size_t room = conn->steg->transmit_room(conn);
+ size_t room = conn->steg->transmit_room();
if (room <= MIN_BLOCK_SIZE)
room = 0;
@@ -877,7 +879,7 @@ chop_circuit_t::pick_connection(size_t desired, size_t *blocksize)
room = MAX_BLOCK_SIZE;
log_debug(conn, "offers %lu bytes (%s)", (unsigned long)room,
- conn->steg->name());
+ conn->steg->cfg()->name());
if (room >= desired) {
if (room < minabove) {
@@ -1029,7 +1031,7 @@ chop_config_t::conn_create(size_t index)
{
chop_conn_t *conn = new chop_conn_t;
conn->config = this;
- conn->steg = steg_new(steg_targets.at(index), mode != LSN_SIMPLE_SERVER);
+ conn->steg = steg_targets.at(index)->steg_create(conn);
if (!conn->steg) {
free(conn);
return 0;
@@ -1082,7 +1084,7 @@ chop_conn_t::send(struct evbuffer *block)
}
}
- if (steg->transmit(block, this)) {
+ if (steg->transmit(block)) {
log_warn(this, "failed to transmit block");
return -1;
}
@@ -1154,7 +1156,7 @@ chop_conn_t::recv_handshake()
int
chop_conn_t::recv()
{
- if (steg->receive(this, recv_pending))
+ if (steg->receive(recv_pending))
return -1;
if (!upstream) {
@@ -1320,7 +1322,7 @@ chop_conn_t::send()
} else {
log_debug(this, "must send (no upstream)");
- size_t room = steg->transmit_room(this);
+ size_t room = steg->transmit_room();
if (room < MIN_BLOCK_SIZE) {
log_warn(this, "send() called without enough transmit room "
"(have %lu, need %lu)", (unsigned long)room,
@@ -1351,7 +1353,7 @@ chop_conn_t::send()
return;
}
- if (steg->transmit(chaff, this))
+ if (steg->transmit(chaff))
conn_do_flush(this);
evbuffer_free(chaff);
diff --git a/src/steg.cc b/src/steg.cc
index 8db5498..12ea291 100644
--- a/src/steg.cc
+++ b/src/steg.cc
@@ -18,16 +18,17 @@ steg_is_supported(const char *name)
}
/* Instantiate a steg module by name. */
-steg_t *
-steg_new(const char *name, bool is_clientside)
+steg_config_t *
+steg_new(const char *name, config_t *cfg)
{
const steg_module *const *s;
for (s = supported_stegs; *s; s++)
if (!strcmp(name, (**s).name))
- return (**s).new_(is_clientside);
- return NULL;
+ return (**s).new_(cfg);
+ return 0;
}
-/* Define this here rather than in the class definition so that the
- vtable will be emitted in only one place. */
+/* Define these here rather than in the class definition so that the
+ vtables will be emitted in only one place. */
+steg_config_t::~steg_config_t() {}
steg_t::~steg_t() {}
diff --git a/src/steg.h b/src/steg.h
index dab44e5..a044afb 100644
--- a/src/steg.h
+++ b/src/steg.h
@@ -5,42 +5,73 @@
#ifndef STEG_H
#define STEG_H
-/** A steganography instance must define a private subclass of this
- type, that implements all of the methods below, plus a descendant
- constructor. The subclass must have exactly the same name that
- you use for the module name in STEG_DEFINE_MODULE, and should be
- declared inside an anonymous namespace. Use STEG_DECLARE_METHODS
- in the declaration. */
-struct steg_t
+/** A 'steg_config_t' is analogous to a 'config_t' (see protocol.h);
+ it defines cross-connection state for a steganography module.
+ (A 'config_t' may be associated with several 'steg_config_t's.)
+
+ A steganography module must define a private subclass of this
+ type, that implements all the methods below, plus a descendant
+ constructor. The subclass must have the name MODULE_steg_config_t,
+ where MODULE is the module name you use in STEG_DEFINE_MODULE.
+ It should be declared inside an anonymous namespace.
+ Use STEG_CONFIG_DECLARE_METHODS in the declaration. */
+
+struct steg_t;
+
+struct steg_config_t
{
- bool is_clientside : 1;
+ struct config_t *cfg;
- steg_t(bool is_clientside) : is_clientside(is_clientside) {}
- virtual ~steg_t();
+ steg_config_t(config_t *c) : cfg(c) {}
+ virtual ~steg_config_t();
/** Report the name of this steg module. You do not have to define
this method in your subclass, STEG_DEFINE_MODULE does it for you. */
virtual const char *name() = 0;
+ /** Create an extended 'steg_t' object (see below) from this
+ configuration, associated with connection CONN. */
+ virtual steg_t *steg_create(conn_t *conn) = 0;
+};
+
+/** A 'steg_t' object handles the actual steganography for one
+ connection, and is responsible for tracking per-connection
+ state for the cover protocol, if any.
+
+ Again, a steganography module must define a private subclass of
+ this type, that implements all of the methods below, plus a
+ descendant constructor. The subclass must have the name
+ MODULE_steg_t, where MODULE is the module name you use in
+ STEG_DEFINE_MODULE. It should be declared inside an anonymous
+ namespace. Use STEG_DECLARE_METHODS in the declaration. */
+struct steg_t
+{
+ steg_t() {}
+ virtual ~steg_t();
+
+ /** Return the steg_config_t from which this steg_t was created. */
+ virtual steg_config_t *cfg() = 0;
+
/** Report the maximum number of bytes that could be transmitted on
- connection CONN at this time. You must be prepared to handle a
+ your connection at this time. You must be prepared to handle a
subsequent request to transmit any _smaller_ number of bytes on
this connection. */
- virtual size_t transmit_room(conn_t *conn) = 0;
+ virtual size_t transmit_room() = 0;
/** Consume all of the data in SOURCE, disguise it, and write it to
- the outbound buffer for CONN. Return 0 on success, -1 on failure. */
- virtual int transmit(struct evbuffer *source, conn_t *conn) = 0;
-
- /** The data in CONN's inbound buffer should have been disguised by
- the peer instance to STATE. Unmask it and write it to DEST.
- Return 0 on success, -1 on failure. If more data needs to come
- over the wire before anything can be unmasked, that is *not* a
- failure condition; return 0, but do not consume any data or
- write anything to DEST. It is *preferable*, but not currently
- *required*, for this method to not consume any data or write
- anything to DEST in a failure situation. */
- virtual int receive(conn_t *conn, struct evbuffer *dest) = 0;
+ the outbound buffer for your connection. Return 0 on success, -1
+ on failure. */
+ virtual int transmit(struct evbuffer *source) = 0;
+
+ /** Unmask as much of the data in your connection's inbound buffer
+ as possible, and write it to DEST. Return 0 on success, -1 on
+ failure. If more data needs to come over the wire before
+ anything can be unmasked, that is *not* a failure condition;
+ return 0, but do not consume any data or write anything to DEST.
+ It is *preferable*, but not currently *required*, for this
+ method to not consume any data or write anything to DEST in a
+ failure situation. */
+ virtual int receive(struct evbuffer *dest) = 0;
};
/** STEG_DEFINE_MODULE defines an object with this type, plus the
@@ -52,38 +83,43 @@ struct steg_module
/** Name of the steganography module. Must be a valid C identifier. */
const char *name;
- /** Create an appropriate steg_t subclass for this module.
- More arguments may be added later. */
- steg_t *(*new_)(bool is_clientside);
+ /** Create an appropriate steg_config_t subclass for this module. */
+ steg_config_t *(*new_)(config_t *cfg);
};
extern const steg_module *const supported_stegs[];
int steg_is_supported(const char *name);
-steg_t *steg_new(const char *name, bool is_clientside);
+steg_config_t *steg_new(const char *name, config_t *cfg);
/* Macros for use in defining steg modules. */
-#define STEG_DEFINE_MODULE(mod) \
- /* new_ dispatchers */ \
- static steg_t *mod##_new(bool is_clientside) \
- { return new mod(is_clientside); } \
- \
- /* canned methods */ \
- const char *mod::name() { return #mod; } \
- \
- /* module object */ \
- extern const steg_module s_mod_##mod = { \
- #mod, mod##_new \
+#define STEG_DEFINE_MODULE(mod) \
+ /* new_ dispatchers */ \
+ static steg_config_t *mod##_new(config_t *cfg) \
+ { return new mod##_steg_config_t(cfg); } \
+ \
+ /* canned methods */ \
+ const char *mod##_steg_config_t::name() { return #mod; } \
+ \
+ /* module object */ \
+ extern const steg_module s_mod_##mod = { \
+ #mod, mod##_new \
} /* deliberate absence of semicolon */
-#define STEG_DECLARE_METHODS(mod) \
- mod(bool is_clientside); \
- virtual ~mod(); \
+#define STEG_CONFIG_DECLARE_METHODS(mod) \
+ mod##_steg_config_t(config_t *cfg); \
+ virtual ~mod##_steg_config_t(); \
virtual const char *name(); \
- virtual size_t transmit_room(conn_t *conn); \
- virtual int transmit(struct evbuffer *source, conn_t *conn); \
- virtual int receive(conn_t *conn, struct evbuffer *dest) \
+ virtual steg_t *steg_create(conn_t *conn) \
+ /* deliberate absence of semicolon */
+
+#define STEG_DECLARE_METHODS(mod) \
+ virtual ~mod##_steg_t(); \
+ virtual steg_config_t *cfg(); \
+ virtual size_t transmit_room(); \
+ virtual int transmit(struct evbuffer *source); \
+ virtual int receive(struct evbuffer *dest) \
/* deliberate absence of semicolon */
#endif
diff --git a/src/steg/embed.cc b/src/steg/embed.cc
index e2f12a0..6559bf7 100644
--- a/src/steg/embed.cc
+++ b/src/steg/embed.cc
@@ -1,5 +1,6 @@
#include "util.h"
#include "connections.h"
+#include "protocol.h"
#include "steg.h"
#include "rng.h"
@@ -9,19 +10,30 @@
#include <unistd.h>
#include <time.h>
-typedef struct trace_t {
- int num_pkt; // number of packets in trace
- short *pkt_sizes; // packet sizes (positive = client->server)
- int *pkt_times; // packet inter-arrival times
-} trace_t;
-
namespace {
- struct embed : steg_t {
+ struct trace_t {
+ int num_pkt; // number of packets in trace
+ short *pkt_sizes; // packet sizes (positive = client->server)
+ int *pkt_times; // packet inter-arrival times
+ };
+
+ struct embed_steg_config_t : steg_config_t {
+ bool is_clientside;
+
+ STEG_CONFIG_DECLARE_METHODS(embed);
+ };
+
+ struct embed_steg_t : steg_t {
+ embed_steg_config_t *config;
+ conn_t *conn;
+
int cur_idx; // current trace index
trace_t *cur; // current trace
int cur_pkt; // current packet in the trace
struct timeval last_pkt; // time at which last packet was sent/received
+ embed_steg_t(embed_steg_config_t *cf, conn_t *cn);
+
STEG_DECLARE_METHODS(embed);
bool advance_packet();
@@ -32,13 +44,15 @@ namespace {
};
}
+STEG_DEFINE_MODULE(embed);
+
static int embed_init = 0; // whether traces are initialized
static int embed_num_traces; // number of traces
static trace_t *embed_traces; // global array of all traces
-STEG_DEFINE_MODULE(embed);
-
-int millis_since(struct timeval *last) {
+static int
+millis_since(struct timeval *last)
+{
struct timeval cur;
int diff = 0;
gettimeofday(&cur, NULL);
@@ -48,13 +62,31 @@ int millis_since(struct timeval *last) {
return diff;
}
-void init_embed_traces() {
+embed_steg_config_t::embed_steg_config_t(config_t *cfg)
+ : steg_config_t(cfg),
+ is_clientside(cfg->mode != LSN_SIMPLE_SERVER)
+{
+}
+
+embed_steg_config_t::~embed_steg_config_t()
+{
+}
+
+steg_t *
+embed_steg_config_t::steg_create(conn_t *conn)
+{
+ return new embed_steg_t(this, conn);
+}
+
+static void
+init_embed_traces()
+{
// read in traces to use for connections
FILE *trace_file = fopen("traces/embed.txt", "r");
if (fscanf(trace_file, "%d", &embed_num_traces) < 1) {
log_abort("couldn't read number of traces to use -- exiting");
exit(1);
- }
+ }
embed_traces = (trace_t *)xmalloc(sizeof(trace_t) * embed_num_traces);
for (int i = 0; i < embed_num_traces; i++) {
int num_pkt;
@@ -67,10 +99,10 @@ void init_embed_traces() {
embed_traces[i].pkt_times = (int *)xmalloc(sizeof(int) * num_pkt);
for (int j = 0; j < embed_traces[i].num_pkt; j++) {
if (fscanf(trace_file, "%hd %d",
- &embed_traces[i].pkt_sizes[j],
- &embed_traces[i].pkt_times[j]) < 1) {
- log_abort("couldn't read numbers of packet size and times to use -- exiting");
- exit(1);
+ &embed_traces[i].pkt_sizes[j],
+ &embed_traces[i].pkt_times[j]) < 1) {
+ log_abort("couldn't read numbers of packet size and times to use -- exiting");
+ exit(1);
}
}
}
@@ -79,39 +111,51 @@ void init_embed_traces() {
embed_init = 1;
}
-int get_random_trace() {
+static int
+get_random_trace()
+{
return rng_int(embed_num_traces);
}
-bool embed::advance_packet() {
+bool
+embed_steg_t::advance_packet()
+{
cur_pkt++;
return cur_pkt == cur->num_pkt;
}
-short embed::get_pkt_size() {
+short
+embed_steg_t::get_pkt_size()
+{
return abs(cur->pkt_sizes[cur_pkt]);
}
-bool embed::is_outgoing() {
- return (cur->pkt_sizes[cur_pkt] < 0) ^ is_clientside;
+bool
+embed_steg_t::is_outgoing()
+{
+ return (cur->pkt_sizes[cur_pkt] < 0) ^ config->is_clientside;
}
-int embed::get_pkt_time() {
+int
+embed_steg_t::get_pkt_time()
+{
return cur->pkt_times[cur_pkt];
}
-bool embed::is_finished() {
+bool
+embed_steg_t::is_finished()
+{
if (cur_idx == -1) return true;
return cur_pkt >= cur->num_pkt;
}
-embed::embed(bool is_clientside)
- : steg_t(is_clientside)
+embed_steg_t::embed_steg_t(embed_steg_config_t *cf, conn_t *cn)
+ : config(cf), conn(cn)
{
if (!embed_init) init_embed_traces();
cur_idx = -1;
- if (is_clientside) {
+ if (config->is_clientside) {
cur_idx = get_random_trace();
cur = &embed_traces[cur_idx];
cur_pkt = 0;
@@ -119,11 +163,19 @@ embed::embed(bool is_clientside)
gettimeofday(&last_pkt, NULL);
}
-embed::~embed()
+embed_steg_t::~embed_steg_t()
+{
+}
+
+steg_config_t *
+embed_steg_t::cfg()
{
+ return config;
}
-size_t embed::transmit_room(conn_t * /* conn */) {
+size_t
+embed_steg_t::transmit_room()
+{
if (is_finished() || !is_outgoing()) return 0;
int time_diff = millis_since(&last_pkt);
@@ -135,7 +187,9 @@ size_t embed::transmit_room(conn_t * /* conn */) {
return room;
}
-int embed::transmit(struct evbuffer *source, conn_t *conn) {
+int
+embed_steg_t::transmit(struct evbuffer *source)
+{
struct evbuffer *dest = conn->outbound();
short src_len = evbuffer_get_length(source);
short pkt_size = get_pkt_size();
@@ -177,13 +231,15 @@ int embed::transmit(struct evbuffer *source, conn_t *conn) {
return 0;
}
-int embed::receive(conn_t *conn, struct evbuffer *dest) {
+int
+embed_steg_t::receive(struct evbuffer *dest)
+{
struct evbuffer *source = conn->inbound();
short src_len = evbuffer_get_length(source);
short pkt_size = 0;
log_debug("receiving buffer of length %d", src_len);
-
+
// if we are receiving the first packet of the trace, read the index
if (cur_idx == -1) {
if (evbuffer_remove(source, &cur_idx, 4) != 4) return -1;
@@ -206,7 +262,7 @@ int embed::receive(conn_t *conn, struct evbuffer *dest) {
if (evbuffer_remove(source, &data_len, 2) != 2) return -1;
if (data_len > 0) {
if (evbuffer_remove_buffer(source, dest, data_len) != data_len) {
- return -1;
+return -1;
}
}
pkt_size += data_len + 2;
@@ -221,7 +277,7 @@ int embed::receive(conn_t *conn, struct evbuffer *dest) {
pkt_size = 0;
log_debug("received packet %d of trace %d",
- cur_pkt, cur_idx);
+ cur_pkt, cur_idx);
// advance packet; if done with trace, sender should close connection
if (advance_packet()) {
diff --git a/src/steg/http.cc b/src/steg/http.cc
index 5a78ffe..05ab940 100644
--- a/src/steg/http.cc
+++ b/src/steg/http.cc
@@ -34,6 +34,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "util.h"
#include "connections.h"
+#include "protocol.h"
#include "steg.h"
#include "payloads.h"
#include "cookies.h"
@@ -60,20 +61,48 @@ static int has_peer_name = 0;
static char peername[512];
namespace {
-struct http : steg_t
-{
- bool have_transmitted : 1;
- bool have_received : 1;
- int type;
+ struct http_steg_config_t : steg_config_t
+ {
+ bool is_clientside : 1;
+
+ STEG_CONFIG_DECLARE_METHODS(http);
+ };
+
+ struct http_steg_t : steg_t
+ {
+ http_steg_config_t *config;
+ conn_t *conn;
+
+ bool have_transmitted : 1;
+ bool have_received : 1;
+ int type;
- STEG_DECLARE_METHODS(http);
-};
+ http_steg_t(http_steg_config_t *cf, conn_t *cn);
+ STEG_DECLARE_METHODS(http);
+ };
}
STEG_DEFINE_MODULE(http);
-int http_client_uri_transmit (steg_t *s, struct evbuffer *source, conn_t *conn);
-int http_client_cookie_transmit (steg_t *s, struct evbuffer *source, conn_t *conn);
+http_steg_config_t::http_steg_config_t(config_t *cfg)
+ : steg_config_t(cfg),
+ is_clientside(cfg->mode != LSN_SIMPLE_SERVER)
+{
+}
+
+http_steg_config_t::~http_steg_config_t()
+{
+}
+
+steg_t *
+http_steg_config_t::steg_create(conn_t *conn)
+{
+ return new http_steg_t(this, conn);
+}
+
+
+int http_client_uri_transmit (http_steg_t *s, struct evbuffer *source, conn_t *conn);
+int http_client_cookie_transmit (http_steg_t *s, struct evbuffer *source, conn_t *conn);
void evbuffer_dump(struct evbuffer *buf, FILE *out);
void buf_dump(unsigned char* buf, int len, FILE *out);
@@ -128,11 +157,11 @@ buf_dump(unsigned char* buf, int len, FILE *out)
}
-http::http(bool is_clientside)
- : steg_t(is_clientside),
+http_steg_t::http_steg_t(http_steg_config_t *cf, conn_t *cn)
+ : config(cf), conn(cn),
have_transmitted(false), have_received(false)
{
- if (is_clientside)
+ if (config->is_clientside)
load_payloads("traces/client.out");
else {
load_payloads("traces/server.out");
@@ -144,12 +173,18 @@ http::http(bool is_clientside)
}
}
-http::~http()
+http_steg_t::~http_steg_t()
{
}
+steg_config_t *
+http_steg_t::cfg()
+{
+ return config;
+}
+
size_t
-http::transmit_room(conn_t *)
+http_steg_t::transmit_room()
{
unsigned int mjc;
@@ -158,7 +193,7 @@ http::transmit_room(conn_t *)
return 0;
- if (is_clientside) {
+ if (config->is_clientside) {
return (MIN_COOKIE_SIZE + rand() % (MAX_COOKIE_SIZE - MIN_COOKIE_SIZE)) / 4;
}
else {
@@ -251,7 +286,9 @@ lookup_peer_name_from_ip(char* p_ip, char* p_name) {
int
-http_client_cookie_transmit (http *s, struct evbuffer *source, conn_t *conn) {
+http_client_cookie_transmit (http_steg_t *s, struct evbuffer *source,
+ conn_t *conn)
+{
/* On the client side, we have to embed the data in a GET query somehow;
the only plausible places to put it are the URL and cookies. This
@@ -455,7 +492,9 @@ int gen_uri_field(char* uri, unsigned int uri_sz, char* data, int datalen) {
int
-http_client_uri_transmit (http *s, struct evbuffer *source, conn_t *conn) {
+http_client_uri_transmit (http_steg_t *s,
+ struct evbuffer *source, conn_t *conn)
+{
struct evbuffer *dest = conn->outbound();
@@ -558,7 +597,7 @@ http_client_uri_transmit (http *s, struct evbuffer *source, conn_t *conn) {
int
-http::transmit(struct evbuffer *source, conn_t *conn)
+http_steg_t::transmit(struct evbuffer *source)
{
// struct evbuffer *dest = conn_get_outbound(conn);
@@ -566,7 +605,7 @@ http::transmit(struct evbuffer *source, conn_t *conn)
- if (is_clientside) {
+ if (config->is_clientside) {
/* On the client side, we have to embed the data in a GET query somehow;
the only plausible places to put it are the URL and cookies. */
@@ -609,7 +648,7 @@ http::transmit(struct evbuffer *source, conn_t *conn)
int
-http_server_receive(http *s, conn_t *conn, struct evbuffer *dest, struct evbuffer* source) {
+http_server_receive(http_steg_t *s, conn_t *conn, struct evbuffer *dest, struct evbuffer* source) {
char* data;
int type;
@@ -710,14 +749,14 @@ http_server_receive(http *s, conn_t *conn, struct evbuffer *dest, struct evbuffe
int
-http::receive(conn_t *conn, struct evbuffer *dest)
+http_steg_t::receive(struct evbuffer *dest)
{
struct evbuffer *source = conn->inbound();
// unsigned int type;
int rval = RECV_BAD;
- if (is_clientside) {
+ if (config->is_clientside) {
switch(type) {
case HTTP_CONTENT_SWF:
diff --git a/src/steg/nosteg.cc b/src/steg/nosteg.cc
index 02d2e10..df80c89 100644
--- a/src/steg/nosteg.cc
+++ b/src/steg/nosteg.cc
@@ -39,31 +39,61 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <event2/buffer.h>
namespace {
-struct nosteg : steg_t
-{
- STEG_DECLARE_METHODS(nosteg);
-};
+ struct nosteg_steg_config_t : steg_config_t
+ {
+ STEG_CONFIG_DECLARE_METHODS(nosteg);
+ };
+
+ struct nosteg_steg_t : steg_t
+ {
+ nosteg_steg_config_t *config;
+ conn_t *conn;
+
+ nosteg_steg_t(nosteg_steg_config_t *cf, conn_t *cn);
+ STEG_DECLARE_METHODS(nosteg);
+ };
}
STEG_DEFINE_MODULE(nosteg);
-nosteg::nosteg(bool is_clientside)
- : steg_t(is_clientside)
+nosteg_steg_config_t::nosteg_steg_config_t(config_t *cfg)
+ : steg_config_t(cfg)
+{
+}
+
+nosteg_steg_config_t::~nosteg_steg_config_t()
+{
+}
+
+steg_t *
+nosteg_steg_config_t::steg_create(conn_t *conn)
+{
+ return new nosteg_steg_t(this, conn);
+}
+
+nosteg_steg_t::nosteg_steg_t(nosteg_steg_config_t *cf, conn_t *cn)
+ : config(cf), conn(cn)
+{
+}
+
+nosteg_steg_t::~nosteg_steg_t()
{
}
-nosteg::~nosteg()
+steg_config_t *
+nosteg_steg_t::cfg()
{
+ return config;
}
size_t
-nosteg::transmit_room(conn_t *)
+nosteg_steg_t::transmit_room()
{
return SIZE_MAX;
}
int
-nosteg::transmit(struct evbuffer *source, conn_t *conn)
+nosteg_steg_t::transmit(struct evbuffer *source)
{
struct evbuffer *dest = conn->outbound();
@@ -79,7 +109,7 @@ nosteg::transmit(struct evbuffer *source, conn_t *conn)
}
int
-nosteg::receive(conn_t *conn, struct evbuffer *dest)
+nosteg_steg_t::receive(struct evbuffer *dest)
{
struct evbuffer *source = conn->inbound();
diff --git a/src/steg/nosteg_rr.cc b/src/steg/nosteg_rr.cc
index 70e376e..8b316bb 100644
--- a/src/steg/nosteg_rr.cc
+++ b/src/steg/nosteg_rr.cc
@@ -39,35 +39,67 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <event2/buffer.h>
namespace {
-struct nosteg_rr : steg_t
-{
- bool can_transmit : 1;
- bool did_transmit : 1;
- STEG_DECLARE_METHODS(nosteg_rr);
-};
+ struct nosteg_rr_steg_config_t : steg_config_t
+ {
+ STEG_CONFIG_DECLARE_METHODS(nosteg_rr);
+ };
+
+ struct nosteg_rr_steg_t : steg_t
+ {
+ nosteg_rr_steg_config_t *config;
+ conn_t *conn;
+
+ bool can_transmit : 1;
+ bool did_transmit : 1;
+
+ nosteg_rr_steg_t(nosteg_rr_steg_config_t *cf, conn_t *cn);
+ STEG_DECLARE_METHODS(nosteg_rr);
+ };
}
STEG_DEFINE_MODULE(nosteg_rr);
-nosteg_rr::nosteg_rr(bool is_clientside)
- : steg_t(is_clientside),
- can_transmit(is_clientside),
+nosteg_rr_steg_config_t::nosteg_rr_steg_config_t(config_t *cfg)
+ : steg_config_t(cfg)
+{
+}
+
+nosteg_rr_steg_config_t::~nosteg_rr_steg_config_t()
+{
+}
+
+steg_t *
+nosteg_rr_steg_config_t::steg_create(conn_t *conn)
+{
+ return new nosteg_rr_steg_t(this, conn);
+}
+
+nosteg_rr_steg_t::nosteg_rr_steg_t(nosteg_rr_steg_config_t *cf,
+ conn_t *cn)
+ : config(cf), conn(cn),
+ can_transmit(cf->cfg->mode != LSN_SIMPLE_SERVER),
did_transmit(false)
{
}
-nosteg_rr::~nosteg_rr()
+nosteg_rr_steg_t::~nosteg_rr_steg_t()
+{
+}
+
+steg_config_t *
+nosteg_rr_steg_t::cfg()
{
+ return config;
}
size_t
-nosteg_rr::transmit_room(conn_t *)
+nosteg_rr_steg_t::transmit_room()
{
return can_transmit ? SIZE_MAX : 0;
}
int
-nosteg_rr::transmit(struct evbuffer *source, conn_t *conn)
+nosteg_rr_steg_t::transmit(struct evbuffer *source)
{
log_assert(can_transmit);
@@ -89,12 +121,12 @@ nosteg_rr::transmit(struct evbuffer *source, conn_t *conn)
}
int
-nosteg_rr::receive(conn_t *conn, struct evbuffer *dest)
+nosteg_rr_steg_t::receive(struct evbuffer *dest)
{
struct evbuffer *source = conn->inbound();
log_debug(conn, "%s-side receiving %lu bytes",
- is_clientside ? "client" : "server",
+ config->cfg->mode == LSN_SIMPLE_SERVER ? "server" : "client",
(unsigned long)evbuffer_get_length(source));
if (evbuffer_add_buffer(dest, source)) {
@@ -102,7 +134,7 @@ nosteg_rr::receive(conn_t *conn, struct evbuffer *dest)
return -1;
}
- if (is_clientside) {
+ if (config->cfg->mode != LSN_SIMPLE_SERVER) {
conn->expect_close();
} else if (!did_transmit) {
can_transmit = true;
1
0
20 Jul '12
commit d64fb4c98988346538013981343fbec3c959661a
Author: Zack Weinberg <zackw(a)panix.com>
Date: Thu Mar 29 19:19:04 2012 -0700
Make HTTP-steg 'peername' per-connection.
---
src/audit-globals.sh | 2 --
src/steg/http.cc | 28 ++++++++++++----------------
2 files changed, 12 insertions(+), 18 deletions(-)
diff --git a/src/audit-globals.sh b/src/audit-globals.sh
index 1768640..3c21643 100644
--- a/src/audit-globals.sh
+++ b/src/audit-globals.sh
@@ -46,8 +46,6 @@ sed '
/^crypt init_crypto()::initialized$/d
# These are grandfathered; they need to be removed.
- /^steg\/http has_peer_name$/d
- /^steg\/http peername$/d
/^steg\/payloads payload_count$/d
/^steg\/payloads payload_hdrs$/d
/^steg\/payloads payloads$/d
diff --git a/src/steg/http.cc b/src/steg/http.cc
index 05ab940..1ee4254 100644
--- a/src/steg/http.cc
+++ b/src/steg/http.cc
@@ -54,12 +54,9 @@ int
http_server_receive(steg_t *s, conn_t *conn, struct evbuffer *dest, struct evbuffer* source);
int
-lookup_peer_name_from_ip(char* p_ip, char* p_name);
+lookup_peer_name_from_ip(const char* p_ip, char* p_name);
-static int has_peer_name = 0;
-static char peername[512];
-
namespace {
struct http_steg_config_t : steg_config_t
{
@@ -72,6 +69,7 @@ namespace {
{
http_steg_config_t *config;
conn_t *conn;
+ char peer_dnsname[512];
bool have_transmitted : 1;
bool have_received : 1;
@@ -161,6 +159,8 @@ http_steg_t::http_steg_t(http_steg_config_t *cf, conn_t *cn)
: config(cf), conn(cn),
have_transmitted(false), have_received(false)
{
+ memset(peer_dnsname, 0, sizeof peer_dnsname);
+
if (config->is_clientside)
load_payloads("traces/client.out");
else {
@@ -243,7 +243,7 @@ http_steg_t::transmit_room()
int
-lookup_peer_name_from_ip(char* p_ip, char* p_name) {
+lookup_peer_name_from_ip(const char* p_ip, char* p_name) {
struct addrinfo* ailist;
struct addrinfo* aip;
struct addrinfo hint;
@@ -330,9 +330,8 @@ http_client_cookie_transmit (http_steg_t *s, struct evbuffer *source,
}
buf[payload_len] = 0;
- if (has_peer_name == 0 && lookup_peer_name_from_ip((char*) conn->peername, peername))
- has_peer_name = 1;
-
+ if (s->peer_dnsname[0] == '\0')
+ lookup_peer_name_from_ip(conn->peername, s->peer_dnsname);
bzero(data2, sbuflen*4);
E.encode((char*) data, sbuflen, (char*) data2);
@@ -370,8 +369,8 @@ http_client_cookie_transmit (http_steg_t *s, struct evbuffer *source,
goto err;
}
- rval = evbuffer_add(dest, peername, strlen(peername));
- if (rval) {
+ rval = evbuffer_add(dest, s->peer_dnsname, strlen(s->peer_dnsname));
+ if (rval) {
log_warn("error adding peername field\n");
goto err;
}
@@ -515,11 +514,8 @@ http_client_uri_transmit (http_steg_t *s,
int len =0;
char buf[10000];
-
- if (has_peer_name == 0 && lookup_peer_name_from_ip((char*) conn->peername, peername))
- has_peer_name = 1;
-
-
+ if (s->peer_dnsname[0] == '\0')
+ lookup_peer_name_from_ip(conn->peername, s->peer_dnsname);
nv = evbuffer_peek(source, slen, NULL, NULL, 0);
iv = (evbuffer_iovec *)xzalloc(sizeof(struct evbuffer_iovec) * nv);
@@ -560,7 +556,7 @@ http_client_uri_transmit (http_steg_t *s,
if (evbuffer_add(dest, outbuf, datalen) || // add uri field
evbuffer_add(dest, "HTTP/1.1\r\nHost: ", 19) ||
- evbuffer_add(dest, peername, strlen(peername)) ||
+ evbuffer_add(dest, s->peer_dnsname, strlen(s->peer_dnsname)) ||
evbuffer_add(dest, strstr(buf, "\r\n"), len - (unsigned int) (strstr(buf, "\r\n") - buf)) || // add everything but first line
evbuffer_add(dest, "\r\n", 2)) {
log_debug("error ***********************");
1
0
[stegotorus/master] Candidate fixes for bugs exposed by running the automated tests on HTTP steg. Not 100% working yet.
by zwol@torproject.org 20 Jul '12
by zwol@torproject.org 20 Jul '12
20 Jul '12
commit eb200a8333b4cbb4b239b2fcfbaeeb3874c298ac
Author: Zack Weinberg <zackw(a)panix.com>
Date: Sun Apr 1 11:34:27 2012 -0700
Candidate fixes for bugs exposed by running the automated tests on HTTP steg. Not 100% working yet.
---
src/network.cc | 8 ++-
src/protocol/chop.cc | 120 ++++++++++++++++++++++++++-----------------------
src/steg/jsSteg.cc | 4 +-
src/steg/payloads.cc | 12 ++---
src/test/test_tl.py | 9 +++-
5 files changed, 81 insertions(+), 72 deletions(-)
diff --git a/src/network.cc b/src/network.cc
index 7eac64d..55944fe 100644
--- a/src/network.cc
+++ b/src/network.cc
@@ -444,12 +444,14 @@ downstream_flush_cb(struct bufferevent *bev, void *arg)
{
conn_t *conn = (conn_t *)arg;
size_t remain = evbuffer_get_length(bufferevent_get_output(bev));
- log_debug(conn, "%lu bytes still to transmit%s%s",
+ log_debug(conn, "%lu bytes still to transmit%s%s%s",
(unsigned long)remain,
conn->connected ? "" : " (not connected)",
- conn->flushing ? "" : " (not flushing)");
+ conn->flushing ? "" : " (not flushing)",
+ conn->circuit() ? "" : " (no circuit)");
- if (remain == 0 && conn->flushing && conn->connected) {
+ if (remain == 0 && ((conn->flushing && conn->connected)
+ || !conn->circuit())) {
bufferevent_disable(bev, EV_WRITE);
if (bufferevent_get_enabled(bev)) {
log_debug(conn, "sending EOF downstream");
diff --git a/src/protocol/chop.cc b/src/protocol/chop.cc
index 27e03ab..a46d0ac 100644
--- a/src/protocol/chop.cc
+++ b/src/protocol/chop.cc
@@ -667,46 +667,49 @@ chop_circuit_t::send()
{
circuit_disarm_flush_timer(this);
- if (downstreams.empty()) {
- // We have no connections, but we must send. If we're the client,
- // reopen our outbound connections; the on-connection event will
- // bring us back here. If we're the server, we have to just
- // twiddle our thumbs and hope the client reconnects.
- log_debug(this, "no downstream connections");
- if (config->mode != LSN_SIMPLE_SERVER)
- circuit_reopen_downstreams(this);
- else
- circuit_arm_axe_timer(this, axe_interval());
- return 0;
- }
-
struct evbuffer *xmit_pending = bufferevent_get_input(up_buffer);
size_t avail = evbuffer_get_length(xmit_pending);
size_t avail0 = avail;
- // Send at least one block, even if there is no real data to send.
- do {
- log_debug(this, "%lu bytes to send", (unsigned long)avail);
- size_t blocksize;
- chop_conn_t *target = pick_connection(avail, &blocksize);
- if (!target) {
- // this is not an error; it can happen e.g. when the server has
- // something to send immediately and the client hasn't spoken yet
- log_debug(this, "no target connection available");
- break;
- }
+ if (downstreams.empty()) {
+ log_debug(this, "no downstream connections");
+ } else {
+ // Send at least one block, even if there is no real data to send.
+ do {
+ log_debug(this, "%lu bytes to send", (unsigned long)avail);
+ size_t blocksize;
+ chop_conn_t *target = pick_connection(avail, &blocksize);
+ if (!target) {
+ // this is not an error; it can happen e.g. when the server has
+ // something to send immediately and the client hasn't spoken yet
+ log_debug(this, "no target connection available");
+ break;
+ }
- if (send_targeted(target, blocksize))
- return -1;
+ if (send_targeted(target, blocksize))
+ return -1;
- avail = evbuffer_get_length(xmit_pending);
- } while (avail > 0);
+ avail = evbuffer_get_length(xmit_pending);
+ } while (avail > 0);
+ }
- if (avail0 > avail) // we transmitted some real data
- dead_cycles = 0;
- else {
+ if (avail0 == avail) { // no forward progress
dead_cycles++;
log_debug(this, "%u dead cycles", dead_cycles);
+
+ // If there was real data and we didn't make any progress on it,
+ // or if there are no downstream connections at all, and we're the
+ // client, try opening new connections. If we're the server, we
+ // have to just twiddle our thumbs and hope the client does that.
+ // Note that due to the sliding window of receive blocks, there is
+ // a hard upper limit of 127 outstanding connections (that is,
+ // half the receive window).
+ if ((avail0 > 0 && downstreams.size() < 127) || downstreams.empty()) {
+ if (config->mode != LSN_SIMPLE_SERVER)
+ circuit_reopen_downstreams(this);
+ else
+ circuit_arm_axe_timer(this, axe_interval());
+ }
}
return check_for_eof();
@@ -843,6 +846,10 @@ chop_circuit_t::send_targeted(chop_conn_t *conn, size_t d, size_t p, opcode_t f,
send_seq++;
if (f == op_FIN)
sent_fin = true;
+ if ((f == op_DAT || f == op_FIN) && d > 0)
+ // We are making forward progress if we are _either_ sending or
+ // receiving data.
+ dead_cycles = 0;
return 0;
}
@@ -868,34 +875,32 @@ chop_circuit_t::pick_connection(size_t desired, size_t *blocksize)
for (unordered_set<chop_conn_t *>::iterator i = downstreams.begin();
i != downstreams.end(); i++) {
chop_conn_t *conn = *i;
- // We can only use candidates that have a steg target already.
- if (conn->steg) {
- // Find the connections whose transmit rooms are closest to the
- // desired transmission length from both directions.
- size_t room = conn->steg->transmit_room();
+ if (!conn->steg) {
+ log_debug(conn, "offers 0 bytes (no steg)");
+ continue;
+ }
- if (room <= MIN_BLOCK_SIZE)
- room = 0;
+ size_t room = conn->steg->transmit_room();
- if (room > MAX_BLOCK_SIZE)
- room = MAX_BLOCK_SIZE;
+ if (room <= MIN_BLOCK_SIZE)
+ room = 0;
- log_debug(conn, "offers %lu bytes (%s)", (unsigned long)room,
- conn->steg->cfg()->name());
+ if (room > MAX_BLOCK_SIZE)
+ room = MAX_BLOCK_SIZE;
- if (room >= desired) {
- if (room < minabove) {
- minabove = room;
- targabove = conn;
- }
- } else {
- if (room > maxbelow) {
- maxbelow = room;
- targbelow = conn;
- }
+ log_debug(conn, "offers %lu bytes (%s)", (unsigned long)room,
+ conn->steg->cfg()->name());
+
+ if (room >= desired) {
+ if (room < minabove) {
+ minabove = room;
+ targabove = conn;
}
} else {
- log_debug(conn, "offers 0 bytes (no steg)");
+ if (room > maxbelow) {
+ maxbelow = room;
+ targbelow = conn;
+ }
}
}
@@ -943,6 +948,9 @@ chop_circuit_t::process_queue()
log_info(this, "protocol error: data after FIN");
pending_error = true;
} else {
+ // We are making forward progress if we are _either_ sending or
+ // receiving data.
+ dead_cycles = 0;
if (evbuffer_add_buffer(bufferevent_get_output(up_buffer),
blk.data)) {
log_warn(this, "buffer transfer failure");
@@ -989,8 +997,6 @@ chop_circuit_t::process_queue()
}
log_debug(this, "processed %u blocks", count);
- if (count > 0)
- dead_cycles = 0;
if (sent_error)
return -1;
@@ -1318,8 +1324,10 @@ chop_conn_t::send()
// comes in for a stale circuit.
if (upstream) {
log_debug(this, "must send");
- if (upstream->send_targeted(this))
+ if (upstream->send_targeted(this)) {
+ upstream->drop_downstream(this);
conn_do_flush(this);
+ }
} else {
log_debug(this, "must send (no upstream)");
diff --git a/src/steg/jsSteg.cc b/src/steg/jsSteg.cc
index 60893ef..06d31e4 100644
--- a/src/steg/jsSteg.cc
+++ b/src/steg/jsSteg.cc
@@ -778,11 +778,9 @@ http_server_JS_transmit (payloads& pl, struct evbuffer *source, conn_t *conn,
free(iv);
- log_debug("SERVER encoded data in hex string (len %d):", datalen);
+ //log_debug("SERVER encoded data in hex string (len %d):", datalen);
// buf_dump((unsigned char*)data, datalen, stderr);
-
-
if (get_payload(pl, content_type, datalen, &jsTemplate, &jsLen) == 1) {
log_debug("SERVER found the applicable HTTP response template with size %d", jsLen);
} else {
diff --git a/src/steg/payloads.cc b/src/steg/payloads.cc
index d9546d2..8a766c5 100644
--- a/src/steg/payloads.cc
+++ b/src/steg/payloads.cc
@@ -1158,10 +1158,7 @@ int init_JS_payload_pool(payloads& pl, int len, int type, int minCapacity) {
}
}
-
pl.max_JS_capacity = maxPayloadCap;
-
-
pl.initTypePayload[contentType] = 1;
pl.typePayloadCount[contentType] = cnt;
log_debug("init_payload_pool: typePayloadCount for contentType %d = %d",
@@ -1243,10 +1240,8 @@ int init_HTML_payload_pool(payloads& pl, int len, int type, int minCapacity) {
}
}
-
pl.max_HTML_capacity = maxPayloadCap;
-
-
+ pl.initTypePayload[contentType] = 1;
pl.typePayloadCount[contentType] = cnt;
log_debug("init_payload_pool: typePayloadCount for contentType %d = %d",
contentType, pl.typePayloadCount[contentType]);
@@ -1436,8 +1431,9 @@ int get_next_payload (payloads& pl, int contentType, char** buf,
int get_payload (payloads& pl, int contentType, int cap, char** buf, int* size) {
int r, i, cnt, found = 0, numCandidate = 0, first, best, current;
- log_debug("get_payload: contentType = %d, initTypePayload = %d, typePayloadCount = %d",
- contentType, pl.initTypePayload[contentType], pl.typePayloadCount[contentType]);
+ log_debug("contentType = %d, initTypePayload = %d, typePayloadCount = %d",
+ contentType, pl.initTypePayload[contentType],
+ pl.typePayloadCount[contentType]);
if (contentType <= 0 ||
contentType >= MAX_CONTENT_TYPE ||
diff --git a/src/test/test_tl.py b/src/test/test_tl.py
index 9987c7d..eb61f31 100644
--- a/src/test/test_tl.py
+++ b/src/test/test_tl.py
@@ -87,8 +87,13 @@ class TimelineTest(object):
# "127.0.0.1:5010","embed",
# ))
- # NOTE: 'http' steg presently cannot be tested using this system
- # because the trace pools are process-global rather than per-listener.
+ def test_http(self):
+ self.doTest("chop",
+ ("chop", "server", "127.0.0.1:5001",
+ "127.0.0.1:5010","http","127.0.0.1:5011","http",
+ "chop", "client", "127.0.0.1:4999",
+ "127.0.0.1:5010","http","127.0.0.1:5011","http",
+ ))
# Synthesize TimelineTest+TestCase subclasses for every 'tl_*' file in
# the test directory.
1
0
commit 00d4889e52789fdce2bbe376b932392df6929d55
Author: Steven Cheung <steven.cheung(a)sri.com>
Date: Mon Apr 2 12:15:29 2012 -0700
removed a noisy debug statement
---
src/steg/http.cc | 6 +++++-
src/steg/payloads.cc | 4 +---
2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/src/steg/http.cc b/src/steg/http.cc
index a4fd790..a41afb8 100644
--- a/src/steg/http.cc
+++ b/src/steg/http.cc
@@ -236,7 +236,11 @@ http_steg_t::transmit_room(size_t pref, size_t lo, size_t hi)
}
}
- log_assert(hi >= lo);
+ if (hi < lo)
+ log_abort("hi<lo: client=%d type=%d hi=%ld lo=%ld",
+ config->is_clientside, type,
+ (unsigned long)hi, (unsigned long)lo);
+
return clamp(pref + rng_range_geom(hi - lo, 8), lo, hi);
}
diff --git a/src/steg/payloads.cc b/src/steg/payloads.cc
index 8a766c5..f5f35b8 100644
--- a/src/steg/payloads.cc
+++ b/src/steg/payloads.cc
@@ -1050,17 +1050,15 @@ unsigned int capacityPDF (char* buf, int len) {
while (bp < (buf+len)) {
streamStart = strInBinary("stream", 6, bp, (buf+len)-bp);
- // streamStart = strstr(bp, "stream");
if (streamStart == NULL) break;
bp = streamStart+6;
streamEnd = strInBinary("endstream", 9, bp, (buf+len)-bp);
- // streamEnd = strstr(bp, "endstream");
if (streamEnd == NULL) break;
// count the number of char between streamStart+6 and streamEnd
size = streamEnd - (streamStart+6) - 2; // 2 for \r\n before streamEnd
if (size > 0) {
cnt = cnt + size;
- log_debug("capacity of pdf increase by %d", size);
+ // log_debug("capacity of pdf increase by %d", size);
}
bp += 9;
}
1
0
[stegotorus/master] Make 'embed' testable with test_tl (removing globals).
by zwol@torproject.org 20 Jul '12
by zwol@torproject.org 20 Jul '12
20 Jul '12
commit 7d121a79b8acbaf1f42807266bac91da1774edd0
Author: Zack Weinberg <zackw(a)panix.com>
Date: Thu Mar 29 18:54:28 2012 -0700
Make 'embed' testable with test_tl (removing globals).
It still doesn't *work*, but now we have a chance of pinning down why.
One bug flushed out of chop.cc already.
---
Makefile.am | 1 +
src/audit-globals.sh | 3 -
src/protocol/chop.cc | 4 +-
src/steg/embed.cc | 101 ++++++++++++++++++++++---------------------------
src/test/test_tl.py | 10 ++++-
5 files changed, 57 insertions(+), 62 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index 377e37f..6ba1b51 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -131,6 +131,7 @@ check-local:
$(AM_V_at) ./unittests
if INTEGRATION_TESTS
@echo --- Integration tests ---
+ [ -e traces ] || ln -s $(srcdir)/traces .
$(AM_V_at) $(PYTHON) -m unittest discover -s $(srcdir)/src/test -p 'test_*.py' -v
else
@echo !!! Integration tests skipped !!!
diff --git a/src/audit-globals.sh b/src/audit-globals.sh
index 99739b3..1768640 100644
--- a/src/audit-globals.sh
+++ b/src/audit-globals.sh
@@ -46,9 +46,6 @@ sed '
/^crypt init_crypto()::initialized$/d
# These are grandfathered; they need to be removed.
- /^steg\/embed embed_init$/d
- /^steg\/embed embed_num_traces$/d
- /^steg\/embed embed_traces$/d
/^steg\/http has_peer_name$/d
/^steg\/http peername$/d
/^steg\/payloads payload_count$/d
diff --git a/src/protocol/chop.cc b/src/protocol/chop.cc
index 06346b7..27e03ab 100644
--- a/src/protocol/chop.cc
+++ b/src/protocol/chop.cc
@@ -771,7 +771,9 @@ chop_circuit_t::send_targeted(chop_conn_t *conn, size_t blocksize)
size_t avail = evbuffer_get_length(xmit_pending);
opcode_t op = op_DAT;
- if (avail > SECTION_LEN)
+ if (avail > blocksize - MIN_BLOCK_SIZE)
+ avail = blocksize - MIN_BLOCK_SIZE;
+ else if (avail > SECTION_LEN)
avail = SECTION_LEN;
else if (upstream_eof && !sent_fin)
// this block will carry the last byte of real data to be sent in
diff --git a/src/steg/embed.cc b/src/steg/embed.cc
index 6559bf7..f24c210 100644
--- a/src/steg/embed.cc
+++ b/src/steg/embed.cc
@@ -4,32 +4,34 @@
#include "steg.h"
#include "rng.h"
+#include <errno.h>
#include <event2/buffer.h>
-#include <event2/event.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <time.h>
+#include <vector>
+
+using std::vector;
namespace {
struct trace_t {
- int num_pkt; // number of packets in trace
- short *pkt_sizes; // packet sizes (positive = client->server)
- int *pkt_times; // packet inter-arrival times
+ vector<short> pkt_sizes; // packet sizes (positive = client->server)
+ vector<int> pkt_times; // packet inter-arrival times
};
struct embed_steg_config_t : steg_config_t {
bool is_clientside;
+ vector<trace_t> traces;
STEG_CONFIG_DECLARE_METHODS(embed);
+
+ size_t get_random_trace() const;
};
struct embed_steg_t : steg_t {
embed_steg_config_t *config;
conn_t *conn;
- int cur_idx; // current trace index
+ int cur_idx; // current trace index
trace_t *cur; // current trace
- int cur_pkt; // current packet in the trace
+ int cur_pkt; // current packet in the trace
struct timeval last_pkt; // time at which last packet was sent/received
embed_steg_t(embed_steg_config_t *cf, conn_t *cn);
@@ -46,10 +48,6 @@ namespace {
STEG_DEFINE_MODULE(embed);
-static int embed_init = 0; // whether traces are initialized
-static int embed_num_traces; // number of traces
-static trace_t *embed_traces; // global array of all traces
-
static int
millis_since(struct timeval *last)
{
@@ -66,6 +64,32 @@ embed_steg_config_t::embed_steg_config_t(config_t *cfg)
: steg_config_t(cfg),
is_clientside(cfg->mode != LSN_SIMPLE_SERVER)
{
+ // read in traces to use for connections
+ FILE *trace_file = fopen("traces/embed.txt", "r");
+ if (!trace_file)
+ log_abort("opening traces/embed.txt: %s", strerror(errno));
+
+ int num_traces;
+ if (fscanf(trace_file, "%d", &num_traces) < 1)
+ log_abort("couldn't read number of traces");
+
+ traces.resize(num_traces);
+
+ for (vector<trace_t>::iterator p = traces.begin(); p != traces.end(); ++p) {
+ int num_pkt;
+ if (fscanf(trace_file, "%d", &num_pkt) < 1)
+ log_abort("couldn't read number of packets in trace %ld",
+ p - traces.begin());
+
+ p->pkt_sizes.resize(num_pkt);
+ p->pkt_times.resize(num_pkt);
+ for (int i = 0; i < num_pkt; i++)
+ if (fscanf(trace_file, "%hd %d", &p->pkt_sizes[i], &p->pkt_times[i]) < 1)
+ log_abort("couldn't read trace entry %ld/%d",
+ p - traces.begin(), i);
+ }
+
+ log_debug("read %d traces", num_traces);
}
embed_steg_config_t::~embed_steg_config_t()
@@ -78,50 +102,17 @@ embed_steg_config_t::steg_create(conn_t *conn)
return new embed_steg_t(this, conn);
}
-static void
-init_embed_traces()
-{
- // read in traces to use for connections
- FILE *trace_file = fopen("traces/embed.txt", "r");
- if (fscanf(trace_file, "%d", &embed_num_traces) < 1) {
- log_abort("couldn't read number of traces to use -- exiting");
- exit(1);
- }
- embed_traces = (trace_t *)xmalloc(sizeof(trace_t) * embed_num_traces);
- for (int i = 0; i < embed_num_traces; i++) {
- int num_pkt;
- if (fscanf(trace_file, "%d", &num_pkt) < 1) {
- log_abort("couldn't read number of packets to use -- exiting");
- exit(1);
- }
- embed_traces[i].num_pkt = num_pkt;
- embed_traces[i].pkt_sizes = (short *)xmalloc(sizeof(short) * num_pkt);
- embed_traces[i].pkt_times = (int *)xmalloc(sizeof(int) * num_pkt);
- for (int j = 0; j < embed_traces[i].num_pkt; j++) {
- if (fscanf(trace_file, "%hd %d",
- &embed_traces[i].pkt_sizes[j],
- &embed_traces[i].pkt_times[j]) < 1) {
- log_abort("couldn't read numbers of packet size and times to use -- exiting");
- exit(1);
- }
- }
- }
- log_debug("read %d traces to use", embed_num_traces);
-
- embed_init = 1;
-}
-
-static int
-get_random_trace()
+size_t
+embed_steg_config_t::get_random_trace() const
{
- return rng_int(embed_num_traces);
+ return rng_int(traces.size());
}
bool
embed_steg_t::advance_packet()
{
cur_pkt++;
- return cur_pkt == cur->num_pkt;
+ return cur_pkt == int(cur->pkt_sizes.size());
}
short
@@ -146,18 +137,16 @@ bool
embed_steg_t::is_finished()
{
if (cur_idx == -1) return true;
- return cur_pkt >= cur->num_pkt;
+ return cur_pkt >= int(cur->pkt_sizes.size());
}
embed_steg_t::embed_steg_t(embed_steg_config_t *cf, conn_t *cn)
: config(cf), conn(cn)
{
- if (!embed_init) init_embed_traces();
-
cur_idx = -1;
if (config->is_clientside) {
- cur_idx = get_random_trace();
- cur = &embed_traces[cur_idx];
+ cur_idx = config->get_random_trace();
+ cur = &config->traces[cur_idx];
cur_pkt = 0;
}
gettimeofday(&last_pkt, NULL);
@@ -243,7 +232,7 @@ embed_steg_t::receive(struct evbuffer *dest)
// if we are receiving the first packet of the trace, read the index
if (cur_idx == -1) {
if (evbuffer_remove(source, &cur_idx, 4) != 4) return -1;
- cur = &embed_traces[cur_idx];
+ cur = &config->traces[cur_idx];
cur_pkt = 0;
pkt_size += 4;
diff --git a/src/test/test_tl.py b/src/test/test_tl.py
index 6d632f8..9987c7d 100644
--- a/src/test/test_tl.py
+++ b/src/test/test_tl.py
@@ -78,8 +78,14 @@ class TimelineTest(object):
"127.0.0.1:5010","nosteg_rr","127.0.0.1:5011","nosteg_rr",
))
- # NOTE: 'embed' steg presently cannot be tested using this system
- # because it runs out of trace data before any of the tests complete.
+ # buggy, disabled
+ #def test_embed(self):
+ # self.doTest("chop",
+ # ("chop", "server", "127.0.0.1:5001",
+ # "127.0.0.1:5010","embed",
+ # "chop", "client", "127.0.0.1:4999",
+ # "127.0.0.1:5010","embed",
+ # ))
# NOTE: 'http' steg presently cannot be tested using this system
# because the trace pools are process-global rather than per-listener.
1
0
[stegotorus/master] Make payload data per-steg configuration. It *should* now be possible to
by zwol@torproject.org 20 Jul '12
by zwol@torproject.org 20 Jul '12
20 Jul '12
commit b9452572f1dfdb6473f3f6308a99c5723a842238
Author: Zack Weinberg <zackw(a)panix.com>
Date: Thu Mar 29 19:49:00 2012 -0700
Make payload data per-steg configuration. It *should* now be possible to
run the automated tests on HTTP steg.
---
src/steg/http.cc | 41 +++++----
src/steg/jsSteg.cc | 12 ++-
src/steg/jsSteg.h | 3 +-
src/steg/payloads.cc | 248 +++++++++++++++++++-------------------------------
src/steg/payloads.h | 34 +++++--
src/steg/pdfSteg.cc | 9 +-
src/steg/pdfSteg.h | 4 +-
src/steg/swfSteg.cc | 15 +--
src/steg/swfSteg.h | 10 +--
9 files changed, 166 insertions(+), 210 deletions(-)
diff --git a/src/steg/http.cc b/src/steg/http.cc
index 1ee4254..77ea859 100644
--- a/src/steg/http.cc
+++ b/src/steg/http.cc
@@ -61,6 +61,7 @@ namespace {
struct http_steg_config_t : steg_config_t
{
bool is_clientside : 1;
+ payloads pl;
STEG_CONFIG_DECLARE_METHODS(http);
};
@@ -86,6 +87,17 @@ http_steg_config_t::http_steg_config_t(config_t *cfg)
: steg_config_t(cfg),
is_clientside(cfg->mode != LSN_SIMPLE_SERVER)
{
+
+ if (is_clientside)
+ load_payloads(this->pl, "traces/client.out");
+ else {
+ load_payloads(this->pl, "traces/server.out");
+ init_JS_payload_pool(this->pl, HTTP_MSG_BUF_SIZE, TYPE_HTTP_RESPONSE, JS_MIN_AVAIL_SIZE);
+ // init_JS_payload_pool(this, HTTP_MSG_BUF_SIZE, TYPE_HTTP_RESPONSE, JS_MIN_AVAIL_SIZE, HTTP_CONTENT_HTML);
+ init_HTML_payload_pool(this->pl, HTTP_MSG_BUF_SIZE, TYPE_HTTP_RESPONSE, HTML_MIN_AVAIL_SIZE);
+ init_PDF_payload_pool(this->pl, HTTP_MSG_BUF_SIZE, TYPE_HTTP_RESPONSE, PDF_MIN_AVAIL_SIZE);
+ init_SWF_payload_pool(this->pl, HTTP_MSG_BUF_SIZE, TYPE_HTTP_RESPONSE, 0);
+ }
}
http_steg_config_t::~http_steg_config_t()
@@ -160,17 +172,6 @@ http_steg_t::http_steg_t(http_steg_config_t *cf, conn_t *cn)
have_transmitted(false), have_received(false)
{
memset(peer_dnsname, 0, sizeof peer_dnsname);
-
- if (config->is_clientside)
- load_payloads("traces/client.out");
- else {
- load_payloads("traces/server.out");
- init_JS_payload_pool(HTTP_MSG_BUF_SIZE, TYPE_HTTP_RESPONSE, JS_MIN_AVAIL_SIZE);
- // init_JS_payload_pool(HTTP_MSG_BUF_SIZE, TYPE_HTTP_RESPONSE, JS_MIN_AVAIL_SIZE, HTTP_CONTENT_HTML);
- init_HTML_payload_pool(HTTP_MSG_BUF_SIZE, TYPE_HTTP_RESPONSE, HTML_MIN_AVAIL_SIZE);
- init_PDF_payload_pool(HTTP_MSG_BUF_SIZE, TYPE_HTTP_RESPONSE, PDF_MIN_AVAIL_SIZE);
- init_SWF_payload_pool(HTTP_MSG_BUF_SIZE, TYPE_HTTP_RESPONSE, 0);
- }
}
http_steg_t::~http_steg_t()
@@ -207,7 +208,7 @@ http_steg_t::transmit_room()
return 1024;
case HTTP_CONTENT_JAVASCRIPT:
- mjc = get_max_JS_capacity() / 2;
+ mjc = config->pl.max_JS_capacity / 2;
if (mjc > 1024) {
// it should be 1024 + ...., but seems like we need to be a little bit smaller (chopper bug?)
int rval = 512 + rand()%(mjc - 1024);
@@ -218,7 +219,7 @@ http_steg_t::transmit_room()
exit(-1);
case HTTP_CONTENT_HTML:
- mjc = get_max_HTML_capacity() / 2;
+ mjc = config->pl.max_HTML_capacity / 2;
if (mjc > 1024) {
// it should be 1024 + ...., but seems like we need to be a little bit smaller (chopper bug?)
int rval = 512 + rand()%(mjc - 1024);
@@ -323,7 +324,8 @@ http_client_cookie_transmit (http_steg_t *s, struct evbuffer *source,
// retry up to 10 times
while (!payload_len) {
- payload_len = find_client_payload(buf, bufsize, TYPE_HTTP_REQUEST);
+ payload_len = find_client_payload(s->config->pl, buf, bufsize,
+ TYPE_HTTP_REQUEST);
if (cnt++ == 10) {
goto err;
}
@@ -547,7 +549,8 @@ http_client_uri_transmit (http_steg_t *s,
// retry up to 10 times
while (!len) {
- len = find_client_payload(buf, sizeof(buf), TYPE_HTTP_REQUEST);
+ len = find_client_payload(s->config->pl, buf, sizeof(buf),
+ TYPE_HTTP_REQUEST);
if (cnt++ == 10) return -1;
}
@@ -617,19 +620,19 @@ http_steg_t::transmit(struct evbuffer *source)
switch(type) {
case HTTP_CONTENT_SWF:
- rval = http_server_SWF_transmit(this, source, conn);
+ rval = http_server_SWF_transmit(this->config->pl, source, conn);
break;
case HTTP_CONTENT_JAVASCRIPT:
- rval = http_server_JS_transmit(this, source, conn, HTTP_CONTENT_JAVASCRIPT);
+ rval = http_server_JS_transmit(this->config->pl, source, conn, HTTP_CONTENT_JAVASCRIPT);
break;
case HTTP_CONTENT_HTML:
- rval = http_server_JS_transmit(this, source, conn, HTTP_CONTENT_HTML);
+ rval = http_server_JS_transmit(this->config->pl, source, conn, HTTP_CONTENT_HTML);
break;
case HTTP_CONTENT_PDF:
- rval = http_server_PDF_transmit(this, source, conn);
+ rval = http_server_PDF_transmit(this->config->pl, source, conn);
break;
}
diff --git a/src/steg/jsSteg.cc b/src/steg/jsSteg.cc
index 335b78e..60893ef 100644
--- a/src/steg/jsSteg.cc
+++ b/src/steg/jsSteg.cc
@@ -706,8 +706,10 @@ int testDecode2(char *inBuf, char *outBuf,
}
-int
-http_server_JS_transmit (steg_t*, struct evbuffer *source, conn_t *conn, unsigned int content_type) {
+int
+http_server_JS_transmit (payloads& pl, struct evbuffer *source, conn_t *conn,
+ unsigned int content_type)
+{
struct evbuffer_iovec *iv;
int nv;
@@ -742,9 +744,9 @@ http_server_JS_transmit (steg_t*, struct evbuffer *source, conn_t *conn, unsigne
}
if (content_type == HTTP_CONTENT_JAVASCRIPT) {
- mjs = get_max_JS_capacity();
+ mjs = pl.max_JS_capacity;
} else if (content_type == HTTP_CONTENT_HTML) {
- mjs = get_max_HTML_capacity();
+ mjs = pl.max_HTML_capacity;
}
if (mjs <= 0) {
@@ -781,7 +783,7 @@ http_server_JS_transmit (steg_t*, struct evbuffer *source, conn_t *conn, unsigne
- if (get_payload(content_type, datalen, &jsTemplate, &jsLen) == 1) {
+ if (get_payload(pl, content_type, datalen, &jsTemplate, &jsLen) == 1) {
log_debug("SERVER found the applicable HTTP response template with size %d", jsLen);
} else {
log_warn("SERVER couldn't find the applicable HTTP response template");
diff --git a/src/steg/jsSteg.h b/src/steg/jsSteg.h
index 8a351cc..709ceb0 100644
--- a/src/steg/jsSteg.h
+++ b/src/steg/jsSteg.h
@@ -18,6 +18,7 @@
// controlling content gzipping for jsSteg
#define JS_GZIP_RESP 1
+struct payloads;
int encodeHTTPBody(char *data, char *jTemplate, char *jData,unsigned int dlen,
unsigned int jtlen, unsigned int jdlen, int mode);
@@ -62,7 +63,7 @@ int testDecode2(char *inBuf, char *outBuf,
int
-http_server_JS_transmit (steg_t* s, struct evbuffer *source, conn_t *conn, unsigned int content_type);
+http_server_JS_transmit (payloads& pl, struct evbuffer *source, conn_t *conn, unsigned int content_type);
int
http_handle_client_JS_receive(steg_t *s, conn_t *conn, struct evbuffer *dest, struct evbuffer* source);
diff --git a/src/steg/payloads.cc b/src/steg/payloads.cc
index c7e2638..d9546d2 100644
--- a/src/steg/payloads.cc
+++ b/src/steg/payloads.cc
@@ -2,38 +2,6 @@
#include "payloads.h"
#include "swfSteg.h"
-
-/* These variables below are write-once, hence they should be race-safe */
-
-static int initTypePayload[MAX_CONTENT_TYPE];
-static int typePayloadCount[MAX_CONTENT_TYPE];
-static int typePayload[MAX_CONTENT_TYPE][MAX_PAYLOADS];
-static int typePayloadCap[MAX_CONTENT_TYPE][MAX_PAYLOADS];
-
-
-static unsigned int max_JS_capacity = 0;
-static unsigned int max_HTML_capacity = 0;
-static unsigned int max_PDF_capacity = 0;
-
-static pentry_header payload_hdrs[MAX_PAYLOADS];
-static char* payloads[MAX_PAYLOADS];
-static int payload_count = 0;
-
-
-unsigned int get_max_JS_capacity() {
- return max_JS_capacity;
-}
-
-unsigned int get_max_HTML_capacity() {
- return max_HTML_capacity;
-}
-
-unsigned int get_max_PDF_capacity() {
- return max_PDF_capacity;
-}
-
-
-
/*
* fixContentLen corrects the Content-Length for an HTTP msg that
* has been ungzipped, and removes the "Content-Encoding: gzip"
@@ -208,7 +176,8 @@ log_debug("new: hdrLen = %d, bodyLen = %d, payloadLen = %d", hdrLen, bodyLen, hd
return -1;
}
-void load_payloads(const char* fname) {
+void load_payloads(payloads& pl, const char* fname)
+{
FILE* f;
char buf[HTTP_MSG_BUF_SIZE];
char buf2[HTTP_MSG_BUF_SIZE];
@@ -216,9 +185,6 @@ void load_payloads(const char* fname) {
int pentryLen;
int r;
- if (payload_count != 0)
- return;
-
srand(time(NULL));
f = fopen(fname, "r");
if (f == NULL) {
@@ -226,9 +192,10 @@ void load_payloads(const char* fname) {
exit(1);
}
- bzero(payload_hdrs, sizeof(payload_hdrs));
+ bzero(pl.payload_hdrs, sizeof(pl.payload_hdrs));
+ pl.payload_count = 0;
- while (payload_count < MAX_PAYLOADS) {
+ while (pl.payload_count < MAX_PAYLOADS) {
if (fread(&pentry, 1, sizeof(pentry_header), f) < sizeof(pentry_header)) {
break;
@@ -270,22 +237,21 @@ void load_payloads(const char* fname) {
// }
if (r < 0) {
- payloads[payload_count] = (char *)xmalloc(pentry.length + 1);
- memcpy(payloads[payload_count], buf, pentry.length);
+ pl.payloads[pl.payload_count] = (char *)xmalloc(pentry.length + 1);
+ memcpy(pl.payloads[pl.payload_count], buf, pentry.length);
} else {
pentry.length = r;
- payloads[payload_count] = (char *)xmalloc(pentry.length + 1);
- memcpy(payloads[payload_count], buf2, pentry.length);
+ pl.payloads[pl.payload_count] = (char *)xmalloc(pentry.length + 1);
+ memcpy(pl.payloads[pl.payload_count], buf2, pentry.length);
}
- payload_hdrs[payload_count] = pentry;
- payloads[payload_count][pentry.length] = 0;
- payload_count++;
+ pl.payload_hdrs[pl.payload_count] = pentry;
+ pl.payloads[pl.payload_count][pentry.length] = 0;
+ pl.payload_count++;
} // while
-#ifdef DEBUG
- printf("loading payload count = %d\n", payload_count);
-#endif
-
+
+ log_debug("loaded %d payloads from %s\n", pl.payload_count, fname);
+
fclose(f);
}
@@ -561,18 +527,16 @@ find_uri_type(char* buf) {
-unsigned int find_client_payload(char* buf, int len, int type) {
- int r = rand() % payload_count;
+unsigned int find_client_payload(payloads& pl, char* buf, int len, int type) {
+ int r = rand() % pl.payload_count;
int cnt = 0;
char* inbuf;
-#ifdef DEBUG
- fprintf(stderr, "TRYING payload %d \n", r);
-#endif
+ log_debug("trying payload %d", r);
while (1) {
- pentry_header* p = &payload_hdrs[r];
+ pentry_header* p = &pl.payload_hdrs[r];
if (p->ptype == type) {
- inbuf = payloads[r];
+ inbuf = pl.payloads[r];
if (find_uri_type(inbuf, p->length) != HTTP_CONTENT_SWF &&
find_uri_type(inbuf, p->length) != HTTP_CONTENT_HTML &&
find_uri_type(inbuf, p->length) != HTTP_CONTENT_JAVASCRIPT &&
@@ -588,12 +552,11 @@ unsigned int find_client_payload(char* buf, int len, int type) {
break;
}
next:
- r = (r+1) % payload_count;
-
+ r = (r+1) % pl.payload_count;
// no matching payloads...
- if (cnt++ == payload_count) {
- fprintf(stderr, "NO MATCHING PAYLOADS... \n");
+ if (cnt++ == pl.payload_count) {
+ log_warn("no matching payloads");
return 0;
}
}
@@ -602,7 +565,6 @@ unsigned int find_client_payload(char* buf, int len, int type) {
// clean up the buffer...
return parse_client_headers(inbuf, buf, len);
-
}
@@ -1132,10 +1094,9 @@ unsigned int capacityPDF (char* buf, int len) {
-int init_JS_payload_pool(int len, int type, int minCapacity) {
-
+int init_JS_payload_pool(payloads& pl, int len, int type, int minCapacity) {
// stat for usable payload
- int minPayloadSize = 0, maxPayloadSize = 0;
+ int minPayloadSize = 0, maxPayloadSize = 0;
int sumPayloadSize = 0;
int minPayloadCap = 0, maxPayloadCap = 0;
int sumPayloadCap = 0;
@@ -1149,40 +1110,35 @@ int init_JS_payload_pool(int len, int type, int minCapacity) {
int cap;
int mode;
-
-
- if (payload_count == 0) {
+ if (pl.payload_count == 0) {
log_debug("payload_count == 0; forgot to run load_payloads()?\n");
return 0;
}
-
- if (initTypePayload[contentType] != 0) return 1; // init is done already
-
- for (r = 0; r < payload_count; r++) {
- p = &payload_hdrs[r];
+ for (r = 0; r < pl.payload_count; r++) {
+ p = &pl.payload_hdrs[r];
if (p->ptype != type || p->length > len) {
continue;
}
- msgbuf = payloads[r];
+ msgbuf = pl.payloads[r];
mode = has_eligible_HTTP_content(msgbuf, p->length, HTTP_CONTENT_JAVASCRIPT);
if (mode == CONTENT_JAVASCRIPT) {
-
+
cap = capacityJS3(msgbuf, p->length, mode);
- if (cap < JS_DELIMITER_SIZE)
+ if (cap < JS_DELIMITER_SIZE)
continue;
cap = (cap - JS_DELIMITER_SIZE)/2;
if (cap > minCapacity) {
- typePayloadCap[contentType][cnt] = cap; // (cap-JS_DELIMITER_SIZE)/2;
+ pl.typePayloadCap[contentType][cnt] = cap; // (cap-JS_DELIMITER_SIZE)/2;
// because we use 2 hex char to encode every data byte, the available
// capacity for encoding data is divided by 2
- typePayload[contentType][cnt] = r;
+ pl.typePayload[contentType][cnt] = r;
cnt++;
-
+
// update stat
if (cnt == 1) {
minPayloadSize = p->length; maxPayloadSize = p->length;
@@ -1203,13 +1159,13 @@ int init_JS_payload_pool(int len, int type, int minCapacity) {
}
- max_JS_capacity = maxPayloadCap;
+ pl.max_JS_capacity = maxPayloadCap;
- initTypePayload[contentType] = 1;
- typePayloadCount[contentType] = cnt;
+ pl.initTypePayload[contentType] = 1;
+ pl.typePayloadCount[contentType] = cnt;
log_debug("init_payload_pool: typePayloadCount for contentType %d = %d",
- contentType, typePayloadCount[contentType]);
+ contentType, pl.typePayloadCount[contentType]);
log_debug("minPayloadSize = %d", minPayloadSize);
log_debug("maxPayloadSize = %d", maxPayloadSize);
log_debug("avgPayloadSize = %f", (float)sumPayloadSize/(float)cnt);
@@ -1220,7 +1176,7 @@ int init_JS_payload_pool(int len, int type, int minCapacity) {
}
-int init_HTML_payload_pool(int len, int type, int minCapacity) {
+int init_HTML_payload_pool(payloads& pl, int len, int type, int minCapacity) {
// stat for usable payload
int minPayloadSize = 0, maxPayloadSize = 0;
@@ -1239,21 +1195,18 @@ int init_HTML_payload_pool(int len, int type, int minCapacity) {
- if (payload_count == 0) {
+ if (pl.payload_count == 0) {
log_debug("payload_count == 0; forgot to run load_payloads()?\n");
return 0;
}
-
- if (initTypePayload[contentType] != 0) return 1; // init is done already
-
- for (r = 0; r < payload_count; r++) {
- p = &payload_hdrs[r];
+ for (r = 0; r < pl.payload_count; r++) {
+ p = &pl.payload_hdrs[r];
if (p->ptype != type || p->length > len) {
continue;
}
- msgbuf = payloads[r];
+ msgbuf = pl.payloads[r];
mode = has_eligible_HTTP_content(msgbuf, p->length, HTTP_CONTENT_HTML);
if (mode == CONTENT_HTML_JAVASCRIPT) {
@@ -1265,10 +1218,10 @@ int init_HTML_payload_pool(int len, int type, int minCapacity) {
cap = (cap - JS_DELIMITER_SIZE)/2;
if (cap > minCapacity) {
- typePayloadCap[contentType][cnt] = cap; // (cap-JS_DELIMITER_SIZE)/2;
+ pl.typePayloadCap[contentType][cnt] = cap; // (cap-JS_DELIMITER_SIZE)/2;
// because we use 2 hex char to encode every data byte, the available
// capacity for encoding data is divided by 2
- typePayload[contentType][cnt] = r;
+ pl.typePayload[contentType][cnt] = r;
cnt++;
// update stat
@@ -1291,13 +1244,12 @@ int init_HTML_payload_pool(int len, int type, int minCapacity) {
}
- max_HTML_capacity = maxPayloadCap;
+ pl.max_HTML_capacity = maxPayloadCap;
- initTypePayload[contentType] = 1;
- typePayloadCount[contentType] = cnt;
+ pl.typePayloadCount[contentType] = cnt;
log_debug("init_payload_pool: typePayloadCount for contentType %d = %d",
- contentType, typePayloadCount[contentType]);
+ contentType, pl.typePayloadCount[contentType]);
log_debug("minPayloadSize = %d", minPayloadSize);
log_debug("maxPayloadSize = %d", maxPayloadSize);
log_debug("avgPayloadSize = %f", (float)sumPayloadSize/(float)cnt);
@@ -1307,14 +1259,9 @@ int init_HTML_payload_pool(int len, int type, int minCapacity) {
return 1;
}
-
-
-
-
-
-
-
-int init_PDF_payload_pool(int len, int type, int minCapacity) {
+int
+init_PDF_payload_pool(payloads& pl, int len, int type, int minCapacity)
+{
// stat for usable payload
int minPayloadSize = 0, maxPayloadSize = 0;
@@ -1331,21 +1278,18 @@ int init_PDF_payload_pool(int len, int type, int minCapacity) {
unsigned int contentType = HTTP_CONTENT_PDF;
- if (payload_count == 0) {
+ if (pl.payload_count == 0) {
fprintf(stderr, "payload_count == 0; forgot to run load_payloads()?\n");
return 0;
}
-
- if (initTypePayload[contentType] != 0) return 1; // init is done already
-
- for (r = 0; r < payload_count; r++) {
- p = &payload_hdrs[r];
+ for (r = 0; r < pl.payload_count; r++) {
+ p = &pl.payload_hdrs[r];
if (p->ptype != type || p->length > len) {
continue;
}
- msgbuf = payloads[r];
+ msgbuf = pl.payloads[r];
mode = has_eligible_HTTP_content(msgbuf, p->length, HTTP_CONTENT_PDF);
if (mode > 0) {
@@ -1356,8 +1300,8 @@ int init_PDF_payload_pool(int len, int type, int minCapacity) {
log_debug("got pdf (index %d) with capacity %d", r, cap);
if (cap > minCapacity) {
log_debug("pdf (index %d) greater than mincapacity %d", cnt, minCapacity);
- typePayloadCap[contentType][cnt] = (cap-PDF_DELIMITER_SIZE)/2;
- typePayload[contentType][cnt] = r;
+ pl.typePayloadCap[contentType][cnt] = (cap-PDF_DELIMITER_SIZE)/2;
+ pl.typePayload[contentType][cnt] = r;
cnt++;
// update stat
@@ -1376,11 +1320,11 @@ int init_PDF_payload_pool(int len, int type, int minCapacity) {
}
}
- max_PDF_capacity = maxPayloadCap;
- initTypePayload[contentType] = 1;
- typePayloadCount[contentType] = cnt;
+ pl.max_PDF_capacity = maxPayloadCap;
+ pl.initTypePayload[contentType] = 1;
+ pl.typePayloadCount[contentType] = cnt;
log_debug("init_payload_pool: typePayloadCount for contentType %d = %d",
- contentType, typePayloadCount[contentType]);
+ contentType, pl.typePayloadCount[contentType]);
log_debug("minPayloadSize = %d", minPayloadSize);
log_debug("maxPayloadSize = %d", maxPayloadSize);
log_debug("avgPayloadSize = %f", (float)sumPayloadSize/(float)cnt);
@@ -1390,12 +1334,9 @@ int init_PDF_payload_pool(int len, int type, int minCapacity) {
return 1;
}
-
-
-
-
-int init_SWF_payload_pool(int len, int type, int /*unused */) {
-
+int
+init_SWF_payload_pool(payloads& pl, int len, int type, int /*unused */)
+{
// stat for usable payload
int minPayloadSize = 0, maxPayloadSize = 0;
int sumPayloadSize = 0;
@@ -1408,26 +1349,23 @@ int init_SWF_payload_pool(int len, int type, int /*unused */) {
unsigned int contentType = HTTP_CONTENT_SWF;
- if (payload_count == 0) {
+ if (pl.payload_count == 0) {
fprintf(stderr, "payload_count == 0; forgot to run load_payloads()?\n");
return 0;
}
-
- if (initTypePayload[contentType] != 0) return 1; // init is done already
-
- for (r = 0; r < payload_count; r++) {
- p = &payload_hdrs[r];
+ for (r = 0; r < pl.payload_count; r++) {
+ p = &pl.payload_hdrs[r];
if (p->ptype != type || p->length > len) {
continue;
}
- msgbuf = payloads[r];
+ msgbuf = pl.payloads[r];
// found a payload corr to the specified contentType
mode = has_eligible_HTTP_content(msgbuf, p->length, HTTP_CONTENT_SWF);
if (mode > 0) {
- typePayload[contentType][cnt] = r;
+ pl.typePayload[contentType][cnt] = r;
cnt++;
// update stat
if (cnt == 1) {
@@ -1444,10 +1382,10 @@ int init_SWF_payload_pool(int len, int type, int /*unused */) {
}
}
- initTypePayload[contentType] = 1;
- typePayloadCount[contentType] = cnt;
+ pl.initTypePayload[contentType] = 1;
+ pl.typePayloadCount[contentType] = cnt;
log_debug("init_payload_pool: typePayloadCount for contentType %d = %d",
- contentType, typePayloadCount[contentType]);
+ contentType, pl.typePayloadCount[contentType]);
log_debug("minPayloadSize = %d", minPayloadSize);
log_debug("maxPayloadSize = %d", maxPayloadSize);
log_debug("avgPayloadSize = %f", (float)sumPayloadSize/(float)cnt);
@@ -1462,27 +1400,29 @@ int init_SWF_payload_pool(int len, int type, int /*unused */) {
-int get_next_payload (int contentType, char** buf, int* size, int* cap) {
+int get_next_payload (payloads& pl, int contentType, char** buf,
+ int* size, int* cap)
+{
int r;
log_debug("get_next_payload: contentType = %d, initTypePayload = %d, typePayloadCount = %d",
- contentType, initTypePayload[contentType], typePayloadCount[contentType]);
+ contentType, pl.initTypePayload[contentType], pl.typePayloadCount[contentType]);
if (contentType <= 0 ||
contentType >= MAX_CONTENT_TYPE ||
- initTypePayload[contentType] == 0 ||
- typePayloadCount[contentType] == 0)
+ pl.initTypePayload[contentType] == 0 ||
+ pl.typePayloadCount[contentType] == 0)
return 0;
- r = rand() % typePayloadCount[contentType];
+ r = rand() % pl.typePayloadCount[contentType];
// int r = 1;
// log_debug("SERVER: *** always choose the same payload ***");
log_debug("SERVER: picked payload with index %d", r);
- *buf = payloads[typePayload[contentType][r]];
- *size = payload_hdrs[typePayload[contentType][r]].length;
- *cap = typePayloadCap[contentType][r];
+ *buf = pl.payloads[pl.typePayload[contentType][r]];
+ *size = pl.payload_hdrs[pl.typePayload[contentType][r]].length;
+ *cap = pl.typePayloadCap[contentType][r];
return 1;
}
@@ -1493,20 +1433,20 @@ int get_next_payload (int contentType, char** buf, int* size, int* cap) {
-int get_payload (int contentType, int cap, char** buf, int* size) {
+int get_payload (payloads& pl, int contentType, int cap, char** buf, int* size) {
int r, i, cnt, found = 0, numCandidate = 0, first, best, current;
log_debug("get_payload: contentType = %d, initTypePayload = %d, typePayloadCount = %d",
- contentType, initTypePayload[contentType], typePayloadCount[contentType]);
+ contentType, pl.initTypePayload[contentType], pl.typePayloadCount[contentType]);
if (contentType <= 0 ||
contentType >= MAX_CONTENT_TYPE ||
- initTypePayload[contentType] == 0 ||
- typePayloadCount[contentType] == 0)
+ pl.initTypePayload[contentType] == 0 ||
+ pl.typePayloadCount[contentType] == 0)
return 0;
- cnt = typePayloadCount[contentType];
+ cnt = pl.typePayloadCount[contentType];
r = rand() % cnt;
best = r;
first = r;
@@ -1518,12 +1458,12 @@ int get_payload (int contentType, int cap, char** buf, int* size) {
i++;
current = (r+i)%cnt;
- if (typePayloadCap[contentType][current] <= cap)
+ if (pl.typePayloadCap[contentType][current] <= cap)
continue;
if (found) {
- if (payload_hdrs[typePayload[contentType][best]].length >
- payload_hdrs[typePayload[contentType][current]].length)
+ if (pl.payload_hdrs[pl.typePayload[contentType][best]].length >
+ pl.payload_hdrs[pl.typePayload[contentType][current]].length)
best = current;
} else {
first = current;
@@ -1535,11 +1475,11 @@ int get_payload (int contentType, int cap, char** buf, int* size) {
if (found) {
log_debug("first payload size=%d, best payload size=%d, num candidate=%d\n",
- payload_hdrs[typePayload[contentType][first]].length,
- payload_hdrs[typePayload[contentType][best]].length,
+ pl.payload_hdrs[pl.typePayload[contentType][first]].length,
+ pl.payload_hdrs[pl.typePayload[contentType][best]].length,
numCandidate);
- *buf = payloads[typePayload[contentType][best]];
- *size = payload_hdrs[typePayload[contentType][best]].length;
+ *buf = pl.payloads[pl.typePayload[contentType][best]];
+ *size = pl.payload_hdrs[pl.typePayload[contentType][best]].length;
return 1;
} else {
return 0;
diff --git a/src/steg/payloads.h b/src/steg/payloads.h
index 34e7edc..05a7307 100644
--- a/src/steg/payloads.h
+++ b/src/steg/payloads.h
@@ -120,22 +120,36 @@ typedef struct service_state {
int dir;
}state;
+struct payloads {
+ int initTypePayload[MAX_CONTENT_TYPE];
+ int typePayloadCount[MAX_CONTENT_TYPE];
+ int typePayload[MAX_CONTENT_TYPE][MAX_PAYLOADS];
+ int typePayloadCap[MAX_CONTENT_TYPE][MAX_PAYLOADS];
-#define HTTP_MSG_BUF_SIZE 100000
+ unsigned int max_JS_capacity;
+ unsigned int max_HTML_capacity;
+ unsigned int max_PDF_capacity;
+
+ pentry_header payload_hdrs[MAX_PAYLOADS];
+ char* payloads[MAX_PAYLOADS];
+ int payload_count;
+};
-void load_payloads(const char* fname);
-unsigned int find_client_payload(char* buf, int len, int type);
-unsigned int find_server_payload(char** buf, int len, int type, int contentType);
-int init_JS_payload_pool(int len, int type, int minCapacity);
-int init_SWF_payload_pool(int len, int type, int minCapacity);
-int init_PDF_payload_pool(int len, int type,int minCapacity);
-int init_HTML_payload_pool(int len, int type, int minCapacity);
+#define HTTP_MSG_BUF_SIZE 100000
+
+void load_payloads(payloads& pl, const char* fname);
+unsigned int find_client_payload(payloads& pl, char* buf, int len, int type);
+unsigned int find_server_payload(payloads& pl, char** buf, int len, int type, int contentType);
+int init_JS_payload_pool(payloads& pl, int len, int type, int minCapacity);
+int init_SWF_payload_pool(payloads& pl, int len, int type, int minCapacity);
+int init_PDF_payload_pool(payloads& pl, int len, int type,int minCapacity);
+int init_HTML_payload_pool(payloads& pl, int len, int type, int minCapacity);
-int get_next_payload (int contentType, char** buf, int* size, int* cap);
-int get_payload (int contentType, int cap, char** buf, int* size);
+int get_next_payload (payloads& pl, int contentType, char** buf, int* size, int* cap);
+int get_payload (payloads& pl, int contentType, int cap, char** buf, int* size);
int has_eligible_HTTP_content (char* buf, int len, int type);
int fixContentLen (char* payload, int payloadLen, char *buf, int bufLen);
diff --git a/src/steg/pdfSteg.cc b/src/steg/pdfSteg.cc
index 504c3d4..c67b0f8 100644
--- a/src/steg/pdfSteg.cc
+++ b/src/steg/pdfSteg.cc
@@ -296,7 +296,10 @@ pdfUnwrap (char *data, unsigned int dlen,
-int http_server_PDF_transmit (steg_t*, struct evbuffer *source, conn_t *conn) {
+int
+http_server_PDF_transmit (payloads& pl, struct evbuffer *source,
+ conn_t *conn)
+{
struct evbuffer *dest = conn->outbound();
size_t sbuflen = evbuffer_get_length(source);
@@ -341,7 +344,7 @@ int http_server_PDF_transmit (steg_t*, struct evbuffer *source, conn_t *conn) {
log_debug("SERVER sbuflen = %d; cnt = %d", (int)sbuflen, cnt);
- mpdf = get_max_PDF_capacity();
+ mpdf = pl.max_PDF_capacity;
if (mpdf <= 0) {
log_warn("SERVER ERROR: No pdfTemplate found\n");
@@ -354,7 +357,7 @@ int http_server_PDF_transmit (steg_t*, struct evbuffer *source, conn_t *conn) {
return -1;
}
- if (get_payload(HTTP_CONTENT_PDF, sbuflen, &pdfTemplate, &pdfTemplateSize) == 1) {
+ if (get_payload(pl, HTTP_CONTENT_PDF, sbuflen, &pdfTemplate, &pdfTemplateSize) == 1) {
log_debug("SERVER found the next HTTP response template with size %d", pdfTemplateSize);
} else {
log_warn("SERVER couldn't find the next HTTP response template");
diff --git a/src/steg/pdfSteg.h b/src/steg/pdfSteg.h
index 3c7a4bd..3d494e1 100644
--- a/src/steg/pdfSteg.h
+++ b/src/steg/pdfSteg.h
@@ -10,7 +10,7 @@
#include "steg.h"
#include <event2/buffer.h>
-
+struct payloads;
#define PDF_DELIMITER '?'
#define PDF_DELIMITER2 '.'
@@ -21,7 +21,7 @@ int pdfUnwrap (char *data, unsigned int dlen, char *outbuf, unsigned int outbufs
int addDelimiter(char *inbuf, int inbuflen, char *outbuf, int outbuflen, const char delimiter1, const char delimiter2);
int removeDelimiter(char *inbuf, int inbuflen, char *outbuf, int outbuflen, const char delimiter1, int* endFlag, int* escape);
-int http_server_PDF_transmit (steg_t* s, struct evbuffer *source, conn_t *conn);
+int http_server_PDF_transmit (payloads& pl, struct evbuffer *source, conn_t *conn);
int
http_handle_client_PDF_receive(steg_t *s, conn_t *conn, struct evbuffer *dest, struct evbuffer* source);
diff --git a/src/steg/swfSteg.cc b/src/steg/swfSteg.cc
index d7c35ec..cd371f3 100644
--- a/src/steg/swfSteg.cc
+++ b/src/steg/swfSteg.cc
@@ -20,7 +20,7 @@ static const char http_response_1[] =
unsigned int
-swf_wrap(char* inbuf, int in_len, char* outbuf, int out_sz) {
+swf_wrap(payloads& pl, char* inbuf, int in_len, char* outbuf, int out_sz) {
char* swf;
int in_swf_len;
@@ -38,7 +38,7 @@ swf_wrap(char* inbuf, int in_len, char* outbuf, int out_sz) {
- if (!get_payload(HTTP_CONTENT_SWF, -1, &resp, &resp_len)) {
+ if (!get_payload(pl, HTTP_CONTENT_SWF, -1, &resp, &resp_len)) {
log_warn("swfsteg: no suitable payload found\n");
return -1;
}
@@ -118,12 +118,9 @@ swf_unwrap(char* inbuf, int in_len, char* outbuf, int out_sz) {
return inf_len - SWF_SAVE_HEADER_LEN - SWF_SAVE_FOOTER_LEN;
}
-
-
-
-
-int
-http_server_SWF_transmit (steg_t*, struct evbuffer *source, conn_t *conn) {
+int
+http_server_SWF_transmit(payloads& pl, struct evbuffer *source, conn_t *conn)
+{
struct evbuffer *dest = conn->outbound();
size_t sbuflen = evbuffer_get_length(source);
@@ -141,7 +138,7 @@ http_server_SWF_transmit (steg_t*, struct evbuffer *source, conn_t *conn) {
outbuf = (char *)xmalloc(4*sbuflen + SWF_SAVE_FOOTER_LEN + SWF_SAVE_HEADER_LEN + 512);
// fprintf(stderr, "server wrapping swf len %d\n", (int) sbuflen);
- outlen = swf_wrap(inbuf, sbuflen, outbuf, 4*sbuflen + SWF_SAVE_FOOTER_LEN + SWF_SAVE_HEADER_LEN + 512);
+ outlen = swf_wrap(pl, inbuf, sbuflen, outbuf, 4*sbuflen + SWF_SAVE_FOOTER_LEN + SWF_SAVE_HEADER_LEN + 512);
if (outlen < 0) {
log_warn("swf_wrap failed\n");
diff --git a/src/steg/swfSteg.h b/src/steg/swfSteg.h
index 7be5207..712a3a3 100644
--- a/src/steg/swfSteg.h
+++ b/src/steg/swfSteg.h
@@ -14,24 +14,20 @@
#include <event2/buffer.h>
#include <stdio.h>
-
-
-
-
-
+struct payloads;
#define SWF_SAVE_HEADER_LEN 1500
#define SWF_SAVE_FOOTER_LEN 1500
unsigned int
-swf_wrap(char* inbuf, int in_len, char* outbuf, int out_sz);
+swf_wrap(payloads& pl, char* inbuf, int in_len, char* outbuf, int out_sz);
unsigned int
swf_unwrap(char* inbuf, int in_len, char* outbuf, int out_sz);
int
-http_server_SWF_transmit (steg_t* s, struct evbuffer *source, conn_t *conn);
+http_server_SWF_transmit(payloads& pl, struct evbuffer *source, conn_t *conn);
int
1
0
[stegotorus/master] transmit_room() now takes 3 arguments and the chopper produces exactly what is asked for. As a side-effect this made HTTP reliable under automated test.
by zwol@torproject.org 20 Jul '12
by zwol@torproject.org 20 Jul '12
20 Jul '12
commit 9a6de8ce32c36d04fd96e48194230dfcdc1132cf
Author: Zack Weinberg <zackw(a)panix.com>
Date: Sun Apr 1 14:23:17 2012 -0700
transmit_room() now takes 3 arguments and the chopper produces exactly what is asked for. As a side-effect this made HTTP reliable under automated test.
---
src/protocol/chop.cc | 106 ++++++++++++++++++++++++++---------------
src/steg.h | 66 +++++++++++++++-----------
src/steg/embed.cc | 5 ++-
src/steg/http.cc | 124 ++++++++++++++++++++-----------------------------
src/steg/nosteg.cc | 4 +-
src/steg/nosteg_rr.cc | 4 +-
6 files changed, 165 insertions(+), 144 deletions(-)
diff --git a/src/protocol/chop.cc b/src/protocol/chop.cc
index a46d0ac..ad8ac9f 100644
--- a/src/protocol/chop.cc
+++ b/src/protocol/chop.cc
@@ -73,6 +73,8 @@ const size_t SECTION_LEN = UINT16_MAX;
const size_t MIN_BLOCK_SIZE = HEADER_LEN + TRAILER_LEN;
const size_t MAX_BLOCK_SIZE = MIN_BLOCK_SIZE + SECTION_LEN*2;
+const size_t HANDSHAKE_LEN = sizeof(uint32_t);
+
enum opcode_t
{
op_DAT = 0, // Pass data section along to upstream
@@ -729,16 +731,18 @@ chop_circuit_t::send_special(opcode_t f, struct evbuffer *payload)
size_t blocksize;
log_assert(d <= SECTION_LEN);
chop_conn_t *conn = pick_connection(d, &blocksize);
+ size_t lo = MIN_BLOCK_SIZE + ((conn && !conn->sent_handshake)
+ ? HANDSHAKE_LEN : 0);
- if (!conn || (blocksize - MIN_BLOCK_SIZE < d)) {
+ if (!conn || (blocksize - lo < d)) {
log_warn("no usable connection for special block "
"(opcode %02x, need %lu bytes, have %lu)",
- (unsigned int)f, (unsigned long)(d + MIN_BLOCK_SIZE),
+ (unsigned int)f, (unsigned long)(d + lo),
(unsigned long)blocksize);
return -1;
}
- return send_targeted(conn, d, (blocksize - MIN_BLOCK_SIZE) - d, f, payload);
+ return send_targeted(conn, d, (blocksize - lo) - d, f, payload);
}
int
@@ -749,33 +753,47 @@ chop_circuit_t::send_targeted(chop_conn_t *conn)
avail = SECTION_LEN;
avail += MIN_BLOCK_SIZE;
- size_t room = conn->steg->transmit_room();
- if (room < MIN_BLOCK_SIZE) {
- log_warn(conn, "send() called without enough transmit room "
- "(have %lu, need %lu)", (unsigned long)room,
- (unsigned long)MIN_BLOCK_SIZE);
- return -1;
+ // If we have any data to transmit, ensure we do not send a block
+ // that contains no data at all.
+ size_t lo = MIN_BLOCK_SIZE + (avail == MIN_BLOCK_SIZE ? 0 : 1);
+
+ // If this connection has not yet sent a handshake, it will need to.
+ size_t hi = MAX_BLOCK_SIZE;
+ if (!conn->sent_handshake) {
+ lo += HANDSHAKE_LEN;
+ hi += HANDSHAKE_LEN;
+ avail += HANDSHAKE_LEN;
}
- log_debug(conn, "offers %lu bytes (%s)", (unsigned long)room,
- conn->steg->cfg()->name());
- if (room < avail)
- avail = room;
+ size_t room = conn->steg->transmit_room(avail, lo, hi);
+ if (room == 0)
+ log_abort(conn, "must send but cannot send");
+ if (room < lo || room >= hi)
+ log_abort(conn, "steg size request (%lu) out of range [%lu, %lu]",
+ (unsigned long)room, (unsigned long)lo, (unsigned long)hi);
- return send_targeted(conn, avail);
+ log_debug(conn, "requests %lu bytes (%s)", (unsigned long)room,
+ conn->steg->cfg()->name());
+
+ return send_targeted(conn, room);
}
int
chop_circuit_t::send_targeted(chop_conn_t *conn, size_t blocksize)
{
- log_assert(blocksize >= MIN_BLOCK_SIZE && blocksize <= MAX_BLOCK_SIZE);
+ size_t lo = MIN_BLOCK_SIZE, hi = MAX_BLOCK_SIZE;
+ if (!conn->sent_handshake) {
+ lo += HANDSHAKE_LEN;
+ hi += HANDSHAKE_LEN;
+ }
+ log_assert(blocksize >= lo && blocksize <= hi);
struct evbuffer *xmit_pending = bufferevent_get_input(up_buffer);
size_t avail = evbuffer_get_length(xmit_pending);
opcode_t op = op_DAT;
- if (avail > blocksize - MIN_BLOCK_SIZE)
- avail = blocksize - MIN_BLOCK_SIZE;
+ if (avail > blocksize - lo)
+ avail = blocksize - lo;
else if (avail > SECTION_LEN)
avail = SECTION_LEN;
else if (upstream_eof && !sent_fin)
@@ -783,7 +801,7 @@ chop_circuit_t::send_targeted(chop_conn_t *conn, size_t blocksize)
// this direction; mark it as such
op = op_FIN;
- return send_targeted(conn, avail, (blocksize - MIN_BLOCK_SIZE) - avail,
+ return send_targeted(conn, avail, (blocksize - lo) - avail,
op, xmit_pending);
}
@@ -868,6 +886,10 @@ chop_circuit_t::pick_connection(size_t desired, size_t *blocksize)
desired += MIN_BLOCK_SIZE;
+ // If we have any data to transmit, ensure we do not send a block
+ // that contains no data at all.
+ size_t lo = MIN_BLOCK_SIZE + (desired == MIN_BLOCK_SIZE ? 0 : 1);
+
log_debug(this, "target block size %lu bytes", (unsigned long)desired);
// Find the best fit for the desired transmission from all the
@@ -880,18 +902,25 @@ chop_circuit_t::pick_connection(size_t desired, size_t *blocksize)
continue;
}
- size_t room = conn->steg->transmit_room();
-
- if (room <= MIN_BLOCK_SIZE)
- room = 0;
+ size_t shake = conn->sent_handshake ? 0 : HANDSHAKE_LEN;
+ size_t room = conn->steg->transmit_room(desired + shake, lo + shake,
+ MAX_BLOCK_SIZE + shake);
+ if (room == 0) {
+ log_debug(conn, "offers 0 bytes (%s)",
+ conn->steg->cfg()->name());
+ continue;
+ }
- if (room > MAX_BLOCK_SIZE)
- room = MAX_BLOCK_SIZE;
+ if (room < lo + shake || room >= MAX_BLOCK_SIZE + shake)
+ log_abort(conn, "steg size request (%lu) out of range [%lu, %lu]",
+ (unsigned long)room,
+ (unsigned long)(lo + shake),
+ (unsigned long)(MAX_BLOCK_SIZE + shake));
log_debug(conn, "offers %lu bytes (%s)", (unsigned long)room,
conn->steg->cfg()->name());
- if (room >= desired) {
+ if (room >= desired + shake) {
if (room < minabove) {
minabove = room;
targabove = conn;
@@ -915,7 +944,7 @@ chop_circuit_t::pick_connection(size_t desired, size_t *blocksize)
// their initial values, so we'll return NULL and set blocksize to 0,
// which callers know how to handle.
if (targabove) {
- *blocksize = desired;
+ *blocksize = minabove;
return targabove;
} else {
*blocksize = maxbelow;
@@ -1086,7 +1115,7 @@ chop_conn_t::send(struct evbuffer *block)
upstream ? '+' : '-',
upstream ? upstream->circuit_id : 0);
if (evbuffer_prepend(block, (void *)&upstream->circuit_id,
- sizeof(upstream->circuit_id))) {
+ HANDSHAKE_LEN)) {
log_warn(this, "failed to prepend handshake to first block");
return -1;
}
@@ -1332,29 +1361,28 @@ chop_conn_t::send()
} else {
log_debug(this, "must send (no upstream)");
- size_t room = steg->transmit_room();
- if (room < MIN_BLOCK_SIZE) {
- log_warn(this, "send() called without enough transmit room "
- "(have %lu, need %lu)", (unsigned long)room,
- (unsigned long)MIN_BLOCK_SIZE);
- conn_do_flush(this);
- return;
- }
+ size_t room = steg->transmit_room(MIN_BLOCK_SIZE, MIN_BLOCK_SIZE,
+ MAX_BLOCK_SIZE);
+ if (room < MIN_BLOCK_SIZE || room >= MAX_BLOCK_SIZE)
+ log_abort(this, "steg size request (%lu) out of range [%lu, %lu]",
+ (unsigned long)room,
+ (unsigned long)MIN_BLOCK_SIZE,
+ (unsigned long)MAX_BLOCK_SIZE);
// Since we have no upstream, we can't encrypt anything; instead,
// generate random bytes and feed them straight to steg_transmit.
struct evbuffer *chaff = evbuffer_new();
struct evbuffer_iovec v;
- if (!chaff || evbuffer_reserve_space(chaff, MIN_BLOCK_SIZE, &v, 1) != 1 ||
- v.iov_len < MIN_BLOCK_SIZE) {
+ if (!chaff || evbuffer_reserve_space(chaff, room, &v, 1) != 1 ||
+ v.iov_len < room) {
log_warn(this, "memory allocation failed");
if (chaff)
evbuffer_free(chaff);
conn_do_flush(this);
return;
}
- v.iov_len = MIN_BLOCK_SIZE;
- rng_bytes((uint8_t *)v.iov_base, MIN_BLOCK_SIZE);
+ v.iov_len = room;
+ rng_bytes((uint8_t *)v.iov_base, room);
if (evbuffer_commit_space(chaff, &v, 1)) {
log_warn(this, "evbuffer_commit_space failed");
if (chaff)
diff --git a/src/steg.h b/src/steg.h
index a044afb..ad6b829 100644
--- a/src/steg.h
+++ b/src/steg.h
@@ -52,11 +52,22 @@ struct steg_t
/** Return the steg_config_t from which this steg_t was created. */
virtual steg_config_t *cfg() = 0;
- /** Report the maximum number of bytes that could be transmitted on
- your connection at this time. You must be prepared to handle a
- subsequent request to transmit any _smaller_ number of bytes on
- this connection. */
- virtual size_t transmit_room() = 0;
+ /** The protocol using this steg module would like to transmit PREF
+ bytes on your connection. Return an adjusted number of bytes;
+ you may adjust down to indicate that you cannot transmit all of
+ the available data, or up to indicate that it should be padded.
+
+ Returning zero indicates that your connection cannot transmit at
+ all right now; if you do this, transmit() will not be called.
+ Returning any nonzero value indicates that you want to transmit
+ exactly that number of bytes. The protocol may or may not call
+ transmit() after you return a nonzero value, but if it does, it
+ will provide the number of bytes you requested.
+
+ If you return a nonzero value, it MUST be greater than or equal
+ to MIN, and less than or equal to MAX. PREF is guaranteed to be
+ in this range already. */
+ virtual size_t transmit_room(size_t pref, size_t min, size_t max) = 0;
/** Consume all of the data in SOURCE, disguise it, and write it to
the outbound buffer for your connection. Return 0 on success, -1
@@ -94,32 +105,33 @@ steg_config_t *steg_new(const char *name, config_t *cfg);
/* Macros for use in defining steg modules. */
-#define STEG_DEFINE_MODULE(mod) \
- /* new_ dispatchers */ \
- static steg_config_t *mod##_new(config_t *cfg) \
- { return new mod##_steg_config_t(cfg); } \
- \
- /* canned methods */ \
- const char *mod##_steg_config_t::name() { return #mod; } \
- \
- /* module object */ \
- extern const steg_module s_mod_##mod = { \
- #mod, mod##_new \
+#define STEG_DEFINE_MODULE(mod) \
+ /* new_ dispatchers */ \
+ static steg_config_t *mod##_new(config_t *cfg) \
+ { return new mod##_steg_config_t(cfg); } \
+ \
+ /* canned methods */ \
+ const char *mod##_steg_config_t::name() \
+ { return #mod; } \
+ \
+ /* module object */ \
+ extern const steg_module s_mod_##mod = { \
+ #mod, mod##_new \
} /* deliberate absence of semicolon */
-#define STEG_CONFIG_DECLARE_METHODS(mod) \
- mod##_steg_config_t(config_t *cfg); \
- virtual ~mod##_steg_config_t(); \
- virtual const char *name(); \
- virtual steg_t *steg_create(conn_t *conn) \
+#define STEG_CONFIG_DECLARE_METHODS(mod) \
+ mod##_steg_config_t(config_t *); \
+ virtual ~mod##_steg_config_t(); \
+ virtual const char *name(); \
+ virtual steg_t *steg_create(conn_t *) \
/* deliberate absence of semicolon */
-#define STEG_DECLARE_METHODS(mod) \
- virtual ~mod##_steg_t(); \
- virtual steg_config_t *cfg(); \
- virtual size_t transmit_room(); \
- virtual int transmit(struct evbuffer *source); \
- virtual int receive(struct evbuffer *dest) \
+#define STEG_DECLARE_METHODS(mod) \
+ virtual ~mod##_steg_t(); \
+ virtual steg_config_t *cfg(); \
+ virtual size_t transmit_room(size_t, size_t, size_t); \
+ virtual int transmit(struct evbuffer *); \
+ virtual int receive(struct evbuffer *) \
/* deliberate absence of semicolon */
#endif
diff --git a/src/steg/embed.cc b/src/steg/embed.cc
index f24c210..d301620 100644
--- a/src/steg/embed.cc
+++ b/src/steg/embed.cc
@@ -163,7 +163,7 @@ embed_steg_t::cfg()
}
size_t
-embed_steg_t::transmit_room()
+embed_steg_t::transmit_room(size_t, size_t lo, size_t hi)
{
if (is_finished() || !is_outgoing()) return 0;
@@ -173,6 +173,9 @@ embed_steg_t::transmit_room()
// 2 bytes for data length, 4 bytes for the index of a new trace
size_t room = get_pkt_size() - 2;
if (cur_pkt == 0) room -= 4;
+
+ if (room < lo) room = lo;
+ if (room > hi) room = hi;
return room;
}
diff --git a/src/steg/http.cc b/src/steg/http.cc
index 77ea859..a4fd790 100644
--- a/src/steg/http.cc
+++ b/src/steg/http.cc
@@ -36,6 +36,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "connections.h"
#include "protocol.h"
#include "steg.h"
+#include "rng.h"
+
#include "payloads.h"
#include "cookies.h"
#include "swfSteg.h"
@@ -184,64 +186,59 @@ http_steg_t::cfg()
return config;
}
-size_t
-http_steg_t::transmit_room()
+static size_t
+clamp(size_t val, size_t lo, size_t hi)
{
- unsigned int mjc;
+ if (val < lo) return lo;
+ if (val > hi) return hi;
+ return val;
+}
+size_t
+http_steg_t::transmit_room(size_t pref, size_t lo, size_t hi)
+{
if (have_transmitted)
/* can't send any more on this connection */
return 0;
-
if (config->is_clientside) {
- return (MIN_COOKIE_SIZE + rand() % (MAX_COOKIE_SIZE - MIN_COOKIE_SIZE)) / 4;
+ // MIN_COOKIE_SIZE and MAX_COOKIE_SIZE are *after* base64'ing
+ if (lo < MIN_COOKIE_SIZE*3/4)
+ lo = MIN_COOKIE_SIZE*3/4;
+
+ if (hi > MAX_COOKIE_SIZE*3/4)
+ hi = MAX_COOKIE_SIZE*3/4;
}
else {
-
if (!have_received)
return 0;
switch (type) {
-
case HTTP_CONTENT_SWF:
- return 1024;
+ if (hi >= 1024)
+ hi = 1024;
+ break;
case HTTP_CONTENT_JAVASCRIPT:
- mjc = config->pl.max_JS_capacity / 2;
- if (mjc > 1024) {
- // it should be 1024 + ...., but seems like we need to be a little bit smaller (chopper bug?)
- int rval = 512 + rand()%(mjc - 1024);
- // fprintf(stderr, "returning rval %d, mjc %d\n", rval, mjc);
- return rval;
- }
- log_warn("js capacity too small\n");
- exit(-1);
+ if (hi >= config->pl.max_JS_capacity / 2)
+ hi = config->pl.max_JS_capacity / 2;
+ break;
case HTTP_CONTENT_HTML:
- mjc = config->pl.max_HTML_capacity / 2;
- if (mjc > 1024) {
- // it should be 1024 + ...., but seems like we need to be a little bit smaller (chopper bug?)
- int rval = 512 + rand()%(mjc - 1024);
- // fprintf(stderr, "returning rval %d, mjc %d\n", rval, mjc);
- return rval;
- }
- log_warn("js capacity too small\n");
- exit(-1);
+ if (hi >= config->pl.max_HTML_capacity / 2)
+ hi = config->pl.max_HTML_capacity / 2;
+ break;
case HTTP_CONTENT_PDF:
- // return 1024 + rand()%(get_max_PDF_capacity() - 1024)
- return PDF_MIN_AVAIL_SIZE;
+ if (hi >= PDF_MIN_AVAIL_SIZE)
+ hi = PDF_MIN_AVAIL_SIZE;
+ break;
}
-
- return SIZE_MAX;
}
-}
-
-
-
-
+ log_assert(hi >= lo);
+ return clamp(pref + rng_range_geom(hi - lo, 8), lo, hi);
+}
int
lookup_peer_name_from_ip(const char* p_ip, char* p_name) {
@@ -346,7 +343,7 @@ http_client_cookie_transmit (http_steg_t *s, struct evbuffer *source,
// substitute / with _, + with ., = with - that maybe inserted anywhere in the middle
sanitize_b64(data2, len);
-
+
cookie_len = gen_b64_cookie_field(cookiebuf, data2, len);
cookiebuf[cookie_len] = 0;
@@ -356,7 +353,10 @@ http_client_cookie_transmit (http_steg_t *s, struct evbuffer *source,
log_debug("cookie generation failed\n");
return -1;
}
-
+ log_debug(conn, "cookie input %ld encoded %d final %d",
+ sbuflen, len, cookie_len);
+ log_debug(conn, "cookie encoded: %s", data2);
+ log_debug(conn, "cookie final: %s", cookiebuf);
// add uri field
rval = evbuffer_add(dest, buf, strstr(buf, "\r\n") - buf + 2);
@@ -657,28 +657,27 @@ http_server_receive(http_steg_t *s, conn_t *conn, struct evbuffer *dest, struct
char *p;
char *pend;
- char outbuf[MAX_COOKIE_SIZE];
+ char outbuf[MAX_COOKIE_SIZE * 3/2];
char outbuf2[MAX_COOKIE_SIZE];
int sofar = 0;
//int cookie_mode = 0;
if (s2.pos == -1) {
- log_debug("Did not find end of request %d", (int) evbuffer_get_length(source));
- // evbuffer_dump(source, stderr);
+ log_debug(conn, "Did not find end of request %d",
+ (int) evbuffer_get_length(source));
return RECV_INCOMPLETE;
}
- log_debug("SERVER received request header of length %d", (int)s2.pos);
+ log_debug(conn, "SERVER received request header of length %d", (int)s2.pos);
data = (char*) evbuffer_pullup(source, s2.pos+4);
if (data == NULL) {
- log_debug("SERVER evbuffer_pullup fails");
+ log_debug(conn, "SERVER evbuffer_pullup fails");
return RECV_BAD;
}
-
data[s2.pos+3] = 0;
type = find_uri_type((char *)data, s2.pos+4);
@@ -691,19 +690,14 @@ http_server_receive(http_steg_t *s, conn_t *conn, struct evbuffer *dest, struct
p = data + sizeof "GET /" -1;
pend = strstr(p, "\r\n");
-
- if (pend == NULL || (pend - p > MAX_COOKIE_SIZE)) {
- fprintf(stderr, "incorrect cookie recovery \n");
- exit(-1);
-
- }
-
-
+ log_assert(pend);
+ if (pend - p > MAX_COOKIE_SIZE * 3/2)
+ log_abort(conn, "cookie too big: %lu (max %lu)",
+ (unsigned long)(pend - p), (unsigned long)MAX_COOKIE_SIZE);
bzero(outbuf, sizeof(outbuf));
int cookielen = unwrap_b64_cookie((char*) p, (char*) outbuf, pend - p);
-
desanitize_b64(outbuf, cookielen);
outbuf[cookielen] = '\n';
bzero(outbuf2, sizeof(outbuf2));
@@ -711,25 +705,19 @@ http_server_receive(http_steg_t *s, conn_t *conn, struct evbuffer *dest, struct
base64::decoder D;
sofar = D.decode(outbuf, cookielen+1, outbuf2);
+ if (sofar <= 0)
+ log_warn(conn, "base64 decode failed\n");
- if (sofar <= 0)
- log_warn("decode failed\n");
-
-
- if (sofar >= MAX_COOKIE_SIZE) {
- log_warn("cookie buffer overflow????\n");
- exit(-1);
- }
-
+ if (sofar >= MAX_COOKIE_SIZE)
+ log_abort(conn, "cookie decode buffer overflow\n");
if (evbuffer_add(dest, outbuf2, sofar)) {
- log_debug("Failed to transfer buffer");
+ log_debug(conn, "Failed to transfer buffer");
return RECV_BAD;
}
evbuffer_drain(source, s2.pos + sizeof("\r\n\r\n") - 1);
} while (evbuffer_get_length(source));
-
s->have_received = 1;
s->type = type;
@@ -737,16 +725,6 @@ http_server_receive(http_steg_t *s, conn_t *conn, struct evbuffer *dest, struct
return RECV_GOOD;
}
-
-
-
-
-
-
-
-
-
-
int
http_steg_t::receive(struct evbuffer *dest)
{
diff --git a/src/steg/nosteg.cc b/src/steg/nosteg.cc
index df80c89..328a1d6 100644
--- a/src/steg/nosteg.cc
+++ b/src/steg/nosteg.cc
@@ -87,9 +87,9 @@ nosteg_steg_t::cfg()
}
size_t
-nosteg_steg_t::transmit_room()
+nosteg_steg_t::transmit_room(size_t pref, size_t, size_t)
{
- return SIZE_MAX;
+ return pref;
}
int
diff --git a/src/steg/nosteg_rr.cc b/src/steg/nosteg_rr.cc
index 8b316bb..adde6c8 100644
--- a/src/steg/nosteg_rr.cc
+++ b/src/steg/nosteg_rr.cc
@@ -93,9 +93,9 @@ nosteg_rr_steg_t::cfg()
}
size_t
-nosteg_rr_steg_t::transmit_room()
+nosteg_rr_steg_t::transmit_room(size_t pref, size_t, size_t)
{
- return can_transmit ? SIZE_MAX : 0;
+ return can_transmit ? pref : 0;
}
int
1
0
[stegotorus/master] Merge branch 'master' of https://git.safdef.isc.org/git/stegotorus
by zwol@torproject.org 20 Jul '12
by zwol@torproject.org 20 Jul '12
20 Jul '12
commit 092842af7faace09e0b6325f7ae40b112367c8e6
Merge: 5513c95 00d4889
Author: Zack Weinberg <zackw(a)panix.com>
Date: Wed Apr 4 18:01:44 2012 -0700
Merge branch 'master' of https://git.safdef.isc.org/git/stegotorus
src/steg/http.cc | 6 +++++-
src/steg/payloads.cc | 4 +---
2 files changed, 6 insertions(+), 4 deletions(-)
1
0
[stegotorus/master] Remove a hack from the configure script and a reference to Crypto++ from the README.
by zwol@torproject.org 20 Jul '12
by zwol@torproject.org 20 Jul '12
20 Jul '12
commit 5513c95762305224973d614cd6f4e839ef948cc3
Author: Zack Weinberg <zackw(a)panix.com>
Date: Wed Apr 4 18:01:27 2012 -0700
Remove a hack from the configure script and a reference to Crypto++ from the README.
---
README | 2 +-
configure.ac | 8 +-------
2 files changed, 2 insertions(+), 8 deletions(-)
diff --git a/README b/README
index b3b82b4..e1f45b3 100644
--- a/README
+++ b/README
@@ -1,6 +1,6 @@
This doesn't work yet.
-It requires Crypto++ 5.6.0 or later.
+It requires OpenSSL 1.0.1 or later.
It requires Libevent 2.0 or later.
diff --git a/configure.ac b/configure.ac
index 69f4150..87cb713 100644
--- a/configure.ac
+++ b/configure.ac
@@ -5,12 +5,6 @@ AC_LANG([C++])
AM_INIT_AUTOMAKE([foreign nostdinc silent-rules subdir-objects])
AM_MAINTAINER_MODE([enable])
-dnl The stock definition of AC_INCLUDES_DEFAULT performs a whole bunch
-dnl of completely unnecessary checks *even if* you override its
-dnl mostly-useless default header list at invocation time.
-dnl Replace it with a version that does nothing unless requested.
-m4_pushdef([AC_INCLUDES_DEFAULT], [$1])
-
### Programs ###
AC_PROG_CXX
@@ -64,7 +58,7 @@ LIBS="$LIBS $ws32_LIBS"
### Language features ###
-AC_CHECK_HEADERS([execinfo.h],,, [AC_INCLUDES_DEFAULT()])
+AC_CHECK_HEADERS([execinfo.h],,,[/**/])
AX_CXXFLAGS_STDCXX_11([ext])
AX_CXX_DELETE_METHOD
1
0