[tor-commits] [tor/master] Move Extended ORPort code to its own module.

nickm at torproject.org nickm at torproject.org
Thu Aug 15 16:16:46 UTC 2013


commit d8f74cc439ad025cc52aea8495705096d6538029
Author: George Kadianakis <desnacked at riseup.net>
Date:   Wed Dec 5 19:18:18 2012 +0200

    Move Extended ORPort code to its own module.
    
    Move the code from the connection_or module to ext_orport.
    
    This commit only moves code: it shouldn't modify anything.
---
 src/or/buffers.c       |    1 +
 src/or/config.c        |    1 +
 src/or/connection.c    |    1 +
 src/or/connection_or.c |  524 +---------------------------------------------
 src/or/connection_or.h |   14 --
 src/or/ext_orport.c    |  537 ++++++++++++++++++++++++++++++++++++++++++++++++
 src/or/ext_orport.h    |   14 ++
 src/or/include.am      |    2 +
 src/or/transports.c    |    1 +
 9 files changed, 558 insertions(+), 537 deletions(-)

diff --git a/src/or/buffers.c b/src/or/buffers.c
index ead6baa..50016d3 100644
--- a/src/or/buffers.c
+++ b/src/or/buffers.c
@@ -19,6 +19,7 @@
 #include "connection_or.h"
 #include "control.h"
 #include "reasons.h"
+#include "ext_orport.h"
 #include "../common/util.h"
 #include "../common/torlog.h"
 #ifdef HAVE_UNISTD_H
diff --git a/src/or/config.c b/src/or/config.c
index 19da45a..542191d 100644
--- a/src/or/config.c
+++ b/src/or/config.c
@@ -45,6 +45,7 @@
 #include "routerset.h"
 #include "statefile.h"
 #include "transports.h"
+#include "ext_orport.h"
 #ifdef _WIN32
 #include <shlobj.h>
 #endif
diff --git a/src/or/connection.c b/src/or/connection.c
index a2719e9..fcdc9ab 100644
--- a/src/or/connection.c
+++ b/src/or/connection.c
@@ -33,6 +33,7 @@
 #include "dns.h"
 #include "dnsserv.h"
 #include "entrynodes.h"
+#include "ext_orport.h"
 #include "geoip.h"
 #include "main.h"
 #include "policies.h"
diff --git a/src/or/connection_or.c b/src/or/connection_or.c
index d6d74a7..42127ad 100644
--- a/src/or/connection_or.c
+++ b/src/or/connection_or.c
@@ -37,7 +37,7 @@
 #include "rephist.h"
 #include "router.h"
 #include "routerlist.h"
-
+#include "ext_orport.h"
 #ifdef USE_BUFFEREVENTS
 #include <event2/bufferevent_ssl.h>
 #endif
@@ -482,24 +482,6 @@ var_cell_free(var_cell_t *cell)
   tor_free(cell);
 }
 
-/** Allocate and return a structure capable of holding an Extended
- *  ORPort message of body length <b>len</b>. */
-ext_or_cmd_t *
-ext_or_cmd_new(uint16_t len)
-{
-  size_t size = STRUCT_OFFSET(ext_or_cmd_t, body) + len;
-  ext_or_cmd_t *cmd = tor_malloc(size);
-  cmd->len = len;
-  return cmd;
-}
-
-/** Deallocate the Extended ORPort message in <b>cmd</b>. */
-void
-ext_or_cmd_free(ext_or_cmd_t *cmd)
-{
-  tor_free(cmd);
-}
-
 /** We've received an EOF from <b>conn</b>. Mark it for close and return. */
 int
 connection_or_reached_eof(or_connection_t *conn)
@@ -2442,507 +2424,3 @@ connection_or_send_authenticate_cell(or_connection_t *conn, int authtype)
 
   return 0;
 }
