connection.c 88.2 KB
Newer Older
Roger Dingledine's avatar
Roger Dingledine committed
1
2
/* Copyright (c) 2001 Matej Pfajfar.
 * Copyright (c) 2001-2004, Roger Dingledine.
3
 * Copyright (c) 2004-2007, Roger Dingledine, Nick Mathewson. */
4
5
/* See LICENSE for licensing information */
/* $Id$ */
6
7
const char connection_c_id[] =
  "$Id$";
Roger Dingledine's avatar
Roger Dingledine committed
8

9
10
/**
 * \file connection.c
11
12
 * \brief General high-level functions to handle reading and writing
 * on connections.
13
14
 **/

Roger Dingledine's avatar
Roger Dingledine committed
15
16
#include "or.h"

17
18
static connection_t *connection_create_listener(const char *listenaddress,
                                                uint16_t listenport, int type);
19
20
static int connection_init_accepted_conn(connection_t *conn,
                                         uint8_t listener_type);
Nick Mathewson's avatar
Nick Mathewson committed
21
static int connection_handle_listener_read(connection_t *conn, int new_type);
22
static int connection_read_bucket_should_increase(or_connection_t *conn);
23
static int connection_finished_flushing(connection_t *conn);
24
static int connection_flushed_some(connection_t *conn);
25
static int connection_finished_connecting(connection_t *conn);
26
static int connection_reached_eof(connection_t *conn);
27
28
static int connection_read_to_buf(connection_t *conn, int *max_to_read);
static int connection_process_inbuf(connection_t *conn, int package_partial);
29
30
31
32
static void client_check_address_changed(int sock);

static uint32_t last_interface_ip = 0;
static smartlist_t *outgoing_addrs = NULL;
33
34
35

/**************************************************************/

36
37
38
/**
 * Return the human-readable name for the connection type <b>type</b>
 */
39
40
41
42
43
44
45
46
const char *
conn_type_to_string(int type)
{
  static char buf[64];
  switch (type) {
    case CONN_TYPE_OR_LISTENER: return "OR listener";
    case CONN_TYPE_OR: return "OR";
    case CONN_TYPE_EXIT: return "Exit";
47
    case CONN_TYPE_AP_LISTENER: return "Socks listener";
48
49
50
    case CONN_TYPE_AP_TRANS_LISTENER:
      return "Transparent pf/netfilter listener";
    case CONN_TYPE_AP_NATD_LISTENER: return "Transparent natd listener";
51
    case CONN_TYPE_AP_DNS_LISTENER: return "DNS listener";
52
53
54
    case CONN_TYPE_AP: return "Socks";
    case CONN_TYPE_DIR_LISTENER: return "Directory listener";
    case CONN_TYPE_DIR: return "Directory";
55
56
57
58
    case CONN_TYPE_CPUWORKER: return "CPU worker";
    case CONN_TYPE_CONTROL_LISTENER: return "Control listener";
    case CONN_TYPE_CONTROL: return "Control";
    default:
59
      log_warn(LD_BUG, "unknown connection type %d", type);
60
61
62
63
64
      tor_snprintf(buf, sizeof(buf), "unknown [%d]", type);
      return buf;
  }
}

65
66
67
68
/**
 * Return the human-readable name for the connection state <b>state</b>
 * for the connection type <b>type</b>
 */
69
const char *
70
71
conn_state_to_string(int type, int state)
{
72
73
74
75
  static char buf[96];
  switch (type) {
    case CONN_TYPE_OR_LISTENER:
    case CONN_TYPE_AP_LISTENER:
76
    case CONN_TYPE_AP_TRANS_LISTENER:
77
    case CONN_TYPE_AP_NATD_LISTENER:
78
    case CONN_TYPE_AP_DNS_LISTENER:
79
80
81
82
83
84
85
86
87
88
    case CONN_TYPE_DIR_LISTENER:
    case CONN_TYPE_CONTROL_LISTENER:
      if (state == LISTENER_STATE_READY)
        return "ready";
      break;
    case CONN_TYPE_OR:
      switch (state) {
        case OR_CONN_STATE_CONNECTING: return "connect()ing";
        case OR_CONN_STATE_PROXY_FLUSHING: return "proxy flushing";
        case OR_CONN_STATE_PROXY_READING: return "proxy reading";
Roger Dingledine's avatar
Roger Dingledine committed
89
        case OR_CONN_STATE_HANDSHAKING: return "handshaking";
90
91
92
93
94
95
96
97
98
99
100
101
102
        case OR_CONN_STATE_OPEN: return "open";
      }
      break;
    case CONN_TYPE_EXIT:
      switch (state) {
        case EXIT_CONN_STATE_RESOLVING: return "waiting for dest info";
        case EXIT_CONN_STATE_CONNECTING: return "connecting";
        case EXIT_CONN_STATE_OPEN: return "open";
        case EXIT_CONN_STATE_RESOLVEFAILED: return "resolve failed";
      }
      break;
    case CONN_TYPE_AP:
      switch (state) {
103
        case AP_CONN_STATE_SOCKS_WAIT: return "waiting for socks info";
104
        case AP_CONN_STATE_NATD_WAIT: return "waiting for natd dest info";
105
106
        case AP_CONN_STATE_RENDDESC_WAIT: return "waiting for rendezvous desc";
        case AP_CONN_STATE_CONTROLLER_WAIT: return "waiting for controller";
107
108
109
        case AP_CONN_STATE_CIRCUIT_WAIT: return "waiting for circuit";
        case AP_CONN_STATE_CONNECT_WAIT: return "waiting for connect response";
        case AP_CONN_STATE_RESOLVE_WAIT: return "waiting for resolve response";
110
111
112
113
114
115
116
        case AP_CONN_STATE_OPEN: return "open";
      }
      break;
    case CONN_TYPE_DIR:
      switch (state) {
        case DIR_CONN_STATE_CONNECTING: return "connecting";
        case DIR_CONN_STATE_CLIENT_SENDING: return "client sending";
Roger Dingledine's avatar
Roger Dingledine committed
117
        case DIR_CONN_STATE_CLIENT_READING: return "client reading";
118
        case DIR_CONN_STATE_CLIENT_FINISHED: return "client finished";
119
120
121
122
123
124
125
126
127
128
129
130
        case DIR_CONN_STATE_SERVER_COMMAND_WAIT: return "waiting for command";
        case DIR_CONN_STATE_SERVER_WRITING: return "writing";
      }
      break;
    case CONN_TYPE_CPUWORKER:
      switch (state) {
        case CPUWORKER_STATE_IDLE: return "idle";
        case CPUWORKER_STATE_BUSY_ONION: return "busy with onion";
      }
      break;
    case CONN_TYPE_CONTROL:
      switch (state) {
131
132
        case CONTROL_CONN_STATE_OPEN: return "open (protocol v1)";
        case CONTROL_CONN_STATE_NEEDAUTH:
133
          return "waiting for authentication (protocol v1)";
134
135
136
137
      }
      break;
  }

138
  log_warn(LD_BUG, "unknown connection state %d (type %d)", state, type);
139
140
141
142
143
144
  tor_snprintf(buf, sizeof(buf),
               "unknown state [%d] on unknown [%s] connection",
               state, conn_type_to_string(type));
  return buf;
}

145
/** Allocate space for a new connection_t. This function just initializes
146
147
 * conn; you must call connection_add() to link it into the main array.
 *
148
 * Set conn-\>type to <b>type</b>. Set conn-\>s and conn-\>conn_array_index to
149
150
151
152
153
154
155
156
157
 * -1 to signify they are not yet assigned.
 *
 * If conn is not a listener type, allocate buffers for it. If it's
 * an AP type, allocate space to store the socks_request.
 *
 * Assign a pseudorandom next_circ_id between 0 and 2**15.
 *
 * Initialize conn's timestamps to now.
 */
158
159
160
connection_t *
connection_new(int type)
{
161
  static uint32_t n_connections_allocated = 1;
Roger Dingledine's avatar
Roger Dingledine committed
162
  connection_t *conn;
163
  time_t now = time(NULL);
164
165
  size_t length;
  uint32_t magic;
Roger Dingledine's avatar
Roger Dingledine committed
166

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
192
  switch (type) {
    case CONN_TYPE_OR:
      length = sizeof(or_connection_t);
      magic = OR_CONNECTION_MAGIC;
      break;
    case CONN_TYPE_EXIT:
    case CONN_TYPE_AP:
      length = sizeof(edge_connection_t);
      magic = EDGE_CONNECTION_MAGIC;
      break;
    case CONN_TYPE_DIR:
      length = sizeof(dir_connection_t);
      magic = DIR_CONNECTION_MAGIC;
      break;
    case CONN_TYPE_CONTROL:
      length = sizeof(control_connection_t);
      magic = CONTROL_CONNECTION_MAGIC;
      break;
    default:
      length = sizeof(connection_t);
      magic = BASE_CONNECTION_MAGIC;
      break;
  }

  conn = tor_malloc_zero(length);
  conn->magic = magic;
193
  conn->s = -1; /* give it a default of 'not used' */
194
  conn->conn_array_index = -1; /* also default to 'not used' */
Roger Dingledine's avatar
Roger Dingledine committed
195
196

  conn->type = type;
197
  if (!connection_is_listener(conn)) { /* listeners never use their buf */
198
199
200
    conn->inbuf = buf_new();
    conn->outbuf = buf_new();
  }
201
  if (type == CONN_TYPE_AP) {
202
203
    TO_EDGE_CONN(conn)->socks_request =
      tor_malloc_zero(sizeof(socks_request_t));
204
  }
205
206
207
  if (CONN_IS_EDGE(conn)) {
    TO_EDGE_CONN(conn)->global_identifier = n_connections_allocated++;
  }
208
209
  if (type == CONN_TYPE_OR)
    TO_OR_CONN(conn)->next_circ_id = crypto_rand_int(1<<15);
210

211
212
213
  conn->timestamp_created = now;
  conn->timestamp_lastread = now;
  conn->timestamp_lastwritten = now;
214

Roger Dingledine's avatar
Roger Dingledine committed
215
216
217
  return conn;
}

Roger Dingledine's avatar
Roger Dingledine committed
218
/** Create a link between <b>conn_a</b> and <b>conn_b</b>. */
219
220
221
222
223
224
225
226
227
228
229
230
void
connection_link_connections(connection_t *conn_a, connection_t *conn_b)
{
  tor_assert(conn_a->s < 0);
  tor_assert(conn_b->s < 0);

  conn_a->linked = 1;
  conn_b->linked = 1;
  conn_a->linked_conn = conn_b;
  conn_b->linked_conn = conn_a;
}

231
232
/** Tell libevent that we don't care about <b>conn</b> any more. */
void
233
connection_unregister_events(connection_t *conn)
234
235
236
{
  if (conn->read_event) {
    if (event_del(conn->read_event))
Roger Dingledine's avatar
Roger Dingledine committed
237
      log_warn(LD_BUG, "Error removing read event for %d", conn->s);
238
239
240
241
    tor_free(conn->read_event);
  }
  if (conn->write_event) {
    if (event_del(conn->write_event))
Roger Dingledine's avatar
Roger Dingledine committed
242
      log_warn(LD_BUG, "Error removing write event for %d", conn->s);
243
244
    tor_free(conn->write_event);
  }
245
246
247
  if (conn->dns_server_port) {
    dnsserv_close_listener(conn);
  }
248
249
}

