[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