summaryrefslogtreecommitdiff
path: root/server/dispatch.c
diff options
context:
space:
mode:
authorGravatar John Kohl <jtkohl@mit.edu>1987-07-07 13:17:57 +0000
committerGravatar John Kohl <jtkohl@mit.edu>1987-07-07 13:17:57 +0000
commite229854d1f1067946c87bc8dd6c7b0908bc09690 (patch)
tree3bba1874e6c8dd799c3767e1ddb135a21345f2d6 /server/dispatch.c
parent4359abae544e3b217e6ee6f917ff8035e44ad9a0 (diff)
new debug style, clean up null pointer checks and comments.
Diffstat (limited to 'server/dispatch.c')
-rw-r--r--server/dispatch.c198
1 files changed, 139 insertions, 59 deletions
diff --git a/server/dispatch.c b/server/dispatch.c
index c7bc723..99b883d 100644
--- a/server/dispatch.c
+++ b/server/dispatch.c
@@ -45,10 +45,14 @@ static char rcsid_dispatch_c[] = "$Header$";
static void xmit(), rexmit(), nack_cancel();
static int is_server();
+#ifdef DEBUG
+static void dump_nack();
+#endif DEBUG
-int num_rexmits = NUM_REXMITS; /* patchable... */
+/* patchable magic numbers controlling the retransmission rate and count */
+int num_rexmits = NUM_REXMITS;
long rexmit_secs = REXMIT_SECS;
-long abs_timo = REXMIT_SECS*NUM_REXMITS;
+long abs_timo = REXMIT_SECS*NUM_REXMITS + 10;
#ifdef DEBUG
static char *pktypes[] = {
@@ -66,6 +70,7 @@ static char *pktypes[] = {
/*
* Dispatch a notice.
*/
+
void
dispatch(notice, auth, who)
register ZNotice_t *notice;
@@ -118,6 +123,10 @@ struct sockaddr_in *who;
sendit(notice, auth, who);
}
+/*
+ * Send a notice off to those clients who have subscribed to it.
+ */
+
void
sendit(notice, auth, who)
register ZNotice_t *notice;
@@ -128,13 +137,13 @@ struct sockaddr_in *who;
ZAcl_t *acl;
register ZClientList_t *clientlist, *ptr;
- if ((acl = class_get_acl(notice->z_class)) != NULLZACLT &&
+ if ((acl = class_get_acl(notice->z_class)) &&
(!auth || !access_check(notice, acl, TRANSMIT))) {
syslog(LOG_WARNING, "sendit unauthorized %s", notice->z_class);
clt_ack(notice, who, AUTH_FAILED);
return;
}
- if ((clientlist = subscr_match_list(notice)) != NULLZCLT) {
+ if ((clientlist = subscr_match_list(notice, acl))) {
for (ptr = clientlist->q_forw;
ptr != clientlist;
ptr = ptr->q_forw) {
@@ -153,6 +162,37 @@ struct sockaddr_in *who;
nack(notice, who);
}
+/*
+ * Clean up the not-yet-acked queue and release anything destined
+ * for the client.
+ */
+
+void
+nack_release(client)
+ZClient_t *client;
+{
+ register ZNotAcked_t *nacked, *nack2;
+
+ /* search the not-yet-acked list for anything destined to him, and
+ flush it. */
+ for (nacked = nacklist->q_forw;
+ nacked != nacklist;)
+ if (nacked->na_client == client) {
+ zdbug((LOG_DEBUG,"nack_rel: punt 0x%x, 0x%x",
+ nacked,
+ nacked->na_timer));
+ /* go back, since remque will change things */
+ nack2 = nacked->q_back;
+ timer_reset(nacked->na_timer);
+ xfree(nacked->na_packet);
+ xremque(nacked);
+ /* now that the remque adjusted the linked list,
+ we go forward again */
+ nacked = nack2->q_forw;
+ } else
+ nacked = nacked->q_forw;
+ return;
+}
/*
* Is this from a server?
@@ -173,6 +213,7 @@ struct sockaddr_in *who;
return(1);
return(0);
}
+
/*
* Send the notice to the client. After transmitting, put it onto the
* not ack'ed list.
@@ -189,8 +230,8 @@ int auth;
int packlen;
Code_t retval;
- zdbug1("xmit");
- if ((noticepack = (caddr_t) xmalloc(sizeof(ZPacket_t))) == (caddr_t) NULL) {
+ zdbug((LOG_DEBUG,"xmit"));
+ if (!(noticepack = (caddr_t) xmalloc(sizeof(ZPacket_t)))) {
syslog(LOG_ERR, "xmit malloc");
return; /* DON'T put on nack list */
}
@@ -199,7 +240,12 @@ int auth;
packlen = sizeof(ZPacket_t);
if (auth) { /* we are distributing authentic */
- if ((retval = ZFormatAuthenticNotice(notice, noticepack, packlen, &packlen, client->zct_cblock)) != ZERR_NONE) {
+ if ((retval = ZFormatAuthenticNotice(notice,
+ noticepack,
+ packlen,
+ &packlen,
+ client->zct_cblock))
+ != ZERR_NONE) {
syslog(LOG_ERR, "xmit auth format: %s",
error_message(retval));
xfree(noticepack);
@@ -209,14 +255,18 @@ int auth;
notice->z_auth = 0;
notice->z_authent_len = 0;
notice->z_ascii_authent = (char *)"";
- if ((retval = ZFormatRawNotice(notice, noticepack, packlen, &packlen)) != ZERR_NONE) {
- syslog(LOG_ERR, "xmit format: %s", error_message(retval));
+ if ((retval = ZFormatRawNotice(notice,
+ noticepack,
+ packlen,
+ &packlen)) != ZERR_NONE) {
+ syslog(LOG_ERR, "xmit format: %s",
+ error_message(retval));
xfree(noticepack);
return; /* DON'T put on nack list */
}
}
- zdbug3(" to %s/%d",inet_ntoa(client->zct_sin.sin_addr),
- ntohs(client->zct_sin.sin_port));
+ zdbug((LOG_DEBUG," to %s/%d",inet_ntoa(client->zct_sin.sin_addr),
+ ntohs(client->zct_sin.sin_port)));
if ((retval = ZSetDestAddr(&client->zct_sin)) != ZERR_NONE) {
syslog(LOG_WARNING, "xmit set addr: %s",
error_message(retval));
@@ -229,7 +279,7 @@ int auth;
/* now we've sent it, mark it as not ack'ed */
- if ((nacked = (ZNotAcked_t *)xmalloc(sizeof(ZNotAcked_t))) == NULLZNAT) {
+ if (!(nacked = (ZNotAcked_t *)xmalloc(sizeof(ZNotAcked_t)))) {
/* no space: just punt */
syslog(LOG_WARNING, "xmit nack malloc");
return;
@@ -242,8 +292,11 @@ int auth;
nacked->na_uid = notice->z_uid;
nacked->q_forw = nacked->q_back = nacked;
nacked->na_abstimo = NOW + abs_timo;
- /* set a timer */
- nacked->na_timer = timer_set_rel (rexmit_secs, rexmit, (caddr_t) nacked);
+
+ /* set a timer to retransmit when done */
+ nacked->na_timer = timer_set_rel(rexmit_secs,
+ rexmit,
+ (caddr_t) nacked);
/* chain in */
xinsque(nacked, nacklist);
#ifdef DEBUG
@@ -254,18 +307,31 @@ int auth;
}
#ifdef DEBUG
+/*
+ * log the nack queue
+ */
+
+static void
dump_nack()
{
register ZNotAcked_t *nacked;
- /* search the not-yet-acked list for anything destined to him, and
- flush it. */
- for (nacked = nacklist->q_forw; nacked != nacklist; nacked = nacked->q_forw)
- syslog(LOG_DEBUG, "nck 0x%x, tmr 0x%x, clt 0x%x",
- nacked, nacked->na_timer, nacked->na_client);
+
+ if (zdebug)
+ for (nacked = nacklist->q_forw;
+ nacked != nacklist;
+ nacked = nacked->q_forw)
+ syslog(LOG_DEBUG, "nck 0x%x, tmr 0x%x, clt 0x%x",
+ nacked, nacked->na_timer, nacked->na_client);
}
#endif DEBUG
+/*
+ * Retransmit the packet specified. If we have timed out or retransmitted
+ * too many times, punt the packet and initiate the host recovery algorithm
+ * Else, increment the count and re-send the notice packet.
+ */
+
static void
rexmit(nackpacket)
register ZNotAcked_t *nackpacket;
@@ -273,7 +339,7 @@ register ZNotAcked_t *nackpacket;
int retval;
register ZClient_t *client;
- zdbug1("rexmit");
+ zdbug((LOG_DEBUG,"rexmit"));
if (++(nackpacket->na_rexmits) > num_rexmits ||
NOW > nackpacket->na_abstimo) {
@@ -300,9 +366,11 @@ register ZNotAcked_t *nackpacket;
/* retransmit the packet */
- zdbug3(" to %s/%d",inet_ntoa(nackpacket->na_client->zct_sin.sin_addr),
- ntohs(nackpacket->na_client->zct_sin.sin_port));
- if ((retval = ZSetDestAddr(&nackpacket->na_client->zct_sin)) != ZERR_NONE) {
+ zdbug((LOG_DEBUG," to %s/%d",
+ inet_ntoa(nackpacket->na_client->zct_sin.sin_addr),
+ ntohs(nackpacket->na_client->zct_sin.sin_port)));
+ if ((retval = ZSetDestAddr(&nackpacket->na_client->zct_sin))
+ != ZERR_NONE) {
syslog(LOG_WARNING, "rexmit set addr: %s",
error_message(retval));
goto requeue;
@@ -314,7 +382,10 @@ register ZNotAcked_t *nackpacket;
requeue:
/* reset the timer */
- nackpacket->na_timer = timer_set_rel (rexmit_secs, rexmit, (caddr_t) nackpacket);
+ nackpacket->na_timer = timer_set_rel(rexmit_secs,
+ rexmit,
+ (caddr_t) nackpacket);
+
#ifdef DEBUG
if (zdebug)
dump_nack();
@@ -323,6 +394,13 @@ requeue:
}
+/*
+ * Send an acknowledgement to the sending client, by sending back the
+ * header from the original notice with the z_kind field changed to either
+ * SERVACK or SERVNAK, and the contents of the message either SENT or
+ * NOT_SENT, depending on the value of the sent argument.
+ */
+
void
clt_ack(notice, who, sent)
ZNotice_t *notice;
@@ -334,11 +412,14 @@ ZSentType sent;
int packlen;
Code_t retval;
- zdbug3("clt_ack type %d for %d", (int) sent, ntohs(notice->z_port));
- zdbug3(" to %s/%d",inet_ntoa(who->sin_addr), ntohs(who->sin_port));
+ zdbug((LOG_DEBUG,"clt_ack type %d for %d to %s/%d",
+ (int) sent,
+ ntohs(notice->z_port),
+ inet_ntoa(who->sin_addr),
+ ntohs(who->sin_port)));
if (hostm_find_server(&who->sin_addr) != me_server) {
- zdbug1("not me");
+ zdbug((LOG_DEBUG,"not me"));
return;
}
acknotice = *notice;
@@ -365,7 +446,10 @@ ZSentType sent;
packlen = sizeof(ackpack);
- if ((retval = ZFormatRawNotice(&acknotice, ackpack, packlen, &packlen)) != ZERR_NONE) {
+ if ((retval = ZFormatRawNotice(&acknotice,
+ ackpack,
+ packlen,
+ &packlen)) != ZERR_NONE) {
syslog(LOG_ERR, "clt_ack format: %s",error_message(retval));
return;
}
@@ -381,25 +465,10 @@ ZSentType sent;
return;
}
-void
-nack_release(client)
-ZClient_t *client;
-{
- register ZNotAcked_t *nacked, *nack2;
-
- /* search the not-yet-acked list for anything destined to him, and
- flush it. */
- for (nacked = nacklist->q_forw; nacked != nacklist; nacked = nacked->q_forw)
- if (nacked->na_client == client) {
- zdbug3("nack_rel: punt 0x%x, 0x%x",nacked, nacked->na_timer);
- nack2 = nacked->q_forw; /* go back */
- timer_reset(nacked->na_timer);
- xfree(nacked->na_packet);
- xremque(nacked);
- nacked = nack2->q_back; /* the remque will have frobbed things */
- }
- return;
-}
+/*
+ * An ack has arrived.
+ * remove the packet matching this notice from the not-yet-acked queue
+ */
static void
nack_cancel(notice, who)
@@ -409,29 +478,40 @@ struct sockaddr_in *who;
register ZNotAcked_t *nacked;
ZClient_t *client;
- notice->z_port = who->sin_port; /* set the origin of the ack to the client who is responding */
- if ((client = client_which_client(who, notice)) == NULLZCNT) {
- zdbug1("nack clt not found");
+ /* set the origin of the ack to the client who is responding,
+ since client_which_client matches on the z_port field */
+
+ notice->z_port = who->sin_port;
+ if (!(client = client_which_client(who, notice))) {
+ zdbug((LOG_DEBUG,"nack clt not found"));
return;
}
- zdbug2("nack_can: 0x%x", notice->z_uid.zuid_addr.s_addr);
- zdbug3(" %d %d", notice->z_uid.tv.tv_sec, notice->z_uid.tv.tv_usec);
+ zdbug((LOG_DEBUG,"nack_can: 0x%x %d %d",
+ notice->z_uid.zuid_addr.s_addr,
+ notice->z_uid.tv.tv_sec,
+ notice->z_uid.tv.tv_usec));
+
/* search the not-yet-acked list for this packet, and
flush it. */
- for (nacked = nacklist->q_forw; nacked != nacklist; nacked = nacked->q_forw)
+ for (nacked = nacklist->q_forw;
+ nacked != nacklist;
+ nacked = nacked->q_forw)
if ((nacked->na_client == client))
- if (!bcmp((caddr_t) &nacked->na_uid, (caddr_t) &notice->z_uid, sizeof(nacked->na_uid))) {
- zdbug1("nack_canceled");
+ if (ZCompareUID((caddr_t) &nacked->na_uid,
+ (caddr_t) &notice->z_uid)) {
+ zdbug((LOG_DEBUG,"nack_canceled"));
timer_reset(nacked->na_timer);
xfree(nacked->na_packet);
xremque(nacked);
return;
} else {
- zdbug1("not this one");
- zdbug2("nack_can: 0x%x", nacked->na_uid.zuid_addr.s_addr);
- zdbug3(" %d %d", nacked->na_uid.tv.tv_sec, nacked->na_uid.tv.tv_usec);
+ zdbug((LOG_DEBUG,
+ "nack_can: not this one 0x%x %d %d",
+ nacked->na_uid.zuid_addr.s_addr,
+ nacked->na_uid.tv.tv_sec,
+ nacked->na_uid.tv.tv_usec));
}
- zdbug1("nack not found");
+ zdbug((LOG_DEBUG,"nack not found"));
return;
}