connection_edge.c 109 KB
Newer Older
Roger Dingledine's avatar
Roger Dingledine committed
1
2
/* Copyright (c) 2001 Matej Pfajfar.
 * Copyright (c) 2001-2004, Roger Dingledine.
3
 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
4
 * Copyright (c) 2007-2012, The Tor Project, Inc. */
5
6
/* See LICENSE for licensing information */

7
8
/**
 * \file connection_edge.c
9
 * \brief Handle edge streams.
10
 **/
11
#define CONNECTION_EDGE_PRIVATE
12

13
#include "or.h"
14
#include "addressmap.h"
Sebastian Hahn's avatar
Sebastian Hahn committed
15
#include "buffers.h"
16
#include "channel.h"
Sebastian Hahn's avatar
Sebastian Hahn committed
17
#include "circuitlist.h"
Sebastian Hahn's avatar
Sebastian Hahn committed
18
#include "circuituse.h"
Sebastian Hahn's avatar
Sebastian Hahn committed
19
#include "config.h"
Sebastian Hahn's avatar
Sebastian Hahn committed
20
#include "connection.h"
Sebastian Hahn's avatar
Sebastian Hahn committed
21
#include "connection_edge.h"
Sebastian Hahn's avatar
Sebastian Hahn committed
22
#include "connection_or.h"
Sebastian Hahn's avatar
Sebastian Hahn committed
23
#include "control.h"
Sebastian Hahn's avatar
Sebastian Hahn committed
24
#include "dns.h"
25
#include "dnsserv.h"
Sebastian Hahn's avatar
Sebastian Hahn committed
26
#include "dirserv.h"
Sebastian Hahn's avatar
Sebastian Hahn committed
27
#include "hibernate.h"
Sebastian Hahn's avatar
Sebastian Hahn committed
28
#include "main.h"
29
#include "nodelist.h"
Sebastian Hahn's avatar
Sebastian Hahn committed
30
#include "policies.h"
Sebastian Hahn's avatar
Sebastian Hahn committed
31
#include "reasons.h"
Sebastian Hahn's avatar
Sebastian Hahn committed
32
#include "relay.h"
Sebastian Hahn's avatar
Sebastian Hahn committed
33
#include "rendclient.h"
Sebastian Hahn's avatar
Sebastian Hahn committed
34
#include "rendcommon.h"
Sebastian Hahn's avatar
Sebastian Hahn committed
35
#include "rendservice.h"
Sebastian Hahn's avatar
Sebastian Hahn committed
36
#include "rephist.h"
Sebastian Hahn's avatar
Sebastian Hahn committed
37
#include "router.h"
Sebastian Hahn's avatar
Sebastian Hahn committed
38
#include "routerlist.h"
39
#include "routerset.h"
40

41
42
43
#ifdef HAVE_LINUX_TYPES_H
#include <linux/types.h>
#endif
44
45
46
47
48
49
50
51
52
53
54
#ifdef HAVE_LINUX_NETFILTER_IPV4_H
#include <linux/netfilter_ipv4.h>
#define TRANS_NETFILTER
#endif

#if defined(HAVE_NET_IF_H) && defined(HAVE_NET_PFVAR_H)
#include <net/if.h>
#include <net/pfvar.h>
#define TRANS_PF
#endif

55
56
57
#define SOCKS4_GRANTED          90
#define SOCKS4_REJECT           91

58
59
static int connection_ap_handshake_process_socks(entry_connection_t *conn);
static int connection_ap_process_natd(entry_connection_t *conn);
Roger Dingledine's avatar
Roger Dingledine committed
60
static int connection_exit_connect_dir(edge_connection_t *exitconn);
61
62
static int consider_plaintext_ports(entry_connection_t *conn, uint16_t port);
static int connection_ap_supports_optimistic_data(const entry_connection_t *);
63

64
65
66
67
68
/** An AP stream has failed/finished. If it hasn't already sent back
 * a socks reply, send one now (based on endreason). Also set
 * has_sent_end to 1, and mark the conn.
 */
void
69
connection_mark_unattached_ap_(entry_connection_t *conn, int endreason,
70
71
                               int line, const char *file)
{
72
  connection_t *base_conn = ENTRY_TO_CONN(conn);
73
  edge_connection_t *edge_conn = ENTRY_TO_EDGE_CONN(conn);
74
75
  tor_assert(base_conn->type == CONN_TYPE_AP);
  ENTRY_TO_EDGE_CONN(conn)->edge_has_sent_end = 1; /* no circ yet */
76

77
78
79
80
  /* If this is a rendezvous stream and it is failing without ever
   * being attached to a circuit, assume that an attempt to connect to
   * the destination hidden service has just ended.
   *
81
   * XXXX This condition doesn't limit to only streams failing
82
83
   * without ever being attached.  That sloppiness should be harmless,
   * but we should fix it someday anyway. */
84
85
86
87
  if ((edge_conn->on_circuit != NULL || edge_conn->edge_has_sent_end) &&
      connection_edge_is_rendezvous_stream(edge_conn)) {
    rend_client_note_connection_attempt_ended(
                                    edge_conn->rend_data->onion_address);
88
89
  }

90
  if (base_conn->marked_for_close) {
91
    /* This call will warn as appropriate. */
92
    connection_mark_for_close_(base_conn, line, file);
93
94
95
    return;
  }

96
  if (!conn->socks_request->has_finished) {
97
    if (endreason & END_STREAM_REASON_FLAG_ALREADY_SOCKS_REPLIED)
Roger Dingledine's avatar
Roger Dingledine committed
98
      log_warn(LD_BUG,
99
               "stream (marked at %s:%d) sending two socks replies?",
Roger Dingledine's avatar
Roger Dingledine committed
100
               file, line);
101

102
    if (SOCKS_COMMAND_IS_CONNECT(conn->socks_request->command))
103
      connection_ap_handshake_socks_reply(conn, NULL, 0, endreason);
104
    else if (SOCKS_COMMAND_IS_RESOLVE(conn->socks_request->command))
105
106
      connection_ap_handshake_socks_resolved(conn,
                                             RESOLVED_TYPE_ERROR_TRANSIENT,
107
                                             0, NULL, -1, -1);
108
109
    else /* unknown or no handshake at all. send no response. */
      conn->socks_request->has_finished = 1;
110
  }
111

112
  connection_mark_and_flush_(base_conn, line, file);
113

114
  ENTRY_TO_EDGE_CONN(conn)->end_reason = endreason;
115
116
}

