compat.c 60.9 KB
Newer Older
1
2
/* Copyright (c) 2003-2004, Roger Dingledine
 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
3
 * Copyright (c) 2007-2008, The Tor Project, Inc. */
4
5
/* See LICENSE for licensing information */
/* $Id$ */
6
7
const char compat_c_id[] =
  "$Id$";
8

9
10
11
12
13
14
15
16
17
/**
 * \file compat.c
 * \brief Wrappers to make calls more portable.  This code defines
 * functions such as tor_malloc, tor_snprintf, get/set various data types,
 * renaming, setting socket options, switching user IDs.  It is basically
 * where the non-portable items are conditionally included depending on
 * the platform.
 **/

Nick Mathewson's avatar
Nick Mathewson committed
18
19
20
/* This is required on rh7 to make strptime not complain.
 * We also need it to make memmem get defined (where available)
 */
21
22
#define _GNU_SOURCE

Nick Mathewson's avatar
Nick Mathewson committed
23
#include "compat.h"
24
25
26

#ifdef MS_WINDOWS
#include <process.h>
27
#include <windows.h>
28
#include <sys/locking.h>
29
#endif
30

31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#ifdef HAVE_UNAME
#include <sys/utsname.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_SYS_FCNTL_H
#include <sys/fcntl.h>
#endif
#ifdef HAVE_PWD_H
#include <pwd.h>
#endif
#ifdef HAVE_GRP_H
#include <grp.h>
#endif
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
55

56
57
58
59
60
#ifndef HAVE_GETTIMEOFDAY
#ifdef HAVE_FTIME
#include <sys/timeb.h>
#endif
#endif
61

62
63
64
#ifdef HAVE_NETDB_H
#include <netdb.h>
#endif
65
66
67
68
69
#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h> /* FreeBSD needs this to know what version it is */
#endif
#include <stdio.h>
#include <stdlib.h>
70
#include <assert.h>
71
72
73
#ifdef HAVE_SIGNAL_H
#include <signal.h>
#endif
74
75
76
77
78
79
#ifdef HAVE_UTIME_H
#include <utime.h>
#endif
#ifdef HAVE_SYS_UTIME_H
#include <sys/utime.h>
#endif
80
81
82
#ifdef HAVE_SYS_MMAN_H
#include <sys/mman.h>
#endif
83
84
85
#ifdef HAVE_SYS_SYSLIMITS_H
#include <sys/syslimits.h>
#endif
86
87
88
#ifdef HAVE_SYS_FILE_H
#include <sys/file.h>
#endif
89

90
91
92
93
#ifdef USE_BSOCKETS
#include <bsocket.h>
#endif

94
95
#include "log.h"
#include "util.h"
96
#include "container.h"
97
#include "address.h"
98

Roger Dingledine's avatar
Roger Dingledine committed
99
/* Inline the strl functions if the platform doesn't have them. */
100
101
102
103
104
105
106
#ifndef HAVE_STRLCPY
#include "strlcpy.c"
#endif
#ifndef HAVE_STRLCAT
#include "strlcat.c"
#endif

107
#ifndef INADDR_NONE
108
109
/* This is used by inet_addr, but apparently Solaris doesn't define it
 * anyplace. */
110
111
112
#define INADDR_NONE ((unsigned long) -1)
#endif

113
#ifdef HAVE_SYS_MMAN_H
114
/** Try to create a memory mapping for <b>filename</b> and return it.  On
115
116
 * failure, return NULL.  Sets errno properly, using ERANGE to mean
 * "empty file". */
