1 /* Copyright 2003 Roger Dingledine */
2 /* See LICENSE for licensing information */
8 #include <sys/utsname.h>
15 void *tor_malloc(size_t size
) {
18 result
= malloc(size
);
21 log_fn(LOG_ERR
, "Out of memory. Dying.");
24 // memset(result,'X',size); /* deadbeef to encourage bugs */
28 void *tor_malloc_zero(size_t size
) {
29 void *result
= tor_malloc(size
);
30 memset(result
, 0, size
);
34 void *tor_realloc(void *ptr
, size_t size
) {
37 result
= realloc(ptr
, size
);
39 log_fn(LOG_ERR
, "Out of memory. Dying.");
45 char *tor_strdup(const char *s
) {
51 log_fn(LOG_ERR
,"Out of memory. Dying.");
57 char *tor_strndup(const char *s
, size_t n
) {
60 dup
= tor_malloc(n
+1);
67 * A simple smartlist interface to make an unordered list of acceptable
68 * nodes and then choose a random one.
69 * smartlist_create() mallocs the list, _free() frees the list,
70 * _add() adds an element, _remove() removes an element if it's there,
71 * _choose() returns a random element.
74 smartlist_t
*smartlist_create(int max_elements
) {
75 smartlist_t
*sl
= tor_malloc(sizeof(smartlist_t
));
76 sl
->list
= tor_malloc(sizeof(void *) * max_elements
);
78 sl
->max
= max_elements
;
82 void smartlist_free(smartlist_t
*sl
) {
87 /* add element to the list, but only if there's room */
88 void smartlist_add(smartlist_t
*sl
, void *element
) {
89 if(sl
->num_used
< sl
->max
)
90 sl
->list
[sl
->num_used
++] = element
;
92 log_fn(LOG_WARN
,"We've already got %d elements, discarding.",sl
->max
);
95 void smartlist_remove(smartlist_t
*sl
, void *element
) {
99 for(i
=0; i
< sl
->num_used
; i
++)
100 if(sl
->list
[i
] == element
) {
101 sl
->list
[i
] = sl
->list
[--sl
->num_used
]; /* swap with the end */
102 i
--; /* so we process the new i'th element */
106 int smartlist_isin(smartlist_t
*sl
, void *element
) {
108 for(i
=0; i
< sl
->num_used
; i
++)
109 if(sl
->list
[i
] == element
)
114 int smartlist_overlap(smartlist_t
*sl1
, smartlist_t
*sl2
) {
116 for(i
=0; i
< sl2
->num_used
; i
++)
117 if(smartlist_isin(sl1
, sl2
->list
[i
]))
122 /* remove elements of sl1 that aren't in sl2 */
123 void smartlist_intersect(smartlist_t
*sl1
, smartlist_t
*sl2
) {
125 for(i
=0; i
< sl1
->num_used
; i
++)
126 if(!smartlist_isin(sl2
, sl1
->list
[i
])) {
127 sl1
->list
[i
] = sl1
->list
[--sl1
->num_used
]; /* swap with the end */
128 i
--; /* so we process the new i'th element */
132 /* remove all elements of sl2 from sl1 */
133 void smartlist_subtract(smartlist_t
*sl1
, smartlist_t
*sl2
) {
135 for(i
=0; i
< sl2
->num_used
; i
++)
136 smartlist_remove(sl1
, sl2
->list
[i
]);
139 void *smartlist_choose(smartlist_t
*sl
) {
141 return sl
->list
[crypto_pseudo_rand_int(sl
->num_used
)];
142 return NULL
; /* no elements to choose from */
146 * String manipulation
149 /* return the first char of s that is not whitespace and not a comment */
150 const char *eat_whitespace(const char *s
) {
153 while(isspace(*s
) || *s
== '#') {
156 if(*s
== '#') { /* read to a \n or \0 */
157 while(*s
&& *s
!= '\n')
166 const char *eat_whitespace_no_nl(const char *s
) {
167 while(*s
== ' ' || *s
== '\t')
172 /* return the first char of s that is whitespace or '#' or '\0 */
173 const char *find_whitespace(const char *s
) {
176 while(*s
&& !isspace(*s
) && *s
!= '#')
186 void tor_gettimeofday(struct timeval
*timeval
) {
187 #ifdef HAVE_GETTIMEOFDAY
188 if (gettimeofday(timeval
, NULL
)) {
189 log_fn(LOG_ERR
, "gettimeofday failed.");
190 /* If gettimeofday dies, we have either given a bad timezone (we didn't),
194 #elif defined(HAVE_FTIME)
197 #error "No way to get time."
203 tv_udiff(struct timeval
*start
, struct timeval
*end
)
206 long secdiff
= end
->tv_sec
- start
->tv_sec
;
208 if (secdiff
+1 > LONG_MAX
/1000000) {
209 log_fn(LOG_WARN
, "comparing times too far apart.");
213 udiff
= secdiff
*1000000L + (end
->tv_usec
- start
->tv_usec
);
215 log_fn(LOG_INFO
, "start (%ld.%ld) is after end (%ld.%ld). Returning 0.",
216 (long)start
->tv_sec
, (long)start
->tv_usec
, (long)end
->tv_sec
, (long)end
->tv_usec
);
222 int tv_cmp(struct timeval
*a
, struct timeval
*b
) {
223 if (a
->tv_sec
> b
->tv_sec
)
225 if (a
->tv_sec
< b
->tv_sec
)
227 if (a
->tv_usec
> b
->tv_usec
)
229 if (a
->tv_usec
< b
->tv_usec
)
234 void tv_add(struct timeval
*a
, struct timeval
*b
) {
235 a
->tv_usec
+= b
->tv_usec
;
236 a
->tv_sec
+= b
->tv_sec
+ (a
->tv_usec
/ 1000000);
237 a
->tv_usec
%= 1000000;
240 void tv_addms(struct timeval
*a
, long ms
) {
241 a
->tv_usec
+= (ms
* 1000) % 1000000;
242 a
->tv_sec
+= ((ms
* 1000) / 1000000) + (a
->tv_usec
/ 1000000);
243 a
->tv_usec
%= 1000000;
247 #define IS_LEAPYEAR(y) (!(y % 4) && ((y % 100) || !(y % 400)))
248 static int n_leapdays(int y1
, int y2
) {
251 return (y2
/4 - y1
/4) - (y2
/100 - y1
/100) + (y2
/400 - y1
/400);
253 static const int days_per_month
[] =
254 { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
256 time_t tor_timegm (struct tm
*tm
) {
257 /* This is a pretty ironclad timegm implementation, snarfed from Python2.2.
258 * It's way more brute-force than fiddling with tzset().
261 unsigned long year
, days
, hours
, minutes
;
263 year
= tm
->tm_year
+ 1900;
264 assert(year
>= 1970);
265 assert(tm
->tm_mon
>= 0 && tm
->tm_mon
<= 11);
266 days
= 365 * (year
-1970) + n_leapdays(1970,year
);
267 for (i
= 0; i
< tm
->tm_mon
; ++i
)
268 days
+= days_per_month
[i
];
269 if (tm
->tm_mon
> 1 && IS_LEAPYEAR(year
))
271 days
+= tm
->tm_mday
- 1;
272 hours
= days
*24 + tm
->tm_hour
;
274 minutes
= hours
*60 + tm
->tm_min
;
275 ret
= minutes
*60 + tm
->tm_sec
;
283 /* a wrapper for write(2) that makes sure to write all count bytes.
284 * Only use if fd is a blocking fd. */
285 int write_all(int fd
, const char *buf
, size_t count
, int isSocket
) {
289 while(written
!= count
) {
291 result
= send(fd
, buf
+written
, count
-written
, 0);
293 result
= write(fd
, buf
+written
, count
-written
);
301 /* a wrapper for read(2) that makes sure to read all count bytes.
302 * Only use if fd is a blocking fd. */
303 int read_all(int fd
, char *buf
, size_t count
, int isSocket
) {
307 while(numread
!= count
) {
309 result
= recv(fd
, buf
+numread
, count
-numread
, 0);
311 result
= read(fd
, buf
+numread
, count
-numread
);
319 void set_socket_nonblocking(int socket
)
322 /* Yes means no and no means yes. Do you not want to be nonblocking? */
324 ioctlsocket(socket
, FIONBIO
, (unsigned long*) &nonblocking
);
326 fcntl(socket
, F_SETFL
, O_NONBLOCK
);
334 /* Minimalist interface to run a void function in the background. On
335 * unix calls fork, on win32 calls beginthread. Returns -1 on failure.
336 * func should not return, but rather should call spawn_exit.
338 int spawn_func(int (*func
)(void *), void *data
)
342 rv
= _beginthread(func
, 0, data
);
343 if (rv
== (unsigned long) -1)
354 assert(0); /* Should never reach here. */
355 return 0; /* suppress "control-reaches-end-of-non-void" warning. */
374 * Windows compatibility.
377 tor_socketpair(int family
, int type
, int protocol
, int fd
[2])
379 #ifdef HAVE_SOCKETPAIR_XXXX
380 /* For testing purposes, we never fall back to real socketpairs. */
381 return socketpair(family
, type
, protocol
, fd
);
386 struct sockaddr_in listen_addr
;
387 struct sockaddr_in connect_addr
;
396 errno
= WSAEAFNOSUPPORT
;
398 errno
= EAFNOSUPPORT
;
407 listener
= socket(AF_INET
, type
, 0);
410 memset (&listen_addr
, 0, sizeof (listen_addr
));
411 listen_addr
.sin_family
= AF_INET
;
412 listen_addr
.sin_addr
.s_addr
= htonl (INADDR_LOOPBACK
);
413 listen_addr
.sin_port
= 0; /* kernel choses port. */
414 if (bind(listener
, (struct sockaddr
*) &listen_addr
, sizeof (listen_addr
))
416 goto tidy_up_and_fail
;
417 if (listen(listener
, 1) == -1)
418 goto tidy_up_and_fail
;
420 connector
= socket(AF_INET
, type
, 0);
422 goto tidy_up_and_fail
;
423 /* We want to find out the port number to connect to. */
424 size
= sizeof (connect_addr
);
425 if (getsockname(listener
, (struct sockaddr
*) &connect_addr
, &size
) == -1)
426 goto tidy_up_and_fail
;
427 if (size
!= sizeof (connect_addr
))
428 goto abort_tidy_up_and_fail
;
429 if (connect(connector
, (struct sockaddr
*) &connect_addr
,
430 sizeof (connect_addr
)) == -1)
431 goto tidy_up_and_fail
;
433 size
= sizeof (listen_addr
);
434 acceptor
= accept(listener
, (struct sockaddr
*) &listen_addr
, &size
);
436 goto tidy_up_and_fail
;
437 if (size
!= sizeof(listen_addr
))
438 goto abort_tidy_up_and_fail
;
440 /* Now check we are talking to ourself by matching port and host on the
442 if (getsockname(connector
, (struct sockaddr
*) &connect_addr
, &size
) == -1)
443 goto tidy_up_and_fail
;
444 if (size
!= sizeof (connect_addr
)
445 || listen_addr
.sin_family
!= connect_addr
.sin_family
446 || listen_addr
.sin_addr
.s_addr
!= connect_addr
.sin_addr
.s_addr
447 || listen_addr
.sin_port
!= connect_addr
.sin_port
) {
448 goto abort_tidy_up_and_fail
;
454 abort_tidy_up_and_fail
:
456 errno
= WSAECONNABORTED
;
458 errno
= ECONNABORTED
; /* I hope this is portable and appropriate. */
462 int save_errno
= errno
;
476 int correct_socket_errno(int s
)
478 int optval
, optvallen
=sizeof(optval
);
479 assert(errno
== WSAEWOULDBLOCK
);
480 if (getsockopt(s
, SOL_SOCKET
, SO_ERROR
, (void*)&optval
, &optvallen
))
484 return WSAEWOULDBLOCK
;
489 * Filesystem operations.
492 /* Return FN_ERROR if filename can't be read, FN_NOENT if it doesn't
493 * exist, FN_FILE if it is a regular file, or FN_DIR if it's a
495 file_status_t
file_status(const char *fname
)
498 if (stat(fname
, &st
)) {
499 if (errno
== ENOENT
) {
504 if (st
.st_mode
& S_IFDIR
)
506 else if (st
.st_mode
& S_IFREG
)
512 /* Check whether dirname exists and is private. If yes returns
513 0. Else returns -1. */
514 int check_private_dir(const char *dirname
, int create
)
518 if (stat(dirname
, &st
)) {
519 if (errno
!= ENOENT
) {
520 log(LOG_WARN
, "Directory %s cannot be read: %s", dirname
,
525 log(LOG_WARN
, "Directory %s does not exist.", dirname
);
528 log(LOG_INFO
, "Creating directory %s", dirname
);
532 r
= mkdir(dirname
, 0700);
535 log(LOG_WARN
, "Error creating directory %s: %s", dirname
,
542 if (!(st
.st_mode
& S_IFDIR
)) {
543 log(LOG_WARN
, "%s is not a directory", dirname
);
547 if (st
.st_uid
!= getuid()) {
548 log(LOG_WARN
, "%s is not owned by this UID (%d)", dirname
, (int)getuid());
551 if (st
.st_mode
& 0077) {
552 log(LOG_WARN
, "Fixing permissions on directory %s", dirname
);
553 if (chmod(dirname
, 0700)) {
554 log(LOG_WARN
, "Could not chmod directory %s: %s", dirname
,
566 write_str_to_file(const char *fname
, const char *str
)
571 if (strlen(fname
) > 1000) {
572 log(LOG_WARN
, "Filename %s is too long.", fname
);
575 strcpy(tempname
,fname
);
576 strcat(tempname
,".tmp");
577 if ((fd
= open(tempname
, O_WRONLY
|O_CREAT
|O_TRUNC
, 0600)) < 0) {
578 log(LOG_WARN
, "Couldn't open %s for writing: %s", tempname
,
582 if (!(file
= fdopen(fd
, "w"))) {
583 log(LOG_WARN
, "Couldn't fdopen %s for writing: %s", tempname
,
585 close(fd
); return -1;
587 if (fputs(str
,file
) == EOF
) {
588 log(LOG_WARN
, "Error writing to %s: %s", tempname
, strerror(errno
));
589 fclose(file
); return -1;
592 if (rename(tempname
, fname
)) {
593 log(LOG_WARN
, "Error replacing %s: %s", fname
, strerror(errno
));
599 char *read_file_to_str(const char *filename
) {
600 int fd
; /* router file */
606 if(strcspn(filename
,CONFIG_LEGAL_FILENAME_CHARACTERS
) != 0) {
607 log_fn(LOG_WARN
,"Filename %s contains illegal characters.",filename
);
611 if(stat(filename
, &statbuf
) < 0) {
612 log_fn(LOG_INFO
,"Could not stat %s.",filename
);
616 fd
= open(filename
,O_RDONLY
,0);
618 log_fn(LOG_WARN
,"Could not open %s.",filename
);
622 string
= tor_malloc(statbuf
.st_size
+1);
624 if(read_all(fd
,string
,statbuf
.st_size
,0) != statbuf
.st_size
) {
625 log_fn(LOG_WARN
,"Couldn't read all %ld bytes of file '%s'.",
626 (long)statbuf
.st_size
,filename
);
633 string
[statbuf
.st_size
] = 0; /* null terminate it */
637 /* read lines from f (no more than maxlen-1 bytes each) until we
638 * get a non-whitespace line. If it isn't of the form "key value"
639 * (value can have spaces), return -1.
640 * Point *key to the first word in line, point *value * to the second.
641 * Put a \0 at the end of key, remove everything at the end of value
642 * that is whitespace or comment.
643 * Return 1 if success, 0 if no more lines, -1 if error.
645 int parse_line_from_file(char *line
, int maxlen
, FILE *f
, char **key_out
, char **value_out
) {
646 char *s
, *key
, *end
, *value
;
649 if(!fgets(line
, maxlen
, f
)) {
652 return -1; /* real error */
655 if((s
= strchr(line
,'#'))) /* strip comments */
656 *s
= 0; /* stop the line there */
658 /* remove end whitespace */
659 s
= strchr(line
, 0); /* now we're at the null */
663 } while (s
>= line
&& isspace(*s
));
669 goto try_next_line
; /* this line has nothing on it */
671 while(*end
&& !isspace(*end
))
674 while(*value
&& isspace(*value
))
677 if(!*end
|| !*value
) { /* only a key on this line. no value. */
679 log_fn(LOG_WARN
,"Line has keyword '%s' but no value. Failing.",key
);
682 *end
= 0; /* null it out */
684 log_fn(LOG_DEBUG
,"got keyword '%s', value '%s'", key
, value
);
685 *key_out
= key
, *value_out
= value
;
689 static char uname_result
[256];
690 static int uname_result_is_set
= 0;
698 if (!uname_result_is_set
) {
701 snprintf(uname_result
, 255, "%s %s %s",
702 u
.sysname
, u
.nodename
, u
.machine
);
703 uname_result
[255] = '\0';
707 strcpy(uname_result
, "Unknown platform");
709 uname_result_is_set
= 1;
715 /* Based on code contributed by christian grothoff */
716 static int start_daemon_called
= 0;
717 static int finish_daemon_called
= 0;
718 static int daemon_filedes
[2];
719 void start_daemon(char *desired_cwd
)
723 if (start_daemon_called
)
725 start_daemon_called
= 1;
729 /* Don't hold the wrong FS mounted */
730 if (chdir(desired_cwd
) < 0) {
731 log_fn(LOG_ERR
,"chdir to %s failed. Exiting.",desired_cwd
);
735 pipe(daemon_filedes
);
738 log_fn(LOG_ERR
,"fork failed. Exiting.");
741 if (pid
) { /* Parent */
745 close(daemon_filedes
[1]); /* we only read */
747 while (0 < read(daemon_filedes
[0], &c
, sizeof(char))) {
755 exit(1); /* child reported error */
757 close(daemon_filedes
[0]); /* we only write */
759 pid
= setsid(); /* Detach from controlling terminal */
761 * Fork one more time, so the parent (the session group leader) can exit.
762 * This means that we, as a non-session group leader, can never regain a
763 * controlling terminal. This part is recommended by Stevens's
764 * _Advanced Programming in the Unix Environment_.
773 void finish_daemon(void)
777 if (finish_daemon_called
)
779 if (!start_daemon_called
)
781 finish_daemon_called
= 1;
783 nullfd
= open("/dev/null",
784 O_CREAT
| O_RDWR
| O_APPEND
);
786 log_fn(LOG_ERR
,"/dev/null can't be opened. Exiting.");
789 /* close fds linking to invoking terminal, but
790 * close usual incoming fds, but redirect them somewhere
791 * useful so the fds don't get reallocated elsewhere.
793 if (dup2(nullfd
,0) < 0 ||
794 dup2(nullfd
,1) < 0 ||
795 dup2(nullfd
,2) < 0) {
796 log_fn(LOG_ERR
,"dup2 failed. Exiting.");
799 write(daemon_filedes
[1], &c
, sizeof(char)); /* signal success */
800 close(daemon_filedes
[1]);
803 /* defined(MS_WINDOWS) */
804 void start_daemon(char *cp
) {}
805 void finish_daemon(void) {}
808 void write_pidfile(char *filename
) {
812 if ((pidfile
= fopen(filename
, "w")) == NULL
) {
813 log_fn(LOG_WARN
, "unable to open %s for writing: %s", filename
,
816 fprintf(pidfile
, "%d", getpid());
822 int switch_id(char *user
, char *group
) {
824 struct passwd
*pw
= NULL
;
825 struct group
*gr
= NULL
;
830 log_fn(LOG_ERR
,"User '%s' not found.", user
);
835 /* switch the group first, while we still have the privileges to do so */
837 gr
= getgrnam(group
);
839 log_fn(LOG_ERR
,"Group '%s' not found.", group
);
843 if (setgid(gr
->gr_gid
) != 0) {
844 log_fn(LOG_ERR
,"Error setting GID: %s", strerror(errno
));
848 if (setgid(pw
->pw_gid
) != 0) {
849 log_fn(LOG_ERR
,"Error setting GID: %s", strerror(errno
));
854 /* now that the group is switched, we can switch users and lose
857 if (setuid(pw
->pw_uid
) != 0) {
858 log_fn(LOG_ERR
,"Error setting UID: %s", strerror(errno
));
867 "User or group specified, but switching users is not supported.");
872 int tor_inet_aton(const char *c
, struct in_addr
* addr
)
874 #ifdef HAVE_INET_ATON
875 return inet_aton(c
, addr
);
879 if (strcmp(c
, "255.255.255.255") == 0) {
880 addr
->s_addr
= 0xFFFFFFFFu
;
884 if (r
== INADDR_NONE
)