117
118
/** There was an EOF. Send an end and mark the connection for close.
 */
119
int
120
connection_edge_reached_eof(edge_connection_t *conn)
121
{
122
  if (connection_get_inbuf_len(TO_CONN(conn)) &&
123
      connection_state_is_open(TO_CONN(conn))) {
Roger Dingledine's avatar
Roger Dingledine committed
124
125
126
    /* it still has stuff to process. don't let it die yet. */
    return 0;
  }
127
128
  log_info(LD_EDGE,"conn (fd %d) reached eof. Closing.", conn->base_.s);
  if (!conn->base_.marked_for_close) {
129
130
    /* only mark it if not already marked. it's possible to
     * get the 'end' right around when the client hangs up on us. */
131
    connection_edge_end(conn, END_STREAM_REASON_DONE);
132
    if (conn->base_.type == CONN_TYPE_AP) {
133
134
135
136
      /* eof, so don't send a socks reply back */
      if (EDGE_TO_ENTRY_CONN(conn)->socks_request)
        EDGE_TO_ENTRY_CONN(conn)->socks_request->has_finished = 1;
    }
137
    connection_mark_for_close(TO_CONN(conn));
138
139
140
141
142
  }
  return 0;
}

/** Handle new bytes on conn->inbuf based on state:
143
144
 *   - If it's waiting for socks info, try to read another step of the
 *     socks handshake out of conn->inbuf.
145
 *   - If it's waiting for the original destination, fetch it.
146
147
148
149
 *   - If it's open, then package more relay cells from the stream.
 *   - Else, leave the bytes on inbuf alone for now.
 *
 * Mark and return -1 if there was an unexpected error with the conn,
150
151
 * else return 0.
 */
152
int
153
connection_edge_process_inbuf(edge_connection_t *conn, int package_partial)
154
{
Roger Dingledine's avatar
Roger Dingledine committed
155
  tor_assert(conn);
156

157
  switch (conn->base_.state) {
158
    case AP_CONN_STATE_SOCKS_WAIT:
159
      if (connection_ap_handshake_process_socks(EDGE_TO_ENTRY_CONN(conn)) <0) {
160
        /* already marked */
161
162
163
        return -1;
      }
      return 0;
164
    case AP_CONN_STATE_NATD_WAIT:
165
      if (connection_ap_process_natd(EDGE_TO_ENTRY_CONN(conn)) < 0) {
166
167
168
169
        /* already marked */
        return -1;
      }
      return 0;
170
171
    case AP_CONN_STATE_OPEN:
    case EXIT_CONN_STATE_OPEN:
172
      if (connection_edge_package_raw_inbuf(conn, package_partial, NULL) < 0) {
173
        /* (We already sent an end cell if possible) */
174
        connection_mark_for_close(TO_CONN(conn));
175
176
        return -1;
      }
177
      return 0;
178
    case AP_CONN_STATE_CONNECT_WAIT:
179
      if (connection_ap_supports_optimistic_data(EDGE_TO_ENTRY_CONN(conn))) {
180
181
182
        log_info(LD_EDGE,
                 "data from edge while in '%s' state. Sending it anyway. "
                 "package_partial=%d, buflen=%ld",
183
                 conn_state_to_string(conn->base_.type, conn->base_.state),
184
185
                 package_partial,
                 (long)connection_get_inbuf_len(TO_CONN(conn)));
186
187
188
189
190
191
192
193
194
        if (connection_edge_package_raw_inbuf(conn, package_partial, NULL)<0) {
          /* (We already sent an end cell if possible) */
          connection_mark_for_close(TO_CONN(conn));
          return -1;
        }
        return 0;
      }
      /* Fall through if the connection is on a circuit without optimistic
       * data support. */
195
    case EXIT_CONN_STATE_CONNECTING:
196
    case AP_CONN_STATE_RENDDESC_WAIT:
197
    case AP_CONN_STATE_CIRCUIT_WAIT:
198
    case AP_CONN_STATE_RESOLVE_WAIT:
199
    case AP_CONN_STATE_CONTROLLER_WAIT:
Roger Dingledine's avatar
Roger Dingledine committed
200
201
      log_info(LD_EDGE,
               "data from edge while in '%s' state. Leaving it on buffer.",
202
               conn_state_to_string(conn->base_.type, conn->base_.state));
203
204
      return 0;
  }
205
  log_warn(LD_BUG,"Got unexpected state %d. Closing.",conn->base_.state);
206
  tor_fragile_assert();
207
  connection_edge_end(conn, END_STREAM_REASON_INTERNAL);
208
  connection_mark_for_close(TO_CONN(conn));
209
  return -1;
210
211
}

