circuit.c 30.4 KB
Newer Older
1
2
3
/* Copyright 2001,2002 Roger Dingledine, Matej Pfajfar. */
/* See LICENSE for licensing information */
/* $Id$ */
Roger Dingledine's avatar
Roger Dingledine committed
4
5
6

#include "or.h"

7
8
extern or_options_t options; /* command-line and config-file options */

Roger Dingledine's avatar
Roger Dingledine committed
9
10
11
12
static void circuit_free_cpath(crypt_path_t *cpath);
static void circuit_free_cpath_node(crypt_path_t *victim);
static aci_t get_unique_aci_by_addr_port(uint32_t addr, uint16_t port, int aci_type);  

Roger Dingledine's avatar
Roger Dingledine committed
13
14
/********* START VARIABLES **********/

Roger Dingledine's avatar
Roger Dingledine committed
15
static circuit_t *global_circuitlist=NULL;
Roger Dingledine's avatar
Roger Dingledine committed
16

17
18
char *circuit_state_to_string[] = {
  "receiving the onion",    /* 0 */
19
20
21
  "waiting to process create", /* 1 */
  "connecting to firsthop", /* 2 */
  "open"                    /* 3 */
22
23
};

Roger Dingledine's avatar
Roger Dingledine committed
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
/********* END VARIABLES ************/

void circuit_add(circuit_t *circ) {

  if(!global_circuitlist) { /* first one */
    global_circuitlist = circ;
    circ->next = NULL;
  } else {
    circ->next = global_circuitlist;
    global_circuitlist = circ;
  }

}

void circuit_remove(circuit_t *circ) {
  circuit_t *tmpcirc;

Roger Dingledine's avatar
Roger Dingledine committed
41
  assert(circ && global_circuitlist);
Roger Dingledine's avatar
Roger Dingledine committed
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57

  if(global_circuitlist == circ) {
    global_circuitlist = global_circuitlist->next;
    return;
  }

  for(tmpcirc = global_circuitlist;tmpcirc->next;tmpcirc = tmpcirc->next) {
    if(tmpcirc->next == circ) {
      tmpcirc->next = circ->next;
      return;
    }
  }
}

circuit_t *circuit_new(aci_t p_aci, connection_t *p_conn) {
  circuit_t *circ; 
58
59
  struct timeval now;

60
  my_gettimeofday(&now);
Roger Dingledine's avatar
Roger Dingledine committed
61

62
  circ = (circuit_t *)tor_malloc(sizeof(circuit_t));
Roger Dingledine's avatar
Roger Dingledine committed
63
64
  memset(circ,0,sizeof(circuit_t)); /* zero it out */

65
66
  circ->timestamp_created = now.tv_sec;

Roger Dingledine's avatar
Roger Dingledine committed
67
68
69
  circ->p_aci = p_aci;
  circ->p_conn = p_conn;

70
  circ->state = CIRCUIT_STATE_ONIONSKIN_PENDING;
Roger Dingledine's avatar
Roger Dingledine committed
71
72
73

  /* ACIs */
  circ->p_aci = p_aci;
Roger Dingledine's avatar
Roger Dingledine committed
74
  /* circ->n_aci remains 0 because we haven't identified the next hop yet */
Roger Dingledine's avatar
Roger Dingledine committed
75

76
77
  circ->package_window = CIRCWINDOW_START;
  circ->deliver_window = CIRCWINDOW_START;
78

Roger Dingledine's avatar
Roger Dingledine committed
79
80
81
82
83
84
  circuit_add(circ);

  return circ;
}

void circuit_free(circuit_t *circ) {
85
86
87
88
  if (circ->n_crypto)
    crypto_free_cipher_env(circ->n_crypto);
  if (circ->p_crypto)
    crypto_free_cipher_env(circ->p_crypto);
89
  circuit_free_cpath(circ->cpath);
Roger Dingledine's avatar
Roger Dingledine committed
90
  free(circ);
91
92
}

Roger Dingledine's avatar
Roger Dingledine committed
93
static void circuit_free_cpath(crypt_path_t *cpath) {
94
  crypt_path_t *victim, *head=cpath;
95

96
97
98
99
100
101
102
103
104
105
106
107
108
  if(!cpath)
    return;

  /* it's a doubly linked list, so we have to notice when we've
   * gone through it once. */
  while(cpath->next && cpath->next != head) {
    victim = cpath;
    cpath = victim->next;
    circuit_free_cpath_node(victim);
  }

  circuit_free_cpath_node(cpath);
}
Roger Dingledine's avatar
Roger Dingledine committed
109

Roger Dingledine's avatar
Roger Dingledine committed
110
static void circuit_free_cpath_node(crypt_path_t *victim) {
111
112
113
114
  if(victim->f_crypto)
    crypto_free_cipher_env(victim->f_crypto);
  if(victim->b_crypto)
    crypto_free_cipher_env(victim->b_crypto);
115
116
  if(victim->handshake_state)
    crypto_dh_free(victim->handshake_state);
117
  free(victim);
Roger Dingledine's avatar
Roger Dingledine committed
118
119
}

