x25_timer.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * X.25 Packet Layer release 002
  4. *
  5. * This is ALPHA test software. This code may break your machine,
  6. * randomly fail to work with new releases, misbehave and/or generally
  7. * screw up. It might even work.
  8. *
  9. * This code REQUIRES 2.1.15 or higher
  10. *
  11. * History
  12. * X.25 001 Jonathan Naylor Started coding.
  13. * X.25 002 Jonathan Naylor New timer architecture.
  14. * Centralised disconnection processing.
  15. */
  16. #include <linux/errno.h>
  17. #include <linux/jiffies.h>
  18. #include <linux/timer.h>
  19. #include <net/sock.h>
  20. #include <net/tcp_states.h>
  21. #include <net/x25.h>
  22. static void x25_heartbeat_expiry(struct timer_list *t);
  23. static void x25_timer_expiry(struct timer_list *t);
  24. void x25_init_timers(struct sock *sk)
  25. {
  26. struct x25_sock *x25 = x25_sk(sk);
  27. timer_setup(&x25->timer, x25_timer_expiry, 0);
  28. /* initialized by sock_init_data */
  29. sk->sk_timer.function = x25_heartbeat_expiry;
  30. }
  31. void x25_start_heartbeat(struct sock *sk)
  32. {
  33. mod_timer(&sk->sk_timer, jiffies + 5 * HZ);
  34. }
  35. void x25_stop_heartbeat(struct sock *sk)
  36. {
  37. del_timer(&sk->sk_timer);
  38. }
  39. void x25_start_t2timer(struct sock *sk)
  40. {
  41. struct x25_sock *x25 = x25_sk(sk);
  42. mod_timer(&x25->timer, jiffies + x25->t2);
  43. }
  44. void x25_start_t21timer(struct sock *sk)
  45. {
  46. struct x25_sock *x25 = x25_sk(sk);
  47. mod_timer(&x25->timer, jiffies + x25->t21);
  48. }
  49. void x25_start_t22timer(struct sock *sk)
  50. {
  51. struct x25_sock *x25 = x25_sk(sk);
  52. mod_timer(&x25->timer, jiffies + x25->t22);
  53. }
  54. void x25_start_t23timer(struct sock *sk)
  55. {
  56. struct x25_sock *x25 = x25_sk(sk);
  57. mod_timer(&x25->timer, jiffies + x25->t23);
  58. }
  59. void x25_stop_timer(struct sock *sk)
  60. {
  61. del_timer(&x25_sk(sk)->timer);
  62. }
  63. unsigned long x25_display_timer(struct sock *sk)
  64. {
  65. struct x25_sock *x25 = x25_sk(sk);
  66. if (!timer_pending(&x25->timer))
  67. return 0;
  68. return x25->timer.expires - jiffies;
  69. }
  70. static void x25_heartbeat_expiry(struct timer_list *t)
  71. {
  72. struct sock *sk = from_timer(sk, t, sk_timer);
  73. bh_lock_sock(sk);
  74. if (sock_owned_by_user(sk)) /* can currently only occur in state 3 */
  75. goto restart_heartbeat;
  76. switch (x25_sk(sk)->state) {
  77. case X25_STATE_0:
  78. /*
  79. * Magic here: If we listen() and a new link dies
  80. * before it is accepted() it isn't 'dead' so doesn't
  81. * get removed.
  82. */
  83. if (sock_flag(sk, SOCK_DESTROY) ||
  84. (sk->sk_state == TCP_LISTEN &&
  85. sock_flag(sk, SOCK_DEAD))) {
  86. bh_unlock_sock(sk);
  87. x25_destroy_socket_from_timer(sk);
  88. return;
  89. }
  90. break;
  91. case X25_STATE_3:
  92. /*
  93. * Check for the state of the receive buffer.
  94. */
  95. x25_check_rbuf(sk);
  96. break;
  97. }
  98. restart_heartbeat:
  99. x25_start_heartbeat(sk);
  100. bh_unlock_sock(sk);
  101. }
  102. /*
  103. * Timer has expired, it may have been T2, T21, T22, or T23. We can tell
  104. * by the state machine state.
  105. */
  106. static inline void x25_do_timer_expiry(struct sock * sk)
  107. {
  108. struct x25_sock *x25 = x25_sk(sk);
  109. switch (x25->state) {
  110. case X25_STATE_3: /* T2 */
  111. if (x25->condition & X25_COND_ACK_PENDING) {
  112. x25->condition &= ~X25_COND_ACK_PENDING;
  113. x25_enquiry_response(sk);
  114. }
  115. break;
  116. case X25_STATE_1: /* T21 */
  117. case X25_STATE_4: /* T22 */
  118. x25_write_internal(sk, X25_CLEAR_REQUEST);
  119. x25->state = X25_STATE_2;
  120. x25_start_t23timer(sk);
  121. break;
  122. case X25_STATE_2: /* T23 */
  123. x25_disconnect(sk, ETIMEDOUT, 0, 0);
  124. break;
  125. }
  126. }
  127. static void x25_timer_expiry(struct timer_list *t)
  128. {
  129. struct x25_sock *x25 = from_timer(x25, t, timer);
  130. struct sock *sk = &x25->sk;
  131. bh_lock_sock(sk);
  132. if (sock_owned_by_user(sk)) { /* can currently only occur in state 3 */
  133. if (x25_sk(sk)->state == X25_STATE_3)
  134. x25_start_t2timer(sk);
  135. } else
  136. x25_do_timer_expiry(sk);
  137. bh_unlock_sock(sk);
  138. }