test.c 68.4 KB
Newer Older
1
2
/* Copyright (c) 2001-2004, Roger Dingledine.
 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
3
 * Copyright (c) 2007-2012, The Tor Project, Inc. */
4
5
/* See LICENSE for licensing information */

6
7
/* Ordinarily defined in tor_main.c; this bit is just here to provide one
 * since we're not linking to tor_main.c */
8
const char tor_git_revision[] = "";
9

10
11
12
13
14
/**
 * \file test.c
 * \brief Unit tests for many pieces of the lower level Tor modules.
 **/

Nick Mathewson's avatar
Nick Mathewson committed
15
#include "orconfig.h"
16

17
#include <stdio.h>
18
#ifdef HAVE_FCNTL_H
19
#include <fcntl.h>
20
21
#endif

22
#ifdef _WIN32
23
24
/* For mkdir() */
#include <direct.h>
Nick Mathewson's avatar
Nick Mathewson committed
25
#else
26
#include <dirent.h>
Nick Mathewson's avatar
Nick Mathewson committed
27
28
#endif

29
30
/* These macros pull in declarations for some functions and structures that
 * are typically file-private. */
31
#define BUFFERS_PRIVATE
32
#define CONFIG_PRIVATE
33
#define GEOIP_PRIVATE
34
#define ROUTER_PRIVATE
35
#define CIRCUITSTATS_PRIVATE
36

37
38
39
40
41
42
43
/*
 * Linux doesn't provide lround in math.h by default, but mac os does...
 * It's best just to leave math.h out of the picture entirely.
 */
//#include <math.h>
long int lround(double x);
double fabs(double x);
44

Nick Mathewson's avatar
Nick Mathewson committed
45
#include "or.h"
Sebastian Hahn's avatar
Sebastian Hahn committed
46
#include "buffers.h"
47
#include "circuitstats.h"
Sebastian Hahn's avatar
Sebastian Hahn committed
48
#include "config.h"
Sebastian Hahn's avatar
Sebastian Hahn committed
49
#include "connection_edge.h"
Sebastian Hahn's avatar
Sebastian Hahn committed
50
#include "geoip.h"
Sebastian Hahn's avatar
Sebastian Hahn committed
51
#include "rendcommon.h"
52
53
54
#include "test.h"
#include "torgzip.h"
#include "mempool.h"
55
#include "memarea.h"
Sebastian Hahn's avatar
Sebastian Hahn committed
56
#include "onion.h"
Sebastian Hahn's avatar
Sebastian Hahn committed
57
#include "policies.h"
Sebastian Hahn's avatar
Sebastian Hahn committed
58
#include "rephist.h"
Sebastian Hahn's avatar
Sebastian Hahn committed
59
#include "routerparse.h"
Nick Mathewson's avatar
Nick Mathewson committed
60

61
62
#ifdef USE_DMALLOC
#include <dmalloc.h>
63
#include <openssl/crypto.h>
64
#include "main.h"
65
66
#endif

67
68
/** Set to true if any unit test has failed.  Mostly, this is set by the macros
 * in test.h */
69
70
int have_failed = 0;

71
72
/** Temporary directory (set up by setup_directory) under which we store all
 * our files during testing. */
73
static char temp_dir[256];
74
#ifdef _WIN32
Nick Mathewson's avatar
Nick Mathewson committed
75
#define pid_t int
76
#endif
77
static pid_t temp_dir_setup_in_pid = 0;
78

79
80
81
/** Select and create the temporary directory we'll use to run our unit tests.
 * Store it in <b>temp_dir</b>.  Exit immediately if we can't create it.
 * idempotent. */
82
static void
Nick Mathewson's avatar
Nick Mathewson committed
83
setup_directory(void)
84
85
{
  static int is_setup = 0;
86
  int r;
87
88
  if (is_setup) return;

89
#ifdef _WIN32
90
91
92
93
  {
    char buf[MAX_PATH];
    const char *tmp = buf;
    /* If this fails, we're probably screwed anyway */
94
    if (!GetTempPathA(sizeof(buf),buf))
95
96
97
98
99
      tmp = "c:\\windows\\temp";
    tor_snprintf(temp_dir, sizeof(temp_dir),
                 "%s\\tor_test_%d", tmp, (int)getpid());
    r = mkdir(temp_dir);
  }
100
#else
Nick Mathewson's avatar
Nick Mathewson committed
101
  tor_snprintf(temp_dir, sizeof(temp_dir), "/tmp/tor_test_%d", (int) getpid());
102
103
104
105
106
107
108
109
  r = mkdir(temp_dir, 0700);
#endif
  if (r) {
    fprintf(stderr, "Can't create directory %s:", temp_dir);
    perror("");
    exit(1);
  }
  is_setup = 1;
110
  temp_dir_setup_in_pid = getpid();
111
112
}

113
/** Return a filename relative to our testing temporary directory */
114
const char *
115
116
117
118
get_fname(const char *name)
{
  static char buf[1024];
  setup_directory();
119
120
  if (!name)
    return temp_dir;
121
  tor_snprintf(buf,sizeof(buf),"%s/%s",temp_dir,name);
122
123
124
  return buf;
}

