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

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

118
119
120
#ifdef HAVE_LINUX_TYPES_H
#include <linux/types.h>
#endif
121
122
123
#ifdef HAVE_LINUX_NETFILTER_IPV4_H
#include <linux/netfilter_ipv4.h>
#define TRANS_NETFILTER
124
#define TRANS_NETFILTER_IPV4
125
126
#endif

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

139
140
141
142
143
144
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
#ifdef HAVE_SYS_IOCTL_H
#include <sys/ioctl.h>
#endif
145
146
147
#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif
148

149
150
151
152
153
154
#if defined(HAVE_NET_IF_H) && defined(HAVE_NET_PFVAR_H)
#include <net/if.h>
#include <net/pfvar.h>
#define TRANS_PF
#endif

155
156
157
158
#ifdef IP_TRANSPARENT
#define TRANS_TPROXY
#endif

159
160
161
#define SOCKS4_GRANTED          90
#define SOCKS4_REJECT           91

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

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

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

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

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

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

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

241
  connection_mark_and_flush_(base_conn, line, file);
242

243
  ENTRY_TO_EDGE_CONN(conn)->end_reason = endreason;
244
245
}

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

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

287
  switch (conn->base_.state) {
288
    case AP_CONN_STATE_SOCKS_WAIT:
289
      if (connection_ap_handshake_process_socks(EDGE_TO_ENTRY_CONN(conn)) <0) {
290
        /* already marked */
291
292
293
        return -1;
      }
      return 0;
294
    case AP_CONN_STATE_NATD_WAIT:
295
      if (connection_ap_process_natd(EDGE_TO_ENTRY_CONN(conn)) < 0) {
296
297
298
299
        /* already marked */
        return -1;
      }
      return 0;
300
301
302
303
304
    case AP_CONN_STATE_HTTP_CONNECT_WAIT:
      if (connection_ap_process_http_connect(EDGE_TO_ENTRY_CONN(conn)) < 0) {
        return -1;
      }
      return 0;
305
    case AP_CONN_STATE_OPEN:
306
307
308
309
      if (! conn->base_.linked) {
        note_user_activity(approx_time());
      }

310
      FALLTHROUGH;
311
    case EXIT_CONN_STATE_OPEN:
312
      if (connection_edge_package_raw_inbuf(conn, package_partial, NULL) < 0) {
313
        /* (We already sent an end cell if possible) */
314
        connection_mark_for_close(TO_CONN(conn));
315
316
        return -1;
      }
317
      return 0;
318
    case AP_CONN_STATE_CONNECT_WAIT:
319
      if (connection_ap_supports_optimistic_data(EDGE_TO_ENTRY_CONN(conn))) {
320
321
322
        log_info(LD_EDGE,
                 "data from edge while in '%s' state. Sending it anyway. "
                 "package_partial=%d, buflen=%ld",
323
                 conn_state_to_string(conn->base_.type, conn->base_.state),
324
325
                 package_partial,
                 (long)connection_get_inbuf_len(TO_CONN(conn)));
326
327
328
329
330
331
332
333
334
        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. */
335
      FALLTHROUGH;
336
    case EXIT_CONN_STATE_CONNECTING:
337
    case AP_CONN_STATE_RENDDESC_WAIT:
338
    case AP_CONN_STATE_CIRCUIT_WAIT:
339
    case AP_CONN_STATE_RESOLVE_WAIT:
340
    case AP_CONN_STATE_CONTROLLER_WAIT:
Roger Dingledine's avatar
Roger Dingledine committed
341
342
      log_info(LD_EDGE,
               "data from edge while in '%s' state. Leaving it on buffer.",
343
               conn_state_to_string(conn->base_.type, conn->base_.state));
344
345
      return 0;
  }
346
  log_warn(LD_BUG,"Got unexpected state %d. Closing.",conn->base_.state);
347
  tor_fragile_assert();
348
  connection_edge_end(conn, END_STREAM_REASON_INTERNAL);
349
  connection_mark_for_close(TO_CONN(conn));
350
  return -1;
351
352
}

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

382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
/** 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;

400
401
402
403
  /* 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. */
404
405
406
407
  return relay_send_command_from_edge(stream_id, circ, RELAY_COMMAND_END,
                                      payload, 1, cpath_layer);
}

408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
/* 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);
    }
  }
}

435
436
437
/** 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>.
438
439
440
441
 *
 * Return -1 if this function has already been called on this conn,
 * else return 0.
 */
