[tor-commits] [stegotorus/master] Split up steg_t into per-connection and per-listener state objects.

zwol at torproject.org zwol at torproject.org
Fri Jul 20 23:17:07 UTC 2012


commit 0448e1cc8aaaa5b4d71277b9738cfa5b33268212
Author: Zack Weinberg <zackw at 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;





More information about the tor-commits mailing list