pinger.c 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. /*
  2. * pinger.c: centralised module that deals with sending TS_PING
  3. * keepalives, to avoid replicating this code in multiple backends.
  4. */
  5. #include "putty.h"
  6. struct pinger_tag {
  7. int interval;
  8. int pending;
  9. unsigned long when_set, next;
  10. Backend *back;
  11. void *backhandle;
  12. };
  13. static void pinger_schedule(Pinger pinger);
  14. static void pinger_timer(void *ctx, unsigned long now)
  15. {
  16. Pinger pinger = (Pinger)ctx;
  17. if (pinger->pending && now == pinger->next) {
  18. pinger->back->special(pinger->backhandle, TS_PING);
  19. pinger->pending = FALSE;
  20. pinger_schedule(pinger);
  21. }
  22. }
  23. static void pinger_schedule(Pinger pinger)
  24. {
  25. unsigned long next;
  26. if (!pinger->interval) {
  27. pinger->pending = FALSE; /* cancel any pending ping */
  28. return;
  29. }
  30. next = schedule_timer(pinger->interval * TICKSPERSEC,
  31. pinger_timer, pinger);
  32. if (!pinger->pending ||
  33. (next - pinger->when_set) < (pinger->next - pinger->when_set)) {
  34. pinger->next = next;
  35. pinger->when_set = timing_last_clock();
  36. pinger->pending = TRUE;
  37. }
  38. }
  39. Pinger pinger_new(Conf *conf, Backend *back, void *backhandle)
  40. {
  41. Pinger pinger = snew(struct pinger_tag);
  42. pinger->interval = conf_get_int(conf, CONF_ping_interval);
  43. pinger->pending = FALSE;
  44. pinger->back = back;
  45. pinger->backhandle = backhandle;
  46. pinger_schedule(pinger);
  47. return pinger;
  48. }
  49. void pinger_reconfig(Pinger pinger, Conf *oldconf, Conf *newconf)
  50. {
  51. int newinterval = conf_get_int(newconf, CONF_ping_interval);
  52. if (conf_get_int(oldconf, CONF_ping_interval) != newinterval) {
  53. pinger->interval = newinterval;
  54. pinger_schedule(pinger);
  55. }
  56. }
  57. void pinger_free(Pinger pinger)
  58. {
  59. expire_timer_context(pinger);
  60. sfree(pinger);
  61. }