tor-commits
Threads by month
- ----- 2026 -----
- April
- March
- February
- 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
- 215040 discussions
[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
09 Sep '11
commit 5b5a0c249815d0b8f600adc3858f91ea2a53af91
Author: Zack Weinberg <zackw(a)panix.com>
Date: Wed Jul 13 15:04:48 2011 -0700
Rename the obfs2 tests to obfs2/whatever
---
src/test/unittest.c | 4 ++--
src/test/unittest_obfs2.c | 36 ++++++++++++++++++------------------
2 files changed, 20 insertions(+), 20 deletions(-)
diff --git a/src/test/unittest.c b/src/test/unittest.c
index fed4bf3..45757e9 100644
--- a/src/test/unittest.c
+++ b/src/test/unittest.c
@@ -6,12 +6,12 @@
#include "../crypt.h"
extern struct testcase_t crypt_tests[];
-extern struct testcase_t protocol_tests[];
+extern struct testcase_t obfs2_tests[];
extern struct testcase_t socks_tests[];
struct testgroup_t groups[] = {
{ "crypt/", crypt_tests },
- { "proto/", protocol_tests },
+ { "obfs2/", obfs2_tests },
{ "socks/", socks_tests },
END_OF_GROUPS
};
diff --git a/src/test/unittest_obfs2.c b/src/test/unittest_obfs2.c
index 594c36c..b3db0be 100644
--- a/src/test/unittest_obfs2.c
+++ b/src/test/unittest_obfs2.c
@@ -28,7 +28,7 @@ downcast(struct protocol_t *proto)
}
static void
-test_proto_option_parsing(void *data)
+test_obfs2_option_parsing(void *data)
{
/* Suppress logs for the duration of this function. */
log_set_method(LOG_METHOD_NULL, NULL);
@@ -77,7 +77,7 @@ test_proto_option_parsing(void *data)
/* Make sure we can successfully set up a protocol state */
static void
-test_proto_setup(void *data)
+test_obfs2_setup(void *data)
{
struct protocol_t *client_proto = NULL;
struct protocol_t *server_proto = NULL;
@@ -114,7 +114,7 @@ test_proto_setup(void *data)
}
static void
-test_proto_handshake(void *data)
+test_obfs2_handshake(void *data)
{
struct evbuffer *output_buffer = NULL;
struct evbuffer *dummy_buffer = NULL;
@@ -188,7 +188,7 @@ test_proto_handshake(void *data)
}
static void
-test_proto_transfer(void *data)
+test_obfs2_transfer(void *data)
{
struct evbuffer *output_buffer = NULL;
struct evbuffer *dummy_buffer = NULL;
@@ -286,7 +286,7 @@ test_proto_transfer(void *data)
Afterwards we will verify that they both got the correct keys.
That's right, this unit test is loco . */
static void
-test_proto_split_handshake(void *data)
+test_obfs2_split_handshake(void *data)
{
obfs2_protocol_t *client_state = NULL;
obfs2_protocol_t *server_state = NULL;
@@ -447,7 +447,7 @@ test_proto_split_handshake(void *data)
Wrong magic value.
*/
static void
-test_proto_wrong_handshake_magic(void *data)
+test_obfs2_wrong_handshake_magic(void *data)
{
obfs2_protocol_t *client_state = NULL;
obfs2_protocol_t *server_state = NULL;
@@ -528,7 +528,7 @@ test_proto_wrong_handshake_magic(void *data)
plength field larger than OBFUSCATE_MAX_PADDING
*/
static void
-test_proto_wrong_handshake_plength(void *data)
+test_obfs2_wrong_handshake_plength(void *data)
{
obfs2_protocol_t *client_state = NULL;
obfs2_protocol_t *server_state = NULL;
@@ -604,16 +604,16 @@ test_proto_wrong_handshake_plength(void *data)
evbuffer_free(dummy_buffer);
}
-#define T(name, flags) \
- { #name, test_proto_##name, (flags), NULL, NULL }
-
-struct testcase_t protocol_tests[] = {
- T(option_parsing,0),
- T(setup, 0),
- T(handshake, 0),
- T(transfer, 0),
- T(split_handshake, 0),
- T(wrong_handshake_magic, 0),
- T(wrong_handshake_plength, 0),
+#define T(name) \
+ { #name, test_obfs2_##name, 0, NULL, NULL }
+
+struct testcase_t obfs2_tests[] = {
+ T(option_parsing),
+ T(setup),
+ T(handshake),
+ T(transfer),
+ T(split_handshake),
+ T(wrong_handshake_magic),
+ T(wrong_handshake_plength),
END_OF_TESTCASES
};
1
0
09 Sep '11
commit 88be04fb580a7e870f5d7f48286bcbdcd9b1317c
Author: Zack Weinberg <zackw(a)panix.com>
Date: Wed Jul 13 16:05:51 2011 -0700
Reduce repetition in unittest_obfs2.c
---
src/test/unittest_obfs2.c | 525 ++++++++++++++++-----------------------------
1 files changed, 186 insertions(+), 339 deletions(-)
diff --git a/src/test/unittest_obfs2.c b/src/test/unittest_obfs2.c
index 11dcb16..01ce501 100644
--- a/src/test/unittest_obfs2.c
+++ b/src/test/unittest_obfs2.c
@@ -18,7 +18,6 @@
#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)
@@ -28,136 +27,159 @@ downcast(struct protocol_t *proto)
}
static void
-test_obfs2_option_parsing(void *data)
+test_obfs2_option_parsing(void *unused)
{
+ struct option_parsing_case {
+ struct protocol_params_t *result;
+ short should_succeed;
+ short n_opts;
+ const char *const opts[6];
+ };
+ static struct option_parsing_case cases[] = {
+ /** good option list */
+ { 0, 1, 4, {"obfs2", "--shared-secret=a", "socks", "127.0.0.1:0"} },
+ /** two --dest. */
+ { 0, 0, 5, {"obfs2", "--dest=127.0.0.1:5555", "--dest=a",
+ "server", "127.0.0.1:5552"} },
+ /** unknown arg */
+ { 0, 0, 4, {"obfs2", "--gabura=a", "server", "127.0.0.1:5552"} },
+ /** too many args */
+ { 0, 0, 6, {"obfs2", "1", "2", "3", "4", "5" } },
+ /** wrong mode */
+ { 0, 0, 4, {"obfs2", "--dest=1:1", "gladiator", "127.0.0.1:5552"} },
+ /** bad listen addr */
+ { 0, 0, 4, {"obfs2", "--dest=1:1", "server", "127.0.0.1:a"} },
+ /** bad dest addr */
+ { 0, 0, 4, {"obfs2", "--dest=1:b", "server", "127.0.0.1:1"} },
+ /** socks with dest */
+ { 0, 0, 4, {"obfs2", "--dest=1:2", "socks", "127.0.0.1:1"} },
+ /** server without dest */
+ { 0, 0, 4, {"obfs2", "--shared-secret=a", "server", "127.0.0.1:1"} },
+
+ { 0, 0, 0, {0} }
+ };
+
/* Suppress logs for the duration of this function. */
log_set_method(LOG_METHOD_NULL, NULL);
- /** 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. */
- 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);
+ 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);
+ }
- /** unknown arg */
- OPTV(options3) = {"obfs2", "--gabura=a", "server", "127.0.0.1:5552"};
- tt_assert(proto_params_init(ALEN(options3), options3) == NULL);
+ end:
+ for (c = cases; c->n_opts; c++)
+ if (c->result)
+ proto_params_free(c->result);
- /** too many args */
- OPTV(options4) = {"obfs2", "1", "2", "3", "4", "5" };
- tt_assert(proto_params_init(ALEN(options4), options4) == NULL);
+ /* Unsuspend logging */
+ log_set_method(LOG_METHOD_STDOUT, NULL);
+}
- /** wrong mode */
- OPTV(options5) = {"obfs2", "--dest=1:1", "gladiator", "127.0.0.1:5552"};
- tt_assert(proto_params_init(ALEN(options5), options5) == NULL);
+/* 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;
+ struct evbuffer *output_buffer;
+ struct evbuffer *dummy_buffer;
+};
- /** bad listen addr. */
- OPTV(options6) = {"obfs2", "--dest=1:1", "server", "127.0.0.1:a"};
- tt_assert(proto_params_init(ALEN(options6), options6) == NULL);
+static int
+cleanup_obfs2_state(const struct testcase_t *unused, void *state)
+{
+ struct test_obfs2_state *s = (struct test_obfs2_state *)state;
- /** bad dest addr. */
- OPTV(options7) = {"obfs2", "--dest=1:b", "server", "127.0.0.1:1"};
- tt_assert(proto_params_init(ALEN(options7), options7) == NULL);
+ if (s->client_proto)
+ proto_destroy(s->client_proto);
+ if (s->server_proto)
+ proto_destroy(s->server_proto);
- /** socks with dest. */
- OPTV(options8) = {"obfs2", "--dest=1:2", "socks", "127.0.0.1:1"};
- tt_assert(proto_params_init(ALEN(options8), options8) == NULL);
+ if (s->proto_params_client)
+ proto_params_free(s->proto_params_client);
+ if (s->proto_params_server)
+ proto_params_free(s->proto_params_server);
- /** socks with dest. */
- OPTV(options9) = {"obfs2", "--shared-secret=a", "server", "127.0.0.1:1"};
- tt_assert(proto_params_init(ALEN(options9), options9) == NULL);
+ if (s->output_buffer)
+ evbuffer_free(s->output_buffer);
+ if (s->dummy_buffer)
+ evbuffer_free(s->dummy_buffer);
- end:
- /* Unsuspend logging */
- log_set_method(LOG_METHOD_STDOUT, NULL);
+ free(state);
+ return 1;
}
-/* Make sure we can successfully set up a protocol state */
-static void
-test_obfs2_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;
+static const char *const options_client[] =
+ {"obfs2", "--shared-secret=hahaha", "socks", "127.0.0.1:1800"};
- 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);
+static const char *const options_server[] =
+ {"obfs2", "--shared-secret=hahaha",
+ "--dest=127.0.0.1:1500", "server", "127.0.0.1:1800"};
- 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);
+static void *
+setup_obfs2_state(const struct testcase_t *unused)
+{
+ struct test_obfs2_state *s = calloc(1, sizeof(struct test_obfs2_state));
+ tt_assert(s);
- client_proto = proto_create(proto_params_client);
- tt_assert(client_proto);
+ s->proto_params_client =
+ proto_params_init(ALEN(options_client), options_client);
+ tt_assert(s->proto_params_client);
- server_proto = proto_create(proto_params_server);
- tt_assert(server_proto);
+ s->proto_params_server =
+ proto_params_init(ALEN(options_server), options_server);
+ tt_assert(s->proto_params_server);
- end:;
- if (client_proto)
- proto_destroy(client_proto);
- if (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);
-}
+ s->client_proto = proto_create(s->proto_params_client);
+ tt_assert(s->client_proto);
-static void
-test_obfs2_handshake(void *data)
-{
- struct evbuffer *output_buffer = NULL;
- struct evbuffer *dummy_buffer = NULL;
- output_buffer = evbuffer_new();
- dummy_buffer = evbuffer_new();
+ s->server_proto = proto_create(s->proto_params_server);
+ tt_assert(s->server_proto);
- 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;
+ s->output_buffer = evbuffer_new();
+ tt_assert(s->output_buffer);
- 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);
+ s->dummy_buffer = evbuffer_new();
+ tt_assert(s->dummy_buffer);
- 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);
+ return s;
- client_proto = proto_create(proto_params_client);
- tt_assert(client_proto);
+ end:
+ if (s)
+ cleanup_obfs2_state(NULL, s);
+ return 0;
+}
- server_proto = proto_create(proto_params_server);
- tt_assert(server_proto);
+static const struct testcase_setup_t obfs2_fixture =
+ { setup_obfs2_state, cleanup_obfs2_state };
- obfs2_protocol_t *client_state = downcast(client_proto);
- obfs2_protocol_t *server_state = downcast(server_proto);
+static void
+test_obfs2_handshake(void *state)
+{
+ struct test_obfs2_state *s = (struct test_obfs2_state *)state;
+ obfs2_protocol_t *client_state = downcast(s->client_proto);
+ obfs2_protocol_t *server_state = downcast(s->server_proto);
/* We create a client handshake message and pass it to output_buffer */
- tt_int_op(0, <=, proto_handshake(client_proto, output_buffer));
+ tt_int_op(0, <=, proto_handshake(s->client_proto, s->output_buffer));
/* We simulate the server receiving and processing the client's
handshake message, by using proto_recv() on the output_buffer */
- tt_assert(RECV_GOOD == proto_recv(server_proto, output_buffer, dummy_buffer));
+ tt_assert(RECV_GOOD == proto_recv(s->server_proto, s->output_buffer,
+ s->dummy_buffer));
/* Now, we create the server's handshake and pass it to output_buffer */
- tt_int_op(0, <=, proto_handshake(server_proto, output_buffer));
+ tt_int_op(0, <=, proto_handshake(s->server_proto, s->output_buffer));
/* We simulate the client receiving and processing the server's handshake */
- tt_assert(RECV_GOOD == proto_recv(client_proto, output_buffer, dummy_buffer));
+ tt_assert(RECV_GOOD == proto_recv(s->client_proto, s->output_buffer,
+ s->dummy_buffer));
/* The handshake is now complete. We should have:
client's send_crypto == server's recv_crypto
@@ -170,109 +192,57 @@ test_obfs2_handshake(void *data)
server_state->send_crypto,
sizeof(crypt_t)));
- end:
- if (client_proto)
- proto_destroy(client_proto);
- if (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);
-
- if (output_buffer)
- evbuffer_free(output_buffer);
- if (dummy_buffer)
- evbuffer_free(dummy_buffer);
+ end:;
}
static void
-test_obfs2_transfer(void *data)
+test_obfs2_transfer(void *state)
{
- struct evbuffer *output_buffer = NULL;
- struct evbuffer *dummy_buffer = NULL;
- output_buffer = evbuffer_new();
- dummy_buffer = evbuffer_new();
-
- 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);
-
- 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);
-
+ struct test_obfs2_state *s = (struct test_obfs2_state *)state;
int n;
struct evbuffer_iovec v[2];
/* Handshake */
- tt_int_op(0, <=, proto_handshake(client_proto, output_buffer));
- tt_assert(RECV_GOOD == proto_recv(server_proto, output_buffer, dummy_buffer));
- tt_int_op(0, <=, proto_handshake(server_proto, output_buffer));
- tt_assert(RECV_GOOD == proto_recv(client_proto, output_buffer, dummy_buffer));
+ tt_int_op(0, <=, proto_handshake(s->client_proto, s->output_buffer));
+ tt_assert(RECV_GOOD == proto_recv(s->server_proto, s->output_buffer,
+ s->dummy_buffer));
+ tt_int_op(0, <=, proto_handshake(s->server_proto, s->output_buffer));
+ tt_assert(RECV_GOOD == proto_recv(s->client_proto, s->output_buffer,
+ s->dummy_buffer));
/* End of Handshake */
/* Now let's pass some data around. */
- char *msg1 = "this is a 54-byte message passed from client to server";
- char *msg2 = "this is a 55-byte message passed from server to client!";
+ 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(dummy_buffer, msg1, 54);
- proto_send(client_proto, dummy_buffer, output_buffer);
-
- tt_assert(RECV_GOOD == proto_recv(server_proto, output_buffer, dummy_buffer));
+ evbuffer_add(s->dummy_buffer, msg1, 54);
+ proto_send(s->client_proto, s->dummy_buffer, s->output_buffer);
- n = evbuffer_peek(dummy_buffer, -1, NULL, &v[0], 2);
- tt_int_op(n, !=, -1);
+ tt_assert(RECV_GOOD == proto_recv(s->server_proto, s->output_buffer,
+ s->dummy_buffer));
- /* Let's check if it matches. */
+ 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(dummy_buffer);
- tt_int_op(0, ==, evbuffer_drain(dummy_buffer, buffer_len));
+ 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(dummy_buffer, msg2, 55);
- tt_int_op(0, <=, proto_send(server_proto, dummy_buffer, output_buffer));
+ 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(client_proto, output_buffer, dummy_buffer));
+ tt_assert(RECV_GOOD == proto_recv(s->client_proto, s->output_buffer,
+ s->dummy_buffer));
- n = evbuffer_peek(dummy_buffer, -1, NULL, &v[1], 2);
+ 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));
- (void) n; /* XXXX: use n for something, or remove it. */
-
- end:
- if (client_proto)
- proto_destroy(client_proto);
- if (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);
-
- if (output_buffer)
- evbuffer_free(output_buffer);
- if (dummy_buffer)
- evbuffer_free(dummy_buffer);
+ end:;
}
/* We are going to split client's handshake into:
@@ -286,40 +256,11 @@ test_obfs2_transfer(void *data)
Afterwards we will verify that they both got the correct keys.
That's right, this unit test is loco . */
static void
-test_obfs2_split_handshake(void *data)
+test_obfs2_split_handshake(void *state)
{
- obfs2_protocol_t *client_state = NULL;
- obfs2_protocol_t *server_state = NULL;
-
- struct evbuffer *output_buffer = NULL;
- struct evbuffer *dummy_buffer = NULL;
- output_buffer = evbuffer_new();
- dummy_buffer = evbuffer_new();
-
- 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);
-
- 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);
-
- client_state = downcast(client_proto);
- server_state = downcast(server_proto);
+ struct test_obfs2_state *s = (struct test_obfs2_state *)state;
+ obfs2_protocol_t *client_state = downcast(s->client_proto);
+ obfs2_protocol_t *server_state = downcast(s->server_proto);
uint32_t magic = htonl(OBFUSCATE_MAGIC_VALUE);
uint32_t plength1, plength1_msg1, plength1_msg2, send_plength1;
@@ -350,12 +291,12 @@ test_obfs2_split_handshake(void *data)
msgclient_1+OBFUSCATE_SEED_LENGTH, 8+plength1_msg1);
/* Client sends handshake part 1 */
- evbuffer_add(output_buffer, msgclient_1,
+ evbuffer_add(s->output_buffer, msgclient_1,
OBFUSCATE_SEED_LENGTH+8+plength1_msg1);
/* Server receives handshake part 1 */
- tt_assert(RECV_INCOMPLETE == proto_recv(server_proto,
- output_buffer, dummy_buffer));
+ tt_assert(RECV_INCOMPLETE == proto_recv(s->server_proto, s->output_buffer,
+ s->dummy_buffer));
tt_assert(server_state->state == ST_WAIT_FOR_PADDING);
@@ -364,10 +305,11 @@ test_obfs2_split_handshake(void *data)
stream_crypt(client_state->send_padding_crypto, msgclient_2, plength1_msg2);
/* Client sends handshake part 2 */
- evbuffer_add(output_buffer, msgclient_2, plength1_msg2);
+ evbuffer_add(s->output_buffer, msgclient_2, plength1_msg2);
/* Server receives handshake part 2 */
- tt_assert(RECV_GOOD == proto_recv(server_proto, output_buffer, dummy_buffer));
+ tt_assert(RECV_GOOD == proto_recv(s->server_proto, s->output_buffer,
+ s->dummy_buffer));
tt_assert(server_state->state == ST_OPEN);
@@ -394,11 +336,11 @@ test_obfs2_split_handshake(void *data)
msgserver_1+OBFUSCATE_SEED_LENGTH, 8);
/* Server sends handshake part 1 */
- evbuffer_add(output_buffer, msgserver_1, OBFUSCATE_SEED_LENGTH+8);
+ evbuffer_add(s->output_buffer, msgserver_1, OBFUSCATE_SEED_LENGTH+8);
/* Client receives handshake part 1 */
- tt_assert(RECV_INCOMPLETE == proto_recv(client_proto,
- output_buffer, dummy_buffer));
+ tt_assert(RECV_INCOMPLETE == proto_recv(s->client_proto, s->output_buffer,
+ s->dummy_buffer));
tt_assert(client_state->state == ST_WAIT_FOR_PADDING);
@@ -407,10 +349,11 @@ test_obfs2_split_handshake(void *data)
stream_crypt(server_state->send_padding_crypto, msgserver_2, plength2);
/* Server sends handshake part 2 */
- evbuffer_add(output_buffer, msgserver_2, plength2);
+ evbuffer_add(s->output_buffer, msgserver_2, plength2);
/* Client receives handshake part 2 */
- tt_assert(RECV_GOOD == proto_recv(client_proto, output_buffer, dummy_buffer));
+ tt_assert(RECV_GOOD == proto_recv(s->client_proto, s->output_buffer,
+ s->dummy_buffer));
tt_assert(client_state->state == ST_OPEN);
@@ -425,21 +368,7 @@ test_obfs2_split_handshake(void *data)
server_state->send_crypto,
sizeof(crypt_t)));
- end:
- if (client_state)
- proto_destroy(client_proto);
- if (server_state)
- proto_destroy(server_proto);
-
- if (proto_params_client)
- proto_params_free(proto_params_client);
- if (proto_params_server)
- proto_params_free(proto_params_server);
-
- if (output_buffer)
- evbuffer_free(output_buffer);
- if (dummy_buffer)
- evbuffer_free(dummy_buffer);
+ end:;
}
/*
@@ -447,40 +376,11 @@ test_obfs2_split_handshake(void *data)
Wrong magic value.
*/
static void
-test_obfs2_wrong_handshake_magic(void *data)
+test_obfs2_wrong_handshake_magic(void *state)
{
- obfs2_protocol_t *client_state = NULL;
- obfs2_protocol_t *server_state = NULL;
-
- struct evbuffer *output_buffer = NULL;
- struct evbuffer *dummy_buffer = NULL;
- output_buffer = evbuffer_new();
- dummy_buffer = evbuffer_new();
-
- 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);
-
- 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);
-
- client_state = downcast(client_proto);
- server_state = downcast(server_proto);
+ struct test_obfs2_state *s = (struct test_obfs2_state *)state;
+ obfs2_protocol_t *client_state = downcast(s->client_proto);
+ obfs2_protocol_t *server_state = downcast(s->server_proto);
uint32_t wrong_magic = 0xD15EA5E;
@@ -501,67 +401,25 @@ test_obfs2_wrong_handshake_magic(void *data)
stream_crypt(client_state->send_padding_crypto,
msg+OBFUSCATE_SEED_LENGTH, 8+plength);
- evbuffer_add(output_buffer, msg, OBFUSCATE_SEED_LENGTH+8+plength);
+ evbuffer_add(s->output_buffer, msg, OBFUSCATE_SEED_LENGTH+8+plength);
- tt_assert(RECV_BAD == proto_recv(server_proto, output_buffer, dummy_buffer));
+ tt_assert(RECV_BAD == proto_recv(s->server_proto, s->output_buffer,
+ s->dummy_buffer));
tt_assert(server_state->state == ST_WAIT_FOR_KEY);
- end:
- if (client_state)
- proto_destroy(client_proto);
- if (server_state)
- proto_destroy(server_proto);
-
- if (proto_params_client)
- proto_params_free(proto_params_client);
- if (proto_params_server)
- proto_params_free(proto_params_server);
-
- if (output_buffer)
- evbuffer_free(output_buffer);
- if (dummy_buffer)
- evbuffer_free(dummy_buffer);
+ end:;
}
/* Erroneous handshake test:
plength field larger than OBFUSCATE_MAX_PADDING
*/
static void
-test_obfs2_wrong_handshake_plength(void *data)
+test_obfs2_wrong_handshake_plength(void *state)
{
- obfs2_protocol_t *client_state = NULL;
- obfs2_protocol_t *server_state = NULL;
-
- struct evbuffer *output_buffer = NULL;
- struct evbuffer *dummy_buffer = NULL;
- output_buffer = evbuffer_new();
- dummy_buffer = evbuffer_new();
-
- 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);
-
- 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);
-
- client_state = downcast(client_proto);
- server_state = downcast(server_proto);
+ struct test_obfs2_state *s = (struct test_obfs2_state *)state;
+ obfs2_protocol_t *client_state = downcast(s->client_proto);
+ obfs2_protocol_t *server_state = downcast(s->server_proto);
uchar msg[OBFUSCATE_MAX_PADDING + OBFUSCATE_SEED_LENGTH + 8 + 1];
uint32_t magic = htonl(OBFUSCATE_MAGIC_VALUE);
@@ -580,40 +438,29 @@ test_obfs2_wrong_handshake_plength(void *data)
stream_crypt(client_state->send_padding_crypto,
msg+OBFUSCATE_SEED_LENGTH, 8+plength);
- evbuffer_add(output_buffer, msg, OBFUSCATE_SEED_LENGTH+8+plength);
+ evbuffer_add(s->output_buffer, msg, OBFUSCATE_SEED_LENGTH+8+plength);
- tt_assert(RECV_BAD == proto_recv(server_proto, output_buffer, dummy_buffer));
+ tt_assert(RECV_BAD == proto_recv(s->server_proto, s->output_buffer,
+ s->dummy_buffer));
tt_assert(server_state->state == ST_WAIT_FOR_KEY);
- end:
- if (client_proto)
- proto_destroy(client_proto);
- if (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);
-
- if (output_buffer)
- evbuffer_free(output_buffer);
- if (dummy_buffer)
- evbuffer_free(dummy_buffer);
+ end:;
}
#define T(name) \
{ #name, test_obfs2_##name, 0, NULL, NULL }
+#define TF(name) \
+ { #name, test_obfs2_##name, 0, &obfs2_fixture, NULL }
+
struct testcase_t obfs2_tests[] = {
T(option_parsing),
- T(setup),
- T(handshake),
- T(transfer),
- T(split_handshake),
- T(wrong_handshake_magic),
- T(wrong_handshake_plength),
+ TF(handshake),
+ TF(transfer),
+ TF(split_handshake),
+ TF(wrong_handshake_magic),
+ TF(wrong_handshake_plength),
END_OF_TESTCASES
};
1
0
commit 9f11da4a801cb725e3831ee24a5cb4e6a5e8ad8f
Author: Zack Weinberg <zackw(a)panix.com>
Date: Wed Jul 13 17:17:04 2011 -0700
Add -Wwrite-strings to warning set
---
Makefile.am | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index 1c2d89b..521ba24 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,6 +1,7 @@
ACLOCAL_AMFLAGS = -I m4
-AM_CFLAGS = -DDEBUG -Wall -Werror @libevent_CFLAGS@ @libcrypto_CFLAGS@
+WARNINGS = -Wall -Wwrite-strings -Werror
+AM_CFLAGS = $(WARNINGS) @libevent_CFLAGS@ @libcrypto_CFLAGS@
LDADD = libobfsproxy.a @libevent_LIBS@ @libcrypto_LIBS@ @ws32_LIBS@
bin_PROGRAMS = obfsproxy
1
0
[obfsproxy/master] Introduce allocate-memory-or-crash helpers and use them throughout the code base.
by nickm@torproject.org 09 Sep '11
by nickm@torproject.org 09 Sep '11
09 Sep '11
commit 6ba1db07b516763ef62df933fb46d88470d6a805
Author: Zack Weinberg <zackw(a)panix.com>
Date: Mon Jul 18 12:23:20 2011 -0700
Introduce allocate-memory-or-crash helpers and use them throughout the code base.
---
src/crypt.c | 26 ++++++---------
src/crypt.h | 11 +++---
src/main.c | 34 ++++----------------
src/network.c | 25 ++++++---------
src/protocols/dummy.c | 6 +--
src/protocols/obfs2.c | 34 +++++---------------
src/socks.c | 28 ++++++----------
src/socks.h | 2 +-
src/test/unittest_obfs2.c | 3 +-
src/test/unittest_socks.c | 5 ---
src/util.c | 76 +++++++++++++++++++++++++++++++++++++++++---
src/util.h | 13 ++++++++
12 files changed, 138 insertions(+), 125 deletions(-)
diff --git a/src/crypt.c b/src/crypt.c
index 6be9726..8d1d607 100644
--- a/src/crypt.c
+++ b/src/crypt.c
@@ -4,9 +4,11 @@
#define CRYPT_PRIVATE
#include "crypt.h"
+#include "util.h"
#include <assert.h>
#include <fcntl.h>
+#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
@@ -74,14 +76,12 @@ struct digest_t {
};
/**
- Returns a new SHA256 digest container, or NULL on failure.
+ Returns a new SHA256 digest container.
*/
digest_t *
digest_new(void)
{
- digest_t *d = malloc(sizeof(digest_t));
- if (!d)
- return NULL;
+ digest_t *d = xmalloc(sizeof(digest_t));
SHA256_Init(&d->ctx);
return d;
}
@@ -89,7 +89,7 @@ digest_new(void)
/**
Updates the contents of the SHA256 container 'd' with the first
'len' bytes of 'buf'.
-*/
+*/
void
digest_update(digest_t *d, const uchar *buf, size_t len)
{
@@ -118,9 +118,7 @@ struct digest_t {
digest_t *
digest_new(void)
{
- digest_t *d = malloc(sizeof(digest_t));
- if (!d)
- return NULL;
+ digest_t *d = xmalloc(sizeof(digest_t));
sha256_init(&d->ctx);
return d;
}
@@ -156,19 +154,15 @@ digest_free(digest_t *d)
/**
Initializes the AES cipher with 'key'.
-*/
+*/
crypt_t *
crypt_new(const uchar *key, size_t keylen)
{
crypt_t *k;
- if (keylen < AES_BLOCK_SIZE)
- return NULL;
-
- k = calloc(1, sizeof(crypt_t));
- if (k == NULL)
- return NULL;
- AES_set_encrypt_key(key, 128, &k->key);
+ assert(keylen == AES_BLOCK_SIZE);
+ k = xzalloc(sizeof(crypt_t));
+ AES_set_encrypt_key(key, AES_BLOCK_SIZE * CHAR_BIT, &k->key);
return k;
}
diff --git a/src/crypt.h b/src/crypt.h
index d87b1de..3f1e4df 100644
--- a/src/crypt.h
+++ b/src/crypt.h
@@ -21,7 +21,7 @@ int initialize_crypto(void);
/** Clean up global crypto state */
void cleanup_crypto(void);
-/** Return a newly allocated digest state, or NULL on failure. */
+/** Return a newly allocated digest state; cannot fail. */
digest_t *digest_new(void);
/** Add n bytes from b to the digest state. */
void digest_update(digest_t *, const uchar *b, size_t n);
@@ -31,10 +31,11 @@ size_t digest_getdigest(digest_t *, uchar *b, size_t n);
/** Clear and free a digest state */
void digest_free(digest_t *);
-/** Return a new stream cipher state taking key and IV from the data provided.
- * The data length must be exactly 32 */
-crypt_t *crypt_new(const uchar *, size_t);
-void crypt_set_iv(crypt_t *key, const uchar *iv, size_t ivlen);
+/** Return a new stream cipher state using 'key' as the symmetric key.
+ * The data length must be exactly 16 bytes. Cannot fail. */
+crypt_t *crypt_new(const uchar *key, size_t);
+/* Set the IV of a stream-cipher state. Cannot fail. */
+void crypt_set_iv(crypt_t *, const uchar *iv, size_t ivlen);
/** Encrypt n bytes of data in the buffer b, in place. */
void stream_crypt(crypt_t *, uchar *b, size_t n);
diff --git a/src/main.c b/src/main.c
index f41d502..21c4feb 100644
--- a/src/main.c
+++ b/src/main.c
@@ -181,13 +181,6 @@ handle_obfsproxy_args(const char **argv)
return i;
}
-static void
-die_oom(void)
-{
- log_warn("Memory allocation failed: %s",strerror(errno));
- exit(1);
-}
-
int
main(int argc, const char **argv)
{
@@ -214,7 +207,6 @@ main(int argc, const char **argv)
int start;
int end;
int n_options;
- void *realloc_temp;
int i;
/* The number of protocols. */
@@ -222,7 +214,7 @@ main(int argc, const char **argv)
/* An array which holds the position in argv of the command line
options for each protocol. */
unsigned int *protocols=NULL;
- /* keeps track of allocated space for the protocols array */
+ /* keeps track of allocated space for the protocols array */
unsigned int n_alloc;
if (argc < 2) {
@@ -235,9 +227,7 @@ main(int argc, const char **argv)
/** Handle optional obfsproxy arguments. */
start_of_protocols = handle_obfsproxy_args(&argv[1]);
- protocols = calloc(sizeof(int), (n_protocols+1));
- if (!protocols)
- die_oom();
+ protocols = xzalloc((n_protocols + 1) * sizeof(int));
n_alloc = n_protocols+1;
/* Populate protocols and calculate n_protocols. */
@@ -249,10 +239,7 @@ main(int argc, const char **argv)
/* Do we need to expand the protocols array? */
if (n_alloc <= n_protocols) {
n_alloc *= 2;
- realloc_temp = realloc(protocols, sizeof(int)*(n_alloc));
- if (!realloc_temp)
- die_oom();
- protocols = realloc_temp;
+ protocols = xrealloc(protocols, sizeof(int)*(n_alloc));
}
}
}
@@ -271,13 +258,9 @@ main(int argc, const char **argv)
that point to arrays carrying the options of the protocols.
Finally, we allocate enough space on the n_options_array so that
we can put the number of options there.
- */
- protocol_options = calloc(sizeof(char**), n_protocols);
- if (!protocol_options)
- die_oom();
- n_options_array = calloc(sizeof(int), n_protocols);
- if (!n_options_array)
- die_oom();
+ */
+ protocol_options = xzalloc(n_protocols * sizeof(char**));
+ n_options_array = xzalloc(n_protocols * sizeof(int));
/* Iterate through protocols. */
for (i=0;i<n_protocols;i++) {
@@ -304,10 +287,7 @@ main(int argc, const char **argv)
/* Allocate space for the array carrying the options of this
protocol. */
- protocol_options[actual_protocols-1] =
- calloc(sizeof(char*), (n_options));
- if (!protocol_options[actual_protocols-1])
- die_oom();
+ protocol_options[actual_protocols-1] = xzalloc(n_options * sizeof(char*));
/* Write the number of options to the correct place in n_options_array[]. */
n_options_array[actual_protocols-1] = n_options;
diff --git a/src/network.c b/src/network.c
index 365c61a..fb770c9 100644
--- a/src/network.c
+++ b/src/network.c
@@ -99,10 +99,15 @@ close_all_connections(void)
assert(!n_connections);
}
/**
- This function spawns a listener according to the 'proto_params'.
+ This function spawns a listener configured according to the
+ provided 'protocol_params_t' object'. Returns the listener on
+ success, NULL on fail.
- Returns the listener on success, NULL on fail.
+ If it succeeds, the new listener object takes ownership of the
+ 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)
@@ -110,14 +115,8 @@ listener_new(struct event_base *base,
const unsigned flags =
LEV_OPT_CLOSE_ON_FREE|LEV_OPT_CLOSE_ON_EXEC|LEV_OPT_REUSEABLE;
- listener_t *lsn = calloc(1, sizeof(listener_t));
- if (!lsn) {
- if (proto_params)
- free(proto_params);
- return NULL;
- }
+ listener_t *lsn = xzalloc(sizeof(listener_t));
- /** If we don't have a connection dll, create one now. */
lsn->proto_params = proto_params;
lsn->listener = evconnlistener_new_bind(base, simple_listener_cb, lsn,
@@ -132,6 +131,7 @@ listener_new(struct event_base *base,
return NULL;
}
+ /** If we don't have a connection dll, create one now. */
dll_append(&listener_list, &lsn->dll_node);
return lsn;
@@ -189,15 +189,12 @@ simple_listener_cb(struct evconnlistener *evcl,
{
listener_t *lsn = arg;
struct event_base *base;
- conn_t *conn = calloc(1, sizeof(conn_t));
+ 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. */
- if (!conn)
- goto err;
-
log_debug("Got a connection attempt.");
conn->mode = lsn->proto_params->mode;
@@ -211,8 +208,6 @@ simple_listener_cb(struct evconnlistener *evcl,
if (conn->mode == LSN_SOCKS_CLIENT) {
/* Construct SOCKS state. */
conn->socks_state = socks_state_new();
- if (!conn->socks_state)
- goto err;
}
/* New bufferevent to wrap socket we received. */
diff --git a/src/protocols/dummy.c b/src/protocols/dummy.c
index f121725..d82818d 100644
--- a/src/protocols/dummy.c
+++ b/src/protocols/dummy.c
@@ -28,9 +28,7 @@ static struct protocol_params_t *
dummy_init(int n_options, const char *const *options)
{
struct protocol_params_t *params
- = calloc(1, sizeof(struct protocol_params_t));
- if (!params)
- return NULL;
+ = xzalloc(sizeof(struct protocol_params_t));
if (parse_and_set_options(n_options, options, params) < 0) {
free(params);
@@ -101,7 +99,7 @@ static struct protocol_t *
dummy_create(struct protocol_params_t *params)
{
/* Dummy needs no per-connection protocol-specific state. */
- struct protocol_t *proto = calloc(1, sizeof(struct protocol_t));
+ struct protocol_t *proto = xzalloc(sizeof(struct protocol_t));
proto->vtable = &dummy_vtable;
return proto;
}
diff --git a/src/protocols/obfs2.c b/src/protocols/obfs2.c
index 41a2614..c42d1c4 100644
--- a/src/protocols/obfs2.c
+++ b/src/protocols/obfs2.c
@@ -36,9 +36,7 @@ static struct protocol_params_t *
obfs2_init(int n_options, const char *const *options)
{
struct protocol_params_t *params
- = calloc(1, sizeof(struct protocol_params_t));
- if (!params)
- return NULL;
+ = xzalloc(sizeof(struct protocol_params_t));
if (parse_and_set_options(n_options, options, params) < 0) {
usage();
@@ -85,8 +83,9 @@ parse_and_set_options(int n_options, const char *const *options,
if (got_ss)
return -1;
/* this is freed in proto_params_free() */
- params->shared_secret = strdup(*options+16);
params->shared_secret_len = strlen(*options+16);
+ params->shared_secret = xmemdup(*options+16,
+ params->shared_secret_len + 1);
got_ss=1;
} else {
log_warn("obfs2: Unknown argument.");
@@ -163,7 +162,7 @@ seed_nonzero(const uchar *seed)
/**
Derive and return key of type 'keytype' from the seeds currently set in
- 'state'. Returns NULL on failure.
+ 'state'.
*/
static crypt_t *
derive_key(void *s, const char *keytype)
@@ -202,7 +201,7 @@ derive_key(void *s, const char *keytype)
/**
Derive and return padding key of type 'keytype' from the seeds
- currently set in state 's'. Returns NULL on failure.
+ currently set in state 's'.
*/
static crypt_t *
derive_padding_key(void *s, const uchar *seed,
@@ -250,12 +249,10 @@ derive_padding_key(void *s, const uchar *seed,
static struct protocol_t *
obfs2_create(protocol_params_t *params)
{
- obfs2_protocol_t *proto = calloc(1, sizeof(obfs2_protocol_t));
+ obfs2_protocol_t *proto = xzalloc(sizeof(obfs2_protocol_t));
uchar *seed;
const char *send_pad_type;
- if (!proto)
- return NULL;
proto->state = ST_WAIT_FOR_KEY;
proto->we_are_initiator = params->is_initiator;
if (proto->we_are_initiator) {
@@ -275,10 +272,6 @@ obfs2_create(protocol_params_t *params)
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);
@@ -286,11 +279,6 @@ obfs2_create(protocol_params_t *params)
/* Derive the key for what we're sending */
proto->send_padding_crypto = derive_padding_key(proto, seed, send_pad_type);
- if (proto->send_padding_crypto == NULL) {
- free(proto);
- return NULL;
- }
-
proto->super.vtable = &obfs2_vtable;
return &proto->super;
}
@@ -420,7 +408,7 @@ obfs2_send(struct protocol_t *s,
Helper: called after reciving our partner's setup message. Initializes all
keys. Returns 0 on success, -1 on failure.
*/
-static int
+static void
init_crypto(void *s)
{
obfs2_protocol_t *state = s;
@@ -447,11 +435,6 @@ init_crypto(void *s)
state->recv_crypto = derive_key(state, recv_keytype);
state->recv_padding_crypto =
derive_padding_key(state, recv_seed, recv_pad_keytype);
-
- if (state->send_crypto && state->recv_crypto && state->recv_padding_crypto)
- return 0;
- else
- return -1;
}
/* Called when we receive data in an evbuffer 'source': deobfuscates that data
@@ -491,8 +474,7 @@ obfs2_recv(struct protocol_t *s, struct evbuffer *source,
memcpy(other_seed, buf, OBFUSCATE_SEED_LENGTH);
/* Now we can set up all the keys from the seed */
- if (init_crypto(state) < 0)
- return RECV_BAD;
+ init_crypto(state);
/* Decrypt the next 8 bytes */
stream_crypt(state->recv_padding_crypto, buf+OBFUSCATE_SEED_LENGTH, 8);
diff --git a/src/socks.c b/src/socks.c
index e89812f..b67455f 100644
--- a/src/socks.c
+++ b/src/socks.c
@@ -43,24 +43,19 @@
typedef unsigned char uchar;
/**
- Creates a new SOCKS state.
-
- Returns a 'socks_state_t' on success, NULL on fail.
+ Creates a new 'socks_state_t' object.
*/
socks_state_t *
socks_state_new(void)
{
- socks_state_t *state = calloc(1, sizeof(socks_state_t));
- if (!state)
- return NULL;
+ socks_state_t *state = xzalloc(sizeof(socks_state_t));
state->state = ST_WAITING;
-
return state;
}
/**
Deallocates memory of socks_state_t 's'.
-*/
+*/
void
socks_state_free(socks_state_t *s)
{
@@ -318,8 +313,8 @@ socks5_handle_negotiation(struct evbuffer *source,
struct evbuffer *dest, socks_state_t *state)
{
unsigned int found_noauth, i;
-
uchar nmethods;
+ uchar methods[0xFF];
evbuffer_copyout(source, &nmethods, 1);
@@ -329,25 +324,22 @@ socks5_handle_negotiation(struct evbuffer *source,
evbuffer_drain(source, 1);
- uchar *p;
- /* XXX user controlled malloc(). range should be: 0x00-0xff */
- p = malloc(nmethods);
- if (!p) {
- log_warn("malloc failed!");
+ /* this should be impossible, but we check it anyway for great defensiveness */
+ if (nmethods > 0xFF) {
+ log_warn("too many methods!");
return SOCKS_BROKEN;
}
- if (evbuffer_remove(source, p, nmethods) < 0)
+
+ if (evbuffer_remove(source, methods, nmethods) < 0)
assert(0);
for (found_noauth=0, i=0; i<nmethods ; i++) {
- if (p[i] == SOCKS5_METHOD_NOAUTH) {
+ if (methods[i] == SOCKS5_METHOD_NOAUTH) {
found_noauth = 1;
break;
}
}
- free(p);
-
return socks5_do_negotiation(dest,found_noauth);
}
diff --git a/src/socks.h b/src/socks.h
index e2c20b5..db10cb5 100644
--- a/src/socks.h
+++ b/src/socks.h
@@ -30,7 +30,7 @@ enum socks_ret {
enum socks_ret handle_socks(struct evbuffer *source,
struct evbuffer *dest,
socks_state_t *socks_state);
-socks_state_t *socks_state_new(void);
+socks_state_t *socks_state_new(void); /* cannot fail */
void socks_state_free(socks_state_t *s);
enum socks_status_t socks_state_get_status(const socks_state_t *state);
diff --git a/src/test/unittest_obfs2.c b/src/test/unittest_obfs2.c
index 01ce501..961bfd2 100644
--- a/src/test/unittest_obfs2.c
+++ b/src/test/unittest_obfs2.c
@@ -125,8 +125,7 @@ static const char *const options_server[] =
static void *
setup_obfs2_state(const struct testcase_t *unused)
{
- struct test_obfs2_state *s = calloc(1, sizeof(struct test_obfs2_state));
- tt_assert(s);
+ struct test_obfs2_state *s = xzalloc(sizeof(struct test_obfs2_state));
s->proto_params_client =
proto_params_init(ALEN(options_client), options_client);
diff --git a/src/test/unittest_socks.c b/src/test/unittest_socks.c
index 001c266..4d95666 100644
--- a/src/test/unittest_socks.c
+++ b/src/test/unittest_socks.c
@@ -31,7 +31,6 @@ test_socks_socks5_send_negotiation(void *data)
socks_state_t *state;
state = socks_state_new();
- tt_assert(state);
/* First test:
Only one method: NOAUTH.
@@ -143,7 +142,6 @@ test_socks_socks5_request(void *data)
socks_state_t *state;
state = socks_state_new();
- tt_assert(state);
const uint32_t addr_ipv4 = htonl(0x7f000001); /* 127.0.0.1 */
const uint8_t addr_ipv6[16] = {0,13,0,1,0,5,0,14,0,10,0,5,0,14,0,0}; /* d:1:5:e:a:5:e:0 */
@@ -308,7 +306,6 @@ test_socks_socks5_request_reply(void *data)
socks_state_t *state;
state = socks_state_new();
- tt_assert(state);
state->parsereq.af = AF_INET;
strcpy(state->parsereq.addr, "127.0.0.1");
@@ -415,7 +412,6 @@ test_socks_socks4_request(void *data)
socks_state_t *state;
state = socks_state_new();
- tt_assert(state);
/* First test:
Correct SOCKS4 req packet with nothing in the optional field. */
@@ -552,7 +548,6 @@ test_socks_socks4_request_reply(void *data)
socks_state_t *state;
state = socks_state_new();
- tt_assert(state);
state->parsereq.af = AF_INET;
strcpy(state->parsereq.addr, "127.0.0.1");
diff --git a/src/util.c b/src/util.c
index cab4bf1..6a0e4a0 100644
--- a/src/util.c
+++ b/src/util.c
@@ -5,6 +5,7 @@
#include "util.h"
#include <assert.h>
+#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <stdio.h>
@@ -22,6 +23,73 @@
/** Any size_t larger than this amount is likely to be an underflow. */
#define SIZE_T_CEILING (SIZE_MAX/2 - 16)
+/**************************** Memory Allocation ******************************/
+
+static void __attribute__((noreturn))
+die_oom(void)
+{
+ log_warn("Memory allocation failed: %s",strerror(errno));
+ exit(1);
+}
+
+void *
+xmalloc(size_t size)
+{
+ void *result;
+
+ assert(size < SIZE_T_CEILING);
+
+ /* Some malloc() implementations return NULL when the input argument
+ is zero. We don't bother detecting whether the implementation we're
+ being compiled for does that, because it should hardly ever come up,
+ and avoiding it unconditionally does no harm. */
+ if (size == 0)
+ size = 1;
+
+ result = malloc(size);
+ if (result == NULL)
+ die_oom();
+
+ return result;
+}
+
+void *
+xrealloc(void *ptr, size_t size)
+{
+ void *result;
+ assert (size < SIZE_T_CEILING);
+ if (size == 0)
+ size = 1;
+
+ result = realloc(ptr, size);
+ if (result == NULL)
+ die_oom();
+
+ return result;
+}
+
+void *
+xzalloc(size_t size)
+{
+ void *result = xmalloc(size);
+ memset(result, 0, size);
+ return result;
+}
+
+void *
+xmemdup(const void *ptr, size_t size)
+{
+ void *copy = xmalloc(size);
+ memcpy(copy, ptr, size);
+ return copy;
+}
+
+char *
+xstrdup(const char *s)
+{
+ return xmemdup(s, strlen(s) + 1);
+}
+
/************************ Obfsproxy Network Routines *************************/
/**
@@ -45,10 +113,8 @@ resolve_address_port(const char *address,
struct evutil_addrinfo *ai = NULL;
struct evutil_addrinfo ai_hints;
int result = -1, ai_res;
- char *a = strdup(address), *cp;
+ char *a = xstrdup(address), *cp;
const char *portstr;
- if (!a)
- return -1;
if ((cp = strchr(a, ':'))) {
portstr = cp+1;
@@ -78,10 +144,8 @@ resolve_address_port(const char *address,
log_warn("No result for address %s", address);
goto done;
}
- struct sockaddr *addr = malloc(ai->ai_addrlen);
- memcpy(addr, ai->ai_addr, ai->ai_addrlen);
- *addr_out = addr;
*addrlen_out = ai->ai_addrlen;
+ *addr_out = xmemdup(ai->ai_addr, ai->ai_addrlen);
result = 0;
done:
diff --git a/src/util.h b/src/util.h
index b526dbf..d909b53 100644
--- a/src/util.h
+++ b/src/util.h
@@ -16,6 +16,19 @@ struct sockaddr;
struct event_base;
struct evdns_base;
+/***** Memory allocation. *****/
+
+/* Because this isn't Tor and functions named "tor_whatever" would be
+ confusing, I am instead following the GNU convention of naming
+ allocate-memory-or-crash functions "xwhatever". Also, at this time
+ I do not see a need for a free() wrapper. */
+
+void *xmalloc(size_t size) __attribute__((malloc)); /* does not clear memory */
+void *xzalloc(size_t size) __attribute__((malloc)); /* clears memory */
+void *xrealloc(void *ptr, size_t size);
+void *xmemdup(const void *ptr, size_t size) __attribute__((malloc));
+char *xstrdup(const char *s) __attribute__((malloc));
+
/***** Network functions stuff. *****/
int resolve_address_port(const char *address,
1
0