117
tor_mmap_t *
118
tor_mmap_file(const char *filename)
119
120
121
122
{
  int fd; /* router file */
  char *string;
  int page_size;
123
  tor_mmap_t *res;
124
  size_t size, filesize;
125
126
127
128
129

  tor_assert(filename);

  fd = open(filename, O_RDONLY, 0);
  if (fd<0) {
130
    int save_errno = errno;
131
132
133
    int severity = (errno == ENOENT) ? LOG_INFO : LOG_WARN;
    log_fn(severity, LD_FS,"Could not open \"%s\" for mmap(): %s",filename,
           strerror(errno));
134
    errno = save_errno;
135
136
137
    return NULL;
  }

138
  size = filesize = (size_t) lseek(fd, 0, SEEK_END);
139
140
141
  lseek(fd, 0, SEEK_SET);
  /* ensure page alignment */
  page_size = getpagesize();
142
  size += (size%page_size) ? page_size-(size%page_size) : 0;
143

144
  if (!size) {
145
146
    /* Zero-length file. If we call mmap on it, it will succeed but
     * return NULL, and bad things will happen. So just fail. */
147
    log_info(LD_FS,"File \"%s\" is empty. Ignoring.",filename);
148
    errno = ERANGE;
149
    close(fd);
150
151
152
    return NULL;
  }

153
  string = mmap(0, size, PROT_READ, MAP_PRIVATE, fd, 0);
154
  close(fd);
155
  if (string == MAP_FAILED) {
156
    int save_errno = errno;
157
158
    log_warn(LD_FS,"Could not mmap file \"%s\": %s", filename,
             strerror(errno));
159
    errno = save_errno;
160
161
162
    return NULL;
  }

163
164
165
  res = tor_malloc_zero(sizeof(tor_mmap_t));
  res->data = string;
  res->size = filesize;
166
  res->mapping_size = size;
167

168
  return res;
169
}
170
/** Release storage held for a memory mapping. */
171
172
173
void
tor_munmap_file(tor_mmap_t *handle)
{
174
175
  munmap((char*)handle->data, handle->mapping_size);
  tor_free(handle);
176
}
177
178
#elif defined(MS_WINDOWS)
tor_mmap_t *
179
tor_mmap_file(const char *filename)
180
{
Nick Mathewson's avatar
Nick Mathewson committed
181
  tor_mmap_t *res = tor_malloc_zero(sizeof(tor_mmap_t));
182
  int empty = 0;
183
184
  res->file_handle = INVALID_HANDLE_VALUE;
  res->mmap_handle = NULL;
185

186
  res->file_handle = CreateFile(filename,
187
188
                                GENERIC_READ, FILE_SHARE_READ,
                                NULL,
189
190
191
                                OPEN_EXISTING,
                                FILE_ATTRIBUTE_NORMAL,
                                0);
192
193

  if (res->file_handle == INVALID_HANDLE_VALUE)
194
    goto win_err;
195

196
  res->size = GetFileSize(res->file_handle, NULL);
197

198
  if (res->size == 0) {
199
    log_info(LD_FS,"File \"%s\" is empty. Ignoring.",filename);
200
    empty = 1;
201
202
203
    goto err;
  }

204
205
206
  res->mmap_handle = CreateFileMapping(res->file_handle,
                                       NULL,
                                       PAGE_READONLY,
207
#if SIZEOF_SIZE_T > 4
208
                                       (res->base.size >> 32),
209
210
211
#else
                                       0,
#endif
Nick Mathewson's avatar
Nick Mathewson committed
212
                                       (res->size & 0xfffffffful),
213
                                       NULL);
214
  if (res->mmap_handle == NULL)
215
    goto win_err;
216
217
218
219
  res->data = (char*) MapViewOfFile(res->mmap_handle,
                                    FILE_MAP_READ,
                                    0, 0, 0);
  if (!res->data)
220
    goto win_err;
221

222
  return res;
223
224
 win_err: {
    DWORD e = GetLastError();
225
    int severity = (e == ERROR_FILE_NOT_FOUND || e == ERROR_PATH_NOT_FOUND) ?
226
227
      LOG_INFO : LOG_WARN;
    char *msg = format_win32_error(e);
228
    log_fn(severity, LD_FS, "Couldn't mmap file \"%s\": %s", filename, msg);
229
    tor_free(msg);
230
231
232
233
    if (e == ERROR_FILE_NOT_FOUND || e == ERROR_PATH_NOT_FOUND)
      errno = ENOENT;
    else
      errno = EINVAL;
234
  }
235
 err:
236
237
  if (empty)
    errno = ERANGE;
238
  tor_munmap_file(res);
239
240
  return NULL;
}
241
void
242
tor_munmap_file(tor_mmap_t *handle)
243
{
244
  if (handle->data)
245
246
    /* This is an ugly cast, but without it, "data" in struct tor_mmap_t would
       have to be redefined as non-const. */
247
248
    UnmapViewOfFile( (LPVOID) handle->data);

249
  if (handle->mmap_handle != NULL)
Nick Mathewson's avatar
Nick Mathewson committed
250
    CloseHandle(handle->mmap_handle);
251
  if (handle->file_handle != INVALID_HANDLE_VALUE)
Nick Mathewson's avatar
Nick Mathewson committed
252
    CloseHandle(handle->file_handle);
253
  tor_free(handle);
254
255
}
#else
256
tor_mmap_t *
257
tor_mmap_file(const char *filename)
258
{
259
  struct stat st;
260
  char *res = read_file_to_str(filename, RFTS_BIN|RFTS_IGNORE_MISSING, &st);
261
  tor_mmap_t *handle;
262
263
  if (! res)
    return NULL;
264
  handle = tor_malloc_zero(sizeof(tor_mmap_t));
265
  handle->data = res;
266
  handle->size = st.st_size;
267
  return handle;
268
269
}
void
270
tor_munmap_file(tor_mmap_t *handle)
271
{
272
273
  char *d = (char*)handle->data;
  tor_free(d);
274
  memset(handle, 0, sizeof(tor_mmap_t));
275
  tor_free(handle);
276
277
278
}
#endif

