x25_timer.c 3.8 KB

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