125
/* Remove a directory and all of its subdirectories */
126
static void
127
rm_rf(const char *dir)
128
{
129
  struct stat st;
130
  smartlist_t *elements;
131
132

  elements = tor_listdir(dir);
133
  if (elements) {
134
    SMARTLIST_FOREACH_BEGIN(elements, const char *, cp) {
135
136
137
138
139
140
141
142
143
         char *tmp = NULL;
         tor_asprintf(&tmp, "%s"PATH_SEPARATOR"%s", dir, cp);
         if (0 == stat(tmp,&st) && (st.st_mode & S_IFDIR)) {
           rm_rf(tmp);
         } else {
           if (unlink(tmp)) {
             fprintf(stderr, "Error removing %s: %s\n", tmp, strerror(errno));
           }
         }
144
         tor_free(tmp);
145
    } SMARTLIST_FOREACH_END(cp);
146
147
    SMARTLIST_FOREACH(elements, char *, cp, tor_free(cp));
    smartlist_free(elements);
Nick Mathewson's avatar
Nick Mathewson committed
148
  }
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
  if (rmdir(dir))
    fprintf(stderr, "Error removing directory %s: %s\n", dir, strerror(errno));
}

/** Remove all files stored under the temporary directory, and the directory
 * itself.  Called by atexit(). */
static void
remove_directory(void)
{
  if (getpid() != temp_dir_setup_in_pid) {
    /* Only clean out the tempdir when the main process is exiting. */
    return;
  }

  rm_rf(temp_dir);
164
165
}

166
167
168
/** Define this if unit tests spend too much time generating public keys*/
#undef CACHE_GENERATED_KEYS

169
static crypto_pk_t *pregen_keys[5] = {NULL, NULL, NULL, NULL, NULL};
170
171
172
173
174
175
#define N_PREGEN_KEYS ((int)(sizeof(pregen_keys)/sizeof(pregen_keys[0])))

/** Generate and return a new keypair for use in unit tests.  If we're using
 * the key cache optimization, we might reuse keys: we only guarantee that
 * keys made with distinct values for <b>idx</b> are different.  The value of
 * <b>idx</b> must be at least 0, and less than N_PREGEN_KEYS. */
176
crypto_pk_t *
177
178
pk_generate(int idx)
{
179
#ifdef CACHE_GENERATED_KEYS
180
  tor_assert(idx < N_PREGEN_KEYS);
181
  if (! pregen_keys[idx]) {
182
    pregen_keys[idx] = crypto_pk_new();
183
184
185
    tor_assert(!crypto_pk_generate_key(pregen_keys[idx]));
  }
  return crypto_pk_dup_key(pregen_keys[idx]);
186
#else
187
  crypto_pk_t *result;
188
  (void) idx;
189
  result = crypto_pk_new();
190
191
192
  tor_assert(!crypto_pk_generate_key(result));
  return result;
#endif
193
194
}

195
/** Free all storage used for the cached key optimization. */
196
197
198
199
static void
free_pregenerated_keys(void)
{
  unsigned idx;
200
  for (idx = 0; idx < N_PREGEN_KEYS; ++idx) {
201
    if (pregen_keys[idx]) {
202
      crypto_pk_free(pregen_keys[idx]);
203
204
      pregen_keys[idx] = NULL;
    }
205
206
207
  }
}

208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
typedef struct socks_test_data_t {
  socks_request_t *req;
  buf_t *buf;
} socks_test_data_t;

static void *
socks_test_setup(const struct testcase_t *testcase)
{
  socks_test_data_t *data = tor_malloc(sizeof(socks_test_data_t));
  (void)testcase;
  data->buf = buf_new_with_capacity(256);
  data->req = socks_request_new();
  config_register_addressmaps(get_options());
  return data;
}
static int
socks_test_cleanup(const struct testcase_t *testcase, void *ptr)
{
  socks_test_data_t *data = ptr;
  (void)testcase;
  buf_free(data->buf);
  socks_request_free(data->req);
  tor_free(data);
  return 1;
}

const struct testcase_setup_t socks_setup = {
  socks_test_setup, socks_test_cleanup
};

#define SOCKS_TEST_INIT()                       \
  socks_test_data_t *testdata = ptr;            \
  buf_t *buf = testdata->buf;                   \
  socks_request_t *socks = testdata->req;
#define ADD_DATA(buf, s)                                        \
  write_to_buf(s, sizeof(s)-1, buf)

static void
socks_request_clear(socks_request_t *socks)
{
  tor_free(socks->username);
  tor_free(socks->password);
  memset(socks, 0, sizeof(socks_request_t));
}

/** Perform unsupported SOCKS 4 commands */
254
static void
255
test_socks_4_unsupported_commands(void *ptr)
256
{
257
258
  SOCKS_TEST_INIT();

259
  /* SOCKS 4 Send BIND [02] to IP address 2.2.2.2:4369 */
260
  ADD_DATA(buf, "\x04\x02\x11\x11\x02\x02\x02\x02\x00");
261
262
263
264
265
  test_assert(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
                                   get_options()->SafeSocks) == -1);
  test_eq(4, socks->socks_version);
  test_eq(0, socks->replylen); /* XXX: shouldn't tor reply? */

Nick Mathewson's avatar
Nick Mathewson committed
266
 done:
267
268
269
  ;
}

270
/** Perform supported SOCKS 4 commands */
271
static void
272
test_socks_4_supported_commands(void *ptr)
273
{
274
275
276
277
278
279
  SOCKS_TEST_INIT();

  test_eq(0, buf_datalen(buf));

  /* SOCKS 4 Send CONNECT [01] to IP address 2.2.2.2:4370 */
  ADD_DATA(buf, "\x04\x01\x11\x12\x02\x02\x02\x03\x00");
280
281
282
283
  test_assert(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
                                   get_options()->SafeSocks) == 1);
  test_eq(4, socks->socks_version);
  test_eq(0, socks->replylen); /* XXX: shouldn't tor reply? */