279
280
281
/** Replacement for snprintf.  Differs from platform snprintf in two
 * ways: First, always NUL-terminates its output.  Second, always
 * returns -1 if the result is truncated.  (Note that this return
282
283
 * behavior does <i>not</i> conform to C99; it just happens to be
 * easier to emulate "return -1" with conformant implementations than
284
285
 * it is to emulate "return number that would be written" with
 * non-conformant implementations.) */
286
287
int
tor_snprintf(char *str, size_t size, const char *format, ...)
288
289
290
291
292
293
294
295
296
{
  va_list ap;
  int r;
  va_start(ap,format);
  r = tor_vsnprintf(str,size,format,ap);
  va_end(ap);
  return r;
}

297
/** Replacement for vsnprintf; behavior differs as tor_snprintf differs from
298
299
 * snprintf.
 */
300
301
int
tor_vsnprintf(char *str, size_t size, const char *format, va_list args)
302
303
{
  int r;
304
305
  if (size == 0)
    return -1; /* no place for the NUL */
306
  if (size > SSIZE_T_MAX-16)
307
    return -1;
308
309
310
311
312
313
#ifdef MS_WINDOWS
  r = _vsnprintf(str, size, format, args);
#else
  r = vsnprintf(str, size, format, args);
#endif
  str[size-1] = '\0';
314
  if (r < 0 || r >= (ssize_t)size)
315
316
317
318
    return -1;
  return r;
}

Nick Mathewson's avatar
Nick Mathewson committed
319
/** Given <b>hlen</b> bytes at <b>haystack</b> and <b>nlen</b> bytes at
Roger Dingledine's avatar
Roger Dingledine committed
320
 * <b>needle</b>, return a pointer to the first occurrence of the needle
Nick Mathewson's avatar
Nick Mathewson committed
321
322
323
324
325
 * within the haystack, or NULL if there is no such occurrence.
 *
 * Requires that nlen be greater than zero.
 */
const void *
326
327
tor_memmem(const void *_haystack, size_t hlen,
           const void *_needle, size_t nlen)
Nick Mathewson's avatar
Nick Mathewson committed
328
329
330
{
#if defined(HAVE_MEMMEM) && (!defined(__GNUC__) || __GNUC__ >= 2)
  tor_assert(nlen);
Nick Mathewson's avatar
Nick Mathewson committed
331
  return memmem(_haystack, hlen, _needle, nlen);
Nick Mathewson's avatar
Nick Mathewson committed
332
#else
333
334
  /* This isn't as fast as the GLIBC implementation, but it doesn't need to
   * be. */
Nick Mathewson's avatar
Nick Mathewson committed
335
336
337
  const char *p, *end;
  const char *haystack = (const char*)_haystack;
  const char *needle = (const char*)_needle;
Nick Mathewson's avatar
Nick Mathewson committed
338
339
340
341
342
343
344
  char first;
  tor_assert(nlen);

  p = haystack;
  end = haystack + hlen;
  first = *(const char*)needle;
  while ((p = memchr(p, first, end-p))) {
345
    if (p+nlen > end)
Nick Mathewson's avatar
Nick Mathewson committed
346
347
348
349
350
351
352
353
354
      return NULL;
    if (!memcmp(p, needle, nlen))
      return p;
    ++p;
  }
  return NULL;
#endif
}

355
#ifdef MS_WINDOWS
356
357
358
359
360
361
362
/** Take a filename and return a pointer to its final element.  This
 * function is called on __FILE__ to fix a MSVC nit where __FILE__
 * contains the full path to the file.  This is bad, because it
 * confuses users to find the home directory of the person who
 * compiled the binary in their warrning messages.
 */
const char *
363
tor_fix_source_file(const char *fname)
364
{
365
  const char *cp1, *cp2, *r;
366
367
368
  cp1 = strrchr(fname, '/');
  cp2 = strrchr(fname, '\\');
  if (cp1 && cp2) {
369
    r = (cp1<cp2)?(cp2+1):(cp1+1);
370
  } else if (cp1) {
371
    r = cp1+1;
372
  } else if (cp2) {
373
    r = cp2+1;
374
  } else {
375
    r = fname;
376
  }
377
  return r;
378
}
379
#endif
380

381
/**
382
 * Read a 16-bit value beginning at <b>cp</b>.  Equivalent to
383
384
385
 * *(uint16_t*)(cp), but will not cause segfaults on platforms that forbid
 * unaligned memory access.
 */
386
387
uint16_t
get_uint16(const char *cp)
388
389
390
391
392
393
{
  uint16_t v;
  memcpy(&v,cp,2);
  return v;
}
/**
394
 * Read a 32-bit value beginning at <b>cp</b>.  Equivalent to
395
396
397
 * *(uint32_t*)(cp), but will not cause segfaults on platforms that forbid
 * unaligned memory access.
 */
