aboutsummaryrefslogtreecommitdiff
path: root/src/or/command.c
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2007-11-05 18:15:44 +0000
committerNick Mathewson <nickm@torproject.org>2007-11-05 18:15:44 +0000
commite94fad36aceece917b65a9558b2f1156c0dba3ea (patch)
tree88f7f9c13dcd8d0040c1af14639382dbaaf5016c /src/or/command.c
parenta7993ea2b6be56229875c72add469ab2c971d8c9 (diff)
downloadtor-e94fad36aceece917b65a9558b2f1156c0dba3ea.tar
tor-e94fad36aceece917b65a9558b2f1156c0dba3ea.tar.gz
r16409@catbus: nickm | 2007-11-05 10:38:25 -0500
Split handshake state into its own structure. Revise versions and netinfo code to use this structure. svn:r12380
Diffstat (limited to 'src/or/command.c')
-rw-r--r--src/or/command.c92
1 files changed, 64 insertions, 28 deletions
diff --git a/src/or/command.c b/src/or/command.c
index c449e6c0a..e667d5e0a 100644
--- a/src/or/command.c
+++ b/src/or/command.c
@@ -396,12 +396,14 @@ command_process_versions_cell(cell_t *cell, or_connection_t *conn)
int highest_supported_version = 0;
const char *cp, *end;
if (conn->link_proto != 0 ||
- conn->_base.state != OR_CONN_STATE_WAITING_FOR_VERSIONS) {
+ conn->_base.state != OR_CONN_STATE_OR_HANDSHAKING ||
+ (conn->handshake_state && conn->handshake_state->received_versions)) {
log_fn(LOG_PROTOCOL_WARN, LD_OR,
"Received a VERSIONS cell on a connection with its version "
"already set to %d; dropping", (int) conn->link_proto);
return;
}
+ tor_assert(conn->handshake_state);
versionslen = ntohs(get_uint16(cell->payload));
end = cell->payload + 2 + versionslen;
if (end > cell->payload + CELL_PAYLOAD_SIZE)
@@ -416,12 +418,12 @@ command_process_versions_cell(cell_t *cell, or_connection_t *conn)
if (!highest_supported_version) {
log_fn(LOG_PROTOCOL_WARN, LD_OR,
"Couldn't find a version in common; defaulting to v1.");
- /*XXXX020 or just break the connection?*/
+ /*XXXX020 just break the connection?*/
conn->link_proto = 1;
return;
}
conn->link_proto = highest_supported_version;
- conn->_base.state = OR_CONN_STATE_OPEN;
+ conn->handshake_state->received_versions = 1;
if (highest_supported_version >= 2)
connection_or_send_netinfo(conn);
@@ -438,46 +440,42 @@ command_process_netinfo_cell(cell_t *cell, or_connection_t *conn)
const char *cp, *end;
uint8_t n_other_addrs;
time_t now = time(NULL);
-
- /*XXXX020 reject duplicate netinfos. */
-
- if (conn->link_proto < 2 || conn->_base.state != OR_CONN_STATE_OPEN) {
+ if (conn->link_proto < 2) {
log_fn(LOG_PROTOCOL_WARN, LD_OR,
"Received a NETINFO cell on %s connection; dropping.",
conn->link_proto == 0 ? "non-versioned" : "a v1");
return;
}
+ if (conn->_base.state != OR_CONN_STATE_OR_HANDSHAKING) {
+ log_fn(LOG_PROTOCOL_WARN, LD_OR,
+ "Received a NETINFO cell on a non-handshaking; dropping.");
+ return;
+ }
+ tor_assert(conn->handshake_state &&
+ conn->handshake_state->received_versions);
+ if (conn->handshake_state->received_netinfo) {
+ log_fn(LOG_PROTOCOL_WARN, LD_OR,
+ "Received a duplicate NETINFO cell; dropping.");
+ return;
+ }
/* Decode the cell. */
timestamp = ntohl(get_uint32(cell->payload));
+ if (abs(now - conn->handshake_state->sent_versions_at) < 180) {
+ conn->handshake_state->apparent_skew = now - timestamp;
+ }
+
my_addr_type = (uint8_t) cell->payload[4];
my_addr_len = (uint8_t) cell->payload[5];
my_addr_ptr = cell->payload + 6;
- /* Possibly learn my address. XXXX020 */
end = cell->payload + CELL_PAYLOAD_SIZE;
cp = cell->payload + 6 + my_addr_len;
if (cp >= end) {
log_fn(LOG_PROTOCOL_WARN, LD_OR,
"Address too long in netinfo cell; dropping.");
+ /*XXXX020 reject and break OR conn! */
return;
- }
-
- /*XXXX020 magic number 3600 */
- if (abs(timestamp - now) > 3600 &&
- router_get_by_digest(conn->identity_digest)) {
- long delta = now - timestamp;
- char dbuf[64];
- /*XXXX020 not always warn!*/
- format_time_interval(dbuf, sizeof(dbuf), delta);
- log_fn(LOG_WARN, LD_HTTP, "Received NETINFO cell with skewed time from "
- "server at %s:%d. It seems that our clock is %s by %s, or "
- "that theirs is %s. Tor requires an accurate clock to work: "
- "please check your time and date settings.",
- conn->_base.address, (int)conn->_base.port,
- delta>0 ? "ahead" : "behind", dbuf,
- delta>0 ? "behind" : "ahead");
- control_event_general_status(LOG_WARN,
- "CLOCK_SKEW SKEW=%ld SOURCE=OR:%s:%d",
- delta, conn->_base.address, conn->_base.port);
+ } else if (my_addr_type == RESOLVED_TYPE_IPV4 && my_addr_len == 4) {
+ conn->handshake_state->my_apparent_addr = ntohl(get_uint32(my_addr_ptr));
}
n_other_addrs = (uint8_t) *cp++;
@@ -491,12 +489,50 @@ command_process_netinfo_cell(cell_t *cell, or_connection_t *conn)
if (other_addr_type == RESOLVED_TYPE_IPV4 && other_addr_len == 4) {
uint32_t addr = ntohl(get_uint32(cp));
if (addr == conn->real_addr) {
- conn->is_canonical = 1;
+ conn->handshake_state->apparently_canonical = 1;
break;
}
}
cp += other_addr_len;
--n_other_addrs;
}
+
+ conn->handshake_state->received_netinfo = 1;
}
+/** DOCDOC Called when we're done authenticating; act on stuff we
+ * learned in netinfo. */
+void
+connection_or_act_on_netinfo(or_connection_t *conn)
+{
+ long delta;
+ if (!conn->handshake_state)
+ return;
+
+ tor_assert(conn->handshake_state->authenticated != 0);
+
+ delta = conn->handshake_state->apparent_skew;
+ /*XXXX020 magic number 3600 */
+ if (abs(delta) > 3600 &&
+ router_get_by_digest(conn->identity_digest)) {
+ char dbuf[64];
+ /*XXXX020 not always warn!*/
+ format_time_interval(dbuf, sizeof(dbuf), delta);
+ log_fn(LOG_WARN, LD_HTTP, "Received NETINFO cell with skewed time from "
+ "server at %s:%d. It seems that our clock is %s by %s, or "
+ "that theirs is %s. Tor requires an accurate clock to work: "
+ "please check your time and date settings.",
+ conn->_base.address, (int)conn->_base.port,
+ delta>0 ? "ahead" : "behind", dbuf,
+ delta>0 ? "behind" : "ahead");
+ control_event_general_status(LOG_WARN,
+ "CLOCK_SKEW SKEW=%ld SOURCE=OR:%s:%d",
+ delta, conn->_base.address, conn->_base.port);
+ }
+
+ /* XXX020 possibly, learn my address from my_apparent_addr */
+
+ if (conn->handshake_state->apparently_canonical) {
+ conn->is_canonical = 1;
+ }
+}