Better implementations of Timers T1, T2 and T3
More strictly adhere to the behaviors of Timers T1, T2 and T3 as prescribed in the AX.25 v2.2 Specification, Section 4.4.5 "Timeout Error Recovery" descriptions for Timer T1 and T3, as well as Section 6.7.1.2 "Response Delay Timer T2"
This commit is contained in:
parent
ba3923495e
commit
a08a70151c
2 changed files with 65 additions and 4 deletions
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
#include <patty/timer.h>
|
#include <patty/timer.h>
|
||||||
|
|
||||||
#define PATTY_AX25_SOCK_DEFAULT_KEEPALIVE (1000 * 5)
|
#define PATTY_AX25_SOCK_DEFAULT_KEEPALIVE (1000 * 30)
|
||||||
#define PATTY_AX25_SOCK_DEFAULT_DELAY 3000
|
#define PATTY_AX25_SOCK_DEFAULT_DELAY 3000
|
||||||
|
|
||||||
#define PATTY_AX25_SOCK_DEFAULT_CLASSES \
|
#define PATTY_AX25_SOCK_DEFAULT_CLASSES \
|
||||||
|
|
67
src/server.c
67
src/server.c
|
@ -1214,6 +1214,8 @@ static int handle_sabm(patty_ax25_server *server,
|
||||||
goto error_respond_accept;
|
goto error_respond_accept;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
patty_timer_start(&remote->timer_t3, PATTY_AX25_SOCK_DEFAULT_KEEPALIVE);
|
||||||
|
|
||||||
return reply_ua(iface, frame, PATTY_AX25_FRAME_FINAL);
|
return reply_ua(iface, frame, PATTY_AX25_FRAME_FINAL);
|
||||||
|
|
||||||
error_respond_accept:
|
error_respond_accept:
|
||||||
|
@ -1251,6 +1253,8 @@ static int handle_ua(patty_ax25_server *server,
|
||||||
|
|
||||||
patty_timer_stop(&sock->timer_t1);
|
patty_timer_stop(&sock->timer_t1);
|
||||||
|
|
||||||
|
patty_timer_start(&sock->timer_t3, PATTY_AX25_SOCK_DEFAULT_KEEPALIVE);
|
||||||
|
|
||||||
sock->status = PATTY_AX25_SOCK_ESTABLISHED;
|
sock->status = PATTY_AX25_SOCK_ESTABLISHED;
|
||||||
|
|
||||||
if ((client = client_by_sock(server, sock)) < 0) {
|
if ((client = client_by_sock(server, sock)) < 0) {
|
||||||
|
@ -1317,10 +1321,11 @@ static int handle_i(patty_ax25_server *server,
|
||||||
patty_timer_stop(&sock->timer_t2);
|
patty_timer_stop(&sock->timer_t2);
|
||||||
|
|
||||||
return patty_ax25_sock_send_rr(sock, PATTY_AX25_FRAME_RESPONSE, 0);
|
return patty_ax25_sock_send_rr(sock, PATTY_AX25_FRAME_RESPONSE, 0);
|
||||||
} else {
|
|
||||||
patty_timer_start(&sock->timer_t2, &server->timer, 3000);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
patty_timer_start(&sock->timer_t2, PATTY_AX25_SOCK_DEFAULT_DELAY);
|
||||||
|
patty_timer_start(&sock->timer_t3, PATTY_AX25_SOCK_DEFAULT_KEEPALIVE);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error_write:
|
error_write:
|
||||||
|
@ -1352,6 +1357,29 @@ reply_dm:
|
||||||
return reply_dm(iface, frame, PATTY_AX25_FRAME_FINAL);
|
return reply_dm(iface, frame, PATTY_AX25_FRAME_FINAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int handle_rr(patty_ax25_server *server,
|
||||||
|
patty_ax25_sock *sock,
|
||||||
|
patty_ax25_frame *frame) {
|
||||||
|
if (sock == NULL || frame->pf == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
patty_timer_stop(&sock->timer_t1);
|
||||||
|
|
||||||
|
switch (frame->cr) {
|
||||||
|
case PATTY_AX25_FRAME_COMMAND:
|
||||||
|
return patty_ax25_sock_send_rr(sock, PATTY_AX25_FRAME_RESPONSE, 1);
|
||||||
|
|
||||||
|
case PATTY_AX25_FRAME_RESPONSE:
|
||||||
|
patty_timer_start(&sock->timer_t3, PATTY_AX25_SOCK_DEFAULT_KEEPALIVE);
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int handle_rej(patty_ax25_server *server,
|
static int handle_rej(patty_ax25_server *server,
|
||||||
patty_ax25_sock *sock,
|
patty_ax25_sock *sock,
|
||||||
patty_ax25_frame *frame) {
|
patty_ax25_frame *frame) {
|
||||||
|
@ -1552,6 +1580,7 @@ static int handle_frame(patty_ax25_server *server,
|
||||||
|
|
||||||
switch (frame.type) {
|
switch (frame.type) {
|
||||||
case PATTY_AX25_FRAME_I: return handle_i(server, iface, sock, &frame);
|
case PATTY_AX25_FRAME_I: return handle_i(server, iface, sock, &frame);
|
||||||
|
case PATTY_AX25_FRAME_RR: return handle_rr(server, sock, &frame);
|
||||||
case PATTY_AX25_FRAME_REJ: return handle_rej(server, sock, &frame);
|
case PATTY_AX25_FRAME_REJ: return handle_rej(server, sock, &frame);
|
||||||
case PATTY_AX25_FRAME_SREJ: return handle_srej(server, sock, &frame);
|
case PATTY_AX25_FRAME_SREJ: return handle_srej(server, sock, &frame);
|
||||||
case PATTY_AX25_FRAME_XID: return handle_xid(server, iface, &frame, buf, offset, len);
|
case PATTY_AX25_FRAME_XID: return handle_xid(server, iface, &frame, buf, offset, len);
|
||||||
|
@ -1657,15 +1686,47 @@ static int handle_sock(uint32_t key,
|
||||||
|
|
||||||
case PATTY_AX25_SOCK_ESTABLISHED:
|
case PATTY_AX25_SOCK_ESTABLISHED:
|
||||||
patty_timer_tick(&sock->timer_t2, &server->elapsed);
|
patty_timer_tick(&sock->timer_t2, &server->elapsed);
|
||||||
|
patty_timer_tick(&sock->timer_t3, &server->elapsed);
|
||||||
|
|
||||||
|
if (patty_timer_expired(&sock->timer_t1)) {
|
||||||
|
if (sock->retries) {
|
||||||
|
int ret = patty_ax25_sock_send_rr(sock,
|
||||||
|
PATTY_AX25_FRAME_COMMAND,
|
||||||
|
1);
|
||||||
|
|
||||||
|
sock->retries--;
|
||||||
|
patty_timer_start(&sock->timer_t1, sock->n_ack);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
} else {
|
||||||
|
(void)sock_shutdown(server, sock);
|
||||||
|
|
||||||
|
return sock_close(server, sock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (patty_timer_expired(&sock->timer_t2)) {
|
if (patty_timer_expired(&sock->timer_t2)) {
|
||||||
|
patty_timer_stop(&sock->timer_t2);
|
||||||
|
|
||||||
if (sock->pending) {
|
if (sock->pending) {
|
||||||
sock->pending = 0;
|
sock->pending = 0;
|
||||||
|
|
||||||
return patty_ax25_sock_send_rr(sock, PATTY_AX25_FRAME_RESPONSE, 0);
|
return patty_ax25_sock_send_rr(sock, PATTY_AX25_FRAME_COMMAND, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (patty_timer_expired(&sock->timer_t3)) {
|
||||||
|
/*
|
||||||
|
* AX.25 v.2.2 Section 6.7.1.3 "Inactive Link Timer T3"
|
||||||
|
*/
|
||||||
|
int ret = patty_ax25_sock_send_rr(sock, PATTY_AX25_FRAME_COMMAND, 1);
|
||||||
|
|
||||||
|
patty_timer_stop(&sock->timer_t3);
|
||||||
|
patty_timer_start(&sock->timer_t1, sock->n_ack);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue