1 /* Copyright 2001 Matej Pfajfar.
2 * Copyright 2001-2004 Roger Dingledine.
3 * Copyright 2004 Roger Dingledine, Nick Mathewson. */
4 /* See LICENSE for licensing information */
6 const char connection_or_c_id
[] = "$Id$";
9 * \file connection_or.c
10 * \brief Functions to handle OR connections, TLS handshaking, and
11 * cells on the network.
16 /** How much clock skew do we tolerate when checking certificates for
17 * known routers? (sec) */
18 #define TIGHT_CERT_ALLOW_SKEW (90*60)
20 static int connection_tls_finish_handshake(connection_t
*conn
);
21 static int connection_or_process_cells_from_inbuf(connection_t
*conn
);
23 /**************************************************************/
25 /** Pack the cell_t host-order structure <b>src</b> into network-order
26 * in the buffer <b>dest</b>. See tor-spec.txt for details about the
29 static void cell_pack(char *dest
, const cell_t
*src
) {
30 *(uint16_t*)dest
= htons(src
->circ_id
);
31 *(uint8_t*)(dest
+2) = src
->command
;
32 memcpy(dest
+3, src
->payload
, CELL_PAYLOAD_SIZE
);
35 /** Unpack the network-order buffer <b>src</b> into a host-order
36 * cell_t structure <b>dest</b>.
38 static void cell_unpack(cell_t
*dest
, const char *src
) {
39 dest
->circ_id
= ntohs(*(uint16_t*)(src
));
40 dest
->command
= *(uint8_t*)(src
+2);
41 memcpy(dest
->payload
, src
+3, CELL_PAYLOAD_SIZE
);
44 int connection_or_reached_eof(connection_t
*conn
) {
45 log_fn(LOG_INFO
,"OR connection reached EOF. Closing.");
46 connection_mark_for_close(conn
);
50 /** Handle any new bytes that have come in on connection <b>conn</b>.
51 * If conn is in 'open' state, hand it to
52 * connection_or_process_cells_from_inbuf()
55 int connection_or_process_inbuf(connection_t
*conn
) {
58 tor_assert(conn
->type
== CONN_TYPE_OR
);
60 if (conn
->state
!= OR_CONN_STATE_OPEN
)
61 return 0; /* don't do anything */
62 return connection_or_process_cells_from_inbuf(conn
);
65 /** Connection <b>conn</b> has finished writing and has no bytes left on
68 * Otherwise it's in state "open": stop writing and return.
70 * If <b>conn</b> is broken, mark it for close and return -1, else
73 int connection_or_finished_flushing(connection_t
*conn
) {
75 tor_assert(conn
->type
== CONN_TYPE_OR
);
77 assert_connection_ok(conn
,0);
79 if (conn
->state
!= OR_CONN_STATE_OPEN
) {
80 log_fn(LOG_WARN
,"BUG: called in unexpected state %d",conn
->state
);
87 connection_stop_writing(conn
);
91 /** Connected handler for OR connections: begin the TLS handshake.
93 int connection_or_finished_connecting(connection_t
*conn
)
96 tor_assert(conn
->type
== CONN_TYPE_OR
);
97 tor_assert(conn
->state
== OR_CONN_STATE_CONNECTING
);
99 log_fn(LOG_INFO
,"OR connect() to router at %s:%u finished.",
100 conn
->address
,conn
->port
);
102 if (connection_tls_start_handshake(conn
, 0) < 0) {
103 /* TLS handshaking error of some kind. */
104 connection_mark_for_close(conn
);
110 /** Initialize <b>conn</b> to include all the relevant data from <b>router</b>.
111 * This function is called either from connection_or_connect(), if
112 * we initiated the connect, or from connection_tls_finish_handshake()
113 * if the other side initiated it.
116 connection_or_init_conn_from_router(connection_t
*conn
, routerinfo_t
*router
) {
117 or_options_t
*options
= get_options();
119 conn
->addr
= router
->addr
;
120 conn
->port
= router
->or_port
;
121 conn
->receiver_bucket
= conn
->bandwidth
= (int)options
->BandwidthBurst
;
122 conn
->identity_pkey
= crypto_pk_dup_key(router
->identity_pkey
);
123 crypto_pk_get_digest(conn
->identity_pkey
, conn
->identity_digest
);
124 conn
->nickname
= tor_strdup(router
->nickname
);
125 tor_free(conn
->address
);
126 conn
->address
= tor_strdup(router
->address
);
130 connection_or_init_conn_from_address(connection_t
*conn
,
131 uint32_t addr
, uint16_t port
,
132 const char *id_digest
)
136 or_options_t
*options
= get_options();
137 routerinfo_t
*r
= router_get_by_digest(id_digest
);
139 connection_or_init_conn_from_router(conn
,r
);
144 /* This next part isn't really right, but it's good enough for now. */
145 conn
->receiver_bucket
= conn
->bandwidth
= (int)options
->BandwidthBurst
;
146 memcpy(conn
->identity_digest
, id_digest
, DIGEST_LEN
);
147 /* If we're an authoritative directory server, we may know a
148 * nickname for this router. */
149 n
= dirserv_get_nickname_by_digest(id_digest
);
151 conn
->nickname
= tor_strdup(n
);
153 conn
->nickname
= tor_malloc(HEX_DIGEST_LEN
+2);
154 conn
->nickname
[0] = '$';
155 base16_encode(conn
->nickname
+1, HEX_DIGEST_LEN
+1,
156 conn
->identity_digest
, DIGEST_LEN
);
158 tor_free(conn
->address
);
159 in
.s_addr
= htonl(addr
);
160 conn
->address
= tor_strdup(inet_ntoa(in
));
164 connection_or_update_nickname(connection_t
*conn
)
170 tor_assert(conn
->type
== CONN_TYPE_OR
);
171 n
= dirserv_get_nickname_by_digest(conn
->identity_digest
);
173 if (!conn
->nickname
|| strcmp(conn
->nickname
, n
)) {
174 tor_free(conn
->nickname
);
175 conn
->nickname
= tor_strdup(n
);
179 r
= router_get_by_digest(conn
->identity_digest
);
180 if (r
&& r
->is_verified
) {
181 if (!conn
->nickname
|| strcmp(conn
->nickname
, r
->nickname
)) {
182 tor_free(conn
->nickname
);
183 conn
->nickname
= tor_strdup(r
->nickname
);
187 if (conn
->nickname
[0] != '$') {
188 tor_free(conn
->nickname
);
189 conn
->nickname
= tor_malloc(HEX_DIGEST_LEN
+1);
190 base16_encode(conn
->nickname
, HEX_DIGEST_LEN
+1,
191 conn
->identity_digest
, DIGEST_LEN
);
195 /** Launch a new OR connection to <b>addr</b>:<b>port</b> and expect to
196 * handshake with an OR with identity digest <b>id_digest</b>.
198 * If <b>id_digest</b> is me, do nothing. If we're already connected to it,
199 * return that connection. If the connect() is in progress, set the
200 * new conn's state to 'connecting' and return it. If connect() succeeds,
201 * call * connection_tls_start_handshake() on it.
203 * This function is called from router_retry_connections(), for
204 * ORs connecting to ORs, and circuit_establish_circuit(), for
205 * OPs connecting to ORs.
207 * Return the launched conn, or NULL if it failed.
209 connection_t
*connection_or_connect(uint32_t addr
, uint16_t port
,
210 const char *id_digest
) {
214 tor_assert(id_digest
);
216 if (server_mode(get_options()) && (me
=router_get_my_routerinfo()) &&
217 !memcmp(me
->identity_digest
, id_digest
,DIGEST_LEN
)) {
218 log_fn(LOG_WARN
,"Bug: Client asked me to connect to myself! Refusing.");
222 /* this function should never be called if we're already connected to
223 * id_digest, but check first to be sure */
224 /*XXX this is getting called, at least by dirservers. */
225 conn
= connection_get_by_identity_digest(id_digest
, CONN_TYPE_OR
);
227 tor_assert(conn
->nickname
);
228 log_fn(LOG_WARN
,"Asked me to connect to router '%s', but there's already a connection.", conn
->nickname
);
232 conn
= connection_new(CONN_TYPE_OR
);
234 /* set up conn so it's got all the data we need to remember */
235 connection_or_init_conn_from_address(conn
, addr
, port
, id_digest
);
236 conn
->state
= OR_CONN_STATE_CONNECTING
;
237 control_event_or_conn_status(conn
, OR_CONN_EVENT_LAUNCHED
);
239 switch (connection_connect(conn
, conn
->address
, addr
, port
)) {
241 router_mark_as_down(conn
->identity_digest
);
242 control_event_or_conn_status(conn
, OR_CONN_EVENT_FAILED
);
243 connection_free(conn
);
246 connection_watch_events(conn
, EV_READ
| EV_WRITE
);
247 /* writable indicates finish, readable indicates broken link,
248 error indicates broken link on windows */
250 /* case 1: fall through */
253 if (connection_tls_start_handshake(conn
, 0) >= 0)
257 connection_mark_for_close(conn
);
261 /** Begin the tls handshake with <b>conn</b>. <b>receiving</b> is 0 if
262 * we initiated the connection, else it's 1.
264 * Assign a new tls object to conn->tls, begin reading on <b>conn</b>, and pass
265 * <b>conn</b> to connection_tls_continue_handshake().
267 * Return -1 if <b>conn</b> is broken, else return 0.
269 int connection_tls_start_handshake(connection_t
*conn
, int receiving
) {
270 conn
->state
= OR_CONN_STATE_HANDSHAKING
;
271 conn
->tls
= tor_tls_new(conn
->s
, receiving
, 0);
273 log_fn(LOG_WARN
,"tor_tls_new failed. Closing.");
276 connection_start_reading(conn
);
277 log_fn(LOG_DEBUG
,"starting the handshake");
278 if (connection_tls_continue_handshake(conn
) < 0) {
284 /** Move forward with the tls handshake. If it finishes, hand
285 * <b>conn</b> to connection_tls_finish_handshake().
287 * Return -1 if <b>conn</b> is broken, else return 0.
289 int connection_tls_continue_handshake(connection_t
*conn
) {
290 switch (tor_tls_handshake(conn
->tls
)) {
293 log_fn(LOG_INFO
,"tls error. breaking.");
296 return connection_tls_finish_handshake(conn
);
297 case TOR_TLS_WANTWRITE
:
298 connection_start_writing(conn
);
299 log_fn(LOG_DEBUG
,"wanted write");
301 case TOR_TLS_WANTREAD
: /* handshaking conns are *always* reading */
302 log_fn(LOG_DEBUG
,"wanted read");
308 static char ZERO_DIGEST
[] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
310 int connection_or_nonopen_was_started_here(connection_t
*conn
)
312 tor_assert(sizeof(ZERO_DIGEST
) == DIGEST_LEN
);
313 tor_assert(conn
->type
== CONN_TYPE_OR
);
315 if (!memcmp(ZERO_DIGEST
, conn
->identity_digest
, DIGEST_LEN
))
321 /** The tls handshake is finished.
323 * Make sure we are happy with the person we just handshaked with:
324 * If it's an OP (that is, it has no certificate), make sure I'm an OR.
325 * If it's an OR (it has a certificate), make sure it has a recognized
326 * nickname, and its cert is signed by the identity key of that nickname.
327 * If I initiated the connection, make sure it's the right guy; and if
328 * he initiated the connection, make sure he's not already connected.
330 * If he initiated the conn, also initialize conn from the information
333 * If either of us is an OP, set bandwidth to the default OP bandwidth.
335 * If all is successful and he's an OR, then call circuit_n_conn_done()
336 * to handle events that have been pending on the tls handshake
337 * completion, and set the directory to be dirty (only matters if I'm
341 connection_tls_finish_handshake(connection_t
*conn
) {
342 routerinfo_t
*router
;
343 char nickname
[MAX_NICKNAME_LEN
+1];
345 crypto_pk_env_t
*identity_rcvd
=NULL
;
346 char digest_rcvd
[DIGEST_LEN
];
347 or_options_t
*options
= get_options();
349 conn
->state
= OR_CONN_STATE_OPEN
;
350 connection_watch_events(conn
, EV_READ
);
351 log_fn(LOG_DEBUG
,"tls handshake done. verifying.");
352 if (! tor_tls_peer_has_cert(conn
->tls
)) {
353 log_fn(LOG_INFO
,"Peer didn't send a cert! Closing.");
354 /* XXX we should handle this case rather than just closing. */
357 if (tor_tls_get_peer_cert_nickname(conn
->tls
, nickname
, sizeof(nickname
))) {
358 log_fn(LOG_WARN
,"Other side (%s:%d) has a cert without a valid nickname. Closing.",
359 conn
->address
, conn
->port
);
362 log_fn(LOG_DEBUG
, "Other side (%s:%d) claims to be router '%s'",
363 conn
->address
, conn
->port
, nickname
);
365 if (tor_tls_verify(conn
->tls
, &identity_rcvd
) < 0) {
366 log_fn(LOG_WARN
,"Other side, which claims to be router '%s' (%s:%d), has a cert but it's invalid. Closing.",
367 nickname
, conn
->address
, conn
->port
);
371 if (tor_tls_check_lifetime(conn
->tls
, LOOSE_CERT_ALLOW_SKEW
)<0) {
372 log_fn(LOG_WARN
,"Other side '%s' (%s:%d) has a very highly skewed clock, or an expired certificate. Closing.",
373 nickname
, conn
->address
, conn
->port
);
377 log_fn(LOG_DEBUG
,"The router's cert is valid.");
378 crypto_pk_get_digest(identity_rcvd
, digest_rcvd
);
380 if (crypto_pk_cmp_keys(get_identity_key(), identity_rcvd
)<0) {
381 conn
->circ_id_type
= CIRC_ID_TYPE_LOWER
;
383 conn
->circ_id_type
= CIRC_ID_TYPE_HIGHER
;
385 crypto_free_pk_env(identity_rcvd
);
387 router
= router_get_by_nickname(nickname
);
388 if (router
&& /* we know this nickname */
389 router
->is_verified
&& /* make sure it's the right guy */
390 memcmp(digest_rcvd
, router
->identity_digest
, DIGEST_LEN
) != 0) {
391 log_fn(LOG_WARN
, "Identity key not as expected for router claiming to be '%s' (%s:%d) ", nickname
, conn
->address
, conn
->port
);
395 if (router_get_by_digest(digest_rcvd
)) {
396 /* This is a known router; don't cut it slack with its clock skew. */
397 if (tor_tls_check_lifetime(conn
->tls
, TIGHT_CERT_ALLOW_SKEW
)<0) {
398 log_fn(LOG_WARN
,"Router '%s' (%s:%d) has a skewed clock, or an expired certificate; or else our clock is skewed. Closing.",
399 nickname
, conn
->address
, conn
->port
);
405 if (connection_or_nonopen_was_started_here(conn
)) {
406 /* I initiated this connection. */
407 if (strcasecmp(conn
->nickname
, nickname
)) {
408 log_fn(authdir_mode(options
) ? LOG_WARN
: LOG_INFO
,
409 "Other side (%s:%d) is '%s', but we tried to connect to '%s'",
410 conn
->address
, conn
->port
, nickname
, conn
->nickname
);
411 control_event_or_conn_status(conn
, OR_CONN_EVENT_FAILED
);
415 if ((c
=connection_get_by_identity_digest(digest_rcvd
, CONN_TYPE_OR
))) {
416 log_fn(LOG_INFO
,"Router '%s' is already connected on fd %d. Dropping fd %d.", nickname
, c
->s
, conn
->s
);
419 connection_or_init_conn_from_address(conn
,conn
->addr
,conn
->port
,digest_rcvd
);
422 if (!server_mode(options
)) { /* If I'm an OP... */
423 conn
->receiver_bucket
= conn
->bandwidth
= DEFAULT_BANDWIDTH_OP
;
426 directory_set_dirty();
427 circuit_n_conn_done(conn
, 1); /* send the pending creates, if any. */
428 /* Note the success */
429 rep_hist_note_connect_succeeded(conn
->identity_digest
, time(NULL
));
430 control_event_or_conn_status(conn
, OR_CONN_EVENT_CONNECTED
);
434 /** Pack <b>cell</b> into wire-format, and write it onto <b>conn</b>'s
437 * (Commented out) If it's an OR conn, and an entire TLS record is
438 * ready, then try to flush the record now.
440 void connection_or_write_cell_to_buf(const cell_t
*cell
, connection_t
*conn
) {
441 char networkcell
[CELL_NETWORK_SIZE
];
442 char *n
= networkcell
;
446 tor_assert(connection_speaks_cells(conn
));
450 connection_write_to_buf(n
, CELL_NETWORK_SIZE
, conn
);
452 #if 0 /* commented out -- can we get away with not doing this,
453 * because we're already round-robining in handle_read?
455 #define MIN_TLS_FLUSHLEN 15872
456 /* openssl tls record size is 16383, this is close. The goal here is to
457 * push data out as soon as we know there's enough for a tls record, so
458 * during periods of high load we won't read the entire megabyte from
459 * input before pushing any data out. */
460 if (conn
->outbuf_flushlen
-CELL_NETWORK_SIZE
< MIN_TLS_FLUSHLEN
&&
461 conn
->outbuf_flushlen
>= MIN_TLS_FLUSHLEN
) {
462 int extra
= conn
->outbuf_flushlen
- MIN_TLS_FLUSHLEN
;
463 conn
->outbuf_flushlen
= MIN_TLS_FLUSHLEN
;
464 if (connection_handle_write(conn
) < 0) {
465 log_fn(LOG_WARN
,"flushing failed.");
469 conn
->outbuf_flushlen
+= extra
;
470 connection_start_writing(conn
);
477 /** Process cells from <b>conn</b>'s inbuf.
479 * Loop: while inbuf contains a cell, pull it off the inbuf, unpack it,
480 * and hand it to command_process_cell().
484 static int connection_or_process_cells_from_inbuf(connection_t
*conn
) {
485 char buf
[CELL_NETWORK_SIZE
];
489 log_fn(LOG_DEBUG
,"%d: starting, inbuf_datalen %d (%d pending in tls object).",
490 conn
->s
,(int)buf_datalen(conn
->inbuf
),tor_tls_get_pending_bytes(conn
->tls
));
491 if (buf_datalen(conn
->inbuf
) < CELL_NETWORK_SIZE
) /* entire response available? */
492 return 0; /* not yet */
494 connection_fetch_from_buf(buf
, CELL_NETWORK_SIZE
, conn
);
496 /* retrieve cell info from buf (create the host-order struct from the
497 * network-order string) */
498 cell_unpack(&cell
, buf
);
500 command_process_cell(&cell
, conn
);
502 goto loop
; /* process the remainder of the buffer */