212
213
214
/** This edge needs to be closed, because its circuit has closed.
 * Mark it for close and return 0.
 */
215
int
216
connection_edge_destroy(circid_t circ_id, edge_connection_t *conn)
217
{
218
  if (!conn->base_.marked_for_close) {
Roger Dingledine's avatar
Roger Dingledine committed
219
220
    log_info(LD_EDGE,
             "CircID %d: At an edge. Marking connection for close.", circ_id);
221
    if (conn->base_.type == CONN_TYPE_AP) {
222
223
      entry_connection_t *entry_conn = EDGE_TO_ENTRY_CONN(conn);
      connection_mark_unattached_ap(entry_conn, END_STREAM_REASON_DESTROY);
224
      control_event_stream_bandwidth(conn);
225
      control_event_stream_status(entry_conn, STREAM_EVENT_CLOSED,
226
227
                                  END_STREAM_REASON_DESTROY);
      conn->end_reason |= END_STREAM_REASON_FLAG_ALREADY_SENT_CLOSED;
228
    } else {
229
      /* closing the circuit, nothing to send an END to */
230
      conn->edge_has_sent_end = 1;
231
      conn->end_reason = END_STREAM_REASON_DESTROY;
232
      conn->end_reason |= END_STREAM_REASON_FLAG_ALREADY_SENT_CLOSED;
233
      connection_mark_and_flush(TO_CONN(conn));
234
    }
235
  }
236
  conn->cpath_layer = NULL;
237
  conn->on_circuit = NULL;
238
239
240
  return 0;
}

241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
/** Send a raw end cell to the stream with ID <b>stream_id</b> out over the
 * <b>circ</b> towards the hop identified with <b>cpath_layer</b>. If this
 * is not a client connection, set the relay end cell's reason for closing
 * as <b>reason</b> */
static int
relay_send_end_cell_from_edge(streamid_t stream_id, circuit_t *circ,
                              uint8_t reason, crypt_path_t *cpath_layer)
{
  char payload[1];

  if (CIRCUIT_PURPOSE_IS_CLIENT(circ->purpose)) {
    /* Never send the server an informative reason code; it doesn't need to
     * know why the client stream is failing. */
    reason = END_STREAM_REASON_MISC;
  }

  payload[0] = (char) reason;

  return relay_send_command_from_edge(stream_id, circ, RELAY_COMMAND_END,
                                      payload, 1, cpath_layer);
}

/** Send a relay end cell from stream <b>conn</b> down conn's circuit, and
 * remember that we've done so.  If this is not a client connection, set the
 * relay end cell's reason for closing as <b>reason</b>.
266
267
268
269
 *
 * Return -1 if this function has already been called on this conn,
 * else return 0.
 */
270
int
271
connection_edge_end(edge_connection_t *conn, uint8_t reason)
272
{
273
  char payload[RELAY_PAYLOAD_SIZE];
274
  size_t payload_len=1;
275
  circuit_t *circ;
Mike Perry's avatar
   
Mike Perry committed
276
  uint8_t control_reason = reason;
277

278
  if (conn->edge_has_sent_end) {
279
    log_warn(LD_BUG,"(Harmless.) Calling connection_edge_end (reason %d) "
Roger Dingledine's avatar
Roger Dingledine committed
280
             "on an already ended stream?", reason);
281
    tor_fragile_assert();
282
    return -1;
283
284
  }

285
  if (conn->base_.marked_for_close) {
Roger Dingledine's avatar
Roger Dingledine committed
286
    log_warn(LD_BUG,
287
             "called on conn that's already marked for close at %s:%d.",
288
             conn->base_.marked_for_close_file, conn->base_.marked_for_close);
289
290
291
    return 0;
  }

292
293
294
295
296
297
298
299
300
  circ = circuit_get_by_edge_conn(conn);
  if (circ && CIRCUIT_PURPOSE_IS_CLIENT(circ->purpose)) {
    /* If this is a client circuit, don't send the server an informative
     * reason code; it doesn't need to know why the client stream is
     * failing. */
    reason = END_STREAM_REASON_MISC;
  }

  payload[0] = (char)reason;
301
302
  if (reason == END_STREAM_REASON_EXITPOLICY &&
      !connection_edge_is_rendezvous_stream(conn)) {
303
    int addrlen;
304
305
    if (tor_addr_family(&conn->base_.addr) == AF_INET) {
      set_uint32(payload+1, tor_addr_to_ipv4n(&conn->base_.addr));
306
307
      addrlen = 4;
    } else {
308
      memcpy(payload+1, tor_addr_to_in6_addr8(&conn->base_.addr), 16);
309
310
311
312
      addrlen = 16;
    }
    set_uint32(payload+1+addrlen, htonl(dns_clip_ttl(conn->address_ttl)));
    payload_len += 4+addrlen;
313
314
  }

315
  if (circ && !circ->marked_for_close) {
316
    log_debug(LD_EDGE,"Sending end on conn (fd %d).",conn->base_.s);
317
    connection_edge_send_command(conn, RELAY_COMMAND_END,
318
                                 payload, payload_len);
319
  } else {
320
    log_debug(LD_EDGE,"No circ to send end on conn (fd %d).",
321
              conn->base_.s);
322
323
  }

324
  conn->edge_has_sent_end = 1;
Mike Perry's avatar
   
Mike Perry committed
325
  conn->end_reason = control_reason;
326
  return 0;
327
328
}

