allow CA addr list to include ports and improve duplicate detect

This commit is contained in:
Jeff Hill
2000-11-21 22:23:28 +00:00
parent 1052c6b2b7
commit c1f7601ad4
3 changed files with 64 additions and 25 deletions

View File

@@ -7,15 +7,16 @@ extern "C" {
#endif
epicsShareFunc void epicsShareAPI configureChannelAccessAddressList
(ELLLIST *pList, SOCKET sock, unsigned short port);
( ELLLIST *pList, SOCKET sock, unsigned short port );
epicsShareFunc void epicsShareAPI addAddrToChannelAccessAddressList
(ELLLIST *pList, const ENV_PARAM *pEnv, unsigned short port);
( ELLLIST *pList, const ENV_PARAM *pEnv, unsigned short port );
epicsShareFunc void epicsShareAPI printChannelAccessAddressList (const ELLLIST *pList);
epicsShareFunc void epicsShareAPI printChannelAccessAddressList
( const ELLLIST *pList );
epicsShareFunc void epicsShareAPI setPortAndRemoveDuplicates
(ELLLIST *pDestList, ELLLIST *pSrcList, unsigned short port);
epicsShareFunc void epicsShareAPI removeDuplicatesAddresses
( ELLLIST *pDestList, ELLLIST *pSrcList );
#ifdef __cplusplus
}

View File

