[tor-commits] [obfsproxy/master] Use 'upstream' and 'downstream' for the two sides of a connection, not 'input' and 'output'.

nickm at torproject.org nickm at torproject.org
Fri Sep 9 17:08:57 UTC 2011


commit 234c332b78cccbdf05316d2d38cc9e635f37df11
Author: Zack Weinberg <zackw at panix.com>
Date:   Mon Jul 25 15:06:41 2011 -0700

    Use 'upstream' and 'downstream' for the two sides of a connection, not 'input' and 'output'.
---
 src/network.c |  195 ++++++++++++++++++++++++++++++++++-----------------------
 src/network.h |    4 +-
 2 files changed, 118 insertions(+), 81 deletions(-)

diff --git a/src/network.c b/src/network.c
index f3d09cf..9003ea9 100644
--- a/src/network.c
+++ b/src/network.c
@@ -26,6 +26,35 @@
 #include <ws2tcpip.h>  /* socklen_t */
 #endif
 
+/* Terminology used in this file:
+
+   A "side" is a bidirectional communications channel, usually backed
+   by a network socket and represented at this layer by a
+   'struct bufferevent'.
+
+   A "connection" is a _pair_ of sides, referred to as the "upstream"
+   side and the "downstream" side.  A connection is represented by a
+   'conn_t'.  The upstream side of a connection communicates in
+   cleartext with the higher-level program that wishes to make use of
+   our obfuscation service.  The downstream side commmunicates in an
+   obfuscated fashion with the remote peer that the higher-level
+   client wishes to contact.
+
+   A "listener" is a listening socket bound to a particular
+   obfuscation protocol, represented in this layer by a 'listener_t'.
+   Connecting to a listener creates one side of a connection, and
+   causes this program to initiate the other side of the connection.
+   A listener is said to be a "client" listener if connecting to it
+   creates the _upstream_ side of a connection, and a "server"
+   listener if connecting to it creates the _downstream_ side.
+
+   There are two kinds of client listeners: a "simple" client listener
+   always connects to the same remote peer every time it needs to
+   initiate a downstream connection; a "socks" client listener can be
+   told to connect to an arbitrary remote peer using the SOCKS protocol
+   (version 4 or 5).
+*/
+
 /** All our listeners. */
 static smartlist_t *listeners;
 
@@ -205,34 +234,37 @@ simple_client_listener_cb(struct evconnlistener *evcl,
 
   /* New bufferevent to wrap socket we received. */
   base = evconnlistener_get_base(lsn->listener);
-  conn->input = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE);
-  if (!conn->input)
+  conn->upstream = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE);
+  if (!conn->upstream)
     goto err;
   fd = -1; /* prevent double-close */
 
+  bufferevent_setcb(conn->upstream,
+                    upstream_read_cb, NULL, error_cb, conn);
+
+  /* Don't enable the upstream side for reading at this point; wait
+     till the downstream side is established. */
+
   /* New bufferevent to connect to the target address */
-  conn->output = bufferevent_socket_new(base, -1, BEV_OPT_CLOSE_ON_FREE);
-  if (!conn->output)
+  conn->downstream = bufferevent_socket_new(base, -1, BEV_OPT_CLOSE_ON_FREE);
+  if (!conn->downstream)
     goto err;
 
