[tor-commits] [obfsproxy/master] Merge remote-tracking branch 'zwol/port-fixes'

nickm at torproject.org nickm at torproject.org
Thu Jul 14 16:28:33 UTC 2011


commit c37354b1e0adcb6d16929613e3bd4a509d487d2d
Merge: 3fb0f0e 7f03b8e
Author: Nick Mathewson <nickm at torproject.org>
Date:   Thu Jul 14 12:28:12 2011 -0400

    Merge remote-tracking branch 'zwol/port-fixes'
    
    Conflicts:
    	src/network.c
    	src/network.h
    	src/protocol.c
    	src/protocols/dummy.c
    	src/protocols/obfs2.c
    	src/socks.c
    	src/socks.h
    	src/util.c

 Makefile.am                 |   34 +++---
 configure.ac                |   49 ++++-----
 m4/winsock.m4               |   56 ++++++++++
 src/crypt.c                 |  220 ++++++++++++++++++++++++++++++++++++++
 src/crypt.h                 |   64 +++++++++++
 src/main.c                  |    7 +-
 src/network.c               |   27 +++--
 src/network.h               |   19 ++--
 src/protocol.c              |   25 +++--
 src/protocol.h              |   35 +++---
 src/protocols/dummy.c       |   54 ++++------
 src/protocols/dummy.h       |    1 -
 src/protocols/obfs2.c       |   84 ++++++---------
 src/protocols/obfs2.h       |   11 +-
 src/protocols/obfs2_crypt.c |  245 -------------------------------------------
 src/protocols/obfs2_crypt.h |   61 -----------
 src/sha256.c                |   89 ++++------------
 src/sha256.h                |   18 +++
 src/socks.c                 |  102 ++++++++----------
 src/socks.h                 |   24 ++---
 src/test/tinytest.c         |   10 +-
 src/test/unittest.c         |    3 +-
 src/test/unittest_crypt.c   |   19 +---
 src/test/unittest_obfs2.c   |  133 ++++++++++++-----------
 src/test/unittest_socks.c   |   16 ++--
 src/util.c                  |  154 ++++++++++------------------
 src/util.h                  |   83 +++++---------
 27 files changed, 772 insertions(+), 871 deletions(-)

