util.c 5.7 KB

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