compat.c 50.6 KB
Newer Older
Nick Mathewson's avatar
Nick Mathewson committed
1
/* Copyright 2003-2004 Roger Dingledine
2
 * Copyright 2004-2007 Roger Dingledine, Nick Mathewson */
3
4
/* See LICENSE for licensing information */
/* $Id$ */
5
6
const char compat_c_id[] =
  "$Id$";
7

8
9
10
11
12
13
14
15
16
/**
 * \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
17
18
19
/* This is required on rh7 to make strptime not complain.
 * We also need it to make memmem get defined (where available)
 */
20
21
22
#define _GNU_SOURCE

#include "orconfig.h"
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
#endif
29

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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#ifdef HAVE_UNAME
#include <sys/utsname.h>
#endif
#ifdef HAVE_SYS_TIME_H
#include <sys/time.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_SYS_RESOURCE_H
#include <sys/resource.h>
#endif
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#ifndef HAVE_GETTIMEOFDAY
#ifdef HAVE_FTIME
#include <sys/timeb.h>
#endif
#endif
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
71
72
73
#ifdef HAVE_NETDB_H
#include <netdb.h>
#endif
74
75
76
77
78
79
80
#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h> /* FreeBSD needs this to know what version it is */
#endif
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
81
#include <assert.h>
82
83
84
#ifdef HAVE_PTHREAD_H
#include <pthread.h>
#endif
85
86
87
#ifdef HAVE_SIGNAL_H
#include <signal.h>
#endif
88
89
90
91
92
93
#ifdef HAVE_UTIME_H
#include <utime.h>
#endif
#ifdef HAVE_SYS_UTIME_H
#include <sys/utime.h>
#endif
94
95
96
#ifdef HAVE_SYS_MMAN_H
#include <sys/mman.h>
#endif
97

98
99
100
101
#ifdef USE_BSOCKETS
#include <bsocket.h>
#endif

102
103
#include "log.h"
#include "util.h"
104
#include "container.h"
105

Roger Dingledine's avatar
Roger Dingledine committed
106
/* Inline the strl functions if the platform doesn't have them. */
107
108
109
110
111
112
113
#ifndef HAVE_STRLCPY
#include "strlcpy.c"
#endif
#ifndef HAVE_STRLCAT
#include "strlcat.c"
#endif

114
#ifndef INADDR_NONE
115
116
/* This is used by inet_addr, but apparently Solaris doesn't define it
 * anyplace. */
117
118
119
#define INADDR_NONE ((unsigned long) -1)
#endif

120
#ifdef HAVE_SYS_MMAN_H
121
122
/** Implementation for tor_mmap_t: holds the regular tor_mmap_t, along
 * with extra fields needed for mmap()-based memory mapping. */
123
124
125
126
127
typedef struct tor_mmap_impl_t {
  tor_mmap_t base;
  size_t mapping_size; /**< Size of the actual mapping. (This is this file
                        * size, rounded up to the nearest page.) */
} tor_mmap_impl_t;
128
129
/** Try to create a memory mapping for <b>filename</b> and return it.  On
 * failure, return NULL. */
130
tor_mmap_t *
131
tor_mmap_file(const char *filename)
132
133
134
135
{
  int fd; /* router file */
  char *string;
  int page_size;
136
137
  tor_mmap_impl_t *res;
  size_t size, filesize;
138
139
140
141
142

  tor_assert(filename);

  fd = open(filename, O_RDONLY, 0);
  if (fd<0) {
143
144
145
    int severity = (errno == ENOENT) ? LOG_INFO : LOG_WARN;
    log_fn(severity, LD_FS,"Could not open \"%s\" for mmap(): %s",filename,
           strerror(errno));
146
147
148
    return NULL;
  }

149
  size = filesize = (size_t) lseek(fd, 0, SEEK_END);
150
151
152
  lseek(fd, 0, SEEK_SET);
  /* ensure page alignment */
  page_size = getpagesize();
153
  size += (size%page_size) ? page_size-(size%page_size) : 0;
154

155
  if (!size) {
156
157
    /* Zero-length file. If we call mmap on it, it will succeed but
     * return NULL, and bad things will happen. So just fail. */
158
    log_info(LD_FS,"File \"%s\" is empty. Ignoring.",filename);
159
160
161
    return NULL;
  }

162
  string = mmap(0, size, PROT_READ, MAP_PRIVATE, fd, 0);
163
  if (string == MAP_FAILED) {
164
    close(fd);
165
166
167
168
169
170
171
    log_warn(LD_FS,"Could not mmap file \"%s\": %s", filename,
             strerror(errno));
    return NULL;
  }

  close(fd);

172
173
174
175
  res = tor_malloc_zero(sizeof(tor_mmap_impl_t));
  res->base.data = string;
  res->base.size = filesize;
  res->mapping_size = size;
176

177
  return &(res->base);
178
}
179
/** Release storage held for a memory mapping. */
180
181
182
void
tor_munmap_file(tor_mmap_t *handle)
{
183
  tor_mmap_impl_t *h = SUBTYPE_P(handle, tor_mmap_impl_t, base);
184
185
  munmap((char*)h->base.data, h->mapping_size);
  tor_free(h);
186
}
187
#elif defined(MS_WINDOWS)
188
189
/** Implementation for tor_mmap_t: holds the regular tor_mmap_t, along
 * with extra fields needed for WIN32 memory mapping. */