diff --cc src/crypt.c
index 0000000,43f6dfb..6be9726
mode 000000,100644..100644
--- a/src/crypt.c
+++ b/src/crypt.c
@@@ -1,0 -1,178 +1,220 @@@
+ /* Copyright 2011 Nick Mathewson, George Kadianakis
+    See LICENSE for other credits and copying information
+ */
+ 
+ #define CRYPT_PRIVATE
+ #include "crypt.h"
+ 
+ #include <assert.h>
+ #include <fcntl.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include <unistd.h>
+ 
+ #include <openssl/opensslv.h>
+ #include <openssl/err.h>
+ #include <openssl/rand.h>
+ 
+ #if OPENSSL_VERSION_NUMBER >= 0x0090800f
+ #define USE_OPENSSL_RANDPOLL 1
+ #define USE_OPENSSL_SHA256 1
+ #include <openssl/sha.h>
+ #else
+ #include "sha256.h"
+ #endif
+ 
++/**
++   Initializes the obfs2 crypto subsystem.
++*/
+ int
+ initialize_crypto(void)
+ {
+   ERR_load_crypto_strings();
+ 
+ #ifdef USE_OPENSSL_RANDPOLL
+   return RAND_poll() == 1 ? 0 : -1;
+ #else
+   /* XXX Or maybe fall back to the arc4random implementation in libevent2? */
+   {
+     char buf[32];
+     int fd, n;
+     fd = open("/dev/urandom", O_RDONLY);
+     if (fd == -1) {
+       perror("open");
+       return -1;
+     }
+     n = read(fd, buf, sizeof(buf));
+     if (n != sizeof(buf)) {
+       close(fd);
+       return -1;
+     }
+     RAND_seed(buf, sizeof(buf));
+     close(fd);
+     return 0;
+   }
+ #endif
+ }
+ 
++/**
++   Cleans up the obfs2 crypto subsystem.
++*/
+ void
+ cleanup_crypto(void)
+ {
+   ERR_free_strings();
+ }
+ 
+ /* =====
+    Digests
+    ===== */
+ 
+ #ifdef USE_OPENSSL_SHA256
+ struct digest_t {
+   SHA256_CTX ctx;
+ };
++
++/**
++   Returns a new SHA256 digest container, or NULL on failure.
++*/
+ digest_t *
+ digest_new(void)
+ {
+   digest_t *d = malloc(sizeof(digest_t));
++  if (!d)
++    return NULL;
+   SHA256_Init(&d->ctx);
+   return d;
+ }
++
++/**
++   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)
+ {
+   SHA256_Update(&d->ctx, buf, len);
+ }
++
++/**
++   Returns the digest stored in 'd' into 'buf' of length 'len'.
++*/
+ size_t
+ digest_getdigest(digest_t *d, uchar *buf, size_t len)
+ {
+   uchar tmp[SHA256_LENGTH];
+   int n = 32;
+   SHA256_Final(tmp, &d->ctx);
+   if (len < 32)
+     n = len;
+   memcpy(buf, tmp, n);
+   memset(tmp, 0, sizeof(tmp));
+   return n;
+ }
+ #else
+ struct digest_t {
+   sha256_state ctx;
+ };
+ digest_t *
+ digest_new(void)
+ {
+   digest_t *d = malloc(sizeof(digest_t));
++  if (!d)
++    return NULL;
+   sha256_init(&d->ctx);
+   return d;
+ }
+ void
+ digest_update(digest_t *d, const uchar *buf, size_t len)
+ {
+   sha256_process(&d->ctx, buf, len);
+ }
+ size_t
+ digest_getdigest(digest_t *d, uchar *buf, size_t len)
+ {
+   uchar tmp[SHA256_LENGTH];
+   int n = 32;
+   sha256_done(&d->ctx, tmp);
+   if (len < 32)
+     n = len;
+   memcpy(buf, tmp, n);
+   memset(tmp, 0, sizeof(tmp));
+   return n;
+ }
+ #endif
+ 
+ void
+ digest_free(digest_t *d)
+ {
+   memset(d, 0, sizeof(digest_t));
+   free(d);
+ }
+ 
+ /* =====
+    Stream crypto
+    ===== */
+ 
++/**
++   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);
+ 
+   return k;
+ }
++
++/**
++   Sets the IV of 'key' to 'iv'.
++*/
+ void
+ crypt_set_iv(crypt_t *key, const uchar *iv, size_t ivlen)
+ {
+   assert(ivlen == sizeof(key->ivec));
+   memcpy(key->ivec, iv, ivlen);
+ }
++
++/*
++  In-place encrypts 'buf' with 'key'.
++*/
+ void
+ stream_crypt(crypt_t *key, uchar *buf, size_t len)
+ {
+   AES_ctr128_encrypt(buf, buf, /* XXX make sure this is okay to do. */
+                      len,
+                      &key->key, key->ivec, key->ecount_buf,
+                      &key->pos);
+ }
++
++/**
++   Deallocates memory space of 'key'.
++*/
+ void
+ crypt_free(crypt_t *key)
+ {
+   memset(key, 0, sizeof(key));
+   free(key);
+ }
+ 
+ /* =====
+    PRNG
+    ===== */
+ 
++/**
++   Fills 'buf' with 'buflen' random bytes and returns 0 on success.
++   Returns -1 on failure.
++*/
+ int
+ random_bytes(uchar *buf, size_t buflen)
+ {
+   return RAND_bytes(buf, buflen) == 1 ? 0 : -1;
+ }
diff --cc src/main.c
index ee2a802,8788067..48d0d37
--- a/src/main.c
+++ b/src/main.c
@@@ -402,12 -358,11 +398,11 @@@ main(int argc, const char **argv
  
    log_info("Exiting.");
  
-   if (close_obfsproxy_logfile() < 0)
-     printf("Failed closing logfile!\n");
+   close_obfsproxy_logfile();
  
 +  free_all_listeners(); /* free all listeners in our listener dll */
 +
    /* We are exiting. Clean everything. */
 -  for (h=0;h<n_listeners;h++)
 -    listener_free(listeners[h]);
    free(protocol_options);
    free(n_options_array);
    free(protocols);
diff --cc src/network.c
index 6d1d211,081af6e..ea06bc2
--- a/src/network.c
+++ b/src/network.c
@@@ -4,13 -4,13 +4,14 @@@
  
  #define NETWORK_PRIVATE
  #include "network.h"
+ 
  #include "util.h"
++#include "main.h"
  #include "socks.h"
  #include "protocol.h"
- #include "socks.h"
- #include "main.h"
  
  #include <assert.h>
+ #include <errno.h>
  #include <stdlib.h>
  #include <string.h>
  
@@@ -18,14 -20,10 +21,14 @@@
  #include <event2/util.h>
  
  #ifdef _WIN32
- #include <WS2tcpip.h>
+ #include <ws2tcpip.h>  /* socklen_t */
  #endif
  
 +/** Doubly linked list holding all our listeners. */
 +static dll_t listener_list = DLL_INIT();
 +
  struct listener_t {
 +  dll_node_t dll_node;
    struct evconnlistener *listener;
    protocol_params_t *proto_params;
  };
@@@ -55,50 -43,10 +58,50 @@@ static void input_event_cb(struct buffe
  static void output_event_cb(struct bufferevent *bev, short what, void *arg);
  
  /**
 -   This function sets up the protocol defined by 'options' and
 -   attempts to bind a new listener for it.
 +   Puts obfsproxy's networking subsystem on "closing time" mode. This
 +   means that we stop accepting new connections and we shutdown when
 +   the last connection is closed.
 +
 +   If 'barbaric' is set, we forcefully close all open connections and
 +   finish shutdown.
 +   
 +   (Only called by signal handlers)
 +*/
 +void
 +start_shutdown(int barbaric)
 +{
 +  if (!shutting_down)
 +    shutting_down=1;
 +
 +  if (!n_connections) {
 +    finish_shutdown();
 +    return;
 +  }
 +
 +  if (barbaric) {
 +    if (n_connections)
 +      close_all_connections();
 +    return;
 +  }
 +}  
 +
 +/**
 +   Closes all open connections.
 +*/ 
 +static void
 +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_free(conn); /* removes it */
 +  }
 +  assert(!n_connections);
 +}
 +/**
 +   This function spawns a listener according to the 'proto_params'.
  
-    Returns the listener on success and NULL on fail.
+    Returns the listener on success, NULL on fail.
  */
  listener_t *
  listener_new(struct event_base *base,
diff --cc src/network.h
index dc6b583,7bc4811..ad54686
--- a/src/network.h
+++ b/src/network.h
@@@ -45,13 -33,13 +33,20 @@@ typedef struct listener_t listener_t
  listener_t *listener_new(struct event_base *base,
                           struct protocol_params_t *params);
  void listener_free(listener_t *listener);
 +void free_all_listeners(void);
 +
 +void start_shutdown(int barbaric);
  
  #ifdef NETWORK_PRIVATE
++
++#include "util.h"
++
+ struct bufferevent;
+ struct socks_state_t;
+ struct protocol_t;
+ 
  typedef struct conn_t {
 +  dll_node_t dll_node;
    struct socks_state_t *socks_state;
    struct protocol_t *proto; /* ASN Do we like this here? We probably don't.
                                 But it's so convenient!! So convenient! */
diff --cc src/protocol.c
index 0845c11,557a5cc..282db10
--- a/src/protocol.c
+++ b/src/protocol.c
@@@ -40,8 -38,9 +38,9 @@@ set_up_protocol(int n_options, char **o
  }
  
  /**
 -   This function creates a protocol object.
 -   It's called once per connection.
 -   It creates a new protocol_t structure and fills it's vtable etc.
 +   This function is called once per connection and creates a protocol
 +   object to be used during the session.
++
     Return a 'protocol_t' if successful, NULL otherwise.
  */
  struct protocol_t *
diff --cc src/protocols/dummy.c
index eaf921c,7a32b47..3b31e12
--- a/src/protocols/dummy.c
+++ b/src/protocols/dummy.c
@@@ -54,20 -49,15 +50,18 @@@ dummy_init(int n_options, char **option
    vtable->send = dummy_send;
    vtable->recv = dummy_recv;
  
 -  return 1;
 +  return 0;
  }
  
 +/**
 +   Helper: Parses 'options' and fills 'params'.
 +*/ 
  static int
- parse_and_set_options(int n_options, char **options, 
+ parse_and_set_options(int n_options, char **options,
                        struct protocol_params_t *params)
  {
-   struct sockaddr_storage ss_listen;
-   int sl_listen;
    const char* defport;
-   
+ 
    if (n_options != 3)
      return -1;
  
@@@ -91,18 -82,10 +86,13 @@@
      log_warn("addr");
      return -1;
    }
-   assert(sl_listen <= sizeof(struct sockaddr_storage));
-   struct sockaddr *sa_listen=NULL;
-   sa_listen = (struct sockaddr *)&ss_listen;
-   memcpy(&params->on_address, sa_listen, sl_listen);
-   params->on_address_len = sl_listen;
-   
-   return 0;
+ 
+   return 1;
  }
  
 +/**
 +   Prints dummy protocol usage information.
 +*/
  static void
  usage(void)
  {
@@@ -115,13 -98,8 +105,13 @@@
           "Example:\n"
           "\tobfsproxy dummy socks 127.0.0.1:5000\n");
  }
-     
+ 
 +/*
 +  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)
diff --cc src/protocols/obfs2.c
index f9beee5,c2169a1..27e9272
--- a/src/protocols/obfs2.c
+++ b/src/protocols/obfs2.c
@@@ -58,18 -55,13 +55,16 @@@ obfs2_init(int n_options, char **option
      return -1;
    }
  
 -  return 1;
 +  return 0;
  }
  
 +/**
 +   Helper: Parses 'options' and fills 'params'.
 +*/
  int
- parse_and_set_options(int n_options, char **options, 
+ parse_and_set_options(int n_options, char **options,
                        struct protocol_params_t *params)
  {
-   struct sockaddr_storage ss_listen;
-   int sl_listen;
    int got_dest=0;
    int got_ss=0;
    const char* defport;
@@@ -192,8 -174,8 +177,8 @@@ set_up_vtable(void
    vtable->handshake = obfs2_send_initial_message;
    vtable->send = obfs2_send;
    vtable->recv = obfs2_recv;
-   
+ 
 -  return 1;
 +  return 0;
  }
  
  /** Return true iff the OBFUSCATE_SEED_LENGTH-byte seed in 'seed' is nonzero */
diff --cc src/socks.c
index f175a8e,e6d72fd..e89812f
--- a/src/socks.c
+++ b/src/socks.c
@@@ -50,16 -40,8 +40,13 @@@
  */
  
  
- static enum socks_ret socks5_do_negotiation(struct evbuffer *dest,
-                                     unsigned int neg_was_success);
- 
  typedef unsigned char uchar;
  
 +/**
 +   Creates a new SOCKS state.
 +
 +   Returns a 'socks_state_t' on success, NULL on fail.
 +*/
  socks_state_t *
  socks_state_new(void)
  {
@@@ -123,17 -102,19 +110,16 @@@ socks_errno_to_reply(socks_state_t *sta
  #undef ERR
  
  /**
 -   Takes a command request from 'source', it evaluates it and if it's
 -   legit it parses it into 'parsereq'.
 -
 -   It returns '1' if everything went fine.
 -   It returns '0' if we need more data from the client.
 -   It returns '-1' if we didn't like something.
 -   It returns '-2' if the client asked for something else than CONNECT.
 -   If that's the case we should send a reply back to the client
 -   telling him that we don't support it.
 -
 -   Disclaimer: This is just a temporary documentation.
 -
 -   Client Request (Client -> Server)
 +   Takes a SOCKS5 command request from 'source', it evaluates it and
 +   if it's legit it parses it into 'parsereq'.
 +   
 +   It returns SOCKS_GOOD if everything went fine.
 +   It returns SOCKS_INCOMPLETE if we need more data from the client.
 +   It returns SOCKS_BROKEN if we didn't like something.
 +   It returns SOCKS_CMD_NOT_CONNECT if the client asked for something
 +   else other than CONNECT.  If that's the case we should send a reply
 +   back to the client telling him that we don't support it.
 +   
-    Client Request (Client -> Server)
  */
  enum socks_ret
  socks5_handle_request(struct evbuffer *source, struct parsereq *parsereq)
@@@ -292,8 -274,35 +280,33 @@@ socks5_send_reply(struct evbuffer *repl
  }
  
  /**
+    This function sends a method negotiation reply to 'dest'.
+    If 'neg_was_success' is true send a positive response,
+    otherwise send a negative one.
+    It returns -1 if no suitable negotiation methods were found,
+    or if there was an error during replying.
+ 
+    Method Negotiation Reply (Server -> Client):
+    | version | method selected |
+        1b           1b
+ */
+ static enum socks_ret
+ socks5_do_negotiation(struct evbuffer *dest, unsigned int neg_was_success)
+ {
+   uchar reply[2];
+   reply[0] = SOCKS5_VERSION;
+ 
+   reply[1] = neg_was_success ? SOCKS5_METHOD_NOAUTH : SOCKS5_METHOD_FAIL;
+ 
+   if (evbuffer_add(dest, reply, 2) == -1 || !neg_was_success)
+     return SOCKS_BROKEN;
+   else
+     return SOCKS_GOOD;
+ }
+ 
+ /**
     This function handles the initial SOCKS5 packet in 'source' sent by
 -   the client, which negotiates the version and method of SOCKS.  If
 +   the client which negotiates the version and method of SOCKS.  If
     the packet is actually valid, we reply to 'dest'.
  
     Method Negotiation Packet (Client -> Server):
@@@ -338,39 -347,7 +351,16 @@@ socks5_handle_negotiation(struct evbuff
    return socks5_do_negotiation(dest,found_noauth);
  }
  
 -/* rename to socks4_handle_request or something. */
 +/**
-    This function sends a method negotiation reply to 'dest'.
-    If 'neg_was_success' is true send a positive response,
-    otherwise send a negative one.
-    It returns -1 if no suitable negotiation methods were found,
-    or if there was an error during replying.
- 
-    Method Negotiation Reply (Server -> Client):
-    | version | method selected |
-        1b           1b
- */
- static enum socks_ret
- socks5_do_negotiation(struct evbuffer *dest, unsigned int neg_was_success)
- {
-   uchar reply[2];
-   reply[0] = SOCKS5_VERSION;
- 
-   reply[1] = neg_was_success ? SOCKS5_METHOD_NOAUTH : SOCKS5_METHOD_FAIL;
- 
-   if (evbuffer_add(dest, reply, 2) == -1 || !neg_was_success)
-     return SOCKS_BROKEN;
-   else
-     return SOCKS_GOOD;
- }
- 
- /**
 +   Takes a SOCKS4/SOCKS4a command request from 'source', it evaluates
 +   it and if it's legit it parses it into 'parsereq'.
 +   
 +   It returns SOCKS_GOOD if everything went fine.
 +   It returns SOCKS_INCOMPLETE if we need more data from the client.
 +   It returns SOCKS_BROKEN if we didn't like something.
 +*/   
++
++/* XXXX rename to socks4_handle_request or something. */
  enum socks_ret
  socks4_read_request(struct evbuffer *source, socks_state_t *state)
  {
diff --cc src/socks.h
index 6ae69e9,ef7b953..e2c20b5
--- a/src/socks.h
+++ b/src/socks.h
@@@ -43,11 -39,11 +39,10 @@@ int socks_state_get_address(const socks
                              const char **addr_out,
                              int *port_out);
  int socks_state_set_address(socks_state_t *state, const struct sockaddr *sa);
 -int socks_send_reply(socks_state_t *state, struct evbuffer *dest, int error);
 -int socks5_send_reply(struct evbuffer *reply_dest,
 -                      socks_state_t *state, int status);
 -
 +void socks_send_reply(socks_state_t *state, struct evbuffer *dest, int error);
- void socks5_send_reply(struct evbuffer *reply_dest, 
++void socks5_send_reply(struct evbuffer *reply_dest,
 +                       socks_state_t *state, int status);
  
- 
  #define SOCKS5_SUCCESS            0x00
  #define SOCKS5_FAILED_GENERAL     0x01
  #define SOCKS5_FAILED_NOTALLOWED  0x02
@@@ -106,11 -102,16 +101,14 @@@ struct socks_state_t 
  
  enum socks_ret socks5_handle_negotiation(struct evbuffer *source,
                                struct evbuffer *dest, socks_state_t *state);
 -int socks5_send_reply(struct evbuffer *reply_dest, socks_state_t *state,
 -                      int status);
 -enum socks_ret socks5_handle_request(struct evbuffer *source,
 -                                     struct parsereq *parsereq);
 +enum socks_ret socks5_handle_request(struct evbuffer *source, struct parsereq *parsereq);
 +
- enum socks_ret socks4_read_request(struct evbuffer *source, socks_state_t *state);
- void socks4_send_reply(struct evbuffer *dest, 
+ 
+ enum socks_ret socks4_read_request(struct evbuffer *source,
+                                    socks_state_t *state);
 -int socks4_send_reply(struct evbuffer *dest,
 -                      socks_state_t *state, int status);
++void socks4_send_reply(struct evbuffer *dest,
 +                       socks_state_t *state, int status);
- #endif
  
- #endif
+ #endif /* SOCKS_PRIVATE */
+ 
+ #endif /* socks.h */
diff --cc src/test/unittest_obfs2.c
index 27395df,a7c8112..0b2054b
--- a/src/test/unittest_obfs2.c
+++ b/src/test/unittest_obfs2.c
@@@ -31,10 -30,10 +30,10 @@@ test_proto_option_parsing(void *data
    log_set_method(LOG_METHOD_NULL, NULL);
  
    tt_assert(set_up_protocol(n_options, options,
 -                            proto_params) == 1);
 +                            proto_params) == 0);
  
    /** two --dest. */
-   char *options2[] = {"obfs2", "--dest=127.0.0.1:5555", "--dest=a", 
+   char *options2[] = {"obfs2", "--dest=127.0.0.1:5555", "--dest=a",
                        "server", "127.0.0.1:5552"};
    n_options = 5;
  
diff --cc src/util.c
index 4517f95,d54c67f..cab4bf1
--- a/src/util.c
+++ b/src/util.c
@@@ -159,120 -134,8 +145,120 @@@ obfs_vsnprintf(char *str, size_t size, 
    return r;
  }
  
 +/************************ Doubly Linked List (DLL) ******************/
 +
 +/**
 +   Insert 'new_node' after 'node' in the doubly linked list 'list'.
 +*/
 +static void
 +dll_insert_after(dll_t *list, dll_node_t *node, dll_node_t *new_node)
 +{
 +  assert(node);
 +  assert(new_node);
 +
 +  if (!list)
 +    return;
 +
 +  new_node->prev = node;
 +  new_node->next = node->next;
 +  if (!node->next)
 +    list->tail = new_node;
 +  else
 +    node->next->prev = new_node;
 +  node->next = new_node;
 +}
 +
 +/**
 +   Insert 'new_node' before 'node' in the doubly linked list 'list'.
 +*/ 
 +static void
 +dll_insert_before(dll_t *list, dll_node_t *node, dll_node_t *new_node)
 +{
 +  assert(node);
 +  assert(new_node);
 +
 +  if (!list)
 +    return;
 +
 +  new_node->prev = node->prev;
 +  new_node->next = node;
 +  if (!node->prev)
 +    list->head = new_node;
 +  else
 +    node->prev->next = new_node;
 +  node->prev = new_node;
 +}
 +
 +/** Initialize <b>list</b> as an empty list. */
 +void
 +dll_init(dll_t *list)
 +{
 +  list->head = list->tail = NULL;
 +}
 +  
 +/**
 +   Insert 'node' in the beginning of the doubly linked 'list'.
 +*/ 
 +static void
 +dll_insert_beginning(dll_t *list, dll_node_t *node)
 +{
 +  assert(node);
 +
 +  if (!list)
 +    return;
 +
 +  if (!list->head) {
 +    list->head = node;
 +    list->tail = node;
 +    node->prev = NULL;
 +    node->next = NULL;
 +  } else {
 +    dll_insert_before(list, list->head, node);
 +  }
 +}
 +  
 +/** 
 +    Appends 'data' to the end of the doubly linked 'list'.
 +    Returns 1 on success, -1 on fail.
 +*/
 +int
 +dll_append(dll_t *list, dll_node_t *node)
 +{
 +  assert(list);
 +  assert(node);
 +
 +  if (!list->tail)
 +    dll_insert_beginning(list, node);
 +  else
 +    dll_insert_after(list, list->tail, node);
 +
 +  return 1;
 +}
 +
 +/**
 +   Removes 'node' from the doubly linked list 'list'.
 +   It frees the list node, but leaves its data intact.
 +*/ 
 +void
 +dll_remove(dll_t *list, dll_node_t *node)
 +{
 +  assert(node);
 +
 +  if (!list)
 +    return;
 +
 +  if (!node->prev)
 +    list->head = node->next;
 +  else
 +    node->prev->next = node->next;
 +  if (!node->next)
 +    list->tail = node->prev;
 +  else
 +    node->next->prev = node->prev;
 +}
 +
  /************************ Logging Subsystem *************************/
- /** The code of this section was to a great extend shamelessly copied
+ /** The code of this section was to a great extent shamelessly copied
      off tor. It's basicaly a stripped down version of tor's logging
      system. Thank you tor. */
  
@@@ -331,27 -200,8 +323,8 @@@ sev_is_valid(int severity
  }
  
  /**
-    Sets the global logging 'method' and also sets and open the logfile
-    'filename' in case we want to log into a file.
-    It returns 0 on success and -1 on fail.
- */
- int
- log_set_method(int method, const char *filename)
- {
-   
-   logging_method = method;
-   if (method == LOG_METHOD_FILE) {
-     if (open_and_set_obfsproxy_logfile(filename) < 0)
-       return -1;
-     if (write_logfile_prologue(logging_logfile) < 0)
-       return -1;
-   }    
-   return 0;
- }
- 
- /**
     Helper: Opens 'filename' and sets it as the obfsproxy logfile.
 -   On success it returns 1, on fail it returns -1.
 +   On success it returns 0, on fail it returns -1.
  */
  static int
  open_and_set_obfsproxy_logfile(const char *filename)
@@@ -381,17 -228,14 +351,16 @@@ close_obfsproxy_logfile(void
  }
  
  /**
 -   Writes a small prologue in the logfile 'fd' to separate log
 -   instances.
 +   Writes a small prologue in the logfile 'fd' that mentions the
 +   obfsproxy version and helps separate log instances.
 +
 +   Returns 0 on success, -1 on failure.
  */
  static int
- write_logfile_prologue(int logfile) {
-   char buf[256];
-   if (compose_logfile_prologue(buf, sizeof(buf)) < 0)
-     return -1;
-   if (write(logfile, buf, strlen(buf)) < 0)
+ write_logfile_prologue(int logfile)
+ {
+   static const char prologue[] = "\nBrand new obfsproxy log:\n";
+   if (write(logfile, prologue, strlen(prologue)) != strlen(prologue))
      return -1;
    return 0;
  }
diff --cc src/util.h
index 7e73cee,f52f335..ff9df22
--- a/src/util.h
+++ b/src/util.h
@@@ -50,60 -35,8 +35,36 @@@ int obfs_snprintf(char *str, size_t siz
                    const char *format, ...)
    __attribute__((format(printf, 3, 4)));
  
 +/***** 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)   \
 +                    )
 +
 +
 +/** A doubly linked list node.
 +    [algorithms ripped off Wikipedia (Doubly_linked_list) ] */
 +typedef struct dll_node_t {
 +  struct dll_node_t *next, *prev;
 +} dll_node_t;
 +
 +/** A doubly linked list. */
 +typedef struct dll_t {
 +  struct dll_node_t *head;
 +  struct dll_node_t *tail;
 +} dll_t;
 +
 +void dll_init(dll_t *list);
 +int dll_append(dll_t *list, dll_node_t *node);
 +void dll_remove(dll_t *list, dll_node_t *node);
 +#define DLL_INIT() { NULL, NULL }
 +
  /***** Logging subsystem stuff. *****/
  
- void log_fn(int severity, const char *format, ...)
-   __attribute__((format(printf, 2, 3)));
- int log_set_method(int method, const char *filename);
- int log_set_min_severity(const char* sev_string);
- int close_obfsproxy_logfile(void);
- 
- #ifdef __GNUC__
- #define log_info(args...) log_fn(LOG_SEV_INFO, args)
- #define log_warn(args...) log_fn(LOG_SEV_WARN, args)
- #define log_debug(args...) log_fn(LOG_SEV_DEBUG, args)
- #elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
- #define log_info(...) log_fn(LOG_SEV_INFO, __VA_ARGS__)
- #define log_warn(...) log_fn(LOG_SEV_WARN, __VA_ARGS__)
- #define log_debug(...) log_fn(LOG_SEV_DEBUG, __VA_ARGS__)
- #else
- #define NEED_LOG_WRAPPERS
- void log_info(const char *format, ...)
-   __attribute__((format(printf, 1, 2)));
- void log_warn(const char *format, ...)
-   __attribute__((format(printf, 1, 2)));
- void log_debug(const char *format, ...)
-   __attribute__((format(printf, 1, 2)));
- #endif
- 
  /** Logging methods */
  
  /** Spit log messages on stdout. */



More information about the tor-commits mailing list