util.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. /* Copyright 2003 Roger Dingledine */
  2. /* See LICENSE for licensing information */
  3. /* $Id$ */
  4. #include "../or/or.h"
  5. #include "util.h"
  6. #include "log.h"
  7. void *tor_malloc(size_t size) {
  8. void *result;
  9. result = malloc(size);
  10. if(!result) {
  11. log_fn(LOG_ERR, "Out of memory. Dying.");
  12. exit(1);
  13. }
  14. return result;
  15. }
  16. void
  17. my_gettimeofday(struct timeval *timeval)
  18. {
  19. #ifdef HAVE_GETTIMEOFDAY
  20. if (gettimeofday(timeval, NULL)) {
  21. log_fn(LOG_ERR, "gettimeofday failed.");
  22. /* If gettimeofday dies, we have either given a bad timezone (we didn't),
  23. or segfaulted.*/
  24. exit(1);
  25. }
  26. #elif defined(HAVE_FTIME)
  27. ftime(timeval);
  28. #else
  29. #error "No way to get time."
  30. #endif
  31. return;
  32. }
  33. long
  34. tv_udiff(struct timeval *start, struct timeval *end)
  35. {
  36. long udiff;
  37. long end_usec = end->tv_usec;
  38. long secdiff = end->tv_sec - start->tv_sec;
  39. if (secdiff+1 > LONG_MAX/1000000) {
  40. log_fn(LOG_NOTICE, "comparing times too far apart.");
  41. return LONG_MAX;
  42. }
  43. udiff = secdiff*1000000L + (end_usec - start->tv_usec);
  44. if(udiff < 0) {
  45. log_fn(LOG_NOTICE, "start is after end. Returning 0.");
  46. return 0;
  47. }
  48. return udiff;
  49. }
  50. int tv_cmp(struct timeval *a, struct timeval *b) {
  51. if (a->tv_sec > b->tv_sec)
  52. return 1;
  53. if (a->tv_sec < b->tv_sec)
  54. return -1;
  55. if (a->tv_usec > b->tv_usec)
  56. return 1;
  57. if (a->tv_usec < b->tv_usec)
  58. return -1;
  59. return 0;
  60. }
  61. void tv_add(struct timeval *a, struct timeval *b) {
  62. a->tv_usec += b->tv_usec;
  63. a->tv_sec += b->tv_sec + (a->tv_usec / 1000000);
  64. a->tv_usec %= 1000000;
  65. }
  66. void tv_addms(struct timeval *a, long ms) {
  67. a->tv_usec += (ms * 1000) % 1000000;
  68. a->tv_sec += ((ms * 1000) / 1000000) + (a->tv_usec / 1000000);
  69. a->tv_usec %= 1000000;
  70. }
  71. void set_socket_nonblocking(int socket)
  72. {
  73. #ifdef _MSC_VER
  74. /* Yes means no and no means yes. Do you not want to be nonblocking? */
  75. int nonblocking = 0;
  76. ioctlsocket(socket, FIONBIO, (unsigned long*) &nonblocking);
  77. #else
  78. fcntl(socket, F_SETFL, O_NONBLOCK);
  79. #endif
  80. }
  81. int spawn_func(int (*func)(void *), void *data)
  82. {
  83. #ifdef _MSC_VER
  84. int rv;
  85. rv = _beginthread(func, 0, data);
  86. if (rv == (unsigned long) -1)
  87. return -1;
  88. return 0;
  89. #else
  90. pid_t pid;
  91. pid = fork();
  92. if (pid<0)
  93. return -1;
  94. if (pid==0) {
  95. /* Child */
  96. func(data);
  97. assert(0); /* Should never reach here. */
  98. } else {
  99. /* Parent */
  100. return 0;
  101. }
  102. #endif
  103. }
  104. void spawn_exit()
  105. {
  106. #ifdef _MSC_VER
  107. _endthread();
  108. #else
  109. exit(0);
  110. #endif
  111. }
  112. /* Fake socket pair over TCP. Code adapted from perl 5.8.0's util.c */
  113. int
  114. tor_socketpair(int family, int type, int protocol, int fd[2])
  115. {
  116. #ifdef HAVE_SOCKETPAIR_XXX
  117. /* For testing purposes, we never fall back to real socketpairs. */
  118. return socketpair(family, type, protocol, fd);
  119. #else
  120. int listener = -1;
  121. int connector = -1;
  122. int acceptor = -1;
  123. struct sockaddr_in listen_addr;
  124. struct sockaddr_in connect_addr;
  125. size_t size;
  126. if (protocol
  127. #ifdef AF_UNIX
  128. || family != AF_UNIX
  129. #endif
  130. ) {
  131. errno = EAFNOSUPPORT;
  132. return -1;
  133. }
  134. if (!fd) {
  135. errno = EINVAL;
  136. return -1;
  137. }
  138. listener = socket(AF_INET, type, 0);
  139. if (listener == -1)
  140. return -1;
  141. memset (&listen_addr, 0, sizeof (listen_addr));
  142. listen_addr.sin_family = AF_INET;
  143. listen_addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
  144. listen_addr.sin_port = 0; /* kernel choses port. */
  145. if (bind(listener, (struct sockaddr *) &listen_addr, sizeof (listen_addr))
  146. == -1)
  147. goto tidy_up_and_fail;
  148. if (listen(listener, 1) == -1)
  149. goto tidy_up_and_fail;
  150. connector = socket(AF_INET, type, 0);
  151. if (connector == -1)
  152. goto tidy_up_and_fail;
  153. /* We want to find out the port number to connect to. */
  154. size = sizeof (connect_addr);
  155. if (getsockname(listener, (struct sockaddr *) &connect_addr, &size) == -1)
  156. goto tidy_up_and_fail;
  157. if (size != sizeof (connect_addr))
  158. goto abort_tidy_up_and_fail;
  159. if (connect(connector, (struct sockaddr *) &connect_addr,
  160. sizeof (connect_addr)) == -1)
  161. goto tidy_up_and_fail;
  162. size = sizeof (listen_addr);
  163. acceptor = accept(listener, (struct sockaddr *) &listen_addr, &size);
  164. if (acceptor == -1)
  165. goto tidy_up_and_fail;
  166. if (size != sizeof(listen_addr))
  167. goto abort_tidy_up_and_fail;
  168. close(listener);
  169. /* Now check we are talking to ourself by matching port and host on the
  170. two sockets. */
  171. if (getsockname(connector, (struct sockaddr *) &connect_addr, &size) == -1)
  172. goto tidy_up_and_fail;
  173. if (size != sizeof (connect_addr)
  174. || listen_addr.sin_family != connect_addr.sin_family
  175. || listen_addr.sin_addr.s_addr != connect_addr.sin_addr.s_addr
  176. || listen_addr.sin_port != connect_addr.sin_port) {
  177. goto abort_tidy_up_and_fail;
  178. }
  179. fd[0] = connector;
  180. fd[1] = acceptor;
  181. return 0;
  182. abort_tidy_up_and_fail:
  183. errno = ECONNABORTED; /* I hope this is portable and appropriate. */
  184. tidy_up_and_fail:
  185. {
  186. int save_errno = errno;
  187. if (listener != -1)
  188. close(listener);
  189. if (connector != -1)
  190. close(connector);
  191. if (acceptor != -1)
  192. close(acceptor);
  193. errno = save_errno;
  194. return -1;
  195. }
  196. #endif
  197. }