commit 8800360fa9dc8f60b9d4d441079f7fc9f968e587 Author: Zack Weinberg zackw@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) {