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

7
8
/**
 * \file connection_edge.c
9
 * \brief Handle edge streams.
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
 *
 * An edge_connection_t is a subtype of a connection_t, and represents two
 * critical concepts in Tor: a stream, and an edge connection.  From the Tor
 * protocol's point of view, a stream is a bi-directional channel that is
 * multiplexed on a single circuit.  Each stream on a circuit is identified
 * with a separate 16-bit stream ID, local to the (circuit,exit) pair.
 * Streams are created in response to client requests.
 *
 * An edge connection is one thing that can implement a stream: it is either a
 * TCP application socket that has arrived via (e.g.) a SOCKS request, or an
 * exit connection.
 *
 * Not every instance of edge_connection_t truly represents an edge connction,
 * however. (Sorry!) We also create edge_connection_t objects for streams that
 * we will not be handling with TCP.  The types of these streams are:
 *   <ul>
 *   <li>DNS lookup streams, created on the client side in response to
 *     a UDP DNS request received on a DNSPort, or a RESOLVE command
 *     on a controller.
 *   <li>DNS lookup streams, created on the exit side in response to
 *     a RELAY_RESOLVE cell from a client.
 *   <li>Tunneled directory streams, created on the directory cache side
32
 *     in response to a RELAY_BEGIN_DIR cell.  These streams attach directly
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
 *     to a dir_connection_t object without ever using TCP.
 *   </ul>
 *
 * This module handles general-purpose functionality having to do with
 * edge_connection_t.  On the client side, it accepts various types of
 * application requests on SocksPorts, TransPorts, and NATDPorts, and
 * creates streams appropriately.
 *
 * This module is also responsible for implementing stream isolation:
 * ensuring that streams that should not be linkable to one another are
 * kept to different circuits.
 *
 * On the exit side, this module handles the various stream-creating
 * type of RELAY cells by launching appropriate outgoing connections,
 * DNS requests, or directory connection objects.
 *
 * And for all edge connections, this module is responsible for handling
 * incoming and outdoing data as it arrives or leaves in the relay.c
 * module.  (Outgoing data will be packaged in
 * connection_edge_process_inbuf() as it calls
 * connection_edge_package_raw_inbuf(); incoming data from RELAY_DATA
 * cells is applied in connection_edge_process_relay_cell().)
55
 **/
56
#define CONNECTION_EDGE_PRIVATE
57

58
#include "core/or/or.h"
59

60
#include "lib/err/backtrace.h"
61

62
#include "feature/client/addressmap.h"
63
#include "lib/container/buffers.h"
64
65
66
67
68
69
70
71
72
#include "core/or/channel.h"
#include "feature/client/circpathbias.h"
#include "core/or/circuitlist.h"
#include "core/or/circuituse.h"
#include "app/config/config.h"
#include "core/mainloop/connection.h"
#include "core/or/connection_edge.h"
#include "core/or/connection_or.h"
#include "feature/control/control.h"
73
#include "lib/crypt_ops/crypto_util.h"
74
75
76
77
78
79
80
81
82
#include "feature/relay/dns.h"
#include "feature/client/dnsserv.h"
#include "feature/dircache/directory.h"
#include "feature/dircache/dirserv.h"
#include "feature/hibernate/hibernate.h"
#include "feature/hs/hs_common.h"
#include "feature/hs/hs_cache.h"
#include "feature/hs/hs_client.h"
#include "feature/hs/hs_circuit.h"
83
#include "core/mainloop/mainloop.h"
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#include "feature/nodelist/networkstatus.h"
#include "feature/nodelist/nodelist.h"
#include "core/or/policies.h"
#include "core/proto/proto_http.h"
#include "core/proto/proto_socks.h"
#include "core/or/reasons.h"
#include "core/or/relay.h"
#include "feature/rend/rendclient.h"
#include "feature/rend/rendcommon.h"
#include "feature/rend/rendservice.h"
#include "feature/stats/rephist.h"
#include "feature/relay/router.h"
#include "feature/nodelist/routerlist.h"
#include "feature/nodelist/routerset.h"
#include "core/or/circuitbuild.h"
99

