summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Greg Hudson <ghudson@mit.edu>1998-09-02 21:37:33 +0000
committerGravatar Greg Hudson <ghudson@mit.edu>1998-09-02 21:37:33 +0000
commita37c099d4b2633186993127d647ad2285af62fa9 (patch)
tree7db77ba64484fce824f646a32c2d37961af305e2
parentf3b7608fc2f87bb8fbed17e8308a109fc4b91a78 (diff)
Keep track of how responsive clients have been and don't time out good ones.
-rw-r--r--server/client.c1
-rw-r--r--server/dispatch.c40
-rw-r--r--server/realm.c2
-rw-r--r--server/server.c1
-rw-r--r--server/zserver.h2
-rw-r--r--server/zsrv_conf.h1
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, &notice->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