util.c 6.4 KB

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