Skip to content

Commit 6aaf4c2

Browse files
committed
Implements some timeouts.
1 parent 832cee6 commit 6aaf4c2

File tree

1 file changed

+71
-17
lines changed

1 file changed

+71
-17
lines changed

src/ncp.c

Lines changed: 71 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@
1515
#include "imp.h"
1616
#include "wire.h"
1717

18+
#define RFNM_TIMEOUT 10
19+
#define RRP_TIMEOUT 20
20+
#define ERP_TIMEOUT 20
21+
1822
#define IMP_REGULAR 0
1923
#define IMP_LEADER_ERROR 1
2024
#define IMP_DOWN 2
@@ -71,6 +75,7 @@ static int fd;
7175
static struct sockaddr_un server;
7276
static struct sockaddr_un client;
7377
static socklen_t len;
78+
static unsigned long time_unit;
7479

7580
typedef struct
7681
{
@@ -86,9 +91,11 @@ struct
8691
int listen;
8792
struct { int link, size; uint32_t lsock, rsock; } rcv, snd;
8893
void (*rrp_callback) (int);
89-
void (*rrp_timeout) (int);
94+
void (*rrp_timed_out) (int);
95+
unsigned long rrp_timeout;
9096
void (*rfnm_callback) (int);
91-
void (*rfnm_timeout) (int);
97+
void (*rfnm_timed_out) (int);
98+
unsigned long rfnm_timeout;
9299
} connection[CONNECTIONS];
93100

94101
struct
@@ -104,6 +111,7 @@ static struct
104111
#define HOST_ALIVE 0001
105112

106113
client_t echo;
114+
unsigned long erp_timeout;
107115
int outstanding_rfnm;
108116
} hosts[256];
109117

@@ -128,10 +136,12 @@ static const char *type_name[] =
128136
static uint8_t packet[200];
129137
static uint8_t app[200];
130138

131-
static void when_rrp (int i, void (*cb) (int), void (*to) (int))
139+
static void when_rrp (int i, void (*cb) (int),
140+
unsigned timeout, void (*to) (int))
132141
{
133142
connection[i].rrp_callback = cb;
134-
connection[i].rrp_timeout = to;
143+
connection[i].rrp_timed_out = to;
144+
connection[i].rrp_timeout = time_unit + timeout;
135145
}
136146

137147
static void check_rrp (int host)
@@ -141,18 +151,20 @@ static void check_rrp (int host)
141151
for (i = 0; i < CONNECTIONS; i++) {
142152
if (connection[i].host != host)
143153
continue;
144-
if (connection[i].rrp_callback == NULL)
145-
continue;
146154
cb = connection[i].rrp_callback;
155+
if (cb == NULL)
156+
continue;
147157
connection[i].rrp_callback = NULL;
148158
cb (i);
149159
}
150160
}
151161

152-
static void when_rfnm (int i, void (*cb) (int), void (*to) (int))
162+
static void when_rfnm (int i, void (*cb) (int),
163+
unsigned timeout, void (*to) (int))
153164
{
154165
connection[i].rfnm_callback = cb;
155-
connection[i].rfnm_timeout = to;
166+
connection[i].rfnm_timed_out = to;
167+
connection[i].rfnm_timeout = time_unit + timeout;
156168
}
157169

158170
static void check_rfnm (int host)
@@ -312,6 +324,8 @@ static int make_open (int host,
312324
connection[i].snd.lsock = snd_lsock;
313325
connection[i].snd.rsock = snd_rsock;
314326
connection[i].flags = 0;
327+
connection[i].rrp_timeout = time_unit - 1;
328+
connection[i].rfnm_timeout = time_unit - 1;
315329

316330
return i;
317331
}
@@ -730,12 +744,13 @@ static int process_cls (uint8_t source, uint8_t *data)
730744

731745
static void just_drop (int i)
732746
{
747+
fprintf (stderr, "NCP: RFNM timeout, drop connection %d.\n", i);
733748
destroy (i);
734749
}
735750

736751
static void cls_and_drop (int i)
737752
{
738-
fprintf (stderr, "NCP: Timeout, drop connection %d.\n", i);
753+
fprintf (stderr, "NCP: RFNM timeout, close connection %d.\n", i);
739754
ncp_cls (connection[i].host,
740755
connection[i].snd.lsock, connection[i].snd.rsock);
741756
ncp_cls (connection[i].host,
@@ -764,7 +779,7 @@ static void send_str_and_rts (int i)
764779
connection[i].snd.rsock, connection[i].snd.size);
765780
connection[i].flags |= CONN_SENT_STR;
766781
}
767-
when_rfnm (i, send_rts, cls_and_drop);
782+
when_rfnm (i, send_rts, RFNM_TIMEOUT, cls_and_drop);
768783
check_rfnm (connection[i].host);
769784
}
770785