250
251
252
/** Deallocate memory used by <b>conn</b>. Deallocate its buffers if
 * necessary, close its socket if necessary, and mark the directory as dirty
 * if <b>conn</b> is an OR or OP connection.
253
 */
254
static void
255
256
_connection_free(connection_t *conn)
{
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
  void *mem;
  switch (conn->type) {
    case CONN_TYPE_OR:
      tor_assert(conn->magic == OR_CONNECTION_MAGIC);
      mem = TO_OR_CONN(conn);
      break;
    case CONN_TYPE_AP:
    case CONN_TYPE_EXIT:
      tor_assert(conn->magic == EDGE_CONNECTION_MAGIC);
      mem = TO_EDGE_CONN(conn);
      break;
    case CONN_TYPE_DIR:
      tor_assert(conn->magic == DIR_CONNECTION_MAGIC);
      mem = TO_DIR_CONN(conn);
      break;
    case CONN_TYPE_CONTROL:
      tor_assert(conn->magic == CONTROL_CONNECTION_MAGIC);
      mem = TO_CONTROL_CONN(conn);
      break;
    default:
      tor_assert(conn->magic == BASE_CONNECTION_MAGIC);
      mem = conn;
      break;
  }
Roger Dingledine's avatar
Roger Dingledine committed
281

282
283
284
285
286
287
288
289
290
291
292
  if (conn->linked) {
    int severity = buf_datalen(conn->inbuf)+buf_datalen(conn->outbuf)
      ? LOG_NOTICE : LOG_INFO;
    log_fn(severity, LD_GENERAL, "Freeing linked %s connection [%s] with %d "
           "bytes on inbuf, %d on outbuf.",
           conn_type_to_string(conn->type),
           conn_state_to_string(conn->type, conn->state),
           (int)buf_datalen(conn->inbuf), (int)buf_datalen(conn->outbuf));
    // tor_assert(!buf_datalen(conn->outbuf)); /*XXXX020 remove me.*/
  }

293
  if (!connection_is_listener(conn)) {
294
295
296
    buf_free(conn->inbuf);
    buf_free(conn->outbuf);
  }
297

298
  tor_free(conn->address);
Roger Dingledine's avatar
Roger Dingledine committed
299

300
  if (connection_speaks_cells(conn)) {
301
302
303
304
    or_connection_t *or_conn = TO_OR_CONN(conn);
    if (or_conn->tls) {
      tor_tls_free(or_conn->tls);
      or_conn->tls = NULL;
305
    }
306
307
308
309
310
311
312
313
314
315
316

    tor_free(or_conn->nickname);
  }
  if (CONN_IS_EDGE(conn)) {
    edge_connection_t *edge_conn = TO_EDGE_CONN(conn);
    tor_free(edge_conn->chosen_exit_name);
    tor_free(edge_conn->socks_request);
  }
  if (conn->type == CONN_TYPE_CONTROL) {
    control_connection_t *control_conn = TO_CONTROL_CONN(conn);
    tor_free(control_conn->incoming_cmd);
Roger Dingledine's avatar
Roger Dingledine committed
317
318
  }

319
320
  tor_free(conn->read_event); /* Probably already freed by connection_free. */
  tor_free(conn->write_event); /* Probably already freed by connection_free. */
321
322
323
324
325
326
327
328
329
330
331
332
333

  if (conn->type == CONN_TYPE_DIR) {
    dir_connection_t *dir_conn = TO_DIR_CONN(conn);
    tor_free(dir_conn->requested_resource);
    if (dir_conn->zlib_state)
      tor_zlib_free(dir_conn->zlib_state);
    if (dir_conn->fingerprint_stack) {
      SMARTLIST_FOREACH(dir_conn->fingerprint_stack, char *, cp, tor_free(cp));
      smartlist_free(dir_conn->fingerprint_stack);
    }
    if (dir_conn->cached_dir)
      cached_dir_decref(dir_conn->cached_dir);
  }
334

335
  if (conn->s >= 0) {
Roger Dingledine's avatar
Roger Dingledine committed
336
    log_debug(LD_NET,"closing fd %d.",conn->s);
337
338
339
    tor_close_socket(conn->s);
  }

340
  if (conn->type == CONN_TYPE_OR &&
341
      !tor_digest_is_zero(TO_OR_CONN(conn)->identity_digest)) {
Roger Dingledine's avatar
Roger Dingledine committed
342
    log_warn(LD_BUG, "called on OR conn with non-zeroed identity_digest");
343
    connection_or_remove_from_identity_map(TO_OR_CONN(conn));
344
  }
345

346
  memset(conn, 0xAA, sizeof(connection_t)); /* poison memory */
347
  tor_free(mem);
Roger Dingledine's avatar
Roger Dingledine committed
348
349
}

350
351
/** Make sure <b>conn</b> isn't in any of the global conn lists; then free it.
 */