-  bufferevent_setcb(conn->input, upstream_read_cb, NULL, error_cb, conn);
-  /* don't enable the input side for reading at this point; wait till we
-     have a connection to the target */
-
-  bufferevent_setcb(conn->output,
+  bufferevent_setcb(conn->downstream,
                     downstream_read_cb, NULL, pending_conn_cb, conn);
 
   /* Queue handshake, if any, before connecting. */
-  if (proto_handshake(conn->proto, bufferevent_get_output(conn->output)) < 0)
+  if (proto_handshake(conn->proto,
+                      bufferevent_get_output(conn->downstream))<0)
     goto err;
 
   /* Launch the connect attempt. */
-  if (bufferevent_socket_connect(conn->output,
+  if (bufferevent_socket_connect(conn->downstream,
                                  lsn->proto_params->target_addr->ai_addr,
                                  lsn->proto_params->target_addr->ai_addrlen)<0)
     goto err;
 
-  bufferevent_enable(conn->output, EV_READ|EV_WRITE);
+  bufferevent_enable(conn->downstream, EV_READ|EV_WRITE);
 
   /* add conn to the connection list */
   if (!connections)
@@ -279,16 +311,16 @@ socks_client_listener_cb(struct evconnlistener *evcl,
 
   /* New bufferevent to wrap socket we received. */
   base = evconnlistener_get_base(lsn->listener);
-  conn->input = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE);
-  if (!conn->input)
+  conn->upstream = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE);
+  if (!conn->upstream)
     goto err;
   fd = -1; /* prevent double-close */
 
-  bufferevent_setcb(conn->input, socks_read_cb, NULL, error_cb, conn);
-  bufferevent_enable(conn->input, EV_READ|EV_WRITE);
+  bufferevent_setcb(conn->upstream, socks_read_cb, NULL, error_cb, conn);
+  bufferevent_enable(conn->upstream, EV_READ|EV_WRITE);
 
-  /* Do not create an output bufferevent at this time; the socks
-     handler will do it after we know where we're connecting */
+  /* Do not create a downstream bufferevent at this time; the socks
+     handler will do it after it learns the downstream peer address. */
 
   /* add conn to the connection list */
   if (!connections)
@@ -332,43 +364,45 @@ simple_server_listener_cb(struct evconnlistener *evcl,
 
   /* New bufferevent to wrap socket we received. */
   base = evconnlistener_get_base(lsn->listener);
-  conn->input = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE);
-  if (!conn->input)
+  conn->downstream = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE);
+  if (!conn->downstream)
     goto err;
   fd = -1; /* prevent double-close */
 
-  bufferevent_setcb(conn->input, downstream_read_cb, NULL, error_cb, conn);
+  bufferevent_setcb(conn->downstream,
+                    downstream_read_cb, NULL, error_cb, conn);
 
-  /* don't enable the input side for reading at this point; wait till we
-     have a connection to the target */
+  /* Don't enable the downstream side for reading at this point; wait
+     till the upstream side is established. */
 
-  /* New bufferevent to connect to the target address */
-  conn->output = bufferevent_socket_new(base, -1, BEV_OPT_CLOSE_ON_FREE);
-  if (!conn->output)
+  /* New bufferevent to connect to the target address. */
+  conn->upstream = bufferevent_socket_new(base, -1, BEV_OPT_CLOSE_ON_FREE);
+  if (!conn->upstream)
     goto err;
 
-  bufferevent_setcb(conn->output, upstream_read_cb, NULL,
-                    pending_conn_cb, conn);
+  bufferevent_setcb(conn->upstream,
+                    upstream_read_cb, NULL, pending_conn_cb, conn);
 
   /* Queue handshake, if any, before connecting. */
   if (proto_handshake(conn->proto,
-                      bufferevent_get_output(conn->input))<0)
+                      bufferevent_get_output(conn->upstream))<0)
     goto err;
 
