From e56c2ace4419f2cce294360ecf85e9402350f09d Mon Sep 17 00:00:00 2001 From: Bob Zieman Date: Wed, 17 Oct 1990 10:17:17 +0000 Subject: [PATCH] Initial revision --- src/rsrv/cast_server.c | 244 ++++++++++++++++++++++++++++++++++++++++ src/rsrv/globalsource.c | 25 ++++ src/rsrv/rsrv_init.c | 49 ++++++++ src/rsrv/server.h | 121 ++++++++++++++++++++ 4 files changed, 439 insertions(+) create mode 100644 src/rsrv/cast_server.c create mode 100644 src/rsrv/globalsource.c create mode 100644 src/rsrv/rsrv_init.c create mode 100644 src/rsrv/server.h diff --git a/src/rsrv/cast_server.c b/src/rsrv/cast_server.c new file mode 100644 index 000000000..e618a7b0f --- /dev/null +++ b/src/rsrv/cast_server.c @@ -0,0 +1,244 @@ + +/* cast_server.c */ +/* share/src/rsrv $Id$ */ + +/* The IOC connection request server */ +/* +******************************************************************************* +** GTA PROJECT +** Copyright 1988, The Regents of the University of California. +** Los Alamos National Laboratory +** Los Alamos New Mexico 87845 +** cast_server.c - GTA request server main loop +** Sun UNIX 4.2 Release 3.4 +** First Release- Jeff Hill May 88 +******************************************************************************* +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +STATUS +cast_server() +{ + struct sockaddr_in sin; + FAST int status; + int i; + FAST struct client *client; + FAST struct client *tmpclient = NULL; + struct sockaddr_in recv_addr; + int recv_addr_size = sizeof(recv_addr); + unsigned nchars; + static struct message_buffer udp_msg; +# define TIMEOUT 60*5 /* sec */ + unsigned long timeout = TIMEOUT * sysClkRateGet(); + + struct client *existing_client(); + struct client *create_udp_client(); + + if( IOC_cast_sock!=0 && IOC_cast_sock!=ERROR ) + if( (status = close(IOC_cast_sock)) == ERROR ) + logMsg("Unable to close open master socket\n"); + + /* + * Open the socket. + * Use ARPA Internet address format and datagram socket. + * Format described in . + */ + + if((IOC_cast_sock = socket (AF_INET, SOCK_DGRAM, 0)) == ERROR){ + logMsg("Socket creation error\n"); + printErrno (errnoGet ()); + taskSuspend(0); + } + + + /* Zero the sock_addr structure */ + bfill(&sin, sizeof(sin), 0); + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = INADDR_ANY; + sin.sin_port = SERVER_NUM; + + /* get server's Internet address */ + if (bind (IOC_cast_sock, &sin, sizeof (sin)) == ERROR){ + logMsg("Bind error\n"); + printErrno (errnoGet ()); + close (IOC_cast_sock); + taskSuspend(0); + } + + + bfill(&udp_msg, sizeof(udp_msg), NULL); + + while(TRUE){ + + status = recvfrom( IOC_cast_sock, + &udp_msg.cnt, + sizeof(udp_msg.cnt)+sizeof(udp_msg.buf), + NULL, + &recv_addr, + &recv_addr_size); + if(status<0){ + logMsg("Cast_server: UDP recieve error\n"); + printErrno(errnoGet ()); + taskSuspend(0); + } + + if(status != udp_msg.cnt){ + logMsg("Cast_server: Recieved a corrupt broadcast\n"); + continue; + } + + if(MPDEBUG==2){ + logMsg( "cast_server(): recieved a broadcast of %d bytes\n", status); + logMsg( "from addr %x, port %x \n", + recv_addr.sin_addr, + recv_addr.sin_port); + } + + /* subtract header size */ + udp_msg.cnt -= sizeof(udp_msg.cnt); + + /* setup new client structure but, reuse old structure if possible */ + LOCK_CLIENTQ; + client = existing_client(&recv_addr); + if(!client){ + if(tmpclient){ + client = tmpclient; + tmpclient = NULL; + } + else + client = create_udp_client(IOC_cast_sock); + if(!client){ + UNLOCK_CLIENTQ; + continue; + } + + client->addr = recv_addr; + client->ticks_at_creation = tickGet(); + lstAdd(&clientQ, client); + } + + if(MPDEBUG==2) + i = client->addrq.count; + + message_process(client, &udp_msg); + + /* remove client data structure from list if channel not found */ + if(client->addrq.count){ + if(MPDEBUG==2) + logMsg( "Found %d new channel name matches (%d cumulative)\n", + client->addrq.count-i, + client->addrq.count); + } + else{ + lstDelete(&clientQ, client); + if(!tmpclient) + tmpclient = client; + else + free(client); + } + + /* + allow message to batch up if more are comming + */ + status = ioctl(IOC_cast_sock, FIONREAD, &nchars); + if(status == ERROR){ + printErrno(errnoGet(0)); + taskSuspend(0); + } + if(nchars == 0){ + client = (struct client *) &clientQ; + while(client = (struct client *) client->node.next) + send_msg(client); + + clean_clientq(timeout); + } + UNLOCK_CLIENTQ; + + } +} + + + + +struct client +*create_udp_client(sock) +unsigned sock; +{ + struct client *client; + + client = (struct client *)malloc(sizeof(struct client)); + if(!client){ + printErrno(errnoGet ()); + return NULL; + } + + if(MPDEBUG==2) + logMsg( "cast_server(): Creating data structures for new udp client\n"); + +/* + The following inits to zero done instead of a bfill since + the send and recv buffers are large and don't need initialization. + + bfill(client, sizeof(*client), NULL); +*/ + lstInit(&client->addrq); + lstInit(&client->eventq); + client->tid = 0; + client->send.stk = 0; + client->send.cnt = 0; + client->recv.stk = 0; + client->recv.cnt = 0; + client->evuser = NULL; + client->eventsoff = FALSE; + + client->proto = IPPROTO_UDP; + client->send.maxstk = MAX_UDP-sizeof(client->recv.cnt); + FASTLOCKINIT(&client->send.lock); + + client->recv.maxstk = MAX_UDP; + FASTLOCKINIT(&client->recv.lock); + + client->sock = sock; + + return client; +} + + +/* + send lock must be applied + +*/ +udp_to_tcp(client,sock) +struct client *client; +unsigned sock; +{ + + if(MPDEBUG==2) + logMsg("cast_server(): converting udp client to tcp\n"); + + client->proto = IPPROTO_TCP; + client->send.maxstk = MAX_TCP; + client->recv.maxstk = MAX_TCP; + client->sock = sock; + + return OK; +} + + + + + + + diff --git a/src/rsrv/globalsource.c b/src/rsrv/globalsource.c new file mode 100644 index 000000000..a6f61a473 --- /dev/null +++ b/src/rsrv/globalsource.c @@ -0,0 +1,25 @@ + +/* globalsource.c */ +/* share/src/rsrv $Id$ */ + +/* +******************************************************************************* +** GTA PROJECT +** Copyright 1988, The Regents of the University of California. +** Los Alamos National Laboratory +** Los Alamos New Mexico 87845 +** inmsgtask0.c - GTA request server message reader task. +** Sun UNIX 4.2 Release 3.4 +** Bob Dingler February 11, 1988 +******************************************************************************* +*/ +#define GLBLSOURCE + + +#include +#include +#include +#include +#include +#include +#include diff --git a/src/rsrv/rsrv_init.c b/src/rsrv/rsrv_init.c new file mode 100644 index 000000000..cf7a3ea57 --- /dev/null +++ b/src/rsrv/rsrv_init.c @@ -0,0 +1,49 @@ + +/* rsrv_init.c */ +/* share/src/rsrv $Id$ */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DELETE_TASK(TID)\ +if(errnoOfTaskGet(TID)!=ERROR)td(TID); + +rsrv_init() +{ + FAST struct client *client; + void req_server(); + void cast_server(); + + FASTLOCKINIT(&rsrv_free_addrq_lck); + FASTLOCKINIT(&rsrv_free_eventq_lck); + FASTLOCKINIT(&clientQlock); + + /* + the following is based on the assumtion that external variables + are not reloaded when debugging. + NOTE: NULL below specifies all clients + */ + free_client(NULL); + + + DELETE_TASK(taskNameToId(CAST_SRVR_NAME)); + DELETE_TASK(taskNameToId(REQ_SRVR_NAME)); + taskSpawn( REQ_SRVR_NAME, + REQ_SRVR_PRI, + REQ_SRVR_OPT, + REQ_SRVR_STACK, + req_server); + + taskSpawn( CAST_SRVR_NAME, + CAST_SRVR_PRI, + CAST_SRVR_OPT, + CAST_SRVR_STACK, + cast_server); +} diff --git a/src/rsrv/server.h b/src/rsrv/server.h new file mode 100644 index 000000000..7fc22d586 --- /dev/null +++ b/src/rsrv/server.h @@ -0,0 +1,121 @@ + +/* server.h */ +/* share/src/rsrv $Id$ */ + +#ifndef INCLfast_lockh +#include +#endif + +#include + +/* buf & cnt must be contiguous */ +/* cnt must be first */ +/* buf must be second */ + +struct message_buffer{ + unsigned stk; + unsigned maxstk; + FAST_LOCK lock; + int cnt; + char buf[MAX_MSG_SIZE]; +}; + +struct client{ + NODE node; + int sock; + int proto; + LIST addrq; + LIST eventq; + struct message_buffer send; + struct message_buffer recv; + struct sockaddr_in addr; + void *evuser; + char eventsoff; + unsigned long ticks_at_creation; /* for UDP timeout */ + int tid; +}; + +/* +Event block extension for channel access +some things duplicated for speed +*/ +struct event_ext{ +NODE node; +struct extmsg msg; +struct extmsg *mp; /* for speed */ +struct client *client; +char modified; /* modified while event flow control applied */ +}; + + +/* NOTE: external used so they remember the state across loads */ +#ifdef GLBLSOURCE +# define GLBLTYPE +# define GLBLTYPE_INIT(A) +#else +# define GLBLTYPE extern +# define GLBLTYPE_INIT(A) +#endif +LOCAL keyed; + +GLBLTYPE int IOC_sock; +GLBLTYPE int IOC_cast_sock; +GLBLTYPE LIST clientQ; +GLBLTYPE FAST_LOCK clientQlock; +GLBLTYPE int MPDEBUG; +GLBLTYPE LIST rsrv_free_addrq; +GLBLTYPE LIST rsrv_free_eventq; +GLBLTYPE FAST_LOCK rsrv_free_addrq_lck; +GLBLTYPE FAST_LOCK rsrv_free_eventq_lck; + +#define LOCK_SEND(CLIENT)\ +FASTLOCK(&(CLIENT)->send.lock); + +#define UNLOCK_SEND(CLIENT)\ +FASTUNLOCK(&(CLIENT)->send.lock); + +#define EXTMSGPTR(CLIENT)\ + ((struct extmsg *) &(CLIENT)->send.buf[(CLIENT)->send.stk]) + +#define ALLOC_MSG(CLIENT, EXTSIZE)\ + (struct extmsg *)\ + ((CLIENT)->send.stk + (EXTSIZE) + sizeof(struct extmsg) > \ + (CLIENT)->send.maxstk ? send_msg_nolock(CLIENT): NULL,\ + (CLIENT)->send.stk + (EXTSIZE) + sizeof(struct extmsg) >\ + (CLIENT)->send.maxstk ? NULL : EXTMSGPTR(CLIENT)) + +#define END_MSG(CLIENT)\ + (CLIENT)->send.stk += sizeof(struct extmsg) + EXTMSGPTR(CLIENT)->m_postsize + +/* send with lock */ +#define send_msg(CLIENT)\ + {LOCK_SEND(CLIENT); send_msg_nolock(CLIENT); UNLOCK_SEND(CLIENT)}; + +/* send with empty test */ +#define send_msg_nolock(CLIENT)\ +!(CLIENT)->send.stk ? FALSE: send_msg_actual(CLIENT) + +/* vanilla send */ +#define send_msg_actual(CLIENT)\ +(\ + (CLIENT)->send.cnt = (CLIENT)->send.stk + sizeof((CLIENT)->send.cnt),\ + (CLIENT)->send.stk = 0,\ + MPDEBUG==2?logMsg("Sent a message of %d bytes\n",(CLIENT)->send.cnt):NULL,\ + sendto ( (CLIENT)->sock, \ + &(CLIENT)->send.cnt, \ + (CLIENT)->send.cnt, \ + 0,\ + &(CLIENT)->addr,\ + sizeof((CLIENT)->addr))==ERROR?LOG_SEND_ERROR:TRUE\ +) + +#define LOG_SEND_ERROR\ +(logMsg("Send_msg() unable to send, connection broken? %\n"),\ +printErrno(errnoGet()),\ +FALSE) + +#define LOCK_CLIENTQ\ +FASTLOCK(&clientQlock) + +#define UNLOCK_CLIENTQ\ +FASTUNLOCK(&clientQlock)