beg nick for some documentation on the locking functions
[tor/rransom.git] / src / common / compat.c
blob11455356ed6887b07a47824d25ec80410f104c48
1 /* Copyright (c) 2003-2004, Roger Dingledine
2 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
3 * Copyright (c) 2007-2008, The Tor Project, Inc. */
4 /* See LICENSE for licensing information */
5 /* $Id$ */
6 const char compat_c_id[] =
7 "$Id$";
9 /**
10 * \file compat.c
11 * \brief Wrappers to make calls more portable. This code defines
12 * functions such as tor_malloc, tor_snprintf, get/set various data types,
13 * renaming, setting socket options, switching user IDs. It is basically
14 * where the non-portable items are conditionally included depending on
15 * the platform.
16 **/
18 /* This is required on rh7 to make strptime not complain.
19 * We also need it to make memmem get defined (where available)
21 #define _GNU_SOURCE
23 #include "compat.h"
25 #ifdef MS_WINDOWS
26 #include <process.h>
27 #include <windows.h>
28 #include <sys/locking.h>
29 #endif
31 #ifdef HAVE_UNAME
32 #include <sys/utsname.h>
33 #endif
34 #ifdef HAVE_UNISTD_H
35 #include <unistd.h>
36 #endif
37 #ifdef HAVE_SYS_FCNTL_H
38 #include <sys/fcntl.h>
39 #endif
40 #ifdef HAVE_PWD_H
41 #include <pwd.h>
42 #endif
43 #ifdef HAVE_GRP_H
44 #include <grp.h>
45 #endif
46 #ifdef HAVE_FCNTL_H
47 #include <fcntl.h>
48 #endif
49 #ifdef HAVE_ERRNO_H
50 #include <errno.h>
51 #endif
52 #ifdef HAVE_ARPA_INET_H
53 #include <arpa/inet.h>
54 #endif
56 #ifndef HAVE_GETTIMEOFDAY
57 #ifdef HAVE_FTIME
58 #include <sys/timeb.h>
59 #endif
60 #endif
62 #ifdef HAVE_NETDB_H
63 #include <netdb.h>
64 #endif
65 #ifdef HAVE_SYS_PARAM_H
66 #include <sys/param.h> /* FreeBSD needs this to know what version it is */
67 #endif
68 #include <stdio.h>
69 #include <stdlib.h>
70 #include <assert.h>
71 #ifdef HAVE_SIGNAL_H
72 #include <signal.h>
73 #endif
74 #ifdef HAVE_UTIME_H
75 #include <utime.h>
76 #endif
77 #ifdef HAVE_SYS_UTIME_H
78 #include <sys/utime.h>
79 #endif
80 #ifdef HAVE_SYS_MMAN_H
81 #include <sys/mman.h>
82 #endif
83 #ifdef HAVE_SYS_SYSLIMITS_H
84 #include <sys/syslimits.h>
85 #endif
86 #ifdef HAVE_SYS_FILE_H
87 #include <sys/file.h>
88 #endif
90 #ifdef USE_BSOCKETS
91 #include <bsocket.h>
92 #endif
94 #include "log.h"
95 #include "util.h"
96 #include "container.h"
97 #include "address.h"
99 /* Inline the strl functions if the platform doesn't have them. */
100 #ifndef HAVE_STRLCPY
101 #include "strlcpy.c"
102 #endif
103 #ifndef HAVE_STRLCAT
104 #include "strlcat.c"
105 #endif
107 #ifndef INADDR_NONE
108 /* This is used by inet_addr, but apparently Solaris doesn't define it
109 * anyplace. */
110 #define INADDR_NONE ((unsigned long) -1)
111 #endif
113 #ifdef HAVE_SYS_MMAN_H
114 /** Implementation for tor_mmap_t: holds the regular tor_mmap_t, along
115 * with extra fields needed for mmap()-based memory mapping. */
116 typedef struct tor_mmap_impl_t {
117 tor_mmap_t base;
118 size_t mapping_size; /**< Size of the actual mapping. (This is this file
119 * size, rounded up to the nearest page.) */
120 } tor_mmap_impl_t;
122 /** Try to create a memory mapping for <b>filename</b> and return it. On
123 * failure, return NULL. Sets errno properly, using ERANGE to mean
124 * "empty file". */
125 tor_mmap_t *
126 tor_mmap_file(const char *filename)
128 int fd; /* router file */
129 char *string;
130 int page_size;
131 tor_mmap_impl_t *res;
132 size_t size, filesize;
134 tor_assert(filename);
136 fd = open(filename, O_RDONLY, 0);
137 if (fd<0) {
138 int save_errno = errno;
139 int severity = (errno == ENOENT) ? LOG_INFO : LOG_WARN;
140 log_fn(severity, LD_FS,"Could not open \"%s\" for mmap(): %s",filename,
141 strerror(errno));
142 errno = save_errno;
143 return NULL;
146 size = filesize = (size_t) lseek(fd, 0, SEEK_END);
147 lseek(fd, 0, SEEK_SET);
148 /* ensure page alignment */
149 page_size = getpagesize();
150 size += (size%page_size) ? page_size-(size%page_size) : 0;
152 if (!size) {
153 /* Zero-length file. If we call mmap on it, it will succeed but
154 * return NULL, and bad things will happen. So just fail. */
155 log_info(LD_FS,"File \"%s\" is empty. Ignoring.",filename);
156 errno = ERANGE;
157 close(fd);
158 return NULL;
161 string = mmap(0, size, PROT_READ, MAP_PRIVATE, fd, 0);
162 close(fd);
163 if (string == MAP_FAILED) {
164 int save_errno = errno;
165 log_warn(LD_FS,"Could not mmap file \"%s\": %s", filename,
166 strerror(errno));
167 errno = save_errno;
168 return NULL;
171 res = tor_malloc_zero(sizeof(tor_mmap_impl_t));
172 res->base.data = string;
173 res->base.size = filesize;
174 res->mapping_size = size;
176 return &(res->base);
178 /** Release storage held for a memory mapping. */
179 void
180 tor_munmap_file(tor_mmap_t *handle)
182 tor_mmap_impl_t *h = SUBTYPE_P(handle, tor_mmap_impl_t, base);
183 munmap((char*)h->base.data, h->mapping_size);
184 tor_free(h);
186 #elif defined(MS_WINDOWS)
187 /** Implementation for tor_mmap_t: holds the regular tor_mmap_t, along
188 * with extra fields needed for WIN32 memory mapping. */
189 typedef struct win_mmap_t {
190 tor_mmap_t base;
191 HANDLE file_handle;
192 HANDLE mmap_handle;
193 } win_mmap_t;
194 tor_mmap_t *
195 tor_mmap_file(const char *filename)
197 win_mmap_t *res = tor_malloc_zero(sizeof(win_mmap_t));
198 int empty = 0;
199 res->file_handle = INVALID_HANDLE_VALUE;
200 res->mmap_handle = NULL;
202 res->file_handle = CreateFile(filename,
203 GENERIC_READ, FILE_SHARE_READ,
204 NULL,
205 OPEN_EXISTING,
206 FILE_ATTRIBUTE_NORMAL,
209 if (res->file_handle == INVALID_HANDLE_VALUE)
210 goto win_err;
212 res->base.size = GetFileSize(res->file_handle, NULL);
214 if (res->base.size == 0) {
215 log_info(LD_FS,"File \"%s\" is empty. Ignoring.",filename);
216 empty = 1;
217 goto err;
220 res->mmap_handle = CreateFileMapping(res->file_handle,
221 NULL,
222 PAGE_READONLY,
223 #if SIZEOF_SIZE_T > 4
224 (res->base.size >> 32),
225 #else
227 #endif
228 (res->base.size & 0xfffffffful),
229 NULL);
230 if (res->mmap_handle == NULL)
231 goto win_err;
232 res->base.data = (char*) MapViewOfFile(res->mmap_handle,
233 FILE_MAP_READ,
234 0, 0, 0);
235 if (!res->base.data)
236 goto win_err;
238 return &(res->base);
239 win_err: {
240 DWORD e = GetLastError();
241 int severity = (e == ERROR_FILE_NOT_FOUND || e == ERROR_PATH_NOT_FOUND) ?
242 LOG_INFO : LOG_WARN;
243 char *msg = format_win32_error(e);
244 log_fn(severity, LD_FS, "Couldn't mmap file \"%s\": %s", filename, msg);
245 tor_free(msg);
246 if (e == ERROR_FILE_NOT_FOUND || e == ERROR_PATH_NOT_FOUND)
247 errno = ENOENT;
248 else
249 errno = EINVAL;
251 err:
252 if (empty)
253 errno = ERANGE;
254 tor_munmap_file(&res->base);
255 return NULL;
257 void
258 tor_munmap_file(tor_mmap_t *handle)
260 win_mmap_t *h = SUBTYPE_P(handle, win_mmap_t, base);
261 if (handle->data)
262 /* This is an ugly cast, but without it, "data" in struct tor_mmap_t would
263 have to be redefined as non-const. */
264 UnmapViewOfFile( (LPVOID) handle->data);
266 if (h->mmap_handle != NULL)
267 CloseHandle(h->mmap_handle);
268 if (h->file_handle != INVALID_HANDLE_VALUE)
269 CloseHandle(h->file_handle);
270 tor_free(h);
272 #else
273 tor_mmap_t *
274 tor_mmap_file(const char *filename)
276 struct stat st;
277 char *res = read_file_to_str(filename, RFTS_BIN|RFTS_IGNORE_MISSING, &st);
278 tor_mmap_t *handle;
279 if (! res)
280 return NULL;
281 handle = tor_malloc_zero(sizeof(tor_mmap_t));
282 handle->data = res;
283 handle->size = st.st_size;
284 return handle;
286 void
287 tor_munmap_file(tor_mmap_t *handle)
289 char *d = (char*)handle->data;
290 tor_free(d);
291 memset(handle, 0, sizeof(tor_mmap_t));
292 tor_free(handle);
294 #endif
296 /** Replacement for snprintf. Differs from platform snprintf in two
297 * ways: First, always NUL-terminates its output. Second, always
298 * returns -1 if the result is truncated. (Note that this return
299 * behavior does <i>not</i> conform to C99; it just happens to be
300 * easier to emulate "return -1" with conformant implementations than
301 * it is to emulate "return number that would be written" with
302 * non-conformant implementations.) */
304 tor_snprintf(char *str, size_t size, const char *format, ...)
306 va_list ap;
307 int r;
308 va_start(ap,format);
309 r = tor_vsnprintf(str,size,format,ap);
310 va_end(ap);
311 return r;
314 /** Replacement for vsnprintf; behavior differs as tor_snprintf differs from
315 * snprintf.
318 tor_vsnprintf(char *str, size_t size, const char *format, va_list args)
320 int r;
321 if (size == 0)
322 return -1; /* no place for the NUL */
323 if (size > SIZE_T_CEILING)
324 return -1;
325 #ifdef MS_WINDOWS
326 r = _vsnprintf(str, size, format, args);
327 #else
328 r = vsnprintf(str, size, format, args);
329 #endif
330 str[size-1] = '\0';
331 if (r < 0 || ((size_t)r) >= size)
332 return -1;
333 return r;
336 /** Given <b>hlen</b> bytes at <b>haystack</b> and <b>nlen</b> bytes at
337 * <b>needle</b>, return a pointer to the first occurrence of the needle
338 * within the haystack, or NULL if there is no such occurrence.
340 * Requires that nlen be greater than zero.
342 const void *
343 tor_memmem(const void *_haystack, size_t hlen,
344 const void *_needle, size_t nlen)
346 #if defined(HAVE_MEMMEM) && (!defined(__GNUC__) || __GNUC__ >= 2)
347 tor_assert(nlen);
348 return memmem(_haystack, hlen, _needle, nlen);
349 #else
350 /* This isn't as fast as the GLIBC implementation, but it doesn't need to
351 * be. */
352 const char *p, *end;
353 const char *haystack = (const char*)_haystack;
354 const char *needle = (const char*)_needle;
355 char first;
356 tor_assert(nlen);
358 p = haystack;
359 end = haystack + hlen;
360 first = *(const char*)needle;
361 while ((p = memchr(p, first, end-p))) {
362 if (p+nlen > end)
363 return NULL;
364 if (!memcmp(p, needle, nlen))
365 return p;
366 ++p;
368 return NULL;
369 #endif
372 #ifdef MS_WINDOWS
373 /** Take a filename and return a pointer to its final element. This
374 * function is called on __FILE__ to fix a MSVC nit where __FILE__
375 * contains the full path to the file. This is bad, because it
376 * confuses users to find the home directory of the person who
377 * compiled the binary in their warrning messages.
379 const char *
380 tor_fix_source_file(const char *fname)
382 const char *cp1, *cp2, *r;
383 cp1 = strrchr(fname, '/');
384 cp2 = strrchr(fname, '\\');
385 if (cp1 && cp2) {
386 r = (cp1<cp2)?(cp2+1):(cp1+1);
387 } else if (cp1) {
388 r = cp1+1;
389 } else if (cp2) {
390 r = cp2+1;
391 } else {
392 r = fname;
394 return r;
396 #endif
399 * Read a 16-bit value beginning at <b>cp</b>. Equivalent to
400 * *(uint16_t*)(cp), but will not cause segfaults on platforms that forbid
401 * unaligned memory access.
403 uint16_t
404 get_uint16(const char *cp)
406 uint16_t v;
407 memcpy(&v,cp,2);
408 return v;
411 * Read a 32-bit value beginning at <b>cp</b>. Equivalent to
412 * *(uint32_t*)(cp), but will not cause segfaults on platforms that forbid
413 * unaligned memory access.
415 uint32_t
416 get_uint32(const char *cp)
418 uint32_t v;
419 memcpy(&v,cp,4);
420 return v;
423 * Set a 16-bit value beginning at <b>cp</b> to <b>v</b>. Equivalent to
424 * *(uint16_t)(cp) = v, but will not cause segfaults on platforms that forbid
425 * unaligned memory access. */
426 void
427 set_uint16(char *cp, uint16_t v)
429 memcpy(cp,&v,2);
432 * Set a 32-bit value beginning at <b>cp</b> to <b>v</b>. Equivalent to
433 * *(uint32_t)(cp) = v, but will not cause segfaults on platforms that forbid
434 * unaligned memory access. */
435 void
436 set_uint32(char *cp, uint32_t v)
438 memcpy(cp,&v,4);
442 * Rename the file <b>from</b> to the file <b>to</b>. On unix, this is
443 * the same as rename(2). On windows, this removes <b>to</b> first if
444 * it already exists.
445 * Returns 0 on success. Returns -1 and sets errno on failure.
448 replace_file(const char *from, const char *to)
450 #ifndef MS_WINDOWS
451 return rename(from,to);
452 #else
453 switch (file_status(to))
455 case FN_NOENT:
456 break;
457 case FN_FILE:
458 if (unlink(to)) return -1;
459 break;
460 case FN_ERROR:
461 return -1;
462 case FN_DIR:
463 errno = EISDIR;
464 return -1;
466 return rename(from,to);
467 #endif
470 /** Change <b>fname</b>'s modification time to now. */
472 touch_file(const char *fname)
474 if (utime(fname, NULL)!=0)
475 return -1;
476 return 0;
479 struct tor_lockfile_t {
480 char *filename;
481 int fd;
484 /** DOCDOC. What's this function do? */
485 tor_lockfile_t *
486 tor_lockfile_lock(const char *filename, int blocking, int *locked_out)
488 tor_lockfile_t *result;
489 int fd;
490 *locked_out = 0;
492 log_info(LD_FS, "Locking \"%s\"", filename);
493 fd = open(filename, O_RDWR|O_CREAT|O_TRUNC, 0600);
494 if (fd < 0) {
495 log_warn(LD_FS,"Couldn't open \"%s\" for locking: %s", filename,
496 strerror(errno));
497 return NULL;
499 #ifdef WIN32
500 _lseek(fd, 0, SEEK_SET);
501 if (_locking(fd, blocking ? _LK_LOCK : _LK_NBLCK, 0) < 0) {
502 if (errno != EDEADLOCK)
503 log_warn(LD_FS,"Couldn't lock \"%s\": %s", filename, strerror(errno));
504 else
505 *locked_out = 1;
506 close(fd);
507 return NULL;
509 #else
510 if (flock(fd, LOCK_EX|(blocking ? 0 : LOCK_NB)) < 0) {
511 if (errno != EWOULDBLOCK)
512 log_warn(LD_FS,"Couldn't lock \"%s\": %s", filename, strerror(errno));
513 else
514 *locked_out = 1;
515 close(fd);
516 return NULL;
518 #endif
520 result = tor_malloc(sizeof(tor_lockfile_t));
521 result->filename = tor_strdup(filename);
522 result->fd = fd;
523 return result;
526 void
527 tor_lockfile_unlock(tor_lockfile_t *lockfile)
529 tor_assert(lockfile);
531 log_info(LD_FS, "Unlocking \"%s\"", lockfile->filename);
532 #ifdef WIN32
533 _lseek(lockfile->fd, 0, SEEK_SET);
534 if (_locking(lockfile->fd, _LK_UNLCK, 0) < 0) {
535 log_warn(LD_FS,"Error unlocking \"%s\": %s", lockfile->filename,
536 strerror(errno));
538 #else
539 if (flock(lockfile->fd, LOCK_UN) < 0) {
540 log_warn(LD_FS, "Error unlocking \"%s\": %s", lockfile->filename,
541 strerror(errno));
543 #endif
545 close(lockfile->fd);
546 lockfile->fd = -1;
547 tor_free(lockfile->filename);
548 tor_free(lockfile);
551 #undef DEBUG_SOCKET_COUNTING
552 #ifdef DEBUG_SOCKET_COUNTING
553 /** A bitarray of all fds that should be passed to tor_socket_close(). Only
554 * used if DEBUG_SOCKET_COUNTING is defined. */
555 static bitarray_t *open_sockets = NULL;
556 /** The size of <b>open_sockets</b>, in bits. */
557 static int max_socket = -1;
558 #endif
560 /** Count of number of sockets currently open. (Undercounts sockets opened by
561 * eventdns and libevent.) */
562 static int n_sockets_open = 0;
564 /** As close(), but guaranteed to work for sockets across platforms (including
565 * Windows, where close()ing a socket doesn't work. Returns 0 on success, -1
566 * on failure. */
568 tor_close_socket(int s)
570 int r = 0;
571 #ifdef DEBUG_SOCKET_COUNTING
572 if (s > max_socket || ! bitarray_is_set(open_sockets, s)) {
573 log_warn(LD_BUG, "Closing a socket (%d) that wasn't returned by tor_open_"
574 "socket(), or that was already closed or something.", s);
575 } else {
576 tor_assert(open_sockets && s <= max_socket);
577 bitarray_clear(open_sockets, s);
579 #endif
580 /* On Windows, you have to call close() on fds returned by open(),
581 * and closesocket() on fds returned by socket(). On Unix, everything
582 * gets close()'d. We abstract this difference by always using
583 * tor_close_socket to close sockets, and always using close() on
584 * files.
586 #ifdef USE_BSOCKETS
587 r = bclose(s);
588 #elif defined(MS_WINDOWS)
589 r = closesocket(s);
590 #else
591 r = close(s);
592 #endif
593 if (r == 0) {
594 --n_sockets_open;
595 } else {
596 int err = tor_socket_errno(-1);
597 log_info(LD_NET, "Close returned an error: %s", tor_socket_strerror(err));
598 #ifdef WIN32
599 if (err != WSAENOTSOCK)
600 --n_sockets_open;
601 #else
602 if (err != EBADF)
603 --n_sockets_open;
604 #endif
605 r = -1;
607 if (n_sockets_open < 0)
608 log_warn(LD_BUG, "Our socket count is below zero: %d. Please submit a "
609 "bug report.", n_sockets_open);
610 return r;
613 #ifdef DEBUG_SOCKET_COUNTING
614 /** Helper: if DEBUG_SOCKET_COUNTING is enabled, remember that <b>s</b> is
615 * now an open socket. */
616 static INLINE void
617 mark_socket_open(int s)
619 if (s > max_socket) {
620 if (max_socket == -1) {
621 open_sockets = bitarray_init_zero(s+128);
622 max_socket = s+128;
623 } else {
624 open_sockets = bitarray_expand(open_sockets, max_socket, s+128);
625 max_socket = s+128;
628 if (bitarray_is_set(open_sockets, s)) {
629 log_warn(LD_BUG, "I thought that %d was already open, but socket() just "
630 "gave it to me!", s);
632 bitarray_set(open_sockets, s);
634 #else
635 #define mark_socket_open(s) STMT_NIL
636 #endif
638 /** As socket(), but counts the number of open sockets. */
640 tor_open_socket(int domain, int type, int protocol)
642 int s = socket(domain, type, protocol);
643 if (s >= 0) {
644 ++n_sockets_open;
645 mark_socket_open(s);
647 return s;
650 /** As socket(), but counts the number of open sockets. */
652 tor_accept_socket(int sockfd, struct sockaddr *addr, socklen_t *len)
654 int s = accept(sockfd, addr, len);
655 if (s >= 0) {
656 ++n_sockets_open;
657 mark_socket_open(s);
659 return s;
662 /** Return the number of sockets we currently have opened. */
664 get_n_open_sockets(void)
666 return n_sockets_open;
669 /** Turn <b>socket</b> into a nonblocking socket.
671 void
672 set_socket_nonblocking(int socket)
674 #if defined(MS_WINDOWS) && !defined(USE_BSOCKETS)
675 unsigned long nonblocking = 1;
676 ioctlsocket(socket, FIONBIO, (unsigned long*) &nonblocking);
677 #else
678 fcntl(socket, F_SETFL, O_NONBLOCK);
679 #endif
683 * Allocate a pair of connected sockets. (Like socketpair(family,
684 * type,protocol,fd), but works on systems that don't have
685 * socketpair.)
687 * Currently, only (AF_UNIX, SOCK_STREAM, 0) sockets are supported.
689 * Note that on systems without socketpair, this call will fail if
690 * localhost is inaccessible (for example, if the networking
691 * stack is down). And even if it succeeds, the socket pair will not
692 * be able to read while localhost is down later (the socket pair may
693 * even close, depending on OS-specific timeouts).
695 * Returns 0 on success and -errno on failure; do not rely on the value
696 * of errno or WSAGetLastError().
698 /* It would be nicer just to set errno, but that won't work for windows. */
700 tor_socketpair(int family, int type, int protocol, int fd[2])
702 //don't use win32 socketpairs (they are always bad)
703 #if defined(HAVE_SOCKETPAIR) && !defined(MS_WINDOWS)
704 int r;
705 r = socketpair(family, type, protocol, fd);
706 if (r == 0) {
707 if (fd[0] >= 0) {
708 ++n_sockets_open;
709 mark_socket_open(fd[0]);
711 if (fd[1] >= 0) {
712 ++n_sockets_open;
713 mark_socket_open(fd[1]);
716 return r < 0 ? -errno : r;
717 #elif defined(USE_BSOCKETS)
718 return bsocketpair(family, type, protocol, fd);
719 #else
720 /* This socketpair does not work when localhost is down. So
721 * it's really not the same thing at all. But it's close enough
722 * for now, and really, when localhost is down sometimes, we
723 * have other problems too.
725 int listener = -1;
726 int connector = -1;
727 int acceptor = -1;
728 struct sockaddr_in listen_addr;
729 struct sockaddr_in connect_addr;
730 int size;
731 int saved_errno = -1;
733 if (protocol
734 #ifdef AF_UNIX
735 || family != AF_UNIX
736 #endif
738 #ifdef MS_WINDOWS
739 return -WSAEAFNOSUPPORT;
740 #else
741 return -EAFNOSUPPORT;
742 #endif
744 if (!fd) {
745 return -EINVAL;
748 listener = tor_open_socket(AF_INET, type, 0);
749 if (listener < 0)
750 return -tor_socket_errno(-1);
751 memset(&listen_addr, 0, sizeof(listen_addr));
752 listen_addr.sin_family = AF_INET;
753 listen_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
754 listen_addr.sin_port = 0; /* kernel chooses port. */
755 if (bind(listener, (struct sockaddr *) &listen_addr, sizeof (listen_addr))
756 == -1)
757 goto tidy_up_and_fail;
758 if (listen(listener, 1) == -1)
759 goto tidy_up_and_fail;
761 connector = tor_open_socket(AF_INET, type, 0);
762 if (connector < 0)
763 goto tidy_up_and_fail;
764 /* We want to find out the port number to connect to. */
765 size = sizeof(connect_addr);
766 if (getsockname(listener, (struct sockaddr *) &connect_addr, &size) == -1)
767 goto tidy_up_and_fail;
768 if (size != sizeof (connect_addr))
769 goto abort_tidy_up_and_fail;
770 if (connect(connector, (struct sockaddr *) &connect_addr,
771 sizeof(connect_addr)) == -1)
772 goto tidy_up_and_fail;
774 size = sizeof(listen_addr);
775 acceptor = tor_accept_socket(listener,
776 (struct sockaddr *) &listen_addr, &size);
777 if (acceptor < 0)
778 goto tidy_up_and_fail;
779 if (size != sizeof(listen_addr))
780 goto abort_tidy_up_and_fail;
781 tor_close_socket(listener);
782 /* Now check we are talking to ourself by matching port and host on the
783 two sockets. */
784 if (getsockname(connector, (struct sockaddr *) &connect_addr, &size) == -1)
785 goto tidy_up_and_fail;
786 if (size != sizeof (connect_addr)
787 || listen_addr.sin_family != connect_addr.sin_family
788 || listen_addr.sin_addr.s_addr != connect_addr.sin_addr.s_addr
789 || listen_addr.sin_port != connect_addr.sin_port) {
790 goto abort_tidy_up_and_fail;
792 fd[0] = connector;
793 fd[1] = acceptor;
795 return 0;
797 abort_tidy_up_and_fail:
798 #ifdef MS_WINDOWS
799 saved_errno = WSAECONNABORTED;
800 #else
801 saved_errno = ECONNABORTED; /* I hope this is portable and appropriate. */
802 #endif
803 tidy_up_and_fail:
804 if (saved_errno < 0)
805 saved_errno = errno;
806 if (listener != -1)
807 tor_close_socket(listener);
808 if (connector != -1)
809 tor_close_socket(connector);
810 if (acceptor != -1)
811 tor_close_socket(acceptor);
812 return -saved_errno;
813 #endif
816 #define ULIMIT_BUFFER 32 /* keep 32 extra fd's beyond _ConnLimit */
818 /** Learn the maximum allowed number of file descriptors. (Some systems
819 * have a low soft limit.
821 * We compute this by finding the largest number that we can use.
822 * If we can't find a number greater than or equal to <b>limit</b>,
823 * then we fail: return -1.
825 * Otherwise, return 0 and store the maximum we found inside <b>max_out</b>.*/
827 set_max_file_descriptors(rlim_t limit, int *max_out)
829 /* Define some maximum connections values for systems where we cannot
830 * automatically determine a limit. Re Cygwin, see
831 * http://archives.seul.org/or/talk/Aug-2006/msg00210.html
832 * For an iPhone, 9999 should work. For Windows and all other unknown
833 * systems we use 15000 as the default. */
834 #ifndef HAVE_GETRLIMIT
835 #if defined(CYGWIN) || defined(__CYGWIN__)
836 const char *platform = "Cygwin";
837 const unsigned long MAX_CONNECTIONS = 3200;
838 #elif defined(IPHONE)
839 const char *platform = "iPhone";
840 const unsigned long MAX_CONNECTIONS = 9999;
841 #elif defined(MS_WINDOWS)
842 const char *platform = "Windows";
843 const unsigned long MAX_CONNECTIONS = 15000;
844 #else
845 const char *platform = "unknown platforms with no getrlimit()";
846 const unsigned long MAX_CONNECTIONS = 15000;
847 #endif
848 log_fn(LOG_INFO, LD_NET,
849 "This platform is missing getrlimit(). Proceeding.");
850 if (limit > MAX_CONNECTIONS) {
851 log_warn(LD_CONFIG,
852 "We do not support more than %lu file descriptors "
853 "on %s. Tried to raise to %lu.",
854 (unsigned long)MAX_CONNECTIONS, platform, (unsigned long)limit);
855 return -1;
857 limit = MAX_CONNECTIONS;
858 #else /* HAVE_GETRLIMIT */
859 struct rlimit rlim;
860 tor_assert(limit > 0);
862 if (getrlimit(RLIMIT_NOFILE, &rlim) != 0) {
863 log_warn(LD_NET, "Could not get maximum number of file descriptors: %s",
864 strerror(errno));
865 return -1;
868 if (rlim.rlim_max < limit) {
869 log_warn(LD_CONFIG,"We need %lu file descriptors available, and we're "
870 "limited to %lu. Please change your ulimit -n.",
871 (unsigned long)limit, (unsigned long)rlim.rlim_max);
872 return -1;
875 if (rlim.rlim_max > rlim.rlim_cur) {
876 log_info(LD_NET,"Raising max file descriptors from %lu to %lu.",
877 (unsigned long)rlim.rlim_cur, (unsigned long)rlim.rlim_max);
879 rlim.rlim_cur = rlim.rlim_max;
881 if (setrlimit(RLIMIT_NOFILE, &rlim) != 0) {
882 int bad = 1;
883 #ifdef OPEN_MAX
884 if (errno == EINVAL && OPEN_MAX < rlim.rlim_cur) {
885 /* On some platforms, OPEN_MAX is the real limit, and getrlimit() is
886 * full of nasty lies. I'm looking at you, OSX 10.5.... */
887 rlim.rlim_cur = OPEN_MAX;
888 if (setrlimit(RLIMIT_NOFILE, &rlim) == 0) {
889 if (rlim.rlim_cur < (rlim_t)limit) {
890 log_warn(LD_CONFIG, "We are limited to %lu file descriptors by "
891 "OPEN_MAX, and ConnLimit is %lu. Changing ConnLimit; sorry.",
892 (unsigned long)OPEN_MAX, (unsigned long)limit);
893 } else {
894 log_info(LD_CONFIG, "Dropped connection limit to OPEN_MAX (%lu); "
895 "Apparently, %lu was too high and rlimit lied to us.",
896 (unsigned long)OPEN_MAX, (unsigned long)rlim.rlim_max);
898 bad = 0;
901 #endif /* OPEN_MAX */
902 if (bad) {
903 log_warn(LD_CONFIG,"Couldn't set maximum number of file descriptors: %s",
904 strerror(errno));
905 return -1;
908 /* leave some overhead for logs, etc, */
909 limit = rlim.rlim_cur;
910 #endif /* HAVE_GETRLIMIT */
912 if (limit < ULIMIT_BUFFER) {
913 log_warn(LD_CONFIG,
914 "ConnLimit must be at least %d. Failing.", ULIMIT_BUFFER);
915 return -1;
917 if (limit > INT_MAX)
918 limit = INT_MAX;
919 tor_assert(max_out);
920 *max_out = (int)limit - ULIMIT_BUFFER;
921 return 0;
924 /** Log details of current user and group credentials. Return 0 on
925 * success. Logs and return -1 on failure.
927 static int
928 log_credential_status(void)
930 #define CREDENTIAL_LOG_LEVEL LOG_INFO
931 #ifndef MS_WINDOWS
932 /* Real, effective and saved UIDs */
933 uid_t ruid, euid, suid;
934 /* Read, effective and saved GIDs */
935 gid_t rgid, egid, sgid;
936 /* Supplementary groups */
937 gid_t sup_gids[NGROUPS_MAX + 1];
938 /* Number of supplementary groups */
939 int ngids;
941 /* log UIDs */
942 #ifdef HAVE_GETRESUID
943 if (getresuid(&ruid, &euid, &suid) != 0 ) {
944 log_warn(LD_GENERAL, "Error getting changed UIDs: %s", strerror(errno));
945 return -1;
946 } else {
947 log_fn(CREDENTIAL_LOG_LEVEL, LD_GENERAL,
948 "UID is %u (real), %u (effective), %u (saved)", ruid, euid, suid);
950 #else
951 /* getresuid is not present on MacOS X, so we can't get the saved (E)UID */
952 ruid = getuid();
953 euid = geteuid();
954 (void)suid;
956 log_fn(CREDENTIAL_LOG_LEVEL, LD_GENERAL,
957 "UID is %u (real), %u (effective), unknown (saved)", ruid, euid);
958 #endif
960 /* log GIDs */
961 #ifdef HAVE_GETRESGID
962 if (getresgid(&rgid, &egid, &sgid) != 0 ) {
963 log_warn(LD_GENERAL, "Error getting changed GIDs: %s", strerror(errno));
964 return -1;
965 } else {
966 log_fn(CREDENTIAL_LOG_LEVEL, LD_GENERAL,
967 "GID is %u (real), %u (effective), %u (saved)", rgid, egid, sgid);
969 #else
970 /* getresgid is not present on MacOS X, so we can't get the saved (E)GID */
971 rgid = getgid();
972 egid = getegid();
973 (void)sgid;
974 log_fn(CREDENTIAL_LOG_LEVEL, LD_GENERAL,
975 "GID is %u (real), %u (effective), unknown (saved)", rgid, egid);
976 #endif
978 /* log supplementary groups */
979 if ((ngids = getgroups(NGROUPS_MAX + 1, sup_gids)) < 0) {
980 log_warn(LD_GENERAL, "Error getting supplementary GIDs: %s",
981 strerror(errno));
982 return -1;
983 } else {
984 int i;
985 char *strgid;
986 char *s = NULL;
987 int formatting_error = 0;
988 smartlist_t *elts = smartlist_create();
990 for (i = 0; i<ngids; i++) {
991 strgid = tor_malloc(11);
992 if (tor_snprintf(strgid, 11, "%u", (unsigned)sup_gids[i]) == -1) {
993 log_warn(LD_GENERAL, "Error printing supplementary GIDs");
994 formatting_error = 1;
995 goto error;
997 smartlist_add(elts, strgid);
1000 s = smartlist_join_strings(elts, " ", 0, NULL);
1002 log_fn(CREDENTIAL_LOG_LEVEL, LD_GENERAL, "Supplementary groups are: %s",s);
1004 error:
1005 tor_free(s);
1006 SMARTLIST_FOREACH(elts, char *, cp,
1008 tor_free(cp);
1010 smartlist_free(elts);
1012 if (formatting_error)
1013 return -1;
1015 #endif
1017 return 0;
1020 /** Call setuid and setgid to run as <b>user</b> and switch to their
1021 * primary group. Return 0 on success. On failure, log and return -1.
1024 switch_id(const char *user)
1026 #ifndef MS_WINDOWS
1027 struct passwd *pw = NULL;
1028 uid_t old_uid;
1029 gid_t old_gid;
1030 static int have_already_switched_id = 0;
1032 tor_assert(user);
1034 if (have_already_switched_id)
1035 return 0;
1037 /* Log the initial credential state */
1038 if (log_credential_status())
1039 return -1;
1041 log_fn(CREDENTIAL_LOG_LEVEL, LD_GENERAL, "Changing user and groups");
1043 /* Get old UID/GID to check if we changed correctly */
1044 old_uid = getuid();
1045 old_gid = getgid();
1047 /* Lookup the user and group information, if we have a problem, bail out. */
1048 pw = getpwnam(user);
1049 if (pw == NULL) {
1050 log_warn(LD_CONFIG, "Error setting configured user: %s not found", user);
1051 return -1;
1054 /* Properly switch egid,gid,euid,uid here or bail out */
1055 if (setgroups(1, &pw->pw_gid)) {
1056 log_warn(LD_GENERAL, "Error setting groups to gid %d: \"%s\". "
1057 "If you set the \"User\" option, you must start Tor as root.",
1058 (int)pw->pw_gid, strerror(errno));
1059 return -1;
1062 if (setegid(pw->pw_gid)) {
1063 log_warn(LD_GENERAL, "Error setting egid to %d: %s",
1064 (int)pw->pw_gid, strerror(errno));
1065 return -1;
1068 if (setgid(pw->pw_gid)) {
1069 log_warn(LD_GENERAL, "Error setting gid to %d: %s",
1070 (int)pw->pw_gid, strerror(errno));
1071 return -1;
1074 if (setuid(pw->pw_uid)) {
1075 log_warn(LD_GENERAL, "Error setting configured uid to %s (%d): %s",
1076 user, (int)pw->pw_uid, strerror(errno));
1077 return -1;
1080 if (seteuid(pw->pw_uid)) {
1081 log_warn(LD_GENERAL, "Error setting configured euid to %s (%d): %s",
1082 user, (int)pw->pw_uid, strerror(errno));
1083 return -1;
1086 /* This is how OpenBSD rolls:
1087 if (setgroups(1, &pw->pw_gid) || setegid(pw->pw_gid) ||
1088 setgid(pw->pw_gid) || setuid(pw->pw_uid) || seteuid(pw->pw_uid)) {
1089 setgid(pw->pw_gid) || seteuid(pw->pw_uid) || setuid(pw->pw_uid)) {
1090 log_warn(LD_GENERAL, "Error setting configured UID/GID: %s",
1091 strerror(errno));
1092 return -1;
1096 /* We've properly switched egid, gid, euid, uid, and supplementary groups if
1097 * we're here. */
1099 #if !defined(CYGWIN) && !defined(__CYGWIN__)
1100 /* If we tried to drop privilege to a group/user other than root, attempt to
1101 * restore root (E)(U|G)ID, and abort if the operation succeeds */
1103 /* Only check for privilege dropping if we were asked to be non-root */
1104 if (pw->pw_uid) {
1105 /* Try changing GID/EGID */
1106 if (pw->pw_gid != old_gid &&
1107 (setgid(old_gid) != -1 || setegid(old_gid) != -1)) {
1108 log_warn(LD_GENERAL, "Was able to restore group credentials even after "
1109 "switching GID: this means that the setgid code didn't work.");
1110 return -1;
1113 /* Try changing UID/EUID */
1114 if (pw->pw_uid != old_uid &&
1115 (setuid(old_uid) != -1 || seteuid(old_uid) != -1)) {
1116 log_warn(LD_GENERAL, "Was able to restore user credentials even after "
1117 "switching UID: this means that the setuid code didn't work.");
1118 return -1;
1121 #endif
1123 /* Check what really happened */
1124 if (log_credential_status()) {
1125 return -1;
1128 have_already_switched_id = 1; /* mark success so we never try again */
1129 return 0;
1131 #else
1132 (void)user;
1134 log_warn(LD_CONFIG,
1135 "User specified but switching users is unsupported on your OS.");
1136 return -1;
1137 #endif
1140 #ifdef HAVE_PWD_H
1141 /** Allocate and return a string containing the home directory for the
1142 * user <b>username</b>. Only works on posix-like systems. */
1143 char *
1144 get_user_homedir(const char *username)
1146 struct passwd *pw;
1147 tor_assert(username);
1149 if (!(pw = getpwnam(username))) {
1150 log_err(LD_CONFIG,"User \"%s\" not found.", username);
1151 return NULL;
1153 return tor_strdup(pw->pw_dir);
1155 #endif
1157 /** Set *addr to the IP address (in dotted-quad notation) stored in c.
1158 * Return 1 on success, 0 if c is badly formatted. (Like inet_aton(c,addr),
1159 * but works on Windows and Solaris.)
1162 tor_inet_aton(const char *c, struct in_addr* addr)
1164 #ifdef HAVE_INET_ATON
1165 return inet_aton(c, addr);
1166 #else
1167 uint32_t r;
1168 tor_assert(c);
1169 tor_assert(addr);
1170 if (strcmp(c, "255.255.255.255") == 0) {
1171 addr->s_addr = 0xFFFFFFFFu;
1172 return 1;
1174 r = inet_addr(c);
1175 if (r == INADDR_NONE)
1176 return 0;
1177 addr->s_addr = r;
1178 return 1;
1179 #endif
1182 /** Given <b>af</b>==AF_INET and <b>src</b> a struct in_addr, or
1183 * <b>af</b>==AF_INET6 and <b>src</b> a struct in6_addr, try to format the
1184 * address and store it in the <b>len</b>-byte buffer <b>dst</b>. Returns
1185 * <b>dst</b> on success, NULL on failure.
1187 * (Like inet_ntop(af,src,dst,len), but works on platforms that don't have it:
1188 * Tor sometimes needs to format ipv6 addresses even on platforms without ipv6
1189 * support.) */
1190 const char *
1191 tor_inet_ntop(int af, const void *src, char *dst, size_t len)
1193 if (af == AF_INET) {
1194 if (tor_inet_ntoa(src, dst, len) < 0)
1195 return NULL;
1196 else
1197 return dst;
1198 } else if (af == AF_INET6) {
1199 const struct in6_addr *addr = src;
1200 char buf[64], *cp;
1201 int longestGapLen = 0, longestGapPos = -1, i,
1202 curGapPos = -1, curGapLen = 0;
1203 uint16_t words[8];
1204 for (i = 0; i < 8; ++i) {
1205 words[i] = (((uint16_t)addr->s6_addr[2*i])<<8) + addr->s6_addr[2*i+1];
1207 if (words[0] == 0 && words[1] == 0 && words[2] == 0 && words[3] == 0 &&
1208 words[4] == 0 && ((words[5] == 0 && words[6] && words[7]) ||
1209 (words[5] == 0xffff))) {
1210 /* This is an IPv4 address. */
1211 if (words[5] == 0) {
1212 tor_snprintf(buf, sizeof(buf), "::%d.%d.%d.%d",
1213 addr->s6_addr[12], addr->s6_addr[13],
1214 addr->s6_addr[14], addr->s6_addr[15]);
1215 } else {
1216 tor_snprintf(buf, sizeof(buf), "::%x:%d.%d.%d.%d", words[5],
1217 addr->s6_addr[12], addr->s6_addr[13],
1218 addr->s6_addr[14], addr->s6_addr[15]);
1220 if (strlen(buf) > len)
1221 return NULL;
1222 strlcpy(dst, buf, len);
1223 return dst;
1225 i = 0;
1226 while (i < 8) {
1227 if (words[i] == 0) {
1228 curGapPos = i++;
1229 curGapLen = 1;
1230 while (i<8 && words[i] == 0) {
1231 ++i; ++curGapLen;
1233 if (curGapLen > longestGapLen) {
1234 longestGapPos = curGapPos;
1235 longestGapLen = curGapLen;
1237 } else {
1238 ++i;
1241 if (longestGapLen<=1)
1242 longestGapPos = -1;
1244 cp = buf;
1245 for (i = 0; i < 8; ++i) {
1246 if (words[i] == 0 && longestGapPos == i) {
1247 if (i == 0)
1248 *cp++ = ':';
1249 *cp++ = ':';
1250 while (i < 8 && words[i] == 0)
1251 ++i;
1252 --i; /* to compensate for loop increment. */
1253 } else {
1254 tor_snprintf(cp, sizeof(buf)-(cp-buf), "%x", (unsigned)words[i]);
1255 cp += strlen(cp);
1256 if (i != 7)
1257 *cp++ = ':';
1260 *cp = '\0';
1261 if (strlen(buf) > len)
1262 return NULL;
1263 strlcpy(dst, buf, len);
1264 return dst;
1265 } else {
1266 return NULL;
1270 /** Given <b>af</b>==AF_INET or <b>af</b>==AF_INET6, and a string <b>src</b>
1271 * encoding an IPv4 address or IPv6 address correspondingly, try to parse the
1272 * address and store the result in <b>dst</b> (which must have space for a
1273 * struct in_addr or a struct in6_addr, as appropriate). Return 1 on success,
1274 * 0 on a bad parse, and -1 on a bad <b>af</b>.
1276 * (Like inet_pton(af,src,dst) but works on platforms that don't have it: Tor
1277 * sometimes needs to format ipv6 addresses even on platforms without ipv6
1278 * support.) */
1280 tor_inet_pton(int af, const char *src, void *dst)
1282 if (af == AF_INET) {
1283 return tor_inet_aton(src, dst);
1284 } else if (af == AF_INET6) {
1285 struct in6_addr *out = dst;
1286 uint16_t words[8];
1287 int gapPos = -1, i, setWords=0;
1288 const char *dot = strchr(src, '.');
1289 const char *eow; /* end of words. */
1290 if (dot == src)
1291 return 0;
1292 else if (!dot)
1293 eow = src+strlen(src);
1294 else {
1295 int byte1,byte2,byte3,byte4;
1296 char more;
1297 for (eow = dot-1; eow >= src && TOR_ISDIGIT(*eow); --eow)
1299 ++eow;
1301 /* We use "scanf" because some platform inet_aton()s are too lax
1302 * about IPv4 addresses of the form "1.2.3" */
1303 if (sscanf(eow, "%d.%d.%d.%d%c", &byte1,&byte2,&byte3,&byte4,&more) != 4)
1304 return 0;
1306 if (byte1 > 255 || byte1 < 0 ||
1307 byte2 > 255 || byte2 < 0 ||
1308 byte3 > 255 || byte3 < 0 ||
1309 byte4 > 255 || byte4 < 0)
1310 return 0;
1312 words[6] = (byte1<<8) | byte2;
1313 words[7] = (byte3<<8) | byte4;
1314 setWords += 2;
1317 i = 0;
1318 while (src < eow) {
1319 if (i > 7)
1320 return 0;
1321 if (TOR_ISXDIGIT(*src)) {
1322 char *next;
1323 long r = strtol(src, &next, 16);
1324 if (next > 4+src)
1325 return 0;
1326 if (next == src)
1327 return 0;
1328 if (r<0 || r>65536)
1329 return 0;
1331 words[i++] = (uint16_t)r;
1332 setWords++;
1333 src = next;
1334 if (*src != ':' && src != eow)
1335 return 0;
1336 ++src;
1337 } else if (*src == ':' && i > 0 && gapPos==-1) {
1338 gapPos = i;
1339 ++src;
1340 } else if (*src == ':' && i == 0 && src[1] == ':' && gapPos==-1) {
1341 gapPos = i;
1342 src += 2;
1343 } else {
1344 return 0;
1348 if (setWords > 8 ||
1349 (setWords == 8 && gapPos != -1) ||
1350 (setWords < 8 && gapPos == -1))
1351 return 0;
1353 if (gapPos >= 0) {
1354 int nToMove = setWords - (dot ? 2 : 0) - gapPos;
1355 int gapLen = 8 - setWords;
1356 tor_assert(nToMove >= 0);
1357 memmove(&words[gapPos+gapLen], &words[gapPos],
1358 sizeof(uint16_t)*nToMove);
1359 memset(&words[gapPos], 0, sizeof(uint16_t)*gapLen);
1361 for (i = 0; i < 8; ++i) {
1362 out->s6_addr[2*i ] = words[i] >> 8;
1363 out->s6_addr[2*i+1] = words[i] & 0xff;
1366 return 1;
1367 } else {
1368 return -1;
1372 /** Similar behavior to Unix gethostbyname: resolve <b>name</b>, and set
1373 * *<b>addr</b> to the proper IP address, in host byte order. Returns 0
1374 * on success, -1 on failure; 1 on transient failure.
1376 * (This function exists because standard windows gethostbyname
1377 * doesn't treat raw IP addresses properly.)
1380 tor_lookup_hostname(const char *name, uint32_t *addr)
1382 tor_addr_t myaddr;
1383 int ret;
1385 if ((ret = tor_addr_lookup(name, AF_INET, &myaddr)))
1386 return ret;
1388 if (tor_addr_family(&myaddr) == AF_INET) {
1389 *addr = tor_addr_to_ipv4h(&myaddr);
1390 return ret;
1393 return -1;
1396 /** Hold the result of our call to <b>uname</b>. */
1397 static char uname_result[256];
1398 /** True iff uname_result is set. */
1399 static int uname_result_is_set = 0;
1401 /** Return a pointer to a description of our platform.
1403 const char *
1404 get_uname(void)
1406 #ifdef HAVE_UNAME
1407 struct utsname u;
1408 #endif
1409 if (!uname_result_is_set) {
1410 #ifdef HAVE_UNAME
1411 if (uname(&u) != -1) {
1412 /* (linux says 0 is success, solaris says 1 is success) */
1413 tor_snprintf(uname_result, sizeof(uname_result), "%s %s",
1414 u.sysname, u.machine);
1415 } else
1416 #endif
1418 #ifdef MS_WINDOWS
1419 OSVERSIONINFOEX info;
1420 int i;
1421 unsigned int leftover_mask;
1422 const char *plat = NULL;
1423 const char *extra = NULL;
1424 static struct {
1425 unsigned major; unsigned minor; const char *version;
1426 } win_version_table[] = {
1427 { 6, 0, "Windows \"Longhorn\"" },
1428 { 5, 2, "Windows Server 2003" },
1429 { 5, 1, "Windows XP" },
1430 { 5, 0, "Windows 2000" },
1431 /* { 4, 0, "Windows NT 4.0" }, */
1432 { 4, 90, "Windows Me" },
1433 { 4, 10, "Windows 98" },
1434 /* { 4, 0, "Windows 95" } */
1435 { 3, 51, "Windows NT 3.51" },
1436 { 0, 0, NULL }
1438 #ifdef VER_SUITE_BACKOFFICE
1439 static struct {
1440 unsigned int mask; const char *str;
1441 } win_mask_table[] = {
1442 { VER_SUITE_BACKOFFICE, " {backoffice}" },
1443 { VER_SUITE_BLADE, " {\"blade\" (2003, web edition)}" },
1444 { VER_SUITE_DATACENTER, " {datacenter}" },
1445 { VER_SUITE_ENTERPRISE, " {enterprise}" },
1446 { VER_SUITE_EMBEDDEDNT, " {embedded}" },
1447 { VER_SUITE_PERSONAL, " {personal}" },
1448 { VER_SUITE_SINGLEUSERTS,
1449 " {terminal services, single user}" },
1450 { VER_SUITE_SMALLBUSINESS, " {small business}" },
1451 { VER_SUITE_SMALLBUSINESS_RESTRICTED,
1452 " {small business, restricted}" },
1453 { VER_SUITE_TERMINAL, " {terminal services}" },
1454 { 0, NULL },
1456 #endif
1457 memset(&info, 0, sizeof(info));
1458 info.dwOSVersionInfoSize = sizeof(info);
1459 if (! GetVersionEx((LPOSVERSIONINFO)&info)) {
1460 strlcpy(uname_result, "Bizarre version of Windows where GetVersionEx"
1461 " doesn't work.", sizeof(uname_result));
1462 uname_result_is_set = 1;
1463 return uname_result;
1465 if (info.dwMajorVersion == 4 && info.dwMinorVersion == 0) {
1466 if (info.dwPlatformId == VER_PLATFORM_WIN32_NT)
1467 plat = "Windows NT 4.0";
1468 else
1469 plat = "Windows 95";
1470 if (info.szCSDVersion[1] == 'B')
1471 extra = "OSR2 (B)";
1472 else if (info.szCSDVersion[1] == 'C')
1473 extra = "OSR2 (C)";
1474 } else {
1475 for (i=0; win_version_table[i].major>0; ++i) {
1476 if (win_version_table[i].major == info.dwMajorVersion &&
1477 win_version_table[i].minor == info.dwMinorVersion) {
1478 plat = win_version_table[i].version;
1479 break;
1483 if (plat && !strcmp(plat, "Windows 98")) {
1484 if (info.szCSDVersion[1] == 'A')
1485 extra = "SE (A)";
1486 else if (info.szCSDVersion[1] == 'B')
1487 extra = "SE (B)";
1489 if (plat) {
1490 if (!extra)
1491 extra = info.szCSDVersion;
1492 tor_snprintf(uname_result, sizeof(uname_result), "%s %s",
1493 plat, extra);
1494 } else {
1495 if (info.dwMajorVersion > 6 ||
1496 (info.dwMajorVersion==6 && info.dwMinorVersion>0))
1497 tor_snprintf(uname_result, sizeof(uname_result),
1498 "Very recent version of Windows [major=%d,minor=%d] %s",
1499 (int)info.dwMajorVersion,(int)info.dwMinorVersion,
1500 info.szCSDVersion);
1501 else
1502 tor_snprintf(uname_result, sizeof(uname_result),
1503 "Unrecognized version of Windows [major=%d,minor=%d] %s",
1504 (int)info.dwMajorVersion,(int)info.dwMinorVersion,
1505 info.szCSDVersion);
1507 #ifdef VER_SUITE_BACKOFFICE
1508 if (info.wProductType == VER_NT_DOMAIN_CONTROLLER) {
1509 strlcat(uname_result, " [domain controller]", sizeof(uname_result));
1510 } else if (info.wProductType == VER_NT_SERVER) {
1511 strlcat(uname_result, " [server]", sizeof(uname_result));
1512 } else if (info.wProductType == VER_NT_WORKSTATION) {
1513 strlcat(uname_result, " [workstation]", sizeof(uname_result));
1515 leftover_mask = info.wSuiteMask;
1516 for (i = 0; win_mask_table[i].mask; ++i) {
1517 if (info.wSuiteMask & win_mask_table[i].mask) {
1518 strlcat(uname_result, win_mask_table[i].str, sizeof(uname_result));
1519 leftover_mask &= ~win_mask_table[i].mask;
1522 if (leftover_mask) {
1523 size_t len = strlen(uname_result);
1524 tor_snprintf(uname_result+len, sizeof(uname_result)-len,
1525 " {0x%x}", info.wSuiteMask);
1527 #endif
1528 #else
1529 strlcpy(uname_result, "Unknown platform", sizeof(uname_result));
1530 #endif
1532 uname_result_is_set = 1;
1534 return uname_result;
1538 * Process control
1541 #if defined(USE_PTHREADS)
1542 /** Wraps a void (*)(void*) function and its argument so we can
1543 * invoke them in a way pthreads would expect.
1545 typedef struct tor_pthread_data_t {
1546 void (*func)(void *);
1547 void *data;
1548 } tor_pthread_data_t;
1549 /** Given a tor_pthread_data_t <b>_data</b>, call _data-&gt;func(d-&gt;data)
1550 * and free _data. Used to make sure we can call functions the way pthread
1551 * expects. */
1552 static void *
1553 tor_pthread_helper_fn(void *_data)
1555 tor_pthread_data_t *data = _data;
1556 void (*func)(void*);
1557 void *arg;
1558 /* mask signals to worker threads to avoid SIGPIPE, etc */
1559 sigset_t sigs;
1560 /* We're in a subthread; don't handle any signals here. */
1561 sigfillset(&sigs);
1562 pthread_sigmask(SIG_SETMASK, &sigs, NULL);
1564 func = data->func;
1565 arg = data->data;
1566 tor_free(_data);
1567 func(arg);
1568 return NULL;
1570 #endif
1572 /** Minimalist interface to run a void function in the background. On
1573 * unix calls fork, on win32 calls beginthread. Returns -1 on failure.
1574 * func should not return, but rather should call spawn_exit.
1576 * NOTE: if <b>data</b> is used, it should not be allocated on the stack,
1577 * since in a multithreaded environment, there is no way to be sure that
1578 * the caller's stack will still be around when the called function is
1579 * running.
1582 spawn_func(void (*func)(void *), void *data)
1584 #if defined(USE_WIN32_THREADS)
1585 int rv;
1586 rv = (int)_beginthread(func, 0, data);
1587 if (rv == (int)-1)
1588 return -1;
1589 return 0;
1590 #elif defined(USE_PTHREADS)
1591 pthread_t thread;
1592 tor_pthread_data_t *d;
1593 d = tor_malloc(sizeof(tor_pthread_data_t));
1594 d->data = data;
1595 d->func = func;
1596 if (pthread_create(&thread,NULL,tor_pthread_helper_fn,d))
1597 return -1;
1598 if (pthread_detach(thread))
1599 return -1;
1600 return 0;
1601 #else
1602 pid_t pid;
1603 pid = fork();
1604 if (pid<0)
1605 return -1;
1606 if (pid==0) {
1607 /* Child */
1608 func(data);
1609 tor_assert(0); /* Should never reach here. */
1610 return 0; /* suppress "control-reaches-end-of-non-void" warning. */
1611 } else {
1612 /* Parent */
1613 return 0;
1615 #endif
1618 /** End the current thread/process.
1620 void
1621 spawn_exit(void)
1623 #if defined(USE_WIN32_THREADS)
1624 _endthread();
1625 //we should never get here. my compiler thinks that _endthread returns, this
1626 //is an attempt to fool it.
1627 tor_assert(0);
1628 _exit(0);
1629 #elif defined(USE_PTHREADS)
1630 pthread_exit(NULL);
1631 #else
1632 /* http://www.erlenstar.demon.co.uk/unix/faq_2.html says we should
1633 * call _exit, not exit, from child processes. */
1634 _exit(0);
1635 #endif
1639 /** Set *timeval to the current time of day. On error, log and terminate.
1640 * (Same as gettimeofday(timeval,NULL), but never returns -1.)
1642 void
1643 tor_gettimeofday(struct timeval *timeval)
1645 #ifdef MS_WINDOWS
1646 /* Epoch bias copied from perl: number of units between windows epoch and
1647 * unix epoch. */
1648 #define EPOCH_BIAS U64_LITERAL(116444736000000000)
1649 #define UNITS_PER_SEC U64_LITERAL(10000000)
1650 #define USEC_PER_SEC U64_LITERAL(1000000)
1651 #define UNITS_PER_USEC U64_LITERAL(10)
1652 union {
1653 uint64_t ft_64;
1654 FILETIME ft_ft;
1655 } ft;
1656 /* number of 100-nsec units since Jan 1, 1601 */
1657 GetSystemTimeAsFileTime(&ft.ft_ft);
1658 if (ft.ft_64 < EPOCH_BIAS) {
1659 log_err(LD_GENERAL,"System time is before 1970; failing.");
1660 exit(1);
1662 ft.ft_64 -= EPOCH_BIAS;
1663 timeval->tv_sec = (unsigned) (ft.ft_64 / UNITS_PER_SEC);
1664 timeval->tv_usec = (unsigned) ((ft.ft_64 / UNITS_PER_USEC) % USEC_PER_SEC);
1665 #elif defined(HAVE_GETTIMEOFDAY)
1666 if (gettimeofday(timeval, NULL)) {
1667 log_err(LD_GENERAL,"gettimeofday failed.");
1668 /* If gettimeofday dies, we have either given a bad timezone (we didn't),
1669 or segfaulted.*/
1670 exit(1);
1672 #elif defined(HAVE_FTIME)
1673 struct timeb tb;
1674 ftime(&tb);
1675 timeval->tv_sec = tb.time;
1676 timeval->tv_usec = tb.millitm * 1000;
1677 #else
1678 #error "No way to get time."
1679 #endif
1680 return;
1683 #if defined(TOR_IS_MULTITHREADED) && !defined(MS_WINDOWS)
1684 /** Defined iff we need to add locks when defining fake versions of reentrant
1685 * versions of time-related functions. */
1686 #define TIME_FNS_NEED_LOCKS
1687 #endif
1689 #ifndef HAVE_LOCALTIME_R
1690 #ifdef TIME_FNS_NEED_LOCKS
1691 struct tm *
1692 tor_localtime_r(const time_t *timep, struct tm *result)
1694 struct tm *r;
1695 static tor_mutex_t *m=NULL;
1696 if (!m) { m=tor_mutex_new(); }
1697 tor_assert(result);
1698 tor_mutex_acquire(m);
1699 r = localtime(timep);
1700 memcpy(result, r, sizeof(struct tm));
1701 tor_mutex_release(m);
1702 return result;
1704 #else
1705 struct tm *
1706 tor_localtime_r(const time_t *timep, struct tm *result)
1708 struct tm *r;
1709 tor_assert(result);
1710 r = localtime(timep);
1711 memcpy(result, r, sizeof(struct tm));
1712 return result;
1714 #endif
1715 #endif
1717 #ifndef HAVE_GMTIME_R
1718 #ifdef TIME_FNS_NEED_LOCKS
1719 struct tm *
1720 tor_gmtime_r(const time_t *timep, struct tm *result)
1722 struct tm *r;
1723 static tor_mutex_t *m=NULL;
1724 if (!m) { m=tor_mutex_new(); }
1725 tor_assert(result);
1726 tor_mutex_acquire(m);
1727 r = gmtime(timep);
1728 memcpy(result, r, sizeof(struct tm));
1729 tor_mutex_release(m);
1730 return result;
1732 #else
1733 struct tm *
1734 tor_gmtime_r(const time_t *timep, struct tm *result)
1736 struct tm *r;
1737 tor_assert(result);
1738 r = gmtime(timep);
1739 memcpy(result, r, sizeof(struct tm));
1740 return result;
1742 #endif
1743 #endif
1745 #if defined(USE_WIN32_THREADS)
1746 void
1747 tor_mutex_init(tor_mutex_t *m)
1749 InitializeCriticalSection(&m->mutex);
1751 void
1752 tor_mutex_uninit(tor_mutex_t *m)
1754 DeleteCriticalSection(&m->mutex);
1756 void
1757 tor_mutex_acquire(tor_mutex_t *m)
1759 tor_assert(m);
1760 EnterCriticalSection(&m->mutex);
1762 void
1763 tor_mutex_release(tor_mutex_t *m)
1765 LeaveCriticalSection(&m->mutex);
1767 unsigned long
1768 tor_get_thread_id(void)
1770 return (unsigned long)GetCurrentThreadId();
1772 #elif defined(USE_PTHREADS)
1773 static pthread_mutexattr_t attr_reentrant;
1774 static int threads_initialized = 0;
1775 void
1776 tor_mutex_init(tor_mutex_t *mutex)
1778 int err;
1779 if (PREDICT_UNLIKELY(!threads_initialized))
1780 tor_threads_init();
1781 err = pthread_mutex_init(&mutex->mutex, &attr_reentrant);
1782 if (PREDICT_UNLIKELY(err)) {
1783 log_err(LD_GENERAL, "Error %d creating a mutex.", err);
1784 tor_fragile_assert();
1787 /** Wait until <b>m</b> is free, then acquire it. */
1788 void
1789 tor_mutex_acquire(tor_mutex_t *m)
1791 int err;
1792 tor_assert(m);
1793 err = pthread_mutex_lock(&m->mutex);
1794 if (PREDICT_UNLIKELY(err)) {
1795 log_err(LD_GENERAL, "Error %d locking a mutex.", err);
1796 tor_fragile_assert();
1799 /** Release the lock <b>m</b> so another thread can have it. */
1800 void
1801 tor_mutex_release(tor_mutex_t *m)
1803 int err;
1804 tor_assert(m);
1805 err = pthread_mutex_unlock(&m->mutex);
1806 if (PREDICT_UNLIKELY(err)) {
1807 log_err(LD_GENERAL, "Error %d unlocking a mutex.", err);
1808 tor_fragile_assert();
1811 void
1812 tor_mutex_uninit(tor_mutex_t *m)
1814 int err;
1815 tor_assert(m);
1816 err = pthread_mutex_destroy(&m->mutex);
1817 if (PREDICT_UNLIKELY(err)) {
1818 log_err(LD_GENERAL, "Error %d destroying a mutex.", err);
1819 tor_fragile_assert();
1822 /** Return an integer representing this thread. */
1823 unsigned long
1824 tor_get_thread_id(void)
1826 union {
1827 pthread_t thr;
1828 unsigned long id;
1829 } r;
1830 r.thr = pthread_self();
1831 return r.id;
1833 #endif
1835 #ifdef TOR_IS_MULTITHREADED
1836 tor_mutex_t *
1837 tor_mutex_new(void)
1839 tor_mutex_t *m = tor_malloc_zero(sizeof(tor_mutex_t));
1840 tor_mutex_init(m);
1841 return m;
1843 void
1844 tor_mutex_free(tor_mutex_t *m)
1846 tor_mutex_uninit(m);
1847 tor_free(m);
1849 #endif
1851 /* Conditions. */
1852 #ifdef USE_PTHREADS
1853 #if 0
1854 /** Cross-platform condition implementation. */
1855 struct tor_cond_t {
1856 pthread_cond_t cond;
1858 /** Return a newly allocated condition, with nobody waiting on it. */
1859 tor_cond_t *
1860 tor_cond_new(void)
1862 tor_cond_t *cond = tor_malloc_zero(sizeof(tor_cond_t));
1863 if (pthread_cond_init(&cond->cond, NULL)) {
1864 tor_free(cond);
1865 return NULL;
1867 return cond;
1869 /** Release all resources held by <b>cond</b>. */
1870 void
1871 tor_cond_free(tor_cond_t *cond)
1873 tor_assert(cond);
1874 if (pthread_cond_destroy(&cond->cond)) {
1875 log_warn(LD_GENERAL,"Error freeing condition: %s", strerror(errno));
1876 return;
1878 tor_free(cond);
1880 /** Wait until one of the tor_cond_signal functions is called on <b>cond</b>.
1881 * All waiters on the condition must wait holding the same <b>mutex</b>.
1882 * Returns 0 on success, negative on failure. */
1884 tor_cond_wait(tor_cond_t *cond, tor_mutex_t *mutex)
1886 return pthread_cond_wait(&cond->cond, &mutex->mutex) ? -1 : 0;
1888 /** Wake up one of the waiters on <b>cond</b>. */
1889 void
1890 tor_cond_signal_one(tor_cond_t *cond)
1892 pthread_cond_signal(&cond->cond);
1894 /** Wake up all of the waiters on <b>cond</b>. */
1895 void
1896 tor_cond_signal_all(tor_cond_t *cond)
1898 pthread_cond_broadcast(&cond->cond);
1900 #endif
1901 /** Set up common structures for use by threading. */
1902 void
1903 tor_threads_init(void)
1905 if (!threads_initialized) {
1906 pthread_mutexattr_init(&attr_reentrant);
1907 pthread_mutexattr_settype(&attr_reentrant, PTHREAD_MUTEX_RECURSIVE);
1908 threads_initialized = 1;
1911 #elif defined(USE_WIN32_THREADS)
1912 #if 0
1913 static DWORD cond_event_tls_index;
1914 struct tor_cond_t {
1915 CRITICAL_SECTION mutex;
1916 smartlist_t *events;
1918 tor_cond_t *
1919 tor_cond_new(void)
1921 tor_cond_t *cond = tor_malloc_zero(sizeof(tor_cond_t));
1922 InitializeCriticalSection(&cond->mutex);
1923 cond->events = smartlist_create();
1924 return cond;
1926 void
1927 tor_cond_free(tor_cond_t *cond)
1929 tor_assert(cond);
1930 DeleteCriticalSection(&cond->mutex);
1931 /* XXXX notify? */
1932 smartlist_free(cond->events);
1933 tor_free(cond);
1936 tor_cond_wait(tor_cond_t *cond, tor_mutex_t *mutex)
1938 HANDLE event;
1939 int r;
1940 tor_assert(cond);
1941 tor_assert(mutex);
1942 event = TlsGetValue(cond_event_tls_index);
1943 if (!event) {
1944 event = CreateEvent(0, FALSE, FALSE, NULL);
1945 TlsSetValue(cond_event_tls_index, event);
1947 EnterCriticalSection(&cond->mutex);
1949 tor_assert(WaitForSingleObject(event, 0) == WAIT_TIMEOUT);
1950 tor_assert(!smartlist_isin(cond->events, event));
1951 smartlist_add(cond->events, event);
1953 LeaveCriticalSection(&cond->mutex);
1955 tor_mutex_release(mutex);
1956 r = WaitForSingleObject(event, INFINITE);
1957 tor_mutex_acquire(mutex);
1959 switch (r) {
1960 case WAIT_OBJECT_0: /* we got the mutex normally. */
1961 break;
1962 case WAIT_ABANDONED: /* holding thread exited. */
1963 case WAIT_TIMEOUT: /* Should never happen. */
1964 tor_assert(0);
1965 break;
1966 case WAIT_FAILED:
1967 log_warn(LD_GENERAL, "Failed to acquire mutex: %d",(int) GetLastError());
1969 return 0;
1971 void
1972 tor_cond_signal_one(tor_cond_t *cond)
1974 HANDLE event;
1975 tor_assert(cond);
1977 EnterCriticalSection(&cond->mutex);
1979 if ((event = smartlist_pop_last(cond->events)))
1980 SetEvent(event);
1982 LeaveCriticalSection(&cond->mutex);
1984 void
1985 tor_cond_signal_all(tor_cond_t *cond)
1987 tor_assert(cond);
1989 EnterCriticalSection(&cond->mutex);
1990 SMARTLIST_FOREACH(cond->events, HANDLE, event, SetEvent(event));
1991 smartlist_clear(cond->events);
1992 LeaveCriticalSection(&cond->mutex);
1994 #endif
1995 void
1996 tor_threads_init(void)
1998 #if 0
1999 cond_event_tls_index = TlsAlloc();
2000 #endif
2002 #endif
2005 * On Windows, WSAEWOULDBLOCK is not always correct: when you see it,
2006 * you need to ask the socket for its actual errno. Also, you need to
2007 * get your errors from WSAGetLastError, not errno. (If you supply a
2008 * socket of -1, we check WSAGetLastError, but don't correct
2009 * WSAEWOULDBLOCKs.)
2011 * The upshot of all of this is that when a socket call fails, you
2012 * should call tor_socket_errno <em>at most once</em> on the failing
2013 * socket to get the error.
2015 #if defined(MS_WINDOWS) && !defined(USE_BSOCKETS)
2017 tor_socket_errno(int sock)
2019 int optval, optvallen=sizeof(optval);
2020 int err = WSAGetLastError();
2021 if (err == WSAEWOULDBLOCK && sock >= 0) {
2022 if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (void*)&optval, &optvallen))
2023 return err;
2024 if (optval)
2025 return optval;
2027 return err;
2029 #endif
2031 #if defined(MS_WINDOWS) && !defined(USE_BSOCKETS)
2032 #define E(code, s) { code, (s " [" #code " ]") }
2033 struct { int code; const char *msg; } windows_socket_errors[] = {
2034 E(WSAEINTR, "Interrupted function call"),
2035 E(WSAEACCES, "Permission denied"),
2036 E(WSAEFAULT, "Bad address"),
2037 E(WSAEINVAL, "Invalid argument"),
2038 E(WSAEMFILE, "Too many open files"),
2039 E(WSAEWOULDBLOCK, "Resource temporarily unavailable"),
2040 E(WSAEINPROGRESS, "Operation now in progress"),
2041 E(WSAEALREADY, "Operation already in progress"),
2042 E(WSAENOTSOCK, "Socket operation on nonsocket"),
2043 E(WSAEDESTADDRREQ, "Destination address required"),
2044 E(WSAEMSGSIZE, "Message too long"),
2045 E(WSAEPROTOTYPE, "Protocol wrong for socket"),
2046 E(WSAENOPROTOOPT, "Bad protocol option"),
2047 E(WSAEPROTONOSUPPORT, "Protocol not supported"),
2048 E(WSAESOCKTNOSUPPORT, "Socket type not supported"),
2049 /* What's the difference between NOTSUPP and NOSUPPORT? :) */
2050 E(WSAEOPNOTSUPP, "Operation not supported"),
2051 E(WSAEPFNOSUPPORT, "Protocol family not supported"),
2052 E(WSAEAFNOSUPPORT, "Address family not supported by protocol family"),
2053 E(WSAEADDRINUSE, "Address already in use"),
2054 E(WSAEADDRNOTAVAIL, "Cannot assign requested address"),
2055 E(WSAENETDOWN, "Network is down"),
2056 E(WSAENETUNREACH, "Network is unreachable"),
2057 E(WSAENETRESET, "Network dropped connection on reset"),
2058 E(WSAECONNABORTED, "Software caused connection abort"),
2059 E(WSAECONNRESET, "Connection reset by peer"),
2060 E(WSAENOBUFS, "No buffer space available"),
2061 E(WSAEISCONN, "Socket is already connected"),
2062 E(WSAENOTCONN, "Socket is not connected"),
2063 E(WSAESHUTDOWN, "Cannot send after socket shutdown"),
2064 E(WSAETIMEDOUT, "Connection timed out"),
2065 E(WSAECONNREFUSED, "Connection refused"),
2066 E(WSAEHOSTDOWN, "Host is down"),
2067 E(WSAEHOSTUNREACH, "No route to host"),
2068 E(WSAEPROCLIM, "Too many processes"),
2069 /* Yes, some of these start with WSA, not WSAE. No, I don't know why. */
2070 E(WSASYSNOTREADY, "Network subsystem is unavailable"),
2071 E(WSAVERNOTSUPPORTED, "Winsock.dll out of range"),
2072 E(WSANOTINITIALISED, "Successful WSAStartup not yet performed"),
2073 E(WSAEDISCON, "Graceful shutdown now in progress"),
2074 #ifdef WSATYPE_NOT_FOUND
2075 E(WSATYPE_NOT_FOUND, "Class type not found"),
2076 #endif
2077 E(WSAHOST_NOT_FOUND, "Host not found"),
2078 E(WSATRY_AGAIN, "Nonauthoritative host not found"),
2079 E(WSANO_RECOVERY, "This is a nonrecoverable error"),
2080 E(WSANO_DATA, "Valid name, no data record of requested type)"),
2082 /* There are some more error codes whose numeric values are marked
2083 * <b>OS dependent</b>. They start with WSA_, apparently for the same
2084 * reason that practitioners of some craft traditions deliberately
2085 * introduce imperfections into their baskets and rugs "to allow the
2086 * evil spirits to escape." If we catch them, then our binaries
2087 * might not report consistent results across versions of Windows.
2088 * Thus, I'm going to let them all fall through.
2090 { -1, NULL },
2092 /** There does not seem to be a strerror equivalent for winsock errors.
2093 * Naturally, we have to roll our own.
2095 const char *
2096 tor_socket_strerror(int e)
2098 int i;
2099 for (i=0; windows_socket_errors[i].code >= 0; ++i) {
2100 if (e == windows_socket_errors[i].code)
2101 return windows_socket_errors[i].msg;
2103 return strerror(e);
2105 #endif
2107 /** Called before we make any calls to network-related functions.
2108 * (Some operating systems require their network libraries to be
2109 * initialized.) */
2111 network_init(void)
2113 #ifdef MS_WINDOWS
2114 /* This silly exercise is necessary before windows will allow
2115 * gethostbyname to work. */
2116 WSADATA WSAData;
2117 int r;
2118 r = WSAStartup(0x101,&WSAData);
2119 if (r) {
2120 log_warn(LD_NET,"Error initializing windows network layer: code was %d",r);
2121 return -1;
2123 /* WSAData.iMaxSockets might show the max sockets we're allowed to use.
2124 * We might use it to complain if we're trying to be a server but have
2125 * too few sockets available. */
2126 #endif
2127 return 0;
2130 #ifdef MS_WINDOWS
2131 /** Return a newly allocated string describing the windows system error code
2132 * <b>err</b>. Note that error codes are different from errno. Error codes
2133 * come from GetLastError() when a winapi call fails. errno is set only when
2134 * ansi functions fail. Whee. */
2135 char *
2136 format_win32_error(DWORD err)
2138 LPVOID str = NULL;
2139 char *result;
2141 /* Somebody once decided that this interface was better than strerror(). */
2142 FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER |
2143 FORMAT_MESSAGE_FROM_SYSTEM |
2144 FORMAT_MESSAGE_IGNORE_INSERTS,
2145 NULL, err,
2146 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
2147 (LPTSTR) &str,
2148 0, NULL);
2150 if (str) {
2151 result = tor_strdup((char*)str);
2152 LocalFree(str); /* LocalFree != free() */
2153 } else {
2154 result = tor_strdup("<unformattable error>");
2156 return result;
2158 #endif