}
#endif
-/*DOCDOC*/
+/** The size of the header of an Extended ORPort message: 2 bytes for
+ * COMMAND, 2 bytes for BODYLEN */
#define EXT_OR_CMD_HEADER_SIZE 4
-/*DOCDOC*/
+
+/** Read <b>buf</b>, which should contain an Extended ORPort message
+ * from a transport proxy. If well-formed, create and populate
+ * <b>out</b> with the Extended ORport message. Return 0 if the
+ * buffer was incomplete, 1 if it was well-formed and -1 if we
+ * encountered an error while parsing it. */
int
fetch_ext_or_command_from_buf(buf_t *buf, ext_or_cmd_t **out)
{
}
#ifdef USE_BUFFEREVENTS
-/*DOCDOC*/
+/** Read <b>buf</b>, which should contain an Extended ORPort message
+ * from a transport proxy. If well-formed, create and populate
+ * <b>out</b> with the Extended ORport message. Return 0 if the
+ * buffer was incomplete, 1 if it was well-formed and -1 if we
+ * encountered an error while parsing it. */
int
fetch_ext_or_command_from_evbuffer(struct evbuffer *buf, ext_or_cmd_t **out)
{
* they form a linked list, with next_with_same_id as the next pointer. */
static digestmap_t *orconn_identity_map = NULL;
-/**DOCDOC */
+/** Global map between Extended ORPort identifiers and OR
+ * connections. */
static digestmap_t *orconn_ext_or_id_map = NULL;
/** If conn is listed in orconn_identity_map, remove it, and clear
#endif
}
+/** Remove the Extended ORPort identifier of <b>conn</b> from the
+ global identifier list. Also, clear the identifier from the
+ connection itself. */
void
connection_or_remove_from_ext_or_id_map(or_connection_t *conn)
{
memset(conn->ext_or_conn_id, 0, EXT_OR_CONN_ID_LEN);
}
-
-/*DOCDOC*/
+/** Deallocate the global Extended ORPort identifier list */
void
connection_or_clear_ext_or_id_map(void)
{
digestmap_free(orconn_ext_or_id_map, NULL);
}
-/*DOCDOC
- sets it to a random value */
+/** Creates an Extended ORPort identifier for <b>conn<b/> and deposits
+ * it into the global list of identifiers. */
void
connection_or_set_ext_or_identifier(or_connection_t *conn)
{
if (!orconn_ext_or_id_map)
orconn_ext_or_id_map = digestmap_new();
+ /* Remove any previous identifiers: */
if (!tor_digest_is_zero(conn->ext_or_conn_id))
connection_or_remove_from_ext_or_id_map(conn);
tor_free(cell);
}
-/*DOCDOC*/
+/** 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)
{
return cmd;
}
-/*DOCDOC*/
+/** Deallocate the Extended ORPort message in <b>cmd</b>. */
void
ext_or_cmd_free(ext_or_cmd_t *cmd)
{
return 0;
}
-/*DOCDOC*/
+/** Get an Extended ORPort message from <b>conn</b>, and place it in <b>out</b>. */
static int
connection_fetch_ext_or_cmd_from_buf(connection_t *conn, ext_or_cmd_t **out)
{
}
}
-/*DOCDOC*/
+/** 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,
return 0;
}
-/*DOCDOC*/
+/** 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)
{
connection_tls_start_handshake(conn, 1);
}
-/*XXXX make these match the spec .*/
-#define EXT_OR_CMD_DONE 0x0001
-#define EXT_OR_CMD_USERADDR 0x0002
#define EXT_OR_CMD_WANT_CONTROL 0x0003
-#define EXT_OR_CMD_OKAY 0x1001
-/*DOCDOC*/
+/** 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 Extended ORPort messages from <b>or_conn</b>. */
int
connection_ext_or_process_inbuf(or_connection_t *or_conn)
{
/* Got a command! */
tor_assert(command);
- if (command->cmd == EXT_OR_CMD_DONE) {
+ 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;
}
- connection_write_ext_or_command(conn, EXT_OR_CMD_OKAY, NULL, 0);
+
+ 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_USERADDR) {
+ } else if (command->cmd == EXT_OR_CMD_TB_USERADDR) {
/* Copy address string. */
tor_addr_t addr;
uint16_t port;
memcpy(addr_str, command->body, command->len);
addr_str[command->len] = 0;
+ log_debug(LD_NET, "Received USERADDR: '%s'!", addr_str);
+
res = tor_addr_port_split(LOG_INFO, addr_str, &address_part, &port);
tor_free(addr_str);
if (res<0)
memcpy(response, or_conn->ext_or_conn_id, EXT_OR_CONN_ID_LEN);
cp = response+EXT_OR_CONN_ID_LEN;
/* XXXX write the TransportControlPort; advance cp. */
- connection_write_ext_or_command(conn, EXT_OR_CMD_OKAY, response,
+ connection_write_ext_or_command(conn, EXT_OR_CMD_BT_OKAY, response,
cp-response);
+ } else {
+ log_notice(LD_NET, "Got an Extended ORPort command we don't understand (%u).",
+ command->cmd);
}
ext_or_cmd_free(command);
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)
{
/** Type for sockets listening for DNS requests. */
#define CONN_TYPE_AP_DNS_LISTENER 15
-/** DOCDOC */
+/** Type for connections from the Extended ORPort. */
#define CONN_TYPE_EXT_OR 16
+/** Type for sockets listening for Extended ORPort connections. */
#define CONN_TYPE_EXT_OR_LISTENER 17
#define CONN_TYPE_MAX_ 17
#define OR_CONN_STATE_OPEN 8
#define OR_CONN_STATE_MAX_ 8
-/*DOCDOC*/
-#define _EXT_OR_CONN_STATE_MIN 1
+/** States of Extended ORPort. */
+#define EXT_OR_CONN_STATE_MIN_ 1
+/** Extended ORPort just launched, and is accepting connections. */
#define EXT_OR_CONN_STATE_OPEN 1
+/** Extended ORPort is flushing its last messages and preparing to
+ * start accepting OR connections. */
#define EXT_OR_CONN_STATE_FLUSHING 2
-#define _EXT_OR_CONN_STATE_MAX 2
+#define EXT_OR_CONN_STATE_MAX_ 2
#define EXIT_CONN_STATE_MIN_ 1
/** State for an exit connection: waiting for response from DNS farm. */
uint8_t payload[FLEXIBLE_ARRAY_MEMBER];
} var_cell_t;
-/* DOCDOC */
+/** A parsed Extended ORPort message. */
typedef struct ext_or_cmd_t {
- uint16_t cmd;
- uint16_t len;
- char body[FLEXIBLE_ARRAY_MEMBER];
+ uint16_t cmd; /** Command type */
+ uint16_t len; /** Body length */
+ char body[FLEXIBLE_ARRAY_MEMBER]; /** Message body */
} ext_or_cmd_t;
/** A cell as packed for writing to the network. */
/**@}*/
} or_handshake_state_t;
-/* DOCDOC */
-#define EXT_OR_CONN_ID_LEN 20
+/** Length of Extended ORPort connection identifier. */
+#define EXT_OR_CONN_ID_LEN DIGEST_LEN /* 20 */
/** Subtype of connection_t for an "OR connection" -- that is, one that speaks
* cells over TLS. */
/** Hash of the public RSA key for the other side's identity key, or zeroes
* if the other side hasn't shown us a valid identity key. */
char identity_digest[DIGEST_LEN];
- /*DOCDOC*/
- char ext_or_conn_id[EXT_OR_CONN_ID_LEN];
+ /** Extended ORPort connection identifier. */
+ char *ext_or_conn_id;
char *nickname; /**< Nickname of OR on other side (if any). */
tor_tls_t *tls; /**< TLS connection state. */