tor-commits
Threads by month
- ----- 2026 -----
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- 1 participants
- 214604 discussions
[obfsproxy/master] Allow protocols to allocate extra state for their protocol_params_t as well as their protocol_t. Use this to remove the obfs2 shared secret from the generic protocol_params_t.
by nickm@torproject.org 09 Sep '11
by nickm@torproject.org 09 Sep '11
09 Sep '11
commit ebd15e8027e89ca3027c2ffc2c629a8a552cb772
Author: Zack Weinberg <zackw(a)panix.com>
Date: Sun Jul 24 13:49:51 2011 -0700
Allow protocols to allocate extra state for their protocol_params_t as well as their protocol_t. Use this to remove the obfs2 shared secret from the generic protocol_params_t.
---
src/protocol.c | 15 ++++--
src/protocol.h | 62 +++++++++++------------
src/protocols/dummy.c | 7 +++
src/protocols/obfs2.c | 131 ++++++++++++++++++++++++++----------------------
src/protocols/obfs2.h | 6 ++-
5 files changed, 122 insertions(+), 99 deletions(-)
diff --git a/src/protocol.c b/src/protocol.c
index 8cd069e..212ddaa 100644
--- a/src/protocol.c
+++ b/src/protocol.c
@@ -52,14 +52,19 @@ void
proto_params_free(protocol_params_t *params)
{
obfs_assert(params);
+ obfs_assert(params->vtable);
+ obfs_assert(params->vtable->fini);
- if (params->target_addr)
+ if (params->target_addr) {
evutil_freeaddrinfo(params->target_addr);
- if (params->listen_addr)
+ params->target_addr = NULL;
+ }
+ if (params->listen_addr) {
evutil_freeaddrinfo(params->listen_addr);
- if (params->shared_secret)
- free(params->shared_secret);
- free(params);
+ params->listen_addr = NULL;
+ }
+
+ params->vtable->fini(params);
}
/**
diff --git a/src/protocol.h b/src/protocol.h
index 6fa3eb4..c1189ea 100644
--- a/src/protocol.h
+++ b/src/protocol.h
@@ -11,39 +11,28 @@
struct evbuffer;
/**
- This struct defines parameters of a protocol on a per-listener basis.
-
- By 'per-listener basis' I mean that the parameters defined here will
- be inherited by *all* connections opened from the listener_t that
- owns this protocol_params_t.
-*/
+ This struct defines the protocol-specific state for all connections
+ opened from a particular listener. Each protocol may extend this
+ structure with additional private data by embedding it as the first
+ member of a larger structure (standard fake-inheritance-in-C
+ technique).
+ */
typedef struct protocol_params_t {
const struct protocol_vtable *vtable;
struct evutil_addrinfo *target_addr;
struct evutil_addrinfo *listen_addr;
- char *shared_secret;
- size_t shared_secret_len;
int mode;
} protocol_params_t;
/**
- This protocol specific struct defines the state of the protocol
- on a per-connection basis.
-
- By 'protocol specific' I mean that every protocol has its own
- state struct. (for example, obfs2 has obfs2_state_t). A protocol_t
- struct is always the first member of this struct, and vtable->create
- returns that member (standard fake-inheritance-in-C technique).
- All data other than the vtable is hidden from everything but the
- protocol implementation.
-
- By 'per-connection basis' I mean that the every connection has a
- different protocol_t struct, and that's precisely the reason that
- this struct is owned by the conn_t struct.
+ 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 {
+typedef struct protocol_t {
const struct protocol_vtable *vtable;
-};
+} protocol_t;
/**
This struct defines a protocol and its methods; note that not all
@@ -58,23 +47,29 @@ typedef struct protocol_vtable
/** The short name of this protocol. */
const char *name;
- /** Initialization function: Allocate a 'protocol_params_t' object
- and fill it in from the provided 'options' array. */
- struct protocol_params_t *(*init)(int n_options,
- const char *const *options);
+ /** Initialization: Allocate a 'protocol_params_t' object and fill
+ it in from the provided 'options' array. */
+ protocol_params_t *(*init)(int n_options, const char *const *options);
+
+ /** Finalization: Destroy the provided 'protocol_params_t' object.
+ This function is responsible for deallocating any data that the
+ protocol's extended structure points to, and deallocating the
+ object itself. But it is *not* responsible for deallocating the
+ data pointed to by the generic 'protocol_params_t'; that's
+ already been done. */
+ void (*fini)(protocol_params_t *params);
/** Constructor: Allocates per-connection, protocol-specific state. */
- struct protocol_t *(*create)(struct protocol_params_t *params);
+ protocol_t *(*create)(protocol_params_t *params);
/** Destructor: Destroys per-connection, protocol-specific state. */
- void (*destroy)(struct protocol_t *state);
+ void (*destroy)(protocol_t *state);
/** Perform a connection handshake. Not all protocols have a handshake. */
- int (*handshake)(struct protocol_t *state,
- struct evbuffer *buf);
+ int (*handshake)(protocol_t *state, struct evbuffer *buf);
/** Send data coming downstream from 'source' along to 'dest'. */
- int (*send)(struct protocol_t *state,
+ int (*send)(protocol_t *state,
struct evbuffer *source,
struct evbuffer *dest);
@@ -93,7 +88,8 @@ typedef struct protocol_vtable
#define DEFINE_PROTOCOL_VTABLE(name) \
const struct protocol_vtable name##_vtable = { \
#name, \
- name##_init, name##_create, name##_destroy, \
+ name##_init, name##_fini, \
+ name##_create, name##_destroy, \
name##_handshake, name##_send, name##_recv \
}
diff --git a/src/protocols/dummy.c b/src/protocols/dummy.c
index c12fe01..ae45d9c 100644
--- a/src/protocols/dummy.c
+++ b/src/protocols/dummy.c
@@ -29,6 +29,7 @@ dummy_init(int n_options, const char *const *options)
{
struct protocol_params_t *params
= xzalloc(sizeof(struct protocol_params_t));
+ params->vtable = &dummy_vtable;
if (parse_and_set_options(n_options, options, params) < 0) {
proto_params_free(params);
@@ -87,6 +88,12 @@ usage(void)
"\tobfsproxy dummy socks 127.0.0.1:5000");
}
+static void
+dummy_fini(struct protocol_params_t *params)
+{
+ free(params);
+}
+
/*
This is called everytime we get a connection for the dummy
protocol.
diff --git a/src/protocols/obfs2.c b/src/protocols/obfs2.c
index 42d30c1..f7862fe 100644
--- a/src/protocols/obfs2.c
+++ b/src/protocols/obfs2.c
@@ -16,13 +16,22 @@
static void usage(void);
static int parse_and_set_options(int n_options,
const char *const *options,
- struct protocol_params_t *params);
+ obfs2_params_t *params);
-static inline obfs2_protocol_t *
-downcast(struct protocol_t *proto)
+/** Return true iff the OBFUSCATE_SEED_LENGTH-byte seed in 'seed' is nonzero */
+static inline int
+seed_nonzero(const uchar *seed)
{
- return (obfs2_protocol_t *)
- ((char *)proto - offsetof(obfs2_protocol_t, super));
+ static const uchar OBFUSCATE_ZERO_SEED[OBFUSCATE_SEED_LENGTH] = {0};
+ return memcmp(seed, OBFUSCATE_ZERO_SEED, OBFUSCATE_SEED_LENGTH) != 0;
+}
+
+/** Return true iff the SHARED_SECRET_LENGTH-byte seed in 'seed' is nonzero */
+static inline int
+shared_seed_nonzero(const uchar *seed)
+{
+ static const uchar SHARED_ZERO_SEED[SHARED_SECRET_LENGTH] = {0};
+ return memcmp(seed, SHARED_ZERO_SEED, SHARED_SECRET_LENGTH) != 0;
}
/*
@@ -31,19 +40,19 @@ downcast(struct protocol_t *proto)
Returns 0 on success, -1 on fail.
*/
-static struct protocol_params_t *
+static protocol_params_t *
obfs2_init(int n_options, const char *const *options)
{
- struct protocol_params_t *params
- = xzalloc(sizeof(struct protocol_params_t));
+ obfs2_params_t *params = xzalloc(sizeof(obfs2_params_t));
+ params->super.vtable = &obfs2_vtable;
if (parse_and_set_options(n_options, options, params) < 0) {
- proto_params_free(params);
+ proto_params_free(¶ms->super);
usage();
return NULL;
}
- return params;
+ return ¶ms->super;
}
/**
@@ -51,7 +60,7 @@ obfs2_init(int n_options, const char *const *options)
*/
int
parse_and_set_options(int n_options, const char *const *options,
- struct protocol_params_t *params)
+ obfs2_params_t *params)
{
int got_dest=0;
int got_ss=0;
@@ -67,17 +76,23 @@ parse_and_set_options(int n_options, const char *const *options,
if (!strncmp(*options,"--dest=",7)) {
if (got_dest)
return -1;
- params->target_addr = resolve_address_port(*options+7, 1, 0, NULL);
- if (!params->target_addr)
+ params->super.target_addr =
+ resolve_address_port(*options+7, 1, 0, NULL);
+ if (!params->super.target_addr)
return -1;
got_dest=1;
} else if (!strncmp(*options,"--shared-secret=",16)) {
+ digest_t *c;
if (got_ss)
return -1;
- /* this is freed in proto_params_free() */
- params->shared_secret_len = strlen(*options+16);
- params->shared_secret = xmemdup(*options+16,
- params->shared_secret_len + 1);
+
+ /* ASN we must say in spec that we hash command line shared
+ secret. */
+ c = digest_new();
+ digest_update(c, (uchar*)*options+16, strlen(*options+16));
+ digest_getdigest(c, params->shared_secret, SHARED_SECRET_LENGTH);
+ digest_free(c);
+
got_ss=1;
} else {
log_warn("obfs2: Unknown argument.");
@@ -88,37 +103,36 @@ parse_and_set_options(int n_options, const char *const *options,
if (!strcmp(*options, "client")) {
defport = "48988"; /* bf5c */
- params->mode = LSN_SIMPLE_CLIENT;
+ params->super.mode = LSN_SIMPLE_CLIENT;
} else if (!strcmp(*options, "socks")) {
defport = "23548"; /* 5bf5 */
- params->mode = LSN_SOCKS_CLIENT;
+ params->super.mode = LSN_SOCKS_CLIENT;
} else if (!strcmp(*options, "server")) {
defport = "11253"; /* 2bf5 */
- params->mode = LSN_SIMPLE_SERVER;
+ params->super.mode = LSN_SIMPLE_SERVER;
} else {
log_warn("obfs2: only client/socks/server modes supported.");
return -1;
}
options++;
- params->listen_addr = resolve_address_port(*options, 1, 1, defport);
- if (!params->listen_addr)
+ params->super.listen_addr = resolve_address_port(*options, 1, 1, defport);
+ if (!params->super.listen_addr)
return -1;
/* Validate option selection. */
- if (got_dest && (params->mode == LSN_SOCKS_CLIENT)) {
+ if (got_dest && (params->super.mode == LSN_SOCKS_CLIENT)) {
log_warn("obfs2: You can't be on socks mode and have --dest.");
return -1;
}
- if (!got_dest && (params->mode != LSN_SOCKS_CLIENT)) {
+ if (!got_dest && (params->super.mode != LSN_SOCKS_CLIENT)) {
log_warn("obfs2: client/server mode needs --dest.");
return -1;
}
log_debug("obfs2: Parsed options nicely!");
- params->vtable = &obfs2_vtable;
return 0;
}
@@ -142,13 +156,6 @@ usage(void)
"\tobfs2 server 127.0.0.1:1026");
}
-/** Return true iff the OBFUSCATE_SEED_LENGTH-byte seed in 'seed' is nonzero */
-static int
-seed_nonzero(const uchar *seed)
-{
- return memcmp(seed, OBFUSCATE_ZERO_SEED, OBFUSCATE_SEED_LENGTH) != 0;
-}
-
/**
Derive and return key of type 'keytype' from the seeds currently set in
'state'.
@@ -166,12 +173,12 @@ derive_key(void *s, const char *keytype)
digest_update(c, state->initiator_seed, OBFUSCATE_SEED_LENGTH);
if (seed_nonzero(state->responder_seed))
digest_update(c, state->responder_seed, OBFUSCATE_SEED_LENGTH);
- if (seed_nonzero(state->secret_seed))
+ if (shared_seed_nonzero(state->secret_seed))
digest_update(c, state->secret_seed, SHARED_SECRET_LENGTH);
digest_update(c, (uchar*)keytype, strlen(keytype));
digest_getdigest(c, buf, sizeof(buf));
- if (seed_nonzero(state->secret_seed)) {
+ if (shared_seed_nonzero(state->secret_seed)) {
digest_t *d;
int i;
for (i=0; i < OBFUSCATE_HASH_ITERATIONS; i++) {
@@ -206,13 +213,13 @@ derive_padding_key(void *s, const uchar *seed,
digest_update(c, (uchar*)keytype, strlen(keytype));
if (seed_nonzero(seed))
digest_update(c, seed, OBFUSCATE_SEED_LENGTH);
- if (seed_nonzero(state->secret_seed))
+ if (shared_seed_nonzero(state->secret_seed))
digest_update(c, state->secret_seed, OBFUSCATE_SEED_LENGTH);
digest_update(c, (uchar*)keytype, strlen(keytype));
digest_getdigest(c, buf, sizeof(buf));
digest_free(c);
- if (seed_nonzero(state->secret_seed)) {
+ if (shared_seed_nonzero(state->secret_seed)) {
digest_t *d;
int i;
for (i=0; i < OBFUSCATE_HASH_ITERATIONS; i++) {
@@ -230,22 +237,32 @@ derive_padding_key(void *s, const uchar *seed,
}
/**
+ Frees obfs2 parameters 'p'
+ */
+static void
+obfs2_fini(protocol_params_t *p)
+{
+ obfs2_params_t *params = DOWNCAST(obfs2_params_t, super, p);
+ /* wipe out keys */
+ memset(params, 0x99, sizeof(obfs2_params_t));
+ free(params);
+}
+
+
+/**
This is called everytime we get a connection for the obfs2
protocol.
-
- It sets up the protocol vtable in 'proto_struct' and then attempts
- to create and return a protocol state according to the protocol
- parameters 'params'.
*/
-static struct protocol_t *
-obfs2_create(protocol_params_t *params)
+static protocol_t *
+obfs2_create(protocol_params_t *p)
{
+ obfs2_params_t *params = DOWNCAST(obfs2_params_t, super, p);
obfs2_protocol_t *proto = xzalloc(sizeof(obfs2_protocol_t));
uchar *seed;
const char *send_pad_type;
proto->state = ST_WAIT_FOR_KEY;
- proto->we_are_initiator = (params->mode != LSN_SIMPLE_SERVER);
+ proto->we_are_initiator = (params->super.mode != LSN_SIMPLE_SERVER);
if (proto->we_are_initiator) {
send_pad_type = INITIATOR_PAD_TYPE;
seed = proto->initiator_seed;
@@ -255,19 +272,13 @@ obfs2_create(protocol_params_t *params)
}
/* Generate our seed */
+ memcpy(proto->secret_seed, params->shared_secret, SHARED_SECRET_LENGTH);
+
if (random_bytes(seed, OBFUSCATE_SEED_LENGTH) < 0) {
free(proto);
return NULL;
}
- if (params->shared_secret) {
- /* ASN we must say in spec that we hash command line shared secret. */
- digest_t *c = digest_new();
- digest_update(c, (uchar*)params->shared_secret, params->shared_secret_len);
- digest_getdigest(c, proto->secret_seed, SHARED_SECRET_LENGTH);
- digest_free(c);
- }
-
/* Derive the key for what we're sending */
proto->send_padding_crypto = derive_padding_key(proto, seed, send_pad_type);
proto->super.vtable = &obfs2_vtable;
@@ -278,9 +289,9 @@ obfs2_create(protocol_params_t *params)
Frees obfs2 state 's'
*/
static void
-obfs2_destroy(struct protocol_t *s)
+obfs2_destroy(protocol_t *s)
{
- obfs2_protocol_t *state = downcast(s);
+ obfs2_protocol_t *state = DOWNCAST(obfs2_protocol_t, super, s);
if (state->send_crypto)
crypt_free(state->send_crypto);
if (state->send_padding_crypto)
@@ -301,9 +312,9 @@ obfs2_destroy(struct protocol_t *s)
the evbuffer 'buf'. Return 0 on success, -1 on failure.
*/
static int
-obfs2_handshake(struct protocol_t *s, struct evbuffer *buf)
+obfs2_handshake(protocol_t *s, struct evbuffer *buf)
{
- obfs2_protocol_t *state = downcast(s);
+ obfs2_protocol_t *state = DOWNCAST(obfs2_protocol_t, super, s);
uint32_t magic = htonl(OBFUSCATE_MAGIC_VALUE), plength, send_plength;
uchar msg[OBFUSCATE_MAX_PADDING + OBFUSCATE_SEED_LENGTH + 8];
@@ -367,10 +378,10 @@ obfs2_crypt_and_transmit(crypt_t *crypto,
using the state in 'state'. Returns 0 on success, -1 on failure.
*/
static int
-obfs2_send(struct protocol_t *s,
- struct evbuffer *source, struct evbuffer *dest)
+obfs2_send(protocol_t *s,
+ struct evbuffer *source, struct evbuffer *dest)
{
- obfs2_protocol_t *state = downcast(s);
+ obfs2_protocol_t *state = DOWNCAST(obfs2_protocol_t, super, s);
if (state->send_crypto) {
/* First of all, send any data that we've been waiting to send. */
@@ -440,10 +451,10 @@ init_crypto(void *s)
* our callers that they must call obfs2_send() immediately.
*/
static enum recv_ret
-obfs2_recv(struct protocol_t *s, struct evbuffer *source,
+obfs2_recv(protocol_t *s, struct evbuffer *source,
struct evbuffer *dest)
{
- obfs2_protocol_t *state = downcast(s);
+ obfs2_protocol_t *state = DOWNCAST(obfs2_protocol_t, super, s);
enum recv_ret r=0;
if (state->state == ST_WAIT_FOR_KEY) {
diff --git a/src/protocols/obfs2.h b/src/protocols/obfs2.h
index e93fbcd..eb55a9f 100644
--- a/src/protocols/obfs2.h
+++ b/src/protocols/obfs2.h
@@ -25,7 +25,6 @@ extern const struct protocol_vtable obfs2_vtable;
#define OBFUSCATE_MAGIC_VALUE 0x2BF5CA7E
#define OBFUSCATE_SEED_LENGTH 16
#define OBFUSCATE_MAX_PADDING 8192
-#define OBFUSCATE_ZERO_SEED "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
#define OBFUSCATE_HASH_ITERATIONS 100000
#define INITIATOR_PAD_TYPE "Initiator obfuscation padding"
@@ -35,6 +34,11 @@ extern const struct protocol_vtable obfs2_vtable;
#define SHARED_SECRET_LENGTH SHA256_LENGTH
+typedef struct obfs2_params_t {
+ protocol_params_t super;
+ uchar shared_secret[SHARED_SECRET_LENGTH];
+} obfs2_params_t;
+
typedef struct obfs2_protocol_t {
struct protocol_t super;
1
0
[obfsproxy/master] Use smartlist instead of dll for the connections and listeners lists.
by nickm@torproject.org 09 Sep '11
by nickm@torproject.org 09 Sep '11
09 Sep '11
commit ec5edc941ef13787f1baae0e741a05536d374571
Author: Zack Weinberg <zackw(a)panix.com>
Date: Tue Jul 19 10:46:23 2011 -0700
Use smartlist instead of dll for the connections and listeners lists.
---
src/main.c | 5 +--
src/network.c | 141 ++++++++++++++++++++++++++++-----------------------------
src/network.h | 3 +-
src/util.c | 112 ---------------------------------------------
src/util.h | 49 +++++++-------------
5 files changed, 88 insertions(+), 222 deletions(-)
diff --git a/src/main.c b/src/main.c
index a7aa298..cf811fa 100644
--- a/src/main.c
+++ b/src/main.c
@@ -372,10 +372,7 @@ main(int argc, const char **argv)
log_info("Exiting.");
close_obfsproxy_logfile();
-
- free_all_listeners(); /* free all listeners in our listener dll */
-
- /* We are exiting. Clean everything. */
+ free_all_listeners();
free(protocol_options);
free(n_options_array);
free(protocols);
diff --git a/src/network.c b/src/network.c
index 35e4eaf..4a85478 100644
--- a/src/network.c
+++ b/src/network.c
@@ -7,6 +7,7 @@
#define NETWORK_PRIVATE
#include "network.h"
+#include "container.h"
#include "main.h"
#include "socks.h"
#include "protocol.h"
@@ -24,19 +25,16 @@
#include <ws2tcpip.h> /* socklen_t */
#endif
-/** Doubly linked list holding all our listeners. */
-static dll_t listener_list = DLL_INIT();
+/** All our listeners. */
+static smartlist_t *listeners;
struct listener_t {
- dll_node_t dll_node;
struct evconnlistener *listener;
protocol_params_t *proto_params;
};
-/** Doubly linked list holding all connections. */
-static dll_t conn_list = DLL_INIT();
-/** Active connection counter */
-static int n_connections=0;
+/** All active connections. */
+static smartlist_t *connections;
/** Flag toggled when obfsproxy is shutting down. It blocks new
connections and shutdowns when the last connection is closed. */
@@ -64,7 +62,7 @@ static void output_event_cb(struct bufferevent *bev, short what, void *arg);
If 'barbaric' is set, we forcefully close all open connections and
finish shutdown.
-
+
(Only called by signal handlers)
*/
void
@@ -73,31 +71,32 @@ start_shutdown(int barbaric)
if (!shutting_down)
shutting_down=1;
- if (!n_connections) {
- finish_shutdown();
- return;
- }
+ if (barbaric)
+ close_all_connections();
- if (barbaric) {
- if (n_connections)
- close_all_connections();
- return;
+ if (connections && smartlist_len(connections) == 0) {
+ smartlist_free(connections);
+ connections = NULL;
}
-}
+
+ if (!connections)
+ finish_shutdown();
+}
/**
Closes all open connections.
-*/
+*/
static void
close_all_connections(void)
{
- /** Traverse the dll and close all connections */
- while (conn_list.head) {
- conn_t *conn = DOWNCAST(conn_t, dll_node, conn_list.head);
- conn_free(conn); /* removes it */
- }
- obfs_assert(!n_connections);
+ if (!connections)
+ return;
+ SMARTLIST_FOREACH(connections, conn_t *, conn,
+ { conn_free(conn); });
+ smartlist_free(connections);
+ connections = NULL;
}
+
/**
This function spawns a listener configured according to the
provided 'protocol_params_t' object'. Returns the listener on
@@ -107,7 +106,6 @@ close_all_connections(void)
protocol_params_t object provided; if it fails, the protocol_params_t
object is deallocated.
*/
-
listener_t *
listener_new(struct event_base *base,
protocol_params_t *proto_params)
@@ -127,12 +125,15 @@ listener_new(struct event_base *base,
if (!lsn->listener) {
log_warn("Failed to create listener!");
- listener_free(lsn);
+ proto_params_free(lsn->proto_params);
+ free(lsn);
return NULL;
}
- /** If we don't have a connection dll, create one now. */
- dll_append(&listener_list, &lsn->dll_node);
+ /* If we don't have a listener list, create one now. */
+ if (!listeners)
+ listeners = smartlist_create();
+ smartlist_add(listeners, lsn);
return lsn;
}
@@ -140,17 +141,13 @@ listener_new(struct event_base *base,
/**
Deallocates listener_t 'lsn'.
*/
-void
+static void
listener_free(listener_t *lsn)
{
if (lsn->listener)
evconnlistener_free(lsn->listener);
if (lsn->proto_params)
proto_params_free(lsn->proto_params);
-
- dll_remove(&listener_list, &lsn->dll_node);
-
- memset(lsn, 0xb0, sizeof(listener_t));
free(lsn);
}
@@ -160,20 +157,14 @@ listener_free(listener_t *lsn)
void
free_all_listeners(void)
{
- static int called_already=0;
-
- if (called_already)
+ if (!listeners)
return;
-
log_info("Closing all listeners.");
- /* Iterate listener doubly linked list and free them all. */
- while (listener_list.head) {
- listener_t *listener = DOWNCAST(listener_t, dll_node, listener_list.head);
- listener_free(listener);
- }
-
- called_already++;
+ SMARTLIST_FOREACH(listeners, listener_t *, lsn,
+ { listener_free(lsn); });
+ smartlist_free(listeners);
+ listeners = NULL;
}
/**
@@ -184,17 +175,13 @@ free_all_listeners(void)
*/
static void
simple_listener_cb(struct evconnlistener *evcl,
- evutil_socket_t fd, struct sockaddr *sourceaddr,
+ 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));
- n_connections++; /* If we call conn_free() later on error, it will decrement
- * n_connections. Therefore, we had better increment it at
- * the start. */
-
log_debug("Got a connection attempt.");
conn->mode = lsn->proto_params->mode;
@@ -266,14 +253,15 @@ simple_listener_cb(struct evconnlistener *evcl,
bufferevent_enable(conn->output, EV_READ|EV_WRITE);
}
- /* add conn to the linked list of connections */
- if (dll_append(&conn_list, &conn->dll_node)<0)
- goto err;
+ /* add conn to the connection list */
+ if (!connections)
+ connections = smartlist_create();
+ smartlist_add(connections, conn);
log_debug("Connection setup completed. "
- "We currently have %d connections!", n_connections);
-
+ "We currently have %d connections!", smartlist_len(connections));
return;
+
err:
if (conn)
conn_free(conn);
@@ -296,39 +284,48 @@ conn_free(conn_t *conn)
if (conn->output)
bufferevent_free(conn->output);
- /* remove conn from the linked list of connections */
- dll_remove(&conn_list, &conn->dll_node);
- n_connections--;
-
memset(conn, 0x99, sizeof(conn_t));
free(conn);
+}
- obfs_assert(n_connections>=0);
+/**
+ Closes a fully open connection.
+*/
+static void
+close_conn(conn_t *conn)
+{
+ obfs_assert(connections);
+ smartlist_remove(connections, conn);
+ conn_free(conn);
log_debug("Connection destroyed. "
- "We currently have %d connections!", n_connections);
+ "We currently have %d connections!", smartlist_len(connections));
/** If this was the last connection AND we are shutting down,
finish shutdown. */
- if (!n_connections && shutting_down) {
- finish_shutdown();
+ if (smartlist_len(connections) == 0) {
+ smartlist_free(connections);
+ connections = NULL;
}
+
+ if (!connections && shutting_down)
+ finish_shutdown();
}
/**
Closes associated connection if the output evbuffer of 'bev' is
empty.
-*/
+*/
static void
close_conn_on_flush(struct bufferevent *bev, void *arg)
{
conn_t *conn = arg;
- if (0 == evbuffer_get_length(bufferevent_get_output(bev)))
- conn_free(conn);
+ if (evbuffer_get_length(bufferevent_get_output(bev)) == 0)
+ close_conn(conn);
}
-/**
- This callback is responsible for handling SOCKS traffic.
+/**
+ This callback is responsible for handling SOCKS traffic.
*/
static void
socks_read_cb(struct bufferevent *bev, void *arg)
@@ -357,7 +354,7 @@ socks_read_cb(struct bufferevent *bev, void *arg)
if (r < 0) {
/* XXXX send socks reply */
- conn_free(conn);
+ close_conn(conn);
return;
}
bufferevent_disable(conn->input, EV_READ|EV_WRITE);
@@ -372,7 +369,7 @@ socks_read_cb(struct bufferevent *bev, void *arg)
if (socks_ret == SOCKS_INCOMPLETE)
return; /* need to read more data. */
else if (socks_ret == SOCKS_BROKEN)
- conn_free(conn); /* XXXX maybe send socks reply */
+ close_conn(conn); /* XXXX maybe send socks reply */
else if (socks_ret == SOCKS_CMD_NOT_CONNECT) {
bufferevent_enable(bev, EV_WRITE);
bufferevent_disable(bev, EV_READ);
@@ -398,7 +395,7 @@ plaintext_read_cb(struct bufferevent *bev, void *arg)
if (proto_send(conn->proto,
bufferevent_get_input(bev),
bufferevent_get_output(other)) < 0)
- conn_free(conn);
+ close_conn(conn);
}
/**
@@ -420,7 +417,7 @@ obfuscated_read_cb(struct bufferevent *bev, void *arg)
bufferevent_get_output(other));
if (r == RECV_BAD)
- conn_free(conn);
+ close_conn(conn);
else if (r == RECV_SEND_PENDING)
proto_send(conn->proto,
bufferevent_get_input(conn->input),
@@ -439,7 +436,7 @@ error_or_eof(conn_t *conn,
if (conn->flushing || ! conn->is_open ||
0 == evbuffer_get_length(bufferevent_get_output(bev_flush))) {
- conn_free(conn);
+ close_conn(conn);
return;
}
diff --git a/src/network.h b/src/network.h
index e631697..7ba9afc 100644
--- a/src/network.h
+++ b/src/network.h
@@ -32,7 +32,6 @@ typedef struct listener_t listener_t;
listener_t *listener_new(struct event_base *base,
struct protocol_params_t *params);
-void listener_free(listener_t *listener);
void free_all_listeners(void);
void start_shutdown(int barbaric);
@@ -44,7 +43,6 @@ struct socks_state_t;
struct protocol_t;
typedef struct conn_t {
- dll_node_t dll_node;
struct socks_state_t *socks_state;
struct protocol_t *proto; /* ASN Do we like this here? We probably don't.
But it's so convenient!! So convenient! */
@@ -54,6 +52,7 @@ typedef struct conn_t {
unsigned int flushing : 1;
unsigned int is_open : 1;
} conn_t;
+
#endif
#endif
diff --git a/src/util.c b/src/util.c
index 9b9fa48..a4801a0 100644
--- a/src/util.c
+++ b/src/util.c
@@ -281,118 +281,6 @@ ascii_strlower(char *s)
}
}
-/************************ Doubly Linked List (DLL) ******************/
-
-/**
- Insert 'new_node' after 'node' in the doubly linked list 'list'.
-*/
-static void
-dll_insert_after(dll_t *list, dll_node_t *node, dll_node_t *new_node)
-{
- obfs_assert(node);
- obfs_assert(new_node);
-
- if (!list)
- return;
-
- new_node->prev = node;
- new_node->next = node->next;
- if (!node->next)
- list->tail = new_node;
- else
- node->next->prev = new_node;
- node->next = new_node;
-}
-
-/**
- Insert 'new_node' before 'node' in the doubly linked list 'list'.
-*/
-static void
-dll_insert_before(dll_t *list, dll_node_t *node, dll_node_t *new_node)
-{
- obfs_assert(node);
- obfs_assert(new_node);
-
- if (!list)
- return;
-
- new_node->prev = node->prev;
- new_node->next = node;
- if (!node->prev)
- list->head = new_node;
- else
- node->prev->next = new_node;
- node->prev = new_node;
-}
-
-/** Initialize <b>list</b> as an empty list. */
-void
-dll_init(dll_t *list)
-{
- list->head = list->tail = NULL;
-}
-
-/**
- Insert 'node' in the beginning of the doubly linked 'list'.
-*/
-static void
-dll_insert_beginning(dll_t *list, dll_node_t *node)
-{
- obfs_assert(node);
-
- if (!list)
- return;
-
- if (!list->head) {
- list->head = node;
- list->tail = node;
- node->prev = NULL;
- node->next = NULL;
- } else {
- dll_insert_before(list, list->head, node);
- }
-}
-
-/**
- Appends 'data' to the end of the doubly linked 'list'.
- Returns 1 on success, -1 on fail.
-*/
-int
-dll_append(dll_t *list, dll_node_t *node)
-{
- obfs_assert(list);
- obfs_assert(node);
-
- if (!list->tail)
- dll_insert_beginning(list, node);
- else
- dll_insert_after(list, list->tail, node);
-
- return 1;
-}
-
-/**
- Removes 'node' from the doubly linked list 'list'.
- It frees the list node, but leaves its data intact.
-*/
-void
-dll_remove(dll_t *list, dll_node_t *node)
-{
- obfs_assert(node);
-
- if (!list)
- return;
-
- if (!node->prev)
- list->head = node->next;
- else
- node->prev->next = node->next;
- if (!node->next)
- list->tail = node->prev;
- else
- node->next->prev = node->prev;
-}
-
/************************ Logging Subsystem *************************/
/** The code of this section was to a great extent shamelessly copied
off tor. It's basicaly a stripped down version of tor's logging
diff --git a/src/util.h b/src/util.h
index e44a711..a88d06c 100644
--- a/src/util.h
+++ b/src/util.h
@@ -6,10 +6,16 @@
#define UTIL_H
#include "config.h"
-#include <stdarg.h> /* for va_list */
-#include <stddef.h> /* size_t, offsetof, NULL, etc */
+#include <stdarg.h> /* va_list */
+#include <stddef.h> /* size_t, ptrdiff_t, offsetof, NULL */
#include <stdint.h> /* intN_t, uintN_t */
+struct sockaddr;
+struct event_base;
+struct evdns_base;
+
+/***** Type annotations. *****/
+
#ifndef __GNUC__
#define __attribute__(x) /* nothing */
#endif
@@ -19,10 +25,6 @@
#define ATTR_PRINTF_3 __attribute__((format(printf, 3, 4)))
#define ATTR_PURE __attribute__((pure))
-struct sockaddr;
-struct event_base;
-struct evdns_base;
-
/***** Memory allocation. *****/
/* Because this isn't Tor and functions named "tor_whatever" would be
@@ -37,11 +39,16 @@ void *xmemdup(const void *ptr, size_t size) ATTR_MALLOC;
char *xstrdup(const char *s) ATTR_MALLOC;
char *xstrndup(const char *s, size_t maxsize) ATTR_MALLOC;
+/***** Pseudo-inheritance. *****/
+
+#define DOWNCAST(container_type, element, ptr) \
+ (container_type*)( ((char*)ptr) - offsetof(container_type, element) )
+
/***** Math. *****/
unsigned int ui64_log2(uint64_t u64);
-/***** Network functions stuff. *****/
+/***** Network functions. *****/
int resolve_address_port(const char *address,
int nodns, int passive,
@@ -52,7 +59,7 @@ int resolve_address_port(const char *address,
struct evdns_base *get_evdns_base(void);
int init_evdns_base(struct event_base *base);
-/***** String functions stuff. *****/
+/***** String functions. *****/
static inline int ascii_isspace(unsigned char c)
{
@@ -72,31 +79,9 @@ int obfs_snprintf(char *str, size_t size,
const char *format, ...)
ATTR_PRINTF_3;
-/***** Doubly Linked List stuff. *****/
-
-#define DOWNCAST(container_type, element, ptr) \
- (container_type*)( ((char*)ptr) - offsetof(container_type, element) )
-
-/** A doubly linked list node.
- [algorithms ripped off Wikipedia (Doubly_linked_list) ] */
-typedef struct dll_node_t {
- struct dll_node_t *next, *prev;
-} dll_node_t;
-
-/** A doubly linked list. */
-typedef struct dll_t {
- struct dll_node_t *head;
- struct dll_node_t *tail;
-} dll_t;
-
-void dll_init(dll_t *list);
-int dll_append(dll_t *list, dll_node_t *node);
-void dll_remove(dll_t *list, dll_node_t *node);
-#define DLL_INIT() { NULL, NULL }
-
-/***** Logging subsystem stuff. *****/
+/***** Logging. *****/
-/** Logging methods */
+/** Log destinations */
/** Spit log messages on stdout. */
#define LOG_METHOD_STDOUT 1
1
0
commit 4e90322f70ceaeebc4308d0412262df2e714333b
Author: Zack Weinberg <zackw(a)panix.com>
Date: Wed Jul 20 15:14:12 2011 -0700
Add unit test for dummy protocol
---
Makefile.am | 5 +-
src/test/unittest.c | 6 +-
src/test/unittest_dummy.c | 200 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 207 insertions(+), 4 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index ff518ad..fe47256 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -29,8 +29,9 @@ unittests_SOURCES = \
src/test/unittest.c \
src/test/unittest_container.c \
src/test/unittest_crypt.c \
- src/test/unittest_obfs2.c \
- src/test/unittest_socks.c
+ src/test/unittest_socks.c \
+ src/test/unittest_dummy.c \
+ src/test/unittest_obfs2.c
noinst_HEADERS = \
src/container.h \
diff --git a/src/test/unittest.c b/src/test/unittest.c
index f872550..6ff938e 100644
--- a/src/test/unittest.c
+++ b/src/test/unittest.c
@@ -7,14 +7,16 @@
extern struct testcase_t container_tests[];
extern struct testcase_t crypt_tests[];
-extern struct testcase_t obfs2_tests[];
extern struct testcase_t socks_tests[];
+extern struct testcase_t dummy_tests[];
+extern struct testcase_t obfs2_tests[];
struct testgroup_t groups[] = {
{ "container/", container_tests },
{ "crypt/", crypt_tests },
- { "obfs2/", obfs2_tests },
{ "socks/", socks_tests },
+ { "dummy/", dummy_tests },
+ { "obfs2/", obfs2_tests },
END_OF_GROUPS
};
diff --git a/src/test/unittest_dummy.c b/src/test/unittest_dummy.c
new file mode 100644
index 0000000..1739e1f
--- /dev/null
+++ b/src/test/unittest_dummy.c
@@ -0,0 +1,200 @@
+/* Copyright 2011 Nick Mathewson, George Kadianakis
+ See LICENSE for other credits and copying information
+*/
+
+#include "../util.h"
+#include "../protocol.h"
+#include "tinytest_macros.h"
+
+#include <event2/buffer.h>
+
+static void
+test_dummy_option_parsing(void *unused)
+{
+ struct option_parsing_case {
+ struct protocol_params_t *result;
+ short should_succeed;
+ short n_opts;
+ const char *const opts[4];
+ };
+ static struct option_parsing_case cases[] = {
+ /* wrong number of options */
+ { 0, 0, 1, {"dummy"} },
+ { 0, 0, 2, {"dummy", "client"} },
+ { 0, 0, 4, {"dummy", "client", "127.0.0.1:5552", "oops"} },
+ { 0, 0, 4, {"dummy", "--frobozz", "client", "127.0.0.1:5552"} },
+ /* unrecognized mode */
+ { 0, 0, 3, {"dummy", "floodcontrol", "127.0.0.1:5552" } },
+ /* bad address */
+ { 0, 0, 3, {"dummy", "client", "@:5552"} },
+ { 0, 0, 3, {"dummy", "client", "127.0.0.1:notanumber"} },
+ /* should succeed */
+ { 0, 1, 3, {"dummy", "client", "127.0.0.1:5552" } },
+ { 0, 1, 3, {"dummy", "client", "127.0.0.1" } },
+ { 0, 1, 3, {"dummy", "server", "127.0.0.1:5552" } },
+ { 0, 1, 3, {"dummy", "socks", "127.0.0.1:5552" } },
+
+ { 0, 0, 0, {0} }
+ };
+
+ /* Suppress logs for the duration of this function. */
+ log_set_method(LOG_METHOD_NULL, NULL);
+
+ struct option_parsing_case *c;
+ for (c = cases; c->n_opts; c++) {
+ c->result = proto_params_init(c->n_opts, c->opts);
+ if (c->should_succeed)
+ tt_ptr_op(c->result, !=, NULL);
+ else
+ tt_ptr_op(c->result, ==, NULL);
+ }
+
+ end:
+ for (c = cases; c->n_opts; c++)
+ if (c->result)
+ proto_params_free(c->result);
+
+ /* Unsuspend logging */
+ log_set_method(LOG_METHOD_STDOUT, NULL);
+}
+
+/* All the tests below use this test environment: */
+struct test_dummy_state
+{
+ struct protocol_params_t *proto_params_client;
+ struct protocol_params_t *proto_params_server;
+ struct protocol_t *client_proto;
+ struct protocol_t *server_proto;
+ struct evbuffer *output_buffer;
+ struct evbuffer *dummy_buffer;
+};
+
+static int
+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->proto_params_client)
+ proto_params_free(s->proto_params_client);
+ if (s->proto_params_server)
+ proto_params_free(s->proto_params_server);
+
+ if (s->output_buffer)
+ evbuffer_free(s->output_buffer);
+ if (s->dummy_buffer)
+ evbuffer_free(s->dummy_buffer);
+
+ free(state);
+ return 1;
+}
+
+#define ALEN(x) (sizeof x/sizeof x[0])
+
+static const char *const options_client[] =
+ {"dummy", "socks", "127.0.0.1:1800"};
+
+static const char *const options_server[] =
+ {"dummy", "server", "127.0.0.1:1800"};
+
+static void *
+setup_dummy_state(const struct testcase_t *unused)
+{
+ struct test_dummy_state *s = xzalloc(sizeof(struct test_dummy_state));
+
+ s->proto_params_client =
+ proto_params_init(ALEN(options_client), options_client);
+ tt_assert(s->proto_params_client);
+
+ s->proto_params_server =
+ proto_params_init(ALEN(options_server), options_server);
+ tt_assert(s->proto_params_server);
+
+ s->client_proto = proto_create(s->proto_params_client);
+ tt_assert(s->client_proto);
+
+ s->server_proto = proto_create(s->proto_params_server);
+ tt_assert(s->server_proto);
+
+ s->output_buffer = evbuffer_new();
+ tt_assert(s->output_buffer);
+
+ s->dummy_buffer = evbuffer_new();
+ tt_assert(s->dummy_buffer);
+
+ return s;
+
+ end:
+ cleanup_dummy_state(NULL, s);
+ return NULL;
+}
+
+static const struct testcase_setup_t dummy_fixture =
+ { setup_dummy_state, cleanup_dummy_state };
+
+static void
+test_dummy_transfer(void *state)
+{
+ struct test_dummy_state *s = (struct test_dummy_state *)state;
+ int n;
+ struct evbuffer_iovec v[2];
+
+ /* 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);
+
+ /* 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(evbuffer_get_length(s->output_buffer), ==, 0);
+
+ const char *msg1 = "this is a 54-byte message passed from client to server";
+ const char *msg2 = "this is a 55-byte message passed from server to client!";
+
+ /* client -> server */
+ evbuffer_add(s->dummy_buffer, msg1, 54);
+ proto_send(s->client_proto, s->dummy_buffer, s->output_buffer);
+
+ tt_assert(RECV_GOOD == proto_recv(s->server_proto, s->output_buffer,
+ s->dummy_buffer));
+
+ n = evbuffer_peek(s->dummy_buffer, -1, NULL, &v[0], 2);
+ tt_int_op(n, ==, 1); /* expect contiguous data */
+ tt_int_op(0, ==, strncmp(msg1, v[0].iov_base, 54));
+
+ /* emptying dummy_buffer before next test */
+ size_t buffer_len = evbuffer_get_length(s->dummy_buffer);
+ tt_int_op(0, ==, evbuffer_drain(s->dummy_buffer, buffer_len));
+
+ /* client <- server */
+ evbuffer_add(s->dummy_buffer, msg2, 55);
+ tt_int_op(0, <=, proto_send(s->server_proto, s->dummy_buffer,
+ s->output_buffer));
+
+ tt_assert(RECV_GOOD == proto_recv(s->client_proto, s->output_buffer,
+ s->dummy_buffer));
+
+ n = evbuffer_peek(s->dummy_buffer, -1, NULL, &v[1], 2);
+ tt_int_op(n, ==, 1); /* expect contiguous data */
+ tt_int_op(0, ==, strncmp(msg2, v[1].iov_base, 55));
+
+ end:;
+}
+
+#define T(name) \
+ { #name, test_dummy_##name, 0, NULL, NULL }
+
+#define TF(name) \
+ { #name, test_dummy_##name, 0, &dummy_fixture, NULL }
+
+struct testcase_t dummy_tests[] = {
+ T(option_parsing),
+ TF(transfer),
+ END_OF_TESTCASES
+};
1
0
[obfsproxy/master] Give dummy pseudo-subclasses of protocol_t and protocol_params_t even though presently it doesn't need them; reintroduce type-safe downcast wrappers to both protocols.
by nickm@torproject.org 09 Sep '11
by nickm@torproject.org 09 Sep '11
09 Sep '11
commit 8800360fa9dc8f60b9d4d441079f7fc9f968e587
Author: Zack Weinberg <zackw(a)panix.com>
Date: Sun Jul 24 17:37:47 2011 -0700
Give dummy pseudo-subclasses of protocol_t and protocol_params_t even though presently it doesn't need them; reintroduce type-safe downcast wrappers to both protocols.
---
src/protocols/dummy.c | 111 ++++++++++++++++++++++---------------------------
src/protocols/dummy.h | 25 +++++++++++
src/protocols/obfs2.c | 72 ++++++++++++++++----------------
3 files changed, 111 insertions(+), 97 deletions(-)
diff --git a/src/protocols/dummy.c b/src/protocols/dummy.c
index 26fe525..e6c4ca5 100644
--- a/src/protocols/dummy.c
+++ b/src/protocols/dummy.c
@@ -4,18 +4,29 @@
#include "../util.h"
+#define PROTOCOL_DUMMY_PRIVATE
#include "dummy.h"
-#include "../protocol.h"
#include <stdlib.h>
#include <string.h>
-
#include <event2/buffer.h>
-static void usage(void);
+/* type-safe downcast wrappers */
+static inline dummy_params_t *
+downcast_params(protocol_params_t *p)
+{
+ return DOWNCAST(dummy_params_t, super, p);
+}
+
+static inline dummy_protocol_t *
+downcast_protocol(protocol_t *p)
+{
+ return DOWNCAST(dummy_protocol_t, super, p);
+}
+
static int parse_and_set_options(int n_options,
const char *const *options,
- protocol_params_t *params);
+ dummy_params_t *params);
/**
This function populates 'params' according to 'options' and sets up
@@ -27,16 +38,24 @@ static int parse_and_set_options(int n_options,
static protocol_params_t *
dummy_init(int n_options, const char *const *options)
{
- protocol_params_t *params = xzalloc(sizeof(protocol_params_t));
- params->vtable = &dummy_vtable;
+ dummy_params_t *params = xzalloc(sizeof(dummy_params_t));
+ params->super.vtable = &dummy_vtable;
- if (parse_and_set_options(n_options, options, params) < 0) {
- proto_params_free(params);
- usage();
- return NULL;
- }
+ if (parse_and_set_options(n_options, options, params) == 0)
+ return ¶ms->super;
- return params;
+ proto_params_free(¶ms->super);
+ log_warn("dummy syntax:\n"
+ "\tdummy <mode> <listen_address> [<target_address>]\n"
+ "\t\tmode ~ server|client|socks\n"
+ "\t\tlisten_address, target_address ~ host:port\n"
+ "\ttarget_address is required for server and client mode,\n"
+ "\tand forbidden for socks mode.\n"
+ "Examples:\n"
+ "\tobfsproxy dummy socks 127.0.0.1:5000\n"
+ "\tobfsproxy dummy client 127.0.0.1:5000 192.168.1.99:11253\n"
+ "\tobfsproxy dummy server 192.168.1.99:11253 127.0.0.1:9005");
+ return NULL;
}
/**
@@ -44,7 +63,7 @@ dummy_init(int n_options, const char *const *options)
*/
static int
parse_and_set_options(int n_options, const char *const *options,
- protocol_params_t *params)
+ dummy_params_t *params)
{
const char* defport;
@@ -53,55 +72,36 @@ parse_and_set_options(int n_options, const char *const *options,
if (!strcmp(options[0], "client")) {
defport = "48988"; /* bf5c */
- params->mode = LSN_SIMPLE_CLIENT;
+ params->super.mode = LSN_SIMPLE_CLIENT;
} else if (!strcmp(options[0], "socks")) {
defport = "23548"; /* 5bf5 */
- params->mode = LSN_SOCKS_CLIENT;
+ params->super.mode = LSN_SOCKS_CLIENT;
} else if (!strcmp(options[0], "server")) {
defport = "11253"; /* 2bf5 */
- params->mode = LSN_SIMPLE_SERVER;
+ params->super.mode = LSN_SIMPLE_SERVER;
} else
return -1;
- if (n_options != (params->mode == LSN_SOCKS_CLIENT ? 2 : 3))
+ if (n_options != (params->super.mode == LSN_SOCKS_CLIENT ? 2 : 3))
return -1;
- params->listen_addr = resolve_address_port(options[1], 1, 1, defport);
- if (!params->listen_addr)
+ params->super.listen_addr = resolve_address_port(options[1], 1, 1, defport);
+ if (!params->super.listen_addr)
return -1;
- if (params->mode != LSN_SOCKS_CLIENT) {
- params->target_addr = resolve_address_port(options[2], 1, 0, NULL);
- if (!params->target_addr)
+ if (params->super.mode != LSN_SOCKS_CLIENT) {
+ params->super.target_addr = resolve_address_port(options[2], 1, 0, NULL);
+ if (!params->super.target_addr)
return -1;
}
- params->vtable = &dummy_vtable;
return 0;
}
-/**
- Prints dummy protocol usage information.
-*/
-static void
-usage(void)
-{
- log_warn("dummy syntax:\n"
- "\tdummy <mode> <listen_address> [<target_address>]\n"
- "\t\tmode ~ server|client|socks\n"
- "\t\tlisten_address, target_address ~ host:port\n"
- "\ttarget_address is required for server and client mode,\n"
- "\tand forbidden for socks mode.\n"
- "Examples:\n"
- "\tobfsproxy dummy socks 127.0.0.1:5000\n"
- "\tobfsproxy dummy client 127.0.0.1:5000 192.168.1.99:11253\n"
- "\tobfsproxy dummy server 192.168.1.99:11253 127.0.0.1:9005");
-}
-
static void
dummy_fini(protocol_params_t *params)
{
- free(params);
+ free(downcast_params(params));
}
/*
@@ -112,44 +112,33 @@ dummy_fini(protocol_params_t *params)
static protocol_t *
dummy_create(protocol_params_t *params)
{
- /* Dummy needs no per-connection protocol-specific state. */
- protocol_t *proto = xzalloc(sizeof(protocol_t));
- proto->vtable = &dummy_vtable;
- return proto;
+ dummy_protocol_t *proto = xzalloc(sizeof(dummy_protocol_t));
+ proto->super.vtable = &dummy_vtable;
+ return &proto->super;
}
static void
dummy_destroy(protocol_t *proto)
{
- free(proto);
+ free(downcast_protocol(proto));
}
-/**
- Responsible for sending data according to the dummy protocol.
-
- The dummy protocol just puts the data of 'source' in 'dest'.
-*/
+/** Dummy has no handshake */
static int
dummy_handshake(protocol_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(protocol_t *proto, struct evbuffer *source, struct evbuffer *dest)
{
return evbuffer_add_buffer(dest,source);
}
-/*
- Responsible for receiving data according to the dummy protocol.
-
- The dummy protocol just puts the data of 'source' into 'dest'.
-*/
static enum recv_ret
-dummy_recv(protocol_t *proto,
- struct evbuffer *source, struct evbuffer *dest)
+dummy_recv(protocol_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 e7dbd2a..944fe1b 100644
--- a/src/protocols/dummy.h
+++ b/src/protocols/dummy.h
@@ -7,4 +7,29 @@
struct protocol_vtable;
extern const struct protocol_vtable dummy_vtable;
+#ifdef PROTOCOL_DUMMY_PRIVATE
+
+/* ==========
+ These definitions are not part of the dummy protocol interface.
+ They're exposed here so that the unit tests can use them.
+ ==========
+*/
+
+#include "../protocol.h"
+
+/* Dummy presently needs no extensions to the generic protocol
+ structures, but we have shims for future expansion, and also
+ because, if you're using dummy as a template, you probably will
+ want to extend the generic structures. */
+
+typedef struct dummy_params_t {
+ protocol_params_t super;
+} dummy_params_t;
+
+typedef struct dummy_protocol_t {
+ protocol_t super;
+} dummy_protocol_t;
+
+#endif
+
#endif
diff --git a/src/protocols/obfs2.c b/src/protocols/obfs2.c
index f7862fe..166c54a 100644
--- a/src/protocols/obfs2.c
+++ b/src/protocols/obfs2.c
@@ -6,14 +6,24 @@
#define PROTOCOL_OBFS2_PRIVATE
#include "obfs2.h"
-#include "../protocol.h"
#include <stdlib.h>
#include <string.h>
-
#include <event2/buffer.h>
-static void usage(void);
+/* type-safe downcast wrappers */
+static inline obfs2_params_t *
+downcast_params(protocol_params_t *p)
+{
+ return DOWNCAST(obfs2_params_t, super, p);
+}
+
+static inline obfs2_protocol_t *
+downcast_protocol(protocol_t *p)
+{
+ return DOWNCAST(obfs2_protocol_t, super, p);
+}
+
static int parse_and_set_options(int n_options,
const char *const *options,
obfs2_params_t *params);
@@ -44,15 +54,25 @@ static protocol_params_t *
obfs2_init(int n_options, const char *const *options)
{
obfs2_params_t *params = xzalloc(sizeof(obfs2_params_t));
-
params->super.vtable = &obfs2_vtable;
- if (parse_and_set_options(n_options, options, params) < 0) {
- proto_params_free(¶ms->super);
- usage();
- return NULL;
- }
- return ¶ms->super;
+ if (parse_and_set_options(n_options, options, params) == 0)
+ return ¶ms->super;
+
+ proto_params_free(¶ms->super);
+ log_warn("You failed at creating a correct obfs2 line.\n"
+ "obfs2 syntax:\n"
+ "\tobfs2 [obfs2_args] obfs2_opts\n"
+ "\t'obfs2_opts':\n"
+ "\t\tmode ~ server|client|socks\n"
+ "\t\tlisten address ~ host:port\n"
+ "\t'obfs2_args':\n"
+ "\t\tDestination Address ~ --dest=host:port\n"
+ "\t\tShared Secret ~ --shared-secret=<secret>\n"
+ "\tExample:\n"
+ "\tobfsproxy --dest=127.0.0.1:666 --shared-secret=himitsu "
+ "\tobfs2 server 127.0.0.1:1026");
+ return NULL;
}
/**
@@ -137,26 +157,6 @@ parse_and_set_options(int n_options, const char *const *options,
}
/**
- Prints usage instructions for the obfs2 protocol.
-*/
-static void
-usage(void)
-{
- log_warn("You failed at creating a correct obfs2 line.\n"
- "obfs2 syntax:\n"
- "\tobfs2 [obfs2_args] obfs2_opts\n"
- "\t'obfs2_opts':\n"
- "\t\tmode ~ server|client|socks\n"
- "\t\tlisten address ~ host:port\n"
- "\t'obfs2_args':\n"
- "\t\tDestination Address ~ --dest=host:port\n"
- "\t\tShared Secret ~ --shared-secret=<secret>\n"
- "\tExample:\n"
- "\tobfsproxy --dest=127.0.0.1:666 --shared-secret=himitsu "
- "\tobfs2 server 127.0.0.1:1026");
-}
-
-/**
Derive and return key of type 'keytype' from the seeds currently set in
'state'.
*/
@@ -242,7 +242,7 @@ derive_padding_key(void *s, const uchar *seed,
static void
obfs2_fini(protocol_params_t *p)
{
- obfs2_params_t *params = DOWNCAST(obfs2_params_t, super, p);
+ obfs2_params_t *params = downcast_params(p);
/* wipe out keys */
memset(params, 0x99, sizeof(obfs2_params_t));
free(params);
@@ -256,7 +256,7 @@ obfs2_fini(protocol_params_t *p)
static protocol_t *
obfs2_create(protocol_params_t *p)
{
- obfs2_params_t *params = DOWNCAST(obfs2_params_t, super, p);
+ obfs2_params_t *params = downcast_params(p);
obfs2_protocol_t *proto = xzalloc(sizeof(obfs2_protocol_t));
uchar *seed;
const char *send_pad_type;
@@ -291,7 +291,7 @@ obfs2_create(protocol_params_t *p)
static void
obfs2_destroy(protocol_t *s)
{
- obfs2_protocol_t *state = DOWNCAST(obfs2_protocol_t, super, s);
+ obfs2_protocol_t *state = downcast_protocol(s);
if (state->send_crypto)
crypt_free(state->send_crypto);
if (state->send_padding_crypto)
@@ -314,7 +314,7 @@ obfs2_destroy(protocol_t *s)
static int
obfs2_handshake(protocol_t *s, struct evbuffer *buf)
{
- obfs2_protocol_t *state = DOWNCAST(obfs2_protocol_t, super, s);
+ obfs2_protocol_t *state = downcast_protocol(s);
uint32_t magic = htonl(OBFUSCATE_MAGIC_VALUE), plength, send_plength;
uchar msg[OBFUSCATE_MAX_PADDING + OBFUSCATE_SEED_LENGTH + 8];
@@ -381,7 +381,7 @@ static int
obfs2_send(protocol_t *s,
struct evbuffer *source, struct evbuffer *dest)
{
- obfs2_protocol_t *state = DOWNCAST(obfs2_protocol_t, super, s);
+ obfs2_protocol_t *state = downcast_protocol(s);
if (state->send_crypto) {
/* First of all, send any data that we've been waiting to send. */
@@ -454,7 +454,7 @@ static enum recv_ret
obfs2_recv(protocol_t *s, struct evbuffer *source,
struct evbuffer *dest)
{
- obfs2_protocol_t *state = DOWNCAST(obfs2_protocol_t, super, s);
+ obfs2_protocol_t *state = downcast_protocol(s);
enum recv_ret r=0;
if (state->state == ST_WAIT_FOR_KEY) {
1
0
[obfsproxy/master] dummy option parsing needs to take two addresses when not in socks mode
by nickm@torproject.org 09 Sep '11
by nickm@torproject.org 09 Sep '11
09 Sep '11
commit b1832a4a236c61da0c70170d7b4a8f11cc4494a3
Author: Zack Weinberg <zackw(a)panix.com>
Date: Sun Jul 24 14:37:22 2011 -0700
dummy option parsing needs to take two addresses when not in socks mode
---
src/protocols/dummy.c | 27 +++++++++++++++++++--------
src/test/unittest_dummy.c | 19 +++++++++++--------
2 files changed, 30 insertions(+), 16 deletions(-)
diff --git a/src/protocols/dummy.c b/src/protocols/dummy.c
index ae45d9c..8646889 100644
--- a/src/protocols/dummy.c
+++ b/src/protocols/dummy.c
@@ -49,7 +49,7 @@ parse_and_set_options(int n_options, const char *const *options,
{
const char* defport;
- if (n_options != 2)
+ if (n_options < 1)
return -1;
if (!strcmp(options[0], "client")) {
@@ -64,10 +64,19 @@ parse_and_set_options(int n_options, const char *const *options,
} else
return -1;
+ if (n_options != (params->mode == LSN_SOCKS_CLIENT ? 2 : 3))
+ return -1;
+
params->listen_addr = resolve_address_port(options[1], 1, 1, defport);
if (!params->listen_addr)
return -1;
+ if (params->mode != LSN_SOCKS_CLIENT) {
+ params->target_addr = resolve_address_port(options[2], 1, 0, NULL);
+ if (!params->target_addr)
+ return -1;
+ }
+
params->vtable = &dummy_vtable;
return 0;
}
@@ -78,14 +87,16 @@ parse_and_set_options(int n_options, const char *const *options,
static void
usage(void)
{
- log_warn("Great... You can't even form a dummy protocol line:\n"
- "dummy syntax:\n"
- "\tdummy dummy_opts\n"
- "\t'dummy_opts':\n"
+ log_warn("dummy syntax:\n"
+ "\tdummy <mode> <listen_address> [<target_address>]\n"
"\t\tmode ~ server|client|socks\n"
- "\t\tlisten address ~ host:port\n"
- "Example:\n"
- "\tobfsproxy dummy socks 127.0.0.1:5000");
+ "\t\tlisten_address, target_address ~ host:port\n"
+ "\ttarget_address is required for server and client mode,\n"
+ "\tand forbidden for socks mode.\n"
+ "Examples:\n"
+ "\tobfsproxy dummy socks 127.0.0.1:5000\n"
+ "\tobfsproxy dummy client 127.0.0.1:5000 192.168.1.99:11253\n"
+ "\tobfsproxy dummy server 192.168.1.99:11253 127.0.0.1:9005");
}
static void
diff --git a/src/test/unittest_dummy.c b/src/test/unittest_dummy.c
index 1739e1f..4a2316d 100644
--- a/src/test/unittest_dummy.c
+++ b/src/test/unittest_dummy.c
@@ -21,17 +21,20 @@ test_dummy_option_parsing(void *unused)
/* wrong number of options */
{ 0, 0, 1, {"dummy"} },
{ 0, 0, 2, {"dummy", "client"} },
- { 0, 0, 4, {"dummy", "client", "127.0.0.1:5552", "oops"} },
- { 0, 0, 4, {"dummy", "--frobozz", "client", "127.0.0.1:5552"} },
+ { 0, 0, 3, {"dummy", "client", "127.0.0.1:5552"} },
+ { 0, 0, 3, {"dummy", "server", "127.0.0.1:5552"} },
+ { 0, 0, 4, {"dummy", "socks", "127.0.0.1:5552", "192.168.1.99:11253"} },
/* unrecognized mode */
{ 0, 0, 3, {"dummy", "floodcontrol", "127.0.0.1:5552" } },
+ { 0, 0, 4, {"dummy", "--frobozz", "client", "127.0.0.1:5552"} },
+ { 0, 0, 4, {"dummy", "client", "--frobozz", "127.0.0.1:5552"} },
/* bad address */
- { 0, 0, 3, {"dummy", "client", "@:5552"} },
- { 0, 0, 3, {"dummy", "client", "127.0.0.1:notanumber"} },
+ { 0, 0, 3, {"dummy", "socks", "@:5552"} },
+ { 0, 0, 3, {"dummy", "socks", "127.0.0.1:notanumber"} },
/* should succeed */
- { 0, 1, 3, {"dummy", "client", "127.0.0.1:5552" } },
- { 0, 1, 3, {"dummy", "client", "127.0.0.1" } },
- { 0, 1, 3, {"dummy", "server", "127.0.0.1:5552" } },
+ { 0, 1, 4, {"dummy", "client", "127.0.0.1:5552", "192.168.1.99:11253" } },
+ { 0, 1, 4, {"dummy", "client", "127.0.0.1", "192.168.1.99:11253" } },
+ { 0, 1, 4, {"dummy", "server", "127.0.0.1:5552", "192.168.1.99:11253" } },
{ 0, 1, 3, {"dummy", "socks", "127.0.0.1:5552" } },
{ 0, 0, 0, {0} }
@@ -99,7 +102,7 @@ static const char *const options_client[] =
{"dummy", "socks", "127.0.0.1:1800"};
static const char *const options_server[] =
- {"dummy", "server", "127.0.0.1:1800"};
+ {"dummy", "server", "127.0.0.1:1800", "127.0.0.1:1801"};
static void *
setup_dummy_state(const struct testcase_t *unused)
1
0
[obfsproxy/master] Remove is_initiator from generic protocol params
by nickm@torproject.org 09 Sep '11
by nickm@torproject.org 09 Sep '11
09 Sep '11
commit 78dfe6c9af14ccf42597176227af43e29aecbb67
Author: Zack Weinberg <zackw(a)panix.com>
Date: Sun Jul 24 12:46:49 2011 -0700
Remove is_initiator from generic protocol params
---
src/protocol.h | 1 -
src/protocols/obfs2.c | 4 +---
2 files changed, 1 insertions(+), 4 deletions(-)
diff --git a/src/protocol.h b/src/protocol.h
index 476d447..06dec08 100644
--- a/src/protocol.h
+++ b/src/protocol.h
@@ -26,7 +26,6 @@ typedef struct protocol_params_t {
size_t shared_secret_len;
size_t target_address_len;
size_t listen_address_len;
- int is_initiator;
int mode;
} protocol_params_t;
diff --git a/src/protocols/obfs2.c b/src/protocols/obfs2.c
index 6688ebf..88d750f 100644
--- a/src/protocols/obfs2.c
+++ b/src/protocols/obfs2.c
@@ -102,8 +102,6 @@ parse_and_set_options(int n_options, const char *const *options,
}
options++;
- params->is_initiator = (params->mode != LSN_SIMPLE_SERVER);
-
if (resolve_address_port(*options, 1, 1,
¶ms->listen_address,
¶ms->listen_address_len, defport) < 0)
@@ -249,7 +247,7 @@ obfs2_create(protocol_params_t *params)
const char *send_pad_type;
proto->state = ST_WAIT_FOR_KEY;
- proto->we_are_initiator = params->is_initiator;
+ proto->we_are_initiator = (params->mode != LSN_SIMPLE_SERVER);
if (proto->we_are_initiator) {
send_pad_type = INITIATOR_PAD_TYPE;
seed = proto->initiator_seed;
1
0
[obfsproxy/master] Consistently don't use 'struct' with protocol_t, protocol_params_t.
by nickm@torproject.org 09 Sep '11
by nickm@torproject.org 09 Sep '11
09 Sep '11
commit 8ef4ccd9209a1ca4f946e7c82932cf28d7f95ba0
Author: Zack Weinberg <zackw(a)panix.com>
Date: Sun Jul 24 16:30:58 2011 -0700
Consistently don't use 'struct' with protocol_t, protocol_params_t.
---
src/protocol.c | 12 ++++++------
src/protocol.h | 16 ++++++++--------
src/protocols/dummy.c | 25 ++++++++++++-------------
src/protocols/obfs2.h | 2 +-
src/test/unittest_dummy.c | 10 +++++-----
src/test/unittest_obfs2.c | 15 +++++++--------
6 files changed, 39 insertions(+), 41 deletions(-)
diff --git a/src/protocol.c b/src/protocol.c
index 212ddaa..a010d16 100644
--- a/src/protocol.c
+++ b/src/protocol.c
@@ -31,7 +31,7 @@ const size_t n_supported_protocols =
This function is called once for every listener through the runtime
of obfsproxy.
*/
-struct protocol_params_t *
+protocol_params_t *
proto_params_init(int n_options, const char *const *options)
{
size_t i;
@@ -73,7 +73,7 @@ proto_params_free(protocol_params_t *params)
Return a 'protocol_t' if successful, NULL otherwise.
*/
-struct protocol_t *
+protocol_t *
proto_create(protocol_params_t *params)
{
obfs_assert(params);
@@ -87,7 +87,7 @@ proto_create(protocol_params_t *params)
Not all protocols have a handshake.
*/
int
-proto_handshake(struct protocol_t *proto, void *buf) {
+proto_handshake(protocol_t *proto, void *buf) {
obfs_assert(proto);
obfs_assert(proto->vtable);
obfs_assert(proto->vtable->handshake);
@@ -98,7 +98,7 @@ proto_handshake(struct protocol_t *proto, void *buf) {
This function is responsible for sending protocol data.
*/
int
-proto_send(struct protocol_t *proto, void *source, void *dest) {
+proto_send(protocol_t *proto, void *source, void *dest) {
obfs_assert(proto);
obfs_assert(proto->vtable);
obfs_assert(proto->vtable->send);
@@ -109,7 +109,7 @@ proto_send(struct protocol_t *proto, void *source, void *dest) {
This function is responsible for receiving protocol data.
*/
enum recv_ret
-proto_recv(struct protocol_t *proto, void *source, void *dest) {
+proto_recv(protocol_t *proto, void *source, void *dest) {
obfs_assert(proto);
obfs_assert(proto->vtable);
obfs_assert(proto->vtable->recv);
@@ -121,7 +121,7 @@ proto_recv(struct protocol_t *proto, void *source, void *dest) {
It's called everytime we close a connection.
*/
void
-proto_destroy(struct protocol_t *proto) {
+proto_destroy(protocol_t *proto) {
obfs_assert(proto);
obfs_assert(proto->vtable);
obfs_assert(proto->vtable->destroy);
diff --git a/src/protocol.h b/src/protocol.h
index c1189ea..c023720 100644
--- a/src/protocol.h
+++ b/src/protocol.h
@@ -74,7 +74,7 @@ typedef struct protocol_vtable
struct evbuffer *dest);
/** Receive data from 'source' and pass it upstream to 'dest'. */
- enum recv_ret (*recv)(struct protocol_t *state,
+ enum recv_ret (*recv)(protocol_t *state,
struct evbuffer *source,
struct evbuffer *dest);
@@ -93,16 +93,16 @@ typedef struct protocol_vtable
name##_handshake, name##_send, name##_recv \
}
-struct protocol_params_t *proto_params_init(int n_options,
- const char *const *options);
+protocol_params_t *proto_params_init(int n_options,
+ const char *const *options);
void proto_params_free(protocol_params_t *params);
-struct protocol_t *proto_create(struct protocol_params_t *params);
-void proto_destroy(struct protocol_t *proto);
+protocol_t *proto_create(protocol_params_t *params);
+void proto_destroy(protocol_t *proto);
-int proto_handshake(struct protocol_t *proto, void *buf);
-int proto_send(struct protocol_t *proto, void *source, void *dest);
-enum recv_ret proto_recv(struct protocol_t *proto, void *source, void *dest);
+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);
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 8646889..26fe525 100644
--- a/src/protocols/dummy.c
+++ b/src/protocols/dummy.c
@@ -15,7 +15,7 @@
static void usage(void);
static int parse_and_set_options(int n_options,
const char *const *options,
- struct protocol_params_t *params);
+ protocol_params_t *params);
/**
This function populates 'params' according to 'options' and sets up
@@ -24,11 +24,10 @@ static int parse_and_set_options(int n_options,
'options' is an array like this:
{"dummy","socks","127.0.0.1:6666"}
*/
-static struct protocol_params_t *
+static protocol_params_t *
dummy_init(int n_options, const char *const *options)
{
- struct protocol_params_t *params
- = xzalloc(sizeof(struct protocol_params_t));
+ protocol_params_t *params = xzalloc(sizeof(protocol_params_t));
params->vtable = &dummy_vtable;
if (parse_and_set_options(n_options, options, params) < 0) {
@@ -45,7 +44,7 @@ dummy_init(int n_options, const char *const *options)
*/
static int
parse_and_set_options(int n_options, const char *const *options,
- struct protocol_params_t *params)
+ protocol_params_t *params)
{
const char* defport;
@@ -100,7 +99,7 @@ usage(void)
}
static void
-dummy_fini(struct protocol_params_t *params)
+dummy_fini(protocol_params_t *params)
{
free(params);
}
@@ -110,17 +109,17 @@ dummy_fini(struct protocol_params_t *params)
protocol.
*/
-static struct protocol_t *
-dummy_create(struct protocol_params_t *params)
+static protocol_t *
+dummy_create(protocol_params_t *params)
{
/* Dummy needs no per-connection protocol-specific state. */
- struct protocol_t *proto = xzalloc(sizeof(struct protocol_t));
+ protocol_t *proto = xzalloc(sizeof(protocol_t));
proto->vtable = &dummy_vtable;
return proto;
}
static void
-dummy_destroy(struct protocol_t *proto)
+dummy_destroy(protocol_t *proto)
{
free(proto);
}
@@ -131,13 +130,13 @@ dummy_destroy(struct protocol_t *proto)
The dummy protocol just puts the data of 'source' in 'dest'.
*/
static int
-dummy_handshake(struct protocol_t *proto, struct evbuffer *buf)
+dummy_handshake(protocol_t *proto, struct evbuffer *buf)
{
return 0;
}
static int
-dummy_send(struct protocol_t *proto,
+dummy_send(protocol_t *proto,
struct evbuffer *source, struct evbuffer *dest)
{
return evbuffer_add_buffer(dest,source);
@@ -149,7 +148,7 @@ dummy_send(struct protocol_t *proto,
The dummy protocol just puts the data of 'source' into 'dest'.
*/
static enum recv_ret
-dummy_recv(struct protocol_t *proto,
+dummy_recv(protocol_t *proto,
struct evbuffer *source, struct evbuffer *dest)
{
if (evbuffer_add_buffer(dest,source)<0)
diff --git a/src/protocols/obfs2.h b/src/protocols/obfs2.h
index eb55a9f..107d15a 100644
--- a/src/protocols/obfs2.h
+++ b/src/protocols/obfs2.h
@@ -40,7 +40,7 @@ typedef struct obfs2_params_t {
} obfs2_params_t;
typedef struct obfs2_protocol_t {
- struct protocol_t super;
+ protocol_t super;
/** Current protocol state. We start out waiting for key information. Then
we have a key and wait for padding to arrive. Finally, we are sending
diff --git a/src/test/unittest_dummy.c b/src/test/unittest_dummy.c
index 4a2316d..aaeafa9 100644
--- a/src/test/unittest_dummy.c
+++ b/src/test/unittest_dummy.c
@@ -12,7 +12,7 @@ static void
test_dummy_option_parsing(void *unused)
{
struct option_parsing_case {
- struct protocol_params_t *result;
+ protocol_params_t *result;
short should_succeed;
short n_opts;
const char *const opts[4];
@@ -64,10 +64,10 @@ test_dummy_option_parsing(void *unused)
/* All the tests below use this test environment: */
struct test_dummy_state
{
- struct protocol_params_t *proto_params_client;
- struct protocol_params_t *proto_params_server;
- struct protocol_t *client_proto;
- struct protocol_t *server_proto;
+ protocol_params_t *proto_params_client;
+ protocol_params_t *proto_params_server;
+ protocol_t *client_proto;
+ protocol_t *server_proto;
struct evbuffer *output_buffer;
struct evbuffer *dummy_buffer;
};
diff --git a/src/test/unittest_obfs2.c b/src/test/unittest_obfs2.c
index 00fc12e..6767769 100644
--- a/src/test/unittest_obfs2.c
+++ b/src/test/unittest_obfs2.c
@@ -15,17 +15,16 @@
#define ALEN(x) (sizeof x/sizeof x[0])
static inline obfs2_protocol_t *
-downcast(struct protocol_t *proto)
+downcast(protocol_t *proto)
{
- return (obfs2_protocol_t *)
- ((char *)proto - offsetof(obfs2_protocol_t, super));
+ return DOWNCAST(obfs2_protocol_t, super, proto);
}
static void
test_obfs2_option_parsing(void *unused)
{
struct option_parsing_case {
- struct protocol_params_t *result;
+ protocol_params_t *result;
short should_succeed;
short n_opts;
const char *const opts[6];
@@ -78,10 +77,10 @@ test_obfs2_option_parsing(void *unused)
/* All the tests below use this test environment: */
struct test_obfs2_state
{
- struct protocol_params_t *proto_params_client;
- struct protocol_params_t *proto_params_server;
- struct protocol_t *client_proto;
- struct protocol_t *server_proto;
+ protocol_params_t *proto_params_client;
+ protocol_params_t *proto_params_server;
+ protocol_t *client_proto;
+ protocol_t *server_proto;
struct evbuffer *output_buffer;
struct evbuffer *dummy_buffer;
};
1
0
commit a3e63eaed8ad4a55352cc945fdf126435d6b6581
Author: Zack Weinberg <zackw(a)panix.com>
Date: Thu Jul 14 13:23:58 2011 -0700
don't reinvent offsetof
---
src/network.c | 4 ++--
src/util.h | 12 +++---------
2 files changed, 5 insertions(+), 11 deletions(-)
diff --git a/src/network.c b/src/network.c
index ea06bc2..6a8afa6 100644
--- a/src/network.c
+++ b/src/network.c
@@ -93,7 +93,7 @@ close_all_connections(void)
{
/** Traverse the dll and close all connections */
while (conn_list.head) {
- conn_t *conn = UPCAST(conn_t, dll_node, conn_list.head);
+ conn_t *conn = DOWNCAST(conn_t, dll_node, conn_list.head);
conn_free(conn); /* removes it */
}
assert(!n_connections);
@@ -169,7 +169,7 @@ free_all_listeners(void)
/* Iterate listener doubly linked list and free them all. */
while (listener_list.head) {
- listener_t *listener = UPCAST(listener_t, dll_node, listener_list.head);
+ listener_t *listener = DOWNCAST(listener_t, dll_node, listener_list.head);
listener_free(listener);
}
diff --git a/src/util.h b/src/util.h
index ff9df22..b526dbf 100644
--- a/src/util.h
+++ b/src/util.h
@@ -6,7 +6,7 @@
#define UTIL_H
#include <stdarg.h> /* for va_list */
-#include <stddef.h> /* for size_t etc */
+#include <stddef.h> /* size_t, offsetof, NULL, etc */
#ifndef __GNUC__
#define __attribute__(x) /* nothing */
@@ -37,14 +37,8 @@ int obfs_snprintf(char *str, size_t size,
/***** Doubly Linked List stuff. *****/
-#define OFFSETOF(container_type, element) \
- (((char*)&((container_type*)0)->element) - ((char*) ((container_type*)0)))
-
-#define UPCAST(container_type, element, ptr) \
- (container_type*) ( \
- ((char*)ptr) - OFFSETOF(container_type, element) \
- )
-
+#define DOWNCAST(container_type, element, ptr) \
+ (container_type*)( ((char*)ptr) - offsetof(container_type, element) )
/** A doubly linked list node.
[algorithms ripped off Wikipedia (Doubly_linked_list) ] */
1
0
commit 4896bd7e4609f74780dbe047ac568283848d06f2
Author: Zack Weinberg <zackw(a)panix.com>
Date: Tue Jul 12 17:04:21 2011 -0700
Protocol API sanitization
* Embed the protocol name in the protocol vtable
* Protocol vtables are now statically allocated
* Return objects rather than error codes when that makes sense
* Use pseudo-inheritance rather than void pointers for protocol-
specific, per-connection state
* Tidy up the protocol.h upward interface a little
* Constification
---
src/main.c | 47 +++----
src/network.c | 2 +-
src/protocol.c | 109 +++++++-------
src/protocol.h | 120 +++++++++------
src/protocols/dummy.c | 104 +++++++-------
src/protocols/dummy.h | 12 +-
src/protocols/obfs2.c | 212 ++++++++++-----------------
src/protocols/obfs2.h | 29 ++--
src/test/unittest_obfs2.c | 363 +++++++++++++++++++--------------------------
9 files changed, 448 insertions(+), 550 deletions(-)
diff --git a/src/main.c b/src/main.c
index 48d0d37..f41d502 100644
--- a/src/main.c
+++ b/src/main.c
@@ -25,10 +25,6 @@
static void usage(void) __attribute__((noreturn));
static int handle_obfsproxy_args(const char **argv);
-/* protocol.c */
-extern char *supported_protocols[];
-extern int n_supported_protocols;
-
static struct event_base *the_event_base=NULL;
/**
@@ -44,7 +40,7 @@ usage(void)
SEPARATOR);
/* this is awful. */
for (i=0;i<n_supported_protocols;i++)
- fprintf(stderr,"[%s] ", supported_protocols[i]);
+ fprintf(stderr,"[%s] ", supported_protocols[i]->name);
fprintf(stderr, "\n* Available arguments:\n"
"--log-file=<file> ~ set logfile\n"
"--log-min-severity=warn|info|debug ~ set minimum logging severity\n"
@@ -93,7 +89,7 @@ handle_signal_cb(evutil_socket_t fd, short what, void *arg)
Stops obfsproxy's event loop.
Final cleanup happens in main().
-*/
+*/
void
finish_shutdown(void)
{
@@ -105,8 +101,8 @@ finish_shutdown(void)
and writes them in 'options_string'.
*/
static void
-populate_options(char **options_string,
- const char **argv, int n_options)
+populate_options(char **options_string,
+ const char **argv, int n_options)
{
int g;
for (g=0;g<=n_options-1;g++)
@@ -114,14 +110,14 @@ populate_options(char **options_string,
}
/**
- Return 0 if 'name' is the nmae of a supported protocol, otherwise
+ Return 0 if 'name' is the name of a supported protocol, otherwise
return -1.
*/
static int
is_supported_protocol(const char *name) {
int f;
for (f=0;f<n_supported_protocols;f++) {
- if (!strcmp(name,supported_protocols[f]))
+ if (!strcmp(name,supported_protocols[f]->name))
return 0;
}
return -1;
@@ -130,7 +126,7 @@ is_supported_protocol(const char *name) {
/**
Receives argv[1] as 'argv' and scans from thereafter for any
obfsproxy optional arguments and tries to set them in effect.
-
+
If it succeeds it returns the number of argv arguments its caller
should skip to get past the optional arguments we already handled.
If it fails, it exits obfsproxy.
@@ -142,14 +138,14 @@ handle_obfsproxy_args(const char **argv)
int logsev_set=0;
int i=0;
- while (argv[i] &&
+ while (argv[i] &&
!strncmp(argv[i],"--",2)) {
if (!strncmp(argv[i], "--log-file=", 11)) {
if (logmethod_set) {
- log_warn("You've already set a log file!");
+ log_warn("You've already set a log file!");
exit(1);
}
- if (log_set_method(LOG_METHOD_FILE,
+ if (log_set_method(LOG_METHOD_FILE,
(char *)argv[i]+11) < 0) {
log_warn("Failed creating logfile.");
exit(1);
@@ -161,7 +157,7 @@ handle_obfsproxy_args(const char **argv)
exit(1);
}
if (log_set_min_severity((char *)argv[i]+19) < 0) {
- log_warn("Error at setting logging severity");
+ log_warn("Error at setting logging severity");
exit(1);
}
logsev_set=1;
@@ -171,7 +167,7 @@ handle_obfsproxy_args(const char **argv)
exit(1);
}
if (log_set_method(LOG_METHOD_NULL, NULL) < 0) {
- printf("Error at setting logging severity.\n");
+ printf("Error at setting logging severity.\n");
exit(1);
}
logsev_set=1;
@@ -212,7 +208,7 @@ main(int argc, const char **argv)
managed to recognize, by their protocol name. Of course it's not
the *actual* actual_protocols since some of them could have wrong
options or arguments, but this will be resolved per-protocol by
- set_up_protocol(). */
+ proto_params_init(). */
int actual_protocols=0;
int start;
@@ -300,7 +296,7 @@ main(int argc, const char **argv)
/* First option should be protocol_name. See if we support it. */
if (is_supported_protocol(argv[start])<0) {
- log_warn("We don't support protocol: %s", argv[start]);
+ log_warn("We don't support protocol: %s", argv[start]);
continue;
}
@@ -308,14 +304,14 @@ main(int argc, const char **argv)
/* Allocate space for the array carrying the options of this
protocol. */
- protocol_options[actual_protocols-1] =
+ protocol_options[actual_protocols-1] =
calloc(sizeof(char*), (n_options));
if (!protocol_options[actual_protocols-1])
die_oom();
/* Write the number of options to the correct place in n_options_array[]. */
n_options_array[actual_protocols-1] = n_options;
-
+
/* Finally! Let's fill protocol_options. */
populate_options(protocol_options[actual_protocols-1],
&argv[start], n_options);
@@ -343,7 +339,7 @@ main(int argc, const char **argv)
log_warn("Can't initialize evdns; failing");
return 1;
}
-
+
/* Handle signals */
#ifdef SIGPIPE
signal(SIGPIPE, SIG_IGN);
@@ -357,7 +353,7 @@ main(int argc, const char **argv)
return 1;
}
- /*Let's open a new listener for each protocol. */
+ /*Let's open a new listener for each protocol. */
int h;
listener_t *temp_listener;
int n_listeners=0;
@@ -366,10 +362,9 @@ main(int argc, const char **argv)
log_debug("Spawning listener %d!", h+1);
/** normally free'd in listener_free() */
- proto_params = calloc(1, sizeof(protocol_params_t));
- if (set_up_protocol(n_options_array[h],protocol_options[h],
- proto_params)<0) {
- free(proto_params);
+ proto_params = proto_params_init(n_options_array[h],
+ (const char *const *)protocol_options[h]);
+ if (!proto_params) {
free(protocol_options[h]);
continue;
}
diff --git a/src/network.c b/src/network.c
index 6a8afa6..365c61a 100644
--- a/src/network.c
+++ b/src/network.c
@@ -202,7 +202,7 @@ simple_listener_cb(struct evconnlistener *evcl,
conn->mode = lsn->proto_params->mode;
- conn->proto = proto_new(lsn->proto_params);
+ conn->proto = proto_create(lsn->proto_params);
if (!conn->proto) {
log_warn("Creation of protocol object failed! Closing connection.");
goto err;
diff --git a/src/protocol.c b/src/protocol.c
index 282db10..85b975f 100644
--- a/src/protocol.c
+++ b/src/protocol.c
@@ -15,8 +15,13 @@
All supported protocols should be put in this array.
It's used by main.c.
*/
-char *supported_protocols[] = { "obfs2", "dummy" };
-int n_supported_protocols = 2;
+const protocol_vtable *const supported_protocols[] =
+{
+ &dummy_vtable,
+ &obfs2_vtable,
+};
+const size_t n_supported_protocols =
+ sizeof(supported_protocols)/sizeof(supported_protocols[0]);
/**
This function figures out which protocol we want to set up, and
@@ -25,16 +30,33 @@ int n_supported_protocols = 2;
This function is called once for every listener through the runtime
of obfsproxy.
*/
-int
-set_up_protocol(int n_options, char **options,
- struct protocol_params_t *params)
+struct protocol_params_t *
+proto_params_init(int n_options, const char *const *options)
{
- if (!strcmp(*options,"dummy"))
- return dummy_init(n_options, options, params);
- else if (!strcmp(*options,"obfs2"))
- return obfs2_init(n_options, options, params);
- else
- return -1;
+ size_t i;
+ for (i = 0; i < n_supported_protocols; i++)
+ if (!strcmp(*options, supported_protocols[i]->name))
+ return supported_protocols[i]->init(n_options, options);
+
+ return NULL;
+}
+
+/**
+ This function destroys 'params'.
+ It's called everytime we free a listener.
+*/
+void
+proto_params_free(protocol_params_t *params)
+{
+ assert(params);
+
+ if (params->target_address)
+ free(params->target_address);
+ if (params->listen_address)
+ free(params->listen_address);
+ if (params->shared_secret)
+ free(params->shared_secret);
+ free(params);
}
/**
@@ -44,17 +66,12 @@ set_up_protocol(int n_options, char **options,
Return a 'protocol_t' if successful, NULL otherwise.
*/
struct protocol_t *
-proto_new(protocol_params_t *params) {
- struct protocol_t *proto = calloc(1, sizeof(struct protocol_t));
- if (!proto)
- return NULL;
-
- if (params->proto == OBFS2_PROTOCOL)
- proto->state = obfs2_new(proto, params);
- else if (params->proto == DUMMY_PROTOCOL)
- proto->state = dummy_new(proto, NULL);
-
- return proto->state ? proto : NULL;
+proto_create(protocol_params_t *params)
+{
+ assert(params);
+ assert(params->vtable);
+ assert(params->vtable->create);
+ return params->vtable->create(params);
}
/**
@@ -64,10 +81,9 @@ proto_new(protocol_params_t *params) {
int
proto_handshake(struct protocol_t *proto, void *buf) {
assert(proto);
- if (proto->vtable->handshake)
- return proto->vtable->handshake(proto->state, buf);
- else /* It's okay with me, protocol didn't have a handshake */
- return 0;
+ assert(proto->vtable);
+ assert(proto->vtable->handshake);
+ return proto->vtable->handshake(proto, buf);
}
/**
@@ -76,10 +92,9 @@ proto_handshake(struct protocol_t *proto, void *buf) {
int
proto_send(struct protocol_t *proto, void *source, void *dest) {
assert(proto);
- if (proto->vtable->send)
- return proto->vtable->send(proto->state, source, dest);
- else
- return -1;
+ assert(proto->vtable);
+ assert(proto->vtable->send);
+ return proto->vtable->send(proto, source, dest);
}
/**
@@ -88,10 +103,9 @@ proto_send(struct protocol_t *proto, void *source, void *dest) {
enum recv_ret
proto_recv(struct protocol_t *proto, void *source, void *dest) {
assert(proto);
- if (proto->vtable->recv)
- return proto->vtable->recv(proto->state, source, dest);
- else
- return -1;
+ assert(proto->vtable);
+ assert(proto->vtable->recv);
+ return proto->vtable->recv(proto, source, dest);
}
/**
@@ -101,28 +115,7 @@ proto_recv(struct protocol_t *proto, void *source, void *dest) {
void
proto_destroy(struct protocol_t *proto) {
assert(proto);
- assert(proto->state);
-
- if (proto->vtable->destroy)
- proto->vtable->destroy(proto->state);
-
- free(proto);
-}
-
-/**
- This function destroys 'params'.
- It's called everytime we free a listener.
-*/
-void
-proto_params_free(protocol_params_t *params)
-{
- assert(params);
-
- if (params->target_address)
- free(params->target_address);
- if (params->listen_address)
- free(params->listen_address);
- if (params->shared_secret)
- free(params->shared_secret);
- free(params);
+ assert(proto->vtable);
+ assert(proto->vtable->destroy);
+ proto->vtable->destroy(proto);
}
diff --git a/src/protocol.h b/src/protocol.h
index 6d5dcfe..476d447 100644
--- a/src/protocol.h
+++ b/src/protocol.h
@@ -11,17 +11,15 @@
struct evbuffer;
struct sockaddr;
-#define DUMMY_PROTOCOL 1
-#define OBFS2_PROTOCOL 2
-
/**
- This struct defines parameters of the protocol per-listener basis.
+ This struct defines parameters of a protocol on a per-listener basis.
By 'per-listener basis' I mean that the parameters defined here will
be inherited by *all* connections opened from the listener_t that
owns this protocol_params_t.
*/
typedef struct protocol_params_t {
+ const struct protocol_vtable *vtable;
struct sockaddr *target_address;
struct sockaddr *listen_address;
char *shared_secret;
@@ -30,61 +28,91 @@ typedef struct protocol_params_t {
size_t listen_address_len;
int is_initiator;
int mode;
- int proto; /* Protocol that this listener can speak. */
} protocol_params_t;
+/**
+ This protocol specific struct defines the state of the protocol
+ on a per-connection basis.
+
+ By 'protocol specific' I mean that every protocol has its own
+ state struct. (for example, obfs2 has obfs2_state_t). A protocol_t
+ struct is always the first member of this struct, and vtable->create
+ returns that member (standard fake-inheritance-in-C technique).
+ All data other than the vtable is hidden from everything but the
+ protocol implementation.
+
+ By 'per-connection basis' I mean that the every connection has a
+ different protocol_t struct, and that's precisely the reason that
+ this struct is owned by the conn_t struct.
+ */
struct protocol_t {
- /* protocol vtable */
- struct protocol_vtable *vtable;
-
- /* This protocol specific struct defines the state of the protocol
- per-connection basis.
-
- By 'protocol specific' I mean that every protocol has it's own
- state struct. (for example, obfs2 has obfs2_state_t)
-
- By 'per-connection basis' I mean that the every connection has a
- different protocol_t struct, and that's precisely the reason that
- this struct is owned by the conn_t struct.
- */
- void *state;
+ const struct protocol_vtable *vtable;
};
-int set_up_protocol(int n_options, char **options,
- struct protocol_params_t *params);
-struct protocol_t *proto_new(struct protocol_params_t *params);
-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);
-enum recv_ret proto_recv(struct protocol_t *proto, void *source, void *dest);
-
-void proto_params_free(protocol_params_t *params);
-
-typedef struct protocol_vtable {
- /* Initialization function: Fills in the protocol vtable. */
- int (*init)(int n_options, char **options,
- struct protocol_params_t *params);
-
- /* Destructor: Destroys the protocol state. */
- void (*destroy)(void *state);
- /* Constructor: Creates a protocol object. */
- void *(*create)(struct protocol_t *proto_params,
- struct protocol_params_t *parameters);
-
- /* does handshake. Not all protocols have a handshake. */
- int (*handshake)(void *state,
+/**
+ This struct defines a protocol and its methods; note that not all
+ of them are methods on the same object in the C++ sense.
+
+ A filled-in, statically allocated protocol_vtable object is the
+ principal interface between each individual protocol and generic
+ code. At present there is a static list of these objects in protocol.c.
+ */
+typedef struct protocol_vtable
+{
+ /** The short name of this protocol. */
+ const char *name;
+
+ /** Initialization function: Allocate a 'protocol_params_t' object
+ and fill it in from the provided 'options' array. */
+ struct protocol_params_t *(*init)(int n_options,
+ const char *const *options);
+
+ /** Constructor: Allocates per-connection, protocol-specific state. */
+ struct protocol_t *(*create)(struct protocol_params_t *params);
+
+ /** Destructor: Destroys per-connection, protocol-specific state. */
+ void (*destroy)(struct protocol_t *state);
+
+ /** Perform a connection handshake. Not all protocols have a handshake. */
+ int (*handshake)(struct protocol_t *state,
struct evbuffer *buf);
- /* send data function */
- int (*send)(void *state,
+ /** Send data coming downstream from 'source' along to 'dest'. */
+ int (*send)(struct protocol_t *state,
struct evbuffer *source,
struct evbuffer *dest);
- /* receive data function */
- enum recv_ret (*recv)(void *state,
+ /** Receive data from 'source' and pass it upstream to 'dest'. */
+ enum recv_ret (*recv)(struct protocol_t *state,
struct evbuffer *source,
struct evbuffer *dest);
} protocol_vtable;
+/**
+ Use this macro to define protocol_vtable objects; it ensures all
+ the methods are in the correct order and enforces a consistent
+ naming convention on protocol implementations.
+ */
+#define DEFINE_PROTOCOL_VTABLE(name) \
+ const struct protocol_vtable name##_vtable = { \
+ #name, \
+ name##_init, name##_create, name##_destroy, \
+ name##_handshake, name##_send, name##_recv \
+ }
+
+struct protocol_params_t *proto_params_init(int n_options,
+ const char *const *options);
+void proto_params_free(protocol_params_t *params);
+
+struct protocol_t *proto_create(struct protocol_params_t *params);
+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);
+enum recv_ret proto_recv(struct protocol_t *proto, void *source, void *dest);
+
+extern const protocol_vtable *const supported_protocols[];
+extern const size_t n_supported_protocols;
+
#endif
diff --git a/src/protocols/dummy.c b/src/protocols/dummy.c
index 3b31e12..7db48d7 100644
--- a/src/protocols/dummy.c
+++ b/src/protocols/dummy.c
@@ -7,22 +7,16 @@
#include "../util.h"
#include <assert.h>
-#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <event2/buffer.h>
-static int dummy_send(void *nothing,
- struct evbuffer *source, struct evbuffer *dest);
-static enum recv_ret dummy_recv(void *nothing, struct evbuffer *source,
- struct evbuffer *dest);
static void usage(void);
-static int parse_and_set_options(int n_options, char **options,
+static int parse_and_set_options(int n_options,
+ const char *const *options,
struct protocol_params_t *params);
-static protocol_vtable *vtable=NULL;
-
/**
This function populates 'params' according to 'options' and sets up
the protocol vtable.
@@ -30,34 +24,28 @@ static protocol_vtable *vtable=NULL;
'options' is an array like this:
{"dummy","socks","127.0.0.1:6666"}
*/
-int
-dummy_init(int n_options, char **options,
- struct protocol_params_t *params)
+static struct protocol_params_t *
+dummy_init(int n_options, const char *const *options)
{
- if (parse_and_set_options(n_options,options,params) < 0) {
+ struct protocol_params_t *params
+ = calloc(1, sizeof(struct protocol_params_t));
+ if (!params)
+ return NULL;
+
+ if (parse_and_set_options(n_options, options, params) < 0) {
+ free(params);
usage();
- return -1;
+ return NULL;
}
- /* XXX memleak. */
- vtable = calloc(1, sizeof(protocol_vtable));
- if (!vtable)
- return -1;
-
- vtable->destroy = NULL;
- vtable->create = dummy_new;
- vtable->handshake = NULL;
- vtable->send = dummy_send;
- vtable->recv = dummy_recv;
-
- return 0;
+ return params;
}
/**
Helper: Parses 'options' and fills 'params'.
-*/
+*/
static int
-parse_and_set_options(int n_options, char **options,
+parse_and_set_options(int n_options, const char *const *options,
struct protocol_params_t *params)
{
const char* defport;
@@ -66,7 +54,6 @@ parse_and_set_options(int n_options, char **options,
return -1;
assert(!strcmp(options[0],"dummy"));
- params->proto = DUMMY_PROTOCOL;
if (!strcmp(options[1], "client")) {
defport = "48988"; /* bf5c */
@@ -87,7 +74,8 @@ parse_and_set_options(int n_options, char **options,
return -1;
}
- return 1;
+ params->vtable = &dummy_vtable;
+ return 0;
}
/**
@@ -96,31 +84,34 @@ parse_and_set_options(int n_options, char **options,
static void
usage(void)
{
- printf("Great... You can't even form a dummy protocol line:\n"
- "dummy syntax:\n"
- "\tdummy dummy_opts\n"
- "\t'dummy_opts':\n"
- "\t\tmode ~ server|client|socks\n"
- "\t\tlisten address ~ host:port\n"
- "Example:\n"
- "\tobfsproxy dummy socks 127.0.0.1:5000\n");
+ log_warn("Great... You can't even form a dummy protocol line:\n"
+ "dummy syntax:\n"
+ "\tdummy dummy_opts\n"
+ "\t'dummy_opts':\n"
+ "\t\tmode ~ server|client|socks\n"
+ "\t\tlisten address ~ host:port\n"
+ "Example:\n"
+ "\tobfsproxy dummy socks 127.0.0.1:5000");
}
/*
This is called everytime we get a connection for the dummy
protocol.
-
- It sets up the protocol vtable in 'proto_struct'.
*/
-void *
-dummy_new(struct protocol_t *proto_struct,
- struct protocol_params_t *params)
+
+static struct protocol_t *
+dummy_create(struct protocol_params_t *params)
{
- proto_struct->vtable = vtable;
+ /* Dummy needs no per-connection protocol-specific state. */
+ struct protocol_t *proto = calloc(1, sizeof(struct protocol_t));
+ proto->vtable = &dummy_vtable;
+ return proto;
+}
- /* Dodging state check.
- This is terrible I know.*/
- return (void *)666U;
+static void
+dummy_destroy(struct protocol_t *proto)
+{
+ free(proto);
}
/**
@@ -129,10 +120,16 @@ dummy_new(struct protocol_t *proto_struct,
The dummy protocol just puts the data of 'source' in 'dest'.
*/
static int
-dummy_send(void *nothing,
- struct evbuffer *source, struct evbuffer *dest) {
- (void)nothing;
+dummy_handshake(struct protocol_t *proto __attribute__((unused)),
+ struct evbuffer *buf __attribute__((unused)))
+{
+ return 0;
+}
+static int
+dummy_send(struct protocol_t *proto __attribute__((unused)),
+ struct evbuffer *source, struct evbuffer *dest)
+{
return evbuffer_add_buffer(dest,source);
}
@@ -142,12 +139,13 @@ dummy_send(void *nothing,
The dummy protocol just puts the data of 'source' into 'dest'.
*/
static enum recv_ret
-dummy_recv(void *nothing,
- struct evbuffer *source, struct evbuffer *dest) {
- (void)nothing;
-
+dummy_recv(struct protocol_t *proto __attribute__((unused)),
+ struct evbuffer *source, struct evbuffer *dest)
+{
if (evbuffer_add_buffer(dest,source)<0)
return RECV_BAD;
else
return RECV_GOOD;
}
+
+DEFINE_PROTOCOL_VTABLE(dummy);
diff --git a/src/protocols/dummy.h b/src/protocols/dummy.h
index a3fa32d..e7dbd2a 100644
--- a/src/protocols/dummy.h
+++ b/src/protocols/dummy.h
@@ -1,14 +1,10 @@
/* Copyright 2011 Nick Mathewson, George Kadianakis
See LICENSE for other credits and copying information
*/
-#ifndef DUMMY_H
-#define DUMMY_H
+#ifndef PROTOCOL_DUMMY_H
+#define PROTOCOL_DUMMY_H
-struct protocol_t;
-struct protocol_params_t;
-
-int dummy_init(int n_options, char **options, struct protocol_params_t *lsn);
-void *dummy_new(struct protocol_t *proto_struct,
- struct protocol_params_t *params);
+struct protocol_vtable;
+extern const struct protocol_vtable dummy_vtable;
#endif
diff --git a/src/protocols/obfs2.c b/src/protocols/obfs2.c
index 27e9272..cc208ed 100644
--- a/src/protocols/obfs2.c
+++ b/src/protocols/obfs2.c
@@ -2,34 +2,28 @@
See LICENSE for other credits and copying information
*/
-#define CRYPT_PROTOCOL_PRIVATE
+#define PROTOCOL_OBFS2_PRIVATE
#include "obfs2.h"
-#include "../protocol.h"
#include "../util.h"
#include <assert.h>
-#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <event2/buffer.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 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,
- size_t secretlen);
-static int set_up_vtable(void);
static void usage(void);
+static int parse_and_set_options(int n_options,
+ const char *const *options,
+ struct protocol_params_t *params);
-static protocol_vtable *vtable=NULL;
+static inline obfs2_protocol_t *
+downcast(struct protocol_t *proto)
+{
+ return (obfs2_protocol_t *)
+ ((char *)proto - offsetof(obfs2_protocol_t, super));
+}
/*
This function parses 'options' and fills the protocol parameters
@@ -38,31 +32,34 @@ static protocol_vtable *vtable=NULL;
Returns 0 on success, -1 on fail.
*/
-int
-obfs2_init(int n_options, char **options,
- struct protocol_params_t *params)
+static struct protocol_params_t *
+obfs2_init(int n_options, const char *const *options)
{
- if (parse_and_set_options(n_options,options,params) < 0) {
+ struct protocol_params_t *params
+ = calloc(1, sizeof(struct protocol_params_t));
+ if (!params)
+ return NULL;
+
+ if (parse_and_set_options(n_options, options, params) < 0) {
usage();
- return -1;
+ free(params);
+ return NULL;
}
- if (set_up_vtable() < 0)
- return -1;
-
if (initialize_crypto() < 0) {
- fprintf(stderr, "Can't initialize crypto; failing\n");
- return -1;
+ log_warn("Can't initialize crypto; failing");
+ free(params);
+ return NULL;
}
- return 0;
+ return params;
}
/**
Helper: Parses 'options' and fills 'params'.
*/
int
-parse_and_set_options(int n_options, char **options,
+parse_and_set_options(int n_options, const char *const *options,
struct protocol_params_t *params)
{
int got_dest=0;
@@ -75,7 +72,6 @@ parse_and_set_options(int n_options, char **options,
}
assert(!strcmp(*options,"obfs2"));
- params->proto = OBFS2_PROTOCOL;
options++;
/* Now parse the optional arguments */
@@ -136,6 +132,8 @@ parse_and_set_options(int n_options, char **options,
}
log_debug("%s(): Parsed obfs2 options nicely!", __func__);
+
+ params->vtable = &obfs2_vtable;
return 0;
}
@@ -159,28 +157,6 @@ usage(void)
"\tobfs2 server 127.0.0.1:1026");
}
-/**
- Helper: Allocates space for the protocol vtable and populates it's
- function pointers.
- Returns 0 on success, -1 on fail.
-*/
-static int
-set_up_vtable(void)
-{
- /* XXX memleak. */
- vtable = calloc(1, sizeof(protocol_vtable));
- if (!vtable)
- return -1;
-
- vtable->destroy = obfs2_state_free;
- vtable->create = obfs2_new;
- vtable->handshake = obfs2_send_initial_message;
- vtable->send = obfs2_send;
- vtable->recv = obfs2_recv;
-
- return 0;
-}
-
/** Return true iff the OBFUSCATE_SEED_LENGTH-byte seed in 'seed' is nonzero */
static int
seed_nonzero(const uchar *seed)
@@ -195,7 +171,7 @@ seed_nonzero(const uchar *seed)
static crypt_t *
derive_key(void *s, const char *keytype)
{
- obfs2_state_t *state = s;
+ obfs2_protocol_t *state = s;
crypt_t *cryptstate;
uchar buf[SHA256_LENGTH];
digest_t *c = digest_new();
@@ -235,7 +211,7 @@ static crypt_t *
derive_padding_key(void *s, const uchar *seed,
const char *keytype)
{
- obfs2_state_t *state = s;
+ obfs2_protocol_t *state = s;
crypt_t *cryptstate;
uchar buf[SHA256_LENGTH];
@@ -274,95 +250,84 @@ derive_padding_key(void *s, const uchar *seed,
to create and return a protocol state according to the protocol
parameters 'params'.
*/
-void *
-obfs2_new(struct protocol_t *proto_struct,
- protocol_params_t *params)
+static struct protocol_t *
+obfs2_create(protocol_params_t *params)
{
- assert(vtable);
- proto_struct->vtable = vtable;
-
- return obfs2_state_new(params);
-}
-
-/**
- Returns an obfs2 state according to the protocol parameters
- 'params'. If something goes wrong it returns NULL.
- */
-static void *
-obfs2_state_new(protocol_params_t *params)
-{
- obfs2_state_t *state = calloc(1, sizeof(obfs2_state_t));
+ obfs2_protocol_t *proto = calloc(1, sizeof(obfs2_protocol_t));
uchar *seed;
const char *send_pad_type;
- if (!state)
+ if (!proto)
return NULL;
- state->state = ST_WAIT_FOR_KEY;
- state->we_are_initiator = params->is_initiator;
- if (state->we_are_initiator) {
+ proto->state = ST_WAIT_FOR_KEY;
+ proto->we_are_initiator = params->is_initiator;
+ if (proto->we_are_initiator) {
send_pad_type = INITIATOR_PAD_TYPE;
- seed = state->initiator_seed;
+ seed = proto->initiator_seed;
} else {
send_pad_type = RESPONDER_PAD_TYPE;
- seed = state->responder_seed;
+ seed = proto->responder_seed;
}
/* Generate our seed */
if (random_bytes(seed, OBFUSCATE_SEED_LENGTH) < 0) {
- free(state);
+ free(proto);
return NULL;
}
- if (params->shared_secret)
- if (obfs2_state_set_shared_secret(state,
- params->shared_secret,
- params->shared_secret_len)<0)
+ if (params->shared_secret) {
+ /* ASN we must say in spec that we hash command line shared secret. */
+ digest_t *c = digest_new();
+ if (!c) {
+ free(proto);
return NULL;
+ }
+ digest_update(c, (uchar*)params->shared_secret, params->shared_secret_len);
+ digest_getdigest(c, proto->secret_seed, SHARED_SECRET_LENGTH);
+ digest_free(c);
+ }
/* Derive the key for what we're sending */
- state->send_padding_crypto = derive_padding_key(state, seed, send_pad_type);
- if (state->send_padding_crypto == NULL) {
- free(state);
+ proto->send_padding_crypto = derive_padding_key(proto, seed, send_pad_type);
+ if (proto->send_padding_crypto == NULL) {
+ free(proto);
return NULL;
}
- return state;
+ proto->super.vtable = &obfs2_vtable;
+ return &proto->super;
}
/**
- Sets the shared 'secret' to be used, on the protocol state 's'.
+ Frees obfs2 state 's'
*/
-static int
-obfs2_state_set_shared_secret(void *s, const char *secret,
- size_t secretlen)
+static void
+obfs2_destroy(struct protocol_t *s)
{
- assert(secret);
- assert(secretlen);
-
- uchar buf[SHARED_SECRET_LENGTH];
- obfs2_state_t *state = s;
-
- /* ASN we must say in spec that we hash command line shared secret. */
- digest_t *c = digest_new();
- digest_update(c, (uchar*)secret, secretlen);
- digest_getdigest(c, buf, sizeof(buf));
-
- memcpy(state->secret_seed, buf, SHARED_SECRET_LENGTH);
-
- memset(buf,0,SHARED_SECRET_LENGTH);
- digest_free(c);
-
- return 0;
+ obfs2_protocol_t *state = downcast(s);
+ if (state->send_crypto)
+ crypt_free(state->send_crypto);
+ if (state->send_padding_crypto)
+ crypt_free(state->send_padding_crypto);
+ if (state->recv_crypto)
+ crypt_free(state->recv_crypto);
+ if (state->recv_padding_crypto)
+ crypt_free(state->recv_padding_crypto);
+ if (state->pending_data_to_send)
+ evbuffer_free(state->pending_data_to_send);
+ memset(state, 0x0a, sizeof(obfs2_protocol_t));
+ free(state);
}
+
/**
Write the initial protocol setup and padding message for state 's' to
the evbuffer 'buf'. Return 0 on success, -1 on failure.
*/
static int
-obfs2_send_initial_message(void *s, struct evbuffer *buf)
+obfs2_handshake(struct protocol_t *s, struct evbuffer *buf)
{
- obfs2_state_t *state = s;
+ obfs2_protocol_t *state = downcast(s);
uint32_t magic = htonl(OBFUSCATE_MAGIC_VALUE), plength, send_plength;
uchar msg[OBFUSCATE_MAX_PADDING + OBFUSCATE_SEED_LENGTH + 8];
@@ -426,10 +391,10 @@ crypt_and_transmit(crypt_t *crypto,
using the state in 'state'. Returns 0 on success, -1 on failure.
*/
static int
-obfs2_send(void *s,
+obfs2_send(struct protocol_t *s,
struct evbuffer *source, struct evbuffer *dest)
{
- obfs2_state_t *state = s;
+ obfs2_protocol_t *state = downcast(s);
if (state->send_crypto) {
/* First of all, send any data that we've been waiting to send. */
@@ -460,7 +425,7 @@ obfs2_send(void *s,
static int
init_crypto(void *s)
{
- obfs2_state_t *state = s;
+ obfs2_protocol_t *state = s;
const char *send_keytype;
const char *recv_keytype;
@@ -503,10 +468,10 @@ init_crypto(void *s)
* our callers that they must call obfs2_send() immediately.
*/
static enum recv_ret
-obfs2_recv(void *s, struct evbuffer *source,
+obfs2_recv(struct protocol_t *s, struct evbuffer *source,
struct evbuffer *dest)
{
- obfs2_state_t *state = s;
+ obfs2_protocol_t *state = downcast(s);
enum recv_ret r=0;
if (state->state == ST_WAIT_FOR_KEY) {
@@ -587,23 +552,4 @@ obfs2_recv(void *s, struct evbuffer *source,
return r;
}
-/**
- Frees obfs2 state 's'
-*/
-static void
-obfs2_state_free(void *s)
-{
- obfs2_state_t *state = s;
- if (state->send_crypto)
- crypt_free(state->send_crypto);
- if (state->send_padding_crypto)
- crypt_free(state->send_padding_crypto);
- if (state->recv_crypto)
- crypt_free(state->recv_crypto);
- if (state->recv_padding_crypto)
- crypt_free(state->recv_padding_crypto);
- if (state->pending_data_to_send)
- evbuffer_free(state->pending_data_to_send);
- memset(state, 0x0a, sizeof(obfs2_state_t));
- free(state);
-}
+DEFINE_PROTOCOL_VTABLE(obfs2);
diff --git a/src/protocols/obfs2.h b/src/protocols/obfs2.h
index a9ebfb1..e93fbcd 100644
--- a/src/protocols/obfs2.h
+++ b/src/protocols/obfs2.h
@@ -2,27 +2,19 @@
See LICENSE for other credits and copying information
*/
-#ifndef OBFS2_H
-#define OBFS2_H
+#ifndef PROTOCOL_OBFS2_H
+#define PROTOCOL_OBFS2_H
-typedef struct obfs2_state_t obfs2_state_t;
-struct evbuffer;
-struct protocol_t;
-struct protocol_params_t;
-struct listener_t;
+struct protocol_vtable;
+extern const struct protocol_vtable obfs2_vtable;
-int obfs2_init(int n_options, char **options, struct protocol_params_t *params);
-void *obfs2_new(struct protocol_t *proto_struct,
- struct protocol_params_t *params);
-int parse_and_set_options(int n_options, char **options,
- struct protocol_params_t *params);
-
-#ifdef CRYPT_PROTOCOL_PRIVATE
+#ifdef PROTOCOL_OBFS2_PRIVATE
#include "../crypt.h"
+#include "../protocol.h"
/* ==========
- These definitions are not part of the crypt_protocol interface.
+ These definitions are not part of the obfs2_protocol interface.
They're exposed here so that the unit tests can use them.
==========
*/
@@ -43,7 +35,9 @@ int parse_and_set_options(int n_options, char **options,
#define SHARED_SECRET_LENGTH SHA256_LENGTH
-struct obfs2_state_t {
+typedef struct obfs2_protocol_t {
+ struct protocol_t super;
+
/** Current protocol state. We start out waiting for key information. Then
we have a key and wait for padding to arrive. Finally, we are sending
and receiving bytes on the connection.
@@ -76,7 +70,8 @@ struct obfs2_state_t {
/** Number of padding bytes to read before we get to real data */
int padding_left_to_read;
-};
+} obfs2_protocol_t;
+
#endif
#endif
diff --git a/src/test/unittest_obfs2.c b/src/test/unittest_obfs2.c
index 0b2054b..594c36c 100644
--- a/src/test/unittest_obfs2.c
+++ b/src/test/unittest_obfs2.c
@@ -5,12 +5,11 @@
#include "tinytest.h"
#include "tinytest_macros.h"
-#define CRYPT_PROTOCOL_PRIVATE
+#define PROTOCOL_OBFS2_PRIVATE
#define CRYPT_PRIVATE
#include "../protocols/obfs2.h"
#include "../crypt.h"
#include "../util.h"
-#include "../protocol.h"
#include <stdio.h>
#include <stdlib.h>
@@ -18,86 +17,60 @@
#include <event2/buffer.h>
+#define ALEN(x) (sizeof x/sizeof x[0])
+#define OPTV(name) static const char *const name[]
+
+static inline obfs2_protocol_t *
+downcast(struct protocol_t *proto)
+{
+ return (obfs2_protocol_t *)
+ ((char *)proto - offsetof(obfs2_protocol_t, super));
+}
static void
test_proto_option_parsing(void *data)
{
- protocol_params_t *proto_params = calloc(1, sizeof(protocol_params_t));
- char *options[] = {"obfs2", "--shared-secret=a", "socks", "127.0.0.1:0"};
- int n_options = 4;
-
/* Suppress logs for the duration of this function. */
log_set_method(LOG_METHOD_NULL, NULL);
- tt_assert(set_up_protocol(n_options, options,
- proto_params) == 0);
+ /** good option list */
+ OPTV(options1) = {"obfs2", "--shared-secret=a", "socks", "127.0.0.1:0"};
+ tt_assert(proto_params_init(ALEN(options1), options1) != NULL);
/** two --dest. */
- char *options2[] = {"obfs2", "--dest=127.0.0.1:5555", "--dest=a",
- "server", "127.0.0.1:5552"};
- n_options = 5;
-
- tt_assert(set_up_protocol(n_options, options2,
- proto_params) == -1);
+ OPTV(options2) = {"obfs2", "--dest=127.0.0.1:5555", "--dest=a",
+ "server", "127.0.0.1:5552"};
+ tt_assert(proto_params_init(ALEN(options2), options2) == NULL);
/** unknown arg */
- char *options3[] = {"obfs2", "--gabura=a",
- "server", "127.0.0.1:5552"};
- n_options = 4;
-
- tt_assert(set_up_protocol(n_options, options3,
- proto_params) == -1);
+ OPTV(options3) = {"obfs2", "--gabura=a", "server", "127.0.0.1:5552"};
+ tt_assert(proto_params_init(ALEN(options3), options3) == NULL)
/** too many args */
- char *options4[] = {"obfs2", "1", "2", "3", "4", "5" };
- n_options = 6;
-
- tt_assert(set_up_protocol(n_options, options4,
- proto_params) == -1);
+ OPTV(options4) = {"obfs2", "1", "2", "3", "4", "5" };
+ tt_assert(proto_params_init(ALEN(options4), options4) == NULL)
/** wrong mode */
- char *options5[] = {"obfs2", "--dest=1:1",
- "gladiator", "127.0.0.1:5552"};
- n_options = 4;
-
- tt_assert(set_up_protocol(n_options, options5,
- proto_params) == -1);
-
- /** stupid listen addr. */
- char *options6[] = {"obfs2", "--dest=1:1",
- "server", "127.0.0.1:a"};
- n_options = 4;
+ OPTV(options5) = {"obfs2", "--dest=1:1", "gladiator", "127.0.0.1:5552"};
+ tt_assert(proto_params_init(ALEN(options5), options5) == NULL)
- tt_assert(set_up_protocol(n_options, options6,
- proto_params) == -1);
+ /** bad listen addr. */
+ OPTV(options6) = {"obfs2", "--dest=1:1", "server", "127.0.0.1:a"};
+ tt_assert(proto_params_init(ALEN(options6), options6) == NULL)
- /** stupid dest addr. */
- char *options7[] = {"obfs2", "--dest=1:b",
- "server", "127.0.0.1:1"};
- n_options = 4;
-
- tt_assert(set_up_protocol(n_options, options7,
- proto_params) == -1);
+ /** bad dest addr. */
+ OPTV(options7) = {"obfs2", "--dest=1:b", "server", "127.0.0.1:1"};
+ tt_assert(proto_params_init(ALEN(options7), options7) == NULL)
/** socks with dest. */
- char *options8[] = {"obfs2", "--dest=1:2",
- "socks", "127.0.0.1:1"};
- n_options = 4;
-
- tt_assert(set_up_protocol(n_options, options8,
- proto_params) == -1);
+ OPTV(options8) = {"obfs2", "--dest=1:2", "socks", "127.0.0.1:1"};
+ tt_assert(proto_params_init(ALEN(options8), options8) == NULL)
/** socks with dest. */
- char *options9[] = {"obfs2", "--shared-secret=a",
- "server", "127.0.0.1:1"};
- n_options = 4;
-
- tt_assert(set_up_protocol(n_options, options9,
- proto_params) == -1);
+ OPTV(options9) = {"obfs2", "--shared-secret=a", "server", "127.0.0.1:1"};
+ tt_assert(proto_params_init(ALEN(options9), options9) == NULL)
end:
- if (proto_params)
- free(proto_params);
/* Unsuspend logging */
log_set_method(LOG_METHOD_STDOUT, NULL);
}
@@ -108,36 +81,36 @@ test_proto_setup(void *data)
{
struct protocol_t *client_proto = NULL;
struct protocol_t *server_proto = NULL;
+ struct protocol_params_t *proto_params_client = NULL;
+ struct protocol_params_t *proto_params_server = NULL;
- protocol_params_t *proto_params_client = calloc(1, sizeof(protocol_params_t));
- char *options_client[] = {"obfs2", "--shared-secret=hahaha",
- "socks", "127.0.0.1:1800"};
- int n_options_client = 4;
-
- protocol_params_t *proto_params_serv = calloc(1, sizeof(protocol_params_t));
- char *options_server[] = {"obfs2", "--shared-secret=hahaha",
- "--dest=127.0.0.1:1500",
- "server", "127.0.0.1:1800"};
- int n_options_server = 5;
-
- tt_assert(set_up_protocol(n_options_client, options_client,
- proto_params_client) >= 0);
- tt_assert(set_up_protocol(n_options_server, options_server,
- proto_params_serv) >= 0);
+ OPTV(options_client) = {"obfs2", "--shared-secret=hahaha",
+ "socks", "127.0.0.1:1800"};
+ proto_params_client = proto_params_init(ALEN(options_client), options_client);
+ tt_assert(proto_params_client);
- client_proto = proto_new(proto_params_serv);
- server_proto = proto_new(proto_params_client);
+ OPTV(options_server) = {"obfs2", "--shared-secret=hahaha",
+ "--dest=127.0.0.1:1500",
+ "server", "127.0.0.1:1800"};
+ proto_params_server = proto_params_init(ALEN(options_server), options_server);
+ tt_assert(proto_params_server);
+ client_proto = proto_create(proto_params_client);
tt_assert(client_proto);
+
+ server_proto = proto_create(proto_params_server);
tt_assert(server_proto);
- tt_assert(client_proto->state);
- tt_assert(server_proto->state);
- end:
+ end:;
if (client_proto)
- proto_destroy(client_proto);
+ proto_destroy(client_proto);
if (server_proto)
- proto_destroy(server_proto);
+ proto_destroy(server_proto);
+
+ if (proto_params_client)
+ proto_params_free(proto_params_client);
+ if (proto_params_server)
+ proto_params_free(proto_params_server);
}
static void
@@ -150,33 +123,28 @@ test_proto_handshake(void *data)
struct protocol_t *client_proto = NULL;
struct protocol_t *server_proto = NULL;
+ struct protocol_params_t *proto_params_client = NULL;
+ struct protocol_params_t *proto_params_server = NULL;
- protocol_params_t *proto_params_client = calloc(1, sizeof(protocol_params_t));
- char *options_client[] = {"obfs2", "--shared-secret=hahaha",
- "socks", "127.0.0.1:1800"};
- int n_options_client = 4;
-
- protocol_params_t *proto_params_serv = calloc(1, sizeof(protocol_params_t));
- char *options_server[] = {"obfs2", "--shared-secret=hahaha",
- "--dest=127.0.0.1:1500",
- "server", "127.0.0.1:1800"};
- int n_options_server = 5;
-
- tt_assert(set_up_protocol(n_options_client, options_client,
- proto_params_client) >= 0);
- tt_assert(set_up_protocol(n_options_server, options_server,
- proto_params_serv) >= 0);
+ OPTV(options_client) = {"obfs2", "--shared-secret=hahaha",
+ "socks", "127.0.0.1:1800"};
+ proto_params_client = proto_params_init(ALEN(options_client), options_client);
+ tt_assert(proto_params_client);
- client_proto = proto_new(proto_params_client);
- server_proto = proto_new(proto_params_serv);
+ OPTV(options_server) = {"obfs2", "--shared-secret=hahaha",
+ "--dest=127.0.0.1:1500",
+ "server", "127.0.0.1:1800"};
+ proto_params_server = proto_params_init(ALEN(options_server), options_server);
+ tt_assert(proto_params_server);
+ client_proto = proto_create(proto_params_client);
tt_assert(client_proto);
+
+ server_proto = proto_create(proto_params_server);
tt_assert(server_proto);
- tt_assert(client_proto->state);
- tt_assert(server_proto->state);
- obfs2_state_t *client_state = client_proto->state;
- obfs2_state_t *server_state = server_proto->state;
+ obfs2_protocol_t *client_state = downcast(client_proto);
+ obfs2_protocol_t *server_state = downcast(server_proto);
/* We create a client handshake message and pass it to output_buffer */
tt_int_op(0, <=, proto_handshake(client_proto, output_buffer));
@@ -209,9 +177,9 @@ test_proto_handshake(void *data)
proto_destroy(server_proto);
if (proto_params_client)
- free(proto_params_client);
- if (proto_params_serv)
- free(proto_params_serv);
+ proto_params_free(proto_params_client);
+ if (proto_params_server)
+ proto_params_free(proto_params_server);
if (output_buffer)
evbuffer_free(output_buffer);
@@ -229,30 +197,25 @@ test_proto_transfer(void *data)
struct protocol_t *client_proto = NULL;
struct protocol_t *server_proto = NULL;
+ struct protocol_params_t *proto_params_client = NULL;
+ struct protocol_params_t *proto_params_server = NULL;
- protocol_params_t *proto_params_client = calloc(1, sizeof(protocol_params_t));
- char *options_client[] = {"obfs2", "--shared-secret=hahaha",
- "socks", "127.0.0.1:1800"};
- int n_options_client = 4;
-
- protocol_params_t *proto_params_serv = calloc(1, sizeof(protocol_params_t));
- char *options_server[] = {"obfs2", "--shared-secret=hahaha",
- "--dest=127.0.0.1:1500",
- "server", "127.0.0.1:1800"};
- int n_options_server = 5;
-
- tt_assert(set_up_protocol(n_options_client, options_client,
- proto_params_client) >= 0);
- tt_assert(set_up_protocol(n_options_server, options_server,
- proto_params_serv) >= 0);
+ OPTV(options_client) = {"obfs2", "--shared-secret=hahaha",
+ "socks", "127.0.0.1:1800"};
+ proto_params_client = proto_params_init(ALEN(options_client), options_client);
+ tt_assert(proto_params_client);
- client_proto = proto_new(proto_params_client);
- server_proto = proto_new(proto_params_serv);
+ OPTV(options_server) = {"obfs2", "--shared-secret=hahaha",
+ "--dest=127.0.0.1:1500",
+ "server", "127.0.0.1:1800"};
+ proto_params_server = proto_params_init(ALEN(options_server), options_server);
+ tt_assert(proto_params_server);
+ client_proto = proto_create(proto_params_client);
tt_assert(client_proto);
+
+ server_proto = proto_create(proto_params_server);
tt_assert(server_proto);
- tt_assert(client_proto->state);
- tt_assert(server_proto->state);
int n;
struct evbuffer_iovec v[2];
@@ -302,9 +265,9 @@ test_proto_transfer(void *data)
proto_destroy(server_proto);
if (proto_params_client)
- free(proto_params_client);
- if (proto_params_serv)
- free(proto_params_serv);
+ proto_params_free(proto_params_client);
+ if (proto_params_server)
+ proto_params_free(proto_params_server);
if (output_buffer)
evbuffer_free(output_buffer);
@@ -325,8 +288,8 @@ test_proto_transfer(void *data)
static void
test_proto_split_handshake(void *data)
{
- obfs2_state_t *client_state = NULL;
- obfs2_state_t *server_state = NULL;
+ obfs2_protocol_t *client_state = NULL;
+ obfs2_protocol_t *server_state = NULL;
struct evbuffer *output_buffer = NULL;
struct evbuffer *dummy_buffer = NULL;
@@ -335,33 +298,28 @@ test_proto_split_handshake(void *data)
struct protocol_t *client_proto = NULL;
struct protocol_t *server_proto = NULL;
+ struct protocol_params_t *proto_params_client = NULL;
+ struct protocol_params_t *proto_params_server = NULL;
- protocol_params_t *proto_params_client = calloc(1, sizeof(protocol_params_t));
- char *options_client[] = {"obfs2", "--shared-secret=hahaha",
- "socks", "127.0.0.1:1800"};
- int n_options_client = 4;
-
- protocol_params_t *proto_params_serv = calloc(1, sizeof(protocol_params_t));
- char *options_server[] = {"obfs2", "--shared-secret=hahaha",
- "--dest=127.0.0.1:1500",
- "server", "127.0.0.1:1800"};
- int n_options_server = 5;
-
- tt_assert(set_up_protocol(n_options_client, options_client,
- proto_params_client) >= 0);
- tt_assert(set_up_protocol(n_options_server, options_server,
- proto_params_serv) >= 0);
+ OPTV(options_client) = {"obfs2", "--shared-secret=hahaha",
+ "socks", "127.0.0.1:1800"};
+ proto_params_client = proto_params_init(ALEN(options_client), options_client);
+ tt_assert(proto_params_client);
- client_proto = proto_new(proto_params_client);
- server_proto = proto_new(proto_params_serv);
+ OPTV(options_server) = {"obfs2", "--shared-secret=hahaha",
+ "--dest=127.0.0.1:1500",
+ "server", "127.0.0.1:1800"};
+ proto_params_server = proto_params_init(ALEN(options_server), options_server);
+ tt_assert(proto_params_server);
+ client_proto = proto_create(proto_params_client);
tt_assert(client_proto);
+
+ server_proto = proto_create(proto_params_server);
tt_assert(server_proto);
- tt_assert(client_proto->state);
- tt_assert(server_proto->state);
- client_state = client_proto->state;
- server_state = server_proto->state;
+ client_state = downcast(client_proto);
+ server_state = downcast(server_proto);
uint32_t magic = htonl(OBFUSCATE_MAGIC_VALUE);
uint32_t plength1, plength1_msg1, plength1_msg2, send_plength1;
@@ -474,9 +432,9 @@ test_proto_split_handshake(void *data)
proto_destroy(server_proto);
if (proto_params_client)
- free(proto_params_client);
- if (proto_params_serv)
- free(proto_params_serv);
+ proto_params_free(proto_params_client);
+ if (proto_params_server)
+ proto_params_free(proto_params_server);
if (output_buffer)
evbuffer_free(output_buffer);
@@ -491,8 +449,8 @@ test_proto_split_handshake(void *data)
static void
test_proto_wrong_handshake_magic(void *data)
{
- obfs2_state_t *client_state = NULL;
- obfs2_state_t *server_state = NULL;
+ obfs2_protocol_t *client_state = NULL;
+ obfs2_protocol_t *server_state = NULL;
struct evbuffer *output_buffer = NULL;
struct evbuffer *dummy_buffer = NULL;
@@ -501,33 +459,28 @@ test_proto_wrong_handshake_magic(void *data)
struct protocol_t *client_proto = NULL;
struct protocol_t *server_proto = NULL;
+ struct protocol_params_t *proto_params_client = NULL;
+ struct protocol_params_t *proto_params_server = NULL;
- protocol_params_t *proto_params_client = calloc(1, sizeof(protocol_params_t));
- char *options_client[] = {"obfs2", "--shared-secret=hahaha",
- "socks", "127.0.0.1:1800"};
- int n_options_client = 4;
-
- protocol_params_t *proto_params_serv = calloc(1, sizeof(protocol_params_t));
- char *options_server[] = {"obfs2", "--shared-secret=hahaha",
- "--dest=127.0.0.1:1500",
- "server", "127.0.0.1:1800"};
- int n_options_server = 5;
+ OPTV(options_client) = {"obfs2", "--shared-secret=hahaha",
+ "socks", "127.0.0.1:1800"};
+ proto_params_client = proto_params_init(ALEN(options_client), options_client);
+ tt_assert(proto_params_client);
- tt_assert(set_up_protocol(n_options_client, options_client,
- proto_params_client) >= 0);
- tt_assert(set_up_protocol(n_options_server, options_server,
- proto_params_serv) >= 0);
-
- client_proto = proto_new(proto_params_client);
- server_proto = proto_new(proto_params_serv);
+ OPTV(options_server) = {"obfs2", "--shared-secret=hahaha",
+ "--dest=127.0.0.1:1500",
+ "server", "127.0.0.1:1800"};
+ proto_params_server = proto_params_init(ALEN(options_server), options_server);
+ tt_assert(proto_params_server);
+ client_proto = proto_create(proto_params_client);
tt_assert(client_proto);
+
+ server_proto = proto_create(proto_params_server);
tt_assert(server_proto);
- tt_assert(client_proto->state);
- tt_assert(server_proto->state);
- client_state = client_proto->state;
- server_state = server_proto->state;
+ client_state = downcast(client_proto);
+ server_state = downcast(server_proto);
uint32_t wrong_magic = 0xD15EA5E;
@@ -561,9 +514,9 @@ test_proto_wrong_handshake_magic(void *data)
proto_destroy(server_proto);
if (proto_params_client)
- free(proto_params_client);
- if (proto_params_serv)
- free(proto_params_serv);
+ proto_params_free(proto_params_client);
+ if (proto_params_server)
+ proto_params_free(proto_params_server);
if (output_buffer)
evbuffer_free(output_buffer);
@@ -577,8 +530,8 @@ test_proto_wrong_handshake_magic(void *data)
static void
test_proto_wrong_handshake_plength(void *data)
{
- obfs2_state_t *client_state = NULL;
- obfs2_state_t *server_state = NULL;
+ obfs2_protocol_t *client_state = NULL;
+ obfs2_protocol_t *server_state = NULL;
struct evbuffer *output_buffer = NULL;
struct evbuffer *dummy_buffer = NULL;
@@ -587,34 +540,28 @@ test_proto_wrong_handshake_plength(void *data)
struct protocol_t *client_proto = NULL;
struct protocol_t *server_proto = NULL;
+ struct protocol_params_t *proto_params_client = NULL;
+ struct protocol_params_t *proto_params_server = NULL;
+ OPTV(options_client) = {"obfs2", "--shared-secret=hahaha",
+ "socks", "127.0.0.1:1800"};
+ proto_params_client = proto_params_init(ALEN(options_client), options_client);
+ tt_assert(proto_params_client);
- protocol_params_t *proto_params_client = calloc(1, sizeof(protocol_params_t));
- char *options_client[] = {"obfs2", "--shared-secret=hahaha",
- "socks", "127.0.0.1:1800"};
- int n_options_client = 4;
-
- protocol_params_t *proto_params_serv = calloc(1, sizeof(protocol_params_t));
- char *options_server[] = {"obfs2", "--shared-secret=hahaha",
- "--dest=127.0.0.1:1500",
- "server", "127.0.0.1:1800"};
- int n_options_server = 5;
-
- tt_assert(set_up_protocol(n_options_client, options_client,
- proto_params_client) >= 0);
- tt_assert(set_up_protocol(n_options_server, options_server,
- proto_params_serv) >= 0);
-
- client_proto = proto_new(proto_params_client);
- server_proto = proto_new(proto_params_serv);
+ OPTV(options_server) = {"obfs2", "--shared-secret=hahaha",
+ "--dest=127.0.0.1:1500",
+ "server", "127.0.0.1:1800"};
+ proto_params_server = proto_params_init(ALEN(options_server), options_server);
+ tt_assert(proto_params_server);
+ client_proto = proto_create(proto_params_client);
tt_assert(client_proto);
+
+ server_proto = proto_create(proto_params_server);
tt_assert(server_proto);
- tt_assert(client_proto->state);
- tt_assert(server_proto->state);
- client_state = client_proto->state;
- server_state = server_proto->state;
+ client_state = downcast(client_proto);
+ server_state = downcast(server_proto);
uchar msg[OBFUSCATE_MAX_PADDING + OBFUSCATE_SEED_LENGTH + 8 + 1];
uint32_t magic = htonl(OBFUSCATE_MAGIC_VALUE);
@@ -641,15 +588,15 @@ test_proto_wrong_handshake_plength(void *data)
tt_assert(server_state->state == ST_WAIT_FOR_KEY);
end:
- if (client_state)
+ if (client_proto)
proto_destroy(client_proto);
- if (server_state)
+ if (server_proto)
proto_destroy(server_proto);
if (proto_params_client)
- free(proto_params_client);
- if (proto_params_serv)
- free(proto_params_serv);
+ proto_params_free(proto_params_client);
+ if (proto_params_server)
+ proto_params_free(proto_params_server);
if (output_buffer)
evbuffer_free(output_buffer);
1
0
[obfsproxy/master] Remove stray semicolons from tinytest_macros.h, and add missing ones to unittest_obfs2.c.
by nickm@torproject.org 09 Sep '11
by nickm@torproject.org 09 Sep '11
09 Sep '11
commit c5a011bc9ea83beb75084813835e0dd99e60ca68
Author: Zack Weinberg <zackw(a)panix.com>
Date: Wed Jul 13 15:13:17 2011 -0700
Remove stray semicolons from tinytest_macros.h, and add missing ones to unittest_obfs2.c.
---
src/test/tinytest_macros.h | 4 ++--
src/test/unittest_obfs2.c | 14 +++++++-------
2 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/src/test/tinytest_macros.h b/src/test/tinytest_macros.h
index 9a67e71..089616a 100644
--- a/src/test/tinytest_macros.h
+++ b/src/test/tinytest_macros.h
@@ -99,11 +99,11 @@
/* Assert b, but do not stop the test if b fails. Log msg on failure. */
#define tt_want_msg(b, msg) \
- _tt_want(b, msg, );
+ _tt_want(b, msg, )
/* Assert b and stop the test if b fails. Log msg on failure. */
#define tt_assert_msg(b, msg) \
- _tt_want(b, msg, TT_EXIT_TEST_FUNCTION);
+ _tt_want(b, msg, TT_EXIT_TEST_FUNCTION)
/* Assert b, but do not stop the test if b fails. */
#define tt_want(b) tt_want_msg( (b), "want("#b")")
diff --git a/src/test/unittest_obfs2.c b/src/test/unittest_obfs2.c
index b3db0be..11dcb16 100644
--- a/src/test/unittest_obfs2.c
+++ b/src/test/unittest_obfs2.c
@@ -44,31 +44,31 @@ test_obfs2_option_parsing(void *data)
/** unknown arg */
OPTV(options3) = {"obfs2", "--gabura=a", "server", "127.0.0.1:5552"};
- tt_assert(proto_params_init(ALEN(options3), options3) == NULL)
+ tt_assert(proto_params_init(ALEN(options3), options3) == NULL);
/** too many args */
OPTV(options4) = {"obfs2", "1", "2", "3", "4", "5" };
- tt_assert(proto_params_init(ALEN(options4), options4) == NULL)
+ tt_assert(proto_params_init(ALEN(options4), options4) == NULL);
/** wrong mode */
OPTV(options5) = {"obfs2", "--dest=1:1", "gladiator", "127.0.0.1:5552"};
- tt_assert(proto_params_init(ALEN(options5), options5) == NULL)
+ tt_assert(proto_params_init(ALEN(options5), options5) == NULL);
/** bad listen addr. */
OPTV(options6) = {"obfs2", "--dest=1:1", "server", "127.0.0.1:a"};
- tt_assert(proto_params_init(ALEN(options6), options6) == NULL)
+ tt_assert(proto_params_init(ALEN(options6), options6) == NULL);
/** bad dest addr. */
OPTV(options7) = {"obfs2", "--dest=1:b", "server", "127.0.0.1:1"};
- tt_assert(proto_params_init(ALEN(options7), options7) == NULL)
+ tt_assert(proto_params_init(ALEN(options7), options7) == NULL);
/** socks with dest. */
OPTV(options8) = {"obfs2", "--dest=1:2", "socks", "127.0.0.1:1"};
- tt_assert(proto_params_init(ALEN(options8), options8) == NULL)
+ tt_assert(proto_params_init(ALEN(options8), options8) == NULL);
/** socks with dest. */
OPTV(options9) = {"obfs2", "--shared-secret=a", "server", "127.0.0.1:1"};
- tt_assert(proto_params_init(ALEN(options9), options9) == NULL)
+ tt_assert(proto_params_init(ALEN(options9), options9) == NULL);
end:
/* Unsuspend logging */
1
0