1 /* 2 * This program is free software; you can redistribute it and/or modify 3 * it under the terms of the GNU General Public License as published by 4 * the Free Software Foundation; either version 2 of the License, or 5 * (at your option) any later version. 6 * 7 * Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk) 8 * Copyright (C) 2002 Ralf Baechle DO1GRB (ralf@gnu.org) 9 */ 10 #include <linux/errno.h> 11 #include <linux/types.h> 12 #include <linux/socket.h> 13 #include <linux/in.h> 14 #include <linux/kernel.h> 15 #include <linux/jiffies.h> 16 #include <linux/timer.h> 17 #include <linux/string.h> 18 #include <linux/sockios.h> 19 #include <linux/net.h> 20 #include <net/ax25.h> 21 #include <linux/inet.h> 22 #include <linux/netdevice.h> 23 #include <linux/skbuff.h> 24 #include <net/sock.h> 25 #include <net/tcp_states.h> 26 #include <linux/uaccess.h> 27 #include <linux/fcntl.h> 28 #include <linux/mm.h> 29 #include <linux/interrupt.h> 30 #include <net/netrom.h> 31 32 static void nr_heartbeat_expiry(struct timer_list *); 33 static void nr_t1timer_expiry(struct timer_list *); 34 static void nr_t2timer_expiry(struct timer_list *); 35 static void nr_t4timer_expiry(struct timer_list *); 36 static void nr_idletimer_expiry(struct timer_list *); 37 38 void nr_init_timers(struct sock *sk) 39 { 40 struct nr_sock *nr = nr_sk(sk); 41 42 timer_setup(&nr->t1timer, nr_t1timer_expiry, 0); 43 timer_setup(&nr->t2timer, nr_t2timer_expiry, 0); 44 timer_setup(&nr->t4timer, nr_t4timer_expiry, 0); 45 timer_setup(&nr->idletimer, nr_idletimer_expiry, 0); 46 47 /* initialized by sock_init_data */ 48 sk->sk_timer.function = nr_heartbeat_expiry; 49 } 50 51 void nr_start_t1timer(struct sock *sk) 52 { 53 struct nr_sock *nr = nr_sk(sk); 54 55 mod_timer(&nr->t1timer, jiffies + nr->t1); 56 } 57 58 void nr_start_t2timer(struct sock *sk) 59 { 60 struct nr_sock *nr = nr_sk(sk); 61 62 mod_timer(&nr->t2timer, jiffies + nr->t2); 63 } 64 65 void nr_start_t4timer(struct sock *sk) 66 { 67 struct nr_sock *nr = nr_sk(sk); 68 69 mod_timer(&nr->t4timer, jiffies + nr->t4); 70 } 71 72 void nr_start_idletimer(struct sock *sk) 73 { 74 struct nr_sock *nr = nr_sk(sk); 75 76 if (nr->idle > 0) 77 mod_timer(&nr->idletimer, jiffies + nr->idle); 78 } 79 80 void nr_start_heartbeat(struct sock *sk) 81 { 82 mod_timer(&sk->sk_timer, jiffies + 5 * HZ); 83 } 84 85 void nr_stop_t1timer(struct sock *sk) 86 { 87 del_timer(&nr_sk(sk)->t1timer); 88 } 89 90 void nr_stop_t2timer(struct sock *sk) 91 { 92 del_timer(&nr_sk(sk)->t2timer); 93 } 94 95 void nr_stop_t4timer(struct sock *sk) 96 { 97 del_timer(&nr_sk(sk)->t4timer); 98 } 99 100 void nr_stop_idletimer(struct sock *sk) 101 { 102 del_timer(&nr_sk(sk)->idletimer); 103 } 104 105 void nr_stop_heartbeat(struct sock *sk) 106 { 107 del_timer(&sk->sk_timer); 108 } 109 110 int nr_t1timer_running(struct sock *sk) 111 { 112 return timer_pending(&nr_sk(sk)->t1timer); 113 } 114 115 static void nr_heartbeat_expiry(struct timer_list *t) 116 { 117 struct sock *sk = from_timer(sk, t, sk_timer); 118 struct nr_sock *nr = nr_sk(sk); 119 120 bh_lock_sock(sk); 121 switch (nr->state) { 122 case NR_STATE_0: 123 /* Magic here: If we listen() and a new link dies before it 124 is accepted() it isn't 'dead' so doesn't get removed. */ 125 if (sock_flag(sk, SOCK_DESTROY) || 126 (sk->sk_state == TCP_LISTEN && sock_flag(sk, SOCK_DEAD))) { 127 sock_hold(sk); 128 bh_unlock_sock(sk); 129 nr_destroy_socket(sk); 130 sock_put(sk); 131 return; 132 } 133 break; 134 135 case NR_STATE_3: 136 /* 137 * Check for the state of the receive buffer. 138 */ 139 if (atomic_read(&sk->sk_rmem_alloc) < (sk->sk_rcvbuf / 2) && 140 (nr->condition & NR_COND_OWN_RX_BUSY)) { 141 nr->condition &= ~NR_COND_OWN_RX_BUSY; 142 nr->condition &= ~NR_COND_ACK_PENDING; 143 nr->vl = nr->vr; 144 nr_write_internal(sk, NR_INFOACK); 145 break; 146 } 147 break; 148 } 149 150 nr_start_heartbeat(sk); 151 bh_unlock_sock(sk); 152 } 153 154 static void nr_t2timer_expiry(struct timer_list *t) 155 { 156 struct nr_sock *nr = from_timer(nr, t, t2timer); 157 struct sock *sk = &nr->sock; 158 159 bh_lock_sock(sk); 160 if (nr->condition & NR_COND_ACK_PENDING) { 161 nr->condition &= ~NR_COND_ACK_PENDING; 162 nr_enquiry_response(sk); 163 } 164 bh_unlock_sock(sk); 165 } 166 167 static void nr_t4timer_expiry(struct timer_list *t) 168 { 169 struct nr_sock *nr = from_timer(nr, t, t4timer); 170 struct sock *sk = &nr->sock; 171 172 bh_lock_sock(sk); 173 nr_sk(sk)->condition &= ~NR_COND_PEER_RX_BUSY; 174 bh_unlock_sock(sk); 175 } 176 177 static void nr_idletimer_expiry(struct timer_list *t) 178 { 179 struct nr_sock *nr = from_timer(nr, t, idletimer); 180 struct sock *sk = &nr->sock; 181 182 bh_lock_sock(sk); 183 184 nr_clear_queues(sk); 185 186 nr->n2count = 0; 187 nr_write_internal(sk, NR_DISCREQ); 188 nr->state = NR_STATE_2; 189 190 nr_start_t1timer(sk); 191 nr_stop_t2timer(sk); 192 nr_stop_t4timer(sk); 193 194 sk->sk_state = TCP_CLOSE; 195 sk->sk_err = 0; 196 sk->sk_shutdown |= SEND_SHUTDOWN; 197 198 if (!sock_flag(sk, SOCK_DEAD)) { 199 sk->sk_state_change(sk); 200 sock_set_flag(sk, SOCK_DEAD); 201 } 202 bh_unlock_sock(sk); 203 } 204 205 static void nr_t1timer_expiry(struct timer_list *t) 206 { 207 struct nr_sock *nr = from_timer(nr, t, t1timer); 208 struct sock *sk = &nr->sock; 209 210 bh_lock_sock(sk); 211 switch (nr->state) { 212 case NR_STATE_1: 213 if (nr->n2count == nr->n2) { 214 nr_disconnect(sk, ETIMEDOUT); 215 bh_unlock_sock(sk); 216 return; 217 } else { 218 nr->n2count++; 219 nr_write_internal(sk, NR_CONNREQ); 220 } 221 break; 222 223 case NR_STATE_2: 224 if (nr->n2count == nr->n2) { 225 nr_disconnect(sk, ETIMEDOUT); 226 bh_unlock_sock(sk); 227 return; 228 } else { 229 nr->n2count++; 230 nr_write_internal(sk, NR_DISCREQ); 231 } 232 break; 233 234 case NR_STATE_3: 235 if (nr->n2count == nr->n2) { 236 nr_disconnect(sk, ETIMEDOUT); 237 bh_unlock_sock(sk); 238 return; 239 } else { 240 nr->n2count++; 241 nr_requeue_frames(sk); 242 } 243 break; 244 } 245 246 nr_start_t1timer(sk); 247 bh_unlock_sock(sk); 248 } 249