diff options
author | John Kohl <jtkohl@mit.edu> | 1988-06-15 18:50:12 +0000 |
---|---|---|
committer | John Kohl <jtkohl@mit.edu> | 1988-06-15 18:50:12 +0000 |
commit | 1ccc10d123d9f6bb34254f34ed14997aa76739c7 (patch) | |
tree | b5293a77ccdb79ea8034764634cc4b7546948af2 /server | |
parent | b68a61bbdea8bac1d245bf726ef4dc61e9b2be2b (diff) |
new library fixes
Diffstat (limited to 'server')
-rw-r--r-- | server/dispatch.c | 99 | ||||
-rw-r--r-- | server/subscr.c | 145 | ||||
-rw-r--r-- | server/uloc.c | 114 |
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, + ¬icepack, + &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, + ¬icepack, &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, ¬ice->z_uid)) { + if (ZCompareUID(&nacked->na_uid, ¬ice->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) |