[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[tor-commits] [obfsproxy/master] Send pending data right after init_crypto() is done.



commit f3636c411cb1e2ee9a5ffe5854d9b59259ff6b77
Author: George Kadianakis <desnacked@xxxxxxxxx>
Date:   Sun May 29 06:55:44 2011 +0200

    Send pending data right after init_crypto() is done.
---
 src/network.c         |   11 +++++++++--
 src/network.h         |   16 ++++++++++++++++
 src/protocol.c        |    2 +-
 src/protocol.h        |    8 ++++----
 src/protocols/dummy.c |   17 ++++++++++-------
 src/protocols/obfs2.c |   31 ++++++++++++++++++++++---------
 6 files changed, 62 insertions(+), 23 deletions(-)

diff --git a/src/network.c b/src/network.c
index cfdd398..f629df9 100644
--- a/src/network.c
+++ b/src/network.c
@@ -309,12 +309,19 @@ obfuscated_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;
 
   dbg(("Got data on encrypted side\n"));
-  if (proto_recv(conn->proto,
+  r = proto_recv(conn->proto,
                  bufferevent_get_input(bev),
-                 bufferevent_get_output(other)) < 0)
+                 bufferevent_get_output(other));
+  
+  if (r == RECV_BAD)
     conn_free(conn);
+  else if (r == RECV_OBFS2_PENDING)
+    proto_send(conn->proto, 
+               bufferevent_get_input(conn->input),
+               bufferevent_get_output(conn->output));
 }
 
 static void
diff --git a/src/network.h b/src/network.h
index 619e45f..d33b377 100644
--- a/src/network.h
+++ b/src/network.h
@@ -20,6 +20,22 @@ struct socks_state_t;
 #define LSN_SIMPLE_SERVER 2
 #define LSN_SOCKS_CLIENT  3
 
+enum recv_ret {
+  /* Everything went fine. */
+  RECV_GOOD=0,
+  /* Something went bad. */
+  RECV_BAD,
+  /* ...need...more...data... */
+  RECV_INCOMPLETE,
+
+  /* Originally needed by the obfs2 protocol but it might get other
+     users in the future. Maybe it should be renamed to something neutral.
+     It means:
+     "We have pending data that we have to send. You should do that by
+     calling proto_send() immediately." */
+  RECV_OBFS2_PENDING
+};
+
 typedef struct listener_t listener_t;
 struct addrinfo;
 
diff --git a/src/protocol.c b/src/protocol.c
index 8fff6a3..bcd5330 100644
--- a/src/protocol.c
+++ b/src/protocol.c
@@ -72,7 +72,7 @@ proto_send(struct protocol_t *proto, void *source, void *dest) {
     return -1;
 }
 
-int
+enum recv_ret
 proto_recv(struct protocol_t *proto, void *source, void *dest) {
   assert(proto);
   if (proto->vtable->recv)
diff --git a/src/protocol.h b/src/protocol.h
index e4c3e0f..4a17c73 100644
--- a/src/protocol.h
+++ b/src/protocol.h
@@ -61,9 +61,9 @@ typedef struct protocol_vtable {
               struct evbuffer *dest);
 
   /* receive data function */
-  int (*recv)(void *state, 
-              struct evbuffer *source,
-              struct evbuffer *dest);
+  enum recv_ret (*recv)(void *state, 
+                        struct evbuffer *source,
+                        struct evbuffer *dest);
 
 } protocol_vtable;
 
@@ -73,6 +73,6 @@ struct protocol_t *proto_new(int protocol,
 void proto_destroy(struct protocol_t *proto);
 int proto_handshake(struct protocol_t *proto, void *buf);
 int proto_send(struct protocol_t *proto, void *source, void *dest);
-int proto_recv(struct protocol_t *proto, void *source, void *dest);
+enum recv_ret proto_recv(struct protocol_t *proto, void *source, void *dest);
 
 #endif
diff --git a/src/protocols/dummy.c b/src/protocols/dummy.c
index 482c927..ed8d672 100644
--- a/src/protocols/dummy.c
+++ b/src/protocols/dummy.c
@@ -11,12 +11,12 @@
 #include "dummy.h"
 #include "../util.h"
 #include "../protocol.h"
-
+#include "../network.h"
 
 static int dummy_send(void *nothing,
-               struct evbuffer *source, struct evbuffer *dest);
-static int dummy_recv(void *nothing, struct evbuffer *source,
-               struct evbuffer *dest);
+                                struct evbuffer *source, struct evbuffer *dest);
+static enum recv_ret dummy_recv(void *nothing, struct evbuffer *source,
+                                struct evbuffer *dest);
 
 static protocol_vtable *vtable=NULL;
 
@@ -54,10 +54,13 @@ dummy_send(void *nothing,
   return evbuffer_add_buffer(dest,source);
 }
 