442
int
443
connection_edge_end(edge_connection_t *conn, uint8_t reason)
444
{
445
  char payload[RELAY_PAYLOAD_SIZE];
446
  size_t payload_len=1;
447
  circuit_t *circ;
Mike Perry's avatar
   
Mike Perry committed
448
  uint8_t control_reason = reason;
449

450
  if (conn->edge_has_sent_end) {
451
    log_warn(LD_BUG,"(Harmless.) Calling connection_edge_end (reason %d) "
Roger Dingledine's avatar
Roger Dingledine committed
452
             "on an already ended stream?", reason);
453
    tor_fragile_assert();
454
    return -1;
455
456
  }

457
  if (conn->base_.marked_for_close) {
Roger Dingledine's avatar
Roger Dingledine committed
458
    log_warn(LD_BUG,
459
             "called on conn that's already marked for close at %s:%d.",
460
             conn->base_.marked_for_close_file, conn->base_.marked_for_close);
461
462
463
    return 0;
  }

464
465
466
467
468
469
470
471
472
  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;
473
474
  if (reason == END_STREAM_REASON_EXITPOLICY &&
      !connection_edge_is_rendezvous_stream(conn)) {
475
    int addrlen;
476
477
    if (tor_addr_family(&conn->base_.addr) == AF_INET) {
      set_uint32(payload+1, tor_addr_to_ipv4n(&conn->base_.addr));
478
479
      addrlen = 4;
    } else {
480
      memcpy(payload+1, tor_addr_to_in6_addr8(&conn->base_.addr), 16);
481
482
483
484
      addrlen = 16;
    }
    set_uint32(payload+1+addrlen, htonl(dns_clip_ttl(conn->address_ttl)));
    payload_len += 4+addrlen;
485
486
  }

487
  if (circ && !circ->marked_for_close) {
488
489
    log_debug(LD_EDGE,"Sending end on conn (fd "TOR_SOCKET_T_FORMAT").",
              conn->base_.s);
490
491
492
493
494
495

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

496
    connection_edge_send_command(conn, RELAY_COMMAND_END,
497
                                 payload, payload_len);
498
499
500
    /* 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);
501
  } else {
Nick Mathewson's avatar
Nick Mathewson committed
502
503
    log_debug(LD_EDGE,"No circ to send end on conn "
              "(fd "TOR_SOCKET_T_FORMAT").",
504
              conn->base_.s);
505
506
  }

507
  conn->edge_has_sent_end = 1;
Mike Perry's avatar
   
Mike Perry committed
508
  conn->end_reason = control_reason;
509
  return 0;
510
511
}

512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
/**
 * 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;
}

532
533
534
/** Total number of half_edge_t objects allocated */
static size_t n_half_conns_allocated = 0;

535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
/**
 * 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));
559
  ++n_half_conns_allocated;
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588

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

589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
/** 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);
}

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

755
756
757
758
759
760
761
762
/** 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)
{
763
  switch (conn->base_.state) {
764
    case AP_CONN_STATE_OPEN:
765
766
767
768
      if (! conn->base_.linked) {
        note_user_activity(approx_time());
      }

769
      FALLTHROUGH;
770
    case EXIT_CONN_STATE_OPEN:
771
      sendme_connection_edge_consider_sending(conn);
772
773
774
775
776
      break;
  }
  return 0;
}

777
778
779
780
781
782
783
784
785
786
/** 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.
 */
787
int
788
connection_edge_finished_flushing(edge_connection_t *conn)
789
{
Roger Dingledine's avatar
Roger Dingledine committed
790
  tor_assert(conn);
791

792
  switch (conn->base_.state) {
793
794
    case AP_CONN_STATE_OPEN:
    case EXIT_CONN_STATE_OPEN:
795
      sendme_connection_edge_consider_sending(conn);
796
      return 0;
Roger Dingledine's avatar
Roger Dingledine committed
797
    case AP_CONN_STATE_SOCKS_WAIT:
798
    case AP_CONN_STATE_NATD_WAIT:
799
    case AP_CONN_STATE_RENDDESC_WAIT:
800
    case AP_CONN_STATE_CIRCUIT_WAIT:
801
    case AP_CONN_STATE_CONNECT_WAIT:
802
    case AP_CONN_STATE_CONTROLLER_WAIT:
803
    case AP_CONN_STATE_RESOLVE_WAIT:
804
    case AP_CONN_STATE_HTTP_CONNECT_WAIT:
Roger Dingledine's avatar
Roger Dingledine committed
805
      return 0;
806
    default:
807
      log_warn(LD_BUG, "Called in unexpected state %d.",conn->base_.state);
808
      tor_fragile_assert();
809
      return -1;
810
811
812
813
  }
  return 0;
}

814
815
816
/** 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. */
817
818
#define MAX_CONNECTED_CELL_PAYLOAD_LEN 25

819
820
821
822
823
824
/** 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. */
825
STATIC int
826
827
828
829
830
831
832
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;

833
834
835
  /* should be needless */
  memset(payload_out, 0, MAX_CONNECTED_CELL_PAYLOAD_LEN);

836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
  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;
}

856
857
858
/* This is an onion service client connection: Export the client circuit ID
 * according to the HAProxy proxy protocol. */
STATIC void
859
export_hs_client_circuit_id(edge_connection_t *edge_conn,
860
                            hs_circuit_id_protocol_t protocol)
861
{
862
863
864
865
866
  /* We only support HAProxy right now. */
  if (protocol != HS_CIRCUIT_ID_PROTOCOL_HAPROXY)
    return;

  char *buf = NULL;
867
  const char dst_ipv6[] = "::1";
868
  /* See RFC4193 regarding fc00::/7 */
869
  const char src_ipv6_prefix[] = "fc00:dead:beef:4dad:";
870
  uint16_t dst_port = 0;
871
872
  uint16_t src_port = 1; /* default value */
  uint32_t gid = 0; /* default value */
873

874
  /* Generate a GID and source port for this client */
875
876
877
878
879
  if (edge_conn->on_circuit != NULL) {
    gid = TO_ORIGIN_CIRCUIT(edge_conn->on_circuit)->global_identifier;
    src_port = gid & 0x0000ffff;
  }

880
881
882
883
884
  /* Grab the original dest port from the hs ident */
  if (edge_conn->hs_ident) {
    dst_port = edge_conn->hs_ident->orig_virtual_port;
  }

885
  /* Build the string */
886
887
888
889
  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);
890

891
  connection_buf_add(buf, strlen(buf), TO_CONN(edge_conn));
892
893

  tor_free(buf);
894
895
}

