Initial revision

This commit is contained in:
Bob Zieman
1990-10-17 10:17:17 +00:00
parent 529a123544
commit e56c2ace44
4 changed files with 439 additions and 0 deletions

244
src/rsrv/cast_server.c Normal file
View File

@ -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 <vxWorks.h>
#include <lstLib.h>
#include <taskLib.h>
#include <types.h>
#include <socket.h>
#include <ioLib.h>
#include <in.h>
#include <db_access.h>
#include <taskParams.h>
#include <server.h>
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 <sys/socket.h>.
*/
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;
}

25
src/rsrv/globalsource.c Normal file
View File

@ -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 <vxWorks.h>
#include <lstLib.h>
#include <types.h>
#include <socket.h>
#include <in.h>
#include <db_access.h>
#include <server.h>

49
src/rsrv/rsrv_init.c Normal file
View File

@ -0,0 +1,49 @@
/* rsrv_init.c */
/* share/src/rsrv $Id$ */
#include <vxWorks.h>
#include <lstLib.h>
#include <taskLib.h>
#include <types.h>
#include <socket.h>
#include <in.h>
#include <db_access.h>
#include <taskParams.h>
#include <server.h>
#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);
}

121
src/rsrv/server.h Normal file
View File

@ -0,0 +1,121 @@
/* server.h */
/* share/src/rsrv $Id$ */
#ifndef INCLfast_lockh
#include <fast_lock.h>
#endif
#include <iocmsg.h>
/* 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)