352
353
354
void
connection_free(connection_t *conn)
{
355
356
357
  tor_assert(conn);
  tor_assert(!connection_is_on_closeable_list(conn));
  tor_assert(!connection_in_array(conn));
358
359
360
361
362
363
364
365
366
  if (conn->linked_conn) {
    log_err(LD_BUG, "Called with conn->linked_conn still set.");
    tor_fragile_assert();
    conn->linked_conn->linked_conn = NULL;
    if (! conn->linked_conn->marked_for_close &&
        conn->linked_conn->reading_from_linked_conn)
      connection_start_reading(conn->linked_conn);
    conn->linked_conn = NULL;
  }
367
  if (connection_speaks_cells(conn)) {
368
369
    if (!tor_digest_is_zero(TO_OR_CONN(conn)->identity_digest)) {
      connection_or_remove_from_identity_map(TO_OR_CONN(conn));
370
    }
371
  }
372
  if (conn->type == CONN_TYPE_CONTROL) {
373
    TO_CONTROL_CONN(conn)->event_mask = 0;
374
375
    control_update_global_event_mask();
  }
376
  connection_unregister_events(conn);
377
378
379
  _connection_free(conn);
}

380
381
382
383
/** Call _connection_free() on every connection in our array, and release all
 * storage helpd by connection.c. This is used by cpuworkers and dnsworkers
 * when they fork, so they don't keep resources held open (especially
 * sockets).
384
385
386
 *
 * Don't do the checks in connection_free(), because they will
 * fail.
387
 */
388
389
390
void
connection_free_all(void)
{
391
  smartlist_t *conns = get_connection_array();
392

393
  /* We don't want to log any messages to controllers. */
394
395
396
397
  SMARTLIST_FOREACH(conns, connection_t *, conn,
    if (conn->type == CONN_TYPE_CONTROL)
      TO_CONTROL_CONN(conn)->event_mask = 0);

398
399
  control_update_global_event_mask();

400
401
402
  /* Unlink everything from the identity map. */
  connection_or_clear_identity_map();

403
  SMARTLIST_FOREACH(conns, connection_t *, conn, _connection_free(conn));
404
405
406
407
408
409

  if (outgoing_addrs) {
    SMARTLIST_FOREACH(outgoing_addrs, void*, addr, tor_free(addr));
    smartlist_free(outgoing_addrs);
    outgoing_addrs = NULL;
  }
410
411
}

412
413
414
415
416
417
418
419
/** Do any cleanup needed:
 *   - Directory conns that failed to fetch a rendezvous descriptor
 *     need to inform pending rendezvous streams.
 *   - OR conns need to call rep_hist_note_*() to record status.
 *   - AP conns need to send a socks reject if necessary.
 *   - Exit conns need to call connection_dns_remove() if necessary.
 *   - AP and Exit conns need to send an end cell if they can.
 *   - DNS conns need to fail any resolves that are pending on them.
420
 *   - OR and edge connections need to be unlinked from circuits.
421
 */
422
423
void
connection_about_to_close_connection(connection_t *conn)
424
{
425
  circuit_t *circ;
426
427
428
  dir_connection_t *dir_conn;
  or_connection_t *or_conn;
  edge_connection_t *edge_conn;
429
  time_t now = time(NULL);
430

431
432
  assert(conn->marked_for_close);

433
  if (CONN_IS_EDGE(conn)) {
434
    if (!conn->edge_has_sent_end) {
435
      log_warn(LD_BUG, "(Harmless.) Edge connection (marked at %s:%d) "
Roger Dingledine's avatar
Roger Dingledine committed
436
437
               "hasn't sent end yet?",
               conn->marked_for_close_file, conn->marked_for_close);
438
      tor_fragile_assert();
439
    }
440
441
  }

442
  switch (conn->type) {
443
    case CONN_TYPE_DIR:
444
      dir_conn = TO_DIR_CONN(conn);
445
446
447
      if (conn->state < DIR_CONN_STATE_CLIENT_FINISHED) {
        /* It's a directory connection and connecting or fetching
         * failed: forget about this router, and maybe try again. */
448
        connection_dir_request_failed(dir_conn);
449
        // XXX if it's rend desc we may want to retry -RD
450
      }
451
      if (conn->purpose == DIR_PURPOSE_FETCH_RENDDESC)
452
        rend_client_desc_here(dir_conn->rend_query); /* give it a try */
453
      break;
454
    case CONN_TYPE_OR:
455
      or_conn = TO_OR_CONN(conn);
456
457
      /* Remember why we're closing this connection. */
      if (conn->state != OR_CONN_STATE_OPEN) {
458
        if (connection_or_nonopen_was_started_here(or_conn)) {
459
460
          rep_hist_note_connect_failed(or_conn->identity_digest, now);
          entry_guard_register_connect_status(or_conn->identity_digest,0,now);
461
          router_set_status(or_conn->identity_digest, 0);
462
          control_event_or_conn_status(or_conn, OR_CONN_EVENT_FAILED,
463
                  control_tls_error_to_reason(or_conn->tls_error));
464
        }
465
466
467
        /* Inform any pending (not attached) circs that they should
         * give up. */
        circuit_n_conn_done(TO_OR_CONN(conn), 0);
468
      } else if (conn->hold_open_until_flushed) {
469
470
        /* We only set hold_open_until_flushed when we're intentionally
         * closing a connection. */
471
        rep_hist_note_disconnect(or_conn->identity_digest, now);
472
473
        control_event_or_conn_status(or_conn, OR_CONN_EVENT_CLOSED,
                control_tls_error_to_reason(or_conn->tls_error));
474
      } else if (or_conn->identity_digest) {
475
        rep_hist_note_connection_died(or_conn->identity_digest, now);
476
477
        control_event_or_conn_status(or_conn, OR_CONN_EVENT_CLOSED,
                control_tls_error_to_reason(or_conn->tls_error));
478
      }
479
480
481
      /* Now close all the attached circuits on it. */
      circuit_unlink_all_from_or_conn(TO_OR_CONN(conn),
                                      END_CIRC_REASON_OR_CONN_CLOSED);
482
      break;
483
    case CONN_TYPE_AP:
484
485
      edge_conn = TO_EDGE_CONN(conn);
      if (edge_conn->socks_request->has_finished == 0) {
486
487
        /* since conn gets removed right after this function finishes,
         * there's no point trying to send back a reply at this point. */
488
        log_warn(LD_BUG,"Closing stream (marked at %s:%d) without sending"
Roger Dingledine's avatar
Roger Dingledine committed
489
490
                 " back a socks reply.",
                 conn->marked_for_close_file, conn->marked_for_close);
491
      }
492
      if (!edge_conn->end_reason) {
493
        log_warn(LD_BUG,"Closing stream (marked at %s:%d) without having"
494
                 " set end_reason.",
495
496
                 conn->marked_for_close_file, conn->marked_for_close);
      }
497
498
499
500
501
502
      if (edge_conn->dns_server_request) {
        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);
        dnsserv_reject_request(edge_conn);
      }
503
      control_event_stream_status(edge_conn, STREAM_EVENT_CLOSED,
504
                                  edge_conn->end_reason);
505
506
507
      circ = circuit_get_by_edge_conn(edge_conn);
      if (circ)
        circuit_detach_stream(circ, edge_conn);
508
      break;
509
    case CONN_TYPE_EXIT:
510
      edge_conn = TO_EDGE_CONN(conn);
511
512
513
      circ = circuit_get_by_edge_conn(edge_conn);
      if (circ)
        circuit_detach_stream(circ, edge_conn);
514
      if (conn->state == EXIT_CONN_STATE_RESOLVING) {
515
        connection_dns_remove(edge_conn);
516
      }
517
      break;
518
  }