Roger Dingledine's avatar
Roger Dingledine committed
120
/* return 0 if can't get a unique aci. */
Roger Dingledine's avatar
Roger Dingledine committed
121
static aci_t get_unique_aci_by_addr_port(uint32_t addr, uint16_t port, int aci_type) {
Roger Dingledine's avatar
Roger Dingledine committed
122
123
  aci_t test_aci;
  connection_t *conn;
124
  uint16_t high_bit;
125

126
  high_bit = (aci_type == ACI_TYPE_HIGHER) ? 1<<15 : 0;
127
128
  conn = connection_exact_get_by_addr_port(addr,port);
  if (!conn)
Roger Dingledine's avatar
Roger Dingledine committed
129
    return (1|high_bit); /* No connection exists; conflict is impossible. */
130

131
  do {
132
133
    /* Sequentially iterate over test_aci=1...1<<15-1 until we find an
     * aci such that (high_bit|test_aci) is not already used. */
Roger Dingledine's avatar
Roger Dingledine committed
134
135
    /* XXX Will loop forever if all aci's in our range are used.
     * This matters because it's an external DoS vulnerability. */
136
137
138
139
140
141
    test_aci = conn->next_aci++;
    if (test_aci == 0 || test_aci >= 1<<15) {
      test_aci = 1;
      conn->next_aci = 2;
    }
    test_aci |= high_bit;
142
  } while(circuit_get_by_aci_conn(test_aci, conn));
Roger Dingledine's avatar
Roger Dingledine committed
143
144
145
  return test_aci;
}

146
circuit_t *circuit_enumerate_by_naddr_nport(circuit_t *circ, uint32_t naddr, uint16_t nport) {
147

148
149
150
151
152
  if(!circ) /* use circ if it's defined, else start from the beginning */
    circ = global_circuitlist; 
  else
    circ = circ->next;

153
  for( ; circ; circ = circ->next) {
154
155
156
157
158
159
    if(circ->n_addr == naddr && circ->n_port == nport)
       return circ;
  }
  return NULL;
}

Roger Dingledine's avatar
Roger Dingledine committed
160
161
circuit_t *circuit_get_by_aci_conn(aci_t aci, connection_t *conn) {
  circuit_t *circ;
162
  connection_t *tmpconn;
Roger Dingledine's avatar
Roger Dingledine committed
163
164

  for(circ=global_circuitlist;circ;circ = circ->next) {
165
    if(circ->p_aci == aci) {
166
167
168
      if(circ->p_conn == conn)
        return circ;
      for(tmpconn = circ->p_streams; tmpconn; tmpconn = tmpconn->next_stream) {
169
170
171
172
173
        if(tmpconn == conn)
          return circ;
      }
    }
    if(circ->n_aci == aci) {
174
175
176
      if(circ->n_conn == conn)
        return circ;
      for(tmpconn = circ->n_streams; tmpconn; tmpconn = tmpconn->next_stream) {
177
178
179
180
        if(tmpconn == conn)
          return circ;
      }
    }
Roger Dingledine's avatar
Roger Dingledine committed
181
182
183
184
185
186
  }
  return NULL;
}

circuit_t *circuit_get_by_conn(connection_t *conn) {
  circuit_t *circ;
187
  connection_t *tmpconn;
Roger Dingledine's avatar
Roger Dingledine committed
188
189

  for(circ=global_circuitlist;circ;circ = circ->next) {
190
191
192
193
194
    if(circ->p_conn == conn)
      return circ;
    if(circ->n_conn == conn)
      return circ;
    for(tmpconn = circ->p_streams; tmpconn; tmpconn=tmpconn->next_stream)
195
196
      if(tmpconn == conn)
        return circ;
197
    for(tmpconn = circ->n_streams; tmpconn; tmpconn=tmpconn->next_stream)
198
199
      if(tmpconn == conn)
        return circ;
Roger Dingledine's avatar
Roger Dingledine committed
200
201
202
203
  }
  return NULL;
}

Roger Dingledine's avatar
Roger Dingledine committed
204
circuit_t *circuit_get_newest_open(void) {
205
  circuit_t *circ, *bestcirc=NULL;
206
207

  for(circ=global_circuitlist;circ;circ = circ->next) {
Roger Dingledine's avatar
Roger Dingledine committed
208
    if(circ->cpath && circ->state == CIRCUIT_STATE_OPEN && circ->n_conn && (!bestcirc ||
209
      bestcirc->timestamp_created < circ->timestamp_created)) {
Roger Dingledine's avatar
Roger Dingledine committed
210
      log_fn(LOG_DEBUG,"Choosing circuit %s:%d:%d.", circ->n_conn->address, circ->n_port, circ->n_aci);
211
212
      assert(circ->n_aci);
      bestcirc = circ;
213
214
    }
  }
215
  return bestcirc;
216
217
}

218
219
220
221
222
int circuit_deliver_relay_cell(cell_t *cell, circuit_t *circ,
                               int cell_direction, crypt_path_t *layer_hint) {
  connection_t *conn=NULL;
  char recognized=0;
  char buf[256];
223
224
225
226

  assert(cell && circ);
  assert(cell_direction == CELL_DIRECTION_OUT || cell_direction == CELL_DIRECTION_IN); 

227
228
  buf[0] = cell->length;
  memcpy(buf+1, cell->payload, CELL_PAYLOAD_SIZE);
Roger Dingledine's avatar
Roger Dingledine committed
229

230
  log_fn(LOG_DEBUG,"direction %d, streamid %d before crypt.", cell_direction, *(int*)(cell->payload+1));
231

232
  if(relay_crypt(circ, buf, 1+CELL_PAYLOAD_SIZE, cell_direction, &layer_hint, &recognized, &conn) < 0) {
233
    log_fn(LOG_WARNING,"relay crypt failed. Dropping connection.");
Roger Dingledine's avatar
Roger Dingledine committed
234
235
236
    return -1;
  }

237
238
239
240
241
  cell->length = buf[0];
  memcpy(cell->payload, buf+1, CELL_PAYLOAD_SIZE);

  if(recognized) {
    if(cell_direction == CELL_DIRECTION_OUT) {
242
      log_fn(LOG_DEBUG,"Sending to exit.");
243
      return connection_edge_process_relay_cell(cell, circ, conn, EDGE_EXIT, NULL);
244
245
    }
    if(cell_direction == CELL_DIRECTION_IN) {
246
      log_fn(LOG_DEBUG,"Sending to AP.");
247
      return connection_edge_process_relay_cell(cell, circ, conn, EDGE_AP, layer_hint);
248
    }
Roger Dingledine's avatar
Roger Dingledine committed
249
  }
250
251
252
253
254
255
256

  /* not recognized. pass it on. */
  if(cell_direction == CELL_DIRECTION_OUT)
    conn = circ->n_conn;
  else
    conn = circ->p_conn;

257
  if(!conn) { //|| !connection_speaks_cells(conn)) {
258
    log_fn(LOG_INFO,"Didn't recognize cell (%d), but circ stops here! Dropping.", *(int *)(cell->payload+1));
259
    return 0;
260
  }
261

262
  log_fn(LOG_DEBUG,"Passing on unrecognized cell.");
263
  return connection_write_cell_to_buf(cell, conn);
Roger Dingledine's avatar
Roger Dingledine committed
264
265
}