398
399
uint32_t
get_uint32(const char *cp)
400
401
402
403
404
405
406
407
408
{
  uint32_t v;
  memcpy(&v,cp,4);
  return v;
}
/**
 * Set a 16-bit value beginning at <b>cp</b> to <b>v</b>. Equivalent to
 * *(uint16_t)(cp) = v, but will not cause segfaults on platforms that forbid
 * unaligned memory access. */
409
410
void
set_uint16(char *cp, uint16_t v)
411
412
413
414
415
416
417
{
  memcpy(cp,&v,2);
}
/**
 * Set a 32-bit value beginning at <b>cp</b> to <b>v</b>. Equivalent to
 * *(uint32_t)(cp) = v, but will not cause segfaults on platforms that forbid
 * unaligned memory access. */
418
419
void
set_uint32(char *cp, uint32_t v)
420
421
422
423
424
{
  memcpy(cp,&v,4);
}

/**
Roger Dingledine's avatar
Roger Dingledine committed
425
426
427
 * Rename the file <b>from</b> to the file <b>to</b>.  On unix, this is
 * the same as rename(2).  On windows, this removes <b>to</b> first if
 * it already exists.
428
429
 * Returns 0 on success.  Returns -1 and sets errno on failure.
 */
430
431
int
replace_file(const char *from, const char *to)
432
433
434
435
{
#ifndef MS_WINDOWS
  return rename(from,to);
#else
436
  switch (file_status(to))
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
    {
    case FN_NOENT:
      break;
    case FN_FILE:
      if (unlink(to)) return -1;
      break;
    case FN_ERROR:
      return -1;
    case FN_DIR:
      errno = EISDIR;
      return -1;
    }
  return rename(from,to);
#endif
}

453
454
455
456
457
458
459
460
461
/** Change <b>fname</b>'s modification time to now. */
int
touch_file(const char *fname)
{
  if (utime(fname, NULL)!=0)
    return -1;
  return 0;
}

462
/** Represents a lockfile on which we hold the lock. */
463
464
465
466
467
struct tor_lockfile_t {
  char *filename;
  int fd;
};

468
469
470
471
472
473
474
475
476
/** Try to get a lock on the lockfile <b>filename</b>, creating it as
 * necessary.  If someone else has the lock and <b>blocking</b> is true,
 * wait until the lock is available.  Otherwise return immediately whether
 * we succeeded or not.
 *
 * Set *<b>locked_out</b> to true if somebody else had the lock, and to false
 * otherwise.
 *
 * Return a <b>tor_lockfile_t</b> on success, NULL on failure.
477
478
479
480
 *
 * (Implementation note: because we need to fall back to fcntl on some
 *  platforms, these locks are per-process, not per-thread.  If you want
 *  to do in-process locking, use tor_mutex_t like a normal person.)
481
 */
482
483
484
485
486
487
488
489
490
491
492
493
494
495
tor_lockfile_t *
tor_lockfile_lock(const char *filename, int blocking, int *locked_out)
{
  tor_lockfile_t *result;
  int fd;
  *locked_out = 0;

  log_info(LD_FS, "Locking \"%s\"", filename);
  fd = open(filename, O_RDWR|O_CREAT|O_TRUNC, 0600);
  if (fd < 0) {
    log_warn(LD_FS,"Couldn't open \"%s\" for locking: %s", filename,
             strerror(errno));
    return NULL;
  }
496

497
498
#ifdef WIN32
  _lseek(fd, 0, SEEK_SET);
499
  if (_locking(fd, blocking ? _LK_LOCK : _LK_NBLCK, 1) < 0) {
500
501
502
503
504
505
506
    if (errno != EDEADLOCK)
      log_warn(LD_FS,"Couldn't lock \"%s\": %s", filename, strerror(errno));
    else
      *locked_out = 1;
    close(fd);
    return NULL;
  }
507
#elif defined(HAVE_FLOCK)
508
509
510
511
512
513
514
515
  if (flock(fd, LOCK_EX|(blocking ? 0 : LOCK_NB)) < 0) {
    if (errno != EWOULDBLOCK)
      log_warn(LD_FS,"Couldn't lock \"%s\": %s", filename, strerror(errno));
    else
      *locked_out = 1;
    close(fd);
    return NULL;
  }
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
#else
  {
    struct flock lock;
    memset(&lock, 0, sizeof(lock));
    lock.l_type = F_WRLCK;
    lock.l_whence = SEEK_SET;
    if (fcntl(fd, blocking ? F_SETLKW : F_SETLK, &lock) < 0) {
      if (errno != EACCES && errno != EAGAIN)
        log_warn(LD_FS, "Couldn't lock \"%s\": %s", filename, strerror(errno));
      else
        *locked_out = 1;
      close(fd);
      return NULL;
    }
  }
531
532
533
534
535
536
537
538
#endif

  result = tor_malloc(sizeof(tor_lockfile_t));
  result->filename = tor_strdup(filename);
  result->fd = fd;
  return result;
}

