diff --git a/src/ca/addrList.h b/src/ca/addrList.h index 6d0e4a71b..69eb47098 100644 --- a/src/ca/addrList.h +++ b/src/ca/addrList.h @@ -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 } diff --git a/src/ca/iocinf.cpp b/src/ca/iocinf.cpp index b1179bd01..8d582b4ff 100644 --- a/src/ca/iocinf.cpp +++ b/src/ca/iocinf.cpp @@ -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 ); } diff --git a/src/cas/io/bsdSocket/casDGIntfIO.cc b/src/cas/io/bsdSocket/casDGIntfIO.cc index f3a4c7004..1320ba261 100644 --- a/src/cas/io/bsdSocket/casDGIntfIO.cc +++ b/src/cas/io/bsdSocket/casDGIntfIO.cc @@ -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