summaryrefslogtreecommitdiff
path: root/server/dispatch.c
diff options
context:
space:
mode:
authorGravatar Kenneth G Raeburn <raeburn@mit.edu>1990-11-13 12:02:59 +0000
committerGravatar Kenneth G Raeburn <raeburn@mit.edu>1990-11-13 12:02:59 +0000
commita36a075433165839ec7a02379ad83c03e08498a5 (patch)
treef6ad43e0f7a6e60f5e65d3e632b49edabf9a9a7a /server/dispatch.c
parentdb89d0d2485f01c3d411c87952f2cd09e372f844 (diff)
C++ conversion and lots of modifications from summer & fall work
Diffstat (limited to 'server/dispatch.c')
-rw-r--r--server/dispatch.c250
1 files changed, 149 insertions, 101 deletions
diff --git a/server/dispatch.c b/server/dispatch.c
index 7de098c..ac45ab7 100644
--- a/server/dispatch.c
+++ b/server/dispatch.c
@@ -15,7 +15,7 @@
#ifndef lint
#ifndef SABER
-static char rcsid_dispatch_c[] = "$Id$";
+static const char rcsid_dispatch_c[] = "$Id$";
#endif SABER
#endif lint
@@ -51,15 +51,17 @@ static char rcsid_dispatch_c[] = "$Id$";
* ZClient_t *client;
*/
-static void rexmit(), nack_cancel();
+static void rexmit(void *nackpacket),
+ nack_cancel(register ZNotice_t *notice, struct sockaddr_in *who);
/* 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 + 10;
+int current_msg;
#ifdef DEBUG
-char *pktypes[] = {
+extern const char *pktypes[] = {
"UNSAFE",
"UNACKED",
"ACKED",
@@ -71,13 +73,19 @@ char *pktypes[] = {
};
#endif DEBUG
+extern const ZString class_control (ZEPHYR_CTL_CLASS, 1);
+extern const ZString class_admin (ZEPHYR_ADMIN_CLASS, 1);
+extern const ZString class_hm (HM_CTL_CLASS, 1);
+extern const ZString class_ulogin (LOGIN_CLASS, 1);
+extern const ZString class_ulocate (LOCATE_CLASS, 1);
+
/*
* Handle an input packet.
* Warning: this function may be called from within a brain dump.
*/
void
-handle_packet()
+handle_packet(void)
{
Code_t status;
ZPacket_t input_packet; /* from the network */
@@ -93,8 +101,10 @@ handle_packet()
if (otherservers[me_server_idx].zs_update_queue) {
/* something here for me; take care of it */
+#if 0
if (zdebug)
syslog(LOG_DEBUG, "internal queue process");
+#endif
pending = otherservers[me_server_idx].zs_update_queue->q_forw;
host = hostm_find_host(&(pending->pend_who.sin_addr));
@@ -103,8 +113,10 @@ handle_packet()
we can't process other packets, esp. since we
may block since we don't really know if there
are things in the real queue. */
+#if 0
zdbug((LOG_DEBUG,"host %s is locked",
inet_ntoa(host->zh_addr.sin_addr)));
+#endif
return;
}
pending = server_dequeue(me_server); /* we can do it, remove */
@@ -171,7 +183,7 @@ handle_packet()
break;
}
if (whoisit.sin_port != hm_port &&
- strcasecmp(new_notice.z_class,ZEPHYR_ADMIN_CLASS) &&
+ strcasecmp (new_notice.z_class,ZEPHYR_ADMIN_CLASS) &&
whoisit.sin_port != sock_sin.sin_port &&
new_notice.z_kind != CLIENTACK) {
syslog(LOG_ERR,
@@ -188,77 +200,87 @@ handle_packet()
*/
void
-dispatch(notice, auth, who)
-register ZNotice_t *notice;
-int auth;
-struct sockaddr_in *who;
-{
+dispatch(ZNotice_t *n, int auth, struct sockaddr_in *who) {
Code_t status;
int dispatched = 0;
+ Notice notice = n;
- /* assumes enums are allocated contiguous, increasing values */
+ current_msg++;
+ if (current_msg >= 9999)
+ current_msg = 0;
- if ((int) notice->z_kind < (int) UNSAFE ||
- (int) notice->z_kind > (int) CLIENTACK) {
+ if ((int) notice.notice->z_kind < (int) UNSAFE ||
+ (int) notice.notice->z_kind > (int) CLIENTACK) {
syslog(LOG_INFO, "bad notice kind 0x%x from %s",
- (int) notice->z_kind,
+ (int) notice.notice->z_kind,
inet_ntoa(who->sin_addr));
return;
}
-#ifdef DEBUG
+#if defined (DEBUG)
if (zdebug) {
- char buf[4096];
-
- (void) sprintf(buf, "disp:%s '%s' '%s' '%s' '%s' '%s' %s/%d/%d",
- pktypes[(int) notice->z_kind],
- notice->z_class,
- notice->z_class_inst,
- notice->z_opcode,
- notice->z_sender,
- notice->z_recipient,
- inet_ntoa(who->sin_addr),
- ntohs(who->sin_port),
- ntohs(notice->z_port));
- syslog(LOG_DEBUG, buf);
+ char buf[BUFSIZ];
+ (void) sprintf (buf,
+ "disp:%s '%s' '%s' '%s' notice to '%s' from '%s' %s/%d/%d",
+ pktypes[(int) notice.notice->z_kind],
+ notice.dest.classname.value (),
+ notice.dest.inst.value (),
+ notice.notice->z_opcode,
+ notice.dest.recip.value (),
+ notice.sender.value (),
+ inet_ntoa(who->sin_addr),
+ ntohs(who->sin_port),
+ ntohs(notice.notice->z_port));
+ syslog (LOG_DEBUG, "%s", buf);
+ }
+#endif
+#if 0
+ if (bdumping) {
+ zdbug ((LOG_DEBUG, "from %s/%d, class %s\n",
+ inet_ntoa (who->sin_addr), who->sin_port,
+ notice.dest.classname.value ()));
+ if (!server_which_server(who) && !class_is_admin (notice)) {
+ syslog (LOG_DEBUG, "brain-dumping, dropping packet");
+ return;
+ }
}
-#endif DEBUG
- if (notice->z_kind == CLIENTACK) {
- nack_cancel(notice, who);
+#endif
+ if (notice.notice->z_kind == CLIENTACK) {
+ nack_cancel(notice.notice, who);
return;
}
if (server_which_server(who)) {
- status = server_dispatch(notice, auth, who);
+ status = server_dispatch(notice.notice, auth, who);
dispatched = 1;
} else if (class_is_hm(notice)) {
- status = hostm_dispatch(notice, auth, who, me_server);
+ status = hostm_dispatch(notice.notice, auth, who, me_server);
dispatched = 1;
} else if (class_is_control(notice)) {
- status = control_dispatch(notice, auth, who, me_server);
+ status = control_dispatch(notice.notice, auth, who, me_server);
dispatched = 1;
} else if (class_is_ulogin(notice)) {
- status = ulogin_dispatch(notice, auth, who, me_server);
+ status = ulogin_dispatch(notice.notice, auth, who, me_server);
dispatched = 1;
} else if (class_is_ulocate(notice)) {
- status = ulocate_dispatch(notice, auth, who, me_server);
+ status = ulocate_dispatch(notice.notice, auth, who, me_server);
dispatched = 1;
} else if (class_is_admin(notice)) {
- status = server_adispatch(notice, auth, who, me_server);
+ status = server_adispatch(notice.notice, auth, who, me_server);
dispatched = 1;
}
if (dispatched) {
if (status == ZSRV_REQUEUE) {
#ifdef CONCURRENT
- server_self_queue(notice, auth, who);
+ server_self_queue(notice.notice, auth, who);
#else
syslog(LOG_ERR, "requeue while not concurr");
abort();
-#endif CONCURRENT
+#endif
}
return;
}
/* oh well, do the dirty work */
- sendit(notice, auth, who);
+ sendit(notice.notice, auth, who);
}
/*
@@ -266,16 +288,13 @@ struct sockaddr_in *who;
*/
void
-sendit(notice, auth, who)
-register ZNotice_t *notice;
-int auth;
-struct sockaddr_in *who;
+sendit(register ZNotice_t *notice, int auth, struct sockaddr_in *who)
{
int acked = 0;
ZAcl_t *acl;
register ZClientList_t *clientlist, *ptr;
- if (acl = class_get_acl(notice->z_class)) {
+ if (acl = class_get_acl(ZString (notice->z_class, 1))) {
/* if controlled and not auth, fail */
if (!auth) {
syslog(LOG_WARNING, "sendit unauthentic %s from %s",
@@ -284,22 +303,28 @@ struct sockaddr_in *who;
return;
}
/* if not auth to transmit, fail */
- if (!access_check(notice, acl, TRANSMIT)) {
+ if (!access_check(notice->z_sender, acl, TRANSMIT)) {
syslog(LOG_WARNING, "sendit unauthorized %s from %s",
notice->z_class, notice->z_sender);
clt_ack(notice, who, AUTH_FAILED);
return;
}
/* sender != inst and not auth to send to others --> fail */
- if (strcmp(notice->z_sender, notice->z_class_inst) &&
- !access_check(notice, acl, INSTUID)) {
- syslog(LOG_WARNING,
- "sendit unauth uid %s %s.%s",
- notice->z_sender,
- notice->z_class,
- notice->z_class_inst);
- clt_ack(notice, who, AUTH_FAILED);
- return;
+ {
+ /* Need to write this funny so that cfront can deal... */
+ int xxx;
+ xxx = strcmp (notice->z_sender, notice->z_class_inst);
+ if (xxx)
+ xxx = !acl->ok (notice->z_sender, INSTUID);
+ if (xxx) {
+ syslog(LOG_WARNING,
+ "sendit unauth uid %s %s.%s",
+ notice->z_sender,
+ notice->z_class,
+ notice->z_class_inst);
+ clt_ack(notice, who, AUTH_FAILED);
+ return;
+ }
}
}
if (bcmp(&notice->z_sender_addr.s_addr, &who->sin_addr.s_addr,
@@ -338,8 +363,7 @@ struct sockaddr_in *who;
*/
void
-nack_release(client)
-ZClient_t *client;
+nack_release(ZClient_t *client)
{
register ZNotAcked_t *nacked, *nack2;
@@ -371,10 +395,7 @@ ZClient_t *client;
/* the arguments must be the same as the arguments to Z_XmitFragment */
/*ARGSUSED*/
Code_t
-xmit_frag(notice, buf, len, waitforack)
-ZNotice_t *notice;
-char *buf;
-int len, waitforack;
+xmit_frag(ZNotice_t *notice, char *buf, int len, int waitforack)
{
char *savebuf;
register ZNotAcked_t *nacked;
@@ -425,19 +446,16 @@ int len, waitforack;
*/
void
-xmit(notice, dest, auth, client)
-register ZNotice_t *notice;
-struct sockaddr_in *dest;
-int auth;
-ZClient_t *client;
+xmit(register ZNotice_t *notice, struct sockaddr_in *dest, int auth, ZClient_t *client)
{
caddr_t noticepack;
register ZNotAcked_t *nacked;
int packlen;
Code_t retval;
+#if 0
zdbug((LOG_DEBUG,"xmit"));
-
+#endif
if (!(noticepack = (caddr_t) xmalloc(sizeof(ZPacket_t)))) {
syslog(LOG_ERR, "xmit malloc");
@@ -488,8 +506,10 @@ ZClient_t *client;
return; /* DON'T put on nack list */
}
}
+#if 0
zdbug((LOG_DEBUG," to %s/%d",inet_ntoa(dest->sin_addr),
ntohs(dest->sin_port)));
+#endif
if ((retval = ZSetDestAddr(dest)) != ZERR_NONE) {
syslog(LOG_WARNING, "xmit set addr: %s",
error_message(retval));
@@ -537,14 +557,16 @@ ZClient_t *client;
*/
static void
-rexmit(nackpacket)
-register ZNotAcked_t *nackpacket;
+rexmit(void *arg)
{
+ register ZNotAcked_t *nackpacket = (ZNotAcked_t*) arg;
int retval;
ZNotice_t dummy_notice;
register ZClient_t *client;
+#if 0
zdbug((LOG_DEBUG,"rexmit"));
+#endif
if (++(nackpacket->na_rexmits) > num_rexmits ||
NOW > nackpacket->na_abstimo) {
@@ -568,9 +590,11 @@ register ZNotAcked_t *nackpacket;
/* retransmit the packet */
+#if 0
zdbug((LOG_DEBUG," to %s/%d",
inet_ntoa(nackpacket->na_addr.sin_addr),
ntohs(nackpacket->na_addr.sin_port)));
+#endif
if ((retval = ZSetDestAddr(&nackpacket->na_addr))
!= ZERR_NONE) {
syslog(LOG_WARNING, "rexmit set addr: %s",
@@ -599,49 +623,62 @@ requeue:
*/
void
-clt_ack(notice, who, sent)
-ZNotice_t *notice;
-struct sockaddr_in *who;
-ZSentType sent;
+clt_ack(ZNotice_t *notice, struct sockaddr_in *who, ZSentType sent)
{
ZNotice_t acknotice;
ZPacket_t ackpack;
int packlen;
int notme = 0;
+ char *sent_name;
Code_t retval;
if (bdumping) { /* don't ack while dumping */
+#if 1
zdbug((LOG_DEBUG,"bdumping, no ack"));
+#endif
return;
}
- 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 (!server_which_server(who) &&
- (hostm_find_server(&who->sin_addr) != me_server)) {
- zdbug((LOG_DEBUG,"not me"));
- notme = 1;
- }
acknotice = *notice;
acknotice.z_kind = SERVACK;
switch (sent) {
case SENT:
acknotice.z_message = ZSRVACK_SENT;
+ sent_name = "sent";
break;
case NOT_FOUND:
acknotice.z_message = ZSRVACK_FAIL;
acknotice.z_kind = SERVNAK;
+ sent_name = "fail";
break;
case AUTH_FAILED:
acknotice.z_kind = SERVNAK;
- /* fall thru */
+ acknotice.z_message = ZSRVACK_NOTSENT;
+ sent_name = "nak/not_sent";
+ break;
case NOT_SENT:
acknotice.z_message = ZSRVACK_NOTSENT;
+ sent_name = "not_sent";
break;
+ default:
+ abort ();
+ }
+
+#if 1
+ zdbug((LOG_DEBUG,"clt_ack type %s for %d to %s/%d",
+ sent_name,
+ ntohs(notice->z_port),
+ inet_ntoa(who->sin_addr),
+ ntohs(who->sin_port)));
+#endif
+
+ if (!server_which_server(who) &&
+ (hostm_find_server(&who->sin_addr) != me_server)) {
+#if 0
+ zdbug((LOG_DEBUG,"not me"));
+#endif
+ notme = 1;
}
acknotice.z_multinotice = "";
@@ -666,6 +703,8 @@ ZSentType sent;
syslog(LOG_WARNING, "clt_ack xmit: %s", error_message(retval));
return;
}
+ else
+ zdbug ((LOG_DEBUG, "packet sent"));
if (notme)
hostm_deathgram(who, me_server);
return;
@@ -677,14 +716,17 @@ ZSentType sent;
*/
static void
-nack_cancel(notice, who)
-register ZNotice_t *notice;
-struct sockaddr_in *who;
+nack_cancel(register ZNotice_t *notice, struct sockaddr_in *who)
{
register ZNotAcked_t *nacked;
/* search the not-yet-acked list for this packet, and
flush it. */
+#if 1
+ zdbug((LOG_DEBUG, "nack_cancel: %s:%08X,%08X",
+ inet_ntoa (notice->z_uid.zuid_addr),
+ notice->z_uid.tv.tv_sec, notice->z_uid.tv.tv_usec));
+#endif
for (nacked = nacklist->q_forw;
nacked != nacklist;
nacked = nacked->q_forw)
@@ -697,7 +739,9 @@ struct sockaddr_in *who;
xfree(nacked);
return;
}
+#if 0
zdbug((LOG_DEBUG,"nack not found"));
+#endif
return;
}
@@ -711,11 +755,7 @@ struct sockaddr_in *who;
*/
Code_t
-control_dispatch(notice, auth, who, server)
-ZNotice_t *notice;
-int auth;
-struct sockaddr_in *who;
-ZServerDesc_t *server;
+control_dispatch(ZNotice_t *notice, int auth, struct sockaddr_in *who, ZServerDesc_t *server)
{
register char *opcode = notice->z_opcode;
ZClient_t *client;
@@ -731,10 +771,12 @@ ZServerDesc_t *server;
* CLIENT_CANCELSUB: ""
*/
- if (!strcasecmp(notice->z_class_inst, ZEPHYR_CTL_HM))
+ zdbug ((LOG_DEBUG, "ctl_disp: opc=%s", opcode));
+
+ if (!strcasecmp (notice->z_class_inst, ZEPHYR_CTL_HM))
return(hostm_dispatch(notice, auth, who, server));
- else if (!strcmp(opcode, CLIENT_GIMMESUBS) ||
- !strcmp(opcode, CLIENT_GIMMEDEFS)) {
+ else if (!strcmp (opcode, CLIENT_GIMMESUBS) ||
+ !strcmp (opcode, CLIENT_GIMMEDEFS)) {
/* this special case is before the auth check so that
someone who has no subscriptions does NOT get a SERVNAK
but rather an empty list. Note we must therefore
@@ -742,7 +784,7 @@ ZServerDesc_t *server;
#ifdef OLD_COMPAT
/* only acknowledge if *not* old version; the old version
acknowledges the packet with the reply */
- if (strcmp(notice->z_version, OLD_ZEPHYR_VERSION))
+ if (strcmp (notice->z_version, OLD_ZEPHYR_VERSION))
ack(notice, who);
#else /* !OLD_COMPAT */
ack(notice, who);
@@ -750,7 +792,9 @@ ZServerDesc_t *server;
subscr_sendlist(notice, auth, who);
return(ZERR_NONE);
} else if (!auth) {
+#if 0
zdbug((LOG_DEBUG,"unauth ctrl_disp"));
+#endif
if (server == me_server)
clt_ack(notice, who, AUTH_FAILED);
return(ZERR_NONE);
@@ -762,8 +806,8 @@ ZServerDesc_t *server;
if (host && host->zh_locked)
return(ZSRV_REQUEUE);
- wantdefs = strcmp(opcode, CLIENT_SUBSCRIBE_NODEFS);
- if (!wantdefs || !strcmp(opcode, CLIENT_SUBSCRIBE)) {
+ wantdefs = strcmp (opcode, CLIENT_SUBSCRIBE_NODEFS);
+ if (!wantdefs || !strcmp (opcode, CLIENT_SUBSCRIBE)) {
/* subscription notice */
if (!(client = client_which_client(who, notice))) {
if ((retval = client_register(notice,
@@ -791,7 +835,7 @@ ZServerDesc_t *server;
abort();
}
}
- if (strcmp(client->zct_principal, notice->z_sender)) {
+ if (strcmp (client->zct_principal.value (), notice->z_sender)) {
/* you may only subscribe for your own clients */
if (server == me_server)
clt_ack(notice, who, AUTH_FAILED);
@@ -811,7 +855,7 @@ ZServerDesc_t *server;
}
} else if (!strcmp(opcode, CLIENT_UNSUBSCRIBE)) {
if ((client = client_which_client(who,notice))) {
- if (strcmp(client->zct_principal, notice->z_sender)) {
+ if (strcmp(client->zct_principal.value (), notice->z_sender)) {
/* you may only cancel for your own clients */
if (server == me_server)
clt_ack(notice, who, AUTH_FAILED);
@@ -826,7 +870,7 @@ ZServerDesc_t *server;
/* canceling subscriptions implies I can punt info about
this client */
if ((client = client_which_client(who,notice))) {
- if (strcmp(client->zct_principal, notice->z_sender)) {
+ if (strcmp(client->zct_principal.value (), notice->z_sender)) {
/* you may only cancel for your own clients */
if (server == me_server)
clt_ack(notice, who, AUTH_FAILED);
@@ -835,16 +879,20 @@ ZServerDesc_t *server;
if (host) {
/* don't flush locations here, let him
do it explicitly */
+#if 0
if (zdebug)
syslog(LOG_DEBUG,
"cancelsub clt_dereg");
+#endif
hostm_lose_ignore(client);
(void) client_deregister(client, host, 0);
}
}
if (!client || !host) {
+#if 0
zdbug((LOG_DEBUG,"can_sub not found client"));
+#endif
if (server == me_server)
nack(notice, who);
return(ZERR_NONE);