100
101
102
103
104
105
106
107
#include "core/or/cell_st.h"
#include "core/or/cpath_build_state_st.h"
#include "feature/dircommon/dir_connection_st.h"
#include "core/or/entry_connection_st.h"
#include "core/or/extend_info_st.h"
#include "feature/nodelist/node_st.h"
#include "core/or/or_circuit_st.h"
#include "core/or/origin_circuit_st.h"
108
#include "core/or/half_edge_st.h"
109
#include "core/or/socks_request_st.h"
110
#include "lib/evloop/compat_libevent.h"
111

112
113
114
#ifdef HAVE_LINUX_TYPES_H
#include <linux/types.h>
#endif
115
116
117
#ifdef HAVE_LINUX_NETFILTER_IPV4_H
#include <linux/netfilter_ipv4.h>
#define TRANS_NETFILTER
118
#define TRANS_NETFILTER_IPV4
119
120
#endif

121
122
123
124
125
126
#ifdef HAVE_LINUX_IF_H
#include <linux/if.h>
#endif

#ifdef HAVE_LINUX_NETFILTER_IPV6_IP6_TABLES_H
#include <linux/netfilter_ipv6/ip6_tables.h>
127
#if defined(IP6T_SO_ORIGINAL_DST)
128
129
130
#define TRANS_NETFILTER
#define TRANS_NETFILTER_IPV6
#endif
131
#endif /* defined(HAVE_LINUX_NETFILTER_IPV6_IP6_TABLES_H) */
132

133
134
135
136
137
138
139
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
#ifdef HAVE_SYS_IOCTL_H
#include <sys/ioctl.h>
#endif

140
141
142
143
144
145
#if defined(HAVE_NET_IF_H) && defined(HAVE_NET_PFVAR_H)
#include <net/if.h>
#include <net/pfvar.h>
#define TRANS_PF
#endif

146
147
148
149
#ifdef IP_TRANSPARENT
#define TRANS_TPROXY
#endif

150
151
152
#define SOCKS4_GRANTED          90
#define SOCKS4_REJECT           91

153
154
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
155
static int connection_exit_connect_dir(edge_connection_t *exitconn);
156
157
static int consider_plaintext_ports(entry_connection_t *conn, uint16_t port);
static int connection_ap_supports_optimistic_data(const entry_connection_t *);
158
159
160
161
162
STATIC void connection_half_edge_add(const edge_connection_t *conn,
                                     origin_circuit_t *circ);
STATIC half_edge_t *connection_half_edge_find_stream_id(
                                    const smartlist_t *half_conns,
                                    streamid_t stream_id);
163

164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
/** Convert a connection_t* to an edge_connection_t*; assert if the cast is
 * invalid. */
edge_connection_t *
TO_EDGE_CONN(connection_t *c)
{
  tor_assert(c->magic == EDGE_CONNECTION_MAGIC ||
             c->magic == ENTRY_CONNECTION_MAGIC);
  return DOWNCAST(edge_connection_t, c);
}

entry_connection_t *
TO_ENTRY_CONN(connection_t *c)
{
  tor_assert(c->magic == ENTRY_CONNECTION_MAGIC);
  return (entry_connection_t*) SUBTYPE_P(c, entry_connection_t, edge_.base_);
}

entry_connection_t *
EDGE_TO_ENTRY_CONN(edge_connection_t *c)
{
  tor_assert(c->base_.magic == ENTRY_CONNECTION_MAGIC);
  return (entry_connection_t*) SUBTYPE_P(c, entry_connection_t, edge_);
}

188
189
190
191
/** 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.
 */
192
193
194
MOCK_IMPL(void,
connection_mark_unattached_ap_,(entry_connection_t *conn, int endreason,
                                int line, const char *file))
