commit 37b973f695a47032d107291d3c91f1ec4ae9ed54 Author: Zack Weinberg zackw@cmu.edu Date: Mon Jan 16 22:37:25 2012 +0000
Various bugs in exponential backoff; split dummy/dummy_rr; remove completely unused steg constants
git-svn-id: svn+ssh://spartan.csl.sri.com/svn/private/DEFIANCE@227 a58ff0ac-194c-e011-a152-003048836090 --- Makefile.am | 3 +- src/protocol/chop.cc | 19 ++++--- src/steg.h | 48 +++++------------- src/steg/dummy.cc | 59 +++------------------- src/steg/dummy_rr.cc | 133 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/steg/embed.cc | 2 +- src/steg/http.cc | 6 +-- 7 files changed, 169 insertions(+), 101 deletions(-)
diff --git a/Makefile.am b/Makefile.am index 04df59d..32f422b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -28,7 +28,8 @@ STEGANOGRAPHERS = \ src/steg/pdfSteg.cc \ src/steg/swfSteg.cc \ src/steg/zpack.cc \ - src/steg/dummy.cc + src/steg/dummy.cc \ + src/steg/dummy_rr.cc
libstegotorus_a_SOURCES = \ src/connections.cc \ diff --git a/src/protocol/chop.cc b/src/protocol/chop.cc index b7e95fb..348f610 100644 --- a/src/protocol/chop.cc +++ b/src/protocol/chop.cc @@ -36,9 +36,9 @@ struct chop_header };
#define CHOP_WIRE_HDR_LEN (sizeof(struct chop_header)) -#define CHOP_MAX_DATA 16384 -#define CHOP_MAX_CHAFF 2048 #define CHOP_BLOCK_OVERHD (CHOP_WIRE_HDR_LEN + GCM_TAG_LEN) +#define CHOP_MAX_DATA (65535 - CHOP_BLOCK_OVERHD) +#define CHOP_MAX_CHAFF 2048
#define CHOP_F_SYN 0x0001 #define CHOP_F_FIN 0x0002 @@ -104,16 +104,18 @@ namespace { CIRCUIT_DECLARE_METHODS(chop);
uint32_t axe_interval() { - // 20*60*1000 lies between 2^20 and 2^21. - uint32_t shift = std::max(1u, std::min(20u, dead_cycles)); - uint32_t xv = std::max(1u, std::min(20u * 60 * 1000, 1u << shift)); - return rng_range_geom(30 * 60 * 1000, xv) + 5 * 1000; + // This function must always return a number which is larger than + // the maximum possible number that *our peer's* flush_interval() + // could have returned; otherwise, we might axe the connection when + // it was just that there was nothing to say for a while. + // For simplicity's sake, right now we hardwire this to be 30 minutes. + return 30 * 60 * 1000; } uint32_t flush_interval() { // 10*60*1000 lies between 2^19 and 2^20. uint32_t shift = std::max(1u, std::min(19u, dead_cycles)); uint32_t xv = std::max(1u, std::min(10u * 60 * 1000, 1u << shift)); - return rng_range_geom(20 * 60 * 1000, xv) + 1000; + return rng_range_geom(20 * 60 * 1000, xv) + 100; } };
@@ -737,14 +739,12 @@ chop_push_to_upstream(circuit_t *c) chop_reassembly_elt *ready = ckt->reassembly_queue.next; if (!ready->data || ckt->recv_offset != ready->offset) { log_debug(c, "no data pushable to upstream yet"); - ckt->dead_cycles++; return 0; }
if (!ckt->received_syn) { if (!(ready->flags & CHOP_F_SYN)) { log_debug(c, "waiting for SYN"); - ckt->dead_cycles++; return 0; } log_debug(c, "processed SYN"); @@ -1113,6 +1113,7 @@ chop_circuit_t::send() if (chop_send_chaff(this)) return -1; this->dead_cycles++; + log_debug(this, "%u dead cycles", this->dead_cycles); } else { if (chop_send_blocks(this)) return -1; diff --git a/src/steg.h b/src/steg.h index c78ffd7..1ad5f82 100644 --- a/src/steg.h +++ b/src/steg.h @@ -54,27 +54,6 @@ struct steg_module /** Name of the steganography module. Must be a valid C identifier. */ const char *name;
- /** Maximum data rate, in bytes per second, that this module can - reasonably absorb when transmitting client-to-server. */ - size_t max_c2s_rate; - - /** Maximum data rate server-to-client. */ - size_t max_s2c_rate; - - /** Maximum number of concurrent connections to any single IP address - that should be made using one instance of this module. - If this value is greater than one, the module proposes to - generate _correlated_ traffic across all concurrent connections. - Only relevant for client-to-server traffic. */ - unsigned int max_corr_conns_per_ip; - - /** Maximum number of IP addresses that should be simultaneously - connected to using one instance of this module. Again, - if this value is greater than one, the module proposes to - generate correlated traffic across all concurrent connections. - Only relevant for client-to-server traffic. */ - unsigned int max_corr_ips; - /** Detect whether the inbound traffic from CONN is disguised using the steganography this module implements. Do not consume any data from CONN's inbound buffer, regardless of success or @@ -95,20 +74,19 @@ steg_t *steg_detect(conn_t *conn);
/* Macros for use in defining steg modules. */
-#define STEG_DEFINE_MODULE(mod, csm, scm, mcci, mci) \ - /* detect and new_ dispatchers */ \ - static bool mod##_detect(conn_t *conn) \ - { return mod::detect(conn); } \ - 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, csm, scm, mcci, mci, \ - mod##_detect, mod##_new \ +#define STEG_DEFINE_MODULE(mod) \ + /* detect and new_ dispatchers */ \ + static bool mod##_detect(conn_t *conn) \ + { return mod::detect(conn); } \ + 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##_detect, mod##_new \ } /* deliberate absence of semicolon */
#define STEG_DECLARE_METHODS(mod) \ diff --git a/src/steg/dummy.cc b/src/steg/dummy.cc index 5823a69..c81b53f 100644 --- a/src/steg/dummy.cc +++ b/src/steg/dummy.cc @@ -37,28 +37,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "protocol.h" #include "steg.h" #include <event2/buffer.h> -#include <stdio.h>
#define DUMMY_PORT 3333
namespace { struct dummy : steg_t { - bool have_transmitted : 1; - bool have_received : 1; STEG_DECLARE_METHODS(dummy); }; }
-STEG_DEFINE_MODULE(dummy, - 1024, /* client-server max data rate - made up */ - 10240, /* server-client max data rate - ditto */ - 1, /* max concurrent connections per IP */ - 1); /* max concurrent IPs */ - +STEG_DEFINE_MODULE(dummy);
dummy::dummy(bool is_clientside) - : have_transmitted(false), have_received(false) { this->is_clientside = is_clientside; } @@ -79,78 +70,46 @@ dummy::detect(conn_t *conn) }
struct sockaddr_in* sin = (struct sockaddr_in*) addrs->ai_addr; - if (sin->sin_port == htons(DUMMY_PORT)) return 1;
return 0; - }
size_t dummy::transmit_room(conn_t *) { - - if (have_transmitted) - return 0; - - if (is_clientside) - return SIZE_MAX; - - if (!have_received) - return 0; - return SIZE_MAX; }
- - - - - - int dummy::transmit(struct evbuffer *source, conn_t *conn) { struct evbuffer *dest = conn_get_outbound(conn);
- fprintf(stderr, "transmitting %d\n", (int) evbuffer_get_length(source));; - + log_debug(conn, "transmitting %lu bytes", + (unsigned long)evbuffer_get_length(source));
if (evbuffer_add_buffer(dest, source)) { - fprintf(stderr, "failed to transfer buffer\n"); + log_warn(conn, "failed to transfer buffer"); + return -1; }
- - - conn_cease_transmission(conn); - this->have_transmitted = 1; return 0; - }
- - - - - int dummy::receive(conn_t *conn, struct evbuffer *dest) { struct evbuffer *source = conn_get_inbound(conn);
- - fprintf(stderr, "receiving %d\n", (int) evbuffer_get_length(source)); + log_debug(conn, "receiving %lu bytes", + (unsigned long)evbuffer_get_length(source));
if (evbuffer_add_buffer(dest, source)) { - fprintf(stderr, "failed to transfer buffer\n"); + log_warn(conn, "failed to transfer buffer"); + return -1; }
- - - - - this->have_received = 1; - conn_transmit_soon(conn, 100); return 0; } diff --git a/src/steg/dummy_rr.cc b/src/steg/dummy_rr.cc new file mode 100644 index 0000000..010b91e --- /dev/null +++ b/src/steg/dummy_rr.cc @@ -0,0 +1,133 @@ +/* Copyright (c) 2011, SRI International + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + + * Neither the names of the copyright owners nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + Contributors: Zack Weinberg, Vinod Yegneswaran + See LICENSE for other credits and copying information +*/ + +#include "util.h" +#include "connections.h" +#include "protocol.h" +#include "steg.h" +#include <event2/buffer.h> + +#define DUMMY_RR_PORT 3334 + +namespace { +struct dummy_rr : steg_t +{ + bool can_transmit : 1; + STEG_DECLARE_METHODS(dummy_rr); +}; +} + +STEG_DEFINE_MODULE(dummy_rr); + +dummy_rr::dummy_rr(bool is_clientside) +{ + this->is_clientside = is_clientside; + this->can_transmit = is_clientside; +} + +dummy_rr::~dummy_rr() +{ +} + +/** Determine whether a connection should be processed by this + steganographer. */ +bool +dummy_rr::detect(conn_t *conn) +{ + struct evutil_addrinfo *addrs = conn->cfg->get_listen_addrs(0); + if (!addrs) { + log_debug("no listen addrs\n"); + return 0; + } + + struct sockaddr_in* sin = (struct sockaddr_in*) addrs->ai_addr; + if (sin->sin_port == htons(DUMMY_RR_PORT)) + return 1; + + return 0; +} + +size_t +dummy_rr::transmit_room(conn_t *) +{ + return can_transmit ? SIZE_MAX : 0; +} + +int +dummy_rr::transmit(struct evbuffer *source, conn_t *conn) +{ + log_assert(can_transmit); + + struct evbuffer *dest = conn_get_outbound(conn); + + log_debug(conn, "transmitting %lu bytes", + (unsigned long)evbuffer_get_length(source)); + + if (evbuffer_add_buffer(dest, source)) { + log_warn(conn, "failed to transfer buffer"); + return -1; + } + + can_transmit = false; + if (is_clientside) { + conn_cease_transmission(conn); + } else { + conn_close_after_transmit(conn); + } + + return 0; +} + +int +dummy_rr::receive(conn_t *conn, struct evbuffer *dest) +{ + struct evbuffer *source = conn_get_inbound(conn); + + log_debug(conn, "receiving %lu bytes", + (unsigned long)evbuffer_get_length(source)); + + if (evbuffer_add_buffer(dest, source)) { + log_warn(conn, "failed to transfer buffer"); + return -1; + } + + if (is_clientside) { + conn_expect_close(conn); + } else { + can_transmit = true; + conn_transmit_soon(conn, 100); + } + + return 0; +} diff --git a/src/steg/embed.cc b/src/steg/embed.cc index 447d4cf..ae1a7fa 100644 --- a/src/steg/embed.cc +++ b/src/steg/embed.cc @@ -36,7 +36,7 @@ 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, 1024, 1024, 1, 1); +STEG_DEFINE_MODULE(embed);
int millis_since(struct timeval *last) { struct timeval cur; diff --git a/src/steg/http.cc b/src/steg/http.cc index 47290b0..70d5014 100644 --- a/src/steg/http.cc +++ b/src/steg/http.cc @@ -68,11 +68,7 @@ struct http : steg_t }; }
-STEG_DEFINE_MODULE(http, - 1024, /* client-server max data rate - made up */ - 10240, /* server-client max data rate - ditto */ - 1, /* max concurrent connections per IP */ - 1); /* max concurrent IPs */ +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);
tor-commits@lists.torproject.org