Nick Mathewson's avatar
Nick Mathewson committed
329
/** An error has just occurred on an operation on an edge connection
330
331
 * <b>conn</b>.  Extract the errno; convert it to an end reason, and send an
 * appropriate relay end cell to the other end of the connection's circuit.
332
 **/
333
int
334
connection_edge_end_errno(edge_connection_t *conn)
335
336
337
{
  uint8_t reason;
  tor_assert(conn);
338
  reason = errno_to_stream_end_reason(tor_socket_errno(conn->base_.s));
339
  return connection_edge_end(conn, reason);
340
341
}

342
343
344
345
346
347
348
349
/** We just wrote some data to <b>conn</b>; act appropriately.
 *
 * (That is, if it's open, consider sending a stream-level sendme cell if we
 * have just flushed enough.)
 */
int
connection_edge_flushed_some(edge_connection_t *conn)
{
350
  switch (conn->base_.state) {
351
352
353
354
355
356
357
358
    case AP_CONN_STATE_OPEN:
    case EXIT_CONN_STATE_OPEN:
      connection_edge_consider_sending_sendme(conn);
      break;
  }
  return 0;
}

359
360
361
362
363
364
365
366
367
368
/** Connection <b>conn</b> has finished writing and has no bytes left on
 * its outbuf.
 *
 * If it's in state 'open', stop writing, consider responding with a
 * sendme, and return.
 * Otherwise, stop writing and return.
 *
 * If <b>conn</b> is broken, mark it for close and return -1, else
 * return 0.
 */
369
int
370
connection_edge_finished_flushing(edge_connection_t *conn)
371
{
Roger Dingledine's avatar
Roger Dingledine committed
372
  tor_assert(conn);
373

374
  switch (conn->base_.state) {
375
376
    case AP_CONN_STATE_OPEN:
    case EXIT_CONN_STATE_OPEN:
377
      connection_edge_consider_sending_sendme(conn);
378
      return 0;
Roger Dingledine's avatar
Roger Dingledine committed
379
    case AP_CONN_STATE_SOCKS_WAIT:
380
    case AP_CONN_STATE_NATD_WAIT:
381
    case AP_CONN_STATE_RENDDESC_WAIT:
382
    case AP_CONN_STATE_CIRCUIT_WAIT:
383
    case AP_CONN_STATE_CONNECT_WAIT:
384
    case AP_CONN_STATE_CONTROLLER_WAIT:
385
    case AP_CONN_STATE_RESOLVE_WAIT:
Roger Dingledine's avatar
Roger Dingledine committed
386
      return 0;
387
    default:
388
      log_warn(LD_BUG, "Called in unexpected state %d.",conn->base_.state);
389
      tor_fragile_assert();
390
      return -1;
391
392
393
394
  }
  return 0;
}

395
396
397
/** Longest size for the relay payload of a RELAY_CONNECTED cell that we're
 * able to generate. */
/* 4 zero bytes; 1 type byte; 16 byte IPv6 address; 4 byte TTL. */
398
399
#define MAX_CONNECTED_CELL_PAYLOAD_LEN 25

400
401
402
403
404
405
/** Set the buffer at <b>payload_out</b> -- which must have at least
 * MAX_CONNECTED_CELL_PAYLOAD_LEN bytes available -- to the body of a
 * RELAY_CONNECTED cell indicating that we have connected to <b>addr</b>, and
 * that the name resolution that led us to <b>addr</b> will be valid for
 * <b>ttl</b> seconds. Return -1 on error, or the number of bytes used on
 * success. */
406
407
408
409
410
411
412
413
/* private */int
connected_cell_format_payload(uint8_t *payload_out,
                              const tor_addr_t *addr,
                              uint32_t ttl)
{
  const sa_family_t family = tor_addr_family(addr);
  int connected_payload_len;

414
415
416
  /* should be needless */
  memset(payload_out, 0, MAX_CONNECTED_CELL_PAYLOAD_LEN);

417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
  if (family == AF_INET) {
    set_uint32(payload_out, tor_addr_to_ipv4n(addr));
    connected_payload_len = 4;
  } else if (family == AF_INET6) {
    set_uint32(payload_out, 0);
    set_uint8(payload_out + 4, 6);
    memcpy(payload_out + 5, tor_addr_to_in6_addr8(addr), 16);
    connected_payload_len = 21;
  } else {
    return -1;
  }

  set_uint32(payload_out + connected_payload_len, htonl(dns_clip_ttl(ttl)));
  connected_payload_len += 4;

  tor_assert(connected_payload_len <= MAX_CONNECTED_CELL_PAYLOAD_LEN);

  return connected_payload_len;
}

437
438
439
/** Connected handler for exit connections: start writing pending
 * data, deliver 'CONNECTED' relay cells as appropriate, and check
 * any pending data that may have been received. */