-  if (bufferevent_socket_connect(conn->output,
+  /* Launch the connect attempt. */
+  if (bufferevent_socket_connect(conn->upstream,
                                  lsn->proto_params->target_addr->ai_addr,
                                  lsn->proto_params->target_addr->ai_addrlen)<0)
     goto err;
 
-  bufferevent_enable(conn->output, EV_READ|EV_WRITE);
+  bufferevent_enable(conn->upstream, EV_READ|EV_WRITE);
 
   /* add conn to the connection list */
   if (!connections)
     connections = smartlist_create();
   smartlist_add(connections, conn);
 
-  log_debug("Connection setup completed. "
-            "We currently have %d connections!", smartlist_len(connections));
+  log_debug("%s: setup completed, %d connections",
+            __func__, smartlist_len(connections));
   return;
 
  err:
@@ -388,10 +422,10 @@ conn_free(conn_t *conn)
     proto_destroy(conn->proto);
   if (conn->socks_state)
     socks_state_free(conn->socks_state);
-  if (conn->input)
-    bufferevent_free(conn->input);
-  if (conn->output)
-    bufferevent_free(conn->output);
+  if (conn->upstream)
+    bufferevent_free(conn->upstream);
+  if (conn->upstream)
+    bufferevent_free(conn->upstream);
 
   memset(conn, 0x99, sizeof(conn_t));
   free(conn);
@@ -409,8 +443,8 @@ close_conn(conn_t *conn)
   log_debug("Connection destroyed. "
             "We currently have %d connections!", smartlist_len(connections));
 
-  /** If this was the last connection AND we are shutting down,
-      finish shutdown. */
+  /* If this was the last connection AND we are shutting down,
+     finish shutdown. */
   if (smartlist_len(connections) == 0) {
     smartlist_free(connections);
     connections = NULL;
@@ -440,9 +474,9 @@ static void
 socks_read_cb(struct bufferevent *bev, void *arg)
 {
   conn_t *conn = arg;
-  //struct bufferevent *other;
   enum socks_ret socks_ret;
-  obfs_assert(bev == conn->input); /* socks only makes sense on the input side */
+  /* socks only makes sense on the upstream side */
+  obfs_assert(bev == conn->upstream);
 
   do {
     enum socks_status_t status = socks_state_get_status(conn->socks_state);
@@ -454,25 +488,25 @@ socks_read_cb(struct bufferevent *bev, void *arg)
       const char *addr=NULL;
       r = socks_state_get_address(conn->socks_state, &af, &addr, &port);
       obfs_assert(r==0);
-      conn->output = bufferevent_socket_new(bufferevent_get_base(conn->input),
-                                            -1,
-                                            BEV_OPT_CLOSE_ON_FREE);
+      conn->downstream =
+        bufferevent_socket_new(bufferevent_get_base(conn->upstream),
+                               -1, BEV_OPT_CLOSE_ON_FREE);
 
-      bufferevent_setcb(conn->output, downstream_read_cb, NULL,
-                        pending_socks_cb, conn);
+      bufferevent_setcb(conn->downstream,
+                        downstream_read_cb, NULL, pending_socks_cb, conn);
 
       /* Queue handshake, if any, before connecting. */
       if (proto_handshake(conn->proto,
-                          bufferevent_get_output(conn->output))<0) {
+                          bufferevent_get_output(conn->downstream))<0) {
         /* XXXX send socks reply */
         close_conn(conn);
         return;
       }
 
-      r = bufferevent_socket_connect_hostname(conn->output,
+      r = bufferevent_socket_connect_hostname(conn->downstream,
                                               get_evdns_base(),
                                               af, addr, port);
-      bufferevent_enable(conn->output, EV_READ|EV_WRITE);
+      bufferevent_enable(conn->downstream, EV_READ|EV_WRITE);
       log_debug("socket_connect_hostname said %d! (%s,%d)", r, addr, port);
 
       if (r < 0) {
@@ -480,13 +514,15 @@ socks_read_cb(struct bufferevent *bev, void *arg)
         close_conn(conn);
         return;
       }
-      bufferevent_disable(conn->input, EV_READ|EV_WRITE);
-      /* ignore data XXX */
+      /* further upstream data will be processed once the downstream
+         side is established */
+      bufferevent_disable(conn->upstream, EV_READ|EV_WRITE);
       return;
     }
 
     socks_ret = handle_socks(bufferevent_get_input(bev),
-                     bufferevent_get_output(bev), conn->socks_state);
+                             bufferevent_get_output(bev),
+                             conn->socks_state);
   } while (socks_ret == SOCKS_GOOD);
 
   if (socks_ret == SOCKS_INCOMPLETE)
@@ -513,13 +549,12 @@ static void
 upstream_read_cb(struct bufferevent *bev, void *arg)
 {
   conn_t *conn = arg;
-  struct bufferevent *other;
-  other = (bev == conn->input) ? conn->output : conn->input;
+  obfs_assert(bev == conn->upstream);
 
   log_debug("Got data on upstream side");
   if (proto_send(conn->proto,
-                 bufferevent_get_input(bev),
-                 bufferevent_get_output(other)) < 0)
+                 bufferevent_get_input(conn->upstream),
+                 bufferevent_get_output(conn->downstream)) < 0)
     close_conn(conn);
 }
 
@@ -532,25 +567,24 @@ static void
 downstream_read_cb(struct bufferevent *bev, void *arg)
 {
   conn_t *conn = arg;
-  struct bufferevent *other;
-  other = (bev == conn->input) ? conn->output : conn->input;
   enum recv_ret r;
+  obfs_assert(bev == conn->downstream);
 
   log_debug("Got data on downstream side");
   r = proto_recv(conn->proto,
-                 bufferevent_get_input(bev),
-                 bufferevent_get_output(other));
+                 bufferevent_get_input(conn->downstream),
+                 bufferevent_get_output(conn->upstream));
 
   if (r == RECV_BAD)
     close_conn(conn);
   else if (r == RECV_SEND_PENDING)
     proto_send(conn->proto,
-               bufferevent_get_input(conn->input),
-               bufferevent_get_output(conn->output));
+               bufferevent_get_input(conn->upstream),
+               bufferevent_get_output(conn->downstream));
 }
 
 /**
-   Something broke in our connection or we reached EOF.
+   Something broke one side of the connection, or we reached EOF.
    We prepare the connection to be closed ASAP.
  */
 static void