-static int
+static enum recv_ret
 dummy_recv(void *nothing,
            struct evbuffer *source, struct evbuffer *dest) {
   (void)nothing;
-
-  return evbuffer_add_buffer(dest,source);
+  
+  if (evbuffer_add_buffer(dest,source)<0)
+    return (enum recv_ret) RECV_BAD;
+  else
+    return (enum recv_ret) RECV_GOOD;
 }
diff --git a/src/protocols/obfs2.c b/src/protocols/obfs2.c
index a8f9155..975458a 100644
--- a/src/protocols/obfs2.c
+++ b/src/protocols/obfs2.c
@@ -19,13 +19,14 @@
 #include "obfs2.h"
 #include "../util.h"
 #include "../protocol.h"
+#include "../network.h"
 
 static void obfs2_state_free(void *state);
 static int obfs2_send_initial_message(void *state, struct evbuffer *buf);
 static int obfs2_send(void *state,
                struct evbuffer *source, struct evbuffer *dest);
-static int obfs2_recv(void *state, struct evbuffer *source,
-               struct evbuffer *dest);
+static enum recv_ret obfs2_recv(void *state, struct evbuffer *source,
+                                struct evbuffer *dest);
 static void *obfs2_state_new(protocol_params_t *params); 
 static int obfs2_state_set_shared_secret(void *s,
                                          const char *secret,
@@ -358,11 +359,12 @@ init_crypto(void *s)
  *
  * Returns x for "don't call again till you have x bytes".  0 for "all ok". -1
  * for "fail, close" */
-static int
+static enum recv_ret
 obfs2_recv(void *s, struct evbuffer *source,
            struct evbuffer *dest)
 {
   obfs2_state_t *state = s;
+  enum recv_ret r=0;
 
   if (state->state == ST_WAIT_FOR_KEY) {
     /* We're waiting for the first OBFUSCATE_SEED_LENGTH+8 bytes to show up
@@ -371,7 +373,7 @@ obfs2_recv(void *s, struct evbuffer *source,
     uint32_t magic, plength;
     if (evbuffer_get_length(source) < OBFUSCATE_SEED_LENGTH+8) {
       /* data not here yet */
-      return OBFUSCATE_SEED_LENGTH+8;
+      return (enum recv_ret) RECV_INCOMPLETE;
     }
     evbuffer_remove(source, buf, OBFUSCATE_SEED_LENGTH+8);
 
@@ -384,7 +386,7 @@ obfs2_recv(void *s, struct evbuffer *source,
 
     /* Now we can set up all the keys from the seed */
     if (init_crypto(state) < 0)
-      return -1;
+      return (enum recv_ret) RECV_BAD;
 
     /* Decrypt the next 8 bytes */
     stream_crypt(state->recv_padding_crypto, buf+OBFUSCATE_SEED_LENGTH, 8);
@@ -394,9 +396,9 @@ obfs2_recv(void *s, struct evbuffer *source,
     magic = ntohl(magic);
     plength = ntohl(plength);
     if (magic != OBFUSCATE_MAGIC_VALUE)
-      return -1;
+      return (enum recv_ret) RECV_BAD;
     if (plength > OBFUSCATE_MAX_PADDING)
-      return -1;
+      return (enum recv_ret) RECV_BAD;
 
     /* XXX FIXME we should now be sending any 'pending_data_to_send'
        but we can't send them from here, so we send them with
@@ -411,13 +413,19 @@ obfs2_recv(void *s, struct evbuffer *source,
     dbg(("Received key, expecting %d bytes of padding\n", plength));
   }
 
+  /* If we have pending data to send, we set the return code
+  appropriately so that we call proto_send() right after we get out of
+  here! */  
+  if (state->pending_data_to_send)
+    r = RECV_OBFS2_PENDING;
+
   /* If we're still looking for padding, start pulling off bytes and
      discarding them. */
   while (state->padding_left_to_read) {
     int n = state->padding_left_to_read;
     size_t sourcelen = evbuffer_get_length(source);
     if (!sourcelen)
-      return n;
+      return RECV_INCOMPLETE;
     if ((size_t) n > evbuffer_get_length(source))
       n = evbuffer_get_length(source);
     evbuffer_drain(source, n);
@@ -431,7 +439,12 @@ obfs2_recv(void *s, struct evbuffer *source,
 
   dbg(("Processing %d bytes data onto destination buffer\n",
        (int) evbuffer_get_length(source)));
-  return crypt_and_transmit(state->recv_crypto, source, dest);
+  crypt_and_transmit(state->recv_crypto, source, dest);
+
+  if (r != RECV_OBFS2_PENDING)
+    r = RECV_GOOD;
+
+  return r;
 }
 
 static void



_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits