util.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  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. /* a wrapper for write(2) that makes sure to write all count bytes.
  77. * Only use if fd is a blocking socket. */
  78. int write_all(int fd, const void *buf, size_t count) {
  79. int written = 0;
  80. int result;
  81. while(written != count) {
  82. result = write(fd, buf+written, count-written);
  83. if(result<0)
  84. return -1;
  85. written += result;
  86. }
  87. return count;
  88. }
  89. void set_socket_nonblocking(int socket)
  90. {
  91. #ifdef MS_WINDOWS
  92. /* Yes means no and no means yes. Do you not want to be nonblocking? */
  93. int nonblocking = 0;
  94. ioctlsocket(socket, FIONBIO, (unsigned long*) &nonblocking);
  95. #else
  96. fcntl(socket, F_SETFL, O_NONBLOCK);
  97. #endif
  98. }
  99. int spawn_func(int (*func)(void *), void *data)
  100. {
  101. #ifdef MS_WINDOWS
  102. int rv;
  103. rv = _beginthread(func, 0, data);
  104. if (rv == (unsigned long) -1)
  105. return -1;
  106. return 0;
  107. #else
  108. pid_t pid;
  109. pid = fork();
  110. if (pid<0)
  111. return -1;
  112. if (pid==0) {
  113. /* Child */
  114. func(data);
  115. assert(0); /* Should never reach here. */
  116. return 0; /* suppress "control-reaches-end-of-non-void" warning. */
  117. } else {
  118. /* Parent */
  119. return 0;
  120. }
  121. #endif
  122. }
  123. void spawn_exit()
  124. {
  125. #ifdef MS_WINDOWS
  126. _endthread();
  127. #else
  128. exit(0);
  129. #endif
  130. }
  131. /* Fake socket pair over TCP. Code adapted from perl 5.8.0's util.c */
  132. int
  133. tor_socketpair(int family, int type, int protocol, int fd[2])
  134. {
  135. #ifdef HAVE_SOCKETPAIR_XXXX
  136. /* For testing purposes, we never fall back to real socketpairs. */
  137. return socketpair(family, type, protocol, fd);
  138. #else
  139. int listener = -1;
  140. int connector = -1;
  141. int acceptor = -1;
  142. struct sockaddr_in listen_addr;
  143. struct sockaddr_in connect_addr;
  144. size_t size;
  145. if (protocol
  146. #ifdef AF_UNIX
  147. || family != AF_UNIX
  148. #endif
  149. ) {
  150. #ifdef MS_WINDOWS
  151. errno = WSAEAFNOSUPPORT;
  152. #else
  153. errno = EAFNOSUPPORT;
  154. #endif
  155. return -1;
  156. }
  157. if (!fd) {
  158. errno = EINVAL;
  159. return -1;
  160. }
  161. listener = socket(AF_INET, type, 0);
  162. if (listener == -1)
  163. return -1;
  164. memset (&listen_addr, 0, sizeof (listen_addr));
  165. listen_addr.sin_family = AF_INET;
  166. listen_addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
  167. listen_addr.sin_port = 0; /* kernel choses port. */
  168. if (bind(listener, (struct sockaddr *) &listen_addr, sizeof (listen_addr))
  169. == -1)
  170. goto tidy_up_and_fail;
  171. if (listen(listener, 1) == -1)
  172. goto tidy_up_and_fail;
  173. connector = socket(AF_INET, type, 0);
  174. if (connector == -1)
  175. goto tidy_up_and_fail;
  176. /* We want to find out the port number to connect to. */
  177. size = sizeof (connect_addr);
  178. if (getsockname(listener, (struct sockaddr *) &connect_addr, &size) == -1)
  179. goto tidy_up_and_fail;
  180. if (size != sizeof (connect_addr))
  181. goto abort_tidy_up_and_fail;
  182. if (connect(connector, (struct sockaddr *) &connect_addr,
  183. sizeof (connect_addr)) == -1)
  184. goto tidy_up_and_fail;
  185. size = sizeof (listen_addr);
  186. acceptor = accept(listener, (struct sockaddr *) &listen_addr, &size);
  187. if (acceptor == -1)
  188. goto tidy_up_and_fail;
  189. if (size != sizeof(listen_addr))
  190. goto abort_tidy_up_and_fail;
  191. close(listener);
  192. /* Now check we are talking to ourself by matching port and host on the
  193. two sockets. */
  194. if (getsockname(connector, (struct sockaddr *) &connect_addr, &size) == -1)
  195. goto tidy_up_and_fail;
  196. if (size != sizeof (connect_addr)
  197. || listen_addr.sin_family != connect_addr.sin_family
  198. || listen_addr.sin_addr.s_addr != connect_addr.sin_addr.s_addr
  199. || listen_addr.sin_port != connect_addr.sin_port) {
  200. goto abort_tidy_up_and_fail;
  201. }
  202. fd[0] = connector;
  203. fd[1] = acceptor;
  204. return 0;
  205. abort_tidy_up_and_fail:
  206. #ifdef MS_WINDOWS
  207. errno = WSAECONNABORTED;
  208. #else
  209. errno = ECONNABORTED; /* I hope this is portable and appropriate. */
  210. #endif
  211. tidy_up_and_fail:
  212. {
  213. int save_errno = errno;
  214. if (listener != -1)
  215. close(listener);
  216. if (connector != -1)
  217. close(connector);
  218. if (acceptor != -1)
  219. close(acceptor);
  220. errno = save_errno;
  221. return -1;
  222. }
  223. #endif
  224. }
  225. #ifdef MS_WINDOWS
  226. int correct_socket_errno(int s)
  227. {
  228. int optval, optvallen=sizeof(optval);
  229. assert(errno == WSAEWOULDBLOCK);
  230. if (getsockopt(s, SOL_SOCKET, SO_ERROR, (void*)&optval, &optvallen))
  231. return errno;
  232. if (optval)
  233. return optval;
  234. return WSAEWOULDBLOCK;
  235. }
  236. #endif