195
{
196
  connection_t *base_conn = ENTRY_TO_CONN(conn);
197
  edge_connection_t *edge_conn = ENTRY_TO_EDGE_CONN(conn);
198
199
  tor_assert(base_conn->type == CONN_TYPE_AP);
  ENTRY_TO_EDGE_CONN(conn)->edge_has_sent_end = 1; /* no circ yet */
200

201
202
203
204
  /* 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.
   *
205
   * XXXX This condition doesn't limit to only streams failing
206
207
   * without ever being attached.  That sloppiness should be harmless,
   * but we should fix it someday anyway. */
208
209
  if ((edge_conn->on_circuit != NULL || edge_conn->edge_has_sent_end) &&
      connection_edge_is_rendezvous_stream(edge_conn)) {
210
211
212
    if (edge_conn->rend_data) {
      rend_client_note_connection_attempt_ended(edge_conn->rend_data);
    }
213
214
  }

215
  if (base_conn->marked_for_close) {
216
    /* This call will warn as appropriate. */
217
    connection_mark_for_close_(base_conn, line, file);
218
219
220
    return;
  }

221
  if (!conn->socks_request->has_finished) {
222
    if (endreason & END_STREAM_REASON_FLAG_ALREADY_SOCKS_REPLIED)
Roger Dingledine's avatar
Roger Dingledine committed
223
      log_warn(LD_BUG,
224
               "stream (marked at %s:%d) sending two socks replies?",
Roger Dingledine's avatar
Roger Dingledine committed
225
               file, line);
226

227
    if (SOCKS_COMMAND_IS_CONNECT(conn->socks_request->command))
228
      connection_ap_handshake_socks_reply(conn, NULL, 0, endreason);
229
    else if (SOCKS_COMMAND_IS_RESOLVE(conn->socks_request->command))
230
231
      connection_ap_handshake_socks_resolved(conn,
                                             RESOLVED_TYPE_ERROR_TRANSIENT,
232
                                             0, NULL, -1, -1);
233
234
    else /* unknown or no handshake at all. send no response. */
      conn->socks_request->has_finished = 1;
235
  }
236

237
  connection_mark_and_flush_(base_conn, line, file);
238

239
  ENTRY_TO_EDGE_CONN(conn)->end_reason = endreason;
240
241
}

242
243
/** There was an EOF. Send an end and mark the connection for close.
 */