@@ -558,8 +592,8 @@ error_or_eof(conn_t *conn, struct bufferevent *bev_err)
 {
   struct bufferevent *bev_flush;
 
-  if (bev_err == conn->input) bev_flush = conn->output;
-  else if (bev_err == conn->output) bev_flush = conn->input;
+  if (bev_err == conn->upstream) bev_flush = conn->downstream;
+  else if (bev_err == conn->downstream) bev_flush = conn->upstream;
   else obfs_abort();
 
   log_debug("error_or_eof");
@@ -619,7 +653,7 @@ flush_error_cb(struct bufferevent *bev, short what, void *arg)
 }
 
 /**
-   Called when an "event" happens on a socket that's still waiting to
+   Called when an event happens on a socket that's still waiting to
    be connected.  We expect to get BEV_EVENT_CONNECTED, which
    indicates that the connection is now open, but we might also get
    errors as above.
@@ -629,8 +663,8 @@ pending_conn_cb(struct bufferevent *bev, short what, void *arg)
 {
   conn_t *conn = arg;
   struct bufferevent *other;
-  if (bev == conn->input) other = conn->output;
-  else if (bev == conn->output) other = conn->input;
+  if (bev == conn->upstream) other = conn->downstream;
+  else if (bev == conn->downstream) other = conn->upstream;
   else obfs_abort();
 
   /* Upon successful connection, enable traffic on the other side,
@@ -639,7 +673,7 @@ pending_conn_cb(struct bufferevent *bev, short what, void *arg)
     obfs_assert(!conn->flushing);
 
     conn->is_open = 1;
-    log_debug("Connection successful") ;
+    log_debug("Connection successful");
     bufferevent_enable(other, EV_READ|EV_WRITE);
 
     /* XXX Dirty access to bufferevent guts.  There appears to be no
@@ -654,15 +688,15 @@ pending_conn_cb(struct bufferevent *bev, short what, void *arg)
 }
 
 /**
-   Called when an "event" happens on a socket in socks mode.
+   Called when an event happens on a socket in socks mode.
    Both connections and errors are possible; must generate
-   appropriate socks messages on the input side.
+   appropriate socks messages on the upstream side.
  */
 static void
 pending_socks_cb(struct bufferevent *bev, short what, void *arg)
 {
   conn_t *conn = arg;
-  obfs_assert(bev == conn->output);
+  obfs_assert(bev == conn->downstream);
   obfs_assert(conn->socks_state);
 
   /* If we got an error while in the ST_HAVE_ADDR state, chances are
@@ -674,7 +708,8 @@ pending_socks_cb(struct bufferevent *bev, short what, void *arg)
     log_warn("Connection error: %s",
              evutil_socket_error_to_string(err));
     if (socks_state_get_status(conn->socks_state) == ST_HAVE_ADDR) {
-      socks_send_reply(conn->socks_state, bufferevent_get_output(conn->input),
+      socks_send_reply(conn->socks_state,
+                       bufferevent_get_output(conn->upstream),
                        err);
     }
     error_or_eof(conn, bev);
@@ -697,7 +732,7 @@ pending_socks_cb(struct bufferevent *bev, short what, void *arg)
       socks_state_set_address(conn->socks_state, sa);
     }
     socks_send_reply(conn->socks_state,
-                     bufferevent_get_output(conn->input), 0);
+                     bufferevent_get_output(conn->upstream), 0);
 
     /* Switch to regular upstream behavior. */
     socks_state_free(conn->socks_state);
@@ -705,11 +740,13 @@ pending_socks_cb(struct bufferevent *bev, short what, void *arg)
     conn->is_open = 1;
     log_debug("Connection successful");
 
-    bufferevent_setcb(conn->input, upstream_read_cb, NULL, error_cb, conn);
-    bufferevent_setcb(conn->output, downstream_read_cb, NULL, error_cb, conn);
-    bufferevent_enable(conn->input, EV_READ|EV_WRITE);
-    if (evbuffer_get_length(bufferevent_get_input(conn->input)) != 0)
-      downstream_read_cb(bev, conn->input);
+    bufferevent_setcb(conn->upstream,
+                      upstream_read_cb, NULL, error_cb, conn);
+    bufferevent_setcb(conn->downstream,
+                      downstream_read_cb, NULL, error_cb, conn);
+    bufferevent_enable(conn->upstream, EV_READ|EV_WRITE);
+    if (evbuffer_get_length(bufferevent_get_input(conn->upstream)) != 0)
+      downstream_read_cb(bev, conn->upstream);
     return;
   }
 
diff --git a/src/network.h b/src/network.h
index 49580c3..0d6ef8d 100644
--- a/src/network.h
+++ b/src/network.h
@@ -45,8 +45,8 @@ struct protocol_t;
 typedef struct conn_t {
   struct protocol_t *proto;
   struct socks_state_t *socks_state;
-  struct bufferevent *input;
-  struct bufferevent *output;
+  struct bufferevent *upstream;
+  struct bufferevent *downstream;
   unsigned int mode : 30;
   unsigned int flushing : 1;
   unsigned int is_open : 1;





More information about the tor-commits mailing list