266
int relay_crypt(circuit_t *circ, char *in, int inlen, char cell_direction,
267
                crypt_path_t **layer_hint, char *recognized, connection_t **conn) {
268
  crypt_path_t *thishop;
269
  char out[256];
Roger Dingledine's avatar
Roger Dingledine committed
270

271
  assert(circ && in && recognized && conn);
Roger Dingledine's avatar
Roger Dingledine committed
272

273
  assert(inlen < 256);
Roger Dingledine's avatar
Roger Dingledine committed
274

Roger Dingledine's avatar
Roger Dingledine committed
275
  if(cell_direction == CELL_DIRECTION_IN) { 
276
    if(circ->cpath) { /* we're at the beginning of the circuit. We'll want to do layered crypts. */
277
      thishop = circ->cpath;
278
      if(thishop->state != CPATH_STATE_OPEN) {
279
        log_fn(LOG_WARNING,"Relay cell before first created cell?");
280
281
        return -1;
      }
282
      do { /* Remember: cpath is in forward order, that is, first hop first. */
283
        assert(thishop);
284

285
        log_fn(LOG_DEBUG,"before decrypt: %d",*(int*)(in+2));
286
287
        /* decrypt */
        if(crypto_cipher_decrypt(thishop->b_crypto, in, inlen, out)) {
288
          log_fn(LOG_WARNING,"Error performing onion decryption: %s", crypto_perror());
289
290
291
          return -1;
        }
        memcpy(in,out,inlen);
292
        log_fn(LOG_DEBUG,"after decrypt: %d",*(int*)(in+2));
293

294
295
        if( (*recognized = relay_check_recognized(circ, cell_direction, in+2, conn))) {
          *layer_hint = thishop;
296
          return 0;
297
        }
298

299
        thishop = thishop->next;
300
      } while(thishop != circ->cpath && thishop->state == CPATH_STATE_OPEN);
301
      log_fn(LOG_INFO,"in-cell at OP not recognized. Dropping.");
302
      return 0;
303
    } else { /* we're in the middle. Just one crypt. */
304

305
      log_fn(LOG_DEBUG,"before encrypt: %d",*(int*)(in+2));
306
      if(crypto_cipher_encrypt(circ->p_crypto, in, inlen, out)) {
307
        log_fn(LOG_WARNING,"Onion encryption failed for ACI %u: %s",
308
            circ->p_aci, crypto_perror());
309
310
311
        return -1;
      }
      memcpy(in,out,inlen);
312
      log_fn(LOG_DEBUG,"after encrypt: %d",*(int*)(in+2));
313

314
      log_fn(LOG_DEBUG,"Skipping recognized check, because we're not the OP.");
315
316
      /* don't check for recognized. only the OP can recognize a stream on the way back. */

Roger Dingledine's avatar
Roger Dingledine committed
317
    }
Roger Dingledine's avatar
Roger Dingledine committed
318
  } else if(cell_direction == CELL_DIRECTION_OUT) { 
319
    if(circ->cpath) { /* we're at the beginning of the circuit. We'll want to do layered crypts. */
320

321
      thishop = *layer_hint; /* we already know which layer, from when we package_raw_inbuf'ed */
322
323
324
      /* moving from last to first hop */
      do {
        assert(thishop);
325

326
        log_fn(LOG_DEBUG,"before encrypt: %d",*(int*)(in+2));
327
        if(crypto_cipher_encrypt(thishop->f_crypto, in, inlen, out)) {
328
          log_fn(LOG_WARNING,"Error performing encryption: %s", crypto_perror());
329
330
331
          return -1;
        }
        memcpy(in,out,inlen);
332
        log_fn(LOG_DEBUG,"after encrypt: %d",*(int*)(in+2));
333

334
335
        thishop = thishop->prev;
      } while(thishop != circ->cpath->prev);
336
    } else { /* we're in the middle. Just one crypt. */
337

338
      if(crypto_cipher_decrypt(circ->n_crypto,in, inlen, out)) {
339
        log_fn(LOG_WARNING,"Decryption failed for ACI %u: %s",
340
               circ->n_aci, crypto_perror());
341
342
343
        return -1;
      }
      memcpy(in,out,inlen);
344
345
346
347

      if( (*recognized = relay_check_recognized(circ, cell_direction, in+2, conn)))
        return 0;

Roger Dingledine's avatar
Roger Dingledine committed
348
    }
349
  } else {
350
    log_fn(LOG_ERR,"unknown cell direction %d.", cell_direction);
351
    assert(0);
Roger Dingledine's avatar
Roger Dingledine committed
352
353
  }

354
355
356
  return 0;
}

