added access control and put notify

This commit is contained in:
Jeff Hill
1994-03-30 11:31:53 +00:00
parent 3fc8e820c8
commit ca21dcce39
8 changed files with 1011 additions and 223 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -205,23 +205,6 @@ FAST int sock;
return ERROR;
}
i = sizeof(client->addr);
status = getpeername(
sock,
(struct sockaddr *)&client->addr,
&i);
if(status == ERROR){
logMsg("CAS: peer address fetch failed\n",
NULL,
NULL,
NULL,
NULL,
NULL,
NULL);
free_client(client);
return ERROR;
}
if(CASDEBUG>0){
logMsg( "CAS: Recieved connection request\n",
NULL,
@@ -240,7 +223,7 @@ FAST int sock;
}
LOCK_CLIENTQ;
ellAdd((ELLLIST *)&clientQ, (ELLNODE *)client);
ellAdd(&clientQ, &client->node);
UNLOCK_CLIENTQ;
client->evuser = (struct event_user *) db_init_events();
@@ -255,6 +238,21 @@ FAST int sock;
free_client(client);
return ERROR;
}
status = db_add_extra_labor_event(
client->evuser,
write_notify_reply,
client);
if(status == ERROR){
logMsg("CAS: unable to setup the event facility\n",
NULL,
NULL,
NULL,
NULL,
NULL,
NULL);
free_client(client);
return ERROR;
}
status = db_start_events(
client->evuser,
CA_EVENT_NAME,
@@ -320,7 +318,7 @@ FAST int sock;
break;
}
client->ticks_at_last_io = tickGet();
client->ticks_at_last_recv = tickGet();
client->recv.cnt += nchars;
status = camessage(client, &client->recv);
@@ -340,10 +338,10 @@ FAST int sock;
/*
* overlapping regions handled
* by bcopy
* by memmove
*/
bcopy( pbuf + client->recv.stk,
pbuf,
memmove(pbuf,
pbuf + client->recv.stk,
bytes_left);
client->recv.cnt = bytes_left;
}

View File