284
285
286
287
288
289
290
291
  test_eq(SOCKS_COMMAND_CONNECT, socks->command);
  test_streq("2.2.2.3", socks->address);
  test_eq(4370, socks->port);
  test_assert(socks->got_auth == 0);
  test_assert(! socks->username);

  test_eq(0, buf_datalen(buf));
  socks_request_clear(socks);
292
293

  /* SOCKS 4 Send CONNECT [01] to IP address 2.2.2.2:4369 with userid*/
294
  ADD_DATA(buf, "\x04\x01\x11\x12\x02\x02\x02\x04me\x00");
295
296
297
298
  test_assert(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
                                   get_options()->SafeSocks) == 1);
  test_eq(4, socks->socks_version);
  test_eq(0, socks->replylen); /* XXX: shouldn't tor reply? */
299
300
301
302
303
304
305
306
307
308
309
310
311
  test_eq(SOCKS_COMMAND_CONNECT, socks->command);
  test_streq("2.2.2.4", socks->address);
  test_eq(4370, socks->port);
  test_assert(socks->got_auth == 1);
  test_assert(socks->username);
  test_eq(2, socks->usernamelen);
  test_memeq("me", socks->username, 2);

  test_eq(0, buf_datalen(buf));
  socks_request_clear(socks);

  /* SOCKS 4a Send RESOLVE [F0] request for torproject.org */
  ADD_DATA(buf, "\x04\xF0\x01\x01\x00\x00\x00\x02me\x00torproject.org\x00");
312
  test_assert(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
313
                                   get_options()->SafeSocks) == 1);
314
315
  test_eq(4, socks->socks_version);
  test_eq(0, socks->replylen); /* XXX: shouldn't tor reply? */
316
317
318
  test_streq("torproject.org", socks->address);

  test_eq(0, buf_datalen(buf));
319

Nick Mathewson's avatar
Nick Mathewson committed
320
 done:
321
322
323
  ;
}

324
/**  Perform unsupported SOCKS 5 commands */
325
static void
326
test_socks_5_unsupported_commands(void *ptr)
327
{
328
329
  SOCKS_TEST_INIT();

330
  /* SOCKS 5 Send unsupported BIND [02] command */
331
332
333
334
335
  ADD_DATA(buf, "\x05\x02\x00\x01");

  test_eq(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
                               get_options()->SafeSocks), 0);
  test_eq(0, buf_datalen(buf));
336
337
338
  test_eq(5, socks->socks_version);
  test_eq(2, socks->replylen);
  test_eq(5, socks->reply[0]);
339
340
341
342
343
344
345
346
  test_eq(0, socks->reply[1]);
  ADD_DATA(buf, "\x05\x02\x00\x01\x02\x02\x02\x01\x01\x01");
  test_eq(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
                               get_options()->SafeSocks), -1);
  /* XXX: shouldn't tor reply 'command not supported' [07]? */

  buf_clear(buf);
  socks_request_clear(socks);
347
348

  /* SOCKS 5 Send unsupported UDP_ASSOCIATE [03] command */
349
350
351
  ADD_DATA(buf, "\x05\x03\x00\x01\x02");
  test_eq(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
                               get_options()->SafeSocks), 0);
352
353
354
  test_eq(5, socks->socks_version);
  test_eq(2, socks->replylen);
  test_eq(5, socks->reply[0]);
355
356
357
358
359
  test_eq(0, socks->reply[1]);
  ADD_DATA(buf, "\x05\x03\x00\x01\x02\x02\x02\x01\x01\x01");
  test_eq(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
                               get_options()->SafeSocks), -1);
  /* XXX: shouldn't tor reply 'command not supported' [07]? */
360

Nick Mathewson's avatar
Nick Mathewson committed
361
 done:
362
363
364
  ;
}

365
/** Perform supported SOCKS 5 commands */
366
static void
367
test_socks_5_supported_commands(void *ptr)
368
{
369
370
  SOCKS_TEST_INIT();

371
  /* SOCKS 5 Send CONNECT [01] to IP address 2.2.2.2:4369 */
372
373
374
  ADD_DATA(buf, "\x05\x01\x00");
  test_eq(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
                                   get_options()->SafeSocks), 0);
375
376
377
378
  test_eq(5, socks->socks_version);
  test_eq(2, socks->replylen);
  test_eq(5, socks->reply[0]);
  test_eq(0, socks->reply[1]);
379
380
381
382

  ADD_DATA(buf, "\x05\x01\x00\x01\x02\x02\x02\x02\x11\x11");
  test_eq(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
                                   get_options()->SafeSocks), 1);
383
384
385
  test_streq("2.2.2.2", socks->address);
  test_eq(4369, socks->port);

386
387
388
  test_eq(0, buf_datalen(buf));
  socks_request_clear(socks);

389
  /* SOCKS 5 Send CONNECT [01] to FQDN torproject.org:4369 */
390
391
392
393
394
  ADD_DATA(buf, "\x05\x01\x00");
  ADD_DATA(buf, "\x05\x01\x00\x03\x0Etorproject.org\x11\x11");
  test_eq(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
                                   get_options()->SafeSocks), 1);