357
358
359
360
int relay_check_recognized(circuit_t *circ, int cell_direction, char *stream, connection_t **conn) {
/* FIXME can optimize by passing thishop in */
  connection_t *tmpconn;

361
  if(!memcmp(stream,ZERO_STREAM,STREAM_ID_SIZE)) {
362
    log_fn(LOG_DEBUG,"It's the zero stream. Recognized.");
363
    return 1; /* the zero stream is always recognized */
364
  }
365
  log_fn(LOG_DEBUG,"not the zero stream.");
366
367

  if(cell_direction == CELL_DIRECTION_OUT)
368
    tmpconn = circ->n_streams;
369
  else
370
    tmpconn = circ->p_streams;
371

372
  if(!tmpconn) {
373
    log_fn(LOG_DEBUG,"No conns. Not recognized.");
374
    return 0;
375
376
377
378
  }

  for( ; tmpconn; tmpconn=tmpconn->next_stream) {
    if(!memcmp(stream,tmpconn->stream_id, STREAM_ID_SIZE)) {
379
      log_fn(LOG_DEBUG,"recognized stream %d.", *(int*)stream);
380
381
382
      *conn = tmpconn;
      return 1;
    }
383
    log_fn(LOG_DEBUG,"considered stream %d, not it.",*(int*)tmpconn->stream_id);
384
385
  }

386
  log_fn(LOG_DEBUG,"Didn't recognize on this iteration of decryption.");
387
388
389
390
  return 0;

}

391
void circuit_resume_edge_reading(circuit_t *circ, int edge_type, crypt_path_t *layer_hint) {
392
393
394
395
  connection_t *conn;

  assert(edge_type == EDGE_EXIT || edge_type == EDGE_AP);

396
  log_fn(LOG_DEBUG,"resuming");
397

Roger Dingledine's avatar
   
Roger Dingledine committed
398
  if(edge_type == EDGE_EXIT)
399
    conn = circ->n_streams;
Roger Dingledine's avatar
   
Roger Dingledine committed
400
  else
401
    conn = circ->p_streams;
Roger Dingledine's avatar
   
Roger Dingledine committed
402

403
  for( ; conn; conn=conn->next_stream) {
404
405
    if((edge_type == EDGE_EXIT && conn->package_window > 0) ||
       (edge_type == EDGE_AP   && conn->package_window > 0 && conn->cpath_layer == layer_hint)) {
406
407
      connection_start_reading(conn);
      connection_package_raw_inbuf(conn); /* handle whatever might still be on the inbuf */
408
409
410
411

      /* If the circuit won't accept any more data, return without looking
       * at any more of the streams. Any connections that should be stopped
       * have already been stopped by connection_package_raw_inbuf. */
412
413
      if(circuit_consider_stop_edge_reading(circ, edge_type, layer_hint))
        return;
414
415
416
417
418
    }
  }
}

/* returns 1 if the window is empty, else 0. If it's empty, tell edge conns to stop reading. */
419
int circuit_consider_stop_edge_reading(circuit_t *circ, int edge_type, crypt_path_t *layer_hint) {
420
421
422
  connection_t *conn = NULL;

  assert(edge_type == EDGE_EXIT || edge_type == EDGE_AP);
423
  assert(edge_type == EDGE_EXIT || layer_hint);
424

425
  log_fn(LOG_DEBUG,"considering");
426
  if(edge_type == EDGE_EXIT && circ->package_window <= 0)
427
    conn = circ->n_streams;
428
  else if(edge_type == EDGE_AP && layer_hint->package_window <= 0)
429
    conn = circ->p_streams;
430
431
432
  else
    return 0;

433
  for( ; conn; conn=conn->next_stream)
434
435
    if(!layer_hint || conn->cpath_layer == layer_hint)
      connection_stop_reading(conn);
436

437
  log_fn(LOG_DEBUG,"yes. stopped.");
438
439
440
  return 1;
}

441
442
int circuit_consider_sending_sendme(circuit_t *circ, int edge_type, crypt_path_t *layer_hint) {
  cell_t cell;
Roger Dingledine's avatar
Roger Dingledine committed
443

444
445
  assert(circ);

446
447
448
449
  memset(&cell, 0, sizeof(cell_t));
  cell.command = CELL_RELAY;
  SET_CELL_RELAY_COMMAND(cell, RELAY_COMMAND_SENDME);
  SET_CELL_STREAM_ID(cell, ZERO_STREAM);
450

451
  cell.length = RELAY_HEADER_SIZE;
452
  if(edge_type == EDGE_AP) { /* i'm the AP */
453
454
    cell.aci = circ->n_aci;
    while(layer_hint->deliver_window < CIRCWINDOW_START-CIRCWINDOW_INCREMENT) {
455
      log_fn(LOG_DEBUG,"deliver_window %d, Queueing sendme forward.", layer_hint->deliver_window);
456
      layer_hint->deliver_window += CIRCWINDOW_INCREMENT;
457
      if(circuit_deliver_relay_cell(&cell, circ, CELL_DIRECTION_OUT, layer_hint) < 0) {
Roger Dingledine's avatar
   
Roger Dingledine committed
458
459
        return -1;
      }
460
461
    }
  } else if(edge_type == EDGE_EXIT) { /* i'm the exit */
462
463
    cell.aci = circ->p_aci;
    while(circ->deliver_window < CIRCWINDOW_START-CIRCWINDOW_INCREMENT) {
464
      log_fn(LOG_DEBUG,"deliver_window %d, Queueing sendme back.", circ->deliver_window);
465
      circ->deliver_window += CIRCWINDOW_INCREMENT;
466
      if(circuit_deliver_relay_cell(&cell, circ, CELL_DIRECTION_IN, layer_hint) < 0) {
Roger Dingledine's avatar
   
Roger Dingledine committed
467
468
        return -1;
      }
469
470
    }
  }
Roger Dingledine's avatar
Roger Dingledine committed
471
472
473
474
  return 0;
}

