quick disconnect changes
This commit is contained in:
@@ -628,6 +628,9 @@ int ca_task_initialize()
|
||||
assert(status == OK);
|
||||
}
|
||||
#endif /*vxWorks*/
|
||||
#ifdef VMS
|
||||
setupConnectionTimer();
|
||||
#endif
|
||||
}
|
||||
return ECA_NORMAL;
|
||||
}
|
||||
@@ -971,6 +974,9 @@ LOCAL void ca_process_exit()
|
||||
ca_printf("CAC: entering the exit handler 2 %x\n", tid);
|
||||
# endif
|
||||
|
||||
#ifdef VMS
|
||||
removeConnectionTimer();
|
||||
#endif
|
||||
# if defined(vxWorks)
|
||||
|
||||
ca_temp = (struct ca_static *)
|
||||
@@ -1261,25 +1267,7 @@ LOCAL void ca_process_exit()
|
||||
/*
|
||||
* free beacon hash table
|
||||
*/
|
||||
{
|
||||
int len;
|
||||
bhe **ppBHE;
|
||||
bhe *pBHE;
|
||||
|
||||
len = NELEMENTS(ca_temp->ca_beaconHash);
|
||||
for( ppBHE = ca_temp->ca_beaconHash;
|
||||
ppBHE < &ca_temp->ca_beaconHash[len];
|
||||
ppBHE++){
|
||||
pBHE = *ppBHE;
|
||||
while(pBHE){
|
||||
bhe *pOld;
|
||||
|
||||
pOld = pBHE;
|
||||
pBHE = pBHE->pNext;
|
||||
free(pOld);
|
||||
}
|
||||
}
|
||||
}
|
||||
freeBeaconHash(ca_temp);
|
||||
|
||||
free((char *)ca_temp);
|
||||
ca_static = (struct ca_static *) NULL;
|
||||
@@ -3063,8 +3051,6 @@ int early;
|
||||
return ECA_EVDISALLOW;
|
||||
}
|
||||
|
||||
manage_conn(TRUE);
|
||||
|
||||
/*
|
||||
* Flush the send buffers
|
||||
*/
|
||||
@@ -3147,8 +3133,6 @@ int early;
|
||||
return ECA_TIMEOUT;
|
||||
}
|
||||
}
|
||||
|
||||
manage_conn(TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3424,13 +3408,38 @@ struct ioc_in_use *piiu;
|
||||
piiu->send_needed = TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* echo_request (lock must be on)
|
||||
*
|
||||
*/
|
||||
#ifdef __STDC__
|
||||
void echo_request(struct ioc_in_use *piiu)
|
||||
#else /*__STDC__*/
|
||||
void echo_request(piiu)
|
||||
struct ioc_in_use *piiu;
|
||||
#endif /*__STDC__*/
|
||||
{
|
||||
struct extmsg hdr;
|
||||
|
||||
hdr.m_cmmd = htons(IOC_ECHO);
|
||||
hdr.m_type = htons(0);
|
||||
hdr.m_count = htons(0);
|
||||
hdr.m_cid = htons(0);
|
||||
hdr.m_available = htons(0);
|
||||
hdr.m_postsize = 0;
|
||||
|
||||
cac_push_msg(piiu, &hdr, NULL);
|
||||
|
||||
piiu->send_needed = TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* NOOP_MSG (lock must be on)
|
||||
*
|
||||
* now allows variable size NOOP message
|
||||
*
|
||||
*/
|
||||
#ifdef __STDC__
|
||||
void noop_msg(struct ioc_in_use *piiu)
|
||||
|
||||
296
src/ca/conn.c
296
src/ca/conn.c
@@ -59,14 +59,74 @@ void manage_conn(silent)
|
||||
int silent;
|
||||
#endif
|
||||
{
|
||||
struct ioc_in_use *piiu;
|
||||
chid chix;
|
||||
unsigned int retry_cnt = 0;
|
||||
unsigned int retry_cnt_no_handler = 0;
|
||||
ca_time current;
|
||||
IIU *piiu;
|
||||
chid chix;
|
||||
unsigned int retry_cnt = 0;
|
||||
unsigned int retry_cnt_no_handler = 0;
|
||||
ca_time current;
|
||||
int sendBytesPending;
|
||||
int sendBytesAvailable;
|
||||
int stmo;
|
||||
int rtmo;
|
||||
|
||||
current = time(NULL);
|
||||
|
||||
/*
|
||||
* issue connection heartbeat
|
||||
*/
|
||||
LOCK;
|
||||
for( piiu = (IIU *) iiuList.node.next;
|
||||
piiu;
|
||||
piiu = (IIU *) piiu->node.next){
|
||||
|
||||
if(piiu == piiuCast || !piiu->conn_up){
|
||||
continue;
|
||||
}
|
||||
|
||||
stmo = (current-piiu->timeAtLastSend)>CA_RETRY_PERIOD;
|
||||
sendBytesPending = cacRingBufferReadSize(&piiu->send, TRUE);
|
||||
|
||||
/*
|
||||
* mark connection for shutdown if outgoing messages
|
||||
* are not accepted by TCP/IP for several seconds
|
||||
*/
|
||||
if(sendBytesPending && stmo){
|
||||
piiu->conn_up = FALSE;
|
||||
}
|
||||
|
||||
rtmo = (current-piiu->timeAtLastRecv)>CA_RETRY_PERIOD;
|
||||
sendBytesAvailable = cacRingBufferWriteSize(&piiu->send, TRUE);
|
||||
|
||||
/*
|
||||
* remain backwards compatible with old servers
|
||||
*/
|
||||
if(!CA_V43(CA_PROTOCOL_VERSION, piiu->minor_version_number)){
|
||||
if(stmo && rtmo && !sendBytesPending){
|
||||
noop_msg(piiu);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if(piiu->echoPending){
|
||||
if((current-piiu->timeAtEchoRequest)>CA_ECHO_TIMEOUT){
|
||||
/*
|
||||
* mark connection for shutdown
|
||||
*/
|
||||
piiu->conn_up = FALSE;
|
||||
}
|
||||
}
|
||||
else{
|
||||
if((current-piiu->timeAtLastRecv)>CA_CONN_VERIFY_PERIOD &&
|
||||
sendBytesAvailable>sizeof(struct extmsg)){
|
||||
piiu->echoPending = TRUE;
|
||||
piiu->timeAtEchoRequest = current;
|
||||
echo_request(piiu);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
UNLOCK;
|
||||
|
||||
if(!piiuCast){
|
||||
return;
|
||||
}
|
||||
@@ -128,16 +188,17 @@ int silent;
|
||||
*/
|
||||
#ifdef __STDC__
|
||||
void mark_server_available(struct in_addr *pnet_addr)
|
||||
#else
|
||||
#else /*__STDC__*/
|
||||
void mark_server_available(pnet_addr)
|
||||
struct in_addr *pnet_addr;
|
||||
#endif
|
||||
#endif /*__STDC__*/
|
||||
{
|
||||
int currentPeriod;
|
||||
int currentTime;
|
||||
bhe *pBHE;
|
||||
unsigned index;
|
||||
unsigned port;
|
||||
int netChange = FALSE;
|
||||
|
||||
/*
|
||||
* if timers have expired take care of them
|
||||
@@ -151,39 +212,27 @@ struct in_addr *pnet_addr;
|
||||
|
||||
currentTime = time(NULL);
|
||||
|
||||
LOCK;
|
||||
/*
|
||||
* look for it in the hash table
|
||||
*/
|
||||
index = ntohl(pnet_addr->s_addr);
|
||||
index &= BHT_INET_ADDR_MASK;
|
||||
LOCK;
|
||||
pBHE = ca_static->ca_beaconHash[index];
|
||||
while(pBHE){
|
||||
if(pBHE->inetAddr.s_addr ==
|
||||
pnet_addr->s_addr){
|
||||
|
||||
break;
|
||||
}
|
||||
pBHE = pBHE->pNext;
|
||||
}
|
||||
|
||||
/*
|
||||
* if we have seen the beacon before ignore it
|
||||
* (unless there is an unusual change in its period)
|
||||
*/
|
||||
pBHE = lookupBeaconInetAddr(pnet_addr);
|
||||
if(pBHE){
|
||||
int netChange = FALSE;
|
||||
|
||||
/*
|
||||
* if we have seen the beacon before ignore it
|
||||
* (unless there is an unusual change in its period)
|
||||
*/
|
||||
|
||||
/*
|
||||
* update time stamp and average period
|
||||
*/
|
||||
currentPeriod = currentTime - pBHE->timeStamp;
|
||||
pBHE->averagePeriod =
|
||||
(currentPeriod + pBHE->averagePeriod)>>1;
|
||||
pBHE->averagePeriod = (currentPeriod + pBHE->averagePeriod)>>1;
|
||||
pBHE->timeStamp = currentTime;
|
||||
|
||||
|
||||
if((currentPeriod>>2)>=pBHE->averagePeriod){
|
||||
#ifdef DEBUG
|
||||
#ifdef DEBUG
|
||||
ca_printf(
|
||||
"net resume seen %x cur=%d avg=%d\n",
|
||||
pnet_addr->s_addr,
|
||||
@@ -203,43 +252,23 @@ struct in_addr *pnet_addr;
|
||||
#endif
|
||||
netChange = TRUE;
|
||||
}
|
||||
|
||||
if(pBHE->piiu){
|
||||
pBHE->piiu->timeAtLastRecv = currentTime;
|
||||
}
|
||||
if(!netChange){
|
||||
UNLOCK;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else{
|
||||
|
||||
/*
|
||||
* create the hash entry
|
||||
*/
|
||||
pBHE = (bhe *)calloc(1,sizeof(*pBHE));
|
||||
pBHE = createBeaconHashEntry(pnet_addr);
|
||||
if(!pBHE){
|
||||
UNLOCK;
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
ca_printf("new IOC %x\n", pnet_addr->s_addr);
|
||||
#endif
|
||||
/*
|
||||
* store the inet address
|
||||
*/
|
||||
pBHE->inetAddr = *pnet_addr;
|
||||
|
||||
/*
|
||||
* start the average at zero
|
||||
*/
|
||||
pBHE->averagePeriod = 0;
|
||||
pBHE->timeStamp = currentTime;
|
||||
|
||||
/*
|
||||
* install in the hash table
|
||||
*/
|
||||
pBHE->pNext = ca_static->ca_beaconHash[index];
|
||||
ca_static->ca_beaconHash[index] = pBHE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
ca_printf("CAC: <%s> ",host_from_addr(pnet_addr));
|
||||
@@ -301,5 +330,160 @@ struct in_addr *pnet_addr;
|
||||
# endif
|
||||
|
||||
UNLOCK;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* createBeaconHashEntry()
|
||||
*
|
||||
* LOCK must be applied
|
||||
*/
|
||||
#ifdef __STDC__
|
||||
bhe *createBeaconHashEntry(struct in_addr *pnet_addr)
|
||||
#else
|
||||
bhe *createBeaconHashEntry(pnet_addr)
|
||||
struct in_addr *pnet_addr;
|
||||
#endif
|
||||
{
|
||||
bhe *pBHE;
|
||||
unsigned index;
|
||||
|
||||
pBHE = lookupBeaconInetAddr(pnet_addr);
|
||||
if(pBHE){
|
||||
return pBHE;
|
||||
}
|
||||
|
||||
index = ntohl(pnet_addr->s_addr);
|
||||
index &= BHT_INET_ADDR_MASK;
|
||||
|
||||
assert(index<NELEMENTS(ca_static->ca_beaconHash));
|
||||
|
||||
pBHE = (bhe *)calloc(1,sizeof(*pBHE));
|
||||
if(!pBHE){
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
ca_printf("new IOC %x\n", pnet_addr->s_addr);
|
||||
#endif
|
||||
/*
|
||||
* store the inet address
|
||||
*/
|
||||
pBHE->inetAddr = *pnet_addr;
|
||||
|
||||
/*
|
||||
* start the average at zero
|
||||
*/
|
||||
pBHE->averagePeriod = 0;
|
||||
pBHE->timeStamp = time(NULL);
|
||||
|
||||
/*
|
||||
* install in the hash table
|
||||
*/
|
||||
pBHE->pNext = ca_static->ca_beaconHash[index];
|
||||
ca_static->ca_beaconHash[index] = pBHE;
|
||||
|
||||
return pBHE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* lookupBeaconInetAddr()
|
||||
*
|
||||
* LOCK must be applied
|
||||
*/
|
||||
#ifdef __STDC__
|
||||
bhe *lookupBeaconInetAddr(struct in_addr *pnet_addr)
|
||||
#else
|
||||
bhe *lookupBeaconInetAddr(pnet_addr)
|
||||
struct in_addr *pnet_addr;
|
||||
#endif
|
||||
{
|
||||
bhe *pBHE;
|
||||
unsigned index;
|
||||
|
||||
index = ntohl(pnet_addr->s_addr);
|
||||
index &= BHT_INET_ADDR_MASK;
|
||||
|
||||
assert(index<NELEMENTS(ca_static->ca_beaconHash));
|
||||
|
||||
pBHE = ca_static->ca_beaconHash[index];
|
||||
while(pBHE){
|
||||
if(pBHE->inetAddr.s_addr == pnet_addr->s_addr){
|
||||
break;
|
||||
}
|
||||
pBHE = pBHE->pNext;
|
||||
}
|
||||
return pBHE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* removeBeaconInetAddr()
|
||||
*
|
||||
* LOCK must be applied
|
||||
*/
|
||||
#ifdef __STDC__
|
||||
void removeBeaconInetAddr(struct in_addr *pnet_addr)
|
||||
#else /*__STDC__*/
|
||||
void removeBeaconInetAddr(pnet_addr)
|
||||
struct in_addr *pnet_addr;
|
||||
#endif /*__STDC__*/
|
||||
{
|
||||
bhe *pBHE;
|
||||
bhe **ppBHE;
|
||||
unsigned index;
|
||||
|
||||
index = ntohl(pnet_addr->s_addr);
|
||||
index &= BHT_INET_ADDR_MASK;
|
||||
|
||||
assert(index<NELEMENTS(ca_static->ca_beaconHash));
|
||||
|
||||
ppBHE = &ca_static->ca_beaconHash[index];
|
||||
pBHE = *ppBHE;
|
||||
while(pBHE){
|
||||
if(pBHE->inetAddr.s_addr == pnet_addr->s_addr){
|
||||
*ppBHE = pBHE->pNext;
|
||||
free(pBHE);
|
||||
return;
|
||||
}
|
||||
ppBHE = &pBHE->pNext;
|
||||
pBHE = *ppBHE;
|
||||
}
|
||||
assert(0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* freeBeaconHash()
|
||||
*
|
||||
* LOCK must be applied
|
||||
*/
|
||||
#ifdef __STDC__
|
||||
void freeBeaconHash(struct ca_static *ca_temp)
|
||||
#else /*__STDC__*/
|
||||
void freeBeaconHash(ca_temp)
|
||||
struct ca_static *ca_temp;
|
||||
#endif /*__STDC__*/
|
||||
{
|
||||
bhe *pBHE;
|
||||
bhe **ppBHE;
|
||||
int len;
|
||||
|
||||
len = NELEMENTS(ca_temp->ca_beaconHash);
|
||||
for( ppBHE = ca_temp->ca_beaconHash;
|
||||
ppBHE < &ca_temp->ca_beaconHash[len];
|
||||
ppBHE++){
|
||||
|
||||
pBHE = *ppBHE;
|
||||
while(pBHE){
|
||||
bhe *pOld;
|
||||
|
||||
pOld = pBHE;
|
||||
pBHE = pBHE->pNext;
|
||||
free(pOld);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -138,42 +138,38 @@ struct ioc_in_use **ppiiu;
|
||||
caAddrNode *pNode;
|
||||
struct ioc_in_use *piiu;
|
||||
int status;
|
||||
bhe *pBHE;
|
||||
|
||||
/*
|
||||
* look for an existing connection
|
||||
*
|
||||
* quite a bottle neck with increasing connection count
|
||||
*
|
||||
*/
|
||||
LOCK;
|
||||
for( piiu = (struct ioc_in_use *) iiuList.node.next;
|
||||
piiu;
|
||||
piiu = (struct ioc_in_use *) piiu->node.next){
|
||||
|
||||
if(piiu->sock_proto!=IPPROTO_TCP){
|
||||
continue;
|
||||
}
|
||||
|
||||
pNode = (caAddrNode *)piiu->destAddr.node.next;
|
||||
assert(pNode);
|
||||
assert(pNode->destAddr.sockAddr.sa_family == AF_INET);
|
||||
if(pnet_addr->s_addr ==
|
||||
pNode->destAddr.inetAddr.sin_addr.s_addr){
|
||||
|
||||
if(!piiu->conn_up){
|
||||
continue;
|
||||
}
|
||||
|
||||
*ppiiu = piiu;
|
||||
pBHE = lookupBeaconInetAddr(pnet_addr);
|
||||
if(!pBHE){
|
||||
pBHE = createBeaconHashEntry(pnet_addr);
|
||||
if(!pBHE){
|
||||
UNLOCK;
|
||||
return ECA_NORMAL;
|
||||
return ECA_ALLOCMEM;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(pBHE->piiu){
|
||||
*ppiiu = pBHE->piiu;
|
||||
status = ECA_NORMAL;
|
||||
}
|
||||
else{
|
||||
status = create_net_chan(
|
||||
ppiiu,
|
||||
pnet_addr,
|
||||
IPPROTO_TCP);
|
||||
if(status == ECA_NORMAL){
|
||||
pBHE->piiu = *ppiiu;
|
||||
}
|
||||
}
|
||||
|
||||
UNLOCK;
|
||||
|
||||
status = create_net_chan(ppiiu, pnet_addr, IPPROTO_TCP);
|
||||
return status;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -209,8 +205,6 @@ int net_proto;
|
||||
return ECA_ALLOCMEM;
|
||||
}
|
||||
|
||||
piiu->active = FALSE;
|
||||
|
||||
piiu->pcas = ca_static;
|
||||
ellInit(&piiu->chidlist);
|
||||
ellInit(&piiu->destAddr);
|
||||
@@ -404,6 +398,10 @@ int net_proto;
|
||||
pnet_addr,
|
||||
piiu->host_name_str,
|
||||
sizeof(piiu->host_name_str));
|
||||
|
||||
piiu->timeAtLastSend = time(NULL);
|
||||
piiu->timeAtLastRecv = time(NULL);
|
||||
|
||||
break;
|
||||
|
||||
case IPPROTO_UDP:
|
||||
@@ -706,6 +704,7 @@ struct ioc_in_use *piiu;
|
||||
if(status>=0){
|
||||
assert(status<=sendCnt);
|
||||
|
||||
piiu->timeAtLastSend = time(NULL);
|
||||
CAC_RING_BUFFER_READ_ADVANCE(&piiu->send, status);
|
||||
|
||||
sendCnt = cacRingBufferReadSize(&piiu->send, FALSE);
|
||||
@@ -829,6 +828,11 @@ int flags;
|
||||
unsigned long minfreespace;
|
||||
unsigned long freespace;
|
||||
|
||||
/*
|
||||
* manage search timers and detect disconnects
|
||||
*/
|
||||
manage_conn(TRUE);
|
||||
|
||||
LOCK;
|
||||
piiu=(IIU *)iiuList.node.next;
|
||||
while(piiu){
|
||||
@@ -1291,7 +1295,7 @@ int tid;
|
||||
*/
|
||||
while(TRUE){
|
||||
timeout.tv_usec = 0;
|
||||
timeout.tv_sec = 20;
|
||||
timeout.tv_sec = 1;
|
||||
ca_mux_io(&timeout, CA_DO_RECVS);
|
||||
}
|
||||
}
|
||||
@@ -1373,9 +1377,9 @@ LOCAL void close_ioc(piiu)
|
||||
struct ioc_in_use *piiu;
|
||||
#endif /*__STDC__*/
|
||||
{
|
||||
chid chix;
|
||||
int status;
|
||||
|
||||
caAddrNode *pNode;
|
||||
chid chix;
|
||||
int status;
|
||||
|
||||
/*
|
||||
* dont close twice
|
||||
@@ -1402,7 +1406,6 @@ struct ioc_in_use *piiu;
|
||||
* prior to calling handlers incase the
|
||||
* handler tries to use a channel before
|
||||
* I mark it disconnected.
|
||||
*
|
||||
*/
|
||||
chix = (chid) &piiu->chidlist.node.next;
|
||||
while(chix = (chid) chix->node.next){
|
||||
@@ -1414,31 +1417,16 @@ struct ioc_in_use *piiu;
|
||||
chix->ar.write_access = FALSE;
|
||||
}
|
||||
|
||||
if(piiu->chidlist.count){
|
||||
ca_signal(ECA_DISCONN,piiu->host_name_str);
|
||||
}
|
||||
|
||||
/*
|
||||
* remove IOC from the hash table
|
||||
*/
|
||||
{
|
||||
caAddrNode *pNode;
|
||||
bhe *pBHE;
|
||||
bhe **ppBHE;
|
||||
unsigned index;
|
||||
|
||||
pNode = (caAddrNode *) piiu->destAddr.node.next;
|
||||
index = ntohl(pNode->destAddr.inetAddr.sin_addr.s_addr);
|
||||
index &= BHT_INET_ADDR_MASK;
|
||||
ppBHE = &ca_static->ca_beaconHash[index];
|
||||
pBHE = *ppBHE;
|
||||
while(pBHE){
|
||||
if(pBHE->inetAddr.s_addr ==
|
||||
pNode->destAddr.inetAddr.sin_addr.s_addr){
|
||||
*ppBHE = pBHE->pNext;
|
||||
free(pBHE);
|
||||
break;
|
||||
}
|
||||
ppBHE = &pBHE->pNext;
|
||||
pBHE = *ppBHE;
|
||||
}
|
||||
}
|
||||
pNode = (caAddrNode *) piiu->destAddr.node.next;
|
||||
assert(pNode);
|
||||
removeBeaconInetAddr(&pNode->destAddr.inetAddr.sin_addr);
|
||||
|
||||
/*
|
||||
* call their connection handler as required
|
||||
|
||||
@@ -83,6 +83,7 @@ static char *iocinfhSccsId = "$Id$";
|
||||
/*
|
||||
* CA private includes
|
||||
*/
|
||||
#include "addrList.h"
|
||||
#include "iocmsg.h"
|
||||
|
||||
#ifndef min
|
||||
@@ -136,36 +137,36 @@ struct pending_io_event{
|
||||
void *io_done_arg;
|
||||
};
|
||||
|
||||
union caAddr{
|
||||
struct sockaddr_in inetAddr;
|
||||
struct sockaddr sockAddr;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
ELLNODE node;
|
||||
union caAddr srcAddr;
|
||||
union caAddr destAddr;
|
||||
}caAddrNode;
|
||||
|
||||
typedef unsigned long ca_time;
|
||||
|
||||
#define MAXCONNTRIES 60 /* N conn retries on unchanged net */
|
||||
#define CA_RETRY_PERIOD 5 /* int sec to next keepalive */
|
||||
#define CA_RECAST_DELAY 1 /* initial int sec to next recast */
|
||||
#define CA_RECAST_PORT_MASK 0x3 /* random retry interval off port */
|
||||
#define CA_RECAST_PERIOD 5 /* ul on retry period long term */
|
||||
/*
|
||||
* dont adjust
|
||||
*/
|
||||
#define CA_CURRENT_TIME 0
|
||||
|
||||
/*
|
||||
* for the beacon's recvd hash table
|
||||
* these control the duration and period of name resolution
|
||||
* broadcasts
|
||||
*/
|
||||
#define BHT_INET_ADDR_MASK 0x7f
|
||||
typedef struct beaconHashEntry{
|
||||
struct beaconHashEntry *pNext;
|
||||
struct in_addr inetAddr;
|
||||
int timeStamp;
|
||||
int averagePeriod;
|
||||
}bhe;
|
||||
#define MAXCONNTRIES 60 /* N conn retries on unchanged net */
|
||||
#define CA_RECAST_DELAY 1 /* initial int sec to next recast */
|
||||
#define CA_RECAST_PORT_MASK 0x3 /* random retry interval off port */
|
||||
#define CA_RECAST_PERIOD 5 /* ul on retry period long term */
|
||||
|
||||
/*
|
||||
* these two control the period of connection verifies
|
||||
* (echo requests) - CA_CONN_VERIFY_PERIOD - and how
|
||||
* long we will wait for an echo reply before we
|
||||
* give up and flag the connection for disconnect
|
||||
* - CA_ECHO_TIMEOUT.
|
||||
*/
|
||||
#define CA_ECHO_TIMEOUT 5 /* disconn if no echo reply tmo */
|
||||
#define CA_CONN_VERIFY_PERIOD 30 /* how often to request echo */
|
||||
|
||||
/*
|
||||
* only used when communicating with old servers
|
||||
*/
|
||||
#define CA_RETRY_PERIOD 5 /* int sec to next keepalive */
|
||||
|
||||
#ifdef vxWorks
|
||||
typedef struct caclient_put_notify{
|
||||
@@ -289,7 +290,6 @@ typedef struct ioc_in_use{
|
||||
unsigned minor_version_number;
|
||||
unsigned contiguous_msg_count;
|
||||
unsigned client_busy;
|
||||
char active;
|
||||
struct ca_buffer send;
|
||||
struct ca_buffer recv;
|
||||
struct extmsg curMsg;
|
||||
@@ -298,6 +298,9 @@ typedef struct ioc_in_use{
|
||||
unsigned long curDataMax;
|
||||
unsigned long curDataBytes;
|
||||
ca_time timeAtLastRecv;
|
||||
ca_time timeAtLastSend;
|
||||
int echoPending;
|
||||
ca_time timeAtEchoRequest;
|
||||
#ifdef __STDC__
|
||||
void (*sendBytes)(struct ioc_in_use *);
|
||||
void (*recvBytes)(struct ioc_in_use *);
|
||||
@@ -328,6 +331,17 @@ typedef struct ioc_in_use{
|
||||
|
||||
}IIU;
|
||||
|
||||
/*
|
||||
* for the beacon's recvd hash table
|
||||
*/
|
||||
#define BHT_INET_ADDR_MASK 0x7f
|
||||
typedef struct beaconHashEntry{
|
||||
struct beaconHashEntry *pNext;
|
||||
IIU *piiu;
|
||||
struct in_addr inetAddr;
|
||||
int timeStamp;
|
||||
int averagePeriod;
|
||||
}bhe;
|
||||
|
||||
struct ca_static{
|
||||
IIU *ca_piiuCast;
|
||||
@@ -426,6 +440,7 @@ int ca_request_event(evid monix);
|
||||
void ca_busy_message(struct ioc_in_use *piiu);
|
||||
void ca_ready_message(struct ioc_in_use *piiu);
|
||||
void noop_msg(struct ioc_in_use *piiu);
|
||||
void echo_request(struct ioc_in_use *piiu);
|
||||
void issue_claim_channel(struct ioc_in_use *piiu, chid pchan);
|
||||
void issue_identify_client(struct ioc_in_use *piiu);
|
||||
void issue_client_host_name(struct ioc_in_use *piiu);
|
||||
@@ -505,6 +520,11 @@ int net_proto
|
||||
|
||||
int ca_check_for_fp();
|
||||
|
||||
void freeBeaconHash(struct ca_static *ca_temp);
|
||||
void removeBeaconInetAddr(struct in_addr *pnet_addr);
|
||||
bhe *lookupBeaconInetAddr(struct in_addr *pnet_addr);
|
||||
bhe *createBeaconHashEntry(struct in_addr *pnet_addr);
|
||||
|
||||
#else /*__STDC__*/
|
||||
int ca_defunct();
|
||||
int repeater_installed();
|
||||
@@ -514,6 +534,7 @@ int broadcast_addr();
|
||||
int local_addr();
|
||||
void manage_conn();
|
||||
void noop_msg();
|
||||
void echo_request();
|
||||
void ca_busy_message();
|
||||
void ca_ready_message();
|
||||
void flow_control();
|
||||
@@ -545,6 +566,10 @@ void caAddConfiguredAddr();
|
||||
void caPrintAddrList();
|
||||
int create_net_chan();
|
||||
int ca_check_for_fp();
|
||||
void freeBeaconHash();
|
||||
void removeBeaconInetAddr();
|
||||
bhe *lookupBeaconInetAddr();
|
||||
bhe *createBeaconHashEntry();
|
||||
#endif /*__STDC__*/
|
||||
|
||||
/*
|
||||
|
||||
@@ -15,18 +15,29 @@
|
||||
* .05 011294 joh New command added - write notify
|
||||
*
|
||||
* .06 020194 joh New command added for CA V4.1 - client name
|
||||
*
|
||||
* .07 041194 joh New command added for CA V4.2 - access rights
|
||||
*
|
||||
* .08 050594 joh New command added for CA V4.3 - echo request
|
||||
*/
|
||||
|
||||
#define __IOCMSG__
|
||||
|
||||
static char *iocmsghSccsId = "$Id$ CA version 4.2";
|
||||
static char *iocmsghSccsId = "$Id$ CA version 4.3";
|
||||
|
||||
/* TCP/UDP port number (bumped each protocol change) */
|
||||
#define CA_PROTOCOL_VERSION 4
|
||||
#define CA_MINOR_VERSION 2
|
||||
#define CA_MINOR_VERSION 3
|
||||
#define CA_UKN_MINOR_VERSION 0 /* unknown minor version */
|
||||
#define CA_V41(MAJOR,MINOR) ( ((MAJOR)==4&&(MINOR)>=1) || (MAJOR)>4 )
|
||||
#define CA_V42(MAJOR,MINOR) ( ((MAJOR)==4&&(MINOR)>=2) || (MAJOR)>4 )
|
||||
#if CA_PROTOCOL_VERSION == 4
|
||||
#define CA_V41(MAJOR,MINOR) ((MINOR)>=1)
|
||||
#define CA_V42(MAJOR,MINOR) ((MINOR)>=2)
|
||||
#define CA_V43(MAJOR,MINOR) ((MINOR)>=3)
|
||||
#else
|
||||
#define CA_V41(MAJOR,MINOR) ( 1 )
|
||||
#define CA_V42(MAJOR,MINOR) ( 1 )
|
||||
#define CA_V43(MAJOR,MINOR) ( 1 )
|
||||
#endif
|
||||
#define CA_PORT_BASE IPPORT_USERRESERVED + 56
|
||||
#define CA_SERVER_PORT (CA_PORT_BASE+CA_PROTOCOL_VERSION*2)
|
||||
#define CA_CLIENT_PORT (CA_PORT_BASE+CA_PROTOCOL_VERSION*2+1)
|
||||
@@ -60,7 +71,8 @@ static char *iocmsghSccsId = "$Id$ CA version 4.2";
|
||||
#define IOC_WRITE_NOTIFY 19 /* notify after write chan value */
|
||||
#define IOC_CLIENT_NAME 20 /* CA V4.1 identify client */
|
||||
#define IOC_HOST_NAME 21 /* CA V4.1 identify client */
|
||||
#define IOC_ACCESS_RIGHTS 22 /* CA V4.1 asynch access rights chg */
|
||||
#define IOC_ACCESS_RIGHTS 22 /* CA V4.2 asynch access rights chg */
|
||||
#define IOC_ECHO 23 /* CA V4.3 connection verify */
|
||||
|
||||
/*
|
||||
* for use with build and search and not_found (if search fails and
|
||||
|
||||
@@ -257,6 +257,10 @@ struct in_addr *pnet_addr;
|
||||
case IOC_NOOP:
|
||||
break;
|
||||
|
||||
case IOC_ECHO:
|
||||
piiu->echoPending = FALSE;
|
||||
break;
|
||||
|
||||
case IOC_WRITE_NOTIFY:
|
||||
{
|
||||
/*
|
||||
|
||||
@@ -289,7 +289,6 @@ float timeout;
|
||||
* at least once.
|
||||
*/
|
||||
ca_flush_io();
|
||||
manage_conn(TRUE);
|
||||
|
||||
status = ECA_NORMAL;
|
||||
beg_time = time(NULL);
|
||||
@@ -339,7 +338,6 @@ float timeout;
|
||||
status = ECA_TIMEOUT;
|
||||
break;
|
||||
}
|
||||
manage_conn(TRUE);
|
||||
}
|
||||
pcasg->opPendCount = 0;
|
||||
pcasg->seqNo++;
|
||||
|
||||
@@ -47,6 +47,44 @@
|
||||
|
||||
#include "iocinf.h"
|
||||
|
||||
#define CONNECTION_TIMER_ID 56
|
||||
|
||||
void connectionTimer(void *astarg);
|
||||
|
||||
struct time{
|
||||
int lval;
|
||||
int hval;
|
||||
}
|
||||
|
||||
struct time timer = {-10000000,-1};
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
void setupConnectionTimer()
|
||||
{
|
||||
struct time tmo;
|
||||
int status;
|
||||
|
||||
status = sys$setimr(NULL, &timer, connectionTimer, CONNECTION_TIMER_ID, 0);
|
||||
assert(status == SS$_NORMAL);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* connectionTimer()
|
||||
*/
|
||||
LOCAL void connectionTimer(void *astarg);
|
||||
struct time tmo;
|
||||
int status;
|
||||
|
||||
manage_conn(TRUE);
|
||||
|
||||
status = sys$setimr(NULL, &timer, connectionTimer, CONNECTION_TIMER_ID, 0);
|
||||
assert(status == SS$_NORMAL);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
|
||||
@@ -241,6 +241,18 @@ struct message_buffer *recv
|
||||
case IOC_NOOP: /* verify TCP */
|
||||
break;
|
||||
|
||||
case IOC_ECHO: /* verify TCP */
|
||||
{
|
||||
struct extmsg *reply;
|
||||
|
||||
SEND_LOCK(client);
|
||||
reply = ALLOC_MSG(client, 0);
|
||||
assert (reply);
|
||||
*reply = *mp;
|
||||
END_MSG(client);
|
||||
SEND_UNLOCK(client);
|
||||
break;
|
||||
}
|
||||
case IOC_CLIENT_NAME:
|
||||
client_name_action(mp, client);
|
||||
break;
|
||||
@@ -316,13 +328,13 @@ struct message_buffer *recv
|
||||
else{
|
||||
status = ECA_PUTFAIL;
|
||||
}
|
||||
LOCK_CLIENT(client);
|
||||
SEND_LOCK(client);
|
||||
send_err(
|
||||
mp,
|
||||
status,
|
||||
client,
|
||||
RECORD_NAME(&pciu->addr));
|
||||
UNLOCK_CLIENT(client);
|
||||
SEND_UNLOCK(client);
|
||||
break;
|
||||
}
|
||||
status = db_put_field(
|
||||
@@ -331,13 +343,13 @@ struct message_buffer *recv
|
||||
mp + 1,
|
||||
mp->m_count);
|
||||
if (status < 0) {
|
||||
LOCK_CLIENT(client);
|
||||
SEND_LOCK(client);
|
||||
send_err(
|
||||
mp,
|
||||
ECA_PUTFAIL,
|
||||
client,
|
||||
RECORD_NAME(&pciu->addr));
|
||||
UNLOCK_CLIENT(client);
|
||||
SEND_UNLOCK(client);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -370,9 +382,9 @@ struct message_buffer *recv
|
||||
* most clients dont recover
|
||||
* from this
|
||||
*/
|
||||
LOCK_CLIENT(client);
|
||||
SEND_LOCK(client);
|
||||
send_err(mp, ECA_INTERNAL, client, "Invalid Msg");
|
||||
UNLOCK_CLIENT(client);
|
||||
SEND_UNLOCK(client);
|
||||
/*
|
||||
* returning ERROR here disconnects
|
||||
* the client with the bad message
|
||||
@@ -409,8 +421,6 @@ struct client *client
|
||||
char *pMalloc;
|
||||
int status;
|
||||
|
||||
LOCK_CLIENT(client);
|
||||
|
||||
pName = (char *)(mp+1);
|
||||
size = strlen(pName)+1;
|
||||
/*
|
||||
@@ -425,15 +435,18 @@ struct client *client
|
||||
"");
|
||||
return;
|
||||
}
|
||||
if(client->pHostName){
|
||||
free(client->pHostName);
|
||||
}
|
||||
client->pHostName = pMalloc;
|
||||
strncpy(
|
||||
client->pHostName,
|
||||
pMalloc,
|
||||
pName,
|
||||
size-1);
|
||||
client->pHostName[size-1]='\0';
|
||||
pMalloc[size-1]='\0';
|
||||
|
||||
FASTLOCK(&client->addrqLock);
|
||||
pName = client->pHostName;
|
||||
client->pHostName = pMalloc;
|
||||
if(pName){
|
||||
free(pName);
|
||||
}
|
||||
|
||||
pciu = (struct channel_in_use *) client->addrq.node.next;
|
||||
while(pciu){
|
||||
@@ -443,14 +456,13 @@ struct client *client
|
||||
client->pUserName,
|
||||
client->pHostName);
|
||||
if(status != 0 && status != S_asLib_asNotActive){
|
||||
UNLOCK_CLIENT(prsrv_cast_client);
|
||||
FASTUNLOCK(&client->addrqLock);
|
||||
free_client(client);
|
||||
exit(0);
|
||||
}
|
||||
pciu = (struct channel_in_use *) pciu->node.next;
|
||||
}
|
||||
|
||||
UNLOCK_CLIENT(client);
|
||||
FASTUNLOCK(&client->addrqLock);
|
||||
}
|
||||
|
||||
|
||||
@@ -468,8 +480,6 @@ struct client *client
|
||||
char *pMalloc;
|
||||
int status;
|
||||
|
||||
LOCK_CLIENT(client);
|
||||
|
||||
pName = (char *)(mp+1);
|
||||
size = strlen(pName)+1;
|
||||
/*
|
||||
@@ -484,15 +494,18 @@ struct client *client
|
||||
"");
|
||||
return;
|
||||
}
|
||||
if(client->pUserName){
|
||||
free(client->pUserName);
|
||||
}
|
||||
client->pUserName = pMalloc;
|
||||
strncpy(
|
||||
client->pUserName,
|
||||
pMalloc,
|
||||
pName,
|
||||
size-1);
|
||||
client->pUserName[size-1]='\0';
|
||||
pMalloc[size-1]='\0';
|
||||
|
||||
FASTLOCK(&client->addrqLock);
|
||||
pName = client->pUserName;
|
||||
client->pUserName = pMalloc;
|
||||
if(pName){
|
||||
free(pName);
|
||||
}
|
||||
|
||||
pciu = (struct channel_in_use *) client->addrq.node.next;
|
||||
while(pciu){
|
||||
@@ -502,14 +515,13 @@ struct client *client
|
||||
client->pUserName,
|
||||
client->pHostName);
|
||||
if(status != 0 && status != S_asLib_asNotActive){
|
||||
UNLOCK_CLIENT(prsrv_cast_client);
|
||||
FASTUNLOCK(&client->addrqLock);
|
||||
free_client(client);
|
||||
exit(0);
|
||||
}
|
||||
pciu = (struct channel_in_use *) pciu->node.next;
|
||||
}
|
||||
|
||||
UNLOCK_CLIENT(client);
|
||||
FASTUNLOCK(&client->addrqLock);
|
||||
}
|
||||
|
||||
|
||||
@@ -526,7 +538,7 @@ struct client *client
|
||||
struct channel_in_use *pciu;
|
||||
|
||||
|
||||
LOCK_CLIENT(prsrv_cast_client);
|
||||
FASTLOCK(&prsrv_cast_client->addrqLock);
|
||||
|
||||
/*
|
||||
* clients which dont claim their
|
||||
@@ -542,7 +554,7 @@ struct client *client
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
UNLOCK_CLIENT(prsrv_cast_client);
|
||||
FASTUNLOCK(&prsrv_cast_client->addrqLock);
|
||||
free_client(client);
|
||||
exit(0);
|
||||
}
|
||||
@@ -556,7 +568,7 @@ struct client *client
|
||||
ellDelete(
|
||||
&prsrv_cast_client->addrq,
|
||||
&pciu->node);
|
||||
UNLOCK_CLIENT(prsrv_cast_client);
|
||||
FASTUNLOCK(&prsrv_cast_client->addrqLock);
|
||||
|
||||
/*
|
||||
* Any other client attachment is a severe error
|
||||
@@ -569,7 +581,6 @@ struct client *client
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
UNLOCK_CLIENT(prsrv_cast_client);
|
||||
free_client(client);
|
||||
exit(0);
|
||||
}
|
||||
@@ -584,9 +595,9 @@ struct client *client
|
||||
client->pUserName,
|
||||
client->pHostName);
|
||||
if(status != 0 && status != S_asLib_asNotActive){
|
||||
LOCK_CLIENT(client);
|
||||
SEND_LOCK(client);
|
||||
send_err(mp, ECA_ALLOCMEM, client, "No room for security table");
|
||||
UNLOCK_CLIENT(client);
|
||||
SEND_UNLOCK(client);
|
||||
free_client(client);
|
||||
exit(0);
|
||||
}
|
||||
@@ -597,10 +608,10 @@ struct client *client
|
||||
*/
|
||||
asPutClientPvt(pciu->asClientPVT, pciu);
|
||||
|
||||
LOCK_CLIENT(client);
|
||||
FASTLOCK(&prsrv_cast_client->addrqLock);
|
||||
pciu->client = client;
|
||||
ellAdd(&client->addrq, &pciu->node);
|
||||
UNLOCK_CLIENT(client);
|
||||
FASTUNLOCK(&prsrv_cast_client->addrqLock);
|
||||
|
||||
/*
|
||||
* The available field is used (abused)
|
||||
@@ -634,7 +645,7 @@ struct client *client
|
||||
if(v42){
|
||||
struct extmsg *claim_reply;
|
||||
|
||||
LOCK_CLIENT(client);
|
||||
SEND_LOCK(client);
|
||||
claim_reply = (struct extmsg *) ALLOC_MSG(client, 0);
|
||||
assert (claim_reply);
|
||||
|
||||
@@ -644,7 +655,7 @@ struct client *client
|
||||
claim_reply->m_count = pciu->addr.no_elements;
|
||||
claim_reply->m_cid = pciu->cid;
|
||||
END_MSG(client);
|
||||
UNLOCK_CLIENT(client);
|
||||
SEND_UNLOCK(client);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -706,7 +717,7 @@ void write_notify_reply(void *pArg)
|
||||
|
||||
pClient = pArg;
|
||||
|
||||
LOCK_CLIENT(pClient);
|
||||
SEND_LOCK(pClient);
|
||||
while(TRUE){
|
||||
/*
|
||||
* independent lock used here in order to
|
||||
@@ -766,7 +777,7 @@ void write_notify_reply(void *pArg)
|
||||
END_MSG(pClient);
|
||||
ppnb->busy = FALSE;
|
||||
}
|
||||
UNLOCK_CLIENT(pClient);
|
||||
SEND_UNLOCK(pClient);
|
||||
|
||||
/*
|
||||
* wakeup the TCP thread if it is waiting for a cb to complete
|
||||
@@ -888,7 +899,7 @@ LOCAL void putNotifyErrorReply(struct client *client, struct extmsg *mp, int sta
|
||||
{
|
||||
struct extmsg *preply;
|
||||
|
||||
LOCK_CLIENT(client);
|
||||
SEND_LOCK(client);
|
||||
preply = ALLOC_MSG(client, 0);
|
||||
if(!preply){
|
||||
logMsg("Fatal Error:%s, %d\n",
|
||||
@@ -908,7 +919,7 @@ LOCAL void putNotifyErrorReply(struct client *client, struct extmsg *mp, int sta
|
||||
*/
|
||||
preply->m_cid = statusCA;
|
||||
END_MSG(client);
|
||||
UNLOCK_CLIENT(client);
|
||||
SEND_UNLOCK(client);
|
||||
}
|
||||
|
||||
|
||||
@@ -927,18 +938,18 @@ struct client *client
|
||||
|
||||
client->eventsoff = FALSE;
|
||||
|
||||
LOCK_CLIENT(client);
|
||||
|
||||
FASTLOCK(&client->addrqLock);
|
||||
pciu = (struct channel_in_use *)
|
||||
client->addrq.node.next;
|
||||
while (pciu) {
|
||||
FASTLOCK(&client->eventqLock);
|
||||
pevext = (struct event_ext *)
|
||||
pciu->eventq.node.next;
|
||||
while (pevext){
|
||||
|
||||
if (pevext->modified) {
|
||||
evext = *pevext;
|
||||
evext.send_lock = FALSE;
|
||||
evext.send_lock = TRUE;
|
||||
evext.get = TRUE;
|
||||
read_reply(
|
||||
&evext,
|
||||
@@ -950,11 +961,12 @@ struct client *client
|
||||
pevext = (struct event_ext *)
|
||||
pevext->node.next;
|
||||
}
|
||||
FASTUNLOCK(&client->eventqLock);
|
||||
|
||||
pciu = (struct channel_in_use *)
|
||||
pciu->node.next;
|
||||
}
|
||||
UNLOCK_CLIENT(client);
|
||||
FASTUNLOCK(&client->addrqLock);
|
||||
}
|
||||
|
||||
|
||||
@@ -987,13 +999,13 @@ struct client *client
|
||||
if (!pevext) {
|
||||
pevext = (struct event_ext *) malloc(size);
|
||||
if (!pevext) {
|
||||
LOCK_CLIENT(client);
|
||||
SEND_LOCK(client);
|
||||
send_err(
|
||||
mp,
|
||||
ECA_ALLOCMEM,
|
||||
client,
|
||||
RECORD_NAME(&pciu->addr));
|
||||
UNLOCK_CLIENT(client);
|
||||
SEND_UNLOCK(client);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1005,9 +1017,9 @@ struct client *client
|
||||
pevext->mask = ((struct monops *) mp)->m_info.m_mask;
|
||||
pevext->get = FALSE;
|
||||
|
||||
LOCK_CLIENT(client);
|
||||
FASTLOCK(&client->eventqLock);
|
||||
ellAdd( &pciu->eventq, &pevext->node);
|
||||
UNLOCK_CLIENT(client);
|
||||
FASTUNLOCK(&client->eventqLock);
|
||||
|
||||
pevext->pdbev = (struct event_block *)(pevext+1);
|
||||
|
||||
@@ -1020,13 +1032,13 @@ struct client *client
|
||||
pevext->pdbev);
|
||||
if (status == ERROR) {
|
||||
pevext->pdbev = NULL;
|
||||
LOCK_CLIENT(client);
|
||||
SEND_LOCK(client);
|
||||
send_err(
|
||||
mp,
|
||||
ECA_ADDFAIL,
|
||||
client,
|
||||
RECORD_NAME(&pciu->addr));
|
||||
UNLOCK_CLIENT(client);
|
||||
SEND_UNLOCK(client);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1107,9 +1119,9 @@ struct client *client
|
||||
}
|
||||
|
||||
while (TRUE){
|
||||
LOCK_CLIENT(client);
|
||||
FASTLOCK(&client->eventqLock);
|
||||
pevext = (struct event_ext *) ellGet(&pciu->eventq);
|
||||
UNLOCK_CLIENT(client);
|
||||
FASTUNLOCK(&client->eventqLock);
|
||||
|
||||
if(!pevext){
|
||||
break;
|
||||
@@ -1136,17 +1148,20 @@ struct client *client
|
||||
/*
|
||||
* send delete confirmed message
|
||||
*/
|
||||
LOCK_CLIENT(client);
|
||||
SEND_LOCK(client);
|
||||
reply = (struct extmsg *) ALLOC_MSG(client, 0);
|
||||
if (!reply) {
|
||||
UNLOCK_CLIENT(client);
|
||||
SEND_UNLOCK(client);
|
||||
taskSuspend(0);
|
||||
}
|
||||
*reply = *mp;
|
||||
|
||||
END_MSG(client);
|
||||
SEND_UNLOCK(client);
|
||||
|
||||
FASTLOCK(&client->addrqLock);
|
||||
ellDelete(&client->addrq, &pciu->node);
|
||||
UNLOCK_CLIENT(client);
|
||||
FASTUNLOCK(&client->addrqLock);
|
||||
|
||||
/*
|
||||
* remove from access control list
|
||||
@@ -1204,7 +1219,7 @@ struct client *client
|
||||
* search events on this channel for a match
|
||||
* (there are usually very few monitors per channel)
|
||||
*/
|
||||
LOCK_CLIENT(client);
|
||||
FASTLOCK(&client->eventqLock);
|
||||
for (pevext = (struct event_ext *) ellFirst(&pciu->eventq);
|
||||
pevext;
|
||||
pevext = (struct event_ext *) ellNext(&pevext->node)){
|
||||
@@ -1214,15 +1229,15 @@ struct client *client
|
||||
break;
|
||||
}
|
||||
}
|
||||
UNLOCK_CLIENT(client);
|
||||
FASTUNLOCK(&client->eventqLock);
|
||||
|
||||
/*
|
||||
* Not Found- return an exception event
|
||||
*/
|
||||
if(!pevext){
|
||||
LOCK_CLIENT(client);
|
||||
SEND_LOCK(client);
|
||||
send_err(mp, ECA_BADMONID, client, RECORD_NAME(&pciu->addr));
|
||||
UNLOCK_CLIENT(client);
|
||||
SEND_UNLOCK(client);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1238,17 +1253,17 @@ struct client *client
|
||||
/*
|
||||
* send delete confirmed message
|
||||
*/
|
||||
LOCK_CLIENT(client);
|
||||
SEND_LOCK(client);
|
||||
reply = (struct extmsg *) ALLOC_MSG(client, 0);
|
||||
if (!reply) {
|
||||
UNLOCK_CLIENT(client);
|
||||
SEND_UNLOCK(client);
|
||||
assert(0);
|
||||
}
|
||||
*reply = pevext->msg;
|
||||
reply->m_postsize = 0;
|
||||
|
||||
END_MSG(client);
|
||||
UNLOCK_CLIENT(client);
|
||||
SEND_UNLOCK(client);
|
||||
|
||||
FASTLOCK(&rsrv_free_eventq_lck);
|
||||
ellAdd(&rsrv_free_eventq, &pevext->node);
|
||||
@@ -1287,7 +1302,7 @@ db_field_log *pfl
|
||||
return;
|
||||
}
|
||||
if (pevext->send_lock)
|
||||
LOCK_CLIENT(client);
|
||||
SEND_LOCK(client);
|
||||
|
||||
reply = (struct extmsg *) ALLOC_MSG(client, pevext->size);
|
||||
if (!reply) {
|
||||
@@ -1295,7 +1310,7 @@ db_field_log *pfl
|
||||
if (!eventsRemaining)
|
||||
cas_send_msg(client,!pevext->send_lock);
|
||||
if (pevext->send_lock)
|
||||
UNLOCK_CLIENT(client);
|
||||
SEND_UNLOCK(client);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1333,7 +1348,7 @@ db_field_log *pfl
|
||||
if (!eventsRemaining)
|
||||
cas_send_msg(client,!pevext->send_lock);
|
||||
if (pevext->send_lock){
|
||||
UNLOCK_CLIENT(client);
|
||||
SEND_UNLOCK(client);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -1414,7 +1429,7 @@ db_field_log *pfl
|
||||
cas_send_msg(client,!pevext->send_lock);
|
||||
|
||||
if (pevext->send_lock)
|
||||
UNLOCK_CLIENT(client);
|
||||
SEND_UNLOCK(client);
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -1495,7 +1510,7 @@ struct client *client
|
||||
{
|
||||
FAST struct extmsg *reply;
|
||||
|
||||
LOCK_CLIENT(client);
|
||||
SEND_LOCK(client);
|
||||
reply = (struct extmsg *) ALLOC_MSG(client, 0);
|
||||
if (!reply)
|
||||
taskSuspend(0);
|
||||
@@ -1504,7 +1519,7 @@ struct client *client
|
||||
|
||||
END_MSG(client);
|
||||
|
||||
UNLOCK_CLIENT(client);
|
||||
SEND_UNLOCK(client);
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -1530,6 +1545,16 @@ struct client *client
|
||||
unsigned long sid;
|
||||
|
||||
|
||||
/*
|
||||
* set true if max memory block drops below MAX_BLOCK_THRESHOLD
|
||||
*/
|
||||
if(casDontAllowSearchReplies){
|
||||
SEND_LOCK(client);
|
||||
send_err(mp, ECA_ALLOCMEM, client, "below MAX_BLOCK_THRESHOLD");
|
||||
SEND_UNLOCK(client);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Exit quickly if channel not on this node */
|
||||
status = db_name_to_addr(
|
||||
mp->m_cmmd == IOC_BUILD ? mp + 2 : mp + 1,
|
||||
@@ -1556,9 +1581,9 @@ struct client *client
|
||||
if (!pchannel) {
|
||||
pchannel = (struct channel_in_use *) malloc(sizeof(*pchannel));
|
||||
if (!pchannel) {
|
||||
LOCK_CLIENT(client);
|
||||
SEND_LOCK(client);
|
||||
send_err(mp, ECA_ALLOCMEM, client, RECORD_NAME(&tmp_addr));
|
||||
UNLOCK_CLIENT(client);
|
||||
SEND_UNLOCK(client);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1581,9 +1606,9 @@ struct client *client
|
||||
if (mp->m_cmmd == IOC_BUILD) {
|
||||
printf("Build access security bypassed\n");
|
||||
#endif
|
||||
LOCK_CLIENT(client);
|
||||
SEND_LOCK(client);
|
||||
send_err(mp, ECA_NORDACCESS, client, RECORD_NAME(&tmp_addr));
|
||||
UNLOCK_CLIENT(client);
|
||||
SEND_UNLOCK(client);
|
||||
FASTLOCK(&rsrv_free_addrq_lck);
|
||||
ellAdd(&rsrv_free_addrq, &pchannel->node);
|
||||
FASTUNLOCK(&rsrv_free_addrq_lck);
|
||||
@@ -1600,9 +1625,9 @@ printf("Build access security bypassed\n");
|
||||
status = bucketAddItem(pCaBucket, sid, pchannel);
|
||||
FASTUNLOCK(&rsrv_free_addrq_lck);
|
||||
if(status!=BUCKET_SUCCESS){
|
||||
LOCK_CLIENT(client);
|
||||
SEND_LOCK(client);
|
||||
send_err(mp, ECA_ALLOCMEM, client, "No room for hash table");
|
||||
UNLOCK_CLIENT(client);
|
||||
SEND_UNLOCK(client);
|
||||
FASTLOCK(&rsrv_free_addrq_lck);
|
||||
ellAdd(&rsrv_free_addrq, &pchannel->node);
|
||||
FASTUNLOCK(&rsrv_free_addrq_lck);
|
||||
@@ -1613,7 +1638,7 @@ printf("Build access security bypassed\n");
|
||||
* UDP reliability schemes rely on both msgs in same reply Therefore
|
||||
* the send buffer locked while both messages are placed
|
||||
*/
|
||||
LOCK_CLIENT(client);
|
||||
SEND_LOCK(client);
|
||||
|
||||
|
||||
if (mp->m_cmmd == IOC_BUILD) {
|
||||
@@ -1635,14 +1660,12 @@ printf("Build access security bypassed\n");
|
||||
if (!get_reply) {
|
||||
/* tell them that their request is to large */
|
||||
send_err(mp, ECA_TOLARGE, client, RECORD_NAME(&tmp_addr));
|
||||
UNLOCK_CLIENT(client);
|
||||
SEND_UNLOCK(client);
|
||||
FASTLOCK(&rsrv_free_addrq_lck);
|
||||
bucketRemoveItem(
|
||||
pCaBucket,
|
||||
pchannel->sid,
|
||||
pchannel);
|
||||
FASTUNLOCK(&rsrv_free_addrq_lck);
|
||||
FASTLOCK(&rsrv_free_addrq_lck);
|
||||
ellAdd(&rsrv_free_addrq, &pchannel->node);
|
||||
FASTUNLOCK(&rsrv_free_addrq_lck);
|
||||
return;
|
||||
@@ -1694,11 +1717,13 @@ printf("Build access security bypassed\n");
|
||||
*pMinorVersion = htons(CA_MINOR_VERSION);
|
||||
|
||||
END_MSG(client);
|
||||
SEND_UNLOCK(client);
|
||||
|
||||
/* store the addr block on the cast queue until it is claimed */
|
||||
FASTLOCK(&client->addrqLock);
|
||||
ellAdd(&client->addrq, &pchannel->node);
|
||||
FASTUNLOCK(&client->addrqLock);
|
||||
|
||||
UNLOCK_CLIENT(client);
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -1718,7 +1743,7 @@ struct client *client
|
||||
{
|
||||
FAST struct extmsg *reply;
|
||||
|
||||
LOCK_CLIENT(client);
|
||||
SEND_LOCK(client);
|
||||
reply = (struct extmsg *) ALLOC_MSG(client, 0);
|
||||
if (!reply) {
|
||||
taskSuspend(0);
|
||||
@@ -1728,7 +1753,7 @@ struct client *client
|
||||
reply->m_postsize = 0;
|
||||
|
||||
END_MSG(client);
|
||||
UNLOCK_CLIENT(client);
|
||||
SEND_UNLOCK(client);
|
||||
|
||||
}
|
||||
|
||||
@@ -1857,7 +1882,7 @@ unsigned lineno
|
||||
)
|
||||
{
|
||||
log_header(mp,0);
|
||||
LOCK_CLIENT(client);
|
||||
SEND_LOCK(client);
|
||||
send_err(
|
||||
mp,
|
||||
ECA_INTERNAL,
|
||||
@@ -1865,7 +1890,7 @@ unsigned lineno
|
||||
"Bad Resource ID at %s.%d",
|
||||
pFileName,
|
||||
lineno);
|
||||
UNLOCK_CLIENT(client);
|
||||
SEND_UNLOCK(client);
|
||||
}
|
||||
|
||||
|
||||
@@ -1985,11 +2010,10 @@ LOCAL void casAccessRightsCB(ASCLIENTPVT ascpvt, asClientStatus type)
|
||||
|
||||
access_rights_reply(pciu);
|
||||
|
||||
LOCK_CLIENT(pclient);
|
||||
|
||||
/*
|
||||
* Update all event call backs
|
||||
*/
|
||||
FASTLOCK(&pclient->eventqLock);
|
||||
for (pevext = (struct event_ext *) ellFirst(&pciu->eventq);
|
||||
pevext;
|
||||
pevext = (struct event_ext *) ellNext(&pevext->node)){
|
||||
@@ -2006,8 +2030,7 @@ LOCAL void casAccessRightsCB(ASCLIENTPVT ascpvt, asClientStatus type)
|
||||
db_post_single_event(pevext->pdbev);
|
||||
}
|
||||
}
|
||||
|
||||
UNLOCK_CLIENT(pclient);
|
||||
FASTUNLOCK(&pclient->eventqLock);
|
||||
|
||||
break;
|
||||
|
||||
@@ -2047,7 +2070,7 @@ LOCAL void access_rights_reply(struct channel_in_use *pciu)
|
||||
ar |= CA_ACCESS_RIGHT_WRITE;
|
||||
}
|
||||
|
||||
LOCK_CLIENT(pclient);
|
||||
SEND_LOCK(pclient);
|
||||
reply = (struct extmsg *)ALLOC_MSG(pclient, 0);
|
||||
assert(reply);
|
||||
|
||||
@@ -2056,5 +2079,5 @@ LOCAL void access_rights_reply(struct channel_in_use *pciu)
|
||||
reply->m_cid = pciu->cid;
|
||||
reply->m_available = ar;
|
||||
END_MSG(pclient);
|
||||
UNLOCK_CLIENT(pclient);
|
||||
SEND_UNLOCK(pclient);
|
||||
}
|
||||
|
||||
@@ -93,7 +93,7 @@ int lock_needed;
|
||||
}
|
||||
|
||||
if(lock_needed){
|
||||
LOCK_CLIENT(pclient);
|
||||
SEND_LOCK(pclient);
|
||||
}
|
||||
|
||||
if(pclient->send.stk){
|
||||
@@ -147,7 +147,7 @@ int lock_needed;
|
||||
|
||||
|
||||
if(lock_needed){
|
||||
UNLOCK_CLIENT(pclient);
|
||||
SEND_UNLOCK(pclient);
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
@@ -274,9 +274,9 @@ LOCAL int terminate_one_client(struct client *client)
|
||||
}
|
||||
|
||||
while(TRUE){
|
||||
LOCK_CLIENT(client);
|
||||
FASTLOCK(&client->addrqLock);
|
||||
pciu = (struct channel_in_use *) ellGet(&client->addrq);
|
||||
UNLOCK_CLIENT(client);
|
||||
FASTUNLOCK(&client->addrqLock);
|
||||
if(!pciu){
|
||||
break;
|
||||
}
|
||||
@@ -294,9 +294,9 @@ LOCAL int terminate_one_client(struct client *client)
|
||||
/*
|
||||
* AS state change could be using this list
|
||||
*/
|
||||
LOCK_CLIENT(client);
|
||||
FASTLOCK(&client->eventqLock);
|
||||
pevext = (struct event_ext *) ellGet(&pciu->eventq);
|
||||
UNLOCK_CLIENT(client);
|
||||
FASTUNLOCK(&client->eventqLock);
|
||||
if(!pevext){
|
||||
break;
|
||||
}
|
||||
@@ -356,6 +356,26 @@ LOCAL int terminate_one_client(struct client *client)
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
if(FASTLOCKFREE(&client->eventqLock)<0){
|
||||
logMsg("CAS: couldnt free sem\n",
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
}
|
||||
|
||||
if(FASTLOCKFREE(&client->addrqLock)<0){
|
||||
logMsg("CAS: couldnt free sem\n",
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
}
|
||||
|
||||
if(FASTLOCKFREE(&client->putNotifyLock)<0){
|
||||
logMsg("CAS: couldnt free sem\n",
|
||||
NULL,
|
||||
@@ -499,7 +519,8 @@ LOCAL void log_one_client(struct client *client)
|
||||
|
||||
bytes_reserved = 0;
|
||||
bytes_reserved += sizeof(struct client);
|
||||
LOCK_CLIENT(client);
|
||||
|
||||
FASTLOCK(&client->addrqLock);
|
||||
pciu = (struct channel_in_use *) client->addrq.node.next;
|
||||
while (pciu){
|
||||
bytes_reserved += sizeof(struct channel_in_use);
|
||||
@@ -512,7 +533,7 @@ LOCAL void log_one_client(struct client *client)
|
||||
}
|
||||
pciu = (struct channel_in_use *) ellNext(&pciu->node);
|
||||
}
|
||||
UNLOCK_CLIENT(client);
|
||||
FASTUNLOCK(&client->addrqLock);
|
||||
|
||||
psaddr = &client->addr;
|
||||
printf("\tRemote address %u.%u.%u.%u Remote port %d state=%s\n",
|
||||
@@ -525,7 +546,7 @@ LOCAL void log_one_client(struct client *client)
|
||||
printf( "\tChannel count %d\n", ellCount(&client->addrq));
|
||||
printf( "\t%d bytes allocated\n", bytes_reserved);
|
||||
|
||||
LOCK_CLIENT(client);
|
||||
FASTLOCK(&client->addrqLock);
|
||||
pciu = (struct channel_in_use *) client->addrq.node.next;
|
||||
i=0;
|
||||
while (pciu){
|
||||
@@ -539,7 +560,7 @@ LOCAL void log_one_client(struct client *client)
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
UNLOCK_CLIENT(client);
|
||||
FASTUNLOCK(&client->addrqLock);
|
||||
|
||||
printf("\n");
|
||||
|
||||
|
||||
@@ -82,7 +82,7 @@ static char *sccsId = "$Id$";
|
||||
#include <server.h>
|
||||
|
||||
|
||||
LOCAL void clean_addrq(struct client *pclient);
|
||||
LOCAL void clean_addrq();
|
||||
|
||||
|
||||
|
||||
@@ -298,7 +298,7 @@ int cast_server(void)
|
||||
|
||||
if(nchars == 0){
|
||||
cas_send_msg(prsrv_cast_client, TRUE);
|
||||
clean_addrq(prsrv_cast_client);
|
||||
clean_addrq();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -311,8 +311,7 @@ int cast_server(void)
|
||||
*/
|
||||
#define TIMEOUT 60 /* sec */
|
||||
|
||||
LOCAL void
|
||||
clean_addrq(struct client *pclient)
|
||||
LOCAL void clean_addrq()
|
||||
{
|
||||
struct channel_in_use *pciu;
|
||||
struct channel_in_use *pnextciu;
|
||||
@@ -325,9 +324,9 @@ clean_addrq(struct client *pclient)
|
||||
|
||||
current = tickGet();
|
||||
|
||||
LOCK_CLIENT(prsrv_cast_client);
|
||||
FASTLOCK(&prsrv_cast_client->addrqLock);
|
||||
pnextciu = (struct channel_in_use *)
|
||||
pclient->addrq.node.next;
|
||||
prsrv_cast_client->addrq.node.next;
|
||||
|
||||
while(pciu = pnextciu){
|
||||
pnextciu = (struct channel_in_use *)pciu->node.next;
|
||||
@@ -342,7 +341,7 @@ clean_addrq(struct client *pclient)
|
||||
if (delay > timeout) {
|
||||
int status;
|
||||
|
||||
ellDelete(&pclient->addrq, &pciu->node);
|
||||
ellDelete(&prsrv_cast_client->addrq, &pciu->node);
|
||||
FASTLOCK(&rsrv_free_addrq_lck);
|
||||
s = bucketRemoveItem(pCaBucket, pciu->sid, pciu);
|
||||
if(s != BUCKET_SUCCESS){
|
||||
@@ -361,7 +360,7 @@ clean_addrq(struct client *pclient)
|
||||
maxdelay = max(delay, maxdelay);
|
||||
}
|
||||
}
|
||||
UNLOCK_CLIENT(prsrv_cast_client);
|
||||
FASTUNLOCK(&prsrv_cast_client->addrqLock);
|
||||
|
||||
# ifdef DEBUG
|
||||
if(ndelete){
|
||||
@@ -471,6 +470,8 @@ struct client *create_udp_client(unsigned sock)
|
||||
|
||||
FASTLOCKINIT(&client->lock);
|
||||
FASTLOCKINIT(&client->putNotifyLock);
|
||||
FASTLOCKINIT(&client->addrqLock);
|
||||
FASTLOCKINIT(&client->eventqLock);
|
||||
|
||||
client->recv.maxstk = MAX_UDP;
|
||||
|
||||
|
||||
@@ -52,19 +52,17 @@ static char *sccsId = "$Id$\t$Date$";
|
||||
#include <in.h>
|
||||
#include <logLib.h>
|
||||
#include <sysLib.h>
|
||||
#include <taskLib.h>
|
||||
|
||||
#define MAX_BLOCK_THRESHOLD 100000
|
||||
|
||||
/*
|
||||
* EPICS includes
|
||||
*/
|
||||
#include <iocinf.h>
|
||||
#if 0
|
||||
#include <taskwd.h>
|
||||
#include <task_params.h>
|
||||
#include <iocmsg.h>
|
||||
#include <ellLib.h>
|
||||
#include <envDefs.h>
|
||||
#endif
|
||||
|
||||
#include "server.h"
|
||||
#include <task_params.h>
|
||||
#include <addrList.h>
|
||||
|
||||
/*
|
||||
* RSRV_ONLINE_NOTIFY_TASK
|
||||
@@ -91,7 +89,7 @@ int rsrv_online_notify_task()
|
||||
int sock;
|
||||
int true = TRUE;
|
||||
|
||||
taskwdInsert((int)taskIdCurrent,NULL,NULL);
|
||||
taskwdInsert(taskIdSelf(),NULL,NULL);
|
||||
|
||||
/*
|
||||
* Open the socket.
|
||||
@@ -143,6 +141,20 @@ int rsrv_online_notify_task()
|
||||
# endif
|
||||
|
||||
while(TRUE){
|
||||
int maxBlock;
|
||||
|
||||
/*
|
||||
* check max block and disable new channels
|
||||
* if its to small
|
||||
*/
|
||||
maxBlock = memFindMax();
|
||||
if(maxBlock<MAX_BLOCK_THRESHOLD){
|
||||
casDontAllowSearchReplies = TRUE;
|
||||
}
|
||||
else{
|
||||
casDontAllowSearchReplies = FALSE;
|
||||
}
|
||||
|
||||
pNode = (caAddrNode *) destAddr.node.next;
|
||||
while(pNode){
|
||||
msg.m_available =
|
||||
|
||||
@@ -69,6 +69,8 @@ struct client{
|
||||
ELLNODE node;
|
||||
FAST_LOCK lock;
|
||||
FAST_LOCK putNotifyLock;
|
||||
FAST_LOCK addrqLock;
|
||||
FAST_LOCK eventqLock;
|
||||
ELLLIST addrq;
|
||||
ELLLIST putNotifyQue;
|
||||
struct message_buffer send;
|
||||
@@ -156,13 +158,18 @@ GLBLTYPE FAST_LOCK rsrv_free_addrq_lck;
|
||||
GLBLTYPE FAST_LOCK rsrv_free_eventq_lck;
|
||||
GLBLTYPE struct client *prsrv_cast_client;
|
||||
GLBLTYPE BUCKET *pCaBucket;
|
||||
/*
|
||||
* set true if max memory block drops below MAX_BLOCK_THRESHOLD
|
||||
*/
|
||||
#define MAX_BLOCK_THRESHOLD 100000
|
||||
GLBLTYPE int casDontAllowSearchReplies;
|
||||
|
||||
#define LOCK_CLIENT(CLIENT)\
|
||||
#define SEND_LOCK(CLIENT)\
|
||||
{\
|
||||
FASTLOCK(&(CLIENT)->lock);\
|
||||
}
|
||||
|
||||
#define UNLOCK_CLIENT(CLIENT)\
|
||||
#define SEND_UNLOCK(CLIENT)\
|
||||
{ \
|
||||
FASTUNLOCK(&(CLIENT)->lock);\
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user