190
191
typedef struct win_mmap_t {
  tor_mmap_t base;
192
193
  HANDLE file_handle;
  HANDLE mmap_handle;
194
} win_mmap_t;
195
tor_mmap_t *
196
tor_mmap_file(const char *filename)
197
{
198
  win_mmap_t *res = tor_malloc_zero(sizeof(win_mmap_t));
199
200
  res->file_handle = INVALID_HANDLE_VALUE;
  res->mmap_handle = NULL;
201

202
  res->file_handle = CreateFile(filename,
203
204
                                GENERIC_READ, FILE_SHARE_READ,
                                NULL,
205
206
207
                                OPEN_EXISTING,
                                FILE_ATTRIBUTE_NORMAL,
                                0);
208
209

  if (res->file_handle == INVALID_HANDLE_VALUE)
210
    goto win_err;
211

212
  res->base.size = GetFileSize(res->file_handle, NULL);
213

214
215
216
217
218
  if (res->base.size == 0) {
    log_info(LD_FS,"File \"%s\" is empty. Ignoring.",filename);
    goto err;
  }

219
220
221
  res->mmap_handle = CreateFileMapping(res->file_handle,
                                       NULL,
                                       PAGE_READONLY,
222
#if SIZEOF_SIZE_T > 4
223
                                       (res->base.size >> 32),
224
225
226
#else
                                       0,
#endif
227
                                       (res->base.size & 0xfffffffful),
228
                                       NULL);
229
  if (res->mmap_handle == NULL)
230
    goto win_err;
231
  res->base.data = (char*) MapViewOfFile(res->mmap_handle,
232
                                         FILE_MAP_READ,
233
                                         0, 0, 0);
234
  if (!res->base.data)
235
    goto win_err;
236

237
  return &(res->base);
238
239
 win_err: {
    DWORD e = GetLastError();
240
    int severity = (e == ERROR_FILE_NOT_FOUND || e == ERROR_PATH_NOT_FOUND) ?
241
242
      LOG_INFO : LOG_WARN;
    char *msg = format_win32_error(e);
243
    log_fn(severity, LD_FS, "Couldn't mmap file \"%s\": %s", filename, msg);
244
245
    tor_free(msg);
  }
246
 err:
247
  tor_munmap_file(&res->base);
248
249
  return NULL;
}
250
void
251
tor_munmap_file(tor_mmap_t *handle)
252
{
253
  win_mmap_t *h = SUBTYPE_P(handle, win_mmap_t, base);
254
  if (handle->data)
255
256
    /* This is an ugly cast, but without it, "data" in struct tor_mmap_t would
       have to be redefined as non-const. */
257
258
    UnmapViewOfFile( (LPVOID) handle->data);

259
  if (h->mmap_handle != NULL)
260
261
262
263
    CloseHandle(h->mmap_handle);
  if (h->file_handle != INVALID_HANDLE_VALUE)
    CloseHandle(h->file_handle);
  tor_free(h);
264
265
}
#else
266
tor_mmap_t *
267
tor_mmap_file(const char *filename)
268
{
269
  struct stat st;
270
  char *res = read_file_to_str(filename, RFTS_BIN|RFTS_IGNORE_MISSING, &st);
271
  tor_mmap_t *handle;
272
273
  if (! res)
    return NULL;
274
  handle = tor_malloc_zero(sizeof(tor_mmap_t));
275
  handle->data = res;
276
  handle->size = st.st_size;
277
  return handle;
278
279
}
void
280
tor_munmap_file(tor_mmap_t *handle)
281
{
282
283
  char *d = (char*)handle->data;
  tor_free(d);
284
  memset(handle, 0, sizeof(tor_mmap_t));
285
  tor_free(handle);
286
287
288
}
#endif