void circuit_close(circuit_t *circ) {
475
  connection_t *conn;
476
  circuit_t *youngest=NULL;
477

478
  assert(circ);
479
  if(options.APPort) {
Roger Dingledine's avatar
Roger Dingledine committed
480
    youngest = circuit_get_newest_open();
481
    log_fn(LOG_DEBUG,"youngest %d, circ %d.",(int)youngest, (int)circ);
482
  }
Roger Dingledine's avatar
Roger Dingledine committed
483
  circuit_remove(circ);
484
485
486
487
  if(circ->n_conn)
    connection_send_destroy(circ->n_aci, circ->n_conn);
  for(conn=circ->n_streams; conn; conn=conn->next_stream) {
    connection_send_destroy(circ->n_aci, conn); 
488
  }
489
490
491
492
  if(circ->p_conn)
    connection_send_destroy(circ->n_aci, circ->p_conn);
  for(conn=circ->p_streams; conn; conn=conn->next_stream) {
    connection_send_destroy(circ->p_aci, conn); 
493
  }
494
495
  if(options.APPort && youngest == circ) { /* check this after we've sent the destroys, to reduce races */
    /* our current circuit just died. Launch another one pronto. */
496
    log_fn(LOG_INFO,"Youngest circuit dying. Launching a replacement.");
497
498
    circuit_launch_new(1);
  }
Roger Dingledine's avatar
Roger Dingledine committed
499
500
501
502
503
504
505
506
507
  circuit_free(circ);
}

void circuit_about_to_close_connection(connection_t *conn) {
  /* send destroys for all circuits using conn */
  /* currently, we assume it's too late to flush conn's buf here.
   * down the road, maybe we'll consider that eof doesn't mean can't-write
   */
  circuit_t *circ;
508
  connection_t *prevconn;
509
510
511

  if(!connection_speaks_cells(conn)) {
    /* it's an edge conn. need to remove it from the linked list of
512
     * conn's for this circuit. Send an 'end' relay command.
513
514
515
516
517
518
519
     * But don't kill the circuit.
     */

    circ = circuit_get_by_conn(conn);
    if(!circ)
      return;

520
521
    if(conn == circ->p_streams) {
      circ->p_streams = conn->next_stream;
522
523
      goto send_end;
    }
524
525
    if(conn == circ->n_streams) {
      circ->n_streams = conn->next_stream;
526
527
      goto send_end;
    }
Roger Dingledine's avatar
bugfix    
Roger Dingledine committed
528
529
    for(prevconn = circ->p_streams; prevconn && prevconn->next_stream && prevconn->next_stream != conn; prevconn = prevconn->next_stream) ;
    if(prevconn && prevconn->next_stream) {
530
      prevconn->next_stream = conn->next_stream;
531
532
      goto send_end;
    }
Roger Dingledine's avatar
bugfix    
Roger Dingledine committed
533
534
    for(prevconn = circ->n_streams; prevconn && prevconn->next_stream && prevconn->next_stream != conn; prevconn = prevconn->next_stream) ;
    if(prevconn && prevconn->next_stream) {
535
      prevconn->next_stream = conn->next_stream;
536
537
      goto send_end;
    }
538
    log_fn(LOG_ERR,"edge conn not in circuit's list?");
539
540
    assert(0); /* should never get here */
send_end:
541
    if(connection_edge_send_command(conn, circ, RELAY_COMMAND_END) < 0) {
542
      log_fn(LOG_DEBUG,"sending end failed. Closing.");
543
544
545
546
      circuit_close(circ);
    }
    return;
  }
Roger Dingledine's avatar
Roger Dingledine committed
547

548
  /* this connection speaks cells. We must close all the circuits on it. */
Roger Dingledine's avatar
Roger Dingledine committed
549
550
  while((circ = circuit_get_by_conn(conn))) {
    if(circ->n_conn == conn) /* it's closing in front of us */
551
      circ->n_conn = NULL;
Roger Dingledine's avatar
Roger Dingledine committed
552
    if(circ->p_conn == conn) /* it's closing behind us */
553
554
      circ->p_conn = NULL;
    circuit_close(circ);
Roger Dingledine's avatar
Roger Dingledine committed
555
556
557
  }  
}

558
/* FIXME this now leaves some out */
559
560
void circuit_dump_by_conn(connection_t *conn) {
  circuit_t *circ;
561
  connection_t *tmpconn;
562
563

  for(circ=global_circuitlist;circ;circ = circ->next) {
564
565
566
567
    if(circ->p_conn == conn)
      printf("Conn %d has App-ward circuit:  aci %d (other side %d), state %d (%s)\n",
        conn->poll_index, circ->p_aci, circ->n_aci, circ->state, circuit_state_to_string[circ->state]);
    for(tmpconn=circ->p_streams; tmpconn; tmpconn=tmpconn->next_stream) {
568
569
570
571
      if(tmpconn == conn) {
        printf("Conn %d has App-ward circuit:  aci %d (other side %d), state %d (%s)\n",
          conn->poll_index, circ->p_aci, circ->n_aci, circ->state, circuit_state_to_string[circ->state]);
      }
572
    }
573
574
575
576
    if(circ->n_conn == conn)
      printf("Conn %d has Exit-ward circuit: aci %d (other side %d), state %d (%s)\n",
        conn->poll_index, circ->n_aci, circ->p_aci, circ->state, circuit_state_to_string[circ->state]);
    for(tmpconn=circ->n_streams; tmpconn; tmpconn=tmpconn->next_stream) {
577
578
579
580
      if(tmpconn == conn) {
        printf("Conn %d has Exit-ward circuit: aci %d (other side %d), state %d (%s)\n",
          conn->poll_index, circ->n_aci, circ->p_aci, circ->state, circuit_state_to_string[circ->state]);
      }
581
582
583
584
    }
  }
}