440
int
441
connection_edge_finished_connecting(edge_connection_t *edge_conn)
442
{
443
  connection_t *conn;
444

445
  tor_assert(edge_conn);
446
  tor_assert(edge_conn->base_.type == CONN_TYPE_EXIT);
447
  conn = TO_CONN(edge_conn);
448
449
  tor_assert(conn->state == EXIT_CONN_STATE_CONNECTING);

Roger Dingledine's avatar
Roger Dingledine committed
450
  log_info(LD_EXIT,"Exit connection to %s:%u (%s) established.",
451
           escaped_safe_str(conn->address), conn->port,
452
           safe_str(fmt_and_decorate_addr(&conn->addr)));
453

454
  rep_hist_note_exit_stream_opened(conn->port);
455

456
  conn->state = EXIT_CONN_STATE_OPEN;
457
458
459
  IF_HAS_NO_BUFFEREVENT(conn)
    connection_watch_events(conn, READ_EVENT); /* stop writing, keep reading */
  if (connection_get_outbuf_len(conn)) /* in case there are any queued relay
460
                                        * cells */
461
462
    connection_start_writing(conn);
  /* deliver a 'connected' relay cell back through the circuit. */
463
464
  if (connection_edge_is_rendezvous_stream(edge_conn)) {
    if (connection_edge_send_command(edge_conn,
465
                                     RELAY_COMMAND_CONNECTED, NULL, 0) < 0)
466
467
      return 0; /* circuit is closed, don't continue */
  } else {
468
469
470
471
472
473
474
    uint8_t connected_payload[MAX_CONNECTED_CELL_PAYLOAD_LEN];
    int connected_payload_len =
      connected_cell_format_payload(connected_payload, &conn->addr,
                                    edge_conn->address_ttl);
    if (connected_payload_len < 0)
      return -1;

475
    if (connection_edge_send_command(edge_conn,
476
477
                        RELAY_COMMAND_CONNECTED,
                        (char*)connected_payload, connected_payload_len) < 0)
478
479
      return 0; /* circuit is closed, don't continue */
  }
480
  tor_assert(edge_conn->package_window > 0);
481
  /* in case the server has written anything */
482
  return connection_edge_process_inbuf(edge_conn, 1);
483
484
}

485
486
487
488
489
490
491
492
493
494
495
496
497
/** Common code to connection_(ap|exit)_about_to_close. */
static void
connection_edge_about_to_close(edge_connection_t *edge_conn)
{
  if (!edge_conn->edge_has_sent_end) {
    connection_t *conn = TO_CONN(edge_conn);
    log_warn(LD_BUG, "(Harmless.) Edge connection (marked at %s:%d) "
             "hasn't sent end yet?",
             conn->marked_for_close_file, conn->marked_for_close);
    tor_fragile_assert();
  }
}

498
/** Called when we're about to finally unlink and free an AP (client)
499
500
 * connection: perform necessary accounting and cleanup */
void
501
connection_ap_about_to_close(entry_connection_t *entry_conn)
502
503
{
  circuit_t *circ;
504
505
  edge_connection_t *edge_conn = ENTRY_TO_EDGE_CONN(entry_conn);
  connection_t *conn = ENTRY_TO_CONN(entry_conn);
506

507
  if (entry_conn->socks_request->has_finished == 0) {
508
509
510
511
512
513
514
515
516
517
518
    /* since conn gets removed right after this function finishes,
     * there's no point trying to send back a reply at this point. */
    log_warn(LD_BUG,"Closing stream (marked at %s:%d) without sending"
             " back a socks reply.",
             conn->marked_for_close_file, conn->marked_for_close);
  }
  if (!edge_conn->end_reason) {
    log_warn(LD_BUG,"Closing stream (marked at %s:%d) without having"
             " set end_reason.",
             conn->marked_for_close_file, conn->marked_for_close);
  }
519
  if (entry_conn->dns_server_request) {
520
521
522
    log_warn(LD_BUG,"Closing stream (marked at %s:%d) without having"
             " replied to DNS request.",
             conn->marked_for_close_file, conn->marked_for_close);
523
    dnsserv_reject_request(entry_conn);
524
525
  }
  control_event_stream_bandwidth(edge_conn);
526
  control_event_stream_status(entry_conn, STREAM_EVENT_CLOSED,
527
528
529
530
531
532
                              edge_conn->end_reason);
  circ = circuit_get_by_edge_conn(edge_conn);
  if (circ)
    circuit_detach_stream(circ, edge_conn);
}

533
/** Called when we're about to finally unlink and free an exit
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
 * connection: perform necessary accounting and cleanup */
void
connection_exit_about_to_close(edge_connection_t *edge_conn)
{
  circuit_t *circ;
  connection_t *conn = TO_CONN(edge_conn);

  connection_edge_about_to_close(edge_conn);

  circ = circuit_get_by_edge_conn(edge_conn);
  if (circ)
    circuit_detach_stream(circ, edge_conn);
  if (conn->state == EXIT_CONN_STATE_RESOLVING) {
    connection_dns_remove(edge_conn);
  }
}

551
552
/** Define a schedule for how long to wait between retrying
 * application connections. Rather than waiting a fixed amount of
553
 * time between each retry, we wait 10 seconds each for the first
554
 * two tries, and 15 seconds for each retry after
555
 * that. Hopefully this will improve the expected user experience. */