519
520
}

521
522
523
/** Close the underlying socket for <b>conn</b>, so we don't try to
 * flush it. Must be used in conjunction with (right before)
 * connection_mark_for_close().
524
 */
525
526
void
connection_close_immediate(connection_t *conn)
527
528
{
  assert_connection_ok(conn,0);
529
  if (conn->s < 0 && !conn->linked) {
530
    log_err(LD_BUG,"Attempt to close already-closed connection.");
531
    tor_fragile_assert();
532
533
    return;
  }
534
  if (conn->outbuf_flushlen) {
Roger Dingledine's avatar
Roger Dingledine committed
535
536
537
538
    log_info(LD_NET,"fd %d, type %s, state %s, %d bytes on outbuf.",
             conn->s, conn_type_to_string(conn->type),
             conn_state_to_string(conn->type, conn->state),
             (int)conn->outbuf_flushlen);
539
  }
540

541
  connection_unregister_events(conn);
542

543
544
  if (conn->s >= 0)
    tor_close_socket(conn->s);
545
  conn->s = -1;
546
  if (!connection_is_listener(conn)) {
547
548
549
    buf_clear(conn->outbuf);
    conn->outbuf_flushlen = 0;
  }
550
551
}

552
/** Mark <b>conn</b> to be closed next time we loop through
553
 * conn_close_if_marked() in main.c. */
554
555
void
_connection_mark_for_close(connection_t *conn, int line, const char *file)
556
557
{
  assert_connection_ok(conn,0);
558
559
  tor_assert(line);
  tor_assert(file);
560
561

  if (conn->marked_for_close) {
562
    log(LOG_WARN,LD_BUG,"Duplicate call to connection_mark_for_close at %s:%d"
563
564
        " (first at %s:%d)", file, line, conn->marked_for_close_file,
        conn->marked_for_close);
565
    tor_fragile_assert();
566
    return;
567
568
  }

569
570
  conn->marked_for_close = line;
  conn->marked_for_close_file = file;
571
  add_connection_to_closeable_list(conn);
572

573
574
575
576
577
578
#if 0
  /* XXXX020 Actually, I don't think this is right. */
  if (conn->linked_conn && !conn->linked_conn->marked_for_close)
    _connection_mark_for_close(conn->linked_conn, line, file);
#endif

579
580
581
582
  /* in case we're going to be held-open-til-flushed, reset
   * the number of seconds since last successful write, so
   * we get our whole 15 seconds */
  conn->timestamp_lastwritten = time(NULL);
583
584
}

585
586
587
588
589
/** Find each connection that has hold_open_until_flushed set to
 * 1 but hasn't written in the past 15 seconds, and set
 * hold_open_until_flushed to 0. This means it will get cleaned
 * up in the next loop through close_if_marked() in main.c.
 */
590
591
void
connection_expire_held_open(void)
592
593
{
  time_t now;
594
  smartlist_t *conns = get_connection_array();
595
596
597

  now = time(NULL);

598
599
  SMARTLIST_FOREACH(conns, connection_t *, conn,
  {
600
601
602
    /* If we've been holding the connection open, but we haven't written
     * for 15 seconds...
     */
603
    if (conn->hold_open_until_flushed) {
Roger Dingledine's avatar
Roger Dingledine committed
604
      tor_assert(conn->marked_for_close);
605
      if (now - conn->timestamp_lastwritten >= 15) {
Roger Dingledine's avatar
Roger Dingledine committed
606
607
        int severity;
        if (conn->type == CONN_TYPE_EXIT ||
608
609
            (conn->type == CONN_TYPE_DIR &&
             conn->purpose == DIR_PURPOSE_SERVER))
Roger Dingledine's avatar
Roger Dingledine committed
610
611
612
          severity = LOG_INFO;
        else
          severity = LOG_NOTICE;
613
        log_fn(severity, LD_NET,
614
615
               "Giving up on marked_for_close conn that's been flushing "
               "for 15s (fd %d, type %s, state %s).",
616
617
               conn->s, conn_type_to_string(conn->type),
               conn_state_to_string(conn->type, conn->state));
618
619
        conn->hold_open_until_flushed = 0;
      }
620
    }
621
  });
622
623
}

