1 /* Copyright 2003-2004 Roger Dingledine
2 * Copyright 2004-2007 Roger Dingledine, Nick Mathewson */
3 /* See LICENSE for licensing information */
5 const char compat_c_id
[] =
10 * \brief Wrappers to make calls more portable. This code defines
11 * functions such as tor_malloc, tor_snprintf, get/set various data types,
12 * renaming, setting socket options, switching user IDs. It is basically
13 * where the non-portable items are conditionally included depending on
17 /* This is required on rh7 to make strptime not complain.
18 * We also need it to make memmem get defined (where available)
31 #include <sys/utsname.h>
33 #ifdef HAVE_SYS_TIME_H
39 #ifdef HAVE_SYS_FCNTL_H
40 #include <sys/fcntl.h>
51 #ifdef HAVE_SYS_RESOURCE_H
52 #include <sys/resource.h>
57 #ifdef HAVE_NETINET_IN_H
58 #include <netinet/in.h>
60 #ifdef HAVE_ARPA_INET_H
61 #include <arpa/inet.h>
63 #ifndef HAVE_GETTIMEOFDAY
65 #include <sys/timeb.h>
68 #ifdef HAVE_SYS_SOCKET_H
69 #include <sys/socket.h>
74 #ifdef HAVE_SYS_PARAM_H
75 #include <sys/param.h> /* FreeBSD needs this to know what version it is */
91 #ifdef HAVE_SYS_UTIME_H
92 #include <sys/utime.h>
94 #ifdef HAVE_SYS_MMAN_H
105 /* Inline the strl functions if the platform doesn't have them. */
114 /* This is used by inet_addr, but apparently Solaris doesn't define it
116 #define INADDR_NONE ((unsigned long) -1)
119 #ifdef HAVE_SYS_MMAN_H
120 /** Implementation for tor_mmap_t: holds the regular tor_mmap_t, along
121 * with extra fields needed for mmap()-based memory mapping. */
122 typedef struct tor_mmap_impl_t
{
124 size_t mapping_size
; /**< Size of the actual mapping. (This is this file
125 * size, rounded up to the nearest page.) */
127 /** Try to create a memory mapping for <b>filename</b> and return it. On
128 * failure, return NULL. */
130 tor_mmap_file(const char *filename
)
132 int fd
; /* router file */
135 tor_mmap_impl_t
*res
;
136 size_t size
, filesize
;
138 tor_assert(filename
);
140 fd
= open(filename
, O_RDONLY
, 0);
142 int severity
= (errno
== ENOENT
) ? LOG_INFO
: LOG_WARN
;
143 log_fn(severity
, LD_FS
,"Could not open \"%s\" for mmap(): %s",filename
,
148 size
= filesize
= (size_t) lseek(fd
, 0, SEEK_END
);
149 lseek(fd
, 0, SEEK_SET
);
150 /* ensure page alignment */
151 page_size
= getpagesize();
152 size
+= (size
%page_size
) ? page_size
-(size
%page_size
) : 0;
155 /* Zero-length file. If we call mmap on it, it will succeed but
156 * return NULL, and bad things will happen. So just fail. */
157 log_info(LD_FS
,"File \"%s\" is empty. Ignoring.",filename
);
161 string
= mmap(0, size
, PROT_READ
, MAP_PRIVATE
, fd
, 0);
162 if (string
== MAP_FAILED
) {
164 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
));
198 res
->file_handle
= INVALID_HANDLE_VALUE
;
199 res
->mmap_handle
= NULL
;
201 res
->file_handle
= CreateFile(filename
,
205 FILE_ATTRIBUTE_NORMAL
,
208 if (res
->file_handle
== INVALID_HANDLE_VALUE
)
211 res
->base
.size
= GetFileSize(res
->file_handle
, NULL
);
213 if (res
->base
.size
== 0) {
214 log_info(LD_FS
,"File \"%s\" is empty. Ignoring.",filename
);
218 res
->mmap_handle
= CreateFileMapping(res
->file_handle
,
221 #if SIZEOF_SIZE_T > 4
222 (res
->base
.size
>> 32),
226 (res
->base
.size
& 0xfffffffful
),
228 if (res
->mmap_handle
== NULL
)
230 res
->base
.data
= (char*) MapViewOfFile(res
->mmap_handle
,
238 DWORD e
= GetLastError();
239 int severity
= (e
== ERROR_FILE_NOT_FOUND
|| e
== ERROR_PATH_NOT_FOUND
) ?
241 char *msg
= format_win32_error(e
);
242 log_fn(severity
, LD_FS
, "Couldn't mmap file \"%s\": %s", filename
, msg
);
246 tor_munmap_file(&res
->base
);
250 tor_munmap_file(tor_mmap_t
*handle
)
252 win_mmap_t
*h
= SUBTYPE_P(handle
, win_mmap_t
, base
);
254 /* This is an ugly cast, but without it, "data" in struct tor_mmap_t would
255 have to be redefined as non-const. */
256 UnmapViewOfFile( (LPVOID
) handle
->data
);
258 if (h
->mmap_handle
!= NULL
)
259 CloseHandle(h
->mmap_handle
);
260 if (h
->file_handle
!= INVALID_HANDLE_VALUE
)
261 CloseHandle(h
->file_handle
);
266 tor_mmap_file(const char *filename
)
269 char *res
= read_file_to_str(filename
, RFTS_BIN
|RFTS_IGNORE_MISSING
, &st
);
273 handle
= tor_malloc_zero(sizeof(tor_mmap_t
));
275 handle
->size
= st
.st_size
;
279 tor_munmap_file(tor_mmap_t
*handle
)
281 char *d
= (char*)handle
->data
;
283 memset(handle
, 0, sizeof(tor_mmap_t
));
288 /** Replacement for snprintf. Differs from platform snprintf in two
289 * ways: First, always NUL-terminates its output. Second, always
290 * returns -1 if the result is truncated. (Note that this return
291 * behavior does <i>not</i> conform to C99; it just happens to be
292 * easier to emulate "return -1" with conformant implementations than
293 * it is to emulate "return number that would be written" with
294 * non-conformant implementations.) */
296 tor_snprintf(char *str
, size_t size
, const char *format
, ...)
301 r
= tor_vsnprintf(str
,size
,format
,ap
);
306 /** Replacement for vsnprintf; behavior differs as tor_snprintf differs from
310 tor_vsnprintf(char *str
, size_t size
, const char *format
, va_list args
)
314 return -1; /* no place for the NUL */
315 if (size
> SIZE_T_CEILING
)
318 r
= _vsnprintf(str
, size
, format
, args
);
320 r
= vsnprintf(str
, size
, format
, args
);
323 if (r
< 0 || ((size_t)r
) >= size
)
328 /** Given <b>hlen</b> bytes at <b>haystack</b> and <b>nlen</b> bytes at
329 * <b>needle</b>, return a pointer to the first occurrence of the needle
330 * within the haystack, or NULL if there is no such occurrence.
332 * Requires that nlen be greater than zero.
335 tor_memmem(const void *_haystack
, size_t hlen
,
336 const void *_needle
, size_t nlen
)
338 #if defined(HAVE_MEMMEM) && (!defined(__GNUC__) || __GNUC__ >= 2)
340 return memmem(_haystack
, hlen
, _needle
, nlen
);
342 /* This isn't as fast as the GLIBC implementation, but it doesn't need to
345 const char *haystack
= (const char*)_haystack
;
346 const char *needle
= (const char*)_needle
;
351 end
= haystack
+ hlen
;
352 first
= *(const char*)needle
;
353 while ((p
= memchr(p
, first
, end
-p
))) {
356 if (!memcmp(p
, needle
, nlen
))
365 /** Take a filename and return a pointer to its final element. This
366 * function is called on __FILE__ to fix a MSVC nit where __FILE__
367 * contains the full path to the file. This is bad, because it
368 * confuses users to find the home directory of the person who
369 * compiled the binary in their warrning messages.
372 tor_fix_source_file(const char *fname
)
374 const char *cp1
, *cp2
, *r
;
375 cp1
= strrchr(fname
, '/');
376 cp2
= strrchr(fname
, '\\');
378 r
= (cp1
<cp2
)?(cp2
+1):(cp1
+1);
391 * Read a 16-bit value beginning at <b>cp</b>. Equivalent to
392 * *(uint16_t*)(cp), but will not cause segfaults on platforms that forbid
393 * unaligned memory access.
396 get_uint16(const char *cp
)
403 * Read a 32-bit value beginning at <b>cp</b>. Equivalent to
404 * *(uint32_t*)(cp), but will not cause segfaults on platforms that forbid
405 * unaligned memory access.
408 get_uint32(const char *cp
)
415 * Set a 16-bit value beginning at <b>cp</b> to <b>v</b>. Equivalent to
416 * *(uint16_t)(cp) = v, but will not cause segfaults on platforms that forbid
417 * unaligned memory access. */
419 set_uint16(char *cp
, uint16_t v
)
424 * Set a 32-bit value beginning at <b>cp</b> to <b>v</b>. Equivalent to
425 * *(uint32_t)(cp) = v, but will not cause segfaults on platforms that forbid
426 * unaligned memory access. */
428 set_uint32(char *cp
, uint32_t v
)
434 * Rename the file <b>from</b> to the file <b>to</b>. On unix, this is
435 * the same as rename(2). On windows, this removes <b>to</b> first if
437 * Returns 0 on success. Returns -1 and sets errno on failure.
440 replace_file(const char *from
, const char *to
)
443 return rename(from
,to
);
445 switch (file_status(to
))
450 if (unlink(to
)) return -1;
458 return rename(from
,to
);
462 /** Change <b>fname</b>'s modification time to now. */
464 touch_file(const char *fname
)
466 if (utime(fname
, NULL
)!=0)
471 /** Turn <b>socket</b> into a nonblocking socket.
474 set_socket_nonblocking(int socket
)
476 #if defined(MS_WINDOWS) && !defined(USE_BSOCKETS)
477 unsigned long nonblocking
= 1;
478 ioctlsocket(socket
, FIONBIO
, (unsigned long*) &nonblocking
);
480 fcntl(socket
, F_SETFL
, O_NONBLOCK
);
485 * Allocate a pair of connected sockets. (Like socketpair(family,
486 * type,protocol,fd), but works on systems that don't have
489 * Currently, only (AF_UNIX, SOCK_STREAM, 0 ) sockets are supported.
491 * Note that on systems without socketpair, this call will fail if
492 * localhost is inaccessible (for example, if the networking
493 * stack is down). And even if it succeeds, the socket pair will not
494 * be able to read while localhost is down later (the socket pair may
495 * even close, depending on OS-specific timeouts).
497 * Returns 0 on success and -errno on failure; do not rely on the value
498 * of errno or WSAGetLastError().
500 /* It would be nicer just to set errno, but that won't work for windows. */
502 tor_socketpair(int family
, int type
, int protocol
, int fd
[2])
504 //don't use win32 socketpairs (they are always bad)
505 #if defined(HAVE_SOCKETPAIR) && !defined(MS_WINDOWS)
507 r
= socketpair(family
, type
, protocol
, fd
);
508 return r
< 0 ? -errno
: r
;
509 #elif defined(USE_BSOCKETS)
510 return bsockepair(family
, type
, protocol
, fd
);
512 /* This socketpair does not work when localhost is down. So
513 * it's really not the same thing at all. But it's close enough
514 * for now, and really, when localhost is down sometimes, we
515 * have other problems too.
520 struct sockaddr_in listen_addr
;
521 struct sockaddr_in connect_addr
;
523 int saved_errno
= -1;
531 return -WSAEAFNOSUPPORT
;
533 return -EAFNOSUPPORT
;
540 listener
= socket(AF_INET
, type
, 0);
542 return -tor_socket_errno(-1);
543 memset(&listen_addr
, 0, sizeof(listen_addr
));
544 listen_addr
.sin_family
= AF_INET
;
545 listen_addr
.sin_addr
.s_addr
= htonl(INADDR_LOOPBACK
);
546 listen_addr
.sin_port
= 0; /* kernel chooses port. */
547 if (bind(listener
, (struct sockaddr
*) &listen_addr
, sizeof (listen_addr
))
549 goto tidy_up_and_fail
;
550 if (listen(listener
, 1) == -1)
551 goto tidy_up_and_fail
;
553 connector
= socket(AF_INET
, type
, 0);
555 goto tidy_up_and_fail
;
556 /* We want to find out the port number to connect to. */
557 size
= sizeof(connect_addr
);
558 if (getsockname(listener
, (struct sockaddr
*) &connect_addr
, &size
) == -1)
559 goto tidy_up_and_fail
;
560 if (size
!= sizeof (connect_addr
))
561 goto abort_tidy_up_and_fail
;
562 if (connect(connector
, (struct sockaddr
*) &connect_addr
,
563 sizeof(connect_addr
)) == -1)
564 goto tidy_up_and_fail
;
566 size
= sizeof(listen_addr
);
567 acceptor
= accept(listener
, (struct sockaddr
*) &listen_addr
, &size
);
569 goto tidy_up_and_fail
;
570 if (size
!= sizeof(listen_addr
))
571 goto abort_tidy_up_and_fail
;
572 tor_close_socket(listener
);
573 /* Now check we are talking to ourself by matching port and host on the
575 if (getsockname(connector
, (struct sockaddr
*) &connect_addr
, &size
) == -1)
576 goto tidy_up_and_fail
;
577 if (size
!= sizeof (connect_addr
)
578 || listen_addr
.sin_family
!= connect_addr
.sin_family
579 || listen_addr
.sin_addr
.s_addr
!= connect_addr
.sin_addr
.s_addr
580 || listen_addr
.sin_port
!= connect_addr
.sin_port
) {
581 goto abort_tidy_up_and_fail
;
588 abort_tidy_up_and_fail
:
590 saved_errno
= WSAECONNABORTED
;
592 saved_errno
= ECONNABORTED
; /* I hope this is portable and appropriate. */
598 tor_close_socket(listener
);
600 tor_close_socket(connector
);
602 tor_close_socket(acceptor
);
607 #define ULIMIT_BUFFER 32 /* keep 32 extra fd's beyond _ConnLimit */
609 /** Learn the maximum allowed number of file descriptors. (Some systems
610 * have a low soft limit.
612 * We compute this by finding the largest number between <b>limit</b>
613 * and <b>cap</b> that we can use. If we can't find a number greater
614 * than or equal to <b>limit</b>, then we fail: return -1.
616 * Otherwise, return the number minus some buffer to allow for other
617 * file descriptors we'll want available for ordinary use. */
619 set_max_file_descriptors(unsigned long limit
, unsigned long cap
)
621 #ifndef HAVE_GETRLIMIT
622 log_fn(LOG_INFO
, LD_NET
,
623 "This platform is missing getrlimit(). Proceeding.");
625 log_info(LD_CONFIG
, "ConnLimit must be at most %d. Using that.", (int)cap
);
631 tor_assert(limit
> 0);
634 if (getrlimit(RLIMIT_NOFILE
, &rlim
) != 0) {
635 log_warn(LD_NET
, "Could not get maximum number of file descriptors: %s",
639 if (rlim
.rlim_max
< limit
) {
640 log_warn(LD_CONFIG
,"We need %lu file descriptors available, and we're "
641 "limited to %lu. Please change your ulimit -n.",
642 limit
, (unsigned long)rlim
.rlim_max
);
645 most
= (rlim
.rlim_max
> cap
) ? cap
: (unsigned) rlim
.rlim_max
;
646 if (most
> rlim
.rlim_cur
) {
647 log_info(LD_NET
,"Raising max file descriptors from %lu to %lu.",
648 (unsigned long)rlim
.rlim_cur
, most
);
650 rlim
.rlim_cur
= most
;
651 if (setrlimit(RLIMIT_NOFILE
, &rlim
) != 0) {
652 log_warn(LD_CONFIG
, "Could not set maximum number of file descriptors: %s",
656 /* leave some overhead for logs, etc, */
660 if (limit
< ULIMIT_BUFFER
) {
662 "ConnLimit must be at least %d. Failing.", ULIMIT_BUFFER
);
665 return limit
- ULIMIT_BUFFER
;
668 /** Call setuid and setgid to run as <b>user</b>:<b>group</b>. Return 0 on
669 * success. On failure, log and return -1.
672 switch_id(const char *user
, const char *group
)
675 struct passwd
*pw
= NULL
;
676 struct group
*gr
= NULL
;
681 log_warn(LD_CONFIG
,"User '%s' not found.", user
);
686 /* switch the group first, while we still have the privileges to do so */
688 gr
= getgrnam(group
);
690 log_warn(LD_CONFIG
,"Group '%s' not found.", group
);
694 if (setgid(gr
->gr_gid
) != 0) {
695 log_warn(LD_GENERAL
,"Error setting to configured GID: %s",
700 if (setgid(pw
->pw_gid
) != 0) {
701 log_warn(LD_GENERAL
,"Error setting to user GID: %s", strerror(errno
));
706 /* now that the group is switched, we can switch users and lose
709 if (setuid(pw
->pw_uid
) != 0) {
710 log_warn(LD_GENERAL
,"Error setting UID: %s", strerror(errno
));
722 "User or group specified, but switching users is not supported.");
727 /** Allocate and return a string containing the home directory for the
728 * user <b>username</b>. Only works on posix-like systems */
730 get_user_homedir(const char *username
)
733 tor_assert(username
);
735 if (!(pw
= getpwnam(username
))) {
736 log_err(LD_CONFIG
,"User \"%s\" not found.", username
);
739 return tor_strdup(pw
->pw_dir
);
743 /** Set *addr to the IP address (in dotted-quad notation) stored in c.
744 * Return 1 on success, 0 if c is badly formatted. (Like inet_aton(c,addr),
745 * but works on Windows and Solaris.)
748 tor_inet_aton(const char *c
, struct in_addr
* addr
)
750 #ifdef HAVE_INET_ATON
751 return inet_aton(c
, addr
);
756 if (strcmp(c
, "255.255.255.255") == 0) {
757 addr
->s_addr
= 0xFFFFFFFFu
;
761 if (r
== INADDR_NONE
)
768 /** Similar behavior to Unix gethostbyname: resolve <b>name</b>, and set
769 * *addr to the proper IP address, in network byte order. Returns 0
770 * on success, -1 on failure; 1 on transient failure.
772 * (This function exists because standard windows gethostbyname
773 * doesn't treat raw IP addresses properly.)
776 tor_lookup_hostname(const char *name
, uint32_t *addr
)
778 /* Perhaps eventually this should be replaced by a tor_getaddrinfo or
781 struct in_addr iaddr
;
785 /* Empty address is an error. */
787 } else if (tor_inet_aton(name
, &iaddr
)) {
789 memcpy(addr
, &iaddr
.s_addr
, 4);
792 #ifdef HAVE_GETADDRINFO
794 struct addrinfo
*res
=NULL
, *res_p
;
795 struct addrinfo hints
;
797 memset(&hints
, 0, sizeof(hints
));
798 hints
.ai_family
= PF_INET
;
799 hints
.ai_socktype
= SOCK_STREAM
;
800 err
= getaddrinfo(name
, NULL
, &hints
, &res
);
802 for (res_p
= res
; res_p
; res_p
= res_p
->ai_next
) {
803 if (res_p
->ai_family
== AF_INET
) {
804 struct sockaddr_in
*sin
= (struct sockaddr_in
*)res_p
->ai_addr
;
805 memcpy(addr
, &sin
->sin_addr
, 4);
813 return (err
== EAI_AGAIN
) ? 1 : -1;
817 #ifdef HAVE_GETHOSTBYNAME_R_6_ARG
819 struct hostent hostent
;
821 r
= gethostbyname_r(name
, &hostent
, buf
, sizeof(buf
), &ent
, &err
);
822 #elif defined(HAVE_GETHOSTBYNAME_R_5_ARG)
824 struct hostent hostent
;
825 ent
= gethostbyname_r(name
, &hostent
, buf
, sizeof(buf
), &err
);
826 #elif defined(HAVE_GETHOSTBYNAME_R_3_ARG)
827 struct hostent_data data
;
829 memset(&data
, 0, sizeof(data
));
830 err
= gethostbyname_r(name
, &hent
, &data
);
831 ent
= err
? NULL
: &hent
;
833 ent
= gethostbyname(name
);
835 err
= WSAGetLastError();
841 /* break to remind us if we move away from IPv4 */
842 tor_assert(ent
->h_length
== 4);
843 memcpy(addr
, ent
->h_addr
, 4);
848 return (err
== WSATRY_AGAIN
) ? 1 : -1;
850 return (err
== TRY_AGAIN
) ? 1 : -1;
856 /** Hold the result of our call to <b>uname</b>. */
857 static char uname_result
[256];
858 /** True iff uname_result is set. */
859 static int uname_result_is_set
= 0;
861 /** Return a pointer to a description of our platform.
869 if (!uname_result_is_set
) {
871 if (uname(&u
) != -1) {
872 /* (linux says 0 is success, solaris says 1 is success) */
873 tor_snprintf(uname_result
, sizeof(uname_result
), "%s %s",
874 u
.sysname
, u
.machine
);
879 OSVERSIONINFOEX info
;
881 unsigned int leftover_mask
;
882 const char *plat
= NULL
;
884 unsigned major
; unsigned minor
; const char *version
;
885 } win_version_table
[] = {
886 { 6, 0, "Windows \"Longhorn\"" },
887 { 5, 2, "Windows Server 2003" },
888 { 5, 1, "Windows XP" },
889 { 5, 0, "Windows 2000" },
890 /* { 4, 0, "Windows NT 4.0" }, */
891 { 4, 90, "Windows Me" },
892 { 4, 10, "Windows 98" },
893 /* { 4, 0, "Windows 95" } */
894 { 3, 51, "Windows NT 3.51" },
897 #ifdef VER_SUITE_BACKOFFICE
899 unsigned int mask
; const char *str
;
900 } win_mask_table
[] = {
901 { VER_SUITE_BACKOFFICE
, " {backoffice}" },
902 { VER_SUITE_BLADE
, " {\"blade\" (2003, web edition)}" },
903 { VER_SUITE_DATACENTER
, " {datacenter}" },
904 { VER_SUITE_ENTERPRISE
, " {enterprise}" },
905 { VER_SUITE_EMBEDDEDNT
, " {embedded}" },
906 { VER_SUITE_PERSONAL
, " {personal}" },
907 { VER_SUITE_SINGLEUSERTS
,
908 " {terminal services, single user}" },
909 { VER_SUITE_SMALLBUSINESS
, " {small business}" },
910 { VER_SUITE_SMALLBUSINESS_RESTRICTED
,
911 " {small business, restricted}" },
912 { VER_SUITE_TERMINAL
, " {terminal services}" },
916 memset(&info
, 0, sizeof(info
));
917 info
.dwOSVersionInfoSize
= sizeof(info
);
918 if (! GetVersionEx((LPOSVERSIONINFO
)&info
)) {
919 strlcpy(uname_result
, "Bizarre version of Windows where GetVersionEx"
920 " doesn't work.", sizeof(uname_result
));
921 uname_result_is_set
= 1;
924 if (info
.dwMajorVersion
== 4 && info
.dwMinorVersion
== 0) {
925 if (info
.dwPlatformId
== VER_PLATFORM_WIN32_NT
)
926 plat
= "Windows NT 4.0";
930 for (i
=0; win_version_table
[i
].major
>0; ++i
) {
931 if (win_version_table
[i
].major
== info
.dwMajorVersion
&&
932 win_version_table
[i
].minor
== info
.dwMinorVersion
) {
933 plat
= win_version_table
[i
].version
;
939 tor_snprintf(uname_result
, sizeof(uname_result
), "%s %s",
940 plat
, info
.szCSDVersion
);
942 if (info
.dwMajorVersion
> 6 ||
943 (info
.dwMajorVersion
==6 && info
.dwMinorVersion
>0))
944 tor_snprintf(uname_result
, sizeof(uname_result
),
945 "Very recent version of Windows [major=%d,minor=%d] %s",
946 (int)info
.dwMajorVersion
,(int)info
.dwMinorVersion
,
949 tor_snprintf(uname_result
, sizeof(uname_result
),
950 "Unrecognized version of Windows [major=%d,minor=%d] %s",
951 (int)info
.dwMajorVersion
,(int)info
.dwMinorVersion
,
954 #ifdef VER_SUITE_BACKOFFICE
955 if (info
.wProductType
== VER_NT_DOMAIN_CONTROLLER
) {
956 strlcat(uname_result
, " [domain controller]", sizeof(uname_result
));
957 } else if (info
.wProductType
== VER_NT_SERVER
) {
958 strlcat(uname_result
, " [server]", sizeof(uname_result
));
959 } else if (info
.wProductType
== VER_NT_WORKSTATION
) {
960 strlcat(uname_result
, " [workstation]", sizeof(uname_result
));
962 leftover_mask
= info
.wSuiteMask
;
963 for (i
= 0; win_mask_table
[i
].mask
; ++i
) {
964 if (info
.wSuiteMask
& win_mask_table
[i
].mask
) {
965 strlcat(uname_result
, win_mask_table
[i
].str
, sizeof(uname_result
));
966 leftover_mask
&= ~win_mask_table
[i
].mask
;
970 size_t len
= strlen(uname_result
);
971 tor_snprintf(uname_result
+len
, sizeof(uname_result
)-len
,
972 " {0x%x}", info
.wSuiteMask
);
976 strlcpy(uname_result
, "Unknown platform", sizeof(uname_result
));
979 uname_result_is_set
= 1;
988 #if defined(USE_PTHREADS)
989 /** Wraps a void (*)(void*) function and its argument so we can
990 * invoke them in a way pthreads would expect.
992 typedef struct tor_pthread_data_t
{
993 void (*func
)(void *);
995 } tor_pthread_data_t
;
996 /** Given a tor_pthread_data_t <b>_data</b>, call _data->func(d->data)
997 * and free _data. Used to make sure we can call functions the way pthread
1000 tor_pthread_helper_fn(void *_data
)
1002 tor_pthread_data_t
*data
= _data
;
1003 void (*func
)(void*);
1005 /* mask signals to worker threads to avoid SIGPIPE, etc */
1007 /* We're in a subthread; don't handle any signals here. */
1009 pthread_sigmask(SIG_SETMASK
, &sigs
, NULL
);
1019 /** Minimalist interface to run a void function in the background. On
1020 * unix calls fork, on win32 calls beginthread. Returns -1 on failure.
1021 * func should not return, but rather should call spawn_exit.
1023 * NOTE: if <b>data</b> is used, it should not be allocated on the stack,
1024 * since in a multithreaded environment, there is no way to be sure that
1025 * the caller's stack will still be around when the called function is
1029 spawn_func(void (*func
)(void *), void *data
)
1031 #if defined(USE_WIN32_THREADS)
1033 rv
= (int)_beginthread(func
, 0, data
);
1037 #elif defined(USE_PTHREADS)
1039 tor_pthread_data_t
*d
;
1040 d
= tor_malloc(sizeof(tor_pthread_data_t
));
1043 if (pthread_create(&thread
,NULL
,tor_pthread_helper_fn
,d
))
1045 if (pthread_detach(thread
))
1056 tor_assert(0); /* Should never reach here. */
1057 return 0; /* suppress "control-reaches-end-of-non-void" warning. */
1065 /** End the current thread/process.
1070 #if defined(USE_WIN32_THREADS)
1072 //we should never get here. my compiler thinks that _endthread returns, this
1073 //is an attempt to fool it.
1076 #elif defined(USE_PTHREADS)
1079 /* http://www.erlenstar.demon.co.uk/unix/faq_2.html says we should
1080 * call _exit, not exit, from child processes. */
1086 /** Set *timeval to the current time of day. On error, log and terminate.
1087 * (Same as gettimeofday(timeval,NULL), but never returns -1.)
1090 tor_gettimeofday(struct timeval
*timeval
)
1093 /* Epoch bias copied from perl: number of units between windows epoch and
1095 #define EPOCH_BIAS U64_LITERAL(116444736000000000)
1096 #define UNITS_PER_SEC U64_LITERAL(10000000)
1097 #define USEC_PER_SEC U64_LITERAL(1000000)
1098 #define UNITS_PER_USEC U64_LITERAL(10)
1103 /* number of 100-nsec units since Jan 1, 1601 */
1104 GetSystemTimeAsFileTime(&ft
.ft_ft
);
1105 if (ft
.ft_64
< EPOCH_BIAS
) {
1106 log_err(LD_GENERAL
,"System time is before 1970; failing.");
1109 ft
.ft_64
-= EPOCH_BIAS
;
1110 timeval
->tv_sec
= (unsigned) (ft
.ft_64
/ UNITS_PER_SEC
);
1111 timeval
->tv_usec
= (unsigned) ((ft
.ft_64
/ UNITS_PER_USEC
) % USEC_PER_SEC
);
1112 #elif defined(HAVE_GETTIMEOFDAY)
1113 if (gettimeofday(timeval
, NULL
)) {
1114 log_err(LD_GENERAL
,"gettimeofday failed.");
1115 /* If gettimeofday dies, we have either given a bad timezone (we didn't),
1119 #elif defined(HAVE_FTIME)
1122 timeval
->tv_sec
= tb
.time
;
1123 timeval
->tv_usec
= tb
.millitm
* 1000;
1125 #error "No way to get time."
1130 #if defined(TOR_IS_MULTITHREADED) && !defined(MS_WINDOWS)
1131 /** Defined iff we need to add locks when defining fake versions of reentrant
1132 * versions of time-related functions. */
1133 #define TIME_FNS_NEED_LOCKS
1136 #ifndef HAVE_LOCALTIME_R
1137 #ifdef TIME_FNS_NEED_LOCKS
1139 tor_localtime_r(const time_t *timep
, struct tm
*result
)
1142 static tor_mutex_t
*m
=NULL
;
1143 if (!m
) { m
=tor_mutex_new(); }
1145 tor_mutex_acquire(m
);
1146 r
= localtime(timep
);
1147 memcpy(result
, r
, sizeof(struct tm
));
1148 tor_mutex_release(m
);
1153 tor_localtime_r(const time_t *timep
, struct tm
*result
)
1157 r
= localtime(timep
);
1158 memcpy(result
, r
, sizeof(struct tm
));
1164 #ifndef HAVE_GMTIME_R
1165 #ifdef TIME_FNS_NEED_LOCKS
1167 tor_gmtime_r(const time_t *timep
, struct tm
*result
)
1170 static tor_mutex_t
*m
=NULL
;
1171 if (!m
) { m
=tor_mutex_new(); }
1173 tor_mutex_acquire(m
);
1175 memcpy(result
, r
, sizeof(struct tm
));
1176 tor_mutex_release(m
);
1181 tor_gmtime_r(const time_t *timep
, struct tm
*result
)
1186 memcpy(result
, r
, sizeof(struct tm
));
1192 #ifdef USE_WIN32_THREADS
1193 /** A generic lock structure for multithreaded builds. */
1194 struct tor_mutex_t
{
1201 m
= tor_malloc_zero(sizeof(tor_mutex_t
));
1202 m
->handle
= CreateMutex(NULL
, FALSE
, NULL
);
1203 tor_assert(m
->handle
!= NULL
);
1207 tor_mutex_free(tor_mutex_t
*m
)
1209 CloseHandle(m
->handle
);
1213 tor_mutex_acquire(tor_mutex_t
*m
)
1216 r
= WaitForSingleObject(m
->handle
, INFINITE
);
1218 case WAIT_ABANDONED
: /* holding thread exited. */
1219 case WAIT_OBJECT_0
: /* we got the mutex normally. */
1221 case WAIT_TIMEOUT
: /* Should never happen. */
1225 log_warn(LD_GENERAL
, "Failed to acquire mutex: %d",(int) GetLastError());
1229 tor_mutex_release(tor_mutex_t
*m
)
1232 r
= ReleaseMutex(m
->handle
);
1234 log_warn(LD_GENERAL
, "Failed to release mutex: %d", (int) GetLastError());
1238 tor_get_thread_id(void)
1240 return (unsigned long)GetCurrentThreadId();
1242 #elif defined(USE_PTHREADS)
1243 /** A generic lock structure for multithreaded builds. */
1244 struct tor_mutex_t
{
1245 pthread_mutex_t mutex
;
1247 /** Allocate and return new lock. */
1251 tor_mutex_t
*mutex
= tor_malloc_zero(sizeof(tor_mutex_t
));
1252 pthread_mutex_init(&mutex
->mutex
, NULL
);
1255 /** Wait until <b>m</b> is free, then acquire it. */
1257 tor_mutex_acquire(tor_mutex_t
*m
)
1260 pthread_mutex_lock(&m
->mutex
);
1262 /** Release the lock <b>m</b> so another thread can have it. */
1264 tor_mutex_release(tor_mutex_t
*m
)
1267 pthread_mutex_unlock(&m
->mutex
);
1269 /** Free all storage held by the lock <b>m</b>. */
1271 tor_mutex_free(tor_mutex_t
*m
)
1274 pthread_mutex_destroy(&m
->mutex
);
1277 /** Return an integer representing this thread. */
1279 tor_get_thread_id(void)
1285 r
.thr
= pthread_self();
1289 /** A generic lock structure for multithreaded builds. */
1290 struct tor_mutex_t
{
1296 * On Windows, WSAEWOULDBLOCK is not always correct: when you see it,
1297 * you need to ask the socket for its actual errno. Also, you need to
1298 * get your errors from WSAGetLastError, not errno. (If you supply a
1299 * socket of -1, we check WSAGetLastError, but don't correct
1302 * The upshot of all of this is that when a socket call fails, you
1303 * should call tor_socket_errno <em>at most once</em> on the failing
1304 * socket to get the error.
1306 #if defined(MS_WINDOWS) && !defined(USE_BSOCKETS)
1308 tor_socket_errno(int sock
)
1310 int optval
, optvallen
=sizeof(optval
);
1311 int err
= WSAGetLastError();
1312 if (err
== WSAEWOULDBLOCK
&& sock
>= 0) {
1313 if (getsockopt(sock
, SOL_SOCKET
, SO_ERROR
, (void*)&optval
, &optvallen
))
1322 #if defined(MS_WINDOWS) && !defined(USE_BSOCKETS)
1323 #define E(code, s) { code, (s " [" #code " ]") }
1324 struct { int code
; const char *msg
; } windows_socket_errors
[] = {
1325 E(WSAEINTR
, "Interrupted function call"),
1326 E(WSAEACCES
, "Permission denied"),
1327 E(WSAEFAULT
, "Bad address"),
1328 E(WSAEINVAL
, "Invalid argument"),
1329 E(WSAEMFILE
, "Too many open files"),
1330 E(WSAEWOULDBLOCK
, "Resource temporarily unavailable"),
1331 E(WSAEINPROGRESS
, "Operation now in progress"),
1332 E(WSAEALREADY
, "Operation already in progress"),
1333 E(WSAENOTSOCK
, "Socket operation on nonsocket"),
1334 E(WSAEDESTADDRREQ
, "Destination address required"),
1335 E(WSAEMSGSIZE
, "Message too long"),
1336 E(WSAEPROTOTYPE
, "Protocol wrong for socket"),
1337 E(WSAENOPROTOOPT
, "Bad protocol option"),
1338 E(WSAEPROTONOSUPPORT
, "Protocol not supported"),
1339 E(WSAESOCKTNOSUPPORT
, "Socket type not supported"),
1340 /* What's the difference between NOTSUPP and NOSUPPORT? :) */
1341 E(WSAEOPNOTSUPP
, "Operation not supported"),
1342 E(WSAEPFNOSUPPORT
, "Protocol family not supported"),
1343 E(WSAEAFNOSUPPORT
, "Address family not supported by protocol family"),
1344 E(WSAEADDRINUSE
, "Address already in use"),
1345 E(WSAEADDRNOTAVAIL
, "Cannot assign requested address"),
1346 E(WSAENETDOWN
, "Network is down"),
1347 E(WSAENETUNREACH
, "Network is unreachable"),
1348 E(WSAENETRESET
, "Network dropped connection on reset"),
1349 E(WSAECONNABORTED
, "Software caused connection abort"),
1350 E(WSAECONNRESET
, "Connection reset by peer"),
1351 E(WSAENOBUFS
, "No buffer space available"),
1352 E(WSAEISCONN
, "Socket is already connected"),
1353 E(WSAENOTCONN
, "Socket is not connected"),
1354 E(WSAESHUTDOWN
, "Cannot send after socket shutdown"),
1355 E(WSAETIMEDOUT
, "Connection timed out"),
1356 E(WSAECONNREFUSED
, "Connection refused"),
1357 E(WSAEHOSTDOWN
, "Host is down"),
1358 E(WSAEHOSTUNREACH
, "No route to host"),
1359 E(WSAEPROCLIM
, "Too many processes"),
1360 /* Yes, some of these start with WSA, not WSAE. No, I don't know why. */
1361 E(WSASYSNOTREADY
, "Network subsystem is unavailable"),
1362 E(WSAVERNOTSUPPORTED
, "Winsock.dll out of range"),
1363 E(WSANOTINITIALISED
, "Successful WSAStartup not yet performed"),
1364 E(WSAEDISCON
, "Graceful shutdown now in progress"),
1365 #ifdef WSATYPE_NOT_FOUND
1366 E(WSATYPE_NOT_FOUND
, "Class type not found"),
1368 E(WSAHOST_NOT_FOUND
, "Host not found"),
1369 E(WSATRY_AGAIN
, "Nonauthoritative host not found"),
1370 E(WSANO_RECOVERY
, "This is a nonrecoverable error"),
1371 E(WSANO_DATA
, "Valid name, no data record of requested type)"),
1373 /* There are some more error codes whose numeric values are marked
1374 * <b>OS dependent</b>. They start with WSA_, apparently for the same
1375 * reason that practitioners of some craft traditions deliberately
1376 * introduce imperfections into their baskets and rugs "to allow the
1377 * evil spirits to escape." If we catch them, then our binaries
1378 * might not report consistent results across versions of Windows.
1379 * Thus, I'm going to let them all fall through.
1383 /** There does not seem to be a strerror equivalent for winsock errors.
1384 * Naturally, we have to roll our own.
1387 tor_socket_strerror(int e
)
1390 for (i
=0; windows_socket_errors
[i
].code
>= 0; ++i
) {
1391 if (e
== windows_socket_errors
[i
].code
)
1392 return windows_socket_errors
[i
].msg
;
1398 /** Called before we make any calls to network-related functions.
1399 * (Some operating systems require their network libraries to be
1405 /* This silly exercise is necessary before windows will allow
1406 * gethostbyname to work. */
1409 r
= WSAStartup(0x101,&WSAData
);
1411 log_warn(LD_NET
,"Error initializing windows network layer: code was %d",r
);
1414 /* WSAData.iMaxSockets might show the max sockets we're allowed to use.
1415 * We might use it to complain if we're trying to be a server but have
1416 * too few sockets available. */
1422 /** Return a newly allocated string describing the windows system error code
1423 * <b>err</b>. Note that error codes are different from errno. Error codes
1424 * come from GetLastError() when a winapi call fails. errno is set only when
1425 * ansi functions fail. Whee. */
1427 format_win32_error(DWORD err
)
1432 /* Somebody once decided that this interface was better than strerror(). */
1433 FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER
|
1434 FORMAT_MESSAGE_FROM_SYSTEM
|
1435 FORMAT_MESSAGE_IGNORE_INSERTS
,
1437 MAKELANGID(LANG_NEUTRAL
, SUBLANG_DEFAULT
),
1442 result
= tor_strdup((char*)str
);
1443 LocalFree(str
); /* LocalFree != free() */
1445 result
= tor_strdup("<unformattable error>");