244
int
245
connection_edge_reached_eof(edge_connection_t *conn)
246
{
247
  if (connection_get_inbuf_len(TO_CONN(conn)) &&
248
      connection_state_is_open(TO_CONN(conn))) {
Roger Dingledine's avatar
Roger Dingledine committed
249
250
251
    /* it still has stuff to process. don't let it die yet. */
    return 0;
  }
252
253
  log_info(LD_EDGE,"conn (fd "TOR_SOCKET_T_FORMAT") reached eof. Closing.",
           conn->base_.s);
254
  if (!conn->base_.marked_for_close) {
255
256
    /* only mark it if not already marked. it's possible to
     * get the 'end' right around when the client hangs up on us. */
257
    connection_edge_end(conn, END_STREAM_REASON_DONE);
258
    if (conn->base_.type == CONN_TYPE_AP) {
259
260
261
262
      /* 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;
    }
263
    connection_mark_for_close(TO_CONN(conn));
264
265
266
267
268
  }
  return 0;
}

/** Handle new bytes on conn->inbuf based on state:
269
270
 *   - If it's waiting for socks info, try to read another step of the
 *     socks handshake out of conn->inbuf.
271
 *   - If it's waiting for the original destination, fetch it.
272
273
274
275
 *   - 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,
276
277
 * else return 0.
 */
278
int
279
connection_edge_process_inbuf(edge_connection_t *conn, int package_partial)
280
{
Roger Dingledine's avatar
Roger Dingledine committed
281
  tor_assert(conn);
282

283
  switch (conn->base_.state) {
284
    case AP_CONN_STATE_SOCKS_WAIT:
285
      if (connection_ap_handshake_process_socks(EDGE_TO_ENTRY_CONN(conn)) <0) {
286
        /* already marked */
287
288
289
        return -1;
      }
      return 0;
290
    case AP_CONN_STATE_NATD_WAIT:
291
      if (connection_ap_process_natd(EDGE_TO_ENTRY_CONN(conn)) < 0) {
292
293
294
295
        /* already marked */
        return -1;
      }
      return 0;
296
297
298
299
300
    case AP_CONN_STATE_HTTP_CONNECT_WAIT:
      if (connection_ap_process_http_connect(EDGE_TO_ENTRY_CONN(conn)) < 0) {
        return -1;
      }
      return 0;
301
302
    case AP_CONN_STATE_OPEN:
    case EXIT_CONN_STATE_OPEN:
303
      if (connection_edge_package_raw_inbuf(conn, package_partial, NULL) < 0) {
304
        /* (We already sent an end cell if possible) */
305
        connection_mark_for_close(TO_CONN(conn));
306
307
        return -1;
      }
308
      return 0;
309
    case AP_CONN_STATE_CONNECT_WAIT:
310
      if (connection_ap_supports_optimistic_data(EDGE_TO_ENTRY_CONN(conn))) {
311
312
313
        log_info(LD_EDGE,
                 "data from edge while in '%s' state. Sending it anyway. "
                 "package_partial=%d, buflen=%ld",
314
                 conn_state_to_string(conn->base_.type, conn->base_.state),
315
316
                 package_partial,
                 (long)connection_get_inbuf_len(TO_CONN(conn)));
317
318
319
320
321
322
323
324
325
        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. */
326
      /* Falls through. */
327
    case EXIT_CONN_STATE_CONNECTING:
328
    case AP_CONN_STATE_RENDDESC_WAIT:
329
    case AP_CONN_STATE_CIRCUIT_WAIT:
330
    case AP_CONN_STATE_RESOLVE_WAIT:
331
    case AP_CONN_STATE_CONTROLLER_WAIT:
Roger Dingledine's avatar
Roger Dingledine committed
332
333
      log_info(LD_EDGE,
               "data from edge while in '%s' state. Leaving it on buffer.",
334
               conn_state_to_string(conn->base_.type, conn->base_.state));
335
336
      return 0;
  }
337
  log_warn(LD_BUG,"Got unexpected state %d. Closing.",conn->base_.state);
338
  tor_fragile_assert();
339
  connection_edge_end(conn, END_STREAM_REASON_INTERNAL);
340
  connection_mark_for_close(TO_CONN(conn));
341
  return -1;
342
343
}

344
345
346
/** This edge needs to be closed, because its circuit has closed.
 * Mark it for close and return 0.
 */
347
int
348
connection_edge_destroy(circid_t circ_id, edge_connection_t *conn)
349
{
350
  if (!conn->base_.marked_for_close) {
351
352
    log_info(LD_EDGE, "CircID %u: At an edge. Marking connection for close.",
             (unsigned) circ_id);
353
    if (conn->base_.type == CONN_TYPE_AP) {
354
355
      entry_connection_t *entry_conn = EDGE_TO_ENTRY_CONN(conn);
      connection_mark_unattached_ap(entry_conn, END_STREAM_REASON_DESTROY);
356
      control_event_stream_bandwidth(conn);
357
      control_event_stream_status(entry_conn, STREAM_EVENT_CLOSED,
358
359
                                  END_STREAM_REASON_DESTROY);
      conn->end_reason |= END_STREAM_REASON_FLAG_ALREADY_SENT_CLOSED;
360
    } else {
361
      /* closing the circuit, nothing to send an END to */
362
      conn->edge_has_sent_end = 1;
363
      conn->end_reason = END_STREAM_REASON_DESTROY;
364
      conn->end_reason |= END_STREAM_REASON_FLAG_ALREADY_SENT_CLOSED;
365
      connection_mark_and_flush(TO_CONN(conn));
366
    }
367
  }
368
  conn->cpath_layer = NULL;
369
  conn->on_circuit = NULL;
370
371
372
  return 0;
}

373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
/** 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;

391
392
393
394
  /* Note: we have to use relay_send_command_from_edge here, not
   * connection_edge_end or connection_edge_send_command, since those require
   * that we have a stream connected to a circuit, and we don't connect to a
   * circuit until we have a pending/successful resolve. */
395
396
397
398
  return relay_send_command_from_edge(stream_id, circ, RELAY_COMMAND_END,
                                      payload, 1, cpath_layer);
}

399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
/* If the connection <b>conn</b> is attempting to connect to an external
 * destination that is an hidden service and the reason is a connection
 * refused or timeout, log it so the operator can take appropriate actions.
 * The log statement is a rate limited warning. */
static void
warn_if_hs_unreachable(const edge_connection_t *conn, uint8_t reason)
{
  tor_assert(conn);

  if (conn->base_.type == CONN_TYPE_EXIT &&
      connection_edge_is_rendezvous_stream(conn) &&
      (reason == END_STREAM_REASON_CONNECTREFUSED ||
       reason == END_STREAM_REASON_TIMEOUT)) {
#define WARN_FAILED_HS_CONNECTION 300
    static ratelim_t warn_limit = RATELIM_INIT(WARN_FAILED_HS_CONNECTION);
    char *m;
    if ((m = rate_limit_log(&warn_limit, approx_time()))) {
      log_warn(LD_EDGE, "Onion service connection to %s failed (%s)",
               (conn->base_.socket_family == AF_UNIX) ?
               safe_str(conn->base_.address) :
               safe_str(fmt_addrport(&conn->base_.addr, conn->base_.port)),
               stream_end_reason_to_string(reason));
      tor_free(m);
    }
  }
}

426
427
428
/** 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>.
429
430
431
432
 *
 * Return -1 if this function has already been called on this conn,
 * else return 0.
 */
433
int
434
connection_edge_end(edge_connection_t *conn, uint8_t reason)
435
{
436
  char payload[RELAY_PAYLOAD_SIZE];
437
  size_t payload_len=1;
438
  circuit_t *circ;
Mike Perry's avatar
   
Mike Perry committed
439
  uint8_t control_reason = reason;
440

441
  if (conn->edge_has_sent_end) {
442
    log_warn(LD_BUG,"(Harmless.) Calling connection_edge_end (reason %d) "
Roger Dingledine's avatar
Roger Dingledine committed
443
             "on an already ended stream?", reason);
444
    tor_fragile_assert();
445
    return -1;
446
447
  }

448
  if (conn->base_.marked_for_close) {
Roger Dingledine's avatar
Roger Dingledine committed
449
    log_warn(LD_BUG,
450
             "called on conn that's already marked for close at %s:%d.",
451
             conn->base_.marked_for_close_file, conn->base_.marked_for_close);
452
453
454
    return 0;
  }

455
456
457
458
459
460
461
462
463
  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;
464
465
  if (reason == END_STREAM_REASON_EXITPOLICY &&
      !connection_edge_is_rendezvous_stream(conn)) {
466
    int addrlen;
467
468
    if (tor_addr_family(&conn->base_.addr) == AF_INET) {
      set_uint32(payload+1, tor_addr_to_ipv4n(&conn->base_.addr));
469
470
      addrlen = 4;
    } else {
471
      memcpy(payload+1, tor_addr_to_in6_addr8(&conn->base_.addr), 16);
472
473
474
475
      addrlen = 16;
    }
    set_uint32(payload+1+addrlen, htonl(dns_clip_ttl(conn->address_ttl)));
    payload_len += 4+addrlen;
476
477
  }

478
  if (circ && !circ->marked_for_close) {
479
480
    log_debug(LD_EDGE,"Sending end on conn (fd "TOR_SOCKET_T_FORMAT").",
              conn->base_.s);
481
482
483
484
485
486

    if (CIRCUIT_IS_ORIGIN(circ)) {
      origin_circuit_t *origin_circ = TO_ORIGIN_CIRCUIT(circ);
      connection_half_edge_add(conn, origin_circ);
    }

487
    connection_edge_send_command(conn, RELAY_COMMAND_END,
488
                                 payload, payload_len);
489
490
491
    /* We'll log warn if the connection was an hidden service and couldn't be
     * made because the service wasn't available. */
    warn_if_hs_unreachable(conn, control_reason);
492
  } else {
Nick Mathewson's avatar
Nick Mathewson committed
493
494
    log_debug(LD_EDGE,"No circ to send end on conn "
              "(fd "TOR_SOCKET_T_FORMAT").",
495
              conn->base_.s);
496
497
  }

498
  conn->edge_has_sent_end = 1;
Mike Perry's avatar
   
Mike Perry committed
499
  conn->end_reason = control_reason;
500
  return 0;
501
502
}

503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
/**
 * Helper function for bsearch.
 *
 * As per smartlist_bsearch, return < 0 if key preceeds member,
 * > 0 if member preceeds key, and 0 if they are equal.
 *
 * This is equivalent to subtraction of the values of key - member
 * (why does no one ever say that explicitly?).
 */
static int
connection_half_edge_compare_bsearch(const void *key, const void **member)
{
  const half_edge_t *e2;
  tor_assert(key);
  tor_assert(member && *(half_edge_t**)member);
  e2 = *(const half_edge_t **)member;

  return *(const streamid_t*)key - e2->stream_id;
}

523
524
525
/** Total number of half_edge_t objects allocated */
static size_t n_half_conns_allocated = 0;

526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
/**
 * Add a half-closed connection to the list, to watch for activity.
 *
 * These connections are removed from the list upon receiving an end
 * cell.
 */
STATIC void
connection_half_edge_add(const edge_connection_t *conn,
                         origin_circuit_t *circ)
{
  half_edge_t *half_conn = NULL;
  int insert_at = 0;
  int ignored;

  /* Double-check for re-insertion. This should not happen,
   * but this check is cheap compared to the sort anyway */
  if (connection_half_edge_find_stream_id(circ->half_streams,
                                          conn->stream_id)) {
    log_warn(LD_BUG, "Duplicate stream close for stream %d on circuit %d",
             conn->stream_id, circ->global_identifier);
    return;
  }

  half_conn = tor_malloc_zero(sizeof(half_edge_t));
550
  ++n_half_conns_allocated;
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579

  if (!circ->half_streams) {
    circ->half_streams = smartlist_new();
  }

  half_conn->stream_id = conn->stream_id;

  // How many sendme's should I expect?
  half_conn->sendmes_pending =
   (STREAMWINDOW_START-conn->package_window)/STREAMWINDOW_INCREMENT;

   // Is there a connected cell pending?
  half_conn->connected_pending = conn->base_.state ==
      AP_CONN_STATE_CONNECT_WAIT;

  /* Data should only arrive if we're not waiting on a resolved cell.
   * It can arrive after waiting on connected, because of optimistic
   * data. */
  if (conn->base_.state != AP_CONN_STATE_RESOLVE_WAIT) {
    // How many more data cells can arrive on this id?
    half_conn->data_pending = conn->deliver_window;
  }

  insert_at = smartlist_bsearch_idx(circ->half_streams, &half_conn->stream_id,
                                    connection_half_edge_compare_bsearch,
                                    &ignored);
  smartlist_insert(circ->half_streams, insert_at, half_conn);
}

580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
/** Release space held by <b>he</b> */
void
half_edge_free_(half_edge_t *he)
{
  if (!he)
    return;
  --n_half_conns_allocated;
  tor_free(he);
}

/** Return the number of bytes devoted to storing info on half-open streams. */
size_t
half_streams_get_total_allocation(void)
{
  return n_half_conns_allocated * sizeof(half_edge_t);
}

597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
/**
 * Find a stream_id_t in the list in O(lg(n)).
 *
 * Returns NULL if the list is empty or element is not found.
 * Returns a pointer to the element if found.
 */
STATIC half_edge_t *
connection_half_edge_find_stream_id(const smartlist_t *half_conns,
                                    streamid_t stream_id)
{
  if (!half_conns)
    return NULL;

  return smartlist_bsearch(half_conns, &stream_id,
                           connection_half_edge_compare_bsearch);
}

/**
 * Check if this stream_id is in a half-closed state. If so,
 * check if it still has data cells pending, and decrement that
 * window if so.
 *
 * Return 1 if the data window was not empty.
 * Return 0 otherwise.
 */
int
connection_half_edge_is_valid_data(const smartlist_t *half_conns,
                                   streamid_t stream_id)
{
  half_edge_t *half = connection_half_edge_find_stream_id(half_conns,
                                                          stream_id);

  if (!half)
    return 0;

  if (half->data_pending > 0) {
    half->data_pending--;
    return 1;
  }

  return 0;
}

/**
 * Check if this stream_id is in a half-closed state. If so,
 * check if it still has a connected cell pending, and decrement
 * that window if so.
 *
 * Return 1 if the connected window was not empty.
 * Return 0 otherwise.
 */
int
connection_half_edge_is_valid_connected(const smartlist_t *half_conns,
                                        streamid_t stream_id)
{
  half_edge_t *half = connection_half_edge_find_stream_id(half_conns,
                                                          stream_id);

  if (!half)
    return 0;

  if (half->connected_pending) {
    half->connected_pending = 0;
    return 1;
  }

  return 0;
}

/**
 * Check if this stream_id is in a half-closed state. If so,
 * check if it still has sendme cells pending, and decrement that
 * window if so.
 *
 * Return 1 if the sendme window was not empty.
 * Return 0 otherwise.
 */
int
connection_half_edge_is_valid_sendme(const smartlist_t *half_conns,
                                     streamid_t stream_id)
{
  half_edge_t *half = connection_half_edge_find_stream_id(half_conns,
                                                          stream_id);

  if (!half)
    return 0;

  if (half->sendmes_pending > 0) {
    half->sendmes_pending--;
    return 1;
  }

  return 0;
}

/**
 * Check if this stream_id is in a half-closed state. If so, remove
 * it from the list. No other data should come after the END cell.
 *
 * Return 1 if stream_id was in half-closed state.
 * Return 0 otherwise.
 */
int
connection_half_edge_is_valid_end(smartlist_t *half_conns,
                                  streamid_t stream_id)
{
  half_edge_t *half;
  int found, remove_idx;

  if (!half_conns)
    return 0;

  remove_idx = smartlist_bsearch_idx(half_conns, &stream_id,
                                    connection_half_edge_compare_bsearch,
                                    &found);
  if (!found)
    return 0;

  half = smartlist_get(half_conns, remove_idx);
  smartlist_del_keeporder(half_conns, remove_idx);
717
  half_edge_free(half);
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
  return 1;
}

/**
 * Streams that were used to send a RESOLVE cell are closed
 * when they get the RESOLVED, without an end. So treat
 * a RESOLVED just like an end, and remove from the list.
 */
int
connection_half_edge_is_valid_resolved(smartlist_t *half_conns,
                                       streamid_t stream_id)
{
  return connection_half_edge_is_valid_end(half_conns, stream_id);
}

Nick Mathewson's avatar
Nick Mathewson committed
733
/** An error has just occurred on an operation on an edge connection
734
735
 * <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.
736
 **/
737
int
738
connection_edge_end_errno(edge_connection_t *conn)
739
740
741
{
  uint8_t reason;
  tor_assert(conn);
742
  reason = errno_to_stream_end_reason(tor_socket_errno(conn->base_.s));
743
  return connection_edge_end(conn, reason);
744
745
}

746
747
748
749
750
751
752
753
/** 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)
{
754
  switch (conn->base_.state) {
755
756
757
758
759
760
761
762
    case AP_CONN_STATE_OPEN:
    case EXIT_CONN_STATE_OPEN:
      connection_edge_consider_sending_sendme(conn);
      break;
  }
  return 0;
}

763
764
765
766
767
768
769
770
771
772
/** 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.
 */
773
int
774
connection_edge_finished_flushing(edge_connection_t *conn)
775
{
Roger Dingledine's avatar
Roger Dingledine committed
776
  tor_assert(conn);
777

778
  switch (conn->base_.state) {
779
780
    case AP_CONN_STATE_OPEN:
    case EXIT_CONN_STATE_OPEN:
781
      connection_edge_consider_sending_sendme(conn);
782
      return 0;
Roger Dingledine's avatar
Roger Dingledine committed
783
    case AP_CONN_STATE_SOCKS_WAIT:
784
    case AP_CONN_STATE_NATD_WAIT:
785
    case AP_CONN_STATE_RENDDESC_WAIT:
786
    case AP_CONN_STATE_CIRCUIT_WAIT:
787
    case AP_CONN_STATE_CONNECT_WAIT:
788
    case AP_CONN_STATE_CONTROLLER_WAIT:
789
    case AP_CONN_STATE_RESOLVE_WAIT:
790
    case AP_CONN_STATE_HTTP_CONNECT_WAIT:
Roger Dingledine's avatar
Roger Dingledine committed
791
      return 0;
792
    default:
793
      log_warn(LD_BUG, "Called in unexpected state %d.",conn->base_.state);
794
      tor_fragile_assert();
795
      return -1;
796
797
798
799
  }
  return 0;
}

800
801
802
/** 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. */
803
804
#define MAX_CONNECTED_CELL_PAYLOAD_LEN 25

805
806
807
808
809
810
/** 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. */
811
STATIC int
812
813
814
815
816
817
818
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;

819
820
821
  /* should be needless */
  memset(payload_out, 0, MAX_CONNECTED_CELL_PAYLOAD_LEN);

822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
  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;
}

842
843
844
/** 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. */
845
int
846
connection_edge_finished_connecting(edge_connection_t *edge_conn)
847
{
848
  connection_t *conn;
849

850
  tor_assert(edge_conn);
851
  tor_assert(edge_conn->base_.type == CONN_TYPE_EXIT);
852
  conn = TO_CONN(edge_conn);
853
854
  tor_assert(conn->state == EXIT_CONN_STATE_CONNECTING);

Roger Dingledine's avatar
Roger Dingledine committed
855
  log_info(LD_EXIT,"Exit connection to %s:%u (%s) established.",
856
           escaped_safe_str(conn->address), conn->port,
857
           safe_str(fmt_and_decorate_addr(&conn->addr)));
858

859
  rep_hist_note_exit_stream_opened(conn->port);
860

861
  conn->state = EXIT_CONN_STATE_OPEN;
862
  connection_watch_events(conn, READ_EVENT); /* stop writing, keep reading */
863
  if (connection_get_outbuf_len(conn)) /* in case there are any queued relay
864
                                        * cells */
865
866
    connection_start_writing(conn);
  /* deliver a 'connected' relay cell back through the circuit. */
867
868
  if (connection_edge_is_rendezvous_stream(edge_conn)) {
    if (connection_edge_send_command(edge_conn,
869
                                     RELAY_COMMAND_CONNECTED, NULL, 0) < 0)
870
871
      return 0; /* circuit is closed, don't continue */
  } else {
872
873
874
875
876
877
878
    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;

879
    if (connection_edge_send_command(edge_conn,
880
881
                        RELAY_COMMAND_CONNECTED,
                        (char*)connected_payload, connected_payload_len) < 0)
882
883
      return 0; /* circuit is closed, don't continue */
  }
884
  tor_assert(edge_conn->package_window > 0);
885
  /* in case the server has written anything */
886
  return connection_edge_process_inbuf(edge_conn, 1);
887
888
}

889
890
891
892
893
894
895
896
/** A list of all the entry_connection_t * objects that are not marked
 * for close, and are in AP_CONN_STATE_CIRCUIT_WAIT.
 *
 * (Right now, we check in several places to make sure that this list is
 * correct.  When it's incorrect, we'll fix it, and log a BUG message.)
 */
static smartlist_t *pending_entry_connections = NULL;

897
898
static int untried_pending_connections = 0;

899
900
901
902
903
904
/**
 * Mainloop event to tell us to scan for pending connections that can
 * be attached.
 */
static mainloop_event_t *attach_pending_entry_connections_ev = NULL;

905
906
907
908
909
910
911
912
913
914
915
916
917
/** 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();
  }
}

918
/** Called when we're about to finally unlink and free an AP (client)
919
920
 * connection: perform necessary accounting and cleanup */
void
921
connection_ap_about_to_close(entry_connection_t *entry_conn)
922
923
{
  circuit_t *circ;
924
925
  edge_connection_t *edge_conn = ENTRY_TO_EDGE_CONN(entry_conn);
  connection_t *conn = ENTRY_TO_CONN(entry_conn);
926

927
928
  connection_edge_about_to_close(edge_conn);

929
  if (entry_conn->socks_request->has_finished == 0) {
930
931
932
933
934
935
936
937
938
939
940
    /* 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);
  }
941
  if (entry_conn->dns_server_request) {
942
943
944
    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);
945
    dnsserv_reject_request(entry_conn);
946
  }
947
948
949
950
951
952
953
954

  if (TO_CONN(edge_conn)->state == AP_CONN_STATE_CIRCUIT_WAIT) {
    smartlist_remove(pending_entry_connections, entry_conn);
  }

#if 1
  /* Check to make sure that this isn't in pending_entry_connections if it
   * didn't actually belong there. */
955
956
957
  if (TO_CONN(edge_conn)->type == CONN_TYPE_AP) {
    connection_ap_warn_and_unmark_if_pending_circ(entry_conn,
                                                  "about_to_close");
958
  }
959
#endif /* 1 */
960

961
  control_event_stream_bandwidth(edge_conn);
962
  control_event_stream_status(entry_conn, STREAM_EVENT_CLOSED,
963
964
965
966
967
968
                              edge_conn->end_reason);
  circ = circuit_get_by_edge_conn(edge_conn);
  if (circ)
    circuit_detach_stream(circ, edge_conn);
}

969
/** Called when we're about to finally unlink and free an exit
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
 * 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);
  }
}

987
988
/** Define a schedule for how long to wait between retrying
 * application connections. Rather than waiting a fixed amount of
989
 * time between each retry, we wait 10 seconds each for the first
990
 * two tries, and 15 seconds for each retry after
991
 * that. Hopefully this will improve the expected user experience. */
992
static int
993
compute_retry_timeout(entry_connection_t *conn)
994
{
995
996
997
  int timeout = get_options()->CircuitStreamTimeout;
  if (timeout) /* if our config options override the default, use them */
    return timeout;
998
  if (conn->num_socks_retries < 2) /* try 0 and try 1 */
999
1000
    return 10;
  return 15;
For faster browsing, not all history is shown. View entire blame