624
/** Bind a new non-blocking socket listening to
625
 * <b>listenaddress</b>:<b>listenport</b>, and add this new connection
626
 * (of type <b>type</b>) to the connection array.
Nick Mathewson's avatar
Nick Mathewson committed
627
 *
628
629
 * If <b>listenaddress</b> includes a port, we bind on that port;
 * otherwise, we use listenport.
630
 */
631
static connection_t *
632
connection_create_listener(const char *listenaddress, uint16_t listenport,
633
                           int type)
634
{
635
  struct sockaddr_in listenaddr; /* where to bind */
636
  char *address = NULL;
Roger Dingledine's avatar
Roger Dingledine committed
637
  connection_t *conn;
638
  uint16_t usePort;
639
  uint32_t addr;
640
  int s; /* the socket we're going to make */
641
#ifndef MS_WINDOWS
Roger Dingledine's avatar
Roger Dingledine committed
642
  int one=1;
643
#endif
644
  int is_tcp = (type != CONN_TYPE_AP_DNS_LISTENER);
Roger Dingledine's avatar
Roger Dingledine committed
645

646
  memset(&listenaddr,0,sizeof(struct sockaddr_in));
647
  if (parse_addr_port(LOG_WARN, listenaddress, &address, &addr, &usePort)<0) {
Roger Dingledine's avatar
Roger Dingledine committed
648
649
    log_warn(LD_CONFIG,
             "Error parsing/resolving ListenAddress %s", listenaddress);
650
    return NULL;
651
  }
652

653
  if (usePort==0)
654
655
656
657
    usePort = listenport;
  listenaddr.sin_addr.s_addr = htonl(addr);
  listenaddr.sin_family = AF_INET;
  listenaddr.sin_port = htons((uint16_t) usePort);
658

Roger Dingledine's avatar
Roger Dingledine committed
659
660
  log_notice(LD_NET, "Opening %s on %s:%d",
             conn_type_to_string(type), address, usePort);
Nick Mathewson's avatar
Nick Mathewson committed
661

662
663
664
665
666
667
668
669
670
  if (get_n_open_sockets() >= get_options()->_ConnLimit-1) {
    int n_conns = get_n_open_sockets();
    log_warn(LD_NET,"Failing because we have %d connections already. Please "
             "raise your ulimit -n.", n_conns);
    control_event_general_status(LOG_WARN, "TOO_MANY_CONNECTIONS CURRENT=%d",
                                 n_conns);
    return NULL;
  }

671
672
673
  s = tor_open_socket(PF_INET,
                      is_tcp ? SOCK_STREAM : SOCK_DGRAM,
                      is_tcp ? IPPROTO_TCP: IPPROTO_UDP);
Roger Dingledine's avatar
Roger Dingledine committed
674
  if (s < 0) {
Roger Dingledine's avatar
Roger Dingledine committed
675
    log_warn(LD_NET,"Socket creation failed.");
676
    goto err;
Roger Dingledine's avatar
Roger Dingledine committed
677
678
  }

679
680
681
#ifndef MS_WINDOWS
  /* REUSEADDR on normal places means you can rebind to the port
   * right after somebody else has let it go. But REUSEADDR on win32
682
   * means you can bind to the port _even when somebody else
683
   * already has it bound_. So, don't do that on Win32. */
684
  setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (void*) &one, sizeof(one));
685
#endif
Roger Dingledine's avatar
Roger Dingledine committed
686

687
  if (bind(s,(struct sockaddr *)&listenaddr,sizeof(listenaddr)) < 0) {
Nick Mathewson's avatar
Nick Mathewson committed
688
    const char *helpfulhint = "";
689
690
691
    int e = tor_socket_errno(s);
    if (ERRNO_IS_EADDRINUSE(e))
      helpfulhint = ". Is Tor already running?";
Roger Dingledine's avatar
Roger Dingledine committed
692
693
    log_warn(LD_NET, "Could not bind to %s:%u: %s%s", address, usePort,
             tor_socket_strerror(e), helpfulhint);
694
    tor_close_socket(s);
695
    goto err;
Roger Dingledine's avatar
Roger Dingledine committed
696
697
  }

698
699
700
701
702
703
704
  if (is_tcp) {
    if (listen(s,SOMAXCONN) < 0) {
      log_warn(LD_NET, "Could not listen on %s:%u: %s", address, usePort,
               tor_socket_strerror(tor_socket_errno(s)));
      tor_close_socket(s);
      goto err;
    }
Roger Dingledine's avatar
Roger Dingledine committed
705
706
  }

707
  set_socket_nonblocking(s);
Roger Dingledine's avatar
Roger Dingledine committed
708
709
710

  conn = connection_new(type);
  conn->s = s;
711
712
  conn->address = address;
  address = NULL;
713
  conn->port = usePort;
Roger Dingledine's avatar
Roger Dingledine committed
714

715
  if (connection_add(conn) < 0) { /* no space, forget it */
716
    log_warn(LD_NET,"connection_add for listener failed. Giving up.");
Roger Dingledine's avatar
Roger Dingledine committed
717
    connection_free(conn);
718
    goto err;
Roger Dingledine's avatar
Roger Dingledine committed
719
720
  }

Roger Dingledine's avatar
Roger Dingledine committed
721
722
  log_debug(LD_NET,"%s listening on port %u.",
            conn_type_to_string(type), usePort);
