[tor-commits] [obfsproxy/master] Move socks_state, is_open, and flushing fields from conn_t to circuit_t.
nickm at torproject.org
nickm at torproject.org
Fri Sep 9 17:08:58 UTC 2011
commit c76bd29587ed0be50125f3ac2cd37a0e89710415
Author: Zack Weinberg <zackw at panix.com>
Date: Wed Aug 3 11:43:13 2011 -0700
Move socks_state, is_open, and flushing fields from conn_t to circuit_t.
---
src/network.c | 89 +++++++++++++++++++++++++++++++++++++--------------------
src/network.h | 27 +++++++++++++----
2 files changed, 78 insertions(+), 38 deletions(-)
diff --git a/src/network.c b/src/network.c
index 08ce696..cc5b633 100644
--- a/src/network.c
+++ b/src/network.c
@@ -82,7 +82,9 @@ static void conn_free(conn_t *conn);
static void conn_free_all(void);
static void conn_free_on_flush(struct bufferevent *bev, void *arg);
-static int circuit_create(conn_t *upstream, conn_t *downstream);
+static int circuit_create(conn_t *up, conn_t *down);
+static void circuit_create_socks(conn_t *up);
+static int circuit_add_down(circuit_t *circuit, conn_t *down);
static void circuit_free(circuit_t *circuit);
static conn_t *open_outbound(conn_t *conn, bufferevent_data_cb readcb);
@@ -293,7 +295,7 @@ socks_client_listener_cb(conn_t *conn)
obfs_assert(conn->mode == LSN_SOCKS_CLIENT);
log_debug("%s: socks client connection", conn->peername);
- conn->socks_state = socks_state_new();
+ circuit_create_socks(conn);
bufferevent_setcb(conn->buffer, socks_read_cb, NULL, error_cb, conn);
bufferevent_enable(conn->buffer, EV_READ|EV_WRITE);
@@ -341,8 +343,6 @@ conn_free(conn_t *conn)
}
if (conn->peername)
free(conn->peername);
- if (conn->socks_state)
- socks_state_free(conn->socks_state);
if (conn->buffer)
bufferevent_free(conn->buffer);
proto_conn_free(conn);
@@ -386,13 +386,38 @@ circuit_create(conn_t *up, conn_t *down)
}
static void
+circuit_create_socks(conn_t *up)
+{
+ obfs_assert(up);
+
+ circuit_t *r = xzalloc(sizeof(circuit_t));
+ r->upstream = up;
+ r->socks_state = socks_state_new();
+ up->circuit = r;
+}
+
+static int
+circuit_add_down(circuit_t *circuit, conn_t *down)
+{
+ if (!down)
+ return -1;
+ circuit->downstream = down;
+ down->circuit = circuit;
+ return 0;
+}
+
+static void
circuit_free(circuit_t *circuit)
{
/* break the circular references before deallocating each side */
circuit->upstream->circuit = NULL;
- circuit->downstream->circuit = NULL;
conn_free(circuit->upstream);
- conn_free(circuit->downstream);
+ if (circuit->downstream) {
+ circuit->downstream->circuit = NULL;
+ conn_free(circuit->downstream);
+ }
+ if (circuit->socks_state)
+ socks_state_free(circuit->socks_state);
free(circuit);
}
@@ -504,22 +529,28 @@ static void
socks_read_cb(struct bufferevent *bev, void *arg)
{
conn_t *conn = arg;
+ socks_state_t *socks;
enum socks_ret socks_ret;
+
log_debug("%s: %s", conn->peername, __func__);
+ obfs_assert(conn->circuit);
+ obfs_assert(conn->circuit->socks_state);
+ socks = conn->circuit->socks_state;
do {
- enum socks_status_t status = socks_state_get_status(conn->socks_state);
+ enum socks_status_t status = socks_state_get_status(socks);
if (status == ST_SENT_REPLY) {
/* We shouldn't be here. */
obfs_abort();
} else if (status == ST_HAVE_ADDR) {
int af, r, port;
const char *addr=NULL;
- r = socks_state_get_address(conn->socks_state, &af, &addr, &port);
+ r = socks_state_get_address(socks, &af, &addr, &port);
obfs_assert(r==0);
log_info("%s: socks: trying to connect to %s:%u",
conn->peername, addr, port);
- if (circuit_create(conn, open_outbound_hostname(conn, af, addr, port))) {
+ if (circuit_add_down(conn->circuit,
+ open_outbound_hostname(conn, af, addr, port))) {
/* XXXX send socks reply */
conn_free(conn);
return;
@@ -532,7 +563,7 @@ socks_read_cb(struct bufferevent *bev, void *arg)
socks_ret = handle_socks(bufferevent_get_input(bev),
bufferevent_get_output(bev),
- conn->socks_state);
+ socks);
} while (socks_ret == SOCKS_GOOD);
if (socks_ret == SOCKS_INCOMPLETE)
@@ -542,7 +573,7 @@ socks_read_cb(struct bufferevent *bev, void *arg)
else if (socks_ret == SOCKS_CMD_NOT_CONNECT) {
bufferevent_enable(bev, EV_WRITE);
bufferevent_disable(bev, EV_READ);
- socks5_send_reply(bufferevent_get_output(bev), conn->socks_state,
+ socks5_send_reply(bufferevent_get_output(bev), socks,
SOCKS5_FAILED_UNSUPPORTED);
bufferevent_setcb(bev, NULL,
conn_free_on_flush, flush_error_cb, conn);
@@ -564,10 +595,10 @@ upstream_read_cb(struct bufferevent *bev, void *arg)
(unsigned long)evbuffer_get_length(bufferevent_get_input(bev)));
obfs_assert(up->buffer == bev);
- obfs_assert(!up->flushing);
- obfs_assert(up->is_open);
obfs_assert(up->circuit);
obfs_assert(up->circuit->downstream);
+ obfs_assert(up->circuit->is_open);
+ obfs_assert(!up->circuit->is_flushing);
down = up->circuit->downstream;
if (proto_send(up,
@@ -597,10 +628,10 @@ downstream_read_cb(struct bufferevent *bev, void *arg)
(unsigned long)evbuffer_get_length(bufferevent_get_input(bev)));
obfs_assert(down->buffer == bev);
- obfs_assert(!down->flushing);
- obfs_assert(down->is_open);
obfs_assert(down->circuit);
obfs_assert(down->circuit->upstream);
+ obfs_assert(down->circuit->is_open);
+ obfs_assert(!down->circuit->is_flushing);
up = down->circuit->upstream;
@@ -644,7 +675,8 @@ error_or_eof(conn_t *conn)
struct bufferevent *bev_flush;
log_debug("%s for %s", __func__, conn->peername);
- if (!circ || conn->flushing || !conn->is_open) {
+ if (!circ || !circ->upstream || !circ->downstream || !circ->is_open
+ || circ->is_flushing) {
conn_free(conn);
return;
}
@@ -656,9 +688,7 @@ error_or_eof(conn_t *conn)
return;
}
- /* XXX move ->flushing and ->is_open to circuit_t */
- circ->upstream->flushing = 1;
- circ->downstream->flushing = 1;
+ circ->is_flushing = 1;
/* Stop reading and writing; wait for the other side to flush if it has
* data. */
@@ -717,7 +747,8 @@ flush_error_cb(struct bufferevent *bev, short what, void *arg)
obfs_assert(what & (BEV_EVENT_EOF|BEV_EVENT_ERROR|BEV_EVENT_TIMEOUT));
obfs_assert(!(what & BEV_EVENT_CONNECTED));
- obfs_assert(conn->flushing);
+ obfs_assert(conn->circuit);
+ obfs_assert(conn->circuit->is_flushing);
log_warn("Error during flush of connection with %s: %s",
conn->peername,
@@ -743,11 +774,9 @@ pending_conn_cb(struct bufferevent *bev, short what, void *arg)
if (what & BEV_EVENT_CONNECTED) {
circuit_t *circ = conn->circuit;
obfs_assert(circ);
- obfs_assert(!circ->upstream->flushing);
- obfs_assert(!circ->downstream->flushing);
+ obfs_assert(!circ->is_flushing);
- circ->upstream->is_open = 1;
- circ->downstream->is_open = 1;
+ circ->is_open = 1;
log_debug("%s: Successful connection", conn->peername);
@@ -790,11 +819,11 @@ pending_socks_cb(struct bufferevent *bev, short what, void *arg)
obfs_assert(circ);
obfs_assert(circ->upstream);
- obfs_assert(circ->upstream->socks_state);
+ obfs_assert(circ->socks_state);
obfs_assert(circ->downstream == down);
up = circ->upstream;
- socks = circ->upstream->socks_state;
+ socks = circ->socks_state;
/* If we got an error while in the ST_HAVE_ADDR state, chances are
that we failed connecting to the host requested by the CONNECT
@@ -820,8 +849,7 @@ pending_socks_cb(struct bufferevent *bev, short what, void *arg)
struct sockaddr *sa = (struct sockaddr*)&ss;
socklen_t slen = sizeof(&ss);
- obfs_assert(!up->flushing);
- obfs_assert(!down->flushing);
+ obfs_assert(!circ->is_flushing);
/* Figure out where we actually connected to, and tell the socks client */
if (getpeername(bufferevent_getfd(bev), sa, &slen) == 0) {
@@ -833,9 +861,8 @@ pending_socks_cb(struct bufferevent *bev, short what, void *arg)
/* Switch to regular upstream behavior. */
socks_state_free(socks);
- up->socks_state = NULL;
- up->is_open = 1;
- down->is_open = 1;
+ circ->socks_state = NULL;
+ circ->is_open = 1;
log_debug("%s: Successful outbound connection to %s",
up->peername, down->peername);
diff --git a/src/network.h b/src/network.h
index 72df32c..fa15f48 100644
--- a/src/network.h
+++ b/src/network.h
@@ -26,23 +26,36 @@ void start_shutdown(int barbaric);
struct conn_t {
config_t *cfg;
char *peername;
- socks_state_t *socks_state;
circuit_t *circuit;
struct bufferevent *buffer;
- enum listen_mode mode : 30;
- unsigned int flushing : 1;
- unsigned int is_open : 1;
+ enum listen_mode mode;
};
/**
- This struct defines a pair of established connections. The "upstream"
- connection is to the higher-level client or server that we are proxying
- traffic for. The "downstream" connection is to the remote peer.
+ This struct defines a pair of established connections.
+
+ The "upstream" connection is to the higher-level client or server
+ that we are proxying traffic for. The "downstream" connection is
+ to the remote peer. Circuits always have an upstream connection,
+ and normally also have a downstream connection; however, a circuit
+ that's waiting for SOCKS directives from its upstream will have a
+ non-null socks_state field instead.
+
+ A circuit is "open" if both its upstream and downstream connections
+ have been established (not just if both conn_t objects exist).
+ It is "flushing" if one of the two connections has hit either EOF
+ or an error, and we are clearing out the other side's pending
+ transmissions before closing it. Both of these flags are used
+ near-exclusively for assertion checks; the actual behavior is
+ controlled by changing bufferevent callbacks on the connections.
*/
struct circuit_t {
conn_t *upstream;
conn_t *downstream;
+ socks_state_t *socks_state;
+ unsigned int is_open : 1;
+ unsigned int is_flushing : 1;
};
#endif
More information about the tor-commits
mailing list