xref: /linux/net/ax25/ax25_ds_timer.c (revision 9cf621bd5fcbeadc2804951d13d487e22e95b363)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  *
4  * Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
5  * Copyright (C) Joerg Reuter DL1BKE (jreuter@yaina.de)
6  */
7 #include <linux/errno.h>
8 #include <linux/types.h>
9 #include <linux/socket.h>
10 #include <linux/spinlock.h>
11 #include <linux/in.h>
12 #include <linux/kernel.h>
13 #include <linux/jiffies.h>
14 #include <linux/timer.h>
15 #include <linux/string.h>
16 #include <linux/sockios.h>
17 #include <linux/net.h>
18 #include <net/tcp_states.h>
19 #include <net/ax25.h>
20 #include <linux/inet.h>
21 #include <linux/netdevice.h>
22 #include <linux/skbuff.h>
23 #include <net/sock.h>
24 #include <linux/uaccess.h>
25 #include <linux/fcntl.h>
26 #include <linux/mm.h>
27 #include <linux/interrupt.h>
28 
29 static void ax25_ds_timeout(struct timer_list *);
30 
31 /*
32  *	Add DAMA slave timeout timer to timer list.
33  *	Unlike the connection based timers the timeout function gets
34  *	triggered every second. Please note that NET_AX25_DAMA_SLAVE_TIMEOUT
35  *	(aka /proc/sys/net/ax25/{dev}/dama_slave_timeout) is still in
36  *	1/10th of a second.
37  */
38 
39 void ax25_ds_setup_timer(ax25_dev *ax25_dev)
40 {
41 	timer_setup(&ax25_dev->dama.slave_timer, ax25_ds_timeout, 0);
42 }
43 
44 void ax25_ds_del_timer(ax25_dev *ax25_dev)
45 {
46 	if (ax25_dev)
47 		del_timer(&ax25_dev->dama.slave_timer);
48 }
49 
50 void ax25_ds_set_timer(ax25_dev *ax25_dev)
51 {
52 	if (ax25_dev == NULL)		/* paranoia */
53 		return;
54 
55 	ax25_dev->dama.slave_timeout =
56 		msecs_to_jiffies(ax25_dev->values[AX25_VALUES_DS_TIMEOUT]) / 10;
57 	mod_timer(&ax25_dev->dama.slave_timer, jiffies + HZ);
58 	return;
59 }
60 
61 /*
62  *	DAMA Slave Timeout
63  *	Silently discard all (slave) connections in case our master forgot us...
64  */
65 
66 static void ax25_ds_timeout(struct timer_list *t)
67 {
68 	ax25_dev *ax25_dev = from_timer(ax25_dev, t, dama.slave_timer);
69 	ax25_cb *ax25;
70 
71 	if (ax25_dev == NULL || !ax25_dev->dama.slave)
72 		return;			/* Yikes! */
73 
74 	if (!ax25_dev->dama.slave_timeout || --ax25_dev->dama.slave_timeout) {
75 		ax25_ds_set_timer(ax25_dev);
76 		return;
77 	}
78 
79 	spin_lock(&ax25_list_lock);
80 	ax25_for_each(ax25, &ax25_list) {
81 		if (ax25->ax25_dev != ax25_dev || !(ax25->condition & AX25_COND_DAMA_MODE))
82 			continue;
83 
84 		ax25_send_control(ax25, AX25_DISC, AX25_POLLON, AX25_COMMAND);
85 		ax25_disconnect(ax25, ETIMEDOUT);
86 	}
87 	spin_unlock(&ax25_list_lock);
88 
89 	ax25_dev_dama_off(ax25_dev);
90 }
91 
92 void ax25_ds_heartbeat_expiry(ax25_cb *ax25)
93 {
94 	struct sock *sk=ax25->sk;
95 
96 	if (sk)
97 		bh_lock_sock(sk);
98 
99 	switch (ax25->state) {
100 
101 	case AX25_STATE_0:
102 	case AX25_STATE_2:
103 		/* Magic here: If we listen() and a new link dies before it
104 		   is accepted() it isn't 'dead' so doesn't get removed. */
105 		if (!sk || sock_flag(sk, SOCK_DESTROY) ||
106 		    (sk->sk_state == TCP_LISTEN &&
107 		     sock_flag(sk, SOCK_DEAD))) {
108 			if (sk) {
109 				sock_hold(sk);
110 				ax25_destroy_socket(ax25);
111 				bh_unlock_sock(sk);
112 				/* Ungrab socket and destroy it */
113 				sock_put(sk);
114 			} else
115 				ax25_destroy_socket(ax25);
116 			return;
117 		}
118 		break;
119 
120 	case AX25_STATE_3:
121 		/*
122 		 * Check the state of the receive buffer.
123 		 */
124 		if (sk != NULL) {
125 			if (atomic_read(&sk->sk_rmem_alloc) <
126 			    (sk->sk_rcvbuf >> 1) &&
127 			    (ax25->condition & AX25_COND_OWN_RX_BUSY)) {
128 				ax25->condition &= ~AX25_COND_OWN_RX_BUSY;
129 				ax25->condition &= ~AX25_COND_ACK_PENDING;
130 				break;
131 			}
132 		}
133 		break;
134 	}
135 
136 	if (sk)
137 		bh_unlock_sock(sk);
138 
139 	ax25_start_heartbeat(ax25);
140 }
141 
142 /* dl1bke 960114: T3 works much like the IDLE timeout, but
143  *                gets reloaded with every frame for this
144  *		  connection.
145  */
146 void ax25_ds_t3timer_expiry(ax25_cb *ax25)
147 {
148 	ax25_send_control(ax25, AX25_DISC, AX25_POLLON, AX25_COMMAND);
149 	ax25_dama_off(ax25);
150 	ax25_disconnect(ax25, ETIMEDOUT);
151 }
152 
153 /* dl1bke 960228: close the connection when IDLE expires.
154  *		  unlike T3 this timer gets reloaded only on
155  *		  I frames.
156  */
157 void ax25_ds_idletimer_expiry(ax25_cb *ax25)
158 {
159 	ax25_clear_queues(ax25);
160 
161 	ax25->n2count = 0;
162 	ax25->state = AX25_STATE_2;
163 
164 	ax25_calculate_t1(ax25);
165 	ax25_start_t1timer(ax25);
166 	ax25_stop_t3timer(ax25);
167 
168 	if (ax25->sk != NULL) {
169 		bh_lock_sock(ax25->sk);
170 		ax25->sk->sk_state     = TCP_CLOSE;
171 		ax25->sk->sk_err       = 0;
172 		ax25->sk->sk_shutdown |= SEND_SHUTDOWN;
173 		if (!sock_flag(ax25->sk, SOCK_DEAD)) {
174 			ax25->sk->sk_state_change(ax25->sk);
175 			sock_set_flag(ax25->sk, SOCK_DEAD);
176 		}
177 		bh_unlock_sock(ax25->sk);
178 	}
179 }
180 
181 /* dl1bke 960114: The DAMA protocol requires to send data and SABM/DISC
182  *                within the poll of any connected channel. Remember
183  *                that we are not allowed to send anything unless we
184  *                get polled by the Master.
185  *
186  *                Thus we'll have to do parts of our T1 handling in
187  *                ax25_enquiry_response().
188  */
189 void ax25_ds_t1_timeout(ax25_cb *ax25)
190 {
191 	switch (ax25->state) {
192 	case AX25_STATE_1:
193 		if (ax25->n2count == ax25->n2) {
194 			if (ax25->modulus == AX25_MODULUS) {
195 				ax25_disconnect(ax25, ETIMEDOUT);
196 				return;
197 			} else {
198 				ax25->modulus = AX25_MODULUS;
199 				ax25->window  = ax25->ax25_dev->values[AX25_VALUES_WINDOW];
200 				ax25->n2count = 0;
201 				ax25_send_control(ax25, AX25_SABM, AX25_POLLOFF, AX25_COMMAND);
202 			}
203 		} else {
204 			ax25->n2count++;
205 			if (ax25->modulus == AX25_MODULUS)
206 				ax25_send_control(ax25, AX25_SABM, AX25_POLLOFF, AX25_COMMAND);
207 			else
208 				ax25_send_control(ax25, AX25_SABME, AX25_POLLOFF, AX25_COMMAND);
209 		}
210 		break;
211 
212 	case AX25_STATE_2:
213 		if (ax25->n2count == ax25->n2) {
214 			ax25_send_control(ax25, AX25_DISC, AX25_POLLON, AX25_COMMAND);
215 			if (!sock_flag(ax25->sk, SOCK_DESTROY))
216 				ax25_disconnect(ax25, ETIMEDOUT);
217 			return;
218 		} else {
219 			ax25->n2count++;
220 		}
221 		break;
222 
223 	case AX25_STATE_3:
224 		if (ax25->n2count == ax25->n2) {
225 			ax25_send_control(ax25, AX25_DM, AX25_POLLON, AX25_RESPONSE);
226 			ax25_disconnect(ax25, ETIMEDOUT);
227 			return;
228 		} else {
229 			ax25->n2count++;
230 		}
231 		break;
232 	}
233 
234 	ax25_calculate_t1(ax25);
235 	ax25_start_t1timer(ax25);
236 }
237