Initial revision
This commit is contained in:
244
src/rsrv/cast_server.c
Normal file
244
src/rsrv/cast_server.c
Normal 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
25
src/rsrv/globalsource.c
Normal 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
49
src/rsrv/rsrv_init.c
Normal 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
121
src/rsrv/server.h
Normal 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)
|
Reference in New Issue
Block a user