289
290
291
/** 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
292
293
 * behavior does <i>not</i> conform to C99; it just happens to be
 * easier to emulate "return -1" with conformant implementations than
294
295
 * it is to emulate "return number that would be written" with
 * non-conformant implementations.) */
296
297
int
tor_snprintf(char *str, size_t size, const char *format, ...)
298
299
300
301
302
303
304
305
306
{
  va_list ap;
  int r;
  va_start(ap,format);
  r = tor_vsnprintf(str,size,format,ap);
  va_end(ap);
  return r;
}

307
/** Replacement for vsnprintf; behavior differs as tor_snprintf differs from
308
309
 * snprintf.
 */
310
311
int
tor_vsnprintf(char *str, size_t size, const char *format, va_list args)
312
313
{
  int r;
314
315
  if (size == 0)
    return -1; /* no place for the NUL */
316
317
  if (size > SIZE_T_CEILING)
    return -1;
318
319
320
321
322
323
324
325
326
327
328
#ifdef MS_WINDOWS
  r = _vsnprintf(str, size, format, args);
#else
  r = vsnprintf(str, size, format, args);
#endif
  str[size-1] = '\0';
  if (r < 0 || ((size_t)r) >= size)
    return -1;
  return r;
}

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

  p = haystack;
  end = haystack + hlen;
  first = *(const char*)needle;
  while ((p = memchr(p, first, end-p))) {
355
    if (p+nlen > end)
Nick Mathewson's avatar
Nick Mathewson committed
356
357
358
359
360
361
362
363
364
      return NULL;
    if (!memcmp(p, needle, nlen))
      return p;
    ++p;
  }
  return NULL;
#endif
}

365
#ifdef MS_WINDOWS
366
367
368
369
370
371
372
/** 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 *
373
tor_fix_source_file(const char *fname)
374
{
375
  const char *cp1, *cp2, *r;
376
377
378
  cp1 = strrchr(fname, '/');
  cp2 = strrchr(fname, '\\');
  if (cp1 && cp2) {
379
    r = (cp1<cp2)?(cp2+1):(cp1+1);
380
  } else if (cp1) {
381
    r = cp1+1;
382
  } else if (cp2) {
383
    r = cp2+1;
384
  } else {
385
    r = fname;
386
  }
387
  return r;
388
}
389
#endif
390

391
/**
392
 * Read a 16-bit value beginning at <b>cp</b>.  Equivalent to
393
394
395
 * *(uint16_t*)(cp), but will not cause segfaults on platforms that forbid
 * unaligned memory access.
 */
396
397
uint16_t
get_uint16(const char *cp)
398
399
400
401
402
403
{
  uint16_t v;
  memcpy(&v,cp,2);
  return v;
}
/**
404
 * Read a 32-bit value beginning at <b>cp</b>.  Equivalent to
405
406
407
 * *(uint32_t*)(cp), but will not cause segfaults on platforms that forbid
 * unaligned memory access.
 */
