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 */
6 const char compat_c_id
[] =
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
18 /* This is required on rh7 to make strptime not complain.
19 * We also need it to make memmem get defined (where available)
28 #include <sys/locking.h>
32 #include <sys/utsname.h>
37 #ifdef HAVE_SYS_FCNTL_H
38 #include <sys/fcntl.h>
52 #ifdef HAVE_ARPA_INET_H
53 #include <arpa/inet.h>
56 #ifndef HAVE_GETTIMEOFDAY
58 #include <sys/timeb.h>
65 #ifdef HAVE_SYS_PARAM_H
66 #include <sys/param.h> /* FreeBSD needs this to know what version it is */
77 #ifdef HAVE_SYS_UTIME_H
78 #include <sys/utime.h>
80 #ifdef HAVE_SYS_MMAN_H
83 #ifdef HAVE_SYS_SYSLIMITS_H
84 #include <sys/syslimits.h>
86 #ifdef HAVE_SYS_FILE_H
96 #include "container.h"
99 /* Inline the strl functions if the platform doesn't have them. */
108 /* This is used by inet_addr, but apparently Solaris doesn't define it
110 #define INADDR_NONE ((unsigned long) -1)
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
{
118 size_t mapping_size
; /**< Size of the actual mapping. (This is this file
119 * size, rounded up to the nearest page.) */
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
126 tor_mmap_file(const char *filename
)
128 int fd
; /* router file */
131 tor_mmap_impl_t
*res
;
132 size_t size
, filesize
;
134 tor_assert(filename
);
136 fd
= open(filename
, O_RDONLY
, 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
,
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;
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
);
161 string
= mmap(0, size
, PROT_READ
, MAP_PRIVATE
, fd
, 0);
163 if (string
== MAP_FAILED
) {
164 int save_errno
= errno
;
165 log_warn(LD_FS
,"Could not mmap file \"%s\": %s", filename
,
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
;
178 /** Release storage held for a memory mapping. */
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
);
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
{
195 tor_mmap_file(const char *filename
)
197 win_mmap_t
*res
= tor_malloc_zero(sizeof(win_mmap_t
));
199 res
->file_handle
= INVALID_HANDLE_VALUE
;
200 res
->mmap_handle
= NULL
;
202 res
->file_handle
= CreateFile(filename
,
203 GENERIC_READ
, FILE_SHARE_READ
,
206 FILE_ATTRIBUTE_NORMAL
,
209 if (res
->file_handle
== INVALID_HANDLE_VALUE
)
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
);
220 res
->mmap_handle
= CreateFileMapping(res
->file_handle
,
223 #if SIZEOF_SIZE_T > 4
224 (res
->base
.size
>> 32),
228 (res
->base
.size
& 0xfffffffful
),
230 if (res
->mmap_handle
== NULL
)
232 res
->base
.data
= (char*) MapViewOfFile(res
->mmap_handle
,
240 DWORD e
= GetLastError();
241 int severity
= (e
== ERROR_FILE_NOT_FOUND
|| e
== ERROR_PATH_NOT_FOUND
) ?
243 char *msg
= format_win32_error(e
);
244 log_fn(severity
, LD_FS
, "Couldn't mmap file \"%s\": %s", filename
, msg
);
246 if (e
== ERROR_FILE_NOT_FOUND
|| e
== ERROR_PATH_NOT_FOUND
)
254 tor_munmap_file(&res
->base
);
258 tor_munmap_file(tor_mmap_t
*handle
)
260 win_mmap_t
*h
= SUBTYPE_P(handle
, win_mmap_t
, base
);
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
);
274 tor_mmap_file(const char *filename
)
277 char *res
= read_file_to_str(filename
, RFTS_BIN
|RFTS_IGNORE_MISSING
, &st
);
281 handle
= tor_malloc_zero(sizeof(tor_mmap_t
));
283 handle
->size
= st
.st_size
;
287 tor_munmap_file(tor_mmap_t
*handle
)
289 char *d
= (char*)handle
->data
;
291 memset(handle
, 0, sizeof(tor_mmap_t
));
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
, ...)
309 r
= tor_vsnprintf(str
,size
,format
,ap
);
314 /** Replacement for vsnprintf; behavior differs as tor_snprintf differs from
318 tor_vsnprintf(char *str
, size_t size
, const char *format
, va_list args
)
322 return -1; /* no place for the NUL */
323 if (size
> SIZE_T_CEILING
)
326 r
= _vsnprintf(str
, size
, format
, args
);
328 r
= vsnprintf(str
, size
, format
, args
);
331 if (r
< 0 || ((size_t)r
) >= size
)
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.
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)
348 return memmem(_haystack
, hlen
, _needle
, nlen
);
350 /* This isn't as fast as the GLIBC implementation, but it doesn't need to
353 const char *haystack
= (const char*)_haystack
;
354 const char *needle
= (const char*)_needle
;
359 end
= haystack
+ hlen
;
360 first
= *(const char*)needle
;
361 while ((p
= memchr(p
, first
, end
-p
))) {
364 if (!memcmp(p
, needle
, nlen
))
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.
380 tor_fix_source_file(const char *fname
)
382 const char *cp1
, *cp2
, *r
;
383 cp1
= strrchr(fname
, '/');
384 cp2
= strrchr(fname
, '\\');
386 r
= (cp1
<cp2
)?(cp2
+1):(cp1
+1);
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.
404 get_uint16(const char *cp
)
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.
416 get_uint32(const char *cp
)
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. */
427 set_uint16(char *cp
, uint16_t v
)
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. */
436 set_uint32(char *cp
, uint32_t v
)
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
445 * Returns 0 on success. Returns -1 and sets errno on failure.
448 replace_file(const char *from
, const char *to
)
451 return rename(from
,to
);
453 switch (file_status(to
))
458 if (unlink(to
)) return -1;
466 return rename(from
,to
);
470 /** Change <b>fname</b>'s modification time to now. */
472 touch_file(const char *fname
)
474 if (utime(fname
, NULL
)!=0)
479 struct tor_lockfile_t
{
484 /** DOCDOC. What's this function do? */
486 tor_lockfile_lock(const char *filename
, int blocking
, int *locked_out
)
488 tor_lockfile_t
*result
;
492 log_info(LD_FS
, "Locking \"%s\"", filename
);
493 fd
= open(filename
, O_RDWR
|O_CREAT
|O_TRUNC
, 0600);
495 log_warn(LD_FS
,"Couldn't open \"%s\" for locking: %s", filename
,
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
));
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
));
520 result
= tor_malloc(sizeof(tor_lockfile_t
));
521 result
->filename
= tor_strdup(filename
);
527 tor_lockfile_unlock(tor_lockfile_t
*lockfile
)
529 tor_assert(lockfile
);
531 log_info(LD_FS
, "Unlocking \"%s\"", lockfile
->filename
);
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
,
539 if (flock(lockfile
->fd
, LOCK_UN
) < 0) {
540 log_warn(LD_FS
, "Error unlocking \"%s\": %s", lockfile
->filename
,
547 tor_free(lockfile
->filename
);
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;
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
568 tor_close_socket(int s
)
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
);
576 tor_assert(open_sockets
&& s
<= max_socket
);
577 bitarray_clear(open_sockets
, s
);
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
588 #elif defined(MS_WINDOWS)
596 int err
= tor_socket_errno(-1);
597 log_info(LD_NET
, "Close returned an error: %s", tor_socket_strerror(err
));
599 if (err
!= WSAENOTSOCK
)
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
);
613 #ifdef DEBUG_SOCKET_COUNTING
614 /** Helper: if DEBUG_SOCKET_COUNTING is enabled, remember that <b>s</b> is
615 * now an open socket. */
617 mark_socket_open(int s
)
619 if (s
> max_socket
) {
620 if (max_socket
== -1) {
621 open_sockets
= bitarray_init_zero(s
+128);
624 open_sockets
= bitarray_expand(open_sockets
, 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
);
635 #define mark_socket_open(s) STMT_NIL
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
);
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
);
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.
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
);
678 fcntl(socket
, F_SETFL
, O_NONBLOCK
);
683 * Allocate a pair of connected sockets. (Like socketpair(family,
684 * type,protocol,fd), but works on systems that don't have
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)
705 r
= socketpair(family
, type
, protocol
, fd
);
709 mark_socket_open(fd
[0]);
713 mark_socket_open(fd
[1]);
716 return r
< 0 ? -errno
: r
;
717 #elif defined(USE_BSOCKETS)
718 return bsocketpair(family
, type
, protocol
, fd
);
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.
728 struct sockaddr_in listen_addr
;
729 struct sockaddr_in connect_addr
;
731 int saved_errno
= -1;
739 return -WSAEAFNOSUPPORT
;
741 return -EAFNOSUPPORT
;
748 listener
= tor_open_socket(AF_INET
, type
, 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
))
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);
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
);
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
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
;
797 abort_tidy_up_and_fail
:
799 saved_errno
= WSAECONNABORTED
;
801 saved_errno
= ECONNABORTED
; /* I hope this is portable and appropriate. */
807 tor_close_socket(listener
);
809 tor_close_socket(connector
);
811 tor_close_socket(acceptor
);
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;
845 const char *platform
= "unknown platforms with no getrlimit()";
846 const unsigned long MAX_CONNECTIONS
= 15000;
848 log_fn(LOG_INFO
, LD_NET
,
849 "This platform is missing getrlimit(). Proceeding.");
850 if (limit
> MAX_CONNECTIONS
) {
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
);
857 limit
= MAX_CONNECTIONS
;
858 #else /* HAVE_GETRLIMIT */
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",
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
);
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) {
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
);
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
);
901 #endif /* OPEN_MAX */
903 log_warn(LD_CONFIG
,"Couldn't set maximum number of file descriptors: %s",
908 /* leave some overhead for logs, etc, */
909 limit
= rlim
.rlim_cur
;
910 #endif /* HAVE_GETRLIMIT */
912 if (limit
< ULIMIT_BUFFER
) {
914 "ConnLimit must be at least %d. Failing.", ULIMIT_BUFFER
);
920 *max_out
= (int)limit
- ULIMIT_BUFFER
;
924 /** Log details of current user and group credentials. Return 0 on
925 * success. Logs and return -1 on failure.
928 log_credential_status(void)
930 #define CREDENTIAL_LOG_LEVEL LOG_INFO
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 */
942 #ifdef HAVE_GETRESUID
943 if (getresuid(&ruid
, &euid
, &suid
) != 0 ) {
944 log_warn(LD_GENERAL
, "Error getting changed UIDs: %s", strerror(errno
));
947 log_fn(CREDENTIAL_LOG_LEVEL
, LD_GENERAL
,
948 "UID is %u (real), %u (effective), %u (saved)", ruid
, euid
, suid
);
951 /* getresuid is not present on MacOS X, so we can't get the saved (E)UID */
956 log_fn(CREDENTIAL_LOG_LEVEL
, LD_GENERAL
,
957 "UID is %u (real), %u (effective), unknown (saved)", ruid
, euid
);
961 #ifdef HAVE_GETRESGID
962 if (getresgid(&rgid
, &egid
, &sgid
) != 0 ) {
963 log_warn(LD_GENERAL
, "Error getting changed GIDs: %s", strerror(errno
));
966 log_fn(CREDENTIAL_LOG_LEVEL
, LD_GENERAL
,
967 "GID is %u (real), %u (effective), %u (saved)", rgid
, egid
, sgid
);
970 /* getresgid is not present on MacOS X, so we can't get the saved (E)GID */
974 log_fn(CREDENTIAL_LOG_LEVEL
, LD_GENERAL
,
975 "GID is %u (real), %u (effective), unknown (saved)", rgid
, egid
);
978 /* log supplementary groups */
979 if ((ngids
= getgroups(NGROUPS_MAX
+ 1, sup_gids
)) < 0) {
980 log_warn(LD_GENERAL
, "Error getting supplementary GIDs: %s",
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;
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
);
1006 SMARTLIST_FOREACH(elts
, char *, cp
,
1010 smartlist_free(elts
);
1012 if (formatting_error
)
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
)
1027 struct passwd
*pw
= NULL
;
1030 static int have_already_switched_id
= 0;
1034 if (have_already_switched_id
)
1037 /* Log the initial credential state */
1038 if (log_credential_status())
1041 log_fn(CREDENTIAL_LOG_LEVEL
, LD_GENERAL
, "Changing user and groups");
1043 /* Get old UID/GID to check if we changed correctly */
1047 /* Lookup the user and group information, if we have a problem, bail out. */
1048 pw
= getpwnam(user
);
1050 log_warn(LD_CONFIG
, "Error setting configured user: %s not found", user
);
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
));
1062 if (setegid(pw
->pw_gid
)) {
1063 log_warn(LD_GENERAL
, "Error setting egid to %d: %s",
1064 (int)pw
->pw_gid
, strerror(errno
));
1068 if (setgid(pw
->pw_gid
)) {
1069 log_warn(LD_GENERAL
, "Error setting gid to %d: %s",
1070 (int)pw
->pw_gid
, strerror(errno
));
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
));
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
));
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",
1096 /* We've properly switched egid, gid, euid, uid, and supplementary groups if
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 */
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.");
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.");
1123 /* Check what really happened */
1124 if (log_credential_status()) {
1128 have_already_switched_id
= 1; /* mark success so we never try again */
1135 "User specified but switching users is unsupported on your OS.");
1141 /** Allocate and return a string containing the home directory for the
1142 * user <b>username</b>. Only works on posix-like systems. */
1144 get_user_homedir(const char *username
)
1147 tor_assert(username
);
1149 if (!(pw
= getpwnam(username
))) {
1150 log_err(LD_CONFIG
,"User \"%s\" not found.", username
);
1153 return tor_strdup(pw
->pw_dir
);
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
);
1170 if (strcmp(c
, "255.255.255.255") == 0) {
1171 addr
->s_addr
= 0xFFFFFFFFu
;
1175 if (r
== INADDR_NONE
)
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
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)
1198 } else if (af
== AF_INET6
) {
1199 const struct in6_addr
*addr
= src
;
1201 int longestGapLen
= 0, longestGapPos
= -1, i
,
1202 curGapPos
= -1, curGapLen
= 0;
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]);
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
)
1222 strlcpy(dst
, buf
, len
);
1227 if (words
[i
] == 0) {
1230 while (i
<8 && words
[i
] == 0) {
1233 if (curGapLen
> longestGapLen
) {
1234 longestGapPos
= curGapPos
;
1235 longestGapLen
= curGapLen
;
1241 if (longestGapLen
<=1)
1245 for (i
= 0; i
< 8; ++i
) {
1246 if (words
[i
] == 0 && longestGapPos
== i
) {
1250 while (i
< 8 && words
[i
] == 0)
1252 --i
; /* to compensate for loop increment. */
1254 tor_snprintf(cp
, sizeof(buf
)-(cp
-buf
), "%x", (unsigned)words
[i
]);
1261 if (strlen(buf
) > len
)
1263 strlcpy(dst
, buf
, len
);
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
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
;
1287 int gapPos
= -1, i
, setWords
=0;
1288 const char *dot
= strchr(src
, '.');
1289 const char *eow
; /* end of words. */
1293 eow
= src
+strlen(src
);
1295 int byte1
,byte2
,byte3
,byte4
;
1297 for (eow
= dot
-1; eow
>= src
&& TOR_ISDIGIT(*eow
); --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)
1306 if (byte1
> 255 || byte1
< 0 ||
1307 byte2
> 255 || byte2
< 0 ||
1308 byte3
> 255 || byte3
< 0 ||
1309 byte4
> 255 || byte4
< 0)
1312 words
[6] = (byte1
<<8) | byte2
;
1313 words
[7] = (byte3
<<8) | byte4
;
1321 if (TOR_ISXDIGIT(*src
)) {
1323 long r
= strtol(src
, &next
, 16);
1331 words
[i
++] = (uint16_t)r
;
1334 if (*src
!= ':' && src
!= eow
)
1337 } else if (*src
== ':' && i
> 0 && gapPos
==-1) {
1340 } else if (*src
== ':' && i
== 0 && src
[1] == ':' && gapPos
==-1) {
1349 (setWords
== 8 && gapPos
!= -1) ||
1350 (setWords
< 8 && gapPos
== -1))
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;
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
)
1385 if ((ret
= tor_addr_lookup(name
, AF_INET
, &myaddr
)))
1388 if (tor_addr_family(&myaddr
) == AF_INET
) {
1389 *addr
= tor_addr_to_ipv4h(&myaddr
);
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.
1409 if (!uname_result_is_set
) {
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
);
1419 OSVERSIONINFOEX info
;
1421 unsigned int leftover_mask
;
1422 const char *plat
= NULL
;
1423 const char *extra
= NULL
;
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" },
1438 #ifdef VER_SUITE_BACKOFFICE
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}" },
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";
1469 plat
= "Windows 95";
1470 if (info
.szCSDVersion
[1] == 'B')
1472 else if (info
.szCSDVersion
[1] == 'C')
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
;
1483 if (plat
&& !strcmp(plat
, "Windows 98")) {
1484 if (info
.szCSDVersion
[1] == 'A')
1486 else if (info
.szCSDVersion
[1] == 'B')
1491 extra
= info
.szCSDVersion
;
1492 tor_snprintf(uname_result
, sizeof(uname_result
), "%s %s",
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
,
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
,
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
);
1529 strlcpy(uname_result
, "Unknown platform", sizeof(uname_result
));
1532 uname_result_is_set
= 1;
1534 return uname_result
;
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 *);
1548 } tor_pthread_data_t
;
1549 /** Given a tor_pthread_data_t <b>_data</b>, call _data->func(d->data)
1550 * and free _data. Used to make sure we can call functions the way pthread
1553 tor_pthread_helper_fn(void *_data
)
1555 tor_pthread_data_t
*data
= _data
;
1556 void (*func
)(void*);
1558 /* mask signals to worker threads to avoid SIGPIPE, etc */
1560 /* We're in a subthread; don't handle any signals here. */
1562 pthread_sigmask(SIG_SETMASK
, &sigs
, NULL
);
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
1582 spawn_func(void (*func
)(void *), void *data
)
1584 #if defined(USE_WIN32_THREADS)
1586 rv
= (int)_beginthread(func
, 0, data
);
1590 #elif defined(USE_PTHREADS)
1592 tor_pthread_data_t
*d
;
1593 d
= tor_malloc(sizeof(tor_pthread_data_t
));
1596 if (pthread_create(&thread
,NULL
,tor_pthread_helper_fn
,d
))
1598 if (pthread_detach(thread
))
1609 tor_assert(0); /* Should never reach here. */
1610 return 0; /* suppress "control-reaches-end-of-non-void" warning. */
1618 /** End the current thread/process.
1623 #if defined(USE_WIN32_THREADS)
1625 //we should never get here. my compiler thinks that _endthread returns, this
1626 //is an attempt to fool it.
1629 #elif defined(USE_PTHREADS)
1632 /* http://www.erlenstar.demon.co.uk/unix/faq_2.html says we should
1633 * call _exit, not exit, from child processes. */
1639 /** Set *timeval to the current time of day. On error, log and terminate.
1640 * (Same as gettimeofday(timeval,NULL), but never returns -1.)
1643 tor_gettimeofday(struct timeval
*timeval
)
1646 /* Epoch bias copied from perl: number of units between windows epoch and
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)
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.");
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),
1672 #elif defined(HAVE_FTIME)
1675 timeval
->tv_sec
= tb
.time
;
1676 timeval
->tv_usec
= tb
.millitm
* 1000;
1678 #error "No way to get time."
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
1689 #ifndef HAVE_LOCALTIME_R
1690 #ifdef TIME_FNS_NEED_LOCKS
1692 tor_localtime_r(const time_t *timep
, struct tm
*result
)
1695 static tor_mutex_t
*m
=NULL
;
1696 if (!m
) { m
=tor_mutex_new(); }
1698 tor_mutex_acquire(m
);
1699 r
= localtime(timep
);
1700 memcpy(result
, r
, sizeof(struct tm
));
1701 tor_mutex_release(m
);
1706 tor_localtime_r(const time_t *timep
, struct tm
*result
)
1710 r
= localtime(timep
);
1711 memcpy(result
, r
, sizeof(struct tm
));
1717 #ifndef HAVE_GMTIME_R
1718 #ifdef TIME_FNS_NEED_LOCKS
1720 tor_gmtime_r(const time_t *timep
, struct tm
*result
)
1723 static tor_mutex_t
*m
=NULL
;
1724 if (!m
) { m
=tor_mutex_new(); }
1726 tor_mutex_acquire(m
);
1728 memcpy(result
, r
, sizeof(struct tm
));
1729 tor_mutex_release(m
);
1734 tor_gmtime_r(const time_t *timep
, struct tm
*result
)
1739 memcpy(result
, r
, sizeof(struct tm
));
1745 #if defined(USE_WIN32_THREADS)
1747 tor_mutex_init(tor_mutex_t
*m
)
1749 InitializeCriticalSection(&m
->mutex
);
1752 tor_mutex_uninit(tor_mutex_t
*m
)
1754 DeleteCriticalSection(&m
->mutex
);
1757 tor_mutex_acquire(tor_mutex_t
*m
)
1760 EnterCriticalSection(&m
->mutex
);
1763 tor_mutex_release(tor_mutex_t
*m
)
1765 LeaveCriticalSection(&m
->mutex
);
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;
1776 tor_mutex_init(tor_mutex_t
*mutex
)
1779 if (PREDICT_UNLIKELY(!threads_initialized
))
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. */
1789 tor_mutex_acquire(tor_mutex_t
*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. */
1801 tor_mutex_release(tor_mutex_t
*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();
1812 tor_mutex_uninit(tor_mutex_t
*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. */
1824 tor_get_thread_id(void)
1830 r
.thr
= pthread_self();
1835 #ifdef TOR_IS_MULTITHREADED
1839 tor_mutex_t
*m
= tor_malloc_zero(sizeof(tor_mutex_t
));
1844 tor_mutex_free(tor_mutex_t
*m
)
1846 tor_mutex_uninit(m
);
1854 /** Cross-platform condition implementation. */
1856 pthread_cond_t cond
;
1858 /** Return a newly allocated condition, with nobody waiting on it. */
1862 tor_cond_t
*cond
= tor_malloc_zero(sizeof(tor_cond_t
));
1863 if (pthread_cond_init(&cond
->cond
, NULL
)) {
1869 /** Release all resources held by <b>cond</b>. */
1871 tor_cond_free(tor_cond_t
*cond
)
1874 if (pthread_cond_destroy(&cond
->cond
)) {
1875 log_warn(LD_GENERAL
,"Error freeing condition: %s", strerror(errno
));
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>. */
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>. */
1896 tor_cond_signal_all(tor_cond_t
*cond
)
1898 pthread_cond_broadcast(&cond
->cond
);
1901 /** Set up common structures for use by threading. */
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)
1913 static DWORD cond_event_tls_index
;
1915 CRITICAL_SECTION mutex
;
1916 smartlist_t
*events
;
1921 tor_cond_t
*cond
= tor_malloc_zero(sizeof(tor_cond_t
));
1922 InitializeCriticalSection(&cond
->mutex
);
1923 cond
->events
= smartlist_create();
1927 tor_cond_free(tor_cond_t
*cond
)
1930 DeleteCriticalSection(&cond
->mutex
);
1932 smartlist_free(cond
->events
);
1936 tor_cond_wait(tor_cond_t
*cond
, tor_mutex_t
*mutex
)
1942 event
= TlsGetValue(cond_event_tls_index
);
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
);
1960 case WAIT_OBJECT_0
: /* we got the mutex normally. */
1962 case WAIT_ABANDONED
: /* holding thread exited. */
1963 case WAIT_TIMEOUT
: /* Should never happen. */
1967 log_warn(LD_GENERAL
, "Failed to acquire mutex: %d",(int) GetLastError());
1972 tor_cond_signal_one(tor_cond_t
*cond
)
1977 EnterCriticalSection(&cond
->mutex
);
1979 if ((event
= smartlist_pop_last(cond
->events
)))
1982 LeaveCriticalSection(&cond
->mutex
);
1985 tor_cond_signal_all(tor_cond_t
*cond
)
1989 EnterCriticalSection(&cond
->mutex
);
1990 SMARTLIST_FOREACH(cond
->events
, HANDLE
, event
, SetEvent(event
));
1991 smartlist_clear(cond
->events
);
1992 LeaveCriticalSection(&cond
->mutex
);
1996 tor_threads_init(void)
1999 cond_event_tls_index
= TlsAlloc();
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
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
))
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"),
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.
2092 /** There does not seem to be a strerror equivalent for winsock errors.
2093 * Naturally, we have to roll our own.
2096 tor_socket_strerror(int e
)
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
;
2107 /** Called before we make any calls to network-related functions.
2108 * (Some operating systems require their network libraries to be
2114 /* This silly exercise is necessary before windows will allow
2115 * gethostbyname to work. */
2118 r
= WSAStartup(0x101,&WSAData
);
2120 log_warn(LD_NET
,"Error initializing windows network layer: code was %d",r
);
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. */
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. */
2136 format_win32_error(DWORD err
)
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
,
2146 MAKELANGID(LANG_NEUTRAL
, SUBLANG_DEFAULT
),
2151 result
= tor_strdup((char*)str
);
2152 LocalFree(str
); /* LocalFree != free() */
2154 result
= tor_strdup("<unformattable error>");