From a37c099d4b2633186993127d647ad2285af62fa9 Mon Sep 17 00:00:00 2001 From: Greg Hudson Date: Wed, 2 Sep 1998 21:37:33 +0000 Subject: Keep track of how responsive clients have been and don't time out good ones. --- server/client.c | 1 + server/dispatch.c | 40 +++++++++++++++++++++------------------- server/realm.c | 2 ++ server/server.c | 1 + server/zserver.h | 2 ++ server/zsrv_conf.h | 1 + 6 files changed, 28 insertions(+), 19 deletions(-) diff --git a/server/client.c b/server/client.c index 93638e8..2dca538 100644 --- a/server/client.c +++ b/server/client.c @@ -89,6 +89,7 @@ client_register(notice, host, client_p, wantdefaults) memset(&client->session_key, 0, sizeof(client->session_key)); #endif client->last_send = 0; + client->last_ack = NOW; client->addr.sin_family = AF_INET; client->addr.sin_addr.s_addr = host->s_addr; client->addr.sin_port = notice->z_port; diff --git a/server/dispatch.c b/server/dispatch.c index 4519812..5659516 100644 --- a/server/dispatch.c +++ b/server/dispatch.c @@ -499,9 +499,7 @@ nack_release(client) for (i = 0; i < NACKTAB_HASHSIZE; i++) { for (nacked = nacktab[i]; nacked; nacked = next) { next = nacked->next; - if (nacked->dest.addr.sin_addr.s_addr == - client->addr.sin_addr.s_addr && - nacked->dest.addr.sin_port == client->addr.sin_port) { + if (nacked->client == client) { timer_reset(nacked->timer); LIST_DELETE(nacked); free(nacked->packet); @@ -558,6 +556,7 @@ xmit_frag(notice, buf, len, waitforack) memcpy(savebuf, buf, len); sin = ZGetDestAddr(); + nacked->client = NULL; nacked->rexmits = (sendfail) ? -1 : 0; nacked->packet = savebuf; nacked->dest.addr = sin; @@ -660,6 +659,7 @@ xmit(notice, dest, auth, client) return; } + nacked->client = client; nacked->rexmits = (sendfail) ? -1 : 0; nacked->packet = noticepack; nacked->dest.addr = *dest; @@ -681,7 +681,6 @@ rexmit(arg) { Unacked *nacked = (Unacked *) arg; int retval; - Client *client; #if 1 syslog(LOG_DEBUG, "rexmit %s/%d #%d time %d", @@ -691,22 +690,23 @@ rexmit(arg) nacked->rexmits++; if (rexmit_times[nacked->rexmits] == -1) { - /* Unresponsive client, find it in our database. */ - client = client_find(&nacked->dest.addr.sin_addr, - nacked->dest.addr.sin_port); - - /* unlink & free nacked */ - LIST_DELETE(nacked); - free(nacked->packet); - free(nacked); - - /* Kill the client. */ - if (client) { - server_kill_clt(client); - client_deregister(client, 1); + if (!nacked->client + || NOW - nacked->client->last_ack >= CLIENT_GIVEUP_MIN) { + /* The client (if there was one) has been unresponsive. Give up + * sending this packet, and kill the client if there was one. */ + LIST_DELETE(nacked); + free(nacked->packet); + free(nacked); + if (nacked->client) { + server_kill_clt(nacked->client); + client_deregister(nacked->client, 1); + } + return; + } else { + /* The client has sent us an ack recently. Retry with the maximum + * retransmit time. */ + nacked->rexmits--; } - - return; } /* retransmit the packet */ @@ -841,6 +841,8 @@ nack_cancel(notice, who) if (nacked->dest.addr.sin_addr.s_addr == who->sin_addr.s_addr && nacked->dest.addr.sin_port == who->sin_port && ZCompareUID(&nacked->uid, ¬ice->z_uid)) { + if (nacked->client) + nacked->client->last_ack = NOW; timer_reset(nacked->timer); free(nacked->packet); LIST_DELETE(nacked); diff --git a/server/realm.c b/server/realm.c index 425cc36..9cf8c92 100644 --- a/server/realm.c +++ b/server/realm.c @@ -451,6 +451,7 @@ realm_init() sprintf(rlmprinc, "%s.%s@%s", SERVER_SERVICE, SERVER_INSTANCE, rlm->name); client->principal = make_string(rlmprinc, 0); client->last_send = 0; + client->last_ack = NOW; client->subs = NULL; client->realm = rlm; client->addr.sin_family = 0; @@ -627,6 +628,7 @@ realm_sendit(notice, who, auth, realm, ack_to_sender) return; } + nacked->client = NULL; nacked->rexmits = 0; nacked->packet = pack; nacked->dest.rlm.rlm_idx = realm - otherrealms; diff --git a/server/server.c b/server/server.c index b034dc2..f5b9678 100644 --- a/server/server.c +++ b/server/server.c @@ -1419,6 +1419,7 @@ server_forw_reliable(server, pack, packlen, notice) return; } + nacked->client = NULL; nacked->rexmits = 0; nacked->packet = pack; nacked->dest.srv_idx = server - otherservers; diff --git a/server/zserver.h b/server/zserver.h index 219e82b..2cad00e 100644 --- a/server/zserver.h +++ b/server/zserver.h @@ -114,6 +114,7 @@ struct _Client { #endif /* HAVE_KRB4 */ String *principal; /* krb principal of user */ int last_send; /* Counter for last sent packet. */ + time_t last_ack; /* Time of last received ack */ Realm *realm; struct _Client *next, **prev_p; }; @@ -135,6 +136,7 @@ enum _Server_state { struct _Unacked { Timer *timer; /* timer for retransmit */ + Client *client; /* responsible client, or NULL */ short rexmits; /* number of retransmits */ short packsz; /* size of packet */ char *packet; /* ptr to packet */ diff --git a/server/zsrv_conf.h b/server/zsrv_conf.h index 9c2cbce..947b4ab 100644 --- a/server/zsrv_conf.h +++ b/server/zsrv_conf.h @@ -32,6 +32,7 @@ #define REXMIT_TIMES { 2, 2, 4, 4, 8, 8, 16, 32, 64, 128, 256, 512, -1 } #define NUM_REXMIT_TIMES 12 +#define CLIENT_GIVEUP_MIN 512 /* hostmanager defines */ #define LOSE_TIMO (60) /* time during which a losing host -- cgit v1.2.3