@@ -825,8 +840,8 @@ static int process_all (uint8_t source, uint8_t *data)
825840
fprintf (stderr, "NCP: New connection %d.\n", j);
826841
connection[j].snd.size = 8;
827842
connection[j].rcv.link = 44;
828-
when_rfnm (j, send_str_and_rts, cls_and_drop);
829-
when_rfnm (i, send_cls_snd, just_drop);
843+
when_rfnm (j, send_str_and_rts, RFNM_TIMEOUT, cls_and_drop);
844+
when_rfnm (i, send_cls_snd, RFNM_TIMEOUT, just_drop);
830845
check_rfnm (source);
831846
}
832847
return 7;
@@ -1062,7 +1077,7 @@ static void process_regular (uint8_t *packet, int length)
10621077
if (connection[i].flags & CONN_CLIENT) {
10631078
uint32_t s = sock (&packet[9]);
10641079
fprintf (stderr, "NCP: ICP link %u socket %u.\n", link, s);
1065-
when_rfnm (i, send_cls_rcv, just_drop);
1080+
when_rfnm (i, send_cls_rcv, RFNM_TIMEOUT, just_drop);
10661081
connection[i].snd.rsock = s;
10671082

10681083
j = find_rcv_sockets (source, connection[i].rcv.lsock+2, s+1);
@@ -1075,7 +1090,7 @@ static void process_regular (uint8_t *packet, int length)
10751090
connection[j].snd.size = 8;
10761091
connection[j].rcv.link = 45;
10771092
fprintf (stderr, "NCP: New connection %d.\n", j);
1078-
when_rfnm (j, send_str_and_rts, cls_and_drop);
1093+
when_rfnm (j, send_str_and_rts, RFNM_TIMEOUT, cls_and_drop);
10791094
}
10801095
connection[j].listen = connection[i].rcv.rsock;
10811096
connection[j].flags |= CONN_GOT_SOCKET;
@@ -1269,6 +1284,7 @@ static void app_echo (void)
12691284

12701285
memcpy (&hosts[host].echo.addr, &client, len);
12711286
hosts[host].echo.len = len;
1287+
hosts[host].erp_timeout = time_unit + ERP_TIMEOUT;
12721288
ncp_eco (host, app[2]);
12731289
}
12741290

@@ -1281,6 +1297,7 @@ static void app_open_send_rts (int i)
12811297

12821298
static void app_open_fail (int i)
12831299
{
1300+
fprintf (stderr, "NCP: Timed out waiting for RRP.\n");
12841301
reply_open (connection[i].host, connection[i].rcv.rsock, 255);
12851302
}
12861303

@@ -1305,7 +1322,7 @@ static void app_open (void)
13051322
// We haven't communicated with this host yet.
13061323
ncp_rst (host);
13071324
// Wait for RRP, then send RTS.
1308-
when_rrp (i, app_open_send_rts, app_open_fail);
1325+
when_rrp (i, app_open_send_rts, RRP_TIMEOUT, app_open_fail);
13091326
} else {
13101327
// Ok to send RTS directly.
13111328
app_open_send_rts (i);
@@ -1417,6 +1434,35 @@ static void application (void)
14171434
}
14181435
}
14191436

1437+
static void tick (void)
1438+
{
1439+
void (*to) (int);
1440+
int i;
1441+
time_unit++;
1442+
for (i = 0; i < CONNECTIONS; i++) {
1443+
to = connection[i].rrp_timed_out;
1444+
if (to != NULL && connection[i].rrp_timeout == time_unit) {
1445+
connection[i].rrp_timed_out = NULL;
1446+
connection[i].rrp_timeout = time_unit - 1;
1447+
to (i);
1448+
}
1449+
to = connection[i].rfnm_timed_out;
1450+
if (to != NULL && connection[i].rfnm_timeout == time_unit) {
1451+
connection[i].rfnm_timed_out = NULL;
1452+
connection[i].rrp_timeout = time_unit - 1;
1453+
to (i);
1454+
}
1455+
}
1456+
for (i = 0; i < 256; i++) {
1457+
if (hosts[i].echo.len == 0)
1458+
continue;
1459+
if (hosts[i].erp_timeout != time_unit)
1460+
continue;
1461+
reply_echo (i, 0, 0x20);
1462+
hosts[i].echo.len = 0;
1463+
}
1464+
}
1465+
14201466
static void cleanup (void)
14211467
{
14221468
unlink (server.sun_path);
@@ -1444,6 +1490,7 @@ void ncp_init (void)
14441490
signal (SIGQUIT, sigcleanup);
14451491
signal (SIGTERM, sigcleanup);
14461492
atexit (cleanup);
1493+
time_unit = 0;
14471494
}
14481495

14491496
int main (int argc, char **argv)
@@ -1456,13 +1503,20 @@ int main (int argc, char **argv)
14561503
for (;;) {
14571504
int n;
14581505
fd_set rfds;
1506+
struct timeval tv;
14591507
FD_ZERO (&rfds);
14601508
FD_SET (fd, &rfds);
14611509
imp_fd_set (&rfds);
1462-
n = select (33, &rfds, NULL, NULL, NULL);
1510+
tv.tv_sec = 1;
1511+
tv.tv_usec = 0;
1512+
n = select (33, &rfds, NULL, NULL, &tv);
14631513
if (n == -1)
14641514
fprintf (stderr, "NCP: select error.\n");
1465-
else if (n > 0) {
1515+
else if (n == 0) {
1516+
tick ();
1517+
tv.tv_sec = 1;
1518+
tv.tv_usec = 0;
1519+
} else {
14661520
if (imp_fd_isset (&rfds)) {
14671521
memset (packet, 0, sizeof packet);
14681522
imp_receive_message (packet, &n);

0 commit comments

Comments
 (0)