539
/** Release the lock held as <b>lockfile</b>. */
540
541
542
543
544
545
546
void
tor_lockfile_unlock(tor_lockfile_t *lockfile)
{
  tor_assert(lockfile);

  log_info(LD_FS, "Unlocking \"%s\"", lockfile->filename);
#ifdef WIN32
547
  _lseek(lockfile->fd, 0, SEEK_SET);
548
  if (_locking(lockfile->fd, _LK_UNLCK, 1) < 0) {
549
550
551
    log_warn(LD_FS,"Error unlocking \"%s\": %s", lockfile->filename,
             strerror(errno));
  }
552
#elif defined(HAVE_FLOCK)
553
554
555
556
  if (flock(lockfile->fd, LOCK_UN) < 0) {
    log_warn(LD_FS, "Error unlocking \"%s\": %s", lockfile->filename,
             strerror(errno));
  }
557
558
#else
  /* Closing the lockfile is sufficient. */
559
560
561
562
563
564
565
566
#endif

  close(lockfile->fd);
  lockfile->fd = -1;
  tor_free(lockfile->filename);
  tor_free(lockfile);
}

567
568
569
570
571
572
573
574
575
/* Some old versions of unix didn't define constants for these values,
 * and instead expect you to say 0, 1, or 2. */
#ifndef SEEK_CUR
#define SEEK_CUR 1
#endif
#ifndef SEEK_END
#define SEEK_END 2
#endif

Roger Dingledine's avatar
Roger Dingledine committed
576
/** Return the position of <b>fd</b> with respect to the start of the file. */
577
578
579
580
581
582
583
584
585
586
off_t
tor_fd_getpos(int fd)
{
#ifdef WIN32
  return (off_t) _lseek(fd, 0, SEEK_CUR);
#else
  return (off_t) lseek(fd, 0, SEEK_CUR);
#endif
}

Roger Dingledine's avatar
Roger Dingledine committed
587
/** Move <b>fd</b> to the end of the file. Return -1 on error, 0 on success. */
588
589
590
591
592
593
594
595
596
597
int
tor_fd_seekend(int fd)
{
#ifdef WIN32
  return _lseek(fd, 0, SEEK_END) < 0 ? -1 : 0;
#else
  return lseek(fd, 0, SEEK_END) < 0 ? -1 : 0;
#endif
}

598
599
#undef DEBUG_SOCKET_COUNTING
#ifdef DEBUG_SOCKET_COUNTING
600
601
/** A bitarray of all fds that should be passed to tor_socket_close(). Only
 * used if DEBUG_SOCKET_COUNTING is defined. */
602
static bitarray_t *open_sockets = NULL;
603
/** The size of <b>open_sockets</b>, in bits. */
604
605
606
static int max_socket = -1;
#endif

607
608
609
610
611
/** Count of number of sockets currently open.  (Undercounts sockets opened by
 * eventdns and libevent.) */
static int n_sockets_open = 0;

/** As close(), but guaranteed to work for sockets across platforms (including
612
613
614
 * Windows, where close()ing a socket doesn't work.  Returns 0 on success, -1
 * on failure. */
int
615
616
tor_close_socket(int s)
{
617
  int r = 0;
618
619
620
621
622
623
624
625
626
#ifdef DEBUG_SOCKET_COUNTING
  if (s > max_socket || ! bitarray_is_set(open_sockets, s)) {
    log_warn(LD_BUG, "Closing a socket (%d) that wasn't returned by tor_open_"
             "socket(), or that was already closed or something.", s);
  } else {
    tor_assert(open_sockets && s <= max_socket);
    bitarray_clear(open_sockets, s);
  }
#endif
627
628
629
630
631
632
633
  /* On Windows, you have to call close() on fds returned by open(),
   * and closesocket() on fds returned by socket().  On Unix, everything
   * gets close()'d.  We abstract this difference by always using
   * tor_close_socket to close sockets, and always using close() on
   * files.
   */
#ifdef USE_BSOCKETS
634
  r = bclose(s);
635
#elif defined(MS_WINDOWS)
636
  r = closesocket(s);
637
#else
638
  r = close(s);
639
#endif
640
641
642
643
644
645
646
647
648
649
650
651
652
653
  if (r == 0) {
    --n_sockets_open;
  } else {
    int err = tor_socket_errno(-1);
    log_info(LD_NET, "Close returned an error: %s", tor_socket_strerror(err));
#ifdef WIN32
    if (err != WSAENOTSOCK)
      --n_sockets_open;
#else
    if (err != EBADF)
      --n_sockets_open;
#endif
    r = -1;
  }
654
655
656
  if (n_sockets_open < 0)
    log_warn(LD_BUG, "Our socket count is below zero: %d. Please submit a "
             "bug report.", n_sockets_open);
657
  return r;
658
659
}