395
396
397
398
  test_eq(5, socks->socks_version);
  test_eq(2, socks->replylen);
  test_eq(5, socks->reply[0]);
  test_eq(0, socks->reply[1]);
399
  test_streq("torproject.org", socks->address);
400
401
  test_eq(4369, socks->port);

402
403
404
  test_eq(0, buf_datalen(buf));
  socks_request_clear(socks);

405
  /* SOCKS 5 Send RESOLVE [F0] request for torproject.org:4369 */
406
407
408
409
  ADD_DATA(buf, "\x05\x01\x00");
  ADD_DATA(buf, "\x05\xF0\x00\x03\x0Etorproject.org\x01\x02");
  test_assert(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
                                   get_options()->SafeSocks) == 1);
410
411
412
413
  test_eq(5, socks->socks_version);
  test_eq(2, socks->replylen);
  test_eq(5, socks->reply[0]);
  test_eq(0, socks->reply[1]);
414
  test_streq("torproject.org", socks->address);
415

416
417
418
419
420
421
  test_eq(0, buf_datalen(buf));
  socks_request_clear(socks);

  /* SOCKS 5 Send RESOLVE_PTR [F1] for IP address 2.2.2.5 */
  ADD_DATA(buf, "\x05\x01\x00");
  ADD_DATA(buf, "\x05\xF1\x00\x01\x02\x02\x02\x05\x01\x03");
422
423
424
425
426
427
  test_assert(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
                                   get_options()->SafeSocks) == 1);
  test_eq(5, socks->socks_version);
  test_eq(2, socks->replylen);
  test_eq(5, socks->reply[0]);
  test_eq(0, socks->reply[1]);
428
429
430
  test_streq("2.2.2.5", socks->address);

  test_eq(0, buf_datalen(buf));
431

Nick Mathewson's avatar
Nick Mathewson committed
432
 done:
433
434
435
  ;
}

436
/**  Perform SOCKS 5 authentication */
437
static void
438
test_socks_5_no_authenticate(void *ptr)
439
{
440
441
  SOCKS_TEST_INIT();

442
  /*SOCKS 5 No Authentication */
443
  ADD_DATA(buf,"\x05\x01\x00");
444
445
446
447
448
449
450
  test_assert(!fetch_from_buf_socks(buf, socks,
                                    get_options()->TestSocks,
                                    get_options()->SafeSocks));
  test_eq(2, socks->replylen);
  test_eq(5, socks->reply[0]);
  test_eq(SOCKS_NO_AUTH, socks->reply[1]);

451
452
  test_eq(0, buf_datalen(buf));

453
  /*SOCKS 5 Send username/password anyway - pretend to be broken */
454
  ADD_DATA(buf,"\x01\x02\x01\x01\x02\x01\x01");
455
456
457
458
459
460
461
462
  test_assert(!fetch_from_buf_socks(buf, socks,
                                    get_options()->TestSocks,
                                    get_options()->SafeSocks));
  test_eq(5, socks->socks_version);
  test_eq(2, socks->replylen);
  test_eq(5, socks->reply[0]);
  test_eq(0, socks->reply[1]);

463
464
465
466
467
468
  test_eq(2, socks->usernamelen);
  test_eq(2, socks->passwordlen);

  test_memeq("\x01\x01", socks->username, 2);
  test_memeq("\x01\x01", socks->password, 2);

Nick Mathewson's avatar
Nick Mathewson committed
469
 done:
470
471
472
  ;
}

473
/** Perform SOCKS 5 authentication */
474
static void
475
test_socks_5_authenticate(void *ptr)
476
{
477
478
  SOCKS_TEST_INIT();

479
  /* SOCKS 5 Negotiate username/password authentication */
480
481
  ADD_DATA(buf, "\x05\x01\x02");

482
483
484
485
486
487
488
489
  test_assert(!fetch_from_buf_socks(buf, socks,
                                   get_options()->TestSocks,
                                   get_options()->SafeSocks));
  test_eq(2, socks->replylen);
  test_eq(5, socks->reply[0]);
  test_eq(SOCKS_USER_PASS, socks->reply[1]);
  test_eq(5, socks->socks_version);

490
491
  test_eq(0, buf_datalen(buf));

492
  /* SOCKS 5 Send username/password */
493
  ADD_DATA(buf, "\x01\x02me\x08mypasswd");
494
495
496
497
498
499
500
  test_assert(!fetch_from_buf_socks(buf, socks,
                                   get_options()->TestSocks,
                                   get_options()->SafeSocks));
  test_eq(5, socks->socks_version);
  test_eq(2, socks->replylen);
  test_eq(5, socks->reply[0]);
  test_eq(0, socks->reply[1]);
501
502
503
504
505
506
507

  test_eq(2, socks->usernamelen);
  test_eq(8, socks->passwordlen);

  test_memeq("me", socks->username, 2);
  test_memeq("mypasswd", socks->password, 8);

Nick Mathewson's avatar
Nick Mathewson committed
508
 done:
509
510
511
  ;
}

