diff options
author | Nick Mathewson <nickm@torproject.org> | 2007-11-05 18:15:44 +0000 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2007-11-05 18:15:44 +0000 |
commit | e94fad36aceece917b65a9558b2f1156c0dba3ea (patch) | |
tree | 88f7f9c13dcd8d0040c1af14639382dbaaf5016c /src/or/command.c | |
parent | a7993ea2b6be56229875c72add469ab2c971d8c9 (diff) | |
download | tor-e94fad36aceece917b65a9558b2f1156c0dba3ea.tar.gz tor-e94fad36aceece917b65a9558b2f1156c0dba3ea.zip |
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.c | 92 |
1 files changed, 64 insertions, 28 deletions
diff --git a/src/or/command.c b/src/or/command.c index c449e6c0a0..e667d5e0a6 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; + } +} |