summaryrefslogtreecommitdiff
path: root/server
diff options
context:
space:
mode:
authorGravatar John Kohl <jtkohl@mit.edu>1988-06-15 18:50:12 +0000
committerGravatar John Kohl <jtkohl@mit.edu>1988-06-15 18:50:12 +0000
commit1ccc10d123d9f6bb34254f34ed14997aa76739c7 (patch)
treeb5293a77ccdb79ea8034764634cc4b7546948af2 /server
parentb68a61bbdea8bac1d245bf726ef4dc61e9b2be2b (diff)
new library fixes
Diffstat (limited to 'server')
-rw-r--r--server/dispatch.c99
-rw-r--r--server/subscr.c145
-rw-r--r--server/uloc.c114
3 files changed, 281 insertions, 77 deletions
diff --git a/server/dispatch.c b/server/dispatch.c
index db925bd..491ca98 100644
--- a/server/dispatch.c
+++ b/server/dispatch.c
@@ -127,7 +127,6 @@ handle_packet()
* queue/socket
*/
if (status = ZReceivePacket(input_packet,
- sizeof(input_packet),
&input_len,
&whoisit)) {
syslog(LOG_ERR,
@@ -155,12 +154,10 @@ handle_packet()
input_sin.sin_port = new_notice.z_port;
input_sin.sin_family = AF_INET;
authentic = ZCheckAuthentication(&new_notice,
- input_packet,
&input_sin);
}
else
authentic = ZCheckAuthentication(&new_notice,
- input_packet,
&whoisit);
if (whoisit.sin_port != hm_port &&
strcmp(new_notice.z_class,ZEPHYR_ADMIN_CLASS) &&
@@ -326,6 +323,61 @@ ZClient_t *client;
}
/*
+ * Send one packet of a fragmented message to a client. After transmitting,
+ * put it onto the not ack'ed list.
+ */
+
+/* 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;
+{
+ char *savebuf;
+ register ZNotAcked_t *nacked;
+
+ if ((retval = ZSendPacket(buf, len, 0)) != ZERR_NONE) {
+ syslog(LOG_WARNING, "xmit_frag send: %s",
+ error_message(retval));
+ return(retval);
+ }
+
+ /* now we've sent it, mark it as not ack'ed */
+
+ if (!(nacked = (ZNotAcked_t *)xmalloc(sizeof(ZNotAcked_t)))) {
+ /* no space: just punt */
+ syslog(LOG_WARNING, "xmit_frag nack malloc");
+ return(ENOMEM);
+ }
+
+ if (!(savebuf = (char *)xmalloc(len))) {
+ /* no space: just punt */
+ syslog(LOG_WARNING, "xmit_frag pack malloc");
+ return(ENOMEM);
+ }
+
+ (void) bcopy(buf, savebuf, len);
+
+ nacked->na_rexmits = 0;
+ nacked->na_packet = savebuf;
+ nacked->na_addr = ZGetDestAddr();
+ nacked->na_packsz = len;
+ nacked->na_uid = notice->z_multiuid;
+ nacked->q_forw = nacked->q_back = nacked;
+ nacked->na_abstimo = NOW + abs_timo;
+
+ /* set a timer to retransmit when done */
+ nacked->na_timer = timer_set_rel(rexmit_secs,
+ rexmit,
+ (caddr_t) nacked);
+ /* chain in */
+ xinsque(nacked, nacklist);
+ return(ZERR_NONE);
+}
+
+/*
* Send the notice to the client. After transmitting, put it onto the
* not ack'ed list.
*/
@@ -343,18 +395,19 @@ ZClient_t *client;
Code_t retval;
zdbug((LOG_DEBUG,"xmit"));
- if (!(noticepack = (caddr_t) xmalloc(sizeof(ZPacket_t)))) {
- syslog(LOG_ERR, "xmit malloc");
- return; /* DON'T put on nack list */
- }
- packlen = sizeof(ZPacket_t);
-
if (auth && client) { /*
we are distributing authentic and
we have a pointer to auth info
*/
+#ifdef KERBEROS
+ if (!(noticepack = (caddr_t) xmalloc(sizeof(ZPacket_t)))) {
+ syslog(LOG_ERR, "xmit malloc");
+ return; /* DON'T put on nack list */
+ }
+ packlen = sizeof(ZPacket_t);
+
if ((retval = ZFormatAuthenticNotice(notice,
noticepack,
packlen,
@@ -366,17 +419,26 @@ ZClient_t *client;
xfree(noticepack);
return;
}
+#else /* !KERBEROS */
+ notice->z_auth = 1;
+ if ((retval = ZFormatRawNotice(notice,
+ &noticepack,
+ &packlen))
+ != ZERR_NONE) {
+ syslog(LOG_ERR, "xmit auth/raw format: %s",
+ error_message(retval));
+ return;
+ }
+#endif /* KERBEROS */
} else {
notice->z_auth = 0;
notice->z_authent_len = 0;
notice->z_ascii_authent = (char *)"";
if ((retval = ZFormatRawNotice(notice,
- noticepack,
- packlen,
+ &noticepack,
&packlen)) != ZERR_NONE) {
syslog(LOG_ERR, "xmit format: %s",
error_message(retval));
- xfree(noticepack);
return; /* DON'T put on nack list */
}
}
@@ -388,7 +450,7 @@ ZClient_t *client;
xfree(noticepack);
return;
}
- if ((retval = ZSendPacket(noticepack, packlen)) != ZERR_NONE) {
+ if ((retval = ZSendPacket(noticepack, packlen, 0)) != ZERR_NONE) {
syslog(LOG_WARNING, "xmit xmit: %s", error_message(retval));
xfree(noticepack);
return;
@@ -407,7 +469,7 @@ ZClient_t *client;
nacked->na_packet = noticepack;
nacked->na_addr = *dest;
nacked->na_packsz = packlen;
- nacked->na_uid = notice->z_uid;
+ nacked->na_uid = notice->z_multiuid;
nacked->q_forw = nacked->q_back = nacked;
nacked->na_abstimo = NOW + abs_timo;
@@ -469,7 +531,7 @@ register ZNotAcked_t *nackpacket;
}
if ((retval = ZSendPacket(nackpacket->na_packet,
- nackpacket->na_packsz)) != ZERR_NONE)
+ nackpacket->na_packsz, 0)) != ZERR_NONE)
syslog(LOG_WARNING, "rexmit xmit: %s", error_message(retval));
requeue:
@@ -539,9 +601,8 @@ ZSentType sent;
packlen = sizeof(ackpack);
- if ((retval = ZFormatRawNotice(&acknotice,
+ if ((retval = ZFormatSmallRawNotice(&acknotice,
ackpack,
- packlen,
&packlen)) != ZERR_NONE) {
syslog(LOG_ERR, "clt_ack format: %s",error_message(retval));
return;
@@ -551,7 +612,7 @@ ZSentType sent;
error_message(retval));
return;
}
- if ((retval = ZSendPacket(ackpack, packlen)) != ZERR_NONE) {
+ if ((retval = ZSendPacket(ackpack, packlen, 0)) != ZERR_NONE) {
syslog(LOG_WARNING, "clt_ack xmit: %s", error_message(retval));
return;
}
@@ -579,7 +640,7 @@ struct sockaddr_in *who;
nacked = nacked->q_forw)
if ((nacked->na_addr.sin_addr.s_addr == who->sin_addr.s_addr) &&
(nacked->na_addr.sin_port == who->sin_port))
- if (ZCompareUID(&nacked->na_uid, &notice->z_uid)) {
+ if (ZCompareUID(&nacked->na_uid, &notice->z_multiuid)) {
timer_reset(nacked->na_timer);
xfree(nacked->na_packet);
xremque(nacked);
diff --git a/server/subscr.c b/server/subscr.c
index db28eda..3d544d2 100644
--- a/server/subscr.c
+++ b/server/subscr.c
@@ -63,11 +63,16 @@ static char rcsid_subscr_s_c[] = "$Header$";
#define OLD_CLIENT_INCOMPSUBS "INCOMP"
static void old_compat_subscr_sendlist();
#endif /* OLD_COMPAT */
+#ifdef NEW_COMPAT
+#define NEW_OLD_ZEPH_VERS "ZEPH0.1"
+static void new_old_compat_subscr_sendlist();
+#endif /* NEW_COMPAT */
extern char *re_comp(), *re_conv(), *rindex(), *index();
static ZSubscr_t *extract_subscriptions();
static int subscr_equiv(), clt_unique();
static void free_subscriptions(), free_sub();
+static char **subscr_marshal_subs();
static ZSubscr_t matchall_sub = {
(ZSubscr_t *) 0,
@@ -472,16 +477,10 @@ ZNotice_t *notice;
int auth;
struct sockaddr_in *who;
{
- ZClient_t *client;
- register ZSubscr_t *subs;
- Code_t retval;
- ZNotice_t reply;
- ZPacket_t reppacket;
+ char **answer;
+ int found;
struct sockaddr_in send_to_who;
- register int i;
- int packlen, found = 0, count, initfound, temp, zerofound;
- char **answer = (char **) NULL;
- char buf[64];
+
#ifdef OLD_COMPAT
if (!strcmp(notice->z_version, OLD_ZEPHYR_VERSION)) {
@@ -490,7 +489,57 @@ struct sockaddr_in *who;
old_compat_subscr_sendlist(notice, auth, who);
return;
}
-#endif OLD_COMPAT
+#endif /* OLD_COMPAT */
+#ifdef NEW_COMPAT
+ if (!strcmp(notice->z_version, NEW_OLD_ZEPHYR_VERSION)) {
+ /* we are talking to a new old client; use the new-old-style
+ acknowledgement-message */
+ new_old_compat_subscr_sendlist(notice, auth, who);
+ return;
+ }
+#endif /* NEW_COMPAT */
+ answer = subscr_marshal_subs(notice, auth, who, &found);
+ send_to_who = *who;
+ send_to_who.sin_port = notice->z_port; /* Return port */
+
+ if ((retval = ZSetDestAddr(&send_to_who)) != ZERR_NONE) {
+ syslog(LOG_WARNING, "subscr_sendlist set addr: %s",
+ error_message(retval));
+ if (answer)
+ xfree(answer);
+ return;
+ }
+
+ /* XXX for now, don't do authentication */
+ auth = 0;
+
+ notice->z_kind = ACKED;
+
+ /* use xmit_frag() to send each piece of the notice */
+
+ if ((retval = ZSrvSendRawList(notice, answer, found*NUM_FIELDS,
+ xmit_frag))
+ != ZERR_NONE) {
+ syslog(LOG_WARNING, "subscr_sendlist xmit: %s",
+ error_message(retval));
+ }
+ if (answer)
+ xfree(answer);
+ return;
+}
+
+static char **
+subscr_marshal_subs(notice, auth, who, &found)
+ZNotice_t *notice;
+int auth;
+struct sockaddr_in *who;
+int *found;
+{
+ ZNotice_t reply;
+ char **answer = (char **) NULL;
+ int temp;
+
+ found = 0;
/* Note that the following code is an incredible crock! */
@@ -501,24 +550,19 @@ struct sockaddr_in *who;
/* Make our own copy so we can send directly back to the client */
/* RSF 11/07/87 */
- send_to_who = *who;
- send_to_who.sin_port = notice->z_port; /* Return port */
/* the message field of the notice contains the port number
- of the client for which the sender desires the subscription
- list. The port field is the port of the sender. */
+ of the client for which the sender desires the subscription
+ list. The port field is the port of the sender. */
if ((retval = ZReadAscii(notice->z_message,notice->z_message_len,
(unsigned char *)&temp,sizeof(u_short)))
!= ZERR_NONE) {
- syslog(LOG_WARNING, "subscr_sendlist read port num: %s",
+ syslog(LOG_WARNING, "subscr_marshal read port num: %s",
error_message(retval));
- xfree(answer);
return;
}
- /* re-use the reply notice struct; it's reinitialized below */
-
/* Blech blech blech */
reply = *notice;
reply.z_port = *((u_short *)&temp);
@@ -529,7 +573,7 @@ struct sockaddr_in *who;
/* check authenticity here. The user must be authentic to get
a list of subscriptions. If he is not subscribed to
- anything, the above test fails, and he gets a response
+ anything, the above if-clause fails, and he gets a response
indicating no subscriptions */
if (!auth) {
@@ -557,21 +601,50 @@ struct sockaddr_in *who;
answer[i*NUM_FIELDS + 2] = subs->zst_recipient;
}
}
- /* note that when there are no subscriptions, found == 0, so
- we needn't worry about answer being NULL */
+ return(answer);
+}
+
+#ifdef NEW_COMPAT
+static void
+new_old_compat_subscr_sendlist(notice, auth, who)
+ZNotice_t *notice;
+int auth;
+struct sockaddr_in *who;
+{
+ ZClient_t *client;
+ register ZSubscr_t *subs;
+ Code_t retval;
+ ZNotice_t reply;
+ ZPacket_t reppacket;
+ register int i;
+ int packlen, found, count, initfound, zerofound;
+ char buf[64];
+ char **answer;
+ struct sockaddr_in send_to_who;
reply = *notice;
reply.z_kind = SERVACK;
reply.z_authent_len = 0; /* save some space */
reply.z_auth = 0;
+ send_to_who = *who;
+ send_to_who.sin_port = notice->z_port; /* Return port */
+
if ((retval = ZSetDestAddr(&send_to_who)) != ZERR_NONE) {
- syslog(LOG_WARNING, "subscr_sendlist set addr: %s",
+ syslog(LOG_WARNING, "new_old_subscr_sendlist set addr: %s",
error_message(retval));
- xfree(answer);
+ if (answer)
+ xfree(answer);
return;
}
+ /* retrieve the subscriptions */
+ answer = subscr_marshal_subs(notice, auth, who, &found);
+
+ /* note that when there are no subscriptions, found == 0, so
+ we needn't worry about answer being NULL since
+ ZFormatSmallRawNoticeList won't reference the pointer */
+
/* send 5 at a time until we are finished */
count = found?((found-1) / 5 + 1):1; /* total # to be sent */
i = 0; /* pkt # counter */
@@ -583,30 +656,34 @@ struct sockaddr_in *who;
packlen = sizeof(reppacket);
(void) sprintf(buf, "%d/%d", ++i, count);
reply.z_opcode = buf;
- retval = ZFormatRawNoticeList(&reply,
- answer+(initfound-found)*
- NUM_FIELDS,
- ((found > 5) ? 5 : found) * NUM_FIELDS,
- reppacket, packlen, &packlen);
+ retval = ZFormatSmallRawNoticeList(&reply,
+ answer+(initfound-found)*NUM_FIELDS,
+ ((found > 5) ? 5 : found)*NUM_FIELDS,
+ reppacket,
+ &packlen);
if (retval != ZERR_NONE) {
syslog(LOG_ERR, "subscr_sendlist format: %s",
error_message(retval));
- xfree(answer);
+ if (answer)
+ xfree(answer);
return;
}
- if ((retval = ZSendPacket(reppacket, packlen)) != ZERR_NONE) {
+ if ((retval = ZSendPacket(reppacket, packlen, 0)) != ZERR_NONE) {
syslog(LOG_WARNING, "subscr_sendlist xmit: %s",
error_message(retval));
- xfree(answer);
+ if (answer)
+ xfree(answer);
return;
}
found -= 5;
zerofound = 0;
}
zdbug((LOG_DEBUG,"subscr_sendlist acked"));
- xfree(answer);
+ if (answer)
+ xfree(answer);
return;
}
+#endif /* NEW_COMPAT */
#ifdef OLD_COMPAT
static void
@@ -687,7 +764,7 @@ struct sockaddr_in *who;
xfree(answer);
return;
}
- if ((retval = ZSendPacket(reppacket, packlen)) != ZERR_NONE) {
+ if ((retval = ZSendPacket(reppacket, packlen, 0)) != ZERR_NONE) {
syslog(LOG_WARNING, "subscr_sendlist xmit: %s",
error_message(retval));
xfree(answer);
@@ -697,7 +774,7 @@ struct sockaddr_in *who;
xfree(answer);
return;
}
-#endif OLD_COMPAT
+#endif /* OLD_COMPAT */
/*
* Send the client's subscriptions to another server
diff --git a/server/uloc.c b/server/uloc.c
index 168d810..ca375fa 100644
--- a/server/uloc.c
+++ b/server/uloc.c
@@ -90,12 +90,19 @@ typedef struct _ZLocation_t {
#define OLD_ZEPHYR_VERSION "ZEPH0.0"
#define LOGIN_QUIET_LOGIN "QUIET_LOGIN"
#endif /* OLD_COMPAT */
+#ifdef NEW_COMPAT
+#define NEW_OLD_ZEPHYR_VERSION "ZEPH0.1"
+#endif NEW_COMPAT
+#if defined(OLD_COMPAT) || defined(NEW_COMPAT)
+static void old_compat_ulogin_locate();
+#endif /* OLD_COMPAT || NEW_COMPAT */
static void ulogin_locate(), ulogin_add_user(), ulogin_flush_user();
static ZLocation_t *ulogin_find();
static int ulogin_setup(), ulogin_parse(), ul_equiv(), ulogin_expose_user();
static exposure_type ulogin_remove_user();
static void login_sendit(), sense_logout();
+static char **ulogin_marshal_locs();
static ZLocation_t *locations = NULLZLT; /* ptr to first in array */
static int num_locs = 0; /* number in array */
@@ -154,7 +161,7 @@ ZServerDesc_t *server;
case NET_ANN:
/* currently no distinction between these.
just announce */
- /* XXX we assume that if this user is at a certain
+ /* we assume that if this user is at a certain
IP address, we can trust the logout to be
authentic. ulogin_remove_user checks the
ip addrs */
@@ -308,7 +315,7 @@ struct sockaddr_in *who;
sense_notice.z_default_format = "Urgent Message from $sender at $time:\n\n$1";
sense_notice.z_message = "Someone tried an unauthentic logout for you";
sense_notice.z_message_len = strlen(sense_notice.z_message);
- sense_notice.z_uid = notice->z_uid;
+ sense_notice.z_uid = notice->z_multiuid;
/* transmit the message to the owning port of the location. */
xmit(&sense_notice, &owner, 0, NULLZCLT);
@@ -1037,31 +1044,74 @@ exposure_type exposure;
return(notfound);
}
-/*
- * Locate the user and send the locations in the acknowledgement to the client.
- */
static void
ulogin_locate(notice, who)
ZNotice_t *notice;
struct sockaddr_in *who;
{
+ char **answer;
+ int found;
+
+#if defined(NEW_COMPAT) || defined(OLD_COMPAT)
+ if (!strcmp(notice->z_version, NEW_OLD_ZEPHYR_VERSION) ||
+ !strcmp(notice->z_version, OLD_ZEPHYR_VERSION)) {
+ /* we are talking to a new old client; use the new-old-style
+ acknowledgement-message */
+ old_compat_ulogin_locate(notice, who);
+ return;
+ }
+#endif /* NEW_COMPAT || OLD_COMPAT */
+ answer = ulogin_marshal_locs(notice, who, &found);
+
+ if ((retval = ZSetDestAddr(who)) != ZERR_NONE) {
+ syslog(LOG_WARNING, "ulogin_locate set addr: %s",
+ error_message(retval));
+ if (answer)
+ xfree(answer);
+ return;
+ }
+
+ notice->z_kind = ACKED;
+
+ /* use xmit_frag() to send each piece of the notice */
+
+ if ((retval = ZSrvSendRawList(notice, answer, found*NUM_FIELDS,
+ xmit_frag))
+ != ZERR_NONE) {
+ syslog(LOG_WARNING, "ulog_locate xmit: %s",
+ error_message(retval));
+ }
+ if (answer)
+ xfree(answer);
+ return;
+}
+
+/*
+ * Locate the user and collect the locations into an array. Return the # of
+ * locations in *found.
+ */
+
+static char **
+ulogin_marshal_locs(notice, who, found)
+ZNotice_t *notice;
+struct sockaddr_in *who;
+register int *found;
+{
ZLocation_t **matches = (ZLocation_t **) 0;
ZLocation_t *loc;
char **answer;
register int i = 0;
- register int found = 0; /* # of matches */
- Code_t retval;
- ZNotice_t reply;
- ZPacket_t reppacket;
- int packlen;
+
+ *found = 0; /* # of matches */
if (!(loc = ulogin_find(notice, 0)))
/* not here anywhere */
- goto rep;
+ return(NULL);
i = loc - locations;
- while (i < num_locs && !strcmp(notice->z_class_inst, locations[i].zlt_user)) {
+ while ((i < num_locs) &&
+ !strcmp(notice->z_class_inst, locations[i].zlt_user)) {
/* these locations match */
zdbug((LOG_DEBUG,"match %s", locations[i].zlt_user));
switch (locations[i].zlt_exposure) {
@@ -1075,20 +1125,20 @@ struct sockaddr_in *who;
default:
break;
}
- if (!found) {
+ if (!*found) {
if ((matches = (ZLocation_t **) xmalloc(sizeof(ZLocation_t *))) == (ZLocation_t **) 0) {
syslog(LOG_ERR, "ulog_loc: no mem");
break; /* from the while */
}
matches[0] = &locations[i];
- found++;
+ (*found)++;
} else {
if ((matches = (ZLocation_t **) realloc((caddr_t) matches, (unsigned) ++found * sizeof(ZLocation_t *))) == (ZLocation_t **) 0) {
syslog(LOG_ERR, "ulog_loc: realloc no mem");
- found = 0;
+ *found = 0;
break; /* from the while */
}
- matches[found - 1] = &locations[i];
+ matches[*found - 1] = &locations[i];
}
i++;
}
@@ -1096,11 +1146,7 @@ struct sockaddr_in *who;
/* OK, now we have a list of user@host's to return to the client
in matches */
-rep:
- reply = *notice;
- reply.z_kind = SERVACK;
- packlen = sizeof(reppacket);
#ifdef DEBUG
if (zdebug) {
@@ -1122,11 +1168,30 @@ rep:
xfree(matches);
/* if it's too long, chop off one at a time till it fits */
- while ((retval = ZFormatRawNoticeList(&reply,
+}
+
+#if defined(OLD_COMPAT) || defined(NEW_COMPAT)
+static void
+old_compat_ulogin_locate(notice, who)
+ZNotice_t *notice;
+struct sockaddr_in *who;
+{
+ char **answer;
+ int found;
+ int packlen;
+ ZPacket_t reppacket;
+ ZNotice_t reply;
+ Code_t retval;
+
+ answer = ulogin_marshal_locs(notice, who, &found);
+
+ reply = *notice;
+ reply.z_kind = SERVACK;
+
+ while ((retval = ZFormatSmallRawNoticeList(&reply,
answer,
found * NUM_FIELDS,
reppacket,
- packlen,
&packlen)) == ZERR_PKTLEN)
found--;
@@ -1137,12 +1202,12 @@ rep:
return;
}
if ((retval = ZSetDestAddr(who)) != ZERR_NONE) {
- syslog(LOG_WARNING, "ulog_locate set addr: %s",
+ syslog(LOG_WARNING, "old_ulog_locate set addr: %s",
error_message(retval));
xfree(answer);
return;
}
- if ((retval = ZSendPacket(reppacket, packlen)) != ZERR_NONE) {
+ if ((retval = ZSendPacket(reppacket, packlen, 0)) != ZERR_NONE) {
syslog(LOG_WARNING, "ulog_locate xmit: %s",
error_message(retval));
xfree(answer);
@@ -1152,6 +1217,7 @@ rep:
xfree(answer);
return;
}
+#endif /* OLD_COMPAT || NEW_COMPAT */
void
uloc_dump_locs(fp)