1 /* Copyright (c) 2001 Matej Pfajfar.
2 * Copyright (c) 2001-2004, Roger Dingledine.
3 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
4 * Copyright (c) 2007-2011, The Tor Project, Inc. */
5 /* See LICENSE for licensing information */
9 * \brief Functions for processing incoming cells.
12 /* In-points to command.c:
14 * - command_process_cell(), called from
15 * connection_or_process_cells_from_inbuf() in connection_or.c
19 #include "circuitbuild.h"
20 #include "circuitlist.h"
22 #include "connection.h"
23 #include "connection_or.h"
26 #include "cpuworker.h"
27 #include "hibernate.h"
31 #include "routerlist.h"
33 /** How many CELL_PADDING cells have we received, ever? */
34 uint64_t stats_n_padding_cells_processed
= 0;
35 /** How many CELL_CREATE cells have we received, ever? */
36 uint64_t stats_n_create_cells_processed
= 0;
37 /** How many CELL_CREATED cells have we received, ever? */
38 uint64_t stats_n_created_cells_processed
= 0;
39 /** How many CELL_RELAY cells have we received, ever? */
40 uint64_t stats_n_relay_cells_processed
= 0;
41 /** How many CELL_DESTROY cells have we received, ever? */
42 uint64_t stats_n_destroy_cells_processed
= 0;
43 /** How many CELL_VERSIONS cells have we received, ever? */
44 uint64_t stats_n_versions_cells_processed
= 0;
45 /** How many CELL_NETINFO cells have we received, ever? */
46 uint64_t stats_n_netinfo_cells_processed
= 0;
48 /* These are the main functions for processing cells */
49 static void command_process_create_cell(cell_t
*cell
, or_connection_t
*conn
);
50 static void command_process_created_cell(cell_t
*cell
, or_connection_t
*conn
);
51 static void command_process_relay_cell(cell_t
*cell
, or_connection_t
*conn
);
52 static void command_process_destroy_cell(cell_t
*cell
, or_connection_t
*conn
);
53 static void command_process_versions_cell(var_cell_t
*cell
,
54 or_connection_t
*conn
);
55 static void command_process_netinfo_cell(cell_t
*cell
, or_connection_t
*conn
);
57 #ifdef KEEP_TIMING_STATS
58 /** This is a wrapper function around the actual function that processes the
59 * <b>cell</b> that just arrived on <b>conn</b>. Increment <b>*time</b>
60 * by the number of microseconds used by the call to <b>*func(cell, conn)</b>.
63 command_time_process_cell(cell_t
*cell
, or_connection_t
*conn
, int *time
,
64 void (*func
)(cell_t
*, or_connection_t
*))
66 struct timeval start
, end
;
69 tor_gettimeofday(&start
);
73 tor_gettimeofday(&end
);
74 time_passed
= tv_udiff(&start
, &end
) ;
76 if (time_passed
> 10000) { /* more than 10ms */
77 log_debug(LD_OR
,"That call just took %ld ms.",time_passed
/1000);
79 if (time_passed
< 0) {
80 log_info(LD_GENERAL
,"That call took us back in time!");
87 /** Process a <b>cell</b> that was just received on <b>conn</b>. Keep internal
88 * statistics about how many of each cell we've processed so far
89 * this second, and the total number of microseconds it took to
90 * process each type of cell.
93 command_process_cell(cell_t
*cell
, or_connection_t
*conn
)
95 int handshaking
= (conn
->_base
.state
== OR_CONN_STATE_OR_HANDSHAKING
);
96 #ifdef KEEP_TIMING_STATS
97 /* how many of each cell have we seen so far this second? needs better
99 static int num_create
=0, num_created
=0, num_relay
=0, num_destroy
=0;
100 /* how long has it taken to process each type of cell? */
101 static int create_time
=0, created_time
=0, relay_time
=0, destroy_time
=0;
102 static time_t current_second
= 0; /* from previous calls to time */
104 time_t now
= time(NULL
);
106 if (now
> current_second
) { /* the second has rolled over */
109 "At end of second: %d creates (%d ms), %d createds (%d ms), "
110 "%d relays (%d ms), %d destroys (%d ms)",
111 num_create
, create_time
/1000,
112 num_created
, created_time
/1000,
113 num_relay
, relay_time
/1000,
114 num_destroy
, destroy_time
/1000);
117 num_create
= num_created
= num_relay
= num_destroy
= 0;
118 create_time
= created_time
= relay_time
= destroy_time
= 0;
120 /* remember which second it is, for next time */
121 current_second
= now
;
125 #ifdef KEEP_TIMING_STATS
126 #define PROCESS_CELL(tp, cl, cn) STMT_BEGIN { \
128 command_time_process_cell(cl, cn, & tp ## time , \
129 command_process_ ## tp ## _cell); \
132 #define PROCESS_CELL(tp, cl, cn) command_process_ ## tp ## _cell(cl, cn)
135 /* Reject all but VERSIONS and NETINFO when handshaking. */
136 if (handshaking
&& cell
->command
!= CELL_VERSIONS
&&
137 cell
->command
!= CELL_NETINFO
)
140 switch (cell
->command
) {
142 ++stats_n_padding_cells_processed
;
146 case CELL_CREATE_FAST
:
147 ++stats_n_create_cells_processed
;
148 PROCESS_CELL(create
, cell
, conn
);
151 case CELL_CREATED_FAST
:
152 ++stats_n_created_cells_processed
;
153 PROCESS_CELL(created
, cell
, conn
);
156 case CELL_RELAY_EARLY
:
157 ++stats_n_relay_cells_processed
;
158 PROCESS_CELL(relay
, cell
, conn
);
161 ++stats_n_destroy_cells_processed
;
162 PROCESS_CELL(destroy
, cell
, conn
);
165 tor_fragile_assert();
168 ++stats_n_netinfo_cells_processed
;
169 PROCESS_CELL(netinfo
, cell
, conn
);
172 log_fn(LOG_INFO
, LD_PROTOCOL
,
173 "Cell of unknown type (%d) received. Dropping.", cell
->command
);
178 /** Process a <b>cell</b> that was just received on <b>conn</b>. Keep internal
179 * statistics about how many of each cell we've processed so far
180 * this second, and the total number of microseconds it took to
181 * process each type of cell.
184 command_process_var_cell(var_cell_t
*cell
, or_connection_t
*conn
)
186 #ifdef KEEP_TIMING_STATS
187 /* how many of each cell have we seen so far this second? needs better
189 static int num_versions
=0, num_cert
=0;
191 time_t now
= time(NULL
);
193 if (now
> current_second
) { /* the second has rolled over */
196 "At end of second: %d versions (%d ms), %d cert (%d ms)",
197 num_versions
, versions_time
/1000,
198 cert
, cert_time
/1000);
200 num_versions
= num_cert
= 0;
201 versions_time
= cert_time
= 0;
203 /* remember which second it is, for next time */
204 current_second
= now
;
208 /* reject all when not handshaking. */
209 if (conn
->_base
.state
!= OR_CONN_STATE_OR_HANDSHAKING
)
212 switch (cell
->command
) {
214 ++stats_n_versions_cells_processed
;
215 PROCESS_CELL(versions
, cell
, conn
);
219 "Variable-length cell of unknown type (%d) received.",
221 tor_fragile_assert();
226 /** Process a 'create' <b>cell</b> that just arrived from <b>conn</b>. Make a
227 * new circuit with the p_circ_id specified in cell. Put the circuit in state
228 * onionskin_pending, and pass the onionskin to the cpuworker. Circ will get
229 * picked up again when the cpuworker finishes decrypting it.
232 command_process_create_cell(cell_t
*cell
, or_connection_t
*conn
)
237 if (we_are_hibernating()) {
239 "Received create cell but we're shutting down. Sending back "
241 connection_or_send_destroy(cell
->circ_id
, conn
,
242 END_CIRC_REASON_HIBERNATING
);
246 if (!server_mode(get_options())) {
247 log_fn(LOG_PROTOCOL_WARN
, LD_PROTOCOL
,
248 "Received create cell (type %d) from %s:%d, but we're a client. "
249 "Sending back a destroy.",
250 (int)cell
->command
, conn
->_base
.address
, conn
->_base
.port
);
251 connection_or_send_destroy(cell
->circ_id
, conn
,
252 END_CIRC_REASON_TORPROTOCOL
);
256 /* If the high bit of the circuit ID is not as expected, close the
258 id_is_high
= cell
->circ_id
& (1<<15);
259 if ((id_is_high
&& conn
->circ_id_type
== CIRC_ID_TYPE_HIGHER
) ||
260 (!id_is_high
&& conn
->circ_id_type
== CIRC_ID_TYPE_LOWER
)) {
261 log_fn(LOG_PROTOCOL_WARN
, LD_PROTOCOL
,
262 "Received create cell with unexpected circ_id %d. Closing.",
264 connection_or_send_destroy(cell
->circ_id
, conn
,
265 END_CIRC_REASON_TORPROTOCOL
);
269 if (circuit_id_in_use_on_orconn(cell
->circ_id
, conn
)) {
270 routerinfo_t
*router
= router_get_by_digest(conn
->identity_digest
);
271 log_fn(LOG_PROTOCOL_WARN
, LD_PROTOCOL
,
272 "Received CREATE cell (circID %d) for known circ. "
273 "Dropping (age %d).",
274 cell
->circ_id
, (int)(time(NULL
) - conn
->_base
.timestamp_created
));
276 log_fn(LOG_PROTOCOL_WARN
, LD_PROTOCOL
,
277 "Details: nickname \"%s\", platform %s.",
278 router
->nickname
, escaped(router
->platform
));
282 circ
= or_circuit_new(cell
->circ_id
, conn
);
283 circ
->_base
.purpose
= CIRCUIT_PURPOSE_OR
;
284 circuit_set_state(TO_CIRCUIT(circ
), CIRCUIT_STATE_ONIONSKIN_PENDING
);
285 if (cell
->command
== CELL_CREATE
) {
286 char *onionskin
= tor_malloc(ONIONSKIN_CHALLENGE_LEN
);
287 memcpy(onionskin
, cell
->payload
, ONIONSKIN_CHALLENGE_LEN
);
289 /* hand it off to the cpuworkers, and then return. */
290 if (assign_onionskin_to_cpuworker(NULL
, circ
, onionskin
) < 0) {
291 #define WARN_HANDOFF_FAILURE_INTERVAL (6*60*60)
292 static ratelim_t handoff_warning
=
293 RATELIM_INIT(WARN_HANDOFF_FAILURE_INTERVAL
);
295 if ((m
= rate_limit_log(&handoff_warning
, approx_time()))) {
296 log_warn(LD_GENERAL
,"Failed to hand off onionskin. Closing.%s",m
);
299 circuit_mark_for_close(TO_CIRCUIT(circ
), END_CIRC_REASON_INTERNAL
);
302 log_debug(LD_OR
,"success: handed off onionskin.");
304 /* This is a CREATE_FAST cell; we can handle it immediately without using
306 char keys
[CPATH_KEY_MATERIAL_LEN
];
307 char reply
[DIGEST_LEN
*2];
308 tor_assert(cell
->command
== CELL_CREATE_FAST
);
309 if (fast_server_handshake(cell
->payload
, (uint8_t*)reply
,
310 (uint8_t*)keys
, sizeof(keys
))<0) {
311 log_warn(LD_OR
,"Failed to generate key material. Closing.");
312 circuit_mark_for_close(TO_CIRCUIT(circ
), END_CIRC_REASON_INTERNAL
);
315 if (onionskin_answer(circ
, CELL_CREATED_FAST
, reply
, keys
)<0) {
316 log_warn(LD_OR
,"Failed to reply to CREATE_FAST cell. Closing.");
317 circuit_mark_for_close(TO_CIRCUIT(circ
), END_CIRC_REASON_INTERNAL
);
323 /** Process a 'created' <b>cell</b> that just arrived from <b>conn</b>.
325 * that it's intended for. If we're not the origin of the circuit, package
326 * the 'created' cell in an 'extended' relay cell and pass it back. If we
327 * are the origin of the circuit, send it to circuit_finish_handshake() to
328 * finish processing keys, and then call circuit_send_next_onion_skin() to
329 * extend to the next hop in the circuit if necessary.
332 command_process_created_cell(cell_t
*cell
, or_connection_t
*conn
)
336 circ
= circuit_get_by_circid_orconn(cell
->circ_id
, conn
);
340 "(circID %d) unknown circ (probably got a destroy earlier). "
341 "Dropping.", cell
->circ_id
);
345 if (circ
->n_circ_id
!= cell
->circ_id
) {
346 log_fn(LOG_PROTOCOL_WARN
,LD_PROTOCOL
,
347 "got created cell from Tor client? Closing.");
348 circuit_mark_for_close(circ
, END_CIRC_REASON_TORPROTOCOL
);
352 if (CIRCUIT_IS_ORIGIN(circ
)) { /* we're the OP. Handshake this. */
353 origin_circuit_t
*origin_circ
= TO_ORIGIN_CIRCUIT(circ
);
355 log_debug(LD_OR
,"at OP. Finishing handshake.");
356 if ((err_reason
= circuit_finish_handshake(origin_circ
, cell
->command
,
357 cell
->payload
)) < 0) {
358 log_warn(LD_OR
,"circuit_finish_handshake failed.");
359 circuit_mark_for_close(circ
, -err_reason
);
362 log_debug(LD_OR
,"Moving to next skin.");
363 if ((err_reason
= circuit_send_next_onion_skin(origin_circ
)) < 0) {
364 log_info(LD_OR
,"circuit_send_next_onion_skin failed.");
365 /* XXX push this circuit_close lower */
366 circuit_mark_for_close(circ
, -err_reason
);
369 } else { /* pack it into an extended relay cell, and send it. */
371 "Converting created cell to extended relay cell, sending.");
372 relay_send_command_from_edge(0, circ
, RELAY_COMMAND_EXTENDED
,
373 (char*)cell
->payload
, ONIONSKIN_REPLY_LEN
,
378 /** Process a 'relay' or 'relay_early' <b>cell</b> that just arrived from
379 * <b>conn</b>. Make sure it came in with a recognized circ_id. Pass it on to
380 * circuit_receive_relay_cell() for actual processing.
383 command_process_relay_cell(cell_t
*cell
, or_connection_t
*conn
)
386 int reason
, direction
;
388 circ
= circuit_get_by_circid_orconn(cell
->circ_id
, conn
);
392 "unknown circuit %d on connection from %s:%d. Dropping.",
393 cell
->circ_id
, conn
->_base
.address
, conn
->_base
.port
);
397 if (circ
->state
== CIRCUIT_STATE_ONIONSKIN_PENDING
) {
398 log_fn(LOG_PROTOCOL_WARN
,LD_PROTOCOL
,"circuit in create_wait. Closing.");
399 circuit_mark_for_close(circ
, END_CIRC_REASON_TORPROTOCOL
);
403 if (CIRCUIT_IS_ORIGIN(circ
)) {
404 /* if we're a relay and treating connections with recent local
405 * traffic better, then this is one of them. */
406 conn
->client_used
= time(NULL
);
409 if (!CIRCUIT_IS_ORIGIN(circ
) &&
410 cell
->circ_id
== TO_OR_CIRCUIT(circ
)->p_circ_id
)
411 direction
= CELL_DIRECTION_OUT
;
413 direction
= CELL_DIRECTION_IN
;
415 /* If we have a relay_early cell, make sure that it's outbound, and we've
416 * gotten no more than MAX_RELAY_EARLY_CELLS_PER_CIRCUIT of them. */
417 if (cell
->command
== CELL_RELAY_EARLY
) {
418 if (direction
== CELL_DIRECTION_IN
) {
419 /* Allow an unlimited number of inbound relay_early cells,
420 * for hidden service compatibility. There isn't any way to make
421 * a long circuit through inbound relay_early cells anyway. See
424 or_circuit_t
*or_circ
= TO_OR_CIRCUIT(circ
);
425 if (or_circ
->remaining_relay_early_cells
== 0) {
426 log_fn(LOG_PROTOCOL_WARN
, LD_OR
,
427 "Received too many RELAY_EARLY cells on circ %d from %s:%d."
429 cell
->circ_id
, safe_str(conn
->_base
.address
),
431 circuit_mark_for_close(circ
, END_CIRC_REASON_TORPROTOCOL
);
434 --or_circ
->remaining_relay_early_cells
;
438 if ((reason
= circuit_receive_relay_cell(cell
, circ
, direction
)) < 0) {
439 log_fn(LOG_PROTOCOL_WARN
,LD_PROTOCOL
,"circuit_receive_relay_cell "
440 "(%s) failed. Closing.",
441 direction
==CELL_DIRECTION_OUT
?"forward":"backward");
442 circuit_mark_for_close(circ
, -reason
);
446 /** Process a 'destroy' <b>cell</b> that just arrived from
447 * <b>conn</b>. Find the circ that it refers to (if any).
449 * If the circ is in state
450 * onionskin_pending, then call onion_pending_remove() to remove it
451 * from the pending onion list (note that if it's already being
452 * processed by the cpuworker, it won't be in the list anymore; but
453 * when the cpuworker returns it, the circuit will be gone, and the
454 * cpuworker response will be dropped).
456 * Then mark the circuit for close (which marks all edges for close,
457 * and passes the destroy cell onward if necessary).
460 command_process_destroy_cell(cell_t
*cell
, or_connection_t
*conn
)
465 circ
= circuit_get_by_circid_orconn(cell
->circ_id
, conn
);
466 reason
= (uint8_t)cell
->payload
[0];
468 log_info(LD_OR
,"unknown circuit %d on connection from %s:%d. Dropping.",
469 cell
->circ_id
, conn
->_base
.address
, conn
->_base
.port
);
472 log_debug(LD_OR
,"Received for circID %d.",cell
->circ_id
);
474 if (!CIRCUIT_IS_ORIGIN(circ
) &&
475 cell
->circ_id
== TO_OR_CIRCUIT(circ
)->p_circ_id
) {
476 /* the destroy came from behind */
477 circuit_set_p_circid_orconn(TO_OR_CIRCUIT(circ
), 0, NULL
);
478 circuit_mark_for_close(circ
, reason
|END_CIRC_REASON_FLAG_REMOTE
);
479 } else { /* the destroy came from ahead */
480 circuit_set_n_circid_orconn(circ
, 0, NULL
);
481 if (CIRCUIT_IS_ORIGIN(circ
)) {
482 circuit_mark_for_close(circ
, reason
|END_CIRC_REASON_FLAG_REMOTE
);
485 log_debug(LD_OR
, "Delivering 'truncated' back.");
486 payload
[0] = (char)reason
;
487 relay_send_command_from_edge(0, circ
, RELAY_COMMAND_TRUNCATED
,
488 payload
, sizeof(payload
), NULL
);
493 /** Process a 'versions' cell. The current link protocol version must be 0
494 * to indicate that no version has yet been negotiated. We compare the
495 * versions in the cell to the list of versions we support, pick the
496 * highest version we have in common, and continue the negotiation from
500 command_process_versions_cell(var_cell_t
*cell
, or_connection_t
*conn
)
502 int highest_supported_version
= 0;
503 const uint8_t *cp
, *end
;
504 if (conn
->link_proto
!= 0 ||
505 conn
->_base
.state
!= OR_CONN_STATE_OR_HANDSHAKING
||
506 (conn
->handshake_state
&& conn
->handshake_state
->received_versions
)) {
507 log_fn(LOG_PROTOCOL_WARN
, LD_OR
,
508 "Received a VERSIONS cell on a connection with its version "
509 "already set to %d; dropping", (int) conn
->link_proto
);
512 tor_assert(conn
->handshake_state
);
513 end
= cell
->payload
+ cell
->payload_len
;
514 for (cp
= cell
->payload
; cp
+1 < end
; ++cp
) {
515 uint16_t v
= ntohs(get_uint16(cp
));
516 if (is_or_protocol_version_known(v
) && v
> highest_supported_version
)
517 highest_supported_version
= v
;
519 if (!highest_supported_version
) {
520 log_fn(LOG_PROTOCOL_WARN
, LD_OR
,
521 "Couldn't find a version in common between my version list and the "
522 "list in the VERSIONS cell; closing connection.");
523 connection_mark_for_close(TO_CONN(conn
));
525 } else if (highest_supported_version
== 1) {
526 /* Negotiating version 1 makes no sense, since version 1 has no VERSIONS
528 log_fn(LOG_PROTOCOL_WARN
, LD_OR
,
529 "Used version negotiation protocol to negotiate a v1 connection. "
530 "That's crazily non-compliant. Closing connection.");
531 connection_mark_for_close(TO_CONN(conn
));
534 conn
->link_proto
= highest_supported_version
;
535 conn
->handshake_state
->received_versions
= 1;
537 log_info(LD_OR
, "Negotiated version %d with %s:%d; sending NETINFO.",
538 highest_supported_version
,
539 safe_str_client(conn
->_base
.address
),
541 tor_assert(conn
->link_proto
>= 2);
543 if (connection_or_send_netinfo(conn
) < 0) {
544 connection_mark_for_close(TO_CONN(conn
));
549 /** Process a 'netinfo' cell: read and act on its contents, and set the
550 * connection state to "open". */
552 command_process_netinfo_cell(cell_t
*cell
, or_connection_t
*conn
)
555 uint8_t my_addr_type
;
557 const uint8_t *my_addr_ptr
;
558 const uint8_t *cp
, *end
;
559 uint8_t n_other_addrs
;
560 time_t now
= time(NULL
);
562 long apparent_skew
= 0;
563 uint32_t my_apparent_addr
= 0;
565 if (conn
->link_proto
< 2) {
566 log_fn(LOG_PROTOCOL_WARN
, LD_OR
,
567 "Received a NETINFO cell on %s connection; dropping.",
568 conn
->link_proto
== 0 ? "non-versioned" : "a v1");
571 if (conn
->_base
.state
!= OR_CONN_STATE_OR_HANDSHAKING
) {
572 log_fn(LOG_PROTOCOL_WARN
, LD_OR
,
573 "Received a NETINFO cell on non-handshaking connection; dropping.");
576 tor_assert(conn
->handshake_state
&&
577 conn
->handshake_state
->received_versions
);
578 /* Decode the cell. */
579 timestamp
= ntohl(get_uint32(cell
->payload
));
580 if (labs(now
- conn
->handshake_state
->sent_versions_at
) < 180) {
581 apparent_skew
= now
- timestamp
;
584 my_addr_type
= (uint8_t) cell
->payload
[4];
585 my_addr_len
= (uint8_t) cell
->payload
[5];
586 my_addr_ptr
= (uint8_t*) cell
->payload
+ 6;
587 end
= cell
->payload
+ CELL_PAYLOAD_SIZE
;
588 cp
= cell
->payload
+ 6 + my_addr_len
;
590 log_fn(LOG_PROTOCOL_WARN
, LD_OR
,
591 "Addresses too long in netinfo cell; closing connection.");
592 connection_mark_for_close(TO_CONN(conn
));
594 } else if (my_addr_type
== RESOLVED_TYPE_IPV4
&& my_addr_len
== 4) {
595 my_apparent_addr
= ntohl(get_uint32(my_addr_ptr
));
598 n_other_addrs
= (uint8_t) *cp
++;
599 while (n_other_addrs
&& cp
< end
-2) {
600 /* Consider all the other addresses; if any matches, this connection is
603 const uint8_t *next
=
604 decode_address_from_payload(&addr
, cp
, (int)(end
-cp
));
606 log_fn(LOG_PROTOCOL_WARN
, LD_OR
,
607 "Bad address in netinfo cell; closing connection.");
608 connection_mark_for_close(TO_CONN(conn
));
611 if (tor_addr_eq(&addr
, &conn
->real_addr
)) {
612 conn
->is_canonical
= 1;
619 /* Act on apparent skew. */
620 /** Warn when we get a netinfo skew with at least this value. */
621 #define NETINFO_NOTICE_SKEW 3600
622 if (labs(apparent_skew
) > NETINFO_NOTICE_SKEW
&&
623 router_get_by_digest(conn
->identity_digest
)) {
626 /*XXXX be smarter about when everybody says we are skewed. */
627 if (router_digest_is_trusted_dir(conn
->identity_digest
))
631 format_time_interval(dbuf
, sizeof(dbuf
), apparent_skew
);
632 log_fn(severity
, LD_GENERAL
, "Received NETINFO cell with skewed time from "
633 "server at %s:%d. It seems that our clock is %s by %s, or "
634 "that theirs is %s. Tor requires an accurate clock to work: "
635 "please check your time and date settings.",
636 conn
->_base
.address
, (int)conn
->_base
.port
,
637 apparent_skew
>0 ? "ahead" : "behind", dbuf
,
638 apparent_skew
>0 ? "behind" : "ahead");
639 if (severity
== LOG_WARN
) /* only tell the controller if an authority */
640 control_event_general_status(LOG_WARN
,
641 "CLOCK_SKEW SKEW=%ld SOURCE=OR:%s:%d",
643 conn
->_base
.address
, conn
->_base
.port
);
646 /* XXX maybe act on my_apparent_addr, if the source is sufficiently
649 if (connection_or_set_state_open(conn
)<0)
650 connection_mark_for_close(TO_CONN(conn
));
652 log_info(LD_OR
, "Got good NETINFO cell from %s:%d; OR connection is now "
653 "open, using protocol version %d",
654 safe_str_client(conn
->_base
.address
),
655 conn
->_base
.port
, (int)conn
->link_proto
);
656 assert_connection_ok(TO_CONN(conn
),time(NULL
));