-
-/** Get an Extended ORPort message from <b>conn</b>, and place it in
- *  <b>out</b>. Return -1 on fail, 0 if we need more data, and 1 if we
- *  successfully extracted an Extended ORPort command from the
- *  buffer.  */
-static int
-connection_fetch_ext_or_cmd_from_buf(connection_t *conn, ext_or_cmd_t **out)
-{
-  IF_HAS_BUFFEREVENT(conn, {
-    struct evbuffer *input = bufferevent_get_input(conn->bufev);
-    return fetch_ext_or_command_from_evbuffer(input, out);
-  }) ELSE_IF_NO_BUFFEREVENT {
-    return fetch_ext_or_command_from_buf(conn->inbuf, out);
-  }
-}
-
-/** Write an Extended ORPort message to <b>conn</b>. Use
- *  <b>command</b> as the command type, <b>bodylen</b> as the body
- *  length, and <b>body</b>, if it's present, as the body of the
- *  message. */
-static int
-connection_write_ext_or_command(connection_t *conn,
-                                uint16_t command,
-                                const char *body,
-                                size_t bodylen)
-{
-  char header[4];
-  if (bodylen > UINT16_MAX)
-    return -1;
-  set_uint16(header, htons(command));
-  set_uint16(header+2, htons(bodylen));
-  connection_write_to_buf(header, 4, conn);
-  if (bodylen) {
-    tor_assert(body);
-    connection_write_to_buf(body, bodylen, conn);
-  }
-  return 0;
-}
-
-/** Transition from an Extended ORPort which accepts Extended ORPort
- *  messages, to an Extended ORport which accepts OR traffic. */
-static void
-connection_ext_or_transition(or_connection_t *conn)
-{
-  tor_assert(conn->base_.type == CONN_TYPE_EXT_OR);
-
-  conn->base_.type = CONN_TYPE_OR;
-  control_event_or_conn_status(conn, OR_CONN_EVENT_NEW, 0);
-  connection_tls_start_handshake(conn, 1);
-}
-
-/** Length of authentication cookie. */
-#define EXT_OR_PORT_AUTH_COOKIE_LEN 32
-/** Length of the header of the cookie file. */
-#define EXT_OR_PORT_AUTH_COOKIE_HEADER_LEN 32
-/** Total length of the cookie file. */
-#define EXT_OR_PORT_AUTH_COOKIE_FILE_LEN \
-  EXT_OR_PORT_AUTH_COOKIE_LEN+EXT_OR_PORT_AUTH_COOKIE_HEADER_LEN
-/** Static cookie file header. */
-#define EXT_OR_PORT_AUTH_COOKIE_HEADER "! Extended ORPort Auth Cookie !\x0a"
-/** Length of safe-cookie protocol hashes. */
-#define EXT_OR_PORT_AUTH_HASH_LEN DIGEST256_LEN
-/** Length of safe-cookie protocol nonces. */
-#define EXT_OR_PORT_AUTH_NONCE_LEN 32
-/** Safe-cookie protocol constants. */
-#define EXT_OR_PORT_AUTH_SERVER_TO_CLIENT_CONST \
-  "ExtORPort authentication server-to-client hash"
-#define EXT_OR_PORT_AUTH_CLIENT_TO_SERVER_CONST \
-  "ExtORPort authentication client-to-server hash"
-
-/** If true, we've set ext_or_auth_cookie to a secret code and stored
- * it to disk. */
-static int ext_or_auth_cookie_is_set = 0;
-/** If ext_or_auth_cookie_is_set, a secret cookie that we've stored to disk
- * and which we're using to authenticate controllers.  (If the controller can
- * read it off disk, it has permission to connect.) */
-static char ext_or_auth_cookie[EXT_OR_PORT_AUTH_COOKIE_LEN] = {0};
-
-/** Helper: Return a newly allocated string containing a path to the
- * file where we store our authentication cookie. */
-char *
-get_ext_or_auth_cookie_file(void)
-{
-  const or_options_t *options = get_options();
-  if (options->ExtORPortCookieAuthFile &&
-      strlen(options->ExtORPortCookieAuthFile)) {
-    return tor_strdup(options->ExtORPortCookieAuthFile);
-  } else {
-    return get_datadir_fname("extended_orport_auth_cookie");
-  }
-}
-
-/** Choose a random authentication cookie and write it to disk.
- * Anybody who can read the cookie from disk will be considered
- * authorized to use the control connection. Return -1 if we can't
- * write the file, or 0 on success. */
-int
-init_ext_or_auth_cookie_authentication(int is_enabled)
-{
-  char *fname;
-  char cookie_file_string[EXT_OR_PORT_AUTH_COOKIE_FILE_LEN];
-
-  if (!is_enabled) {
-    ext_or_auth_cookie_is_set = 0;
-    return 0;
-  }
-
-  /* We don't want to generate a new cookie every time we call
-   * options_act(). One should be enough. */
-  if (ext_or_auth_cookie_is_set)
-    return 0; /* all set */
-
-  if (crypto_rand(ext_or_auth_cookie, EXT_OR_PORT_AUTH_COOKIE_LEN) < 0)
-    return -1;
-  ext_or_auth_cookie_is_set = 1;
-
-  memcpy(cookie_file_string, EXT_OR_PORT_AUTH_COOKIE_HEADER,
-         EXT_OR_PORT_AUTH_COOKIE_HEADER_LEN);
-  memcpy(cookie_file_string+EXT_OR_PORT_AUTH_COOKIE_HEADER_LEN,
-         ext_or_auth_cookie, EXT_OR_PORT_AUTH_COOKIE_LEN);
-
-  fname = get_ext_or_auth_cookie_file();
-  if (write_bytes_to_file(fname, cookie_file_string,
-                          EXT_OR_PORT_AUTH_COOKIE_FILE_LEN, 1)) {
-    log_warn(LD_FS,"Error writing authentication cookie to %s.",
-             escaped(fname));
-    tor_free(fname);
-    return -1;
-  }
-
-  log_warn(LD_GENERAL, "Generated Extended ORPort cookie file in '%s'.",
-           fname);
-
-  tor_free(fname);
-  return 0;
-}
-
-/** Read data from <b>conn</b> and see if the client sent us the
- *  authentication type that she prefers to use in this session.
- *
- *  Return -1 if we received corrupted data or if we don't support the
- *  authentication type. Return 0 if we need more data in
- *  <b>conn</b>. Return 1 if the authentication type negotiation was
- *  successful. */
-static int
-connection_ext_or_auth_neg_auth_type(connection_t *conn)
-{
-  char authtype[1] = {0};
-
-  if (connection_get_inbuf_len(conn) < 1)
-    return 0;
-
-  if (connection_fetch_from_buf(authtype, 1, conn) < 0)
-    return -1;
-
-  log_warn(LD_GENERAL, "Client wants us to use %d auth type", authtype[0]);
-  if (authtype[0] != 1) /* '1' is the only auth type supported atm */
-    return -1;
-
-  conn->state = EXT_OR_CONN_STATE_AUTH_WAIT_CLIENT_NONCE;
-  return 1;
-}
-
-/** Read the client's nonce out of <b>conn</b>, setup the safe-cookie
- *  crypto, and then send our own hash and nonce to the client
- *
- *  Return -1 if there was an error; return 0 if we need more data in
- *  <b>conn</b>, and return 1 if we successfully retrieved the
- *  client's nonce and sent our own. */
-static int
-connection_ext_or_auth_handle_client_nonce(connection_t *conn)
-{
-  char server_hash[EXT_OR_PORT_AUTH_HASH_LEN] = {0};
-  char client_nonce[EXT_OR_PORT_AUTH_NONCE_LEN] = {0};
-  char server_nonce[EXT_OR_PORT_AUTH_NONCE_LEN] = {0};
-  char reply[EXT_OR_PORT_AUTH_COOKIE_LEN+EXT_OR_PORT_AUTH_NONCE_LEN] = {0};
-
-  if (!ext_or_auth_cookie_is_set) { /* this should not happen */
-    log_warn(LD_BUG, "Extended ORPort authentication cookie was not set. "
-             "That's weird since we should have done that on startup. "
-             "This might be a Tor bug, please file a bug report. ");
-    return -1;
-  }
-
-  if (connection_get_inbuf_len(conn) < EXT_OR_PORT_AUTH_NONCE_LEN)
-    return 0;
-
-  if (connection_fetch_from_buf(client_nonce,
-                                EXT_OR_PORT_AUTH_NONCE_LEN, conn) < 0) /* XXX check-spaces */
-    return -1;
-
-  /* Get our nonce */
-  if (crypto_rand(server_nonce, EXT_OR_PORT_AUTH_NONCE_LEN) < 0)
-    return -1;
-
-  { /* set up macs */
-    size_t hmac_s_msg_len = strlen(EXT_OR_PORT_AUTH_SERVER_TO_CLIENT_CONST) +
-      2*EXT_OR_PORT_AUTH_NONCE_LEN;
-    size_t hmac_c_msg_len = strlen(EXT_OR_PORT_AUTH_CLIENT_TO_SERVER_CONST) +
-      2*EXT_OR_PORT_AUTH_NONCE_LEN;
-
-    char *hmac_s_msg = tor_malloc_zero(hmac_s_msg_len);
-    char *hmac_c_msg = tor_malloc_zero(hmac_c_msg_len);
-    char *correct_client_hash = tor_malloc_zero(EXT_OR_PORT_AUTH_HASH_LEN);
-
-    memcpy(hmac_s_msg,
-           EXT_OR_PORT_AUTH_SERVER_TO_CLIENT_CONST,
-           strlen(EXT_OR_PORT_AUTH_SERVER_TO_CLIENT_CONST));
-    memcpy(hmac_s_msg + strlen(EXT_OR_PORT_AUTH_SERVER_TO_CLIENT_CONST),
-           client_nonce, EXT_OR_PORT_AUTH_NONCE_LEN);
-    memcpy(hmac_s_msg + strlen(EXT_OR_PORT_AUTH_SERVER_TO_CLIENT_CONST) +
-           EXT_OR_PORT_AUTH_NONCE_LEN,
-           server_nonce, EXT_OR_PORT_AUTH_NONCE_LEN);
-
-    memcpy(hmac_c_msg,
-           EXT_OR_PORT_AUTH_CLIENT_TO_SERVER_CONST,
-           strlen(EXT_OR_PORT_AUTH_CLIENT_TO_SERVER_CONST));
-    memcpy(hmac_c_msg + strlen(EXT_OR_PORT_AUTH_CLIENT_TO_SERVER_CONST),
-           client_nonce, EXT_OR_PORT_AUTH_NONCE_LEN);
-    memcpy(hmac_c_msg + strlen(EXT_OR_PORT_AUTH_CLIENT_TO_SERVER_CONST) +
-           EXT_OR_PORT_AUTH_NONCE_LEN,
-           server_nonce, EXT_OR_PORT_AUTH_NONCE_LEN);
-
-    crypto_hmac_sha256(server_hash,
-                       ext_or_auth_cookie,
-                       EXT_OR_PORT_AUTH_COOKIE_LEN,
-                       hmac_s_msg,
-                       hmac_s_msg_len);
-
-    crypto_hmac_sha256(correct_client_hash,
-                       ext_or_auth_cookie,
-                       EXT_OR_PORT_AUTH_COOKIE_LEN,
-                       hmac_c_msg,
-                       hmac_c_msg_len);
-
-    /* Store the client hash we generated. We will need to compare it
-       with the hash sent by the client. */
-    TO_OR_CONN(conn)->ext_or_auth_correct_client_hash = correct_client_hash;
-
-    tor_free(hmac_s_msg);
-    tor_free(hmac_c_msg);
-  }
-
-  { /* debug logging */ /* XXX disable this codepath if not logging on debug?*/
-    char server_hash_encoded[(2*EXT_OR_PORT_AUTH_HASH_LEN) + 1];
-    char server_nonce_encoded[(2*EXT_OR_PORT_AUTH_NONCE_LEN) + 1];
-    char client_nonce_encoded[(2*EXT_OR_PORT_AUTH_NONCE_LEN) + 1];
-
-    base16_encode(server_hash_encoded, sizeof(server_hash_encoded),
-                  server_hash, sizeof(server_hash));
-    base16_encode(server_nonce_encoded, sizeof(server_nonce_encoded),
-                  server_nonce, sizeof(server_nonce));
-    base16_encode(client_nonce_encoded, sizeof(client_nonce_encoded),
-                  client_nonce, sizeof(client_nonce));
-
-    log_warn(LD_GENERAL,
-             "server_hash: '%s'\nserver_nonce: '%s'\nclient_nonce: '%s'",
-             server_hash_encoded, server_nonce_encoded, client_nonce_encoded);
-  }
-
-  { /* write reply: (server_hash, server_nonce) */
-    memcpy(reply, server_hash, EXT_OR_PORT_AUTH_HASH_LEN);
-    memcpy(reply + EXT_OR_PORT_AUTH_HASH_LEN, server_nonce,
-           EXT_OR_PORT_AUTH_NONCE_LEN);
-    connection_write_to_buf(reply, sizeof(reply), conn);
-  }
-
-  log_warn(LD_GENERAL, "Got client nonce, and sent our own nonce and hash.");
-
-  conn->state = EXT_OR_CONN_STATE_AUTH_WAIT_CLIENT_HASH;
-  return 1;
-}
-
-#define connection_ext_or_auth_send_result_success(c)  \
-  connection_ext_or_auth_send_result(c, 1)
-#define connection_ext_or_auth_send_result_fail(c)  \
-  connection_ext_or_auth_send_result(c, 0)
-
-/** Send authentication results to <b>conn</b>. Successful results if
- *  <b>success</b> is set; failure results otherwise. */
-static void
-connection_ext_or_auth_send_result(connection_t *conn, int success)
-{
-  if (success)
-    connection_write_to_buf("\x01", 1, conn);
-  else
-    connection_write_to_buf("\x00", 1, conn);
-}
-
-/** Receive the client's hash from <b>conn</b>, validate that it's
- *  correct, and then send the authentication results to the client.
- *
- *  Return -1 if there was an error during validation; return 0 if we
- *  need more data in <b>conn</b>, and return 1 if we successfully
- *  validated the client's hash and sent a happy authentication
- *  result. */
-static int
-connection_ext_or_auth_handle_client_hash(connection_t *conn)
-{
-  char provided_client_hash[EXT_OR_PORT_AUTH_HASH_LEN] = {0};
-
-  if (connection_get_inbuf_len(conn) < EXT_OR_PORT_AUTH_HASH_LEN)
-    return 0;
-
-  if (connection_fetch_from_buf(provided_client_hash,
-                                EXT_OR_PORT_AUTH_HASH_LEN, conn) < 0)
-    return -1;
-
-  if (tor_memneq(TO_OR_CONN(conn)->ext_or_auth_correct_client_hash,
-                 provided_client_hash, EXT_OR_PORT_AUTH_HASH_LEN)) {
-    log_warn(LD_GENERAL, "Incorrect client hash. Authentication failed.");
-    connection_ext_or_auth_send_result_fail(conn);
-    return -1;
-  }
-
-  log_warn(LD_GENERAL, "Got client's hash and it was legit.");
-
-  /* send positive auth result */
-  connection_ext_or_auth_send_result_success(conn);
-  conn->state = EXT_OR_CONN_STATE_OPEN;
-  return 1;
-}
-
-/** Handle data from <b>or_conn</b> received on Extended ORPort.
- *  Return -1 on error. 0 on unsufficient data. 1 on correct. */
-static int
-connection_ext_or_auth_process_inbuf(or_connection_t *or_conn)
-{
-  connection_t *conn = TO_CONN(or_conn);
-
-  switch (conn->state) { /* Functionify */
-  case EXT_OR_CONN_STATE_AUTH_WAIT_AUTH_TYPE:
-    return connection_ext_or_auth_neg_auth_type(conn);
-
-  case EXT_OR_CONN_STATE_AUTH_WAIT_CLIENT_NONCE:
-    return connection_ext_or_auth_handle_client_nonce(conn);
-
-  case EXT_OR_CONN_STATE_AUTH_WAIT_CLIENT_HASH:
-    return connection_ext_or_auth_handle_client_hash(conn);
-
-  default:
-    log_warn(LD_BUG, "Encountered unexpected connection state %d while trying "
-             "to process Extended ORPort authentication data.", conn->state);
-    return -1;
-  }
-}
-
-/** Extended ORPort commands (Transport-to-Bridge) */
-#define EXT_OR_CMD_TB_DONE 0x0000
-#define EXT_OR_CMD_TB_USERADDR 0x0001
-
-/** Extended ORPort commands (Bridge-to-Transport) */
-#define EXT_OR_CMD_BT_OKAY 0x1000
-#define EXT_OR_CMD_BT_DENY 0x1001
-#define EXT_OR_CMD_BT_CONTROL 0x1002
-
-/** Process a USERADDR command from the Extended
- *  ORPort. <b>payload</b> is a payload of size <b>len</b>.
- *
- *  If the USERADDR command was well formed, change the address of
- *  <b>conn</b> to the address on the USERADDR command.
- *
- *  Return 0 on success and -1 on error. */
-static int
-connection_ext_or_handle_useraddr(connection_t *conn,
-                                  char *payload, uint16_t len)
-{
-  /* Copy address string. */
-  tor_addr_t addr;
-  uint16_t port;
-  char *addr_str;
-  char *address_part=NULL;
-  int res;
-  addr_str = tor_malloc(len + 1);
-  memcpy(addr_str, payload, len);
-  addr_str[len] = 0;
-
-  res = tor_addr_port_split(LOG_INFO, addr_str, &address_part, &port);
-  tor_free(addr_str);
-  if (res<0)
-    return -1;
-
-  res = tor_addr_parse(&addr, address_part);
-  tor_free(address_part);
-  if (res<0)
-    return -1;
-
-  { /* do some logging */
-    char *old_address = tor_dup_addr(&conn->addr);
-    char *new_address = tor_dup_addr(&addr);
-
-    log_warn(LD_NET, "Received USERADDR." /* XXX Fix log severities/messages */
-             "We rewrite our address from '%s:%u' to '%s:%u'.",
-             safe_str(old_address), conn->port, safe_str(new_address), port);
-
-    tor_free(old_address);
-    tor_free(new_address);
-  }
-
-  /* record the address */
-  tor_addr_copy(&conn->addr, &addr);
-  conn->port = port;
-
-  return 0;
-}
-
-/** Process Extended ORPort messages from <b>or_conn</b>. */
-int
-connection_ext_or_process_inbuf(or_connection_t *or_conn)
-{
-  connection_t *conn = TO_CONN(or_conn);
-  ext_or_cmd_t *command;
-  int r;
-
-  /* If we are still in the authentication stage, process traffic as
-     authentication data: */
-  while (conn->state <= EXT_OR_CONN_STATE_AUTH_MAX) {
-    log_warn(LD_GENERAL, "Got Extended ORPort authentication data (%u).",
-             (unsigned int) connection_get_inbuf_len(conn));
-    r = connection_ext_or_auth_process_inbuf(or_conn);
-    if (r < 0) {
-      connection_mark_for_close(conn);
-      return -1;
-    } else if (r == 0) {
-      return 0;
-    }
-    /* if r > 0, loop and process more data (if any). */
-  }
-
-  while (1) {
-    log_warn(LD_GENERAL, "Got Extended ORPort data.");
-    command = NULL;
-    r = connection_fetch_ext_or_cmd_from_buf(conn, &command);
-    if (r < 0)
-      goto err;
-    else if (r == 0)
-      return 0; /* need to wait for more data */
-
-    /* Got a command! */
-    tor_assert(command);
-
-    if (command->cmd == EXT_OR_CMD_TB_DONE) {
-      if (connection_get_inbuf_len(conn)) {
-        /* The inbuf isn't empty; the client is misbehaving. */
-        goto err;
-      }
-
-      log_debug(LD_NET, "Received DONE.");
-
-      connection_write_ext_or_command(conn, EXT_OR_CMD_BT_OKAY, NULL, 0);
-
-      /* can't transition immediately; need to flush first. */
-      conn->state = EXT_OR_CONN_STATE_FLUSHING;
-      connection_stop_reading(conn);
-    } else if (command->cmd == EXT_OR_CMD_TB_USERADDR) {
-      if (connection_ext_or_handle_useraddr(conn,
-                                            command->body, command->len) < 0)
-        goto err;
-    } else {
-      log_notice(LD_NET,"Got Extended ORPort command we don't regognize (%u).",
-                 command->cmd);
-    }
-
-    ext_or_cmd_free(command);
-  }
-
-  return 0;
-
- err:
-  ext_or_cmd_free(command);
-  connection_mark_for_close(conn);
-  return -1;
-}
-
-/** <b>conn</b> finished flushing Extended ORPort messages to the
- *  network, and is now ready to accept OR traffic. This function
- *  does the transition. */
-int
-connection_ext_or_finished_flushing(or_connection_t *conn)
-{
-  if (conn->base_.state == EXT_OR_CONN_STATE_FLUSHING) {
-    connection_start_reading(TO_CONN(conn));
-    connection_ext_or_transition(conn);
-  }
-  return 0;
-}
-
-/** Initiate Extended ORPort authentication, by sending the list of
- *  supported authentication types to the client. */
-int
-connection_ext_or_start_auth(or_connection_t *or_conn)
-{
-  connection_t *conn = TO_CONN(or_conn);
-  char authtypes[2] = "\x01\x00"; /* We only support authtype '1' for now. */
-
-  log_warn(LD_GENERAL,
-           "ExtORPort authentication: Sending supported authentication types");
-
-  connection_write_to_buf(authtypes, sizeof(authtypes), conn);
-  conn->state = EXT_OR_CONN_STATE_AUTH_WAIT_AUTH_TYPE;
-
-  return 0;
-}
-
diff --git a/src/or/connection_or.h b/src/or/connection_or.h
index d420dc7..85e68f1 100644
--- a/src/or/connection_or.h
+++ b/src/or/connection_or.h
@@ -45,8 +45,6 @@ void connection_or_close_for_error(or_connection_t *orconn, int flush);
 
 void connection_or_report_broken_states(int severity, int domain);
 