896
897
898
/** 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. */
899
int
900
connection_edge_finished_connecting(edge_connection_t *edge_conn)
901
{
902
  connection_t *conn;
903

904
  tor_assert(edge_conn);
905
  tor_assert(edge_conn->base_.type == CONN_TYPE_EXIT);
906
  conn = TO_CONN(edge_conn);
907
908
  tor_assert(conn->state == EXIT_CONN_STATE_CONNECTING);

Roger Dingledine's avatar
Roger Dingledine committed
909
  log_info(LD_EXIT,"Exit connection to %s:%u (%s) established.",
910
           escaped_safe_str(conn->address), conn->port,
911
           safe_str(fmt_and_decorate_addr(&conn->addr)));
912

913
  rep_hist_note_exit_stream_opened(conn->port);
914

915
  conn->state = EXIT_CONN_STATE_OPEN;
916

917
  connection_watch_events(conn, READ_EVENT); /* stop writing, keep reading */
918
  if (connection_get_outbuf_len(conn)) /* in case there are any queued relay
919
                                        * cells */
920
921
    connection_start_writing(conn);
  /* deliver a 'connected' relay cell back through the circuit. */
922
923
  if (connection_edge_is_rendezvous_stream(edge_conn)) {
    if (connection_edge_send_command(edge_conn,
924
                                     RELAY_COMMAND_CONNECTED, NULL, 0) < 0)
925
926
      return 0; /* circuit is closed, don't continue */
  } else {
927
928
929
930
931
932
933
    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;

934
    if (connection_edge_send_command(edge_conn,
935
936
                        RELAY_COMMAND_CONNECTED,
                        (char*)connected_payload, connected_payload_len) < 0)
937
938
      return 0; /* circuit is closed, don't continue */
  }
939
  tor_assert(edge_conn->package_window > 0);
940
  /* in case the server has written anything */
941
  return connection_edge_process_inbuf(edge_conn, 1);
942
943
}

944
945
946
947
948
949
950
951
/** 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;

952
953
static int untried_pending_connections = 0;

954
955
956
957
958
959
/**
 * Mainloop event to tell us to scan for pending connections that can
 * be attached.
 */
static mainloop_event_t *attach_pending_entry_connections_ev = NULL;

960
961
962
963
964
965
966
967
968
969
970
971
972
/** 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();
  }
}

973
/** Called when we're about to finally unlink and free an AP (client)
974
975
 * connection: perform necessary accounting and cleanup */
void
976
connection_ap_about_to_close(entry_connection_t *entry_conn)
977
978
{
  circuit_t *circ;
979
980
  edge_connection_t *edge_conn = ENTRY_TO_EDGE_CONN(entry_conn);
  connection_t *conn = ENTRY_TO_CONN(entry_conn);
981

982
983
  connection_edge_about_to_close(edge_conn);

984
  if (entry_conn->socks_request->has_finished == 0) {
985
986
987
988
989
990
991
992
993
994
995
    /* 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);
  }
996
  if (entry_conn->dns_server_request) {
997
998
999
    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);
1000
    dnsserv_reject_request(entry_conn);