commit f3636c411cb1e2ee9a5ffe5854d9b59259ff6b77 Author: George Kadianakis desnacked@gmail.com 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@lists.torproject.org