@@ -78,6 +78,7 @@ epicsShareFunc void epicsShareAPI addAddrToChannelAccessAddressList
}
pNewNode->addr.ia = addr;
memset ( &pNewNode->netMask, '\0', sizeof ( pNewNode->netMask ) );
/*
* LOCK applied externally
@@ -89,30 +90,26 @@ epicsShareFunc void epicsShareAPI addAddrToChannelAccessAddressList
}
/*
* setPortAndRemoveDuplicates ()
* removeDuplicatesAddresses ()
*/
epicsShareFunc void epicsShareAPI setPortAndRemoveDuplicates
(ELLLIST *pDestList, ELLLIST *pSrcList, unsigned short port)
epicsShareFunc void epicsShareAPI removeDuplicatesAddresses
( ELLLIST *pDestList, ELLLIST *pSrcList )
{
osiSockAddrNode *pNode;
/*
* eliminate duplicates and set the port
*/
while ( (pNode = (osiSockAddrNode *) ellGet ( pSrcList ) ) ) {
osiSockAddrNode *pTmpNode;
if ( pNode->addr.sa.sa_family == AF_INET ) {
/*
* set the correct destination port
*/
pNode->addr.ia.sin_port = htons (port);
pTmpNode = (osiSockAddrNode *) ellFirst (pDestList);
while ( pTmpNode ) {
if (pTmpNode->addr.sa.sa_family == AF_INET) {
if (pNode->addr.ia.sin_addr.s_addr == pTmpNode->addr.ia.sin_addr.s_addr &&
pNode->addr.ia.sin_port == pTmpNode->addr.ia.sin_port) {
unsigned netMask = pNode->netMask.ia.sin_addr.s_addr |
pTmpNode->netMask.ia.sin_addr.s_addr;
unsigned exorAddr = pNode->addr.ia.sin_addr.s_addr ^ pTmpNode->addr.ia.sin_addr.s_addr;
exorAddr &= netMask;
if ( exorAddr == 0u && pNode->addr.ia.sin_port == pTmpNode->addr.ia.sin_port) {
char buf[64];
ipAddrToDottedIP ( &pNode->addr.ia, buf, sizeof (buf) );
ca_printf ( "Warning: Duplicate EPICS CA Address list entry \"%s\" discarded\n", buf );
@@ -133,6 +130,23 @@ epicsShareFunc void epicsShareAPI setPortAndRemoveDuplicates
}
}
/*
* forcePort ()
*/
static void forcePort (ELLLIST *pList, unsigned short port)
{
osiSockAddrNode *pNode;
pNode = (osiSockAddrNode *) ellFirst ( pList );
while ( pNode ) {
if ( pNode->addr.sa.sa_family == AF_INET ) {
pNode->addr.ia.sin_port = htons (port);
}
pNode = (osiSockAddrNode *) ellNext ( &pNode->node );
}
}
/*
* configureChannelAccessAddressList ()
*/
@@ -183,17 +197,21 @@ epicsShareFunc void epicsShareAPI configureChannelAccessAddressList
*/
pNewNode->addr.ia.sin_family = AF_INET;
pNewNode->addr.ia.sin_addr.s_addr = htonl ( INADDR_LOOPBACK );
pNewNode->addr.ia.sin_port = htons ( port );
memset ( &pNewNode->netMask, '\0', sizeof ( pNewNode->netMask ) );
ellAdd ( &tmpList, &pNewNode->node );
}
else {
errlogPrintf ( "configureChannelAccessAddressList(): no memory available for configuration\n" );
}
}
else {
forcePort ( &tmpList, port );
}
}
addAddrToChannelAccessAddressList ( &tmpList, &EPICS_CA_ADDR_LIST, port );
setPortAndRemoveDuplicates (pList, &tmpList, port);
removeDuplicatesAddresses ( pList, &tmpList );
}

View File

@@ -37,6 +37,24 @@
#include "server.h"
#include "addrList.h"
/*
* forcePort ()
*/
static void forcePort (ELLLIST *pList, unsigned short port)
{
osiSockAddrNode *pNode;
pNode = (osiSockAddrNode *) ellFirst ( pList );
while ( pNode ) {
if ( pNode->addr.sa.sa_family == AF_INET ) {
pNode->addr.ia.sin_port = htons (port);
}
pNode = (osiSockAddrNode *) ellNext ( &pNode->node );
}
}
//
// casDGIntfIO::casDGIntfIO()
//
@@ -44,12 +62,14 @@ casDGIntfIO::casDGIntfIO (caServerI &serverIn, const caNetAddr &addr,
bool autoBeaconAddr, bool addConfigBeaconAddr) :
casDGClient (serverIn)
{
ELLLIST BCastAddrList;
osiSockAddr serverAddr;
osiSockAddr serverBCastAddr;
int status;
unsigned short beaconPort;
ellInit(&this->beaconAddrList);
ellInit ( &BCastAddrList );
ellInit ( &this->beaconAddrList );
if ( ! osiSockAttach () ) {
throw S_cas_internal;
@@ -90,10 +110,8 @@ casDGIntfIO::casDGIntfIO (caServerI &serverIn, const caNetAddr &addr,
// discover beacon addresses associated with this interface
//
{
ELLLIST BCastAddrList;
osiSockAddrNode *pAddr;
ellInit (&BCastAddrList);
osiSockDiscoverBroadcastAddresses (&BCastAddrList,
this->sock, &serverAddr); // match addr
if (ellCount(&BCastAddrList)<1) {
@@ -106,7 +124,7 @@ casDGIntfIO::casDGIntfIO (caServerI &serverIn, const caNetAddr &addr,
serverBCastAddr.ia.sin_port = htons (this->dgPort);
if (autoBeaconAddr) {
setPortAndRemoveDuplicates (&this->beaconAddrList, &BCastAddrList, beaconPort);
forcePort (&BCastAddrList,beaconPort);
}
else {
ellFree (&BCastAddrList);
@@ -144,9 +162,11 @@ casDGIntfIO::casDGIntfIO (caServerI &serverIn, const caNetAddr &addr,
// add in the configured addresses
//
addAddrToChannelAccessAddressList (
&this->beaconAddrList, pParam, beaconPort);
&BCastAddrList, pParam, beaconPort);
}
removeDuplicatesAddresses ( &this->beaconAddrList, &BCastAddrList );
//
// Solaris specific:
// If they are binding to a particular interface then