408
409
uint32_t
get_uint32(const char *cp)
410
411
412
413
414
415
416
417
418
{
  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. */
419
420
void
set_uint16(char *cp, uint16_t v)
421
422
423
424
425
426
427
{
  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. */
428
429
void
set_uint32(char *cp, uint32_t v)
430
431
432
433
434
{
  memcpy(cp,&v,4);
}

/**
Roger Dingledine's avatar
Roger Dingledine committed
435
436
437
 * 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.
438
439
 * Returns 0 on success.  Returns -1 and sets errno on failure.
 */
440
441
int
replace_file(const char *from, const char *to)
442
443
444
445
{
#ifndef MS_WINDOWS
  return rename(from,to);
#else
446
  switch (file_status(to))
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
    {
    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
}

463
464
465
466
467
468
469
470
471
/** Change <b>fname</b>'s modification time to now. */
int
touch_file(const char *fname)
{
  if (utime(fname, NULL)!=0)
    return -1;
  return 0;
}

472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
/** 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
 * Windows, where close()ing a socket doesn't work. */
void
tor_close_socket(int s)
{
  /* 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
  bclose(s);
#elif defined(MS_WINDOWS)
  closesocket(s);
#else
  close(s);
#endif
  --n_sockets_open;
}

/** 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);
  if (s >= 0)
    ++n_sockets_open;
  return s;
}

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

514
515
/** Turn <b>socket</b> into a nonblocking socket.
 */
516
517
void
set_socket_nonblocking(int socket)
518
{
519
#if defined(MS_WINDOWS) && !defined(USE_BSOCKETS)
520
521
  unsigned long nonblocking = 1;
  ioctlsocket(socket, FIONBIO, (unsigned long*) &nonblocking);
522
523
524
525
526
527
528
529
530
531
#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.)
 *
532
 * Currently, only (AF_UNIX, SOCK_STREAM, 0) sockets are supported.
533
534
535
536
537
538
 *
 * 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).
539
 *
540
 * Returns 0 on success and -errno on failure; do not rely on the value
541
 * of errno or WSAGetLastError().
542
 **/
543
/* It would be nicer just to set errno, but that won't work for windows. */
544
545
546
int
tor_socketpair(int family, int type, int protocol, int fd[2])
{
547
548
//don't use win32 socketpairs (they are always bad)
#if defined(HAVE_SOCKETPAIR) && !defined(MS_WINDOWS)
549
550
551
  int r;
  r = socketpair(family, type, protocol, fd);
  return r < 0 ? -errno : r;
552
#elif defined(USE_BSOCKETS)
553
  return bsocketpair(family, type, protocol, fd);
554
555
556
557
558
559
560
561
562
563
564
565
#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;
566
    int saved_errno = -1;
567
568
569
570
571
572
573

    if (protocol
#ifdef AF_UNIX
        || family != AF_UNIX
#endif
        ) {
#ifdef MS_WINDOWS
574
      return -WSAEAFNOSUPPORT;
575
#else
576
      return -EAFNOSUPPORT;
577
578
579
#endif
    }
    if (!fd) {
580
      return -EINVAL;
581
582
    }

583
    listener = tor_open_socket(AF_INET, type, 0);
584
    if (listener < 0)
585
      return -tor_socket_errno(-1);
586
    memset(&listen_addr, 0, sizeof(listen_addr));
587
    listen_addr.sin_family = AF_INET;
588
    listen_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
589
    listen_addr.sin_port = 0;   /* kernel chooses port.  */
590
591
    if (bind(listener, (struct sockaddr *) &listen_addr, sizeof (listen_addr))
        == -1)
592
      goto tidy_up_and_fail;
593
    if (listen(listener, 1) == -1)
594
      goto tidy_up_and_fail;
595

596
    connector = tor_open_socket(AF_INET, type, 0);
597
    if (connector < 0)
598
      goto tidy_up_and_fail;
599
    /* We want to find out the port number to connect to.  */
600
    size = sizeof(connect_addr);
601
    if (getsockname(listener, (struct sockaddr *) &connect_addr, &size) == -1)
602
      goto tidy_up_and_fail;
603
    if (size != sizeof (connect_addr))
604
      goto abort_tidy_up_and_fail;
605
    if (connect(connector, (struct sockaddr *) &connect_addr,
606
                sizeof(connect_addr)) == -1)
607
      goto tidy_up_and_fail;
608

609
    size = sizeof(listen_addr);
610
    acceptor = accept(listener, (struct sockaddr *) &listen_addr, &size);
611
    if (acceptor < 0)
612
      goto tidy_up_and_fail;
613
    if (size != sizeof(listen_addr))
614
      goto abort_tidy_up_and_fail;
615
616
617
618
    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)
619
      goto tidy_up_and_fail;
620
621
622
623
    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) {
624
      goto abort_tidy_up_and_fail;
625
626
627
    }
    fd[0] = connector;
    fd[1] = acceptor;
628

629
630
631
632
    return 0;

  abort_tidy_up_and_fail:
#ifdef MS_WINDOWS
633
    saved_errno = WSAECONNABORTED;
634
#else
635
    saved_errno = ECONNABORTED; /* I hope this is portable and appropriate.  */
636
637
#endif
  tidy_up_and_fail:
638
639
640
641
642
643
644
645
646
    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;
647
648
649
#endif
}

650
651
#define ULIMIT_BUFFER 32 /* keep 32 extra fd's beyond _ConnLimit */

652
653
654
655
656
657
658
659
660
/** Learn the maximum allowed number of file descriptors. (Some systems
 * have a low soft limit.
 *
 * We compute this by finding the largest number between <b>limit</b>
 * and <b>cap</b> that we can use. If we can't find a number greater
 * than or equal to <b>limit</b>, then we fail: return -1.
 *
 * Otherwise, return the number minus some buffer to allow for other
 * file descriptors we'll want available for ordinary use. */
661
int
662
663
set_max_file_descriptors(unsigned long limit, unsigned long cap)
{
664
#ifndef HAVE_GETRLIMIT
665
666
  log_fn(LOG_INFO, LD_NET,
         "This platform is missing getrlimit(). Proceeding.");
667
  if (limit < cap) {
668
    log_info(LD_CONFIG, "ConnLimit must be at most %d. Using that.", (int)cap);
669
670
    limit = cap;
  }
671
672
#else
  struct rlimit rlim;
673
674
675
  unsigned long most;
  tor_assert(limit > 0);
  tor_assert(cap > 0);
676
677

  if (getrlimit(RLIMIT_NOFILE, &rlim) != 0) {
678
679
    log_warn(LD_NET, "Could not get maximum number of file descriptors: %s",
             strerror(errno));
680
681
    return -1;
  }
682
  if (rlim.rlim_max < limit) {
683
684
685
    log_warn(LD_CONFIG,"We need %lu file descriptors available, and we're "
             "limited to %lu. Please change your ulimit -n.",
             limit, (unsigned long)rlim.rlim_max);
686
687
    return -1;
  }
688
  most = (rlim.rlim_max > cap) ? cap : (unsigned) rlim.rlim_max;
689
  if (most > rlim.rlim_cur) {
690
691
    log_info(LD_NET,"Raising max file descriptors from %lu to %lu.",
             (unsigned long)rlim.rlim_cur, most);
692
  }
693
  rlim.rlim_cur = most;
694
  if (setrlimit(RLIMIT_NOFILE, &rlim) != 0) {
695
696
    log_warn(LD_CONFIG, "Could not set maximum number of file descriptors: %s",
             strerror(errno));
697
698
    return -1;
  }
699
700
  /* leave some overhead for logs, etc, */
  limit = most;
701
#endif
702
703

  if (limit < ULIMIT_BUFFER) {
704
705
    log_warn(LD_CONFIG,
             "ConnLimit must be at least %d. Failing.", ULIMIT_BUFFER);
706
707
708
    return -1;
  }
  return limit - ULIMIT_BUFFER;
709
710
711
712
713
}

/** Call setuid and setgid to run as <b>user</b>:<b>group</b>.  Return 0 on
 * success.  On failure, log and return -1.
 */
714
int
715
switch_id(const char *user, const char *group)
716
{
717
718
719
720
721
722
723
#ifndef MS_WINDOWS
  struct passwd *pw = NULL;
  struct group *gr = NULL;

  if (user) {
    pw = getpwnam(user);
    if (pw == NULL) {
724
      log_warn(LD_CONFIG,"User '%s' not found.", user);
725
726
727
728
729
730
731
732
      return -1;
    }
  }

  /* switch the group first, while we still have the privileges to do so */
  if (group) {
    gr = getgrnam(group);
    if (gr == NULL) {
733
      log_warn(LD_CONFIG,"Group '%s' not found.", group);
734
735
736
737
      return -1;
    }

    if (setgid(gr->gr_gid) != 0) {
738
739
      log_warn(LD_GENERAL,"Error setting to configured GID: %s",
               strerror(errno));
740
741
742
743
      return -1;
    }
  } else if (user) {
    if (setgid(pw->pw_gid) != 0) {
744
      log_warn(LD_GENERAL,"Error setting to user GID: %s", strerror(errno));
745
746
747
748
749
750
751
752
      return -1;
    }
  }

  /* now that the group is switched, we can switch users and lose
     privileges */
  if (user) {
    if (setuid(pw->pw_uid) != 0) {
753
      log_warn(LD_GENERAL,"Error setting UID: %s", strerror(errno));
754
755
756
757
758
      return -1;
    }
  }

  return 0;
759
760
761
#else
  (void)user;
  (void)group;
762
763
#endif

764
765
  log_warn(LD_CONFIG,
           "User or group specified, but switching users is not supported.");
766
767
768
  return -1;
}

769
770
#ifdef HAVE_PWD_H
/** Allocate and return a string containing the home directory for the
771
 * user <b>username</b>. Only works on posix-like systems. */
772
773
774
775
776
777
778
char *
get_user_homedir(const char *username)
{
  struct passwd *pw;
  tor_assert(username);

  if (!(pw = getpwnam(username))) {
779
    log_err(LD_CONFIG,"User \"%s\" not found.", username);
780
781
782
783
784
785
    return NULL;
  }
  return tor_strdup(pw->pw_dir);
}
#endif

786
787
788
789
/** Set *addr to the IP address (in dotted-quad notation) stored in c.
 * Return 1 on success, 0 if c is badly formatted.  (Like inet_aton(c,addr),
 * but works on Windows and Solaris.)
 */
790
791
int
tor_inet_aton(const char *c, struct in_addr* addr)
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
{
#ifdef HAVE_INET_ATON
  return inet_aton(c, addr);
#else
  uint32_t r;
  tor_assert(c);
  tor_assert(addr);
  if (strcmp(c, "255.255.255.255") == 0) {
    addr->s_addr = 0xFFFFFFFFu;
    return 1;
  }
  r = inet_addr(c);
  if (r == INADDR_NONE)
    return 0;
  addr->s_addr = r;
  return 1;
#endif
}

811
812
813
814
815
816
817
818
/** Given <b>af</b>==AF_INET and <b>src</b> a struct in_addr, or
 * <b>af</b>==AF_INET6 and <b>src</b> a struct in6_addr, try to format the
 * address and store it in the <b>len</b>-byte buffer <b>dst</b>.  Returns
 * <b>dst</b> on success, NULL on failure.
 *
 * (Like inet_ntop(af,src,dst,len), but works on platforms that don't have it:
 * Tor sometimes needs to format ipv6 addresses even on platforms without ipv6
 * support.) */
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
const char *
tor_inet_ntop(int af, const void *src, char *dst, size_t len)
{
#ifdef HAVE_INET_NTOP
  return inet_ntop(af,src,dst,(socklen_t)len);
#else
  if (af == AF_INET) {
    if (tor_inet_ntoa(src, dst, len) < 0)
      return NULL;
    else
      return dst;
  } else if (af == AF_INET6) {
    const struct in6_addr *addr = src;
    char buf[64], *cp;
    int longestGapLen = 0, longestGapPos = -1, i,
      curGapPos = -1, curGapLen = 0;
    uint16_t words[8];
    for (i = 0; i < 8; ++i) {
      words[i] = (((uint16_t)addr->s6_addr[2*i])<<8) + addr->s6_addr[2*i+1];
    }
    if (words[0] == 0 && words[1] == 0 && words[2] == 0 && words[3] == 0 &&
        words[4] == 0 && (words[5] == 0 || words[5] == 0xffff) && words[6]) {
      /* This is an IPv4 address. */
842
843
844
845
846
847
848
849
850
      if (words[5] == 0) {
        tor_snprintf(buf, sizeof(buf), "::%d.%d.%d.%d",
                     addr->s6_addr[12], addr->s6_addr[13],
                     addr->s6_addr[14], addr->s6_addr[15]);
      } else {
        tor_snprintf(buf, sizeof(buf), "::%x:%d.%d.%d.%d", words[5],
                     addr->s6_addr[12], addr->s6_addr[13],
                     addr->s6_addr[14], addr->s6_addr[15]);
      }
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
      if (strlen(buf) > len)
        return NULL;
      strlcpy(dst, buf, len);
      return dst;
    }
    i = 0;
    while (i < 8) {
      if (words[i] == 0) {
        curGapPos = i++;
        curGapLen = 1;
        while (i<8 && words[i] == 0) {
          ++i; ++curGapLen;
        }
        if (curGapLen > longestGapLen) {
          longestGapPos = curGapPos;
          longestGapLen = curGapLen;
        }
      } else {
        ++i;
      }
    }
872
873
874
    if (longestGapLen<=1)
      longestGapPos = -1;

875
876
877
    cp = buf;
    for (i = 0; i < 8; ++i) {
      if (words[i] == 0 && longestGapPos == i) {
878
879
        if (i == 0)
          *cp++ = ':';
880
881
882
883
884
885
886
887
888
889
890
        *cp++ = ':';
        while (i < 8 && words[i] == 0)
          ++i;
        --i; /* to compensate for loop increment. */
      } else {
        tor_snprintf(cp, sizeof(buf)-(cp-buf), "%x", (unsigned)words[i]);
        cp += strlen(cp);
        if (i != 7)
          *cp++ = ':';
      }
    }
891
    *cp = '\0';
892
893
894
895
896
897
898
899
900
901
    if (strlen(buf) > len)
      return NULL;
    strlcpy(dst, buf, len);
    return dst;
  } else {
    return NULL;
  }
#endif
}

902
903
904
905
906
907
908
909
910
/** Given <b>af</b>==AF_INET or <b>af</b>==AF_INET6, and a string <b>src</b>
 * encoding an IPv4 address or IPv6 address correspondingly, try to parse the
 * address and store the result in <b>dst</b> (which must have space for a
 * struct in_addr or a struct in6_addr, as appropriate).  Return 1 on success,
 * 0 on a bad parse, and -1 on a bad <b>af</b>.
 *
 * (Like inet_pton(af,src,dst) but works on platforms that don't have it: Tor
 * sometimes needs to format ipv6 addresses even on platforms without ipv6
 * support.) */
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
int
tor_inet_pton(int af, const char *src, void *dst)
{
#ifdef HAVE_INET_PTON
  return inet_pton(af, src, dst);
#else
  if (af == AF_INET) {
    return tor_inet_aton(src, dst);
  } else if (af == AF_INET6) {
    struct in6_addr *out = dst;
    uint16_t words[8];
    int gapPos = -1, i, setWords=0;
    const char *dot = strchr(src, '.');
    const char *eow; /* end of words. */
    if (dot == src)
      return 0;
    else if (!dot)
      eow = src+strlen(src);
    else {
930
931
      int byte1,byte2,byte3,byte4;
      char more;
932
933
934
935
      for (eow = dot-1; eow >= src && TOR_ISDIGIT(*eow); --eow)
        ;
      ++eow;

936
937
938
939
940
941
942
943
944
      /* We use "scanf" because some platform inet_aton()s are too lax
       * about IPv4 addresses of the form "1.2.3" */
      if (sscanf(eow, "%d.%d.%d.%d%c", &byte1,&byte2,&byte3,&byte4,&more) != 4)
        return 0;

      if (byte1 > 255 || byte1 < 0 ||
          byte2 > 255 || byte2 < 0 ||
          byte3 > 255 || byte3 < 0 ||
          byte4 > 255 || byte4 < 0)
945
        return 0;
946
947
948

      words[6] = (byte1<<8) | byte2;
      words[7] = (byte3<<8) | byte4;
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
      setWords += 2;
    }

    i = 0;
    while (src < eow) {
      if (i > 7)
        return 0;
      if (TOR_ISXDIGIT(*src)) {
        char *next;
        int r = strtol(src, &next, 16);
        if (next > 4+src)
          return 0;
        if (next == src)
          return 0;
        if (r<0 || r>65536)
          return 0;

        words[i++] = (uint16_t)r;
        setWords++;
        src = next;
969
        if (*src != ':' && src != eow)
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
          return 0;
        ++src;
      } else if (*src == ':' && i > 0 && gapPos==-1) {
        gapPos = i;
        ++src;
      } else if (*src == ':' && i == 0 && src[1] == ':') {
        gapPos = i;
        src += 2;
      } else {
        return 0;
      }
    }

    if (setWords > 8 || (setWords < 8 && gapPos == -1))
      return 0;

    if (gapPos >= 0) {
987
      int nToMove = setWords - (dot ? 2 : 0) - gapPos;
988
      int gapLen = 8 - setWords;
989
      tor_assert(nToMove >= 0);
990
      memmove(&words[gapPos+gapLen], &words[gapPos],
991
992
              sizeof(uint16_t)*nToMove);
      memset(&words[gapPos], 0, sizeof(uint16_t)*gapLen);
993
994
995
996
997
998
999
1000
    }
    for (i = 0; i < 8; ++i) {
      out->s6_addr[2*i  ] = words[i] >> 8;
      out->s6_addr[2*i+1] = words[i] & 0xff;
    }

    return 1;
  } else {
For faster browsing, not all history is shown. View entire blame