556
static int
557
compute_retry_timeout(entry_connection_t *conn)
558
{
559
560
561
  int timeout = get_options()->CircuitStreamTimeout;
  if (timeout) /* if our config options override the default, use them */
    return timeout;
562
  if (conn->num_socks_retries < 2) /* try 0 and try 1 */
563
564
565
566
    return 10;
  return 15;
}

567
/** Find all general-purpose AP streams waiting for a response that sent their
568
 * begin/resolve cell too long ago. Detach from their current circuit, and
569
 * mark their current circuit as unsuitable for new streams. Then call
570
571
572
 * connection_ap_handshake_attach_circuit() to attach to a new circuit (if
 * available) or launch a new one.
 *
573
 * For rendezvous streams, simply give up after SocksTimeout seconds (with no
574
575
 * retry attempt).
 */
576
577
578
void
connection_ap_expire_beginning(void)
{
579
  edge_connection_t *conn;
580
  entry_connection_t *entry_conn;
581
  circuit_t *circ;
582
  time_t now = time(NULL);
583
  const or_options_t *options = get_options();
584
  int severity;
585
  int cutoff;
586
  int seconds_idle, seconds_since_born;
587
  smartlist_t *conns = get_connection_array();
588

589
590
  SMARTLIST_FOREACH_BEGIN(conns, connection_t *, base_conn) {
    if (base_conn->type != CONN_TYPE_AP || base_conn->marked_for_close)
591
      continue;
592
593
    entry_conn = TO_ENTRY_CONN(base_conn);
    conn = ENTRY_TO_EDGE_CONN(entry_conn);
594
    /* if it's an internal linked connection, don't yell its status. */
595
    severity = (tor_addr_is_null(&base_conn->addr) && !base_conn->port)
596
      ? LOG_INFO : LOG_NOTICE;
597
598
    seconds_idle = (int)( now - base_conn->timestamp_lastread );
    seconds_since_born = (int)( now - base_conn->timestamp_created );
599

600
    if (base_conn->state == AP_CONN_STATE_OPEN)
601
602
603
604
605
606
      continue;

    /* We already consider SocksTimeout in
     * connection_ap_handshake_attach_circuit(), but we need to consider
     * it here too because controllers that put streams in controller_wait
     * state never ask Tor to attach the circuit. */
607
    if (AP_CONN_STATE_IS_UNATTACHED(base_conn->state)) {
608
      if (seconds_since_born >= options->SocksTimeout) {
609
610
611
        log_fn(severity, LD_APP,
            "Tried for %d seconds to get a connection to %s:%d. "
            "Giving up. (%s)",
612
            seconds_since_born,
613
614
615
616
            safe_str_client(entry_conn->socks_request->address),
            entry_conn->socks_request->port,
            conn_state_to_string(CONN_TYPE_AP, base_conn->state));
        connection_mark_unattached_ap(entry_conn, END_STREAM_REASON_TIMEOUT);
617
618
619
620
      }
      continue;
    }

621
622
623
    /* We're in state connect_wait or resolve_wait now -- waiting for a
     * reply to our relay cell. See if we want to retry/give up. */

624
    cutoff = compute_retry_timeout(entry_conn);
625
    if (seconds_idle < cutoff)
626
      continue;
627
    circ = circuit_get_by_edge_conn(conn);
628
    if (!circ) { /* it's vanished? */
Roger Dingledine's avatar
Roger Dingledine committed
629
      log_info(LD_APP,"Conn is waiting (address %s), but lost its circ.",
630
631
               safe_str_client(entry_conn->socks_request->address));
      connection_mark_unattached_ap(entry_conn, END_STREAM_REASON_TIMEOUT);
632
633
      continue;
    }
634
    if (circ->purpose == CIRCUIT_PURPOSE_C_REND_JOINED) {
635
      if (seconds_idle >= options->SocksTimeout) {
636
637
638
        log_fn(severity, LD_REND,
               "Rend stream is %d seconds late. Giving up on address"
               " '%s.onion'.",
639
               seconds_idle,
640
               safe_str_client(entry_conn->socks_request->address));
641
        connection_edge_end(conn, END_STREAM_REASON_TIMEOUT);
642
        connection_mark_unattached_ap(entry_conn, END_STREAM_REASON_TIMEOUT);
643
644
645
      }
      continue;
    }
Roger Dingledine's avatar
Roger Dingledine committed
646
    tor_assert(circ->purpose == CIRCUIT_PURPOSE_C_GENERAL);
647
    log_fn(cutoff < 15 ? LOG_INFO : severity, LD_APP,
648
           "We tried for %d seconds to connect to '%s' using exit %s."
649
           " Retrying on a new circuit.",
650
           seconds_idle,
651
           safe_str_client(entry_conn->socks_request->address),
652
           conn->cpath_layer ?
653
654
             extend_info_describe(conn->cpath_layer->extend_info):
             "*unnamed*");
655
    /* send an end down the circuit */
656
    connection_edge_end(conn, END_STREAM_REASON_TIMEOUT);
657
    /* un-mark it as ending, since we're going to reuse it */
658
    conn->edge_has_sent_end = 0;
659
    conn->end_reason = 0;
660
661
662
    /* kludge to make us not try this circuit again, yet to allow
     * current streams on it to survive if they can: make it
     * unattractive to use for new streams */
663
    /* XXXX024 this is a kludgy way to do this. */
664
    tor_assert(circ->timestamp_dirty);
665
    circ->timestamp_dirty -= options->MaxCircuitDirtiness;
666
    /* give our stream another 'cutoff' seconds to try */
667
    conn->base_.timestamp_lastread += cutoff;
668
669
    if (entry_conn->num_socks_retries < 250) /* avoid overflow */
      entry_conn->num_socks_retries++;
670
    /* move it back into 'pending' state, and try to attach. */
671
    if (connection_ap_detach_retriable(entry_conn, TO_ORIGIN_CIRCUIT(circ),
672
                                       END_STREAM_REASON_TIMEOUT)<0) {
673
      if (!base_conn->marked_for_close)
674
675
        connection_mark_unattached_ap(entry_conn,
                                      END_STREAM_REASON_CANT_ATTACH);
676
    }
677
  } SMARTLIST_FOREACH_END(base_conn);
678
679
}

