A clone of btpd with my configuration changes.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

438 lines
10 KiB

  1. /*
  2. * Copyright 2000-2002 Niels Provos <provos@citi.umich.edu>
  3. * Copyright 2003 Michael A. Davis <mike@datanerds.net>
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions
  8. * are met:
  9. * 1. Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions and the following disclaimer.
  11. * 2. Redistributions in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in the
  13. * documentation and/or other materials provided with the distribution.
  14. * 3. The name of the author may not be used to endorse or promote products
  15. * derived from this software without specific prior written permission.
  16. *
  17. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  18. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  19. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  20. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  21. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  22. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  23. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  24. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  26. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27. */
  28. #ifdef _MSC_VER
  29. #include "config.h"
  30. #else
  31. /* Avoid the windows/msvc thing. */
  32. #include "../config.h"
  33. #endif
  34. #include <windows.h>
  35. #include <winsock2.h>
  36. #include <sys/types.h>
  37. #include <sys/queue.h>
  38. #include <sys/tree.h>
  39. #include <signal.h>
  40. #include <stdio.h>
  41. #include <stdlib.h>
  42. #include <string.h>
  43. #include <errno.h>
  44. #include <assert.h>
  45. #include "log.h"
  46. #include "event.h"
  47. #include "event-internal.h"
  48. #define XFREE(ptr) do { if (ptr) free(ptr); } while(0)
  49. extern struct event_list timequeue;
  50. extern struct event_list addqueue;
  51. extern struct event_list signalqueue;
  52. struct win_fd_set {
  53. u_int fd_count;
  54. SOCKET fd_array[1];
  55. };
  56. int evsigcaught[NSIG];
  57. volatile sig_atomic_t signal_caught = 0;
  58. /* MSDN says this is required to handle SIGFPE */
  59. volatile double SIGFPE_REQ = 0.0f;
  60. static void signal_handler(int sig);
  61. void signal_process(void);
  62. int signal_recalc(void);
  63. struct win32op {
  64. int fd_setsz;
  65. struct win_fd_set *readset_in;
  66. struct win_fd_set *writeset_in;
  67. struct win_fd_set *readset_out;
  68. struct win_fd_set *writeset_out;
  69. struct win_fd_set *exset_out;
  70. int n_events;
  71. int n_events_alloc;
  72. struct event **events;
  73. };
  74. void *win32_init (void);
  75. int win32_insert (void *, struct event *);
  76. int win32_del (void *, struct event *);
  77. int win32_recalc (struct event_base *base, void *, int);
  78. int win32_dispatch (struct event_base *base, void *, struct timeval *);
  79. void win32_dealloc (void *);
  80. struct eventop win32ops = {
  81. "win32",
  82. win32_init,
  83. win32_insert,
  84. win32_del,
  85. win32_recalc,
  86. win32_dispatch,
  87. win32_dealloc
  88. };
  89. #define FD_SET_ALLOC_SIZE(n) ((sizeof(struct win_fd_set) + ((n)-1)*sizeof(SOCKET)))
  90. static int
  91. realloc_fd_sets(struct win32op *op, size_t new_size)
  92. {
  93. size_t size;
  94. assert(new_size >= op->readset_in->fd_count &&
  95. new_size >= op->writeset_in->fd_count);
  96. assert(new_size >= 1);
  97. size = FD_SET_ALLOC_SIZE(new_size);
  98. if (!(op->readset_in = realloc(op->readset_in, size)))
  99. return (-1);
  100. if (!(op->writeset_in = realloc(op->writeset_in, size)))
  101. return (-1);
  102. if (!(op->readset_out = realloc(op->readset_out, size)))
  103. return (-1);
  104. if (!(op->exset_out = realloc(op->exset_out, size)))
  105. return (-1);
  106. if (!(op->writeset_out = realloc(op->writeset_out, size)))
  107. return (-1);
  108. op->fd_setsz = new_size;
  109. return (0);
  110. }
  111. static int
  112. timeval_to_ms(struct timeval *tv)
  113. {
  114. return ((tv->tv_sec * 1000) + (tv->tv_usec / 1000));
  115. }
  116. static int
  117. do_fd_set(struct win32op *op, SOCKET s, int read)
  118. {
  119. unsigned int i;
  120. struct win_fd_set *set = read ? op->readset_in : op->writeset_in;
  121. for (i=0;i<set->fd_count;++i) {
  122. if (set->fd_array[i]==s)
  123. return (0);
  124. }
  125. if (set->fd_count == op->fd_setsz) {
  126. if (realloc_fd_sets(op, op->fd_setsz*2))
  127. return (-1);
  128. /* set pointer will have changed and needs reiniting! */
  129. set = read ? op->readset_in : op->writeset_in;
  130. }
  131. set->fd_array[set->fd_count] = s;
  132. return (set->fd_count++);
  133. }
  134. static int
  135. do_fd_clear(struct win32op *op, SOCKET s, int read)
  136. {
  137. unsigned int i;
  138. struct win_fd_set *set = read ? op->readset_in : op->writeset_in;
  139. for (i=0;i<set->fd_count;++i) {
  140. if (set->fd_array[i]==s) {
  141. if (--set->fd_count != i) {
  142. set->fd_array[i] = set->fd_array[set->fd_count];
  143. }
  144. return (0);
  145. }
  146. }
  147. return (0);
  148. }
  149. #define NEVENT 64
  150. void *
  151. win32_init(void)
  152. {
  153. struct win32op *winop;
  154. size_t size;
  155. if (!(winop = calloc(1, sizeof(struct win32op))))
  156. return NULL;
  157. winop->fd_setsz = NEVENT;
  158. size = FD_SET_ALLOC_SIZE(NEVENT);
  159. if (!(winop->readset_in = malloc(size)))
  160. goto err;
  161. if (!(winop->writeset_in = malloc(size)))
  162. goto err;
  163. if (!(winop->readset_out = malloc(size)))
  164. goto err;
  165. if (!(winop->writeset_out = malloc(size)))
  166. goto err;
  167. if (!(winop->exset_out = malloc(size)))
  168. goto err;
  169. winop->n_events = 0;
  170. winop->n_events_alloc = NEVENT;
  171. if (!(winop->events = malloc(NEVENT*sizeof(struct event*))))
  172. goto err;
  173. winop->readset_in->fd_count = winop->writeset_in->fd_count = 0;
  174. winop->readset_out->fd_count = winop->writeset_out->fd_count
  175. = winop->exset_out->fd_count = 0;
  176. return (winop);
  177. err:
  178. XFREE(winop->readset_in);
  179. XFREE(winop->writeset_in);
  180. XFREE(winop->readset_out);
  181. XFREE(winop->writeset_out);
  182. XFREE(winop->exset_out);
  183. XFREE(winop->events);
  184. XFREE(winop);
  185. return (NULL);
  186. }
  187. int
  188. win32_recalc(struct event_base *base, void *arg, int max)
  189. {
  190. return (signal_recalc());
  191. }
  192. int
  193. win32_insert(void *op, struct event *ev)
  194. {
  195. struct win32op *win32op = op;
  196. int i;
  197. if (ev->ev_events & EV_SIGNAL) {
  198. if (ev->ev_events & (EV_READ|EV_WRITE))
  199. event_errx(1, "%s: EV_SIGNAL incompatible use",
  200. __func__);
  201. if((int)signal(EVENT_SIGNAL(ev), signal_handler) == -1)
  202. return (-1);
  203. return (0);
  204. }
  205. if (!(ev->ev_events & (EV_READ|EV_WRITE)))
  206. return (0);
  207. for (i=0;i<win32op->n_events;++i) {
  208. if(win32op->events[i] == ev) {
  209. event_debug(("%s: Event for %d already inserted.",
  210. __func__, (int)ev->ev_fd));
  211. return (0);
  212. }
  213. }
  214. event_debug(("%s: adding event for %d", __func__, (int)ev->ev_fd));
  215. if (ev->ev_events & EV_READ) {
  216. if (do_fd_set(win32op, ev->ev_fd, 1)<0)
  217. return (-1);
  218. }
  219. if (ev->ev_events & EV_WRITE) {
  220. if (do_fd_set(win32op, ev->ev_fd, 0)<0)
  221. return (-1);
  222. }
  223. if (win32op->n_events_alloc == win32op->n_events) {
  224. size_t sz;
  225. win32op->n_events_alloc *= 2;
  226. sz = sizeof(struct event*)*win32op->n_events_alloc;
  227. if (!(win32op->events = realloc(win32op->events, sz)))
  228. return (-1);
  229. }
  230. win32op->events[win32op->n_events++] = ev;
  231. return (0);
  232. }
  233. int
  234. win32_del(void *op, struct event *ev)
  235. {
  236. struct win32op *win32op = op;
  237. int i, found;
  238. if (ev->ev_events & EV_SIGNAL)
  239. return ((int)signal(EVENT_SIGNAL(ev), SIG_IGN));
  240. found = -1;
  241. for (i=0;i<win32op->n_events;++i) {
  242. if(win32op->events[i] == ev) {
  243. found = i;
  244. break;
  245. }
  246. }
  247. if (found < 0) {
  248. event_debug(("%s: Unable to remove non-inserted event for %d",
  249. __func__, ev->ev_fd));
  250. return (-1);
  251. }
  252. event_debug(("%s: Removing event for %d", __func__, ev->ev_fd));
  253. if (ev->ev_events & EV_READ)
  254. do_fd_clear(win32op, ev->ev_fd, 1);
  255. if (ev->ev_events & EV_WRITE)
  256. do_fd_clear(win32op, ev->ev_fd, 0);
  257. if (i != --win32op->n_events) {
  258. win32op->events[i] = win32op->events[win32op->n_events];
  259. }
  260. return 0;
  261. }
  262. static void
  263. fd_set_copy(struct win_fd_set *out, const struct win_fd_set *in)
  264. {
  265. out->fd_count = in->fd_count;
  266. memcpy(out->fd_array, in->fd_array, in->fd_count * (sizeof(SOCKET)));
  267. }
  268. /*
  269. static void dump_fd_set(struct win_fd_set *s)
  270. {
  271. unsigned int i;
  272. printf("[ ");
  273. for(i=0;i<s->fd_count;++i)
  274. printf("%d ",(int)s->fd_array[i]);
  275. printf("]\n");
  276. }
  277. */
  278. int
  279. win32_dispatch(struct event_base *base, void *op,
  280. struct timeval *tv)
  281. {
  282. struct win32op *win32op = op;
  283. int res = 0;
  284. int i;
  285. int fd_count;
  286. fd_set_copy(win32op->readset_out, win32op->readset_in);
  287. fd_set_copy(win32op->exset_out, win32op->readset_in);
  288. fd_set_copy(win32op->writeset_out, win32op->writeset_in);
  289. fd_count =
  290. (win32op->readset_out->fd_count > win32op->writeset_out->fd_count) ?
  291. win32op->readset_out->fd_count : win32op->writeset_out->fd_count;
  292. if (!fd_count) {
  293. /* Windows doesn't like you to call select() with no sockets */
  294. Sleep(timeval_to_ms(tv));
  295. signal_process();
  296. return (0);
  297. }
  298. res = select(fd_count,
  299. (struct fd_set*)win32op->readset_out,
  300. (struct fd_set*)win32op->writeset_out,
  301. (struct fd_set*)win32op->exset_out, tv);
  302. event_debug(("%s: select returned %d", __func__, res));
  303. if(res <= 0) {
  304. signal_process();
  305. return res;
  306. }
  307. for (i=0;i<win32op->n_events;++i) {
  308. struct event *ev;
  309. int got = 0;
  310. ev = win32op->events[i];
  311. if ((ev->ev_events & EV_READ)) {
  312. if (FD_ISSET(ev->ev_fd, win32op->readset_out) ||
  313. FD_ISSET(ev->ev_fd, win32op->exset_out)) {
  314. got |= EV_READ;
  315. }
  316. }
  317. if ((ev->ev_events & EV_WRITE)) {
  318. if (FD_ISSET(ev->ev_fd, win32op->writeset_out)) {
  319. got |= EV_WRITE;
  320. }
  321. }
  322. if (!got)
  323. continue;
  324. if (!(ev->ev_events & EV_PERSIST)) {
  325. event_del(ev);
  326. }
  327. event_active(ev,got,1);
  328. }
  329. if (signal_recalc() == -1)
  330. return (-1);
  331. return (0);
  332. }
  333. void
  334. win32_dealloc(void *arg)
  335. {
  336. struct win32op *win32op = arg;
  337. if (win32op->readset_in)
  338. free(win32op->readset_in);
  339. if (win32op->writeset_in)
  340. free(win32op->writeset_in);
  341. if (win32op->readset_out)
  342. free(win32op->readset_out);
  343. if (win32op->writeset_out)
  344. free(win32op->writeset_out);
  345. if (win32op->exset_out)
  346. free(win32op->exset_out);
  347. if (win32op->events)
  348. free(win32op->events);
  349. memset(win32op, 0, sizeof(win32op));
  350. free(win32op);
  351. }
  352. static void
  353. signal_handler(int sig)
  354. {
  355. evsigcaught[sig]++;
  356. signal_caught = 1;
  357. }
  358. int
  359. signal_recalc(void)
  360. {
  361. struct event *ev;
  362. /* Reinstall our signal handler. */
  363. TAILQ_FOREACH(ev, &signalqueue, ev_signal_next) {
  364. if((int)signal(EVENT_SIGNAL(ev), signal_handler) == -1)
  365. return (-1);
  366. }
  367. return (0);
  368. }
  369. void
  370. signal_process(void)
  371. {
  372. struct event *ev;
  373. short ncalls;
  374. TAILQ_FOREACH(ev, &signalqueue, ev_signal_next) {
  375. ncalls = evsigcaught[EVENT_SIGNAL(ev)];
  376. if (ncalls) {
  377. if (!(ev->ev_events & EV_PERSIST))
  378. event_del(ev);
  379. event_active(ev, EV_SIGNAL, ncalls);
  380. }
  381. }
  382. memset(evsigcaught, 0, sizeof(evsigcaught));
  383. signal_caught = 0;
  384. }