585
586
587
588
void circuit_expire_unused_circuits(void) {
  circuit_t *circ, *tmpcirc;
  circuit_t *youngest;

Roger Dingledine's avatar
Roger Dingledine committed
589
  youngest = circuit_get_newest_open();
590
591
592
593
594

  circ = global_circuitlist;
  while(circ) {
    tmpcirc = circ;
    circ = circ->next;
595
    if(tmpcirc != youngest && !tmpcirc->p_conn && !tmpcirc->p_streams) {
596
      log_fn(LOG_DEBUG,"Closing n_aci %d",tmpcirc->n_aci);
597
598
599
600
601
602
603
604
605
606
607
608
      circuit_close(tmpcirc);
    }
  }
}

/* failure_status code: negative means reset failures to 0. Other values mean
 * add that value to the current number of failures, then if we don't have too
 * many failures on record, try to make a new circuit.
 */
void circuit_launch_new(int failure_status) {
  static int failures=0;

609
610
611
  if(!options.APPort) /* we're not an application proxy. no need for circuits. */
    return;

612
613
614
615
616
617
618
619
620
621
  if(failure_status == -1) { /* I was called because a circuit succeeded */
    failures = 0;
    return;
  }

  failures += failure_status;

retry_circuit:

  if(failures > 5) {
622
    log_fn(LOG_INFO,"Giving up for now, %d failures.", failures);
623
624
625
    return;
  }

626
  if(circuit_establish_circuit() < 0) {
627
628
629
630
631
632
633
634
    failures++;
    goto retry_circuit;
  }

  failures = 0;
  return;
}

635
int circuit_establish_circuit(void) {
636
637
638
639
640
641
  routerinfo_t *firsthop;
  connection_t *n_conn;
  circuit_t *circ;

  circ = circuit_new(0, NULL); /* sets circ->p_aci and circ->p_conn */
  circ->state = CIRCUIT_STATE_OR_WAIT;
642
643
  circ->cpath = onion_generate_cpath(&firsthop);
  if(!circ->cpath) {
644
    log_fn(LOG_INFO,"Generating cpath failed.");
645
646
647
648
649
    circuit_close(circ);
    return -1;
  }

  /* now see if we're already connected to the first OR in 'route' */
650

651
  log_fn(LOG_DEBUG,"Looking for firsthop '%s:%u'",
652
653
654
655
656
      firsthop->address,firsthop->or_port);
  n_conn = connection_twin_get_by_addr_port(firsthop->addr,firsthop->or_port);
  if(!n_conn || n_conn->state != OR_CONN_STATE_OPEN) { /* not currently connected */
    circ->n_addr = firsthop->addr;
    circ->n_port = firsthop->or_port;
657
    if(options.OnionRouter) { /* we would be connected if he were up. but he's not. */
658
      log_fn(LOG_INFO,"Route's firsthop isn't connected.");
659
660
661
662
663
      circuit_close(circ); 
      return -1;
    }

    if(!n_conn) { /* launch the connection */
664
      n_conn = connection_or_connect(firsthop);
665
      if(!n_conn) { /* connect failed, forget the whole thing */
666
        log_fn(LOG_INFO,"connect to firsthop failed. Closing.");
667
668
669
670
671
        circuit_close(circ);
        return -1;
      }
    }

672
    log_fn(LOG_DEBUG,"connecting in progress (or finished). Good.");
673
674
675
676
677
678
    return 0; /* return success. The onion/circuit/etc will be taken care of automatically
               * (may already have been) whenever n_conn reaches OR_CONN_STATE_OPEN.
               */ 
  } else { /* it (or a twin) is already open. use it. */
    circ->n_addr = n_conn->addr;
    circ->n_port = n_conn->port;
679
    circ->n_conn = n_conn;
680
    log_fn(LOG_DEBUG,"Conn open. Delivering first onion skin.");
681
    if(circuit_send_next_onion_skin(circ) < 0) {
682
      log_fn(LOG_INFO,"circuit_send_next_onion_skin failed.");
683
684
685
      circuit_close(circ);
      return -1;
    }
686
  }
687
  return 0;
688
689
690
691
692
693
}

/* find circuits that are waiting on me, if any, and get them to send the onion */
void circuit_n_conn_open(connection_t *or_conn) {
  circuit_t *circ;

694
  log_fn(LOG_DEBUG,"Starting.");
695
696
697
698
699
  circ = circuit_enumerate_by_naddr_nport(NULL, or_conn->addr, or_conn->port);
  for(;;) {
    if(!circ)
      return;

700
    log_fn(LOG_DEBUG,"Found circ, sending onion skin.");
701
702
    circ->n_conn = or_conn;
    if(circuit_send_next_onion_skin(circ) < 0) {
703
      log_fn(LOG_INFO,"send_next_onion_skin failed; circuit marked for closing.");
704
705
706
707
708
709
710
      circuit_close(circ);
      return; /* FIXME will want to try the other circuits too? */
    }
    circ = circuit_enumerate_by_naddr_nport(circ, or_conn->addr, or_conn->port);
  }
}