Roger Dingledine's avatar
Roger Dingledine committed
723
724

  conn->state = LISTENER_STATE_READY;
725
726
727
728
729
730
  if (is_tcp) {
    connection_start_reading(conn);
  } else {
    tor_assert(type == CONN_TYPE_AP_DNS_LISTENER);
    dnsserv_configure_listener(conn);
  }
Roger Dingledine's avatar
Roger Dingledine committed
731

732
  return conn;
733
734
735

 err:
  tor_free(address);
736
  return NULL;
Roger Dingledine's avatar
Roger Dingledine committed
737
738
}

739
740
741
742
743
744
745
746
747
/** Do basic sanity checking on a newly received socket. Return 0
 * if it looks ok, else return -1. */
static int
check_sockaddr_in(struct sockaddr *sa, int len, int level)
{
  int ok = 1;
  struct sockaddr_in *sin=(struct sockaddr_in*)sa;

  if (len != sizeof(struct sockaddr_in)) {
748
    log_fn(level, LD_NET, "Length of address not as expected: %d vs %d",
749
750
751
752
           len,(int)sizeof(struct sockaddr_in));
    ok = 0;
  }
  if (sa->sa_family != AF_INET) {
753
    log_fn(level, LD_NET, "Family of address not as expected: %d vs %d",
754
755
756
757
           sa->sa_family, AF_INET);
    ok = 0;
  }
  if (sin->sin_addr.s_addr == 0 || sin->sin_port == 0) {
758
759
    log_fn(level, LD_NET,
           "Address for new connection has address/port equal to zero.");
760
761
762
763
764
    ok = 0;
  }
  return ok ? 0 : -1;
}

765
/** The listener connection <b>conn</b> told poll() it wanted to read.
Nick Mathewson's avatar
Nick Mathewson committed
766
 * Call accept() on conn-\>s, and add the new connection if necessary.
767
 */
768
769
770
static int
connection_handle_listener_read(connection_t *conn, int new_type)
{
Roger Dingledine's avatar
Roger Dingledine committed
771
772
  int news; /* the new socket */
  connection_t *newconn;
773
774
  /* information about the remote peer when connecting to other routers */
  struct sockaddr_in remote;
775
  char addrbuf[256];
776
777
  /* length of the remote address. Must be whatever accept() needs. */
  socklen_t remotelen = 256;
778
  char tmpbuf[INET_NTOA_BUF_LEN];
Nick Mathewson's avatar
Nick Mathewson committed
779
  tor_assert((size_t)remotelen >= sizeof(struct sockaddr_in));
780
  memset(addrbuf, 0, sizeof(addrbuf));
Roger Dingledine's avatar
Roger Dingledine committed
781

782
  news = accept(conn->s,(struct sockaddr *)&addrbuf,&remotelen);
Roger Dingledine's avatar
tweak    
Roger Dingledine committed
783
  if (news < 0) { /* accept() error */
784
    int e = tor_socket_errno(conn->s);
785
    if (ERRNO_IS_ACCEPT_EAGAIN(e)) {
Roger Dingledine's avatar
Roger Dingledine committed
786
      return 0; /* he hung up before we could accept(). that's fine. */
787
    } else if (ERRNO_IS_ACCEPT_RESOURCE_LIMIT(e)) {
Roger Dingledine's avatar
Roger Dingledine committed
788
789
      log_notice(LD_NET,"accept failed: %s. Dropping incoming connection.",
                 tor_socket_strerror(e));
790
      return 0;
791
    }
Roger Dingledine's avatar
Roger Dingledine committed
792
    /* else there was a real error. */
Roger Dingledine's avatar
Roger Dingledine committed
793
794
    log_warn(LD_NET,"accept() failed: %s. Closing listener.",
             tor_socket_strerror(e));
795
    connection_mark_for_close(conn);
Roger Dingledine's avatar
Roger Dingledine committed
796
797
    return -1;
  }
Roger Dingledine's avatar
Roger Dingledine committed
798
799
800
  log_debug(LD_NET,
            "Connection accepted on socket %d (child of fd %d).",
            news,conn->s);
Roger Dingledine's avatar
Roger Dingledine committed
801

802
  set_socket_nonblocking(news);
803

804
  if (check_sockaddr_in((struct sockaddr*)addrbuf, remotelen, LOG_INFO)<0) {
Roger Dingledine's avatar
Roger Dingledine committed
805
806
    log_info(LD_NET,
             "accept() returned a strange address; trying getsockname().");
807
808
809
    remotelen=256;
    memset(addrbuf, 0, sizeof(addrbuf));
    if (getsockname(news, (struct sockaddr*)addrbuf, &remotelen)<0) {
810
811
      int e = tor_socket_errno(news);
      log_warn(LD_NET, "getsockname() for new connection failed: %s",
812
               tor_socket_strerror(e));
813
    } else {
814
815
      if (check_sockaddr_in((struct sockaddr*)addrbuf, remotelen,
                            LOG_WARN) < 0) {
Roger Dingledine's avatar
Roger Dingledine committed
816
        log_warn(LD_NET,"Something's wrong with this conn. Closing it.");
817
818
819
820
821
822
823
        tor_close_socket(news);
        return 0;
      }
    }
  }
  memcpy(&remote, addrbuf, sizeof(struct sockaddr_in));

824
  /* process entrance policies here, before we even create the connection */
825
  if (new_type == CONN_TYPE_AP) {
826
    /* check sockspolicy to see if we should accept it */
827
    if (socks_policy_permits_address(ntohl(remote.sin_addr.s_addr)) == 0) {
828
      tor_inet_ntoa(&remote.sin_addr, tmpbuf, sizeof(tmpbuf));
Roger Dingledine's avatar
Roger Dingledine committed
829
830
      log_notice(LD_APP,"Denying socks connection from untrusted address %s.",
                 tmpbuf);
831
832
833
834
      tor_close_socket(news);
      return 0;
    }
  }
835
  if (new_type == CONN_TYPE_DIR) {
836
    /* check dirpolicy to see if we should accept it */
837
    if (dir_policy_permits_address(ntohl(remote.sin_addr.s_addr)) == 0) {
838
      tor_inet_ntoa(&remote.sin_addr, tmpbuf, sizeof(tmpbuf));
Roger Dingledine's avatar
Roger Dingledine committed
839
840
      log_notice(LD_DIRSERV,"Denying dir connection from address %s.",
                 tmpbuf);
841
842
843
844
      tor_close_socket(news);
      return 0;
    }
  }
845

Roger Dingledine's avatar
Roger Dingledine committed
846
847
848
  newconn = connection_new(new_type);
  newconn->s = news;

849
  /* remember the remote address */
850
851
  newconn->addr = ntohl(remote.sin_addr.s_addr);
  newconn->port = ntohs(remote.sin_port);
852
  newconn->address = tor_dup_addr(newconn->addr);
Roger Dingledine's avatar
Roger Dingledine committed
853

854
  if (connection_add(newconn) < 0) { /* no space, forget it */
Roger Dingledine's avatar
Roger Dingledine committed
855
    connection_free(newconn);
856
    return 0; /* no need to tear down the parent */
Roger Dingledine's avatar
Roger Dingledine committed
857
858
  }

859
  if (connection_init_accepted_conn(newconn, conn->type) < 0) {
860
    connection_mark_for_close(newconn);
861
862
863
864
865
    return 0;
  }
  return 0;
}