680
681
/** Tell any AP streams that are waiting for a new circuit to try again,
 * either attaching to an available circ or launching a new one.
682
 */
683
684
void
connection_ap_attach_pending(void)
685
{
686
  entry_connection_t *entry_conn;
687
  smartlist_t *conns = get_connection_array();
688
  SMARTLIST_FOREACH_BEGIN(conns, connection_t *, conn) {
Roger Dingledine's avatar
Roger Dingledine committed
689
690
    if (conn->marked_for_close ||
        conn->type != CONN_TYPE_AP ||
691
        conn->state != AP_CONN_STATE_CIRCUIT_WAIT)
692
      continue;
693
694
695
696
    entry_conn = TO_ENTRY_CONN(conn);
    if (connection_ap_handshake_attach_circuit(entry_conn) < 0) {
      if (!conn->marked_for_close)
        connection_mark_unattached_ap(entry_conn,
697
                                      END_STREAM_REASON_CANT_ATTACH);
698
    }
699
  } SMARTLIST_FOREACH_END(conn);
700
701
}

Nick Mathewson's avatar
Nick Mathewson committed
702
/** Tell any AP streams that are waiting for a one-hop tunnel to
703
 * <b>failed_digest</b> that they are going to fail. */
704
/* XXX024 We should get rid of this function, and instead attach
Nick Mathewson's avatar
Nick Mathewson committed
705
 * one-hop streams to circ->p_streams so they get marked in
706
707
 * circuit_mark_for_close like normal p_streams. */
void
708
709
connection_ap_fail_onehop(const char *failed_digest,
                          cpath_build_state_t *build_state)
710
{
711
  entry_connection_t *entry_conn;
712
713
  char digest[DIGEST_LEN];
  smartlist_t *conns = get_connection_array();
714
  SMARTLIST_FOREACH_BEGIN(conns, connection_t *, conn) {
715
716
717
718
    if (conn->marked_for_close ||
        conn->type != CONN_TYPE_AP ||
        conn->state != AP_CONN_STATE_CIRCUIT_WAIT)
      continue;
719
720
    entry_conn = TO_ENTRY_CONN(conn);
    if (!entry_conn->want_onehop)
721
      continue;
722
    if (hexdigest_to_digest(entry_conn->chosen_exit_name, digest) < 0 ||
723
        tor_memneq(digest, failed_digest, DIGEST_LEN))
724
725
726
      continue;
    if (tor_digest_is_zero(digest)) {
      /* we don't know the digest; have to compare addr:port */
727
      tor_addr_t addr;
728
      if (!build_state || !build_state->chosen_exit ||
729
          !entry_conn->socks_request || !entry_conn->socks_request->address)
730
        continue;
731
      if (tor_addr_parse(&addr, entry_conn->socks_request->address)<0 ||
732
          !tor_addr_eq(&build_state->chosen_exit->addr, &addr) ||
733
          build_state->chosen_exit->port != entry_conn->socks_request->port)
734
        continue;
735
    }
Nick Mathewson's avatar
Nick Mathewson committed
736
    log_info(LD_APP, "Closing one-hop stream to '%s/%s' because the OR conn "
737
738
739
                     "just failed.", entry_conn->chosen_exit_name,
                     entry_conn->socks_request->address);
    connection_mark_unattached_ap(entry_conn, END_STREAM_REASON_TIMEOUT);
740
  } SMARTLIST_FOREACH_END(conn);
741
742
}

743
744
745
746
747
748
749
/** A circuit failed to finish on its last hop <b>info</b>. If there
 * are any streams waiting with this exit node in mind, but they
 * don't absolutely require it, make them give up on it.
 */