711
int circuit_send_next_onion_skin(circuit_t *circ) {
712
  cell_t cell;
713
714
  crypt_path_t *hop;
  routerinfo_t *router;
715

716
  assert(circ && circ->cpath);
717

718
  if(circ->cpath->state == CPATH_STATE_CLOSED) {
719

720
    log_fn(LOG_DEBUG,"First skin; sending create cell.");
721
    circ->n_aci = get_unique_aci_by_addr_port(circ->n_addr, circ->n_port, ACI_TYPE_BOTH);
722

723
    memset(&cell, 0, sizeof(cell_t));
724
725
    cell.command = CELL_CREATE;
    cell.aci = circ->n_aci;
726
    cell.length = DH_ONIONSKIN_LEN;
727

728
    if(onion_skin_create(circ->n_conn->onion_pkey, &(circ->cpath->handshake_state), cell.payload) < 0) {
729
      log_fn(LOG_WARNING,"onion_skin_create (first hop) failed.");
730
731
732
733
734
735
736
737
738
      return -1;
    }

    if(connection_write_cell_to_buf(&cell, circ->n_conn) < 0) {
      return -1;
    }

    circ->cpath->state = CPATH_STATE_AWAITING_KEYS;
    circ->state = CIRCUIT_STATE_BUILDING;
739
    log_fn(LOG_DEBUG,"first skin; finished sending create cell.");
740
741
742
  } else {
    assert(circ->cpath->state == CPATH_STATE_OPEN);
    assert(circ->state == CIRCUIT_STATE_BUILDING);
743
    log_fn(LOG_DEBUG,"starting to send subsequent skin.");
744
745
746
747
748
    for(hop=circ->cpath->next;
        hop != circ->cpath && hop->state == CPATH_STATE_OPEN;
        hop=hop->next) ;
    if(hop == circ->cpath) { /* done building the circuit. whew. */
      circ->state = CIRCUIT_STATE_OPEN;
749
      log_fn(LOG_INFO,"circuit built!");
750
751
752
753
754
      return 0;
    }

    router = router_get_by_addr_port(hop->addr,hop->port);
    if(!router) {
755
      log_fn(LOG_WARNING,"couldn't lookup router %d:%d",hop->addr,hop->port);
756
757
758
759
760
761
762
763
764
      return -1;
    }

    memset(&cell, 0, sizeof(cell_t));
    cell.command = CELL_RELAY; 
    cell.aci = circ->n_aci;
    SET_CELL_RELAY_COMMAND(cell, RELAY_COMMAND_EXTEND);
    SET_CELL_STREAM_ID(cell, ZERO_STREAM);

765
    cell.length = RELAY_HEADER_SIZE + 6 + DH_ONIONSKIN_LEN;
766
    *(uint32_t*)(cell.payload+RELAY_HEADER_SIZE) = htonl(hop->addr);
Nick Mathewson's avatar
Nick Mathewson committed
767
    *(uint16_t*)(cell.payload+RELAY_HEADER_SIZE+4) = htons(hop->port);
768
    if(onion_skin_create(router->onion_pkey, &(hop->handshake_state), cell.payload+RELAY_HEADER_SIZE+6) < 0) {
769
      log_fn(LOG_WARNING,"onion_skin_create failed.");
770
771
772
      return -1;
    }

773
    log_fn(LOG_DEBUG,"Sending extend relay cell.");
774
    /* send it to hop->prev, because it will transfer it to a create cell and then send to hop */
775
    if(circuit_deliver_relay_cell(&cell, circ, CELL_DIRECTION_OUT, hop->prev) < 0) {
776
      log_fn(LOG_WARNING,"failed to deliver extend cell. Closing.");
777
778
779
780
781
782
783
      return -1;
    }
    hop->state = CPATH_STATE_AWAITING_KEYS;
  }
  return 0;
}

784
785
786
/* take the 'extend' cell, pull out addr/port plus the onion skin. Make
 * sure we're connected to the next hop, and pass it the onion skin in
 * a create cell.
787
788
789
790
791
792
793
 */
int circuit_extend(cell_t *cell, circuit_t *circ) {
  connection_t *n_conn;
  aci_t aci_type;
  struct sockaddr_in me; /* my router identity */
  cell_t newcell;

794
  if(circ->n_conn) {
795
    log_fn(LOG_WARNING,"n_conn already set. Bug/attack. Closing.");
796
797
798
    return -1;
  }

799
800
801
802
803
804
805
806
807
808
809
810
811
812
  circ->n_addr = ntohl(*(uint32_t*)(cell->payload+RELAY_HEADER_SIZE));
  circ->n_port = ntohs(*(uint16_t*)(cell->payload+RELAY_HEADER_SIZE+4));

  if(learn_my_address(&me) < 0)
    return -1;

  n_conn = connection_twin_get_by_addr_port(circ->n_addr,circ->n_port);
  if(!n_conn || n_conn->type != CONN_TYPE_OR) {
    /* i've disabled making connections through OPs, but it's definitely
     * possible here. I'm not sure if it would be a bug or a feature. -RD
     */
    /* note also that this will close circuits where the onion has the same
     * router twice in a row in the path. i think that's ok. -RD
     */
813
814
815
    struct in_addr in;
    in.s_addr = htonl(circ->n_addr);
    log_fn(LOG_DEBUG,"Next router (%s:%d) not connected. Closing.", inet_ntoa(in), circ->n_port);
816
817
818
819
820
821
822
823
    /* XXX later we should fail more gracefully here, like with a 'truncated' */
    return -1;
  }

  circ->n_addr = n_conn->addr; /* these are different if we found a twin instead */
  circ->n_port = n_conn->port;

  circ->n_conn = n_conn;
824
  log_fn(LOG_DEBUG,"n_conn is %s:%u",n_conn->address,n_conn->port);
825
826
827
828

  aci_type = decide_aci_type(ntohl(me.sin_addr.s_addr), ntohs(me.sin_port),
                             circ->n_addr, circ->n_port);

829
  log_fn(LOG_DEBUG,"aci_type = %u.",aci_type);
830
831
  circ->n_aci = get_unique_aci_by_addr_port(circ->n_addr, circ->n_port, aci_type);
  if(!circ->n_aci) {
832
    log_fn(LOG_WARNING,"failed to get unique aci.");
833
834
    return -1;
  }
835
  log_fn(LOG_DEBUG,"Chosen ACI %u.",circ->n_aci);
836
837
838
839

  memset(&newcell, 0, sizeof(cell_t));
  newcell.command = CELL_CREATE;
  newcell.aci = circ->n_aci;
840
  newcell.length = DH_ONIONSKIN_LEN;
841

842
  memcpy(newcell.payload, cell->payload+RELAY_HEADER_SIZE+6, DH_ONIONSKIN_LEN);
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865

  if(connection_write_cell_to_buf(&newcell, circ->n_conn) < 0) {
    return -1;
  }

  return 0;
}