512
/** Perform SOCKS 5 authentication and send data all in one go */
513
static void
514
test_socks_5_authenticate_with_data(void *ptr)
515
{
516
517
  SOCKS_TEST_INIT();

518
  /* SOCKS 5 Negotiate username/password authentication */
519
520
  ADD_DATA(buf, "\x05\x01\x02");

521
522
523
524
525
526
527
528
  test_assert(!fetch_from_buf_socks(buf, socks,
                                   get_options()->TestSocks,
                                   get_options()->SafeSocks));
  test_eq(2, socks->replylen);
  test_eq(5, socks->reply[0]);
  test_eq(SOCKS_USER_PASS, socks->reply[1]);
  test_eq(5, socks->socks_version);

529
530
  test_eq(0, buf_datalen(buf));

531
532
  /* SOCKS 5 Send username/password */
  /* SOCKS 5 Send CONNECT [01] to IP address 2.2.2.2:4369 */
533
534
  ADD_DATA(buf, "\x01\x02me\x03you\x05\x01\x00\x01\x02\x02\x02\x02\x11\x11");
  test_assert(fetch_from_buf_socks(buf, socks,
535
536
537
538
539
540
                                   get_options()->TestSocks,
                                   get_options()->SafeSocks) == 1);
  test_eq(5, socks->socks_version);
  test_eq(2, socks->replylen);
  test_eq(5, socks->reply[0]);
  test_eq(0, socks->reply[1]);
541

542
543
  test_streq("2.2.2.2", socks->address);
  test_eq(4369, socks->port);
544

545
546
547
548
549
  test_eq(2, socks->usernamelen);
  test_eq(3, socks->passwordlen);
  test_memeq("me", socks->username, 2);
  test_memeq("you", socks->password, 3);

Nick Mathewson's avatar
Nick Mathewson committed
550
 done:
551
552
553
  ;
}

554
/** Perform SOCKS 5 authentication before method negotiated */
555
static void
556
test_socks_5_auth_before_negotiation(void *ptr)
557
{
558
559
  SOCKS_TEST_INIT();

560
  /* SOCKS 5 Send username/password */
561
  ADD_DATA(buf, "\x01\x02me\x02me");
562
563
564
565
566
567
568
569
  test_assert(fetch_from_buf_socks(buf, socks,
                                   get_options()->TestSocks,
                                   get_options()->SafeSocks) == -1);
  test_eq(0, socks->socks_version);
  test_eq(0, socks->replylen);
  test_eq(0, socks->reply[0]);
  test_eq(0, socks->reply[1]);

Nick Mathewson's avatar
Nick Mathewson committed
570
 done:
571
572
573
  ;
}

574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
static void
test_buffer_copy(void *arg)
{
  generic_buffer_t *buf=NULL, *buf2=NULL;
  const char *s;
  size_t len;
  char b[256];
  int i;
  (void)arg;

  buf = generic_buffer_new();
  tt_assert(buf);

  /* Copy an empty buffer. */
  tt_int_op(0, ==, generic_buffer_set_to_copy(&buf2, buf));
  tt_assert(buf2);
  tt_int_op(0, ==, generic_buffer_len(buf2));

  /* Now try with a short buffer. */
  s = "And now comes an act of enormous enormance!";
  len = strlen(s);
  generic_buffer_add(buf, s, len);
  tt_int_op(len, ==, generic_buffer_len(buf));
  /* Add junk to buf2 so we can test replacing.*/
  generic_buffer_add(buf2, "BLARG", 5);
  tt_int_op(0, ==, generic_buffer_set_to_copy(&buf2, buf));
  tt_int_op(len, ==, generic_buffer_len(buf2));
  generic_buffer_get(buf2, b, len);
  test_mem_op(b, ==, s, len);
  /* Now free buf2 and retry so we can test allocating */
  generic_buffer_free(buf2);
  buf2 = NULL;
  tt_int_op(0, ==, generic_buffer_set_to_copy(&buf2, buf));
  tt_int_op(len, ==, generic_buffer_len(buf2));
  generic_buffer_get(buf2, b, len);
  test_mem_op(b, ==, s, len);
  /* Clear buf for next test */
  generic_buffer_get(buf, b, len);
  tt_int_op(generic_buffer_len(buf),==,0);

  /* Okay, now let's try a bigger buffer. */
  s = "Quis autem vel eum iure reprehenderit qui in ea voluptate velit "
    "esse quam nihil molestiae consequatur, vel illum qui dolorem eum "
    "fugiat quo voluptas nulla pariatur?";
  len = strlen(s);
  for (i = 0; i < 256; ++i) {
    b[0]=i;
    generic_buffer_add(buf, b, 1);
    generic_buffer_add(buf, s, len);
  }
  tt_int_op(0, ==, generic_buffer_set_to_copy(&buf2, buf));
  tt_int_op(generic_buffer_len(buf2), ==, generic_buffer_len(buf));
  for (i = 0; i < 256; ++i) {
    generic_buffer_get(buf2, b, len+1);
    tt_int_op((unsigned char)b[0],==,i);
    test_mem_op(b+1, ==, s, len);
  }

 done:
  if (buf)
    generic_buffer_free(buf);
  if (buf2)
    generic_buffer_free(buf2);
}

