Merged cas-intf-addr-list branch.

This commit is contained in:
Andrew Johnson
2014-07-31 11:34:10 -05:00
5 changed files with 70 additions and 54 deletions

View File

@@ -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

View File

@@ -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>

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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;