void
circuit_discard_optional_exit_enclaves(extend_info_t *info)
{
750
  entry_connection_t *entry_conn;
751
  const node_t *r1, *r2;
752

753
  smartlist_t *conns = get_connection_array();
754
  SMARTLIST_FOREACH_BEGIN(conns, connection_t *, conn) {
755
756
    if (conn->marked_for_close ||
        conn->type != CONN_TYPE_AP ||
757
        conn->state != AP_CONN_STATE_CIRCUIT_WAIT)
758
      continue;
759
760
761
    entry_conn = TO_ENTRY_CONN(conn);
    if (!entry_conn->chosen_exit_optional &&
        !entry_conn->chosen_exit_retries)
762
      continue;
763
    r1 = node_get_by_nickname(entry_conn->chosen_exit_name, 0);
764
    r2 = node_get_by_id(info->identity_digest);
765
766
    if (!r1 || !r2 || r1 != r2)
      continue;
767
768
    tor_assert(entry_conn->socks_request);
    if (entry_conn->chosen_exit_optional) {
769
      log_info(LD_APP, "Giving up on enclave exit '%s' for destination %s.",
770
771
772
773
               safe_str_client(entry_conn->chosen_exit_name),
               escaped_safe_str_client(entry_conn->socks_request->address));
      entry_conn->chosen_exit_optional = 0;
      tor_free(entry_conn->chosen_exit_name); /* clears it */
774
775
      /* if this port is dangerous, warn or reject it now that we don't
       * think it'll be using an enclave. */
776
      consider_plaintext_ports(entry_conn, entry_conn->socks_request->port);
777
    }
778
779
780
781
    if (entry_conn->chosen_exit_retries) {
      if (--entry_conn->chosen_exit_retries == 0) { /* give up! */
        clear_trackexithost_mappings(entry_conn->chosen_exit_name);
        tor_free(entry_conn->chosen_exit_name); /* clears it */
782
783
        /* if this port is dangerous, warn or reject it now that we don't
         * think it'll be using an enclave. */
784
        consider_plaintext_ports(entry_conn, entry_conn->socks_request->port);
785
786
      }
    }
787
  } SMARTLIST_FOREACH_END(conn);
788
789
}

790
791
/** The AP connection <b>conn</b> has just failed while attaching or
 * sending a BEGIN or resolving on <b>circ</b>, but another circuit
792
 * might work. Detach the circuit, and either reattach it, launch a
793
794
795
 * new circuit, tell the controller, or give up as a appropriate.
 *
 * Returns -1 on err, 1 on success, 0 on not-yet-sure.
796
797
 */
int
798
799
connection_ap_detach_retriable(entry_connection_t *conn,
                               origin_circuit_t *circ,
800
                               int reason)
801
{
802
  control_event_stream_status(conn, STREAM_EVENT_FAILED_RETRIABLE, reason);
803
  ENTRY_TO_CONN(conn)->timestamp_lastread = time(NULL);
804
805
806
807
808
809

  if (conn->pending_optimistic_data) {
    generic_buffer_set_to_copy(&conn->sending_optimistic_data,
                               conn->pending_optimistic_data);
  }

810
811
812
  if (!get_options()->LeaveStreamsUnattached || conn->use_begindir) {
    /* If we're attaching streams ourself, or if this connection is
     * a tunneled directory connection, then just attach it. */
813
814
    ENTRY_TO_CONN(conn)->state = AP_CONN_STATE_CIRCUIT_WAIT;
    circuit_detach_stream(TO_CIRCUIT(circ),ENTRY_TO_EDGE_CONN(conn));
815
816
    return connection_ap_handshake_attach_circuit(conn);
  } else {
817
818
    ENTRY_TO_CONN(conn)->state = AP_CONN_STATE_CONTROLLER_WAIT;
    circuit_detach_stream(TO_CIRCUIT(circ),ENTRY_TO_EDGE_CONN(conn));
819
820
821
822
    return 0;
  }
}

823
824
825
/** Check if <b>conn</b> is using a dangerous port. Then warn and/or
 * reject depending on our config options. */
static int
826
consider_plaintext_ports(entry_connection_t *conn, uint16_t port)
827
{
828
  const or_options_t *options = get_options();
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
  int reject = smartlist_string_num_isin(options->RejectPlaintextPorts, port);

  if (smartlist_string_num_isin(options->WarnPlaintextPorts, port)) {
    log_warn(LD_APP, "Application request to port %d: this port is "
             "commonly used for unencrypted protocols. Please make sure "
             "you don't send anything you would mind the rest of the "
             "Internet reading!%s", port, reject ? " Closing." : "");
    control_event_client_status(LOG_WARN, "DANGEROUS_PORT PORT=%d RESULT=%s",
                                port, reject ? "REJECT" : "WARN");
  }

  if (reject) {
    log_info(LD_APP, "Port %d listed in RejectPlaintextPorts. Closing.", port);
    connection_mark_unattached_ap(conn, END_STREAM_REASON_ENTRYPOLICY);
    return -1;
  }

  return 0;
}

Nick Mathewson's avatar
Nick Mathewson committed
849
850
851
852
853
/** How many times do we try connecting with an exit configured via
 * TrackHostExits before concluding that it won't work any more and trying a
 * different one? */
#define TRACKHOSTEXITS_RETRIES 5

854
/** Call connection_ap_handshake_rewrite_and_attach() unless a controller
855
856
857
858
 *  asked us to leave streams unattached. Return 0 in that case.
 *
 *  See connection_ap_handshake_rewrite_and_attach()'s
 *  documentation for arguments and return value.
859
860
 */
int
861
connection_ap_rewrite_and_attach_if_allowed(entry_connection_t *conn,
862
863
864
                                            origin_circuit_t *circ,
                                            crypt_path_t *cpath)
{
865
  const or_options_t *options = get_options();
866
867

  if (options->LeaveStreamsUnattached) {
868
    ENTRY_TO_CONN(conn)->state = AP_CONN_STATE_CONTROLLER_WAIT;