pinger.c 1.7 KB

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