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

103
104
105
106
107
108
109
110
#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"
111
#include "core/or/half_edge_st.h"
112
#include "core/or/socks_request_st.h"
113
#include "lib/evloop/compat_libevent.h"
114

115
116
117
#ifdef HAVE_LINUX_TYPES_H
#include <linux/types.h>
#endif
118
119
120
#ifdef HAVE_LINUX_NETFILTER_IPV4_H
#include <linux/netfilter_ipv4.h>
#define TRANS_NETFILTER
121
#define TRANS_NETFILTER_IPV4
122
123
#endif

124
125
126
127
128
129
#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>
130
#if defined(IP6T_SO_ORIGINAL_DST)
131
132
133
#define TRANS_NETFILTER
#define TRANS_NETFILTER_IPV6
#endif
134
#endif /* defined(HAVE_LINUX_NETFILTER_IPV6_IP6_TABLES_H) */
135

136
137
138
139
140
141
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
#ifdef HAVE_SYS_IOCTL_H
#include <sys/ioctl.h>
#endif
142
143
144
#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif
145

146
147
148
149
150
151
#if defined(HAVE_NET_IF_H) && defined(HAVE_NET_PFVAR_H)
#include <net/if.h>
#include <net/pfvar.h>
#define TRANS_PF
#endif

152
153
154
155
#ifdef IP_TRANSPARENT
#define TRANS_TPROXY
#endif

156
157
158
#define SOCKS4_GRANTED          90
#define SOCKS4_REJECT           91

159
160
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
161
static int connection_exit_connect_dir(edge_connection_t *exitconn);
162
163
static int consider_plaintext_ports(entry_connection_t *conn, uint16_t port);
static int connection_ap_supports_optimistic_data(const entry_connection_t *);
164

165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
/** 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_);
}

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

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

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

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

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

238
  connection_mark_and_flush_(base_conn, line, file);
239

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

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

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

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

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

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

392
393
394
395
  /* 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. */
396
397
398
399
  return relay_send_command_from_edge(stream_id, circ, RELAY_COMMAND_END,
                                      payload, 1, cpath_layer);
}

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
426
/* 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);
    }
  }
}

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

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

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

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

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

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

488
    connection_edge_send_command(conn, RELAY_COMMAND_END,
489
                                 payload, payload_len);
490
491
492
    /* 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);
493
  } else {
Nick Mathewson's avatar
Nick Mathewson committed
494
495
    log_debug(LD_EDGE,"No circ to send end on conn "
              "(fd "TOR_SOCKET_T_FORMAT").",
496
              conn->base_.s);
497
498
  }

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

504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
/**
 * 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;
}

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

527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
/**
 * 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));
551
  ++n_half_conns_allocated;
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
580

  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);
}

581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
/** 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);
}

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
717
/**
 * 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);
718
  half_edge_free(half);
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
  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
734
/** An error has just occurred on an operation on an edge connection
735
736
 * <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.
737
 **/
738
int
739
connection_edge_end_errno(edge_connection_t *conn)
740
741
742
{
  uint8_t reason;
  tor_assert(conn);
743
  reason = errno_to_stream_end_reason(tor_socket_errno(conn->base_.s));
744
  return connection_edge_end(conn, reason);
745
746
}

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

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

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

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

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

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

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

843
844
845
/* This is an onion service client connection: Export the client circuit ID
 * according to the HAProxy proxy protocol. */
STATIC void
846
export_hs_client_circuit_id(edge_connection_t *edge_conn,
847
                            hs_circuit_id_protocol_t protocol)