866
867
/** Initialize states for newly accepted connection <b>conn</b>.
 * If conn is an OR, start the tls handshake.
868
869
 * If conn is a transparent AP, get its original destination
 * and place it in circuit_wait.
870
 */
871
static int
872
connection_init_accepted_conn(connection_t *conn, uint8_t listener_type)
873
{
874
875
  connection_start_reading(conn);

876
  switch (conn->type) {
877
    case CONN_TYPE_OR:
878
      control_event_or_conn_status(TO_OR_CONN(conn), OR_CONN_EVENT_NEW, 0);
879
      return connection_tls_start_handshake(TO_OR_CONN(conn), 1);
880
    case CONN_TYPE_AP:
881
882
883
884
885
      switch (listener_type) {
        case CONN_TYPE_AP_LISTENER:
          conn->state = AP_CONN_STATE_SOCKS_WAIT;
          break;
        case CONN_TYPE_AP_TRANS_LISTENER:
886
887
          conn->state = AP_CONN_STATE_CIRCUIT_WAIT;
          return connection_ap_process_transparent(TO_EDGE_CONN(conn));
888
889
890
        case CONN_TYPE_AP_NATD_LISTENER:
          conn->state = AP_CONN_STATE_NATD_WAIT;
          break;
891
      }
892
893
      break;
    case CONN_TYPE_DIR:
Roger Dingledine's avatar
Roger Dingledine committed
894
      conn->purpose = DIR_PURPOSE_SERVER;
895
      conn->state = DIR_CONN_STATE_SERVER_COMMAND_WAIT;
896
      break;
897
    case CONN_TYPE_CONTROL:
898
      conn->state = CONTROL_CONN_STATE_NEEDAUTH;
899
      break;
900
901
902
903
  }
  return 0;
}

904
/** Take conn, make a nonblocking socket; try to connect to
905
 * addr:port (they arrive in *host order*). If fail, return -1. Else
906
 * assign s to conn-\>s: if connected return 1, if EAGAIN return 0.
907
908
909
 *
 * address is used to make the logs useful.
 *
Nick Mathewson's avatar
Nick Mathewson committed
910
 * On success, add conn to the list of polled connections.
911
 */
912
int
913
connection_connect(connection_t *conn, const char *address,
914
915
                   uint32_t addr, uint16_t port)
{
916
  int s, inprogress = 0;
917
  struct sockaddr_in dest_addr;
918
  or_options_t *options = get_options();
919

920
921
922
923
924
925
926
927
928
929
  if (get_n_open_sockets() >= get_options()->_ConnLimit-1) {
    int n_conns = get_n_open_sockets();
    log_warn(LD_NET,"Failing because we have %d connections already. Please "
             "raise your ulimit -n.", n_conns);
    control_event_general_status(LOG_WARN, "TOO_MANY_CONNECTIONS CURRENT=%d",
                                 n_conns);
    return -1;
  }

  s = tor_open_socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
930
  if (s < 0) {
Roger Dingledine's avatar
Roger Dingledine committed
931
932
    log_warn(LD_NET,"Error creating network socket: %s",
             tor_socket_strerror(tor_socket_errno(-1)));
933
934
    return -1;
  }
935

936
  if (options->OutboundBindAddress) {
937
938
939
940
941
    struct sockaddr_in ext_addr;

    memset(&ext_addr, 0, sizeof(ext_addr));
    ext_addr.sin_family = AF_INET;
    ext_addr.sin_port = 0;
942
    if (!tor_inet_aton(options->OutboundBindAddress, &ext_addr.sin_addr)) {
Roger Dingledine's avatar
Roger Dingledine committed
943
944
      log_warn(LD_CONFIG,"Outbound bind address '%s' didn't parse. Ignoring.",
               options->OutboundBindAddress);