[obfsproxy/master] Merge protocol_t into conn_t.

commit 6b3b9273f5b2e67f99b0c49ebf2fa7d36e0f9f56 Author: Zack Weinberg <zackw@panix.com> Date: Tue Aug 2 10:46:13 2011 -0700 Merge protocol_t into conn_t. --- src/network.c | 61 ++++++++++++++++++++------------------------- src/network.h | 33 ++++++++++++++---------- src/protocol.c | 50 ++++++++++++++++++------------------ src/protocol.h | 39 +++++++++++----------------- src/protocols/dummy.c | 22 ++++++++-------- src/protocols/dummy.h | 6 ++-- src/test/unittest_dummy.c | 52 +++++++++++++++++++------------------- src/util.h | 2 +- 8 files changed, 127 insertions(+), 138 deletions(-) diff --git a/src/network.c b/src/network.c index b1d71dc..d11b60f 100644 --- a/src/network.c +++ b/src/network.c @@ -4,7 +4,6 @@ #include "util.h" -#define NETWORK_PRIVATE #include "network.h" #include "container.h" @@ -217,9 +216,14 @@ simple_client_listener_cb(struct evconnlistener *evcl, evutil_socket_t fd, struct sockaddr *sourceaddr, int socklen, void *arg) { - listener_t *lsn = arg; struct event_base *base; - conn_t *conn = xzalloc(sizeof(conn_t)); + listener_t *lsn = arg; + conn_t *conn = proto_conn_create(lsn); + if (!conn) { + log_warn("Failed to create state object for new connection to %s", + lsn->listen_addr_str); + goto err; + } conn->peername = printable_address(sourceaddr, socklen); log_debug("%s: connection to %s from %s", __func__, @@ -228,12 +232,6 @@ simple_client_listener_cb(struct evconnlistener *evcl, conn->mode = lsn->mode; obfs_assert(conn->mode == LSN_SIMPLE_CLIENT); - conn->proto = proto_create(lsn); - if (!conn->proto) { - log_warn("Creation of protocol object failed! Closing connection."); - goto err; - } - /* New bufferevent to wrap socket we received. */ base = evconnlistener_get_base(lsn->listener); conn->upstream = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE); @@ -288,9 +286,14 @@ socks_client_listener_cb(struct evconnlistener *evcl, evutil_socket_t fd, struct sockaddr *sourceaddr, int socklen, void *arg) { - listener_t *lsn = arg; struct event_base *base; - conn_t *conn = xzalloc(sizeof(conn_t)); + listener_t *lsn = arg; + conn_t *conn = proto_conn_create(lsn); + if (!conn) { + log_warn("Failed to create state object for new connection to %s", + lsn->listen_addr_str); + goto err; + } conn->peername = printable_address(sourceaddr, socklen); log_debug("%s: connection to %s from %s", __func__, @@ -299,12 +302,6 @@ socks_client_listener_cb(struct evconnlistener *evcl, conn->mode = lsn->mode; obfs_assert(conn->mode == LSN_SOCKS_CLIENT); - conn->proto = proto_create(lsn); - if (!conn->proto) { - log_warn("Creation of protocol object failed! Closing connection."); - goto err; - } - /* Construct SOCKS state. */ conn->socks_state = socks_state_new(); @@ -346,9 +343,14 @@ simple_server_listener_cb(struct evconnlistener *evcl, evutil_socket_t fd, struct sockaddr *sourceaddr, int socklen, void *arg) { - listener_t *lsn = arg; struct event_base *base; - conn_t *conn = xzalloc(sizeof(conn_t)); + listener_t *lsn = arg; + conn_t *conn = proto_conn_create(lsn); + if (!conn) { + log_warn("Failed to create state object for new connection to %s", + lsn->listen_addr_str); + goto err; + } conn->peername = printable_address(sourceaddr, socklen); log_debug("%s: connection to %s from %s", __func__, @@ -357,12 +359,6 @@ simple_server_listener_cb(struct evconnlistener *evcl, conn->mode = lsn->mode; obfs_assert(conn->mode == LSN_SIMPLE_SERVER); - conn->proto = proto_create(lsn); - if (!conn->proto) { - log_warn("Creation of protocol object failed! Closing connection."); - goto err; - } - /* New bufferevent to wrap socket we received. */ base = evconnlistener_get_base(lsn->listener); conn->downstream = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE); @@ -416,8 +412,6 @@ conn_free(conn_t *conn) { if (conn->peername) free(conn->peername); - if (conn->proto) - proto_destroy(conn->proto); if (conn->socks_state) socks_state_free(conn->socks_state); if (conn->upstream) @@ -425,8 +419,7 @@ conn_free(conn_t *conn) if (conn->downstream) bufferevent_free(conn->downstream); - memset(conn, 0x99, sizeof(conn_t)); - free(conn); + proto_conn_free(conn); } /** @@ -546,7 +539,7 @@ upstream_read_cb(struct bufferevent *bev, void *arg) (unsigned long)evbuffer_get_length(bufferevent_get_input(bev))); obfs_assert(bev == conn->upstream); - if (proto_send(conn->proto, + if (proto_send(conn, bufferevent_get_input(conn->upstream), bufferevent_get_output(conn->downstream)) < 0) { log_debug("%s: Error during transmit.", conn->peername); @@ -568,7 +561,7 @@ downstream_read_cb(struct bufferevent *bev, void *arg) (unsigned long)evbuffer_get_length(bufferevent_get_input(bev))); obfs_assert(bev == conn->downstream); - r = proto_recv(conn->proto, + r = proto_recv(conn, bufferevent_get_input(conn->downstream), bufferevent_get_output(conn->upstream)); @@ -579,7 +572,7 @@ downstream_read_cb(struct bufferevent *bev, void *arg) log_debug("%s: Reply of %lu bytes", conn->peername, (unsigned long) evbuffer_get_length(bufferevent_get_input(conn->upstream))); - if (proto_send(conn->proto, + if (proto_send(conn, bufferevent_get_input(conn->upstream), bufferevent_get_output(conn->downstream)) < 0) { log_debug("%s: Error during reply.", conn->peername); @@ -708,7 +701,7 @@ pending_conn_cb(struct bufferevent *bev, short what, void *arg) bev == conn->upstream ? "upstream" : "downstream"); /* Queue handshake, if any. */ - if (proto_handshake(conn->proto, + if (proto_handshake(conn, bufferevent_get_output(conn->downstream))<0) { log_debug("%s: Error during handshake", conn->peername); close_conn(conn); @@ -791,7 +784,7 @@ pending_socks_cb(struct bufferevent *bev, short what, void *arg) bufferevent_enable(conn->upstream, EV_READ|EV_WRITE); /* Queue handshake, if any. */ - if (proto_handshake(conn->proto, + if (proto_handshake(conn, bufferevent_get_output(conn->downstream))<0) { log_debug("%s: Error during handshake", conn->peername); close_conn(conn); diff --git a/src/network.h b/src/network.h index dc099f6..17b0e6b 100644 --- a/src/network.h +++ b/src/network.h @@ -29,19 +29,24 @@ struct listener_t { enum listen_mode mode; }; -#ifdef NETWORK_PRIVATE - -typedef struct conn_t { - char *peername; - protocol_t *proto; - socks_state_t *socks_state; - struct bufferevent *upstream; - struct bufferevent *downstream; - unsigned int mode : 30; - unsigned int flushing : 1; - unsigned int is_open : 1; -} conn_t; - -#endif +/** + This struct defines the state of a connection between "upstream" + and "downstream" peers (it's really two connections at the socket + level). Again, each protocol may extend this structure with + additional private data by embedding it as the first member of a + larger structure. The protocol's conn_create() method is responsible + only for filling in the |vtable| field of this structure, plus any + private data of course. + */ +struct conn_t { + const protocol_vtable *vtable; + char *peername; + socks_state_t *socks_state; + struct bufferevent *upstream; + struct bufferevent *downstream; + enum listen_mode mode : 30; + unsigned int flushing : 1; + unsigned int is_open : 1; +}; #endif diff --git a/src/protocol.c b/src/protocol.c index 7865aac..eddb9a3 100644 --- a/src/protocol.c +++ b/src/protocol.c @@ -56,13 +56,13 @@ proto_listener_free(listener_t *lsn) Return a 'protocol_t' if successful, NULL otherwise. */ -protocol_t * -proto_create(listener_t *lsn) +conn_t * +proto_conn_create(listener_t *lsn) { obfs_assert(lsn); obfs_assert(lsn->vtable); - obfs_assert(lsn->vtable->create); - return lsn->vtable->create(lsn); + obfs_assert(lsn->vtable->conn_create); + return lsn->vtable->conn_create(lsn); } /** @@ -70,43 +70,43 @@ proto_create(listener_t *lsn) Not all protocols have a handshake. */ int -proto_handshake(protocol_t *proto, void *buf) { - obfs_assert(proto); - obfs_assert(proto->vtable); - obfs_assert(proto->vtable->handshake); - return proto->vtable->handshake(proto, buf); +proto_handshake(conn_t *conn, void *buf) { + obfs_assert(conn); + obfs_assert(conn->vtable); + obfs_assert(conn->vtable->handshake); + return conn->vtable->handshake(conn, buf); } /** This function is responsible for sending protocol data. */ int -proto_send(protocol_t *proto, void *source, void *dest) { - obfs_assert(proto); - obfs_assert(proto->vtable); - obfs_assert(proto->vtable->send); - return proto->vtable->send(proto, source, dest); +proto_send(conn_t *conn, void *source, void *dest) { + obfs_assert(conn); + obfs_assert(conn->vtable); + obfs_assert(conn->vtable->send); + return conn->vtable->send(conn, source, dest); } /** This function is responsible for receiving protocol data. */ enum recv_ret -proto_recv(protocol_t *proto, void *source, void *dest) { - obfs_assert(proto); - obfs_assert(proto->vtable); - obfs_assert(proto->vtable->recv); - return proto->vtable->recv(proto, source, dest); +proto_recv(conn_t *conn, void *source, void *dest) { + obfs_assert(conn); + obfs_assert(conn->vtable); + obfs_assert(conn->vtable->recv); + return conn->vtable->recv(conn, source, dest); } /** - This function destroys 'proto'. + This function destroys 'conn'. It's called everytime we close a connection. */ void -proto_destroy(protocol_t *proto) { - obfs_assert(proto); - obfs_assert(proto->vtable); - obfs_assert(proto->vtable->destroy); - proto->vtable->destroy(proto); +proto_conn_free(conn_t *conn) { + obfs_assert(conn); + obfs_assert(conn->vtable); + obfs_assert(conn->vtable->conn_free); + conn->vtable->conn_free(conn); } diff --git a/src/protocol.h b/src/protocol.h index 0f4f32d..6dfb04a 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -6,16 +6,6 @@ #define PROTOCOL_H /** - This struct defines the protocol-specific state for a particular - connection. Again, each protocol may extend this structure with - additional private data by embedding it as the first member of a - larger structure. - */ -struct protocol_t { - const protocol_vtable *vtable; -}; - -/** This struct defines a protocol and its methods; note that not all of them are methods on the same object in the C++ sense. @@ -40,22 +30,22 @@ struct protocol_vtable by generic code. */ void (*listener_free)(listener_t *params); - /** Constructor: Allocates per-connection, protocol-specific state. */ - protocol_t *(*create)(listener_t *params); + /** Allocate per-connection, protocol-specific state. */ + conn_t *(*conn_create)(listener_t *params); - /** Destructor: Destroys per-connection, protocol-specific state. */ - void (*destroy)(protocol_t *state); + /** Destroy per-connection, protocol-specific state. */ + void (*conn_free)(conn_t *state); /** Perform a connection handshake. Not all protocols have a handshake. */ - int (*handshake)(protocol_t *state, struct evbuffer *buf); + int (*handshake)(conn_t *state, struct evbuffer *buf); /** Send data coming downstream from 'source' along to 'dest'. */ - int (*send)(protocol_t *state, + int (*send)(conn_t *state, struct evbuffer *source, struct evbuffer *dest); /** Receive data from 'source' and pass it upstream to 'dest'. */ - enum recv_ret (*recv)(protocol_t *state, + enum recv_ret (*recv)(conn_t *state, struct evbuffer *source, struct evbuffer *dest); @@ -71,19 +61,20 @@ struct protocol_vtable #name, \ name##_listener_create, \ name##_listener_free, \ - name##_create, name##_destroy, \ + name##_conn_create, \ + name##_conn_free, \ name##_handshake, name##_send, name##_recv \ } listener_t *proto_listener_create(int n_options, const char *const *options); -void proto_listener_free(listener_t *params); +void proto_listener_free(listener_t *lsn); -protocol_t *proto_create(listener_t *params); -void proto_destroy(protocol_t *proto); +conn_t *proto_conn_create(listener_t *lsn); +void proto_conn_free(conn_t *conn); -int proto_handshake(protocol_t *proto, void *buf); -int proto_send(protocol_t *proto, void *source, void *dest); -enum recv_ret proto_recv(protocol_t *proto, void *source, void *dest); +int proto_handshake(conn_t *conn, void *buf); +int proto_send(conn_t *conn, void *source, void *dest); +enum recv_ret proto_recv(conn_t *conn, void *source, void *dest); extern const protocol_vtable *const supported_protocols[]; extern const size_t n_supported_protocols; diff --git a/src/protocols/dummy.c b/src/protocols/dummy.c index e78398f..30b0d16 100644 --- a/src/protocols/dummy.c +++ b/src/protocols/dummy.c @@ -16,10 +16,10 @@ downcast_listener(listener_t *p) return DOWNCAST(dummy_listener_t, super, p); } -static inline dummy_protocol_t * -downcast_protocol(protocol_t *p) +static inline dummy_conn_t * +downcast_conn(conn_t *p) { - return DOWNCAST(dummy_protocol_t, super, p); + return DOWNCAST(dummy_conn_t, super, p); } static int parse_and_set_options(int n_options, @@ -112,36 +112,36 @@ dummy_listener_free(listener_t *lsn) protocol. */ -static protocol_t * -dummy_create(listener_t *lsn) +static conn_t * +dummy_conn_create(listener_t *lsn) { - dummy_protocol_t *proto = xzalloc(sizeof(dummy_protocol_t)); + dummy_conn_t *proto = xzalloc(sizeof(dummy_conn_t)); proto->super.vtable = &dummy_vtable; return &proto->super; } static void -dummy_destroy(protocol_t *proto) +dummy_conn_free(conn_t *proto) { - free(downcast_protocol(proto)); + free(downcast_conn(proto)); } /** Dummy has no handshake */ static int -dummy_handshake(protocol_t *proto, struct evbuffer *buf) +dummy_handshake(conn_t *proto, struct evbuffer *buf) { return 0; } /** send, receive - just copy */ static int -dummy_send(protocol_t *proto, struct evbuffer *source, struct evbuffer *dest) +dummy_send(conn_t *proto, struct evbuffer *source, struct evbuffer *dest) { return evbuffer_add_buffer(dest,source); } static enum recv_ret -dummy_recv(protocol_t *proto, struct evbuffer *source, struct evbuffer *dest) +dummy_recv(conn_t *proto, struct evbuffer *source, struct evbuffer *dest) { if (evbuffer_add_buffer(dest,source)<0) return RECV_BAD; diff --git a/src/protocols/dummy.h b/src/protocols/dummy.h index b4e9c84..e7a450e 100644 --- a/src/protocols/dummy.h +++ b/src/protocols/dummy.h @@ -26,9 +26,9 @@ typedef struct dummy_listener_t { listener_t super; } dummy_listener_t; -typedef struct dummy_protocol_t { - protocol_t super; -} dummy_protocol_t; +typedef struct dummy_conn_t { + conn_t super; +} dummy_conn_t; #endif diff --git a/src/test/unittest_dummy.c b/src/test/unittest_dummy.c index 2a55b9d..ec09a82 100644 --- a/src/test/unittest_dummy.c +++ b/src/test/unittest_dummy.c @@ -64,10 +64,10 @@ test_dummy_option_parsing(void *unused) /* All the tests below use this test environment: */ struct test_dummy_state { - listener_t *proto_lsn_client; - listener_t *proto_lsn_server; - protocol_t *client_proto; - protocol_t *server_proto; + listener_t *lsn_client; + listener_t *lsn_server; + conn_t *conn_client; + conn_t *conn_server; struct evbuffer *output_buffer; struct evbuffer *dummy_buffer; }; @@ -77,15 +77,15 @@ cleanup_dummy_state(const struct testcase_t *unused, void *state) { struct test_dummy_state *s = (struct test_dummy_state *)state; - if (s->client_proto) - proto_destroy(s->client_proto); - if (s->server_proto) - proto_destroy(s->server_proto); + if (s->conn_client) + proto_conn_free(s->conn_client); + if (s->conn_server) + proto_conn_free(s->conn_server); - if (s->proto_lsn_client) - proto_listener_free(s->proto_lsn_client); - if (s->proto_lsn_server) - proto_listener_free(s->proto_lsn_server); + if (s->lsn_client) + proto_listener_free(s->lsn_client); + if (s->lsn_server) + proto_listener_free(s->lsn_server); if (s->output_buffer) evbuffer_free(s->output_buffer); @@ -109,19 +109,19 @@ setup_dummy_state(const struct testcase_t *unused) { struct test_dummy_state *s = xzalloc(sizeof(struct test_dummy_state)); - s->proto_lsn_client = + s->lsn_client = proto_listener_create(ALEN(options_client), options_client); - tt_assert(s->proto_lsn_client); + tt_assert(s->lsn_client); - s->proto_lsn_server = + s->lsn_server = proto_listener_create(ALEN(options_server), options_server); - tt_assert(s->proto_lsn_server); + tt_assert(s->lsn_server); - s->client_proto = proto_create(s->proto_lsn_client); - tt_assert(s->client_proto); + s->conn_client = proto_conn_create(s->lsn_client); + tt_assert(s->conn_client); - s->server_proto = proto_create(s->proto_lsn_server); - tt_assert(s->server_proto); + s->conn_server = proto_conn_create(s->lsn_server); + tt_assert(s->conn_server); s->output_buffer = evbuffer_new(); tt_assert(s->output_buffer); @@ -148,13 +148,13 @@ test_dummy_transfer(void *state) /* Call the handshake method to satisfy the high-level contract, even though dummy doesn't use a handshake */ - tt_int_op(proto_handshake(s->client_proto, s->output_buffer), >=, 0); + tt_int_op(proto_handshake(s->conn_client, s->output_buffer), >=, 0); /* That should have put nothing into the output buffer */ tt_int_op(evbuffer_get_length(s->output_buffer), ==, 0); /* Ditto on the server side */ - tt_int_op(proto_handshake(s->server_proto, s->output_buffer), >=, 0); + tt_int_op(proto_handshake(s->conn_server, s->output_buffer), >=, 0); tt_int_op(evbuffer_get_length(s->output_buffer), ==, 0); const char *msg1 = "this is a 54-byte message passed from client to server"; @@ -162,9 +162,9 @@ test_dummy_transfer(void *state) /* client -> server */ evbuffer_add(s->dummy_buffer, msg1, 54); - proto_send(s->client_proto, s->dummy_buffer, s->output_buffer); + proto_send(s->conn_client, s->dummy_buffer, s->output_buffer); - tt_assert(RECV_GOOD == proto_recv(s->server_proto, s->output_buffer, + tt_assert(RECV_GOOD == proto_recv(s->conn_server, s->output_buffer, s->dummy_buffer)); n = evbuffer_peek(s->dummy_buffer, -1, NULL, &v[0], 2); @@ -177,10 +177,10 @@ test_dummy_transfer(void *state) /* client <- server */ evbuffer_add(s->dummy_buffer, msg2, 55); - tt_int_op(0, <=, proto_send(s->server_proto, s->dummy_buffer, + tt_int_op(0, <=, proto_send(s->conn_server, s->dummy_buffer, s->output_buffer)); - tt_assert(RECV_GOOD == proto_recv(s->client_proto, s->output_buffer, + tt_assert(RECV_GOOD == proto_recv(s->conn_client, s->output_buffer, s->dummy_buffer)); n = evbuffer_peek(s->dummy_buffer, -1, NULL, &v[1], 2); diff --git a/src/util.h b/src/util.h index d8c6bb2..8b6f3b4 100644 --- a/src/util.h +++ b/src/util.h @@ -62,8 +62,8 @@ unsigned int ui64_log2(uint64_t u64); /***** Network types and functions. *****/ +typedef struct conn_t conn_t; typedef struct listener_t listener_t; -typedef struct protocol_t protocol_t; typedef struct protocol_vtable protocol_vtable; typedef struct socks_state_t socks_state_t;
participants (1)
-
nickm@torproject.org