848
{
849
850
851
852
853
  /* We only support HAProxy right now. */
  if (protocol != HS_CIRCUIT_ID_PROTOCOL_HAPROXY)
    return;

  char *buf = NULL;
854
  const char dst_ipv6[] = "::1";
855
  /* See RFC4193 regarding fc00::/7 */
856
  const char src_ipv6_prefix[] = "fc00:dead:beef:4dad:";
857
  uint16_t dst_port = 0;
858
859
  uint16_t src_port = 1; /* default value */
  uint32_t gid = 0; /* default value */
860

861
  /* Generate a GID and source port for this client */
862
863
864
865
866
  if (edge_conn->on_circuit != NULL) {
    gid = TO_ORIGIN_CIRCUIT(edge_conn->on_circuit)->global_identifier;
    src_port = gid & 0x0000ffff;
  }

867
868
869
870
871
  /* Grab the original dest port from the hs ident */
  if (edge_conn->hs_ident) {
    dst_port = edge_conn->hs_ident->orig_virtual_port;
  }

872
  /* Build the string */
873
874
875
876
  tor_asprintf(&buf, "PROXY TCP6 %s:%x:%x %s %d %d\r\n",
               src_ipv6_prefix,
               gid >> 16, gid & 0x0000ffff,
               dst_ipv6, src_port, dst_port);
877

878
  connection_buf_add(buf, strlen(buf), TO_CONN(edge_conn));
879
880

  tor_free(buf);
881
882
}

883
884
885
/** 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. */
886
int
887
connection_edge_finished_connecting(edge_connection_t *edge_conn)
888
{
889
  connection_t *conn;
890

891
  tor_assert(edge_conn);
892
  tor_assert(edge_conn->base_.type == CONN_TYPE_EXIT);
893
  conn = TO_CONN(edge_conn);
894
895
  tor_assert(conn->state == EXIT_CONN_STATE_CONNECTING);

Roger Dingledine's avatar
Roger Dingledine committed
896
  log_info(LD_EXIT,"Exit connection to %s:%u (%s) established.",
897
           escaped_safe_str(conn->address), conn->port,
898
           safe_str(fmt_and_decorate_addr(&conn->addr)));
899

900
  rep_hist_note_exit_stream_opened(conn->port);
901

902
  conn->state = EXIT_CONN_STATE_OPEN;
903

904
  connection_watch_events(conn, READ_EVENT); /* stop writing, keep reading */
905
  if (connection_get_outbuf_len(conn)) /* in case there are any queued relay
906
                                        * cells */
907
908
    connection_start_writing(conn);
  /* deliver a 'connected' relay cell back through the circuit. */
909
910
  if (connection_edge_is_rendezvous_stream(edge_conn)) {
    if (connection_edge_send_command(edge_conn,
911
                                     RELAY_COMMAND_CONNECTED, NULL, 0) < 0)
912
913
      return 0; /* circuit is closed, don't continue */
  } else {
914
915
916
917
918
919
920
    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;

921
    if (connection_edge_send_command(edge_conn,
922
923
                        RELAY_COMMAND_CONNECTED,
                        (char*)connected_payload, connected_payload_len) < 0)
924
925
      return 0; /* circuit is closed, don't continue */
  }
926
  tor_assert(edge_conn->package_window > 0);
927
  /* in case the server has written anything */
928
  return connection_edge_process_inbuf(edge_conn, 1);
929
930
}

931
932
933
934
935
936
937
938
/** 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;

939
940
static int untried_pending_connections = 0;

941
942
943
944
945
946
/**
 * Mainloop event to tell us to scan for pending connections that can
 * be attached.
 */
static mainloop_event_t *attach_pending_entry_connections_ev = NULL;

947
948
949
950
951
952
953
954
955
956
957
958
959
/** 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();
  }
}

960
/** Called when we're about to finally unlink and free an AP (client)
961
962
 * connection: perform necessary accounting and cleanup */
void
963
connection_ap_about_to_close(entry_connection_t *entry_conn)
964
965
{
  circuit_t *circ;
966
967
  edge_connection_t *edge_conn = ENTRY_TO_EDGE_CONN(entry_conn);
  connection_t *conn = ENTRY_TO_CONN(entry_conn);
968

969
970
  connection_edge_about_to_close(edge_conn);

971
  if (entry_conn->socks_request->has_finished == 0) {
972
973
974
975
976
977
978
979
980
981
982
    /* 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);
  }
983
  if (entry_conn->dns_server_request) {
984
985
986
    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);
987
    dnsserv_reject_request(entry_conn);
988
  }
989
990
991
992
993
994
995
996

  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. */
997
998
999
  if (TO_CONN(edge_conn)->type == CONN_TYPE_AP) {
    connection_ap_warn_and_unmark_if_pending_circ(entry_conn,
                                                  "about_to_close");
1000
  }
For faster browsing, not all history is shown. View entire blame