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/system.h> 27 #include <linux/fcntl.h> 28 #include <linux/mm.h> 29 #include <linux/interrupt.h> 30 #include <net/rose.h> 31 32 static void rose_heartbeat_expiry(unsigned long); 33 static void rose_timer_expiry(unsigned long); 34 static void rose_idletimer_expiry(unsigned long); 35 36 void rose_start_heartbeat(struct sock *sk) 37 { 38 del_timer(&sk->sk_timer); 39 40 sk->sk_timer.data = (unsigned long)sk; 41 sk->sk_timer.function = &rose_heartbeat_expiry; 42 sk->sk_timer.expires = jiffies + 5 * HZ; 43 44 add_timer(&sk->sk_timer); 45 } 46 47 void rose_start_t1timer(struct sock *sk) 48 { 49 struct rose_sock *rose = rose_sk(sk); 50 51 del_timer(&rose->timer); 52 53 rose->timer.data = (unsigned long)sk; 54 rose->timer.function = &rose_timer_expiry; 55 rose->timer.expires = jiffies + rose->t1; 56 57 add_timer(&rose->timer); 58 } 59 60 void rose_start_t2timer(struct sock *sk) 61 { 62 struct rose_sock *rose = rose_sk(sk); 63 64 del_timer(&rose->timer); 65 66 rose->timer.data = (unsigned long)sk; 67 rose->timer.function = &rose_timer_expiry; 68 rose->timer.expires = jiffies + rose->t2; 69 70 add_timer(&rose->timer); 71 } 72 73 void rose_start_t3timer(struct sock *sk) 74 { 75 struct rose_sock *rose = rose_sk(sk); 76 77 del_timer(&rose->timer); 78 79 rose->timer.data = (unsigned long)sk; 80 rose->timer.function = &rose_timer_expiry; 81 rose->timer.expires = jiffies + rose->t3; 82 83 add_timer(&rose->timer); 84 } 85 86 void rose_start_hbtimer(struct sock *sk) 87 { 88 struct rose_sock *rose = rose_sk(sk); 89 90 del_timer(&rose->timer); 91 92 rose->timer.data = (unsigned long)sk; 93 rose->timer.function = &rose_timer_expiry; 94 rose->timer.expires = jiffies + rose->hb; 95 96 add_timer(&rose->timer); 97 } 98 99 void rose_start_idletimer(struct sock *sk) 100 { 101 struct rose_sock *rose = rose_sk(sk); 102 103 del_timer(&rose->idletimer); 104 105 if (rose->idle > 0) { 106 rose->idletimer.data = (unsigned long)sk; 107 rose->idletimer.function = &rose_idletimer_expiry; 108 rose->idletimer.expires = jiffies + rose->idle; 109 110 add_timer(&rose->idletimer); 111 } 112 } 113 114 void rose_stop_heartbeat(struct sock *sk) 115 { 116 del_timer(&sk->sk_timer); 117 } 118 119 void rose_stop_timer(struct sock *sk) 120 { 121 del_timer(&rose_sk(sk)->timer); 122 } 123 124 void rose_stop_idletimer(struct sock *sk) 125 { 126 del_timer(&rose_sk(sk)->idletimer); 127 } 128 129 static void rose_heartbeat_expiry(unsigned long param) 130 { 131 struct sock *sk = (struct sock *)param; 132 struct rose_sock *rose = rose_sk(sk); 133 134 bh_lock_sock(sk); 135 switch (rose->state) { 136 case ROSE_STATE_0: 137 /* Magic here: If we listen() and a new link dies before it 138 is accepted() it isn't 'dead' so doesn't get removed. */ 139 if (sock_flag(sk, SOCK_DESTROY) || 140 (sk->sk_state == TCP_LISTEN && sock_flag(sk, SOCK_DEAD))) { 141 bh_unlock_sock(sk); 142 rose_destroy_socket(sk); 143 return; 144 } 145 break; 146 147 case ROSE_STATE_3: 148 /* 149 * Check for the state of the receive buffer. 150 */ 151 if (atomic_read(&sk->sk_rmem_alloc) < (sk->sk_rcvbuf / 2) && 152 (rose->condition & ROSE_COND_OWN_RX_BUSY)) { 153 rose->condition &= ~ROSE_COND_OWN_RX_BUSY; 154 rose->condition &= ~ROSE_COND_ACK_PENDING; 155 rose->vl = rose->vr; 156 rose_write_internal(sk, ROSE_RR); 157 rose_stop_timer(sk); /* HB */ 158 break; 159 } 160 break; 161 } 162 163 rose_start_heartbeat(sk); 164 bh_unlock_sock(sk); 165 } 166 167 static void rose_timer_expiry(unsigned long param) 168 { 169 struct sock *sk = (struct sock *)param; 170 struct rose_sock *rose = rose_sk(sk); 171 172 bh_lock_sock(sk); 173 switch (rose->state) { 174 case ROSE_STATE_1: /* T1 */ 175 case ROSE_STATE_4: /* T2 */ 176 rose_write_internal(sk, ROSE_CLEAR_REQUEST); 177 rose->state = ROSE_STATE_2; 178 rose_start_t3timer(sk); 179 break; 180 181 case ROSE_STATE_2: /* T3 */ 182 rose->neighbour->use--; 183 rose_disconnect(sk, ETIMEDOUT, -1, -1); 184 break; 185 186 case ROSE_STATE_3: /* HB */ 187 if (rose->condition & ROSE_COND_ACK_PENDING) { 188 rose->condition &= ~ROSE_COND_ACK_PENDING; 189 rose_enquiry_response(sk); 190 } 191 break; 192 } 193 bh_unlock_sock(sk); 194 } 195 196 static void rose_idletimer_expiry(unsigned long param) 197 { 198 struct sock *sk = (struct sock *)param; 199 200 bh_lock_sock(sk); 201 rose_clear_queues(sk); 202 203 rose_write_internal(sk, ROSE_CLEAR_REQUEST); 204 rose_sk(sk)->state = ROSE_STATE_2; 205 206 rose_start_t3timer(sk); 207 208 sk->sk_state = TCP_CLOSE; 209 sk->sk_err = 0; 210 sk->sk_shutdown |= SEND_SHUTDOWN; 211 212 if (!sock_flag(sk, SOCK_DEAD)) { 213 sk->sk_state_change(sk); 214 sock_set_flag(sk, SOCK_DEAD); 215 } 216 bh_unlock_sock(sk); 217 } 218