660
#ifdef DEBUG_SOCKET_COUNTING
661
662
/** Helper: if DEBUG_SOCKET_COUNTING is enabled, remember that <b>s</b> is
 * now an open socket. */
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
static INLINE void
mark_socket_open(int s)
{
  if (s > max_socket) {
    if (max_socket == -1) {
      open_sockets = bitarray_init_zero(s+128);
      max_socket = s+128;
    } else {
      open_sockets = bitarray_expand(open_sockets, max_socket, s+128);
      max_socket = s+128;
    }
  }
  if (bitarray_is_set(open_sockets, s)) {
    log_warn(LD_BUG, "I thought that %d was already open, but socket() just "
             "gave it to me!", s);
  }
  bitarray_set(open_sockets, s);
}
#else
#define mark_socket_open(s) STMT_NIL
#endif

685
686
687
688
689
/** As socket(), but counts the number of open sockets. */
int
tor_open_socket(int domain, int type, int protocol)
{
  int s = socket(domain, type, protocol);
690
  if (s >= 0) {
691
    ++n_sockets_open;
692
693
694
695
696
697
698
699
700
701
702
703
704
    mark_socket_open(s);
  }
  return s;
}

/** As socket(), but counts the number of open sockets. */
int
tor_accept_socket(int sockfd, struct sockaddr *addr, socklen_t *len)
{
  int s = accept(sockfd, addr, len);
  if (s >= 0) {
    ++n_sockets_open;
    mark_socket_open(s);
705
  }
706
707
708
709
710
711
712
713
714
715
  return s;
}

/** Return the number of sockets we currently have opened. */
int
get_n_open_sockets(void)
{
  return n_sockets_open;
}

716
717
/** Turn <b>socket</b> into a nonblocking socket.
 */
718
719
void
set_socket_nonblocking(int socket)
720
{
721
#if defined(MS_WINDOWS) && !defined(USE_BSOCKETS)
722
723
  unsigned long nonblocking = 1;
  ioctlsocket(socket, FIONBIO, (unsigned long*) &nonblocking);
724
725
726
727
728
729
730
731
732
733
#else
  fcntl(socket, F_SETFL, O_NONBLOCK);
#endif
}

/**
 * Allocate a pair of connected sockets.  (Like socketpair(family,
 * type,protocol,fd), but works on systems that don't have
 * socketpair.)
 *
734
 * Currently, only (AF_UNIX, SOCK_STREAM, 0) sockets are supported.
735
736
737
738
739
740
 *
 * Note that on systems without socketpair, this call will fail if
 * localhost is inaccessible (for example, if the networking
 * stack is down). And even if it succeeds, the socket pair will not
 * be able to read while localhost is down later (the socket pair may
 * even close, depending on OS-specific timeouts).
741
 *
742
 * Returns 0 on success and -errno on failure; do not rely on the value
743
 * of errno or WSAGetLastError().
744
 **/