int circuit_finish_handshake(circuit_t *circ, char *reply) {
  unsigned char iv[16];
  unsigned char keys[32];
  crypt_path_t *hop;

  memset(iv, 0, 16);

  assert(circ->cpath);
  if(circ->cpath->state == CPATH_STATE_AWAITING_KEYS)
    hop = circ->cpath;
  else {
    for(hop=circ->cpath->next;
        hop != circ->cpath && hop->state == CPATH_STATE_OPEN;
        hop=hop->next) ;
    if(hop == circ->cpath) { /* got an extended when we're all done? */
866
      log_fn(LOG_WARNING,"got extended when circ already built? Closing.");
867
      return -1;
868
869
870
871
872
    }
  }
  assert(hop->state == CPATH_STATE_AWAITING_KEYS);

  if(onion_skin_client_handshake(hop->handshake_state, reply, keys, 32) < 0) {
873
    log_fn(LOG_WARNING,"onion_skin_client_handshake failed.");
874
875
876
877
878
879
    return -1;
  }

  crypto_dh_free(hop->handshake_state); /* don't need it anymore */
  hop->handshake_state = NULL;

880
  log_fn(LOG_DEBUG,"hop %d init cipher forward %d, backward %d.", (uint32_t)hop, *(uint32_t*)keys, *(uint32_t*)(keys+16));
881
  if (!(hop->f_crypto =
Nick Mathewson's avatar
src/or    
Nick Mathewson committed
882
        crypto_create_init_cipher(CIRCUIT_CIPHER,keys,iv,1))) {
883
    log(LOG_WARNING,"forward cipher initialization failed.");
884
885
886
887
    return -1;
  }

  if (!(hop->b_crypto =
Nick Mathewson's avatar
src/or    
Nick Mathewson committed
888
        crypto_create_init_cipher(CIRCUIT_CIPHER,keys+16,iv,0))) {
889
    log(LOG_WARNING,"backward cipher initialization failed.");
890
891
    return -1;
  }
892

893
  hop->state = CPATH_STATE_OPEN;
894
  log_fn(LOG_INFO,"finished");
895
896
897
  return 0;
}

898
899
900
901
902
903
904
905
906
907
int circuit_truncated(circuit_t *circ, crypt_path_t *layer) {
  crypt_path_t *victim;
  connection_t *stream;

  assert(circ);
  assert(layer);

  while(layer->next != circ->cpath) {
    /* we need to clear out layer->next */
    victim = layer->next;
908
    log_fn(LOG_DEBUG, "Killing a layer of the cpath.");
909
910
911

    for(stream = circ->p_streams; stream; stream=stream->next_stream) {
      if(stream->cpath_layer == victim) {
912
        log_fn(LOG_INFO, "Marking stream %d for close.", *(int*)stream->stream_id);
913
914
915
916
917
918
919
920
        stream->marked_for_close = 1;
      }
    }

    layer->next = victim->next;
    circuit_free_cpath_node(victim);
  }

921
  log_fn(LOG_INFO, "finished");
922
923
924
  return 0;
}

925

926
void assert_cpath_layer_ok(const crypt_path_t *cp)
927
928
929
930
931
932
933
934
935
936
{
  assert(cp->f_crypto);
  assert(cp->b_crypto);
  assert(cp->addr);
  assert(cp->port);
  switch(cp->state) 
    {
    case CPATH_STATE_CLOSED:
    case CPATH_STATE_OPEN:
      assert(!cp->handshake_state);
937
      break;
938
939
    case CPATH_STATE_AWAITING_KEYS:
      assert(cp->handshake_state);
940
      break;
941
942
943
944
945
946
947
    default:
      assert(0);
    }
  assert(cp->package_window >= 0);
  assert(cp->deliver_window >= 0);
}

948
void assert_cpath_ok(const crypt_path_t *cp)
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
{
  while(cp->prev)
    cp = cp->prev;

  while(cp->next) {
    assert_cpath_layer_ok(cp);
    /* layers must be in sequence of: "open* awaiting? closed*" */
    if (cp->prev) {
      if (cp->prev->state == CPATH_STATE_OPEN) {
        assert(cp->state == CPATH_STATE_CLOSED ||
               cp->state == CPATH_STATE_AWAITING_KEYS);
      } else {
        assert(cp->state == CPATH_STATE_CLOSED);
      }
    }
    cp = cp->next;
  }
}

968
void assert_circuit_ok(const circuit_t *c) 
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
{
  connection_t *conn;

  assert(c->n_addr);
  assert(c->n_port);
  assert(c->n_conn);
  assert(c->n_conn->type == CONN_TYPE_OR);
  if (c->p_conn)
    assert(c->p_conn->type == CONN_TYPE_OR);
  for (conn = c->p_streams; conn; conn = conn->next_stream)
    assert(c->p_conn->type == CONN_TYPE_EXIT);
  for (conn = c->n_streams; conn; conn = conn