639
/** Run unit tests for buffers.c */
640
static void
641
642
test_buffers(void)
{
643
644
645
  char str[256];
  char str2[256];

646
  buf_t *buf = NULL, *buf2 = NULL;
647
  const char *cp;
Nick Mathewson's avatar
Nick Mathewson committed
648

Nick Mathewson's avatar
Nick Mathewson committed
649
  int j;
650
  size_t r;
651
652
653
654

  /****
   * buf_new
   ****/
655
  if (!(buf = buf_new()))
Nick Mathewson's avatar
Nick Mathewson committed
656
    test_fail();
657

658
  //test_eq(buf_capacity(buf), 4096);
659
  test_eq(buf_datalen(buf), 0);
660
661

  /****
662
663
   * General pointer frobbing
   */
664
665
  for (j=0;j<256;++j) {
    str[j] = (char)j;
Nick Mathewson's avatar
Nick Mathewson committed
666
  }
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
  write_to_buf(str, 256, buf);
  write_to_buf(str, 256, buf);
  test_eq(buf_datalen(buf), 512);
  fetch_from_buf(str2, 200, buf);
  test_memeq(str, str2, 200);
  test_eq(buf_datalen(buf), 312);
  memset(str2, 0, sizeof(str2));

  fetch_from_buf(str2, 256, buf);
  test_memeq(str+200, str2, 56);
  test_memeq(str, str2+56, 200);
  test_eq(buf_datalen(buf), 56);
  memset(str2, 0, sizeof(str2));
  /* Okay, now we should be 512 bytes into the 4096-byte buffer.  If we add
   * another 3584 bytes, we hit the end. */
Nick Mathewson's avatar
Nick Mathewson committed
682
  for (j=0;j<15;++j) {
683
684
685
686
687
688
689
    write_to_buf(str, 256, buf);
  }
  assert_buf_ok(buf);
  test_eq(buf_datalen(buf), 3896);
  fetch_from_buf(str2, 56, buf);
  test_eq(buf_datalen(buf), 3840);
  test_memeq(str+200, str2, 56);
Nick Mathewson's avatar
Nick Mathewson committed
690
  for (j=0;j<15;++j) {
691
692
693
694
695
696
    memset(str2, 0, sizeof(str2));
    fetch_from_buf(str2, 256, buf);
    test_memeq(str, str2, 256);
  }
  test_eq(buf_datalen(buf), 0);
  buf_free(buf);
697
  buf = NULL;
698
699
700

  /* Okay, now make sure growing can work. */
  buf = buf_new_with_capacity(16);
701
  //test_eq(buf_capacity(buf), 16);
702
  write_to_buf(str+1, 255, buf);
703
  //test_eq(buf_capacity(buf), 256);
704
705
  fetch_from_buf(str2, 254, buf);
  test_memeq(str+1, str2, 254);
706
  //test_eq(buf_capacity(buf), 256);
707
708
  assert_buf_ok(buf);
  write_to_buf(str, 32, buf);
709
  //test_eq(buf_capacity(buf), 256);
710
711
712
  assert_buf_ok(buf);
  write_to_buf(str, 256, buf);
  assert_buf_ok(buf);
713
  //test_eq(buf_capacity(buf), 512);
714
715
716
717
718
  test_eq(buf_datalen(buf), 33+256);
  fetch_from_buf(str2, 33, buf);
  test_eq(*str2, str[255]);

  test_memeq(str2+1, str, 32);
719
  //test_eq(buf_capacity(buf), 512);
720
721
722
723
724
725
726
727
728
729
  test_eq(buf_datalen(buf), 256);
  fetch_from_buf(str2, 256, buf);
  test_memeq(str, str2, 256);

  /* now try shrinking: case 1. */
  buf_free(buf);
  buf = buf_new_with_capacity(33668);
  for (j=0;j<67;++j) {
    write_to_buf(str,255, buf);
  }
730
  //test_eq(buf_capacity(buf), 33668);
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
  test_eq(buf_datalen(buf), 17085);
  for (j=0; j < 40; ++j) {
    fetch_from_buf(str2, 255,buf);
    test_memeq(str2, str, 255);
  }

  /* now try shrinking: case 2. */
  buf_free(buf);
  buf = buf_new_with_capacity(33668);
  for (j=0;j<67;++j) {
    write_to_buf(str,255, buf);
  }
  for (j=0; j < 20; ++j) {
    fetch_from_buf(str2, 255,buf);
    test_memeq(str2, str, 255);
  }
  for (j=0;j<80;++j) {
    write_to_buf(str,255, buf);
  }
750
  //test_eq(buf_capacity(buf),33668);
751
752
753
754
755
  for (j=0; j < 120; ++j) {
    fetch_from_buf(str2, 255,buf);
    test_memeq(str2, str, 255);
  }

756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
  /* Move from buf to buf. */
  buf_free(buf);
  buf = buf_new_with_capacity(4096);
  buf2 = buf_new_with_capacity(4096);
  for (j=0;j<100;++j)
    write_to_buf(str, 255, buf);
  test_eq(buf_datalen(buf), 25500);
  for (j=0;j<100;++j) {
    r = 10;
    move_buf_to_buf(buf2, buf, &r);
    test_eq(r, 0);
  }
  test_eq(buf_datalen(buf), 24500);
  test_eq(buf_datalen(buf2), 1000);
  for (j=0;j<3;++j) {
    fetch_from_buf(str2, 255, buf2);
    test_memeq(str2, str, 255);
  }
  r = 8192; /*big move*/
  move_buf_to_buf(buf2, buf, &r);
  test_eq(r, 0);
  r = 30000; /* incomplete move */
  move_buf_to_buf(buf2, buf, &r);
  test_eq(r, 13692);
  for (j=0;j<97;++j) {
    fetch_from_buf(str2, 255, buf2);
    test_memeq(str2, str, 255);
  }
  buf_free(buf);
  buf_free(buf2);
786
  buf = buf2 = NULL;
787

788
789
790
791
792
793
794
795
796
797
  buf = buf_new_with_capacity(5);
  cp = "Testing. This is a moderately long Testing string.";
  for (j = 0; cp[j]; j++)
    write_to_buf(cp+j, 1, buf);
  test_eq(0, buf_find_string_offset(buf, "Testing", 7));
  test_eq(1, buf_find_string_offset(buf, "esting", 6));
  test_eq(1, buf_find_string_offset(buf, "est", 3));
  test_eq(39, buf_find_string_offset(buf, "ing str", 7));
  test_eq(35, buf_find_string_offset(buf, "Testing str", 11));
  test_eq(32, buf_find_string_offset(buf, "ng ", 3));
798
  test_eq(43, buf_find_string_offset(buf, "string.", 7));
799
800
801
802
  test_eq(-1, buf_find_string_offset(buf, "shrdlu", 6));
  test_eq(-1, buf_find_string_offset(buf, "Testing thing", 13));
  test_eq(-1, buf_find_string_offset(buf, "ngx", 3));
  buf_free(buf);
803
  buf = NULL;
804

805
 done:
806
807
808
809
  if (buf)
    buf_free(buf);
  if (buf2)
    buf_free(buf2);
Nick Mathewson's avatar
Nick Mathewson committed
810
811
}