@@ -69,7 +69,7 @@ int lock_needed;
if(CASDEBUG>2){
logMsg( "CAS: Sending a message of %d bytes\n",
pclient->send.cnt,
pclient->send.stk,
NULL,
NULL,
NULL,
@@ -95,16 +95,15 @@ int lock_needed;
}
if(pclient->send.stk){
pclient->send.cnt = pclient->send.stk;
status = sendto(
pclient->sock,
pclient->send.buf,
pclient->send.cnt,
pclient->send.stk,
NULL,
(struct sockaddr *)&pclient->addr,
sizeof(pclient->addr));
if(status != pclient->send.cnt){
if(status != pclient->send.stk){
if(status < 0){
int anerrno;
@@ -133,7 +132,7 @@ int lock_needed;
else{
logMsg(
"CAS: blk sock partial send: req %d sent %d \n",
pclient->send.cnt,
pclient->send.stk,
status,
NULL,
NULL,
@@ -144,7 +143,7 @@ int lock_needed;
pclient->send.stk = 0;
pclient->ticks_at_last_io = tickGet();
pclient->ticks_at_last_send = tickGet();
}

View File

@@ -41,6 +41,7 @@
* .09 joh 022092 print free list statistics in client_stat()
* .10 joh 022592 print more statistics in client_stat()
* .11 joh 073093 added args to taskSpawn for v5.1 vxWorks
* .12 joh 020494 identifies the client in client_stat
*/
static char *sccsId = "$Id$";
@@ -68,6 +69,7 @@ static char *sccsId = "$Id$";
LOCAL int terminate_one_client(struct client *client);
LOCAL void log_one_client(struct client *client);
LOCAL unsigned long delay_in_ticks(unsigned long prev);
/*
@@ -146,14 +148,16 @@ int req_server(void)
while (TRUE) {
if ((i = accept(IOC_sock, NULL, 0)) == ERROR) {
logMsg("CAS: Accept error\n",
logMsg("CAS: Client accept error\n",
NULL,
NULL,
NULL,
NULL,
NULL,
NULL);
taskSuspend(0);
printErrno(errnoGet());
taskDelay(15*sysClkRateGet());
continue;
} else {
status = taskSpawn(CA_CLIENT_NAME,
CA_CLIENT_PRI,
@@ -186,7 +190,8 @@ int req_server(void)
NULL,
NULL);
printErrno(errnoGet());
close(i);
taskDelay(15*sysClkRateGet());
continue;
}
}
}
@@ -200,36 +205,22 @@ int req_server(void)
*/
int free_client(struct client *client)
{
if (client) {
/* remove it from the list of clients */
/* list delete returns no status */
LOCK_CLIENTQ;
ellDelete((ELLLIST *)&clientQ, (ELLNODE *)client);
UNLOCK_CLIENTQ;
terminate_one_client(client);
LOCK_CLIENTQ;
ellAdd((ELLLIST *)&rsrv_free_clientQ, (ELLNODE *)client);
UNLOCK_CLIENTQ;
} else {
LOCK_CLIENTQ;
while (client = (struct client *) ellGet(&clientQ))
terminate_one_client(client);
FASTLOCK(&rsrv_free_addrq_lck);
ellFree(&rsrv_free_addrq);
ellInit(&rsrv_free_addrq);
FASTUNLOCK(&rsrv_free_addrq_lck);
FASTLOCK(&rsrv_free_eventq_lck);
ellFree(&rsrv_free_eventq);
ellInit(&rsrv_free_eventq);
FASTUNLOCK(&rsrv_free_eventq_lck);
ellFree(&rsrv_free_clientQ);
UNLOCK_CLIENTQ;
if (!client) {
return ERROR;
}
/* remove it from the list of clients */
/* list delete returns no status */
LOCK_CLIENTQ;
ellDelete(&clientQ, &client->node);
UNLOCK_CLIENTQ;
terminate_one_client(client);
LOCK_CLIENTQ;
ellAdd(&rsrv_free_clientQ, &client->node);
UNLOCK_CLIENTQ;
return OK;
}
@@ -272,9 +263,9 @@ LOCAL int terminate_one_client(struct client *client)
* Server task deleted first since close() is not reentrant
*/
servertid = client->tid;
taskwdRemove(servertid);
if (servertid != taskIdSelf()){
if (taskIdVerify(servertid) == OK){
taskwdRemove(servertid);
if (taskDelete(servertid) == ERROR) {
printErrno(errnoGet());
}
@@ -283,14 +274,24 @@ LOCAL int terminate_one_client(struct client *client)
pciu = (struct channel_in_use *) & client->addrq;
while (pciu = (struct channel_in_use *) pciu->node.next){
while (pevext = (struct event_ext *) ellGet((ELLLIST *)&pciu->eventq)) {
/*
* put notify in progress needs to be deleted
*/
if(pciu->pPutNotify){
if(pciu->pPutNotify->busy){
dbNotifyCancel(&pciu->pPutNotify->dbPutNotify);
}
free(pciu->pPutNotify);
}
while (pevext = (struct event_ext *) ellGet(&pciu->eventq)) {
status = db_cancel_event(
(struct event_block *)(pevext + 1));
if (status == ERROR)
taskSuspend(0);
FASTLOCK(&rsrv_free_eventq_lck);
ellAdd((ELLLIST *)&rsrv_free_eventq, (ELLNODE *)pevext);
ellAdd(&rsrv_free_eventq, &pevext->node);
FASTUNLOCK(&rsrv_free_eventq_lck);
}
FASTLOCK(&rsrv_free_addrq_lck);
@@ -306,6 +307,16 @@ LOCAL int terminate_one_client(struct client *client)
NULL,
NULL);
}
status = asRemoveClient(&pciu->asClientPVT);
if(status){
logMsg( "%s Bad client PVD during client shutdown",
(int)__FILE__,
NULL,
NULL,
NULL,
NULL,
NULL);
}
}
if (client->evuser) {
@@ -339,6 +350,27 @@ LOCAL int terminate_one_client(struct client *client)
NULL);
}
status = semDelete(client->blockSem);
if(status != OK){
logMsg("CAS: couldnt free block sem\n",
NULL,
NULL,
NULL,
NULL,
NULL,
NULL);
}
if(client->pUserName){
free(client->pUserName);
}
if(client->pLocationName){
free(client->pLocationName);
}
client->minor_version_number = CA_UKN_MINOR_VERSION;
return OK;
}
@@ -352,14 +384,17 @@ int client_stat(void)
int bytes_reserved;
struct client *client;
printf( "Channel Access Server Status V%d.%d\n",
CA_PROTOCOL_VERSION,
CA_MINOR_VERSION);
LOCK_CLIENTQ;
client = (struct client *) ellNext((ELLNODE *)&clientQ);
client = (struct client *) ellNext(&clientQ);
while (client) {
log_one_client(client);
client = (struct client *) ellNext((ELLNODE *)client);
client = (struct client *) ellNext(&client->node);
}
UNLOCK_CLIENTQ;
@@ -375,7 +410,7 @@ int client_stat(void)
ellCount(&rsrv_free_eventq);
printf( "There are currently %d bytes on the server's free list\n",
bytes_reserved);
printf( "{%d client(s), %d channel(s), and %d event(s) (monitors)}\n",
printf( "%d client(s), %d channel(s), and %d event(s) (monitors)\n",
ellCount(&rsrv_free_clientQ),
ellCount(&rsrv_free_addrq),
ellCount(&rsrv_free_eventq));
@@ -401,8 +436,8 @@ LOCAL void log_one_client(struct client *client)
struct channel_in_use *pciu;
struct sockaddr_in *psaddr;
char *pproto;
unsigned long current;
unsigned long delay;
float send_delay;
float recv_delay;
unsigned long bytes_reserved;
char *state[] = {"up", "down"};
@@ -416,19 +451,24 @@ LOCAL void log_one_client(struct client *client)
pproto = "UKN";
}
current = tickGet();
if (current >= client->ticks_at_last_io) {
delay = current - client->ticks_at_last_io;
}
else {
delay = current + (~0L - client->ticks_at_last_io);
}
send_delay = delay_in_ticks(client->ticks_at_last_send);
recv_delay = delay_in_ticks(client->ticks_at_last_recv);
printf( "Socket=%d, Protocol=%s, tid=%x, secs since last interaction %d\n",
client->sock,
printf( "Client Name=%s, Client Location=%s, ver=%d.%u, server tid=%x\n",
client->pUserName,
client->pLocationName,
CA_PROTOCOL_VERSION,
client->minor_version_number,
client->tid);
printf( "\tProtocol=%s, Socket fd=%d\n",
pproto,
client->tid,
delay/sysClkRateGet());
client->sock);
printf( "\tSecs since last send %6.2f, Secs since last receive %6.2f\n",
send_delay/sysClkRateGet(),
recv_delay/sysClkRateGet());
printf( "\tUnprocessed request bytes=%d, Undelivered response bytes=%d\n",
client->send.stk,
client->recv.cnt - client->recv.stk);
bytes_reserved = 0;
bytes_reserved += sizeof(struct client);
@@ -437,12 +477,14 @@ LOCAL void log_one_client(struct client *client)
bytes_reserved += sizeof(struct channel_in_use);
bytes_reserved +=
(sizeof(struct event_ext)+db_sizeof_event_block())*
ellCount((ELLLIST *)&pciu->eventq);
pciu = (struct channel_in_use *) ellNext((ELLNODE *)pciu);
ellCount(&pciu->eventq);
if(pciu->pPutNotify){
bytes_reserved += sizeof(*pciu->pPutNotify);
bytes_reserved += pciu->pPutNotify->valueSize;
}
pciu = (struct channel_in_use *) ellNext(&pciu->node);
}
psaddr = &client->addr;
printf("\tRemote address %u.%u.%u.%u Remote port %d state=%s\n",
(psaddr->sin_addr.s_addr & 0xff000000) >> 24,
@@ -459,8 +501,31 @@ LOCAL void log_one_client(struct client *client)
printf( "\t%s(%d) ",
pciu->addr.precord,
pciu->eventq.count);
pciu = (struct channel_in_use *) ellNext((ELLNODE *)pciu);
pciu = (struct channel_in_use *) ellNext(&pciu->node);
}
printf("\n");
}
/*
* delay_in_ticks()
*/
unsigned long delay_in_ticks(unsigned long prev)
{
unsigned long delay;
unsigned long current;
current = tickGet();
if (current >= prev) {
delay = current - prev;
}
else {
delay = current + (ULONG_MAX - prev);
}
return delay;
}

View File

@@ -216,7 +216,7 @@ int cast_server(void)
prsrv_cast_client->recv.cnt = status;
prsrv_cast_client->recv.stk = 0;
prsrv_cast_client->ticks_at_last_io = tickGet();
prsrv_cast_client->ticks_at_last_recv = tickGet();
/*
* If we are talking to a new client flush the old one
@@ -337,7 +337,20 @@ clean_addrq(struct client *pclient)
}
if (delay > timeout) {
ellDelete((ELLLIST *)&pclient->addrq, (ELLNODE *)pciu);
int status;
ellDelete(&pclient->addrq, &pciu->node);
status = asRemoveClient(&pciu->asClientPVT);
if(status){
logMsg(
"%s Bad client PVD at close",
(int)__FILE__,
NULL,
NULL,
NULL,
NULL,
NULL);
}
FASTLOCK(&rsrv_free_addrq_lck);
s = bucketRemoveItem(pCaBucket, pciu->sid, pciu);
if(s != BUCKET_SUCCESS){
@@ -350,7 +363,7 @@ clean_addrq(struct client *pclient)
NULL,
NULL);
}
ellAdd((ELLLIST *)&rsrv_free_addrq, (ELLNODE *)pciu);
ellAdd(&rsrv_free_addrq, &pciu->node);
FASTUNLOCK(&rsrv_free_addrq_lck);
ndelete++;
maxdelay = max(delay, maxdelay);
@@ -413,10 +426,40 @@ struct client *create_udp_client(unsigned sock)
* 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);
* memset(client, 0, sizeof(*client));
*/
client->blockSem = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY);
if(!client->blockSem){
free(client);
return NULL;
}
/*
* user name initially unknown
*/
client->pUserName = malloc(1);
if(!client->pUserName){
semDelete(client->blockSem);
free(client);
return NULL;
}
client->pUserName[0] = '\0';
/*
* location name initially unknown
*/
client->pLocationName = malloc(1);
if(!client->pLocationName){
semDelete(client->blockSem);
free(client->pUserName);
free(client);
return NULL;
}
client->pLocationName[0] = '\0';
ellInit(&client->addrq);
ellInit(&client->putNotifyQue);
bfill((char *)&client->addr, sizeof(client->addr), 0);
client->tid = taskIdSelf();
client->send.stk = 0;
@@ -426,13 +469,16 @@ struct client *create_udp_client(unsigned sock)
client->evuser = NULL;
client->eventsoff = FALSE;
client->disconnect = FALSE; /* for TCP only */
client->ticks_at_last_io = tickGet();
client->ticks_at_last_send = tickGet();
client->ticks_at_last_recv = tickGet();
client->proto = IPPROTO_UDP;
client->sock = sock;
client->minor_version_number = CA_UKN_MINOR_VERSION;
client->send.maxstk = MAX_UDP-sizeof(client->recv.cnt);
FASTLOCKINIT(&client->lock);
FASTLOCKINIT(&client->putNotifyLock);
client->recv.maxstk = MAX_UDP;
@@ -452,6 +498,8 @@ struct client *client,
unsigned sock
)
{
int status;
int addrSize;
if(CASDEBUG>2){
logMsg("CAS: converting udp client to tcp\n",
@@ -469,6 +517,22 @@ unsigned sock
client->sock = sock;
client->tid = taskIdSelf();
addrSize = sizeof(client->addr);
status = getpeername(
sock,
(struct sockaddr *)&client->addr,
&addrSize);
if(status == ERROR){
logMsg("CAS: peer address fetch failed\n",
NULL,
NULL,
NULL,
NULL,
NULL,
NULL);
return ERROR;
}
return OK;
}

View File

@@ -124,7 +124,7 @@ int rsrv_online_notify_task()
bfill((char *)&recv_addr, sizeof recv_addr, 0);
recv_addr.sin_family = AF_INET;
recv_addr.sin_addr.s_addr = htonl(INADDR_ANY); /* let slib pick lcl addr */
recv_addr.sin_addr.s_addr = INADDR_ANY; /* let slib pick lcl addr */
recv_addr.sin_port = htons(0); /* let slib pick port */
status = bind(sock, (struct sockaddr *)&recv_addr, sizeof recv_addr);
if(status<0)

View File

@@ -46,7 +46,7 @@ static char *sccsId = "@(#)rsrv_init.c 1.7\t7/28/92";
#include <server.h>
#define DELETE_TASK(TID)\
if(errnoOfTaskGet(TID)!=ERROR)td(TID);
if(errnoOfTaskGet(TID)!=ERROR)taskDelete(TID);
/*
@@ -61,16 +61,17 @@ int rsrv_init()
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);
ellInit(&clientQ);
ellInit(&rsrv_free_clientQ);
ellInit(&rsrv_free_addrq);
ellInit(&rsrv_free_eventq);
prsrv_cast_client = NULL;
pCaBucket = NULL;
DELETE_TASK(taskNameToId(CAST_SRVR_NAME));
DELETE_TASK(taskNameToId(REQ_SRVR_NAME));
DELETE_TASK(taskNameToId(CA_ONLINE_NAME));
taskSpawn(REQ_SRVR_NAME,
REQ_SRVR_PRI,
REQ_SRVR_OPT,

View File

@@ -55,30 +55,56 @@ static char *serverhSccsId = "$Id$";
#include <iocmsg.h>
#include <bucketLib.h>
#include <asLib.h>
#include <asDbLib.h>
#if 1
#include <memDebugLib.h>
#endif
struct message_buffer{
unsigned stk;
unsigned maxstk;
int cnt;
unsigned long stk;
unsigned long maxstk;
long cnt;
char buf[MAX_MSG_SIZE];
};
struct client{
ELLNODE node;
int sock;
int proto;
FAST_LOCK lock;
FAST_LOCK putNotifyLock;
ELLLIST addrq;
ELLLIST putNotifyQue;
struct message_buffer send;
struct message_buffer recv;
struct sockaddr_in addr;
unsigned long ticks_at_last_send;
unsigned long ticks_at_last_recv;
void *evuser;
SEM_ID blockSem; /* used whenever the client blocks */
int sock;
int proto;
int tid;
unsigned minor_version_number;
char eventsoff;
char disconnect; /* disconnect detected */
unsigned long ticks_at_last_io;
char *pUserName;
char *pLocationName;
};
/*
* for tracking db put notifies
*/
typedef struct rsrv_put_notify{
ELLNODE node;
PUTNOTIFY dbPutNotify;
struct extmsg msg;
unsigned long valueSize; /* size of block pointed to by dbPutNotify */
int busy; /* put notify in progress */
}RSRVPUTNOTIFY;
/*
* per channel structure
* (stored in addrq off of a client block)
@@ -86,11 +112,13 @@ struct client{
struct channel_in_use{
ELLNODE node;
ELLLIST eventq;
struct db_addr addr;
struct client *client;
RSRVPUTNOTIFY *pPutNotify; /* potential active put notify */
unsigned long cid; /* client id */
unsigned long sid; /* server id */
unsigned long ticks_at_creation; /* for UDP timeout */
struct db_addr addr;
ASCLIENTPVT asClientPVT;
};
@@ -119,14 +147,14 @@ char get; /* T: get F: monitor */
# define GLBLTYPE_INIT(A)
#endif
GLBLTYPE int CASDEBUG;
GLBLTYPE int IOC_sock;
GLBLTYPE int IOC_cast_sock;
GLBLTYPE ELLLIST clientQ; /* locked by clientQlock */
GLBLTYPE ELLLIST rsrv_free_clientQ; /* locked by clientQlock */
GLBLTYPE ELLLIST clientQ; /* locked by clientQlock */
GLBLTYPE ELLLIST rsrv_free_clientQ; /* locked by clientQlock */
GLBLTYPE ELLLIST rsrv_free_addrq;
GLBLTYPE ELLLIST rsrv_free_eventq;
GLBLTYPE FAST_LOCK clientQlock;
GLBLTYPE int CASDEBUG;
GLBLTYPE ELLLIST rsrv_free_addrq;
GLBLTYPE ELLLIST rsrv_free_eventq;
GLBLTYPE FAST_LOCK rsrv_free_addrq_lck;
GLBLTYPE FAST_LOCK rsrv_free_eventq_lck;
GLBLTYPE struct client *prsrv_cast_client;
@@ -180,5 +208,15 @@ void cas_send_heartbeat(
struct client *pc
);
void write_notify_reply(void *pArg);
#endif INCLserverh
/*
* !!KLUDGE!!
*
* this was extracted from dbAccess.h because we are unable
* to include both dbAccess.h and db_access.h at the
* same time.
*/
#define S_db_Blocked (M_dbAccess|39) /*Request is Blocked*/
#endif /*INCLserverh*/