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 <asm/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(unsigned long); 33 static void nr_t1timer_expiry(unsigned long); 34 static void nr_t2timer_expiry(unsigned long); 35 static void nr_t4timer_expiry(unsigned long); 36 static void nr_idletimer_expiry(unsigned long); 37 38 void nr_init_timers(struct sock *sk) 39 { 40 struct nr_sock *nr = nr_sk(sk); 41 42 setup_timer(&nr->t1timer, nr_t1timer_expiry, (unsigned long)sk); 43 setup_timer(&nr->t2timer, nr_t2timer_expiry, (unsigned long)sk); 44 setup_timer(&nr->t4timer, nr_t4timer_expiry, (unsigned long)sk); 45 setup_timer(&nr->idletimer, nr_idletimer_expiry, (unsigned long)sk); 46 47 /* initialized by sock_init_data */ 48 sk->sk_timer.data = (unsigned long)sk; 49 sk->sk_timer.function = &nr_heartbeat_expiry; 50 } 51 52 void nr_start_t1timer(struct sock *sk) 53 { 54 struct nr_sock *nr = nr_sk(sk); 55 56 mod_timer(&nr->t1timer, jiffies + nr->t1); 57 } 58 59 void nr_start_t2timer(struct sock *sk) 60 { 61 struct nr_sock *nr = nr_sk(sk); 62 63 mod_timer(&nr->t2timer, jiffies + nr->t2); 64 } 65 66 void nr_start_t4timer(struct sock *sk) 67 { 68 struct nr_sock *nr = nr_sk(sk); 69 70 mod_timer(&nr->t4timer, jiffies + nr->t4); 71 } 72 73 void nr_start_idletimer(struct sock *sk) 74 { 75 struct nr_sock *nr = nr_sk(sk); 76 77 if (nr->idle > 0) 78 mod_timer(&nr->idletimer, jiffies + nr->idle); 79 } 80 81 void nr_start_heartbeat(struct sock *sk) 82 { 83 mod_timer(&sk->sk_timer, jiffies + 5 * HZ); 84 } 85 86 void nr_stop_t1timer(struct sock *sk) 87 { 88 del_timer(&nr_sk(sk)->t1timer); 89 } 90 91 void nr_stop_t2timer(struct sock *sk) 92 { 93 del_timer(&nr_sk(sk)->t2timer); 94 } 95 96 void nr_stop_t4timer(struct sock *sk) 97 { 98 del_timer(&nr_sk(sk)->t4timer); 99 } 100 101 void nr_stop_idletimer(struct sock *sk) 102 { 103 del_timer(&nr_sk(sk)->idletimer); 104 } 105 106 void nr_stop_heartbeat(struct sock *sk) 107 { 108 del_timer(&sk->sk_timer); 109 } 110 111 int nr_t1timer_running(struct sock *sk) 112 { 113 return timer_pending(&nr_sk(sk)->t1timer); 114 } 115 116 static void nr_heartbeat_expiry(unsigned long param) 117 { 118 struct sock *sk = (struct sock *)param; 119 struct nr_sock *nr = nr_sk(sk); 120 121 bh_lock_sock(sk); 122 switch (nr->state) { 123 case NR_STATE_0: 124 /* Magic here: If we listen() and a new link dies before it 125 is accepted() it isn't 'dead' so doesn't get removed. */ 126 if (sock_flag(sk, SOCK_DESTROY) || 127 (sk->sk_state == TCP_LISTEN && sock_flag(sk, SOCK_DEAD))) { 128 sock_hold(sk); 129 bh_unlock_sock(sk); 130 nr_destroy_socket(sk); 131 sock_put(sk); 132 return; 133 } 134 break; 135 136 case NR_STATE_3: 137 /* 138 * Check for the state of the receive buffer. 139 */ 140 if (atomic_read(&sk->sk_rmem_alloc) < (sk->sk_rcvbuf / 2) && 141 (nr->condition & NR_COND_OWN_RX_BUSY)) { 142 nr->condition &= ~NR_COND_OWN_RX_BUSY; 143 nr->condition &= ~NR_COND_ACK_PENDING; 144 nr->vl = nr->vr; 145 nr_write_internal(sk, NR_INFOACK); 146 break; 147 } 148 break; 149 } 150 151 nr_start_heartbeat(sk); 152 bh_unlock_sock(sk); 153 } 154 155 static void nr_t2timer_expiry(unsigned long param) 156 { 157 struct sock *sk = (struct sock *)param; 158 struct nr_sock *nr = nr_sk(sk); 159 160 bh_lock_sock(sk); 161 if (nr->condition & NR_COND_ACK_PENDING) { 162 nr->condition &= ~NR_COND_ACK_PENDING; 163 nr_enquiry_response(sk); 164 } 165 bh_unlock_sock(sk); 166 } 167 168 static void nr_t4timer_expiry(unsigned long param) 169 { 170 struct sock *sk = (struct sock *)param; 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(unsigned long param) 178 { 179 struct sock *sk = (struct sock *)param; 180 struct nr_sock *nr = nr_sk(sk); 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(unsigned long param) 206 { 207 struct sock *sk = (struct sock *)param; 208 struct nr_sock *nr = nr_sk(sk); 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