812
/** Run unit tests for the onion handshake code. */
813
static void
Nick Mathewson's avatar
Nick Mathewson committed
814
815
test_onion_handshake(void)
{
816
  /* client-side */
817
  crypto_dh_t *c_dh = NULL;
818
  char c_buf[ONIONSKIN_CHALLENGE_LEN];
819
820
821
  char c_keys[40];

  /* server-side */
822
  char s_buf[ONIONSKIN_REPLY_LEN];
823
  char s_keys[40];
Roger Dingledine's avatar
Roger Dingledine committed
824

825
  /* shared */
826
  crypto_pk_t *pk = NULL;
827

828
  pk = pk_generate(0);
829
830

  /* client handshake 1. */
831
  memset(c_buf, 0, ONIONSKIN_CHALLENGE_LEN);
832
833
834
  test_assert(! onion_skin_create(pk, &c_dh, c_buf));

  /* server handshake */
835
  memset(s_buf, 0, ONIONSKIN_REPLY_LEN);
836
  memset(s_keys, 0, 40);
837
838
  test_assert(! onion_skin_server_handshake(c_buf, pk, NULL,
                                            s_buf, s_keys, 40));
Roger Dingledine's avatar
Roger Dingledine committed
839

840
841
842
  /* client handshake 2 */
  memset(c_keys, 0, 40);
  test_assert(! onion_skin_client_handshake(c_dh, s_buf, c_keys, 40));
Roger Dingledine's avatar
Roger Dingledine committed
843

844
845
846
847
  if (memcmp(c_keys, s_keys, 40)) {
    puts("Aiiiie");
    exit(1);
  }
848
849
850
  test_memeq(c_keys, s_keys, 40);
  memset(s_buf, 0, 40);
  test_memneq(c_keys, s_buf, 40);
851
852
853
854
855

 done:
  if (c_dh)
    crypto_dh_free(c_dh);
  if (pk)
856
    crypto_pk_free(pk);
857
858
}