745
/* It would be nicer just to set errno, but that won't work for windows. */
746
747
748
int
tor_socketpair(int family, int type, int protocol, int fd[2])
{
749
750
//don't use win32 socketpairs (they are always bad)
#if defined(HAVE_SOCKETPAIR) && !defined(MS_WINDOWS)
751
752
  int r;
  r = socketpair(family, type, protocol, fd);
753
754
755
756
757
758
759
760
761
762
  if (r == 0) {
    if (fd[0] >= 0) {
      ++n_sockets_open;
      mark_socket_open(fd[0]);
    }
    if (fd[1] >= 0) {
      ++n_sockets_open;
      mark_socket_open(fd[1]);
    }
  }
763
  return r < 0 ? -errno : r;
764
#elif defined(USE_BSOCKETS)
765
  return bsocketpair(family, type, protocol, fd);
766
767
768
769
770
771
772
773
774
775
776
777
#else
    /* This socketpair does not work when localhost is down. So
     * it's really not the same thing at all. But it's close enough
     * for now, and really, when localhost is down sometimes, we
     * have other problems too.
     */
    int listener = -1;
    int connector = -1;
    int acceptor = -1;
    struct sockaddr_in listen_addr;
    struct sockaddr_in connect_addr;
    int size;
778
    int saved_errno = -1;
779
780
781
782
783
784
785

    if (protocol
#ifdef AF_UNIX
        || family != AF_UNIX
#endif
        ) {
#ifdef MS_WINDOWS
786
      return -WSAEAFNOSUPPORT;
787
#else
788
      return -EAFNOSUPPORT;
789
790
791
#endif
    }
    if (!fd) {
792
      return -EINVAL;
793
794
    }

795
    listener = tor_open_socket(AF_INET, type, 0);
796
    if (listener < 0)
797
      return -tor_socket_errno(-1);
798
    memset(&listen_addr, 0, sizeof(listen_addr));
799
    listen_addr.sin_family = AF_INET;
800
    listen_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
801
    listen_addr.sin_port = 0;   /* kernel chooses port.  */
802
803
    if (bind(listener, (struct sockaddr *) &listen_addr, sizeof (listen_addr))
        == -1)
804
      goto tidy_up_and_fail;
805
    if (listen(listener, 1) == -1)
806
      goto tidy_up_and_fail;
807

808
    connector = tor_open_socket(AF_INET, type, 0);
809
    if (connector < 0)
810
      goto tidy_up_and_fail;
811
    /* We want to find out the port number to connect to.  */
812
    size = sizeof(connect_addr);
813
    if (getsockname(listener, (struct sockaddr *) &connect_addr, &size) == -1)
814
      goto tidy_up_and_fail;
815
    if (size != sizeof (connect_addr))
816
      goto abort_tidy_up_and_fail;
817
    if (connect(connector, (struct sockaddr *) &connect_addr,
818
                sizeof(connect_addr)) == -1)
819
      goto tidy_up_and_fail;
820

821
    size = sizeof(listen_addr);
822
823
    acceptor = tor_accept_socket(listener,
                                 (struct sockaddr *) &listen_addr, &size);
824
    if (acceptor < 0)
825
      goto tidy_up_and_fail;
826
    if (size != sizeof(listen_addr))
827
      goto abort_tidy_up_and_fail;
828
829
830
831
    tor_close_socket(listener);
    /* Now check we are talking to ourself by matching port and host on the
       two sockets.  */
    if (getsockname(connector, (struct sockaddr *) &connect_addr, &size) == -1)
832
      goto tidy_up_and_fail;
833
834
835
836
    if (size != sizeof (connect_addr)
        || listen_addr.sin_family != connect_addr.sin_family
        || listen_addr.sin_addr.s_addr != connect_addr.sin_addr.s_addr
        || listen_addr.sin_port != connect_addr.sin_port) {
837
      goto abort_tidy_up_and_fail;
838
839
840
    }
    fd[0] = connector;
    fd[1] = acceptor;
841

842
843
844
845
    return 0;

  abort_tidy_up_and_fail:
#ifdef MS_WINDOWS
846
    saved_errno = WSAECONNABORTED;
847
#else
848
    saved_errno = ECONNABORTED; /* I hope this is portable and appropriate.  */
849
850
#endif
  tidy_up_and_fail:
851
852
853
854
855
856
857
858
859
    if (saved_errno < 0)
      saved_errno = errno;
    if (listener != -1)
      tor_close_socket(listener);
    if (connector != -1)
      tor_close_socket(connector);
    if (acceptor != -1)
      tor_close_socket(acceptor);
    return -saved_errno;
860
861
862
#endif
}

863
864
#define ULIMIT_BUFFER 32 /* keep 32 extra fd's beyond _ConnLimit */

865
866
867
/** Learn the maximum allowed number of file descriptors. (Some systems
 * have a low soft limit.
 *
868
869
870
 * We compute this by finding the largest number that we can use.
 * If we can't find a number greater than or equal to <b>limit</b>,
 * then we fail: return -1.
871
 *
872
 * Otherwise, return 0 and store the maximum we found inside <b>max_out</b>.*/
