Merged cas-intf-addr-list branch.
This commit is contained in:
@@ -15,6 +15,13 @@ EPICS Base 3.15.0.x releases are not intended for use in production systems.</p>
|
||||
<h2 align="center">Changes between 3.15.0.1 and 3.15.0.2</h2>
|
||||
<!-- Insert new items immediately below here ... -->
|
||||
|
||||
<h3>Implement EPICS_CAS_INTF_ADDR_LIST in rsrv</h3>
|
||||
|
||||
<p>The IOC server can now bind to a single IP address (and optional port number)
|
||||
read from the standard environment parameter EPICS_CAS_INTF_ADDR_LIST.
|
||||
Additional addresses included in that parameter after the first will be ignored
|
||||
and a warning message displayed at iocInit time.</p>
|
||||
|
||||
<h3>alarmString.h deprecated again</h3>
|
||||
|
||||
<p>The string arrays that provide string versions of the alarm status and
|
||||
|
||||
@@ -874,8 +874,13 @@ network interfaces. Specifically, UDP search messages addressed to both the IP
|
||||
addresses in EPICS_CAS_INTF_ADDR_LIST and also to the broadcast addresses of
|
||||
the corresponding LAN interfaces will be accepted by the server. By default,
|
||||
the CA server is accessible from all network interfaces configured into its
|
||||
host. <em>In R3.14 and previous releases the CA server employed by iocCore does
|
||||
not implement this feature</em>.</p>
|
||||
host.</p>
|
||||
|
||||
<p>In R3.14 and previous releases the CA server employed by iocCore did not
|
||||
implement the EPICS_CAS_INTF_ADDR_LIST feature. In this release the iocCore
|
||||
server will read the first IP address from the parameter variable and use that
|
||||
to select which interface to bind to. Any additional IP addresses will be
|
||||
ignored and a warning message displayed during IOC initialization.</p>
|
||||
|
||||
<h4>Ignoring Process Variable Name Resolution Requests From Certain Hosts</h4>
|
||||
|
||||
|
||||
@@ -63,8 +63,9 @@ static void req_server (void *pParm)
|
||||
unsigned priorityOfSelf = epicsThreadGetPrioritySelf ();
|
||||
unsigned priorityOfBeacons;
|
||||
epicsThreadBooleanStatus tbs;
|
||||
osiSockAddrNode *pNode;
|
||||
struct sockaddr_in serverAddr; /* server's address */
|
||||
osiSocklen_t addrSize;
|
||||
osiSocklen_t addrSize = (osiSocklen_t) sizeof(struct sockaddr_in);
|
||||
int status;
|
||||
SOCKET clientSock;
|
||||
epicsThreadId tid;
|
||||
@@ -85,6 +86,24 @@ static void req_server (void *pParm)
|
||||
(unsigned short) CA_SERVER_PORT );
|
||||
}
|
||||
|
||||
addAddrToChannelAccessAddressList ( &casIntfAddrList,
|
||||
&EPICS_CAS_INTF_ADDR_LIST, ca_server_port, 0 );
|
||||
if (ellCount(&casIntfAddrList) == 0) {
|
||||
pNode = (osiSockAddrNode *) calloc ( 1, sizeof(*pNode) );
|
||||
pNode->addr.ia.sin_family = AF_INET;
|
||||
pNode->addr.ia.sin_addr.s_addr = htonl ( INADDR_ANY );
|
||||
pNode->addr.ia.sin_port = htons ( ca_server_port );
|
||||
ellAdd ( &casIntfAddrList, &pNode->node );
|
||||
}
|
||||
else {
|
||||
if (ellCount ( &casIntfAddrList ) > 1)
|
||||
epicsPrintf ("CAS: Multiple entries in EPICS_CAS_INTF_ADDR_LIST, "
|
||||
"only the first will be used.\n");
|
||||
pNode = (osiSockAddrNode *) ellFirst ( &casIntfAddrList );
|
||||
}
|
||||
|
||||
memcpy ( &serverAddr, &pNode->addr.ia, addrSize );
|
||||
|
||||
if (IOC_sock != 0 && IOC_sock != INVALID_SOCKET) {
|
||||
epicsSocketDestroy ( IOC_sock );
|
||||
}
|
||||
@@ -100,50 +119,43 @@ static void req_server (void *pParm)
|
||||
|
||||
epicsSocketEnableAddressReuseDuringTimeWaitState ( IOC_sock );
|
||||
|
||||
/* Zero the sock_addr structure */
|
||||
memset ( (void *) &serverAddr, 0, sizeof ( serverAddr ) );
|
||||
serverAddr.sin_family = AF_INET;
|
||||
serverAddr.sin_addr.s_addr = htonl (INADDR_ANY);
|
||||
serverAddr.sin_port = htons ( ca_server_port );
|
||||
|
||||
/* get server's Internet address */
|
||||
status = bind ( IOC_sock, (struct sockaddr *) &serverAddr, sizeof ( serverAddr ) );
|
||||
if ( status < 0 ) {
|
||||
if ( SOCKERRNO == SOCK_EADDRINUSE ) {
|
||||
/*
|
||||
* enable assignment of a default port
|
||||
* (so the getsockname() call below will
|
||||
* work correctly)
|
||||
*/
|
||||
serverAddr.sin_port = ntohs (0);
|
||||
status = bind ( IOC_sock,
|
||||
(struct sockaddr *) &serverAddr, sizeof ( serverAddr ) );
|
||||
}
|
||||
if ( status < 0 ) {
|
||||
|
||||
status = bind(IOC_sock, (struct sockaddr *) &serverAddr, addrSize);
|
||||
if ( status < 0 ) {
|
||||
if ( SOCKERRNO == SOCK_EADDRINUSE ) {
|
||||
/*
|
||||
* enable assignment of a default port
|
||||
* (so the getsockname() call below will
|
||||
* work correctly)
|
||||
*/
|
||||
serverAddr.sin_port = ntohs (0);
|
||||
status = bind(IOC_sock, (struct sockaddr *) &serverAddr, addrSize);
|
||||
}
|
||||
if ( status < 0 ) {
|
||||
char sockErrBuf[64];
|
||||
epicsSocketConvertErrnoToString (
|
||||
sockErrBuf, sizeof ( sockErrBuf ) );
|
||||
errlogPrintf ( "CAS: Socket bind error was \"%s\"\n",
|
||||
sockErrBuf );
|
||||
epicsThreadSuspendSelf ();
|
||||
}
|
||||
}
|
||||
portChange = 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
portChange = 0;
|
||||
}
|
||||
|
||||
addrSize = ( osiSocklen_t ) sizeof ( serverAddr );
|
||||
status = getsockname ( IOC_sock,
|
||||
(struct sockaddr *)&serverAddr, &addrSize);
|
||||
if ( status ) {
|
||||
status = getsockname ( IOC_sock,
|
||||
(struct sockaddr *)&serverAddr, &addrSize);
|
||||
if ( status ) {
|
||||
char sockErrBuf[64];
|
||||
epicsSocketConvertErrnoToString (
|
||||
sockErrBuf, sizeof ( sockErrBuf ) );
|
||||
errlogPrintf ( "CAS: getsockname() error %s\n",
|
||||
sockErrBuf );
|
||||
errlogPrintf ( "CAS: getsockname() error %s\n",
|
||||
sockErrBuf );
|
||||
epicsThreadSuspendSelf ();
|
||||
}
|
||||
}
|
||||
|
||||
ca_server_port = ntohs (serverAddr.sin_port);
|
||||
|
||||
@@ -274,6 +286,7 @@ int rsrv_init (void)
|
||||
}
|
||||
}
|
||||
freeListInitPvt ( &rsrvLargeBufFreeListTCP, rsrvSizeofLargeBufTCP, 1 );
|
||||
ellInit ( &casIntfAddrList );
|
||||
ellInit ( &beaconAddrList );
|
||||
prsrv_cast_client = NULL;
|
||||
pCaBucket = NULL;
|
||||
@@ -948,16 +961,16 @@ struct client *create_tcp_client ( SOCKET sock )
|
||||
|
||||
void casStatsFetch ( unsigned *pChanCount, unsigned *pCircuitCount )
|
||||
{
|
||||
LOCK_CLIENTQ;
|
||||
LOCK_CLIENTQ;
|
||||
{
|
||||
int circuitCount = ellCount ( &clientQ );
|
||||
if ( circuitCount < 0 ) {
|
||||
*pCircuitCount = 0;
|
||||
*pCircuitCount = 0;
|
||||
}
|
||||
else {
|
||||
*pCircuitCount = (unsigned) circuitCount;
|
||||
*pCircuitCount = (unsigned) circuitCount;
|
||||
}
|
||||
*pChanCount = rsrvChannelCount;
|
||||
}
|
||||
UNLOCK_CLIENTQ;
|
||||
UNLOCK_CLIENTQ;
|
||||
}
|
||||
|
||||
@@ -115,23 +115,14 @@ static void clean_addrq(void)
|
||||
*/
|
||||
void cast_server(void *pParm)
|
||||
{
|
||||
struct sockaddr_in sin;
|
||||
osiSockAddrNode *paddrNode;
|
||||
struct sockaddr_in sin;
|
||||
int status;
|
||||
int count=0;
|
||||
struct sockaddr_in new_recv_addr;
|
||||
osiSocklen_t recv_addr_size;
|
||||
unsigned short port;
|
||||
osiSockIoctl_t nchars;
|
||||
|
||||
if ( envGetConfigParamPtr ( &EPICS_CAS_SERVER_PORT ) ) {
|
||||
port = envGetInetPortConfigParam ( &EPICS_CAS_SERVER_PORT,
|
||||
(unsigned short) CA_SERVER_PORT );
|
||||
}
|
||||
else {
|
||||
port = envGetInetPortConfigParam ( &EPICS_CA_SERVER_PORT,
|
||||
(unsigned short) CA_SERVER_PORT );
|
||||
}
|
||||
|
||||
recv_addr_size = sizeof(new_recv_addr);
|
||||
|
||||
if( IOC_cast_sock!=0 && IOC_cast_sock!=INVALID_SOCKET ) {
|
||||
@@ -174,13 +165,11 @@ void cast_server(void *pParm)
|
||||
#endif
|
||||
|
||||
epicsSocketEnableAddressUseForDatagramFanout ( IOC_cast_sock );
|
||||
|
||||
/* Zero the sock_addr structure */
|
||||
memset((char *)&sin, 0, sizeof(sin));
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
sin.sin_port = htons(port);
|
||||
|
||||
|
||||
paddrNode = (osiSockAddrNode *) ellFirst ( &casIntfAddrList );
|
||||
|
||||
memcpy(&sin, &paddrNode->addr.ia, sizeof (sin));
|
||||
|
||||
/* get server's Internet address */
|
||||
if( bind(IOC_cast_sock, (struct sockaddr *)&sin, sizeof (sin)) < 0){
|
||||
char sockErrBuf[64];
|
||||
@@ -245,7 +234,8 @@ void cast_server(void *pParm)
|
||||
* see if the next message is for this same client.
|
||||
*/
|
||||
if (prsrv_cast_client->send.stk>sizeof(caHdr)) {
|
||||
status = memcmp( (void *)&prsrv_cast_client->addr, (void *)&new_recv_addr, recv_addr_size);
|
||||
status = memcmp(&prsrv_cast_client->addr,
|
||||
&new_recv_addr, recv_addr_size);
|
||||
if(status){
|
||||
/*
|
||||
* if the address is different
|
||||
|
||||
@@ -165,6 +165,7 @@ GLBLTYPE SOCKET IOC_cast_sock;
|
||||
GLBLTYPE unsigned short ca_server_port;
|
||||
GLBLTYPE ELLLIST clientQ; /* locked by clientQlock */
|
||||
GLBLTYPE ELLLIST beaconAddrList;
|
||||
GLBLTYPE ELLLIST casIntfAddrList;
|
||||
GLBLTYPE epicsMutexId clientQlock;
|
||||
GLBLTYPE struct client *prsrv_cast_client;
|
||||
GLBLTYPE BUCKET *pCaBucket;
|
||||
|
||||
Reference in New Issue
Block a user