859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
static void
test_circuit_timeout(void)
{
  /* Plan:
   *  1. Generate 1000 samples
   *  2. Estimate parameters
   *  3. If difference, repeat
   *  4. Save state
   *  5. load state
   *  6. Estimate parameters
   *  7. compare differences
   */
  circuit_build_times_t initial;
  circuit_build_times_t estimate;
  circuit_build_times_t final;
874
  double timeout1, timeout2;
875
  or_state_t state;
876
  int i, runs;
Mike Perry's avatar
Mike Perry committed
877
  double close_ms;
878
879
880
881
  circuit_build_times_init(&initial);
  circuit_build_times_init(&estimate);
  circuit_build_times_init(&final);

882
883
  memset(&state, 0, sizeof(or_state_t));

884
  circuitbuild_running_unit_tests();
885
#define timeout0 (build_time_t)(30*1000.0)
Mike Perry's avatar
Mike Perry committed
886
  initial.Xm = 3000;
Mike Perry's avatar
Mike Perry committed
887
888
  circuit_build_times_initial_alpha(&initial,
                                    CBT_DEFAULT_QUANTILE_CUTOFF/100.0,
889
                                    timeout0);
Mike Perry's avatar
Mike Perry committed
890
891
892
  close_ms = MAX(circuit_build_times_calculate_timeout(&initial,
                             CBT_DEFAULT_CLOSE_QUANTILE/100.0),
                 CBT_DEFAULT_TIMEOUT_INITIAL_VALUE);
893
  do {
Mike Perry's avatar
Mike Perry committed
894
    for (i=0; i < CBT_DEFAULT_MIN_CIRCUITS_TO_OBSERVE; i++) {
Mike Perry's avatar
Mike Perry committed
895
896
897
898
899
900
      build_time_t sample = circuit_build_times_generate_sample(&initial,0,1);

      if (sample > close_ms) {
        circuit_build_times_add_time(&estimate, CBT_BUILD_ABANDONED);
      } else {
        circuit_build_times_add_time(&estimate, sample);
901
902
903
904
      }
    }
    circuit_build_times_update_alpha(&estimate);
    timeout1 = circuit_build_times_calculate_timeout(&estimate,
Mike Perry's avatar
Mike Perry committed
905
                                  CBT_DEFAULT_QUANTILE_CUTOFF/100.0);
906
    circuit_build_times_set_timeout(&estimate);
907
    log_notice(LD_CIRC, "Timeout1 is %f, Xm is %d", timeout1, estimate.Xm);
Mike Perry's avatar
Mike Perry committed
908
           /* 2% error */
909
  } while (fabs(circuit_build_times_cdf(&initial, timeout0) -
Mike Perry's avatar
Mike Perry committed
910
                circuit_build_times_cdf(&initial, timeout1)) > 0.02);
911

912
  test_assert(estimate.total_build_times <= CBT_NCIRCUITS_TO_OBSERVE);
913

914
  circuit_build_times_update_state(&estimate, &state);
915
  test_assert(circuit_build_times_parse_state(&final, &state) == 0);
916
917
918

  circuit_build_times_update_alpha(&final);
  timeout2 = circuit_build_times_calculate_timeout(&final,
Mike Perry's avatar
Mike Perry committed
919
                                 CBT_DEFAULT_QUANTILE_CUTOFF/100.0);
920
921

  circuit_build_times_set_timeout(&final);
922
  log_notice(LD_CIRC, "Timeout2 is %f, Xm is %d", timeout2, final.Xm);
923

924
  /* 5% here because some accuracy is lost due to histogram conversion */
925
  test_assert(fabs(circuit_build_times_cdf(&initial, timeout0) -
926
                   circuit_build_times_cdf(&initial, timeout2)) < 0.05);
927

928
929
930
931
  for (runs = 0; runs < 50; runs++) {
    int build_times_idx = 0;
    int total_build_times = 0;

932
933
934
    final.close_ms = final.timeout_ms = CBT_DEFAULT_TIMEOUT_INITIAL_VALUE;
    estimate.close_ms = estimate.timeout_ms
                      = CBT_DEFAULT_TIMEOUT_INITIAL_VALUE;
935

Mike Perry's avatar
Mike Perry committed
936
    for (i = 0; i < CBT_DEFAULT_RECENT_CIRCUITS*2; i++) {
937
938
939
      circuit_build_times_network_circ_success(&estimate);
      circuit_build_times_add_time(&estimate,
            circuit_build_times_generate_sample(&estimate, 0,
Mike Perry's avatar
Mike Perry committed
940
                CBT_DEFAULT_QUANTILE_CUTOFF/100.0));
941

942
943
944
      circuit_build_times_network_circ_success(&estimate);
      circuit_build_times_add_time(&final,
            circuit_build_times_generate_sample(&final, 0,
Mike Perry's avatar
Mike Perry committed
945
                CBT_DEFAULT_QUANTILE_CUTOFF/100.0));
946
    }
947

948
949
950
951
952
953
954
955
956
957
    test_assert(!circuit_build_times_network_check_changed(&estimate));
    test_assert(!circuit_build_times_network_check_changed(&final));

    /* Reset liveness to be non-live */
    final.liveness.network_last_live = 0;
    estimate.liveness.network_last_live = 0;

    build_times_idx = estimate.build_times_idx;
    total_build_times = estimate.total_build_times;

958
959
    test_assert(circuit_build_times_network_check_live(&estimate));
    test_assert(circuit_build_times_network_check_live(&final));
960

961
962
963
964
    circuit_build_times_count_close(&estimate, 0,
            (time_t)(approx_time()-estimate.close_ms/1000.0-1));
    circuit_build_times_count_close(&final, 0,
            (time_t)(approx_time()-final.close_ms/1000.0-1));
965

966
967
968
969
970
971
972
973
974
    test_assert(!circuit_build_times_network_check_live(&estimate));
    test_assert(!circuit_build_times_network_check_live(&final));

    log_info(LD_CIRC, "idx: %d %d, tot: %d %d",
             build_times_idx, estimate.build_times_idx,
             total_build_times, estimate.total_build_times);

    /* Check rollback index. Should match top of loop. */
    test_assert(build_times_idx == estimate.build_times_idx);
975
976
977
978
    // This can fail if estimate.total_build_times == 1000, because
    // in that case, rewind actually causes us to lose timeouts
    if (total_build_times != CBT_NCIRCUITS_TO_OBSERVE)
      test_assert(total_build_times == estimate.total_build_times);
979
980
981
982
983
984

    /* Now simulate that the network has become live and we need
     * a change */
    circuit_build_times_network_is_live(&estimate);
    circuit_build_times_network_is_live(&final);

Mike Perry's avatar
Mike Perry committed
985
    for (i = 0; i < CBT_DEFAULT_MAX_RECENT_TIMEOUT_COUNT; i++) {
986
      circuit_build_times_count_timeout(&estimate, 1);
987

Mike Perry's avatar
Mike Perry committed
988
      if (i < CBT_DEFAULT_MAX_RECENT_TIMEOUT_COUNT-1) {
989
        circuit_build_times_count_timeout(&final, 1);
990
991
992
      }
    }

993
994
    test_assert(estimate.liveness.after_firsthop_idx == 0);
    test_assert(final.liveness.after_firsthop_idx ==
Mike Perry's avatar
Mike Perry committed
995
                CBT_DEFAULT_MAX_RECENT_TIMEOUT_COUNT-1);
996
997
998
999

    test_assert(circuit_build_times_network_check_live(&estimate));
    test_assert(circuit_build_times_network_check_live(&final));

1000
    circuit_build_times_count_timeout(&final, 1);