From bd1dcdb1eb79997f3dea268a7c3963857fb36f6a Mon Sep 17 00:00:00 2001 From: "David C. Jedlinsky" Date: Tue, 6 Oct 1987 16:37:31 +0000 Subject: Initial revision --- zhm/zhm_client.c | 82 +++++++++++++++++++ zhm/zhm_server.c | 235 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 317 insertions(+) create mode 100644 zhm/zhm_client.c create mode 100644 zhm/zhm_server.c (limited to 'zhm') diff --git a/zhm/zhm_client.c b/zhm/zhm_client.c new file mode 100644 index 0000000..fdd55fe --- /dev/null +++ b/zhm/zhm_client.c @@ -0,0 +1,82 @@ +/* This file is part of the Project Athena Zephyr Notification System. + * It contains the hostmanager <--> client interaction routines. + * + * Created by: David C. Jedlinsky + * + * $Source$ + * $Author$ + * + * Copyright (c) 1987 by the Massachusetts Institute of Technology. + * For copying and distribution information, see the file + * "mit-copyright.h". + */ + +#include "hm.h" + +#ifndef lint +#ifndef SABER +static char rcsid_hm_client_c[] = "$Header$"; +#endif SABER +#endif lint + +extern int no_server, timeout_type, nclt; +extern struct sockaddr_in cli_sin, serv_sin, from; + +transmission_tower(notice, packet, pak_len) + ZNotice_t *notice; + caddr_t packet; + int pak_len; +{ + ZNotice_t gack; + Code_t ret; + struct sockaddr_in gsin; + int tleft; + + nclt++; + if (notice->z_kind == HMCTL) { + if (!strcmp(notice->z_opcode, CLIENT_FLUSH)) + send_flush_notice(HM_FLUSH); + else if (!strcmp(notice->z_opcode, CLIENT_NEW_SERVER)) + new_server(NULL); + else + syslog (LOG_INFO, "Bad control notice from client."); + } else + if (notice->z_kind != UNSAFE) { + gack = *notice; + gack.z_kind = HMACK; + gack.z_message_len = 0; + gsin = cli_sin; + gsin.sin_port = from.sin_port; + if (gack.z_port == 0) + gack.z_port = from.sin_port; + DPR2 ("Client Port = %u\n", ntohs(gack.z_port)); + notice->z_port = gack.z_port; + if ((ret = ZSetDestAddr(&gsin)) != ZERR_NONE) { + Zperr(ret); + com_err("hm", ret, "setting destination"); + } + /* Bounce ACK to library */ + if ((ret = ZSendRawNotice(&gack)) != ZERR_NONE) { + Zperr(ret); + com_err("hm", ret, "sending raw notice"); + } + } + if (!no_server) { + DPR2 ("Server Port = %u\n", ntohs(serv_sin.sin_port)); + if ((ret = ZSetDestAddr(&serv_sin)) != ZERR_NONE) { + Zperr(ret); + com_err("hm", ret, "setting destination"); + } + if ((ret = ZSendRawNotice(notice)) != ZERR_NONE) { + Zperr(ret); + com_err("hm", ret, "while sending raw notice"); + } + if ((tleft = alarm(0)) > 0) + (void)alarm(tleft); + else { + timeout_type = NOTICES; + (void)alarm(NOTICE_TIMEOUT); + } + } + (void)add_notice_to_queue(notice, packet, &gsin, pak_len); +} diff --git a/zhm/zhm_server.c b/zhm/zhm_server.c new file mode 100644 index 0000000..90b82fb --- /dev/null +++ b/zhm/zhm_server.c @@ -0,0 +1,235 @@ +/* This file is part of the Project Athena Zephyr Notification System. + * It contains the hostmanager <--> server interaction routines. + * + * Created by: David C. Jedlinsky + * + * $Source$ + * $Author$ + * + * Copyright (c) 1987 by the Massachusetts Institute of Technology. + * For copying and distribution information, see the file + * "mit-copyright.h". + */ + +#include "hm.h" + +#ifndef lint +#ifndef SABER +static char rcsid_hm_server_c[] = "$Header$"; +#endif SABER +#endif lint + +int serv_loop = 0; +extern u_short cli_port; +extern struct sockaddr_in serv_sin, from; +extern int timeout_type, hmdebug, nservchang, booting, nserv, no_server; +extern char **serv_list, **cur_serv_list; +extern char cur_serv[], prim_serv[]; + +/* Argument is whether we are actually booting, or just attaching + after a server switch */ +send_boot_notice(op) + char *op; +{ + ZNotice_t notice; + Code_t ret; + + /* Set up server notice */ + notice.z_kind = HMCTL; + notice.z_port = cli_port; + notice.z_class = ZEPHYR_CTL_CLASS; + notice.z_class_inst = ZEPHYR_CTL_HM; + notice.z_opcode = op; + notice.z_sender = "HM"; + notice.z_recipient = ""; + notice.z_default_format = 0; + notice.z_message_len = 0; + + /* Notify server that this host is here */ + if ((ret = ZSetDestAddr(&serv_sin)) != ZERR_NONE) { + Zperr(ret); + com_err("hm", ret, "setting destination"); + } + if ((ret = ZSendNotice(¬ice, ZNOAUTH)) != ZERR_NONE) { + Zperr(ret); + com_err("hm", ret, "sending startup notice"); + } + timeout_type = BOOTING; + (void)alarm(SERV_TIMEOUT); +} + +/* Argument is whether we are detaching or really going down */ +send_flush_notice(op) + char *op; +{ + ZNotice_t notice; + Code_t ret; + + /* Set up server notice */ + notice.z_kind = HMCTL; + notice.z_port = cli_port; + notice.z_class = ZEPHYR_CTL_CLASS; + notice.z_class_inst = ZEPHYR_CTL_HM; + notice.z_opcode = op; + notice.z_sender = "HM"; + notice.z_recipient = ""; + notice.z_default_format = 0; + notice.z_message_len = 0; + + /* Tell server to lose us */ + if ((ret = ZSetDestAddr(&serv_sin)) != ZERR_NONE) { + Zperr(ret); + com_err("hm", ret, "setting destination"); + } + if ((ret = ZSendNotice(¬ice, ZNOAUTH)) != ZERR_NONE) { + Zperr(ret); + com_err("hm", ret, "sending flush notice"); + } +} + +find_next_server(sugg_serv) + char *sugg_serv; +{ + struct hostent *hp; + int done = 0; + char **parse = serv_list; + + if (sugg_serv) { + do { + if (!strcmp(*parse, sugg_serv)) + done = 1; + } while ((done == 0) && (*++parse != NULL)); + } + if (done) { + if (hmdebug) + syslog(LOG_DEBUG, "Suggested server: %s\n", sugg_serv); + hp = gethostbyname(sugg_serv); + DPR2 ("Server = %s\n", sugg_serv); + (void)strcpy(cur_serv, sugg_serv); + } else { + if ((++serv_loop > 3) && (strcmp(cur_serv, prim_serv))) { + serv_loop = 0; + hp = gethostbyname(prim_serv); + DPR2 ("Server = %s\n", prim_serv); + (void)strcpy(cur_serv, prim_serv); + } else + do { + if (*++cur_serv_list == NULL) + cur_serv_list = serv_list; + if (strcmp(*cur_serv_list, cur_serv)) { + hp = gethostbyname(*cur_serv_list); + DPR2 ("Server = %s\n", *cur_serv_list); + (void)strcpy(cur_serv, *cur_serv_list); + done = 1; + } + } while (done == 0); + } + bcopy(hp->h_addr, &serv_sin.sin_addr, hp->h_length); + nservchang++; +} + +server_manager(notice) + ZNotice_t *notice; +{ + if ((bcmp(&serv_sin.sin_addr, &from.sin_addr, 4) != 0) || + (serv_sin.sin_port != from.sin_port)) { + syslog (LOG_INFO, "Bad notice from port %u.", notice->z_port); + } else { + /* This is our server, handle the notice */ + booting = 0; + DPR ("A notice came in from the server.\n"); + nserv++; + switch(notice->z_kind) { + case HMCTL: + hm_control(notice); + break; + case SERVNAK: + case SERVACK: + send_back(notice); + break; + default: + syslog (LOG_INFO, "Bad notice kind!?"); + break; + } + } +} + +hm_control(notice) + ZNotice_t *notice; +{ + Code_t ret; + struct hostent *hp; + char suggested_server[64]; + long addr; + + DPR("Control message!\n"); + if (!strcmp(notice->z_opcode, SERVER_SHUTDOWN)) { + if (notice->z_message_len) { + addr = inet_addr(notice->z_message); + if ((hp = gethostbyaddr(&addr, + 4, + AF_INET)) != NULL) { + (void)strcpy(suggested_server, hp->h_name); + new_server(suggested_server); + } else + new_server(NULL); + } + else + new_server(NULL); + } else if (!strcmp(notice->z_opcode, SERVER_PING)) { + if (no_server) + (void)alarm(0); + notice->z_kind = HMACK; + if ((ret = ZSetDestAddr(&serv_sin)) != ZERR_NONE) { + Zperr(ret); + com_err("hm", ret, "setting destination"); + } + if ((ret = ZSendRawNotice(notice)) != ZERR_NONE) { + Zperr(ret); + com_err("hm", ret, "sending ACK"); + } + if (no_server) { + no_server = 0; + retransmit_queue(&serv_sin); + } + } else + syslog (LOG_INFO, "Bad control message."); +} + +send_back(notice) + ZNotice_t *notice; +{ + ZNotice_Kind_t kind; + struct sockaddr_in repl; + Code_t ret; + + if (no_server) + (void)alarm(0); + if (!strcmp(notice->z_opcode, HM_BOOT) || + !strcmp(notice->z_opcode, HM_ATTACH)) { + /* ignore message, just an ack from boot */ + } else { + if (remove_notice_from_queue(notice, &kind, + &repl) != ZERR_NONE) { + syslog (LOG_INFO, "Hey! This packet isn't in my queue!"); + } else { + /* check if client wants an ACK, and send it */ + if (kind == ACKED) { + DPR2 ("Client ACK port: %u\n", ntohs(repl.sin_port)); + if ((ret = ZSetDestAddr(&repl)) != ZERR_NONE) { + Zperr(ret); + com_err("hm", ret, "setting destination"); + } + if ((ret = ZSendRawNotice(notice)) != ZERR_NONE) { + Zperr(ret); + com_err("hm", ret, "sending ACK"); + } + } + } + } + if (no_server) { + no_server = 0; + retransmit_queue(&serv_sin); + } +} + -- cgit v1.2.3