873
int
874
set_max_file_descriptors(rlim_t limit, int *max_out)
875
{
876
877
878
879
880
  /* Define some maximum connections values for systems where we cannot
   * automatically determine a limit. Re Cygwin, see
   * http://archives.seul.org/or/talk/Aug-2006/msg00210.html
   * For an iPhone, 9999 should work. For Windows and all other unknown
   * systems we use 15000 as the default. */
881
#ifndef HAVE_GETRLIMIT
882
883
884
885
886
887
888
889
890
891
892
893
894
#if defined(CYGWIN) || defined(__CYGWIN__)
  const char *platform = "Cygwin";
  const unsigned long MAX_CONNECTIONS = 3200;
#elif defined(IPHONE)
  const char *platform = "iPhone";
  const unsigned long MAX_CONNECTIONS = 9999;
#elif defined(MS_WINDOWS)
  const char *platform = "Windows";
  const unsigned long MAX_CONNECTIONS = 15000;
#else
  const char *platform = "unknown platforms with no getrlimit()";
  const unsigned long MAX_CONNECTIONS = 15000;
#endif
895
896
  log_fn(LOG_INFO, LD_NET,
         "This platform is missing getrlimit(). Proceeding.");
897
  if (limit > MAX_CONNECTIONS) {
898
    log_warn(LD_CONFIG,
899
             "We do not support more than %lu file descriptors "
900
901
             "on %s. Tried to raise to %lu.",
             (unsigned long)MAX_CONNECTIONS, platform, (unsigned long)limit);
902
903
    return -1;
  }
904
905
  limit = MAX_CONNECTIONS;
#else /* HAVE_GETRLIMIT */
906
  struct rlimit rlim;
907
  tor_assert(limit > 0);
908
909

  if (getrlimit(RLIMIT_NOFILE, &rlim) != 0) {
910
911
    log_warn(LD_NET, "Could not get maximum number of file descriptors: %s",
             strerror(errno));
912
913
    return -1;
  }
914

915
  if (rlim.rlim_max < limit) {
916
917
    log_warn(LD_CONFIG,"We need %lu file descriptors available, and we're "
             "limited to %lu. Please change your ulimit -n.",
918
             (unsigned long)limit, (unsigned long)rlim.rlim_max);
919
920
    return -1;
  }
921
922

  if (rlim.rlim_max > rlim.rlim_cur) {
923
    log_info(LD_NET,"Raising max file descriptors from %lu to %lu.",
924
             (unsigned long)rlim.rlim_cur, (unsigned long)rlim.rlim_max);
925
  }
926
  rlim.rlim_cur = rlim.rlim_max;
927

928
  if (setrlimit(RLIMIT_NOFILE, &rlim) != 0) {
929
930
931
932
933
934
935
    int bad = 1;
#ifdef OPEN_MAX
    if (errno == EINVAL && OPEN_MAX < rlim.rlim_cur) {
      /* On some platforms, OPEN_MAX is the real limit, and getrlimit() is
       * full of nasty lies.  I'm looking at you, OSX 10.5.... */
      rlim.rlim_cur = OPEN_MAX;
      if (setrlimit(RLIMIT_NOFILE, &rlim) == 0) {
936
        if (rlim.rlim_cur < (rlim_t)limit) {
937
938
          log_warn(LD_CONFIG, "We are limited to %lu file descriptors by "
                 "OPEN_MAX, and ConnLimit is %lu.  Changing ConnLimit; sorry.",
939
                   (unsigned long)OPEN_MAX, (unsigned long)limit);
940
941
942
        } else {
          log_info(LD_CONFIG, "Dropped connection limit to OPEN_MAX (%lu); "
                   "Apparently, %lu was too high and rlimit lied to us.",
943
                   (unsigned long)OPEN_MAX, (unsigned long)rlim.rlim_max);
944
945
946
947
        }
        bad = 0;
      }
    }
948
#endif /* OPEN_MAX */
949
    if (bad) {
950
      log_warn(LD_CONFIG,"Couldn't set maximum number of file descriptors: %s",
951
952
953
               strerror(errno));
      return -1;
    }
954
  }
955
  /* leave some overhead for logs, etc, */
956
  limit = rlim.rlim_cur;
957
#endif /* HAVE_GETRLIMIT */
958
959

  if (limit < ULIMIT_BUFFER) {
960
961
    log_warn(LD_CONFIG,
             "ConnLimit must be at least %d. Failing.", ULIMIT_BUFFER);
962
963
    return -1;
  }
964
  if (limit > INT_MAX)
965
    limit = INT_MAX;
966
967
968
  tor_assert(max_out);
  *max_out = (int)limit - ULIMIT_BUFFER;
  return 0;
969
970
}

971
#ifndef MS_WINDOWS
972
973
/** Log details of current user and group credentials. Return 0 on
 * success. Logs and return -1 on failure.
974
 */
975
976
static int
log_credential_status(void)
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
{
#define CREDENTIAL_LOG_LEVEL LOG_INFO
  /* Real, effective and saved UIDs */
  uid_t ruid, euid, suid;
  /* Read, effective and saved GIDs */
  gid_t rgid, egid, sgid;
  /* Supplementary groups */
  gid_t sup_gids[NGROUPS_MAX + 1];
  /* Number of supplementary groups */
  int ngids;

  /* log UIDs */
#ifdef HAVE_GETRESUID
  if (getresuid(&ruid, &euid, &suid) != 0 ) {
    log_warn(LD_GENERAL, "Error getting changed UIDs: %s", strerror(errno));
    return -1;
  } else {
994
    log_fn(CREDENTIAL_LOG_LEVEL, LD_GENERAL,
995
996
           "UID is %u (real), %u (effective), %u (saved)",
           (unsigned)ruid, (unsigned)euid, (unsigned)suid);
997
998
999
1000
  }
#else
  /* getresuid is not present on MacOS X, so we can't get the saved (E)UID */
  ruid = getuid();