-int connection_ext_or_start_auth(or_connection_t *or_conn);
-
 int connection_tls_start_handshake(or_connection_t *conn, int receiving);
 int connection_tls_continue_handshake(or_connection_t *conn);
 
@@ -97,17 +95,5 @@ void var_cell_free(var_cell_t *cell);
 /** DOCDOC */
 #define MIN_LINK_PROTO_FOR_WIDE_CIRC_IDS 4
 
-ext_or_cmd_t *ext_or_cmd_new(uint16_t len);
-void ext_or_cmd_free(ext_or_cmd_t *cmd);
-void connection_or_set_ext_or_identifier(or_connection_t *conn);
-void connection_or_remove_from_ext_or_id_map(or_connection_t *conn);
-void connection_or_clear_ext_or_id_map(void);
-
-int connection_ext_or_finished_flushing(or_connection_t *conn);
-int connection_ext_or_process_inbuf(or_connection_t *or_conn);
-
-int init_ext_or_auth_cookie_authentication(int is_enabled);
-char *get_ext_or_auth_cookie_file(void);
-
 #endif
 
diff --git a/src/or/ext_orport.c b/src/or/ext_orport.c
new file mode 100644
index 0000000..18ee5ab
--- /dev/null
+++ b/src/or/ext_orport.c
@@ -0,0 +1,537 @@
+/* Copyright (c) 2012, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file ext_orport.c
+ * \brief Code implementing the Extended ORPort.
+*/
+
+#include "or.h"
+#include "connection.h"
+#include "connection_or.h"
+#include "ext_orport.h"
+#include "control.h"
+#include "config.h"
+#include "main.h"
+
+/** Allocate and return a structure capable of holding an Extended
+ *  ORPort message of body length <b>len</b>. */
+ext_or_cmd_t *
+ext_or_cmd_new(uint16_t len)
+{
+  size_t size = STRUCT_OFFSET(ext_or_cmd_t, body) + len;
+  ext_or_cmd_t *cmd = tor_malloc(size);
+  cmd->len = len;
+  return cmd;
+}
+
+/** Deallocate the Extended ORPort message in <b>cmd</b>. */
+void
+ext_or_cmd_free(ext_or_cmd_t *cmd)
+{
+  tor_free(cmd);
+}
+
+/** Get an Extended ORPort message from <b>conn</b>, and place it in
+ *  <b>out</b>. Return -1 on fail, 0 if we need more data, and 1 if we
+ *  successfully extracted an Extended ORPort command from the
+ *  buffer.  */
+static int
+connection_fetch_ext_or_cmd_from_buf(connection_t *conn, ext_or_cmd_t **out)
+{
+  IF_HAS_BUFFEREVENT(conn, {
+    struct evbuffer *input = bufferevent_get_input(conn->bufev);
+    return fetch_ext_or_command_from_evbuffer(input, out);
+  }) ELSE_IF_NO_BUFFEREVENT {
+    return fetch_ext_or_command_from_buf(conn->inbuf, out);
+  }
+}
+
+/** Write an Extended ORPort message to <b>conn</b>. Use
+ *  <b>command</b> as the command type, <b>bodylen</b> as the body
+ *  length, and <b>body</b>, if it's present, as the body of the
+ *  message. */
+static int
+connection_write_ext_or_command(connection_t *conn,
+                                uint16_t command,
+                                const char *body,
+                                size_t bodylen)
+{
+  char header[4];
+  if (bodylen > UINT16_MAX)
+    return -1;
+  set_uint16(header, htons(command));
+  set_uint16(header+2, htons(bodylen));
+  connection_write_to_buf(header, 4, conn);
+  if (bodylen) {
+    tor_assert(body);
+    connection_write_to_buf(body, bodylen, conn);
+  }
+  return 0;
+}
+
+/** Transition from an Extended ORPort which accepts Extended ORPort
+ *  messages, to an Extended ORport which accepts OR traffic. */
+static void
+connection_ext_or_transition(or_connection_t *conn)
+{
+  tor_assert(conn->base_.type == CONN_TYPE_EXT_OR);
+
+  conn->base_.type = CONN_TYPE_OR;
+  control_event_or_conn_status(conn, OR_CONN_EVENT_NEW, 0);
+  connection_tls_start_handshake(conn, 1);
+}
+
+/** Length of authentication cookie. */
+#define EXT_OR_PORT_AUTH_COOKIE_LEN 32
+/** Length of the header of the cookie file. */
+#define EXT_OR_PORT_AUTH_COOKIE_HEADER_LEN 32
+/** Total length of the cookie file. */
+#define EXT_OR_PORT_AUTH_COOKIE_FILE_LEN \
+  EXT_OR_PORT_AUTH_COOKIE_LEN+EXT_OR_PORT_AUTH_COOKIE_HEADER_LEN
+/** Static cookie file header. */
+#define EXT_OR_PORT_AUTH_COOKIE_HEADER "! Extended ORPort Auth Cookie !\x0a"
+/** Length of safe-cookie protocol hashes. */
+#define EXT_OR_PORT_AUTH_HASH_LEN DIGEST256_LEN
+/** Length of safe-cookie protocol nonces. */
+#define EXT_OR_PORT_AUTH_NONCE_LEN 32
+/** Safe-cookie protocol constants. */
+#define EXT_OR_PORT_AUTH_SERVER_TO_CLIENT_CONST \
+  "ExtORPort authentication server-to-client hash"
+#define EXT_OR_PORT_AUTH_CLIENT_TO_SERVER_CONST \
+  "ExtORPort authentication client-to-server hash"
+
+/** If true, we've set ext_or_auth_cookie to a secret code and stored
+ * it to disk. */
+static int ext_or_auth_cookie_is_set = 0;
+/** If ext_or_auth_cookie_is_set, a secret cookie that we've stored to disk
+ * and which we're using to authenticate controllers.  (If the controller can
+ * read it off disk, it has permission to connect.) */
+static char ext_or_auth_cookie[EXT_OR_PORT_AUTH_COOKIE_LEN] = {0};
+
+/** Helper: Return a newly allocated string containing a path to the
+ * file where we store our authentication cookie. */
+char *
+get_ext_or_auth_cookie_file(void)
+{
+  const or_options_t *options = get_options();
+  if (options->ExtORPortCookieAuthFile &&
+      strlen(options->ExtORPortCookieAuthFile)) {
+    return tor_strdup(options->ExtORPortCookieAuthFile);
+  } else {
+    return get_datadir_fname("extended_orport_auth_cookie");
+  }
+}
+
+/** Choose a random authentication cookie and write it to disk.
+ * Anybody who can read the cookie from disk will be considered
+ * authorized to use the control connection. Return -1 if we can't
+ * write the file, or 0 on success. */
+int
+init_ext_or_auth_cookie_authentication(int is_enabled)
+{
+  char *fname;
+  char cookie_file_string[EXT_OR_PORT_AUTH_COOKIE_FILE_LEN];
+
+  if (!is_enabled) {
+    ext_or_auth_cookie_is_set = 0;
+    return 0;
+  }
+
+  /* We don't want to generate a new cookie every time we call
+   * options_act(). One should be enough. */
+  if (ext_or_auth_cookie_is_set)
+    return 0; /* all set */
+
+  if (crypto_rand(ext_or_auth_cookie, EXT_OR_PORT_AUTH_COOKIE_LEN) < 0)
+    return -1;
+  ext_or_auth_cookie_is_set = 1;
+
+  memcpy(cookie_file_string, EXT_OR_PORT_AUTH_COOKIE_HEADER,
+         EXT_OR_PORT_AUTH_COOKIE_HEADER_LEN);
+  memcpy(cookie_file_string+EXT_OR_PORT_AUTH_COOKIE_HEADER_LEN,
+         ext_or_auth_cookie, EXT_OR_PORT_AUTH_COOKIE_LEN);
+
+  fname = get_ext_or_auth_cookie_file();
+  if (write_bytes_to_file(fname, cookie_file_string,
+                          EXT_OR_PORT_AUTH_COOKIE_FILE_LEN, 1)) {
+    log_warn(LD_FS,"Error writing authentication cookie to %s.",
+             escaped(fname));
+    tor_free(fname);
+    return -1;
+  }
+
+  log_warn(LD_GENERAL, "Generated Extended ORPort cookie file in '%s'.",
+           fname);
+
+  tor_free(fname);
+  return 0;
+}
+
+/** Read data from <b>conn</b> and see if the client sent us the
+ *  authentication type that she prefers to use in this session.
+ *
+ *  Return -1 if we received corrupted data or if we don't support the
+ *  authentication type. Return 0 if we need more data in
+ *  <b>conn</b>. Return 1 if the authentication type negotiation was
+ *  successful. */
+static int
+connection_ext_or_auth_neg_auth_type(connection_t *conn)
+{
+  char authtype[1] = {0};
+
+  if (connection_get_inbuf_len(conn) < 1)
+    return 0;
+
+  if (connection_fetch_from_buf(authtype, 1, conn) < 0)
+    return -1;
+
+  log_warn(LD_GENERAL, "Client wants us to use %d auth type", authtype[0]);
+  if (authtype[0] != 1) /* '1' is the only auth type supported atm */
+    return -1;
+
+  conn->state = EXT_OR_CONN_STATE_AUTH_WAIT_CLIENT_NONCE;
+  return 1;
+}
+
+/** Read the client's nonce out of <b>conn</b>, setup the safe-cookie
+ *  crypto, and then send our own hash and nonce to the client
+ *
+ *  Return -1 if there was an error; return 0 if we need more data in
+ *  <b>conn</b>, and return 1 if we successfully retrieved the
+ *  client's nonce and sent our own. */
+static int
+connection_ext_or_auth_handle_client_nonce(connection_t *conn)
+{
+  char server_hash[EXT_OR_PORT_AUTH_HASH_LEN] = {0};
+  char client_nonce[EXT_OR_PORT_AUTH_NONCE_LEN] = {0};
+  char server_nonce[EXT_OR_PORT_AUTH_NONCE_LEN] = {0};
+  char reply[EXT_OR_PORT_AUTH_COOKIE_LEN+EXT_OR_PORT_AUTH_NONCE_LEN] = {0};
+
+  if (!ext_or_auth_cookie_is_set) { /* this should not happen */
+    log_warn(LD_BUG, "Extended ORPort authentication cookie was not set. "
+             "That's weird since we should have done that on startup. "
+             "This might be a Tor bug, please file a bug report. ");
+    return -1;
+  }
+
+  if (connection_get_inbuf_len(conn) < EXT_OR_PORT_AUTH_NONCE_LEN)
+    return 0;
+
+  if (connection_fetch_from_buf(client_nonce,
+                                EXT_OR_PORT_AUTH_NONCE_LEN, conn) < 0) /* XXX check-spaces */
+    return -1;
+
+  /* Get our nonce */
+  if (crypto_rand(server_nonce, EXT_OR_PORT_AUTH_NONCE_LEN) < 0)
+    return -1;
+
+  { /* set up macs */
+    size_t hmac_s_msg_len = strlen(EXT_OR_PORT_AUTH_SERVER_TO_CLIENT_CONST) +
+      2*EXT_OR_PORT_AUTH_NONCE_LEN;
+    size_t hmac_c_msg_len = strlen(EXT_OR_PORT_AUTH_CLIENT_TO_SERVER_CONST) +
+      2*EXT_OR_PORT_AUTH_NONCE_LEN;
+
+    char *hmac_s_msg = tor_malloc_zero(hmac_s_msg_len);
+    char *hmac_c_msg = tor_malloc_zero(hmac_c_msg_len);
+    char *correct_client_hash = tor_malloc_zero(EXT_OR_PORT_AUTH_HASH_LEN);
+
+    memcpy(hmac_s_msg,
+           EXT_OR_PORT_AUTH_SERVER_TO_CLIENT_CONST,
+           strlen(EXT_OR_PORT_AUTH_SERVER_TO_CLIENT_CONST));
+    memcpy(hmac_s_msg + strlen(EXT_OR_PORT_AUTH_SERVER_TO_CLIENT_CONST),
+           client_nonce, EXT_OR_PORT_AUTH_NONCE_LEN);
+    memcpy(hmac_s_msg + strlen(EXT_OR_PORT_AUTH_SERVER_TO_CLIENT_CONST) +
+           EXT_OR_PORT_AUTH_NONCE_LEN,
+           server_nonce, EXT_OR_PORT_AUTH_NONCE_LEN);
+
+    memcpy(hmac_c_msg,
+           EXT_OR_PORT_AUTH_CLIENT_TO_SERVER_CONST,
+           strlen(EXT_OR_PORT_AUTH_CLIENT_TO_SERVER_CONST));
+    memcpy(hmac_c_msg + strlen(EXT_OR_PORT_AUTH_CLIENT_TO_SERVER_CONST),
+           client_nonce, EXT_OR_PORT_AUTH_NONCE_LEN);
+    memcpy(hmac_c_msg + strlen(EXT_OR_PORT_AUTH_CLIENT_TO_SERVER_CONST) +
+           EXT_OR_PORT_AUTH_NONCE_LEN,
+           server_nonce, EXT_OR_PORT_AUTH_NONCE_LEN);
+
+    crypto_hmac_sha256(server_hash,
+                       ext_or_auth_cookie,
+                       EXT_OR_PORT_AUTH_COOKIE_LEN,
+                       hmac_s_msg,
+                       hmac_s_msg_len);
+
+    crypto_hmac_sha256(correct_client_hash,
+                       ext_or_auth_cookie,
+                       EXT_OR_PORT_AUTH_COOKIE_LEN,
+                       hmac_c_msg,
+                       hmac_c_msg_len);
+
+    /* Store the client hash we generated. We will need to compare it
+       with the hash sent by the client. */
+    TO_OR_CONN(conn)->ext_or_auth_correct_client_hash = correct_client_hash;
+
+    tor_free(hmac_s_msg);
+    tor_free(hmac_c_msg);
+  }
+
+  { /* debug logging */ /* XXX disable this codepath if not logging on debug?*/
+    char server_hash_encoded[(2*EXT_OR_PORT_AUTH_HASH_LEN) + 1];
+    char server_nonce_encoded[(2*EXT_OR_PORT_AUTH_NONCE_LEN) + 1];
+    char client_nonce_encoded[(2*EXT_OR_PORT_AUTH_NONCE_LEN) + 1];
+
+    base16_encode(server_hash_encoded, sizeof(server_hash_encoded),
+                  server_hash, sizeof(server_hash));
+    base16_encode(server_nonce_encoded, sizeof(server_nonce_encoded),
+                  server_nonce, sizeof(server_nonce));
+    base16_encode(client_nonce_encoded, sizeof(client_nonce_encoded),
+                  client_nonce, sizeof(client_nonce));
+
+    log_warn(LD_GENERAL,
+             "server_hash: '%s'\nserver_nonce: '%s'\nclient_nonce: '%s'",
+             server_hash_encoded, server_nonce_encoded, client_nonce_encoded);
+  }
+
+  { /* write reply: (server_hash, server_nonce) */
+    memcpy(reply, server_hash, EXT_OR_PORT_AUTH_HASH_LEN);
+    memcpy(reply + EXT_OR_PORT_AUTH_HASH_LEN, server_nonce,
+           EXT_OR_PORT_AUTH_NONCE_LEN);
+    connection_write_to_buf(reply, sizeof(reply), conn);
+  }
+
+  log_warn(LD_GENERAL, "Got client nonce, and sent our own nonce and hash.");
+
+  conn->state = EXT_OR_CONN_STATE_AUTH_WAIT_CLIENT_HASH;
+  return 1;
+}
+
+#define connection_ext_or_auth_send_result_success(c)  \
+  connection_ext_or_auth_send_result(c, 1)
+#define connection_ext_or_auth_send_result_fail(c)  \
+  connection_ext_or_auth_send_result(c, 0)
+
+/** Send authentication results to <b>conn</b>. Successful results if
+ *  <b>success</b> is set; failure results otherwise. */
+static void
+connection_ext_or_auth_send_result(connection_t *conn, int success)
+{
+  if (success)
+    connection_write_to_buf("\x01", 1, conn);
+  else
+    connection_write_to_buf("\x00", 1, conn);
+}
+
+/** Receive the client's hash from <b>conn</b>, validate that it's
+ *  correct, and then send the authentication results to the client.
+ *
+ *  Return -1 if there was an error during validation; return 0 if we
+ *  need more data in <b>conn</b>, and return 1 if we successfully
+ *  validated the client's hash and sent a happy authentication
+ *  result. */
+static int
+connection_ext_or_auth_handle_client_hash(connection_t *conn)
+{
+  char provided_client_hash[EXT_OR_PORT_AUTH_HASH_LEN] = {0};
+
+  if (connection_get_inbuf_len(conn) < EXT_OR_PORT_AUTH_HASH_LEN)
+    return 0;
+
+  if (connection_fetch_from_buf(provided_client_hash,
+                                EXT_OR_PORT_AUTH_HASH_LEN, conn) < 0)
+    return -1;
+
+  if (tor_memneq(TO_OR_CONN(conn)->ext_or_auth_correct_client_hash,
+                 provided_client_hash, EXT_OR_PORT_AUTH_HASH_LEN)) {
+    log_warn(LD_GENERAL, "Incorrect client hash. Authentication failed.");
+    connection_ext_or_auth_send_result_fail(conn);
+    return -1;
+  }
+
+  log_warn(LD_GENERAL, "Got client's hash and it was legit.");
+
+  /* send positive auth result */
+  connection_ext_or_auth_send_result_success(conn);
+  conn->state = EXT_OR_CONN_STATE_OPEN;
+  return 1;
+}
+
+/** Handle data from <b>or_conn</b> received on Extended ORPort.
+ *  Return -1 on error. 0 on unsufficient data. 1 on correct. */
+static int
+connection_ext_or_auth_process_inbuf(or_connection_t *or_conn)
+{
+  connection_t *conn = TO_CONN(or_conn);
+
+  switch (conn->state) { /* Functionify */
+  case EXT_OR_CONN_STATE_AUTH_WAIT_AUTH_TYPE:
+    return connection_ext_or_auth_neg_auth_type(conn);
+
+  case EXT_OR_CONN_STATE_AUTH_WAIT_CLIENT_NONCE:
+    return connection_ext_or_auth_handle_client_nonce(conn);
+
+  case EXT_OR_CONN_STATE_AUTH_WAIT_CLIENT_HASH:
+    return connection_ext_or_auth_handle_client_hash(conn);
+
+  default:
+    log_warn(LD_BUG, "Encountered unexpected connection state %d while trying "
+             "to process Extended ORPort authentication data.", conn->state);
+    return -1;
+  }
+}
+
+/** Extended ORPort commands (Transport-to-Bridge) */
+#define EXT_OR_CMD_TB_DONE 0x0000
+#define EXT_OR_CMD_TB_USERADDR 0x0001
+
+/** Extended ORPort commands (Bridge-to-Transport) */
+#define EXT_OR_CMD_BT_OKAY 0x1000
+#define EXT_OR_CMD_BT_DENY 0x1001
+#define EXT_OR_CMD_BT_CONTROL 0x1002
+
+/** Process a USERADDR command from the Extended
+ *  ORPort. <b>payload</b> is a payload of size <b>len</b>.
+ *
+ *  If the USERADDR command was well formed, change the address of
+ *  <b>conn</b> to the address on the USERADDR command.
+ *
+ *  Return 0 on success and -1 on error. */
+static int
+connection_ext_or_handle_useraddr(connection_t *conn,
+                                  const char *payload, uint16_t len)
+{
+  /* Copy address string. */
+  tor_addr_t addr;
+  uint16_t port;
+  char *addr_str;
+  char *address_part=NULL;
+  int res;
+  addr_str = tor_malloc(len + 1);
+  memcpy(addr_str, payload, len);
+  addr_str[len] = 0;
+
+  res = tor_addr_port_split(LOG_INFO, addr_str, &address_part, &port);
+  tor_free(addr_str);
+  if (res<0)
+    return -1;
+
+  res = tor_addr_parse(&addr, address_part);
+  tor_free(address_part);
+  if (res<0)
+    return -1;
+
+  { /* do some logging */
+    char *old_address = tor_dup_addr(&conn->addr);
+    char *new_address = tor_dup_addr(&addr);
+
+    log_warn(LD_NET, "Received USERADDR." /* XXX Fix log severities/messages */
+             "We rewrite our address from '%s:%u' to '%s:%u'.",
+             safe_str(old_address), conn->port, safe_str(new_address), port);
+
+    tor_free(old_address);
+    tor_free(new_address);
+  }
+
+  /* record the address */
+  tor_addr_copy(&conn->addr, &addr);
+  conn->port = port;
+
+  return 0;
+}
+
+/** Process Extended ORPort messages from <b>or_conn</b>. */
+int
+connection_ext_or_process_inbuf(or_connection_t *or_conn)
+{
+  connection_t *conn = TO_CONN(or_conn);
+  ext_or_cmd_t *command;
+  int r;
+
+  /* If we are still in the authentication stage, process traffic as
+     authentication data: */
+  while (conn->state <= EXT_OR_CONN_STATE_AUTH_MAX) {
+    log_warn(LD_GENERAL, "Got Extended ORPort authentication data (%u).",
+             (unsigned int) connection_get_inbuf_len(conn));
+    r = connection_ext_or_auth_process_inbuf(or_conn);
+    if (r < 0) {
+      connection_mark_for_close(conn);
+      return -1;
+    } else if (r == 0) {
+      return 0;
+    }
+    /* if r > 0, loop and process more data (if any). */
+  }
+
+  while (1) {
+    log_warn(LD_GENERAL, "Got Extended ORPort data.");
+    command = NULL;
+    r = connection_fetch_ext_or_cmd_from_buf(conn, &command);
+    if (r < 0)
+      goto err;
+    else if (r == 0)
+      return 0; /* need to wait for more data */
+
+    /* Got a command! */
+    tor_assert(command);
+
+    if (command->cmd == EXT_OR_CMD_TB_DONE) {
+      if (connection_get_inbuf_len(conn)) {
+        /* The inbuf isn't empty; the client is misbehaving. */
+        goto err;
+      }
+
+      log_debug(LD_NET, "Received DONE.");
+
+      connection_write_ext_or_command(conn, EXT_OR_CMD_BT_OKAY, NULL, 0);
+
+      /* can't transition immediately; need to flush first. */
+      conn->state = EXT_OR_CONN_STATE_FLUSHING;
+      connection_stop_reading(conn);
+    } else if (command->cmd == EXT_OR_CMD_TB_USERADDR) {
+      if (connection_ext_or_handle_useraddr(conn,
+                                            command->body, command->len) < 0)
+        goto err;
+    } else {
+      log_notice(LD_NET,"Got Extended ORPort command we don't regognize (%u).",
+                 command->cmd);
+    }
+
+    ext_or_cmd_free(command);
+  }
+
+  return 0;
+
+ err:
+  ext_or_cmd_free(command);
+  connection_mark_for_close(conn);
+  return -1;
+}
+
+/** <b>conn</b> finished flushing Extended ORPort messages to the
+ *  network, and is now ready to accept OR traffic. This function
+ *  does the transition. */
+int
+connection_ext_or_finished_flushing(or_connection_t *conn)
+{
+  if (conn->base_.state == EXT_OR_CONN_STATE_FLUSHING) {
+    connection_start_reading(TO_CONN(conn));
+    connection_ext_or_transition(conn);
+  }
+  return 0;
+}
+
+/** Initiate Extended ORPort authentication, by sending the list of
+ *  supported authentication types to the client. */
+int
+connection_ext_or_start_auth(or_connection_t *or_conn)
+{
+  connection_t *conn = TO_CONN(or_conn);
+  char authtypes[2] = "\x01\x00"; /* We only support authtype '1' for now. */
+
+  log_warn(LD_GENERAL,
+           "ExtORPort authentication: Sending supported authentication types");
+
+  connection_write_to_buf(authtypes, sizeof(authtypes), conn);
+  conn->state = EXT_OR_CONN_STATE_AUTH_WAIT_AUTH_TYPE;
+
+  return 0;
+}
+
diff --git a/src/or/ext_orport.h b/src/or/ext_orport.h
new file mode 100644
index 0000000..fbd7ed6
--- /dev/null
+++ b/src/or/ext_orport.h
@@ -0,0 +1,14 @@
+int connection_ext_or_start_auth(or_connection_t *or_conn);
+
+ext_or_cmd_t *ext_or_cmd_new(uint16_t len);
+void ext_or_cmd_free(ext_or_cmd_t *cmd);
+void connection_or_set_ext_or_identifier(or_connection_t *conn);
+void connection_or_remove_from_ext_or_id_map(or_connection_t *conn);
+void connection_or_clear_ext_or_id_map(void);
+
+int connection_ext_or_finished_flushing(or_connection_t *conn);
+int connection_ext_or_process_inbuf(or_connection_t *or_conn);
+
+int init_ext_or_auth_cookie_authentication(int is_enabled);
+char *get_ext_or_auth_cookie_file(void);
+
diff --git a/src/or/include.am b/src/or/include.am
index f5002e6..8922e03 100644
--- a/src/or/include.am
+++ b/src/or/include.am
@@ -56,6 +56,7 @@ LIBTOR_A_SOURCES = \
         src/or/fp_pair.c				\
 	src/or/geoip.c					\
 	src/or/entrynodes.c				\
+	src/or/ext_orport.c				\
 	src/or/hibernate.c				\
 	src/or/main.c					\
 	src/or/microdesc.c				\
@@ -153,6 +154,7 @@ ORHEADERS = \
 	src/or/dns.h					\
 	src/or/dnsserv.h				\
 	src/or/eventdns_tor.h				\
+	src/or/ext_orport.h				\
 	src/or/fp_pair.h				\
 	src/or/geoip.h					\
 	src/or/entrynodes.h				\
diff --git a/src/or/transports.c b/src/or/transports.c
index 8beb9a5c..196e18b 100644
--- a/src/or/transports.c
+++ b/src/or/transports.c
@@ -97,6 +97,7 @@
 #include "statefile.h"
 #include "entrynodes.h"
 #include "connection_or.h"
+#include "ext_orport.h"
 
 static process_environment_t *
 create_managed_proxy_environment